中文 | English
An iOS tool application that automatically generates Apple AHAP (Haptic and Audio Pattern) files from multi-channel audio. Supports stereo to 22.2-channel audio with FFT-based spectrum analysis for haptic feature extraction. The current version focuses on analyze/generate/export and does not provide in-app playback preview.
Current version is an alpha demo (0.1.0-alpha) for feasibility validation.
Warning
This project is in early development. Zip import/export is under verification. Not recommended for production use.
-
Multi-Channel Audio Analysis: Support 2ch to 24ch (22.2-channel standard)
- FFT spectrum analysis using Accelerate/vDSP
- Streaming block-based processing for long audio files (default 30s blocks)
- Per-channel parallel analysis, utilizing multi-core efficiently
-
Haptic Feature Extraction
- RMS intensity (intensity)
- Spectral centroid (spectral centroid → sharpness)
- Transient detection (transient events)
-
AHAP 1.0 Generation
- Cross-channel weighted blending (custom weight configuration supported)
- Parameter curve simplification (Ramer-Douglas-Peucker algorithm, 16384 control point limit)
- Three event types coverage: Transient / Continuous / ParameterCurve
-
Haptic Trailer Packaging (Under Verification)
- Generate HLS manifest (.m3u8) + AHAP + audio as a zip package
- Relative path references, auto-resolve after cross-device extraction
- File packaging/distribution only; no in-app playback preview
- iOS 26.0+
- Audio formats: WAV, CAF, M4A, MP3, AIFF (supported by AVAudioFile)
This project uses XcodeGen to manage project configuration. Do not commit .xcodeproj; instead, generate via project.yml.
# 1. Install XcodeGen (if not installed)
brew install xcodegen
# 2. Generate Xcode project (also run after modifying project.yml)
xcodegen generate
# 3. Open project
open HapticGen.xcodeproj# Build in Xcode (Cmd+B) or command line
xcodebuild build -scheme HapticGen \
-destination 'platform=iOS Simulator,name=iPhone 17 Pro'Press Cmd+R in Xcode, or connect a real device and install via Xcode (auto-signing).
Click "Import Audio" -> Select a local multi-channel audio file
Supported formats: WAV, M4A, MP3, AIFF, CAF, etc.
Click "Analyze"
- Auto-detect channel count & layout (stereo / 7.1 / 7.1.4, etc.)
- FFT analysis extracts haptic features (progress bar shown)
- Display total frames & layout on completion
Click "Generate" -> Adjust parameters and produce a haptic pattern
Adjustable parameters:
- Intensity Scale: 0.2x ~ 2.0x (overall haptic amplitude)
- Sharpness Bias: -0.5 ~ +0.5 (frequency perception)
- Event Density: 0.2x ~ 3.0x (transient haptic frequency)
- Transient Sensitivity: 0.0 ~ 1.0 (transient detection threshold)
Results display: transient event count, curve control point count
- Export .ahap: Export AHAP JSON file (usable in other apps)
- Package Haptic Trailer: Package as zip (audio + AHAP + manifest)
Sender:
- Click "Package Haptic Trailer" -> Share .zip file
Receiver:
- Receive .zip via AirDrop / Email / Files App
- Long press in Files App -> "Open with Haptic Gen"
- App auto-extracts and imports resources (no in-app playback)
- 2ch_haptic_trailer.ahap - Generated AHAP sample (2ch audio)
- Contains HapticContinuous (continuous haptic) and HapticTransient (transient haptic) events
Under Verification:
- Zip import/export
- m3u8 uses relative paths, should work in theory
- Currently validating file structure/parsing only, not playback
Performance Optimizations:
- 8ch FLAC analysis on simulator ~1.95s (RTF ≈ 164×), acceptable but room for improvement
- Haptic curve downsampling can be further optimized
- Analysis progress display: only percentage, no detailed info
- UI polish: currently debug dashboard (DebugDashboardView), needs refinement
Future Extensions:
- Haptic preset support
- Audio visualization
- Batch processing
Audio File
↓
AudioAnalyzer.analyze() FFT analysis, parallel multi-channel processing
↓
MultiChannelAnalysisResult RMS / spectral centroid / transient frame sequences
↓
HapticGenerator.generate() Cross-channel weighted blending
↓
HapticPatternDescriptor Haptic pattern intermediate representation
↓
HapticExporter Generate CHHapticPattern + AHAP JSON
- Swift 6.0 (strict concurrency mode)
- CoreHaptics (haptic engine)
- AVFoundation (audio processing)
- Accelerate / vDSP (vectorized FFT computation)
- ZIPFoundation (zip packaging/extraction)
- SwiftUI (UI framework)
- XcodeGen (project configuration)
# Run all tests
xcodebuild test -scheme HapticGen \
-destination 'platform=iOS Simulator,name=iPhone 17 Pro'
# Run single test class
xcodebuild test -scheme HapticGen \
-only-testing HapticGenTests/AudioAnalyzerTests
# Run benchmark tests (optional, requires sample audio)
xcodebuild test -scheme HapticGen \
-only-testing HapticGenTests/AnalysisBenchmarkTestsThis repository includes a GitHub Actions pipeline: .github/workflows/build-packages.yml.
push master: automatically uploadsHapticGen-simulator-app.zipand an unsigned IPA package (for local re-signing).workflow_dispatch:package_type=simulator: build simulator package only.package_type=unsigned: build unsigned IPA only (for local re-signing).package_type=signed: build signed IPA only.package_type=both: build simulator package + unsigned IPA.package_type=all: build simulator package + unsigned IPA + signed IPA.
Default push master artifacts:
HapticGen-simulator-app.zipHapticGen-unsigned-ipa(artifact name)
Unsigned IPA cannot be directly installed on iPhone. Users must re-sign it first via tools such as Sideloadly, AltStore, or ios-app-signer.
Signed IPA builds require these GitHub Secrets:
IOS_CERTIFICATE_P12_BASE64IOS_CERTIFICATE_PASSWORDIOS_PROVISIONING_PROFILE_BASE64IOS_EXPORT_OPTIONS_BASE64IOS_KEYCHAIN_PASSWORDIOS_TEAM_ID
Only signed / all modes require signing secrets. If these secrets are not fully configured, Build Signed IPA fails at the Validate signing secrets step.
Use this export options template as reference:
scripts/ci/ExportOptions.plist.example.
Base64 examples:
base64 < certificate.p12 | tr -d '\n'
base64 < profile.mobileprovision | tr -d '\n'
base64 < ExportOptions.plist | tr -d '\n'This project is a personal feasibility validation project and does not currently accept external contributions. For suggestions or bug reports, please open a GitHub Issue.
MIT License © 2026 Sakuzy Peng