Skip to content

Latest commit

 

History

History
221 lines (156 loc) · 7.05 KB

File metadata and controls

221 lines (156 loc) · 7.05 KB

Haptic Gen

中文 | 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.

Features

  • 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

System Requirements

  • iOS 26.0+
  • Audio formats: WAV, CAF, M4A, MP3, AIFF (supported by AVAudioFile)

Installation & Setup

This project uses XcodeGen to manage project configuration. Do not commit .xcodeproj; instead, generate via project.yml.

Initial Setup

# 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

# Build in Xcode (Cmd+B) or command line
xcodebuild build -scheme HapticGen \
  -destination 'platform=iOS Simulator,name=iPhone 17 Pro'

Run

Press Cmd+R in Xcode, or connect a real device and install via Xcode (auto-signing).

Workflow

1. Import Audio

Click "Import Audio" -> Select a local multi-channel audio file

Supported formats: WAV, M4A, MP3, AIFF, CAF, etc.

2. Analyze

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

3. Generate

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

4. Export

  • Export .ahap: Export AHAP JSON file (usable in other apps)
  • Package Haptic Trailer: Package as zip (audio + AHAP + manifest)

5. Share & Receive (File-Level)

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)

Sample Files

  • 2ch_haptic_trailer.ahap - Generated AHAP sample (2ch audio)
    • Contains HapticContinuous (continuous haptic) and HapticTransient (transient haptic) events

Known Issues & TODO

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

Architecture Overview

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

Tech Stack

  • 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)

Testing

# 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/AnalysisBenchmarkTests

CI/CD (App Package Output)

This repository includes a GitHub Actions pipeline: .github/workflows/build-packages.yml.

  1. push master: automatically uploads HapticGen-simulator-app.zip and an unsigned IPA package (for local re-signing).
  2. 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:

  1. HapticGen-simulator-app.zip
  2. HapticGen-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:

  1. IOS_CERTIFICATE_P12_BASE64
  2. IOS_CERTIFICATE_PASSWORD
  3. IOS_PROVISIONING_PROFILE_BASE64
  4. IOS_EXPORT_OPTIONS_BASE64
  5. IOS_KEYCHAIN_PASSWORD
  6. IOS_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'

Contributing

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.

License

MIT License © 2026 Sakuzy Peng