Upgrade to Pro — share decks privately, control downloads, hide ads and more …

EffectDeck_KC3_2026.pdf

Avatar for Masahiro Masahiro
September 22, 2026
260

 EffectDeck_KC3_2026.pdf

KC3 2026でEffectDeckについてLTしたスライドです。理解する間もない超高速でのLTだったためgithubやdeepwikiも併せてご活用していただくことで理解を深められるはずです!
https://github.com/satomasahiro2005/effectdeck
https://deepwiki.com/satomasahiro2005/effectdeck

Avatar for Masahiro

Masahiro

September 22, 2026

Transcript

  1. まずお願い 1. GitHubで Star 2. App Storeから Install 3. 作者を

    Follow App StoreのリンクもGitHubのREADMEに あります link.nemut.ai/fxd 2
  2. まずデモ 1. Spotifyで再生 2. Control Centerから EffectDeck を選択 3. EQを大きく動かす

    4. Bypassして比較 Spotify側には 何もしていない 出力先にEffectDeckが出る 4
  3. iOS 27: Media Device Extension(MDE) アプリがメディア出力デバイスを 提供できる Control Centerの出力先に並ぶ RealtimeSampleHandling

    で リアルタイム配信を開始できる 右上のAirPlayボタン → 出力先を選ぶ Apple Developer Documentation: Creating a media device extension / 画像: Apple Support 8
  4. 気付いた瞬間に作り始めた iOS 27 仕様に気付く 1⽇ 2⽇ 3⽇ 実装開始 AltStore TestFlight

    App Store その⽇の夜 ドパミン駆動開発(ADHD駆動開発) EffectDeck git log: 最初のcommit 9/15 21:00 / AltStore PAL 9/16 / App Storeバッジ 9/17 9
  5. Appleが想定している使い方 iPhone Spotify iOS Media Device Extension Wi-Fi など 外部スピーカー

    / TV (機器メーカーのアプリ) iPhone → 外部のSpeaker / TV Apple Developer Documentation: MediaDevice.framework (iOS 27+) 10
  6. 全体アーキテクチャ iPhone Spotify プロセス① Extension(制限が強い) iOS 再⽣するだけ 出⼒先を切替 localhost TCP

    受信 TCP :47101 プロセス② EffectDeck.app(本体) DSP EQ など 仮想オーディオデバイス PCMを受け取るだけ 再⽣ AVAudioEngine スピーカー 13
  7. MediaOutputDevice を公開する MediaOutputDevice( id: deviceUUID, displayName: "EffectDeck", capabilities: [.realtimeAudioStreaming], deviceType:

    .hifiSpeaker, requiredNetworkEndpoints: endpoints ) これがControl Centerの出力先に現れる 14
  8. PCMってなに? +0.00 +0.45 +0.80 +0.90 +0.78 +0.57 +0.27 -0.15 …

    ⾳の波を 1秒に48,000回 測った数字の列 = PCM これさえあれば好きに加工できる 16
  9. localhost TCPで本体へ送る Extension → 127.0.0.1:47101 → Main App PCM capture

    DSP + playback 本体側がlisten Extension側から接続 19
  10. TCPはfloat32の境界を守らない 送った A A A A B B float 1個

    = 4 byte 届いた A A recv() 1回⽬ A B B float 1個 = 4 byte A B B recv() 2回⽬ B B recv() 3回⽬ 区切りがずれる → 端数は次のrecv()へ持ち越して組み⽴てる PCMでもframingは自分で持つ EffectDeck commit 3f1e56c 20
  11. Main AppでDSPして鳴らす EffeTune chain PCM Extensionから EQ AUv3 Comp JSFX

    出⼒ AUv3 / JSFX も同じchainの好きな位置に並ぶ 最後は AVAudioEngine で Speaker へ 21
  12. 音が無限に戻っていた EffectDeck.app DSP + 再⽣ TCPで 本体へ 出⼒が また⼊⼒に Extension

    EffectDeck commit 3f1e56c float32なので クリップせず上がり続ける 出⼒先 = EffectDeck 出力がそのまま次の入力になる 周回ごとに 23
  13. 出力先を固定しても直らない 試したこと 結果 .speaker override × AirPlayを外す × A2DPを外す ×

    default deviceを外す × independent policy ×(起動しなくなる) EffectDeck commit 3f1e56c 24
  14. 犯人は AVRoutePickerView Spotify 出⼒先: EffectDeck EffectDeck.app 共有の 出⼒コンテキスト EffectDeck (仮想デバイス)

    AVRoutePickerViewあり ⼀緒に引きずられる 置いただけで共有の出力コンテキストへ参加していた → 外したら直った EffectDeck commit 3f1e56c / RoutePicker.swift 25
  15. requiredNetworkEndpoints の罠 最初 修正 127.0.0.1:0 127.0.0.1:47101 bindを拒否され 0番を 実在するendpointを宣言 名乗っていた

    でも約1.5秒でlocalへ戻るのは止まらなかった → 後半へ EffectDeck commit 863a3d7 26
  16. activateも速く返す必要がある すぐにデバイスを出す 選択 activate デバイス出現 activate …待ち… もたつく 選択 Unable

    to Connect 「選べた」だけでは繋がっていない Apple Developer Documentation: Creating a media device extension 27
  17. 逆にExtensionを早く終了しても失敗する すぐ exit(0) quit() exit(0) iOSが呼びに来る もういない 2秒 猶予 iOSが呼びに来る

    応答できる 2秒待ってから exit quit() EffectDeck commit a58ba82 終了に2秒の猶予を置いた 28
  18. 最初はアプリを2本にした Bridge App DSP App + Media Device Extension AVAudioSession

    MDEを同梱するとAVAudioSessionが '!pla' で失敗すると思っていた 29
  19. 原因は本体側のentitlementだった 思い込み:2本に分ける Bridge App DSP App Extension⼊り ⾳を鳴らす Extensionを同梱すると 鳴らせないと思っていた

    iOSが⾒ていたのは 本体プロセスの署名だけ 実際:1本でよかった EffectDeck.app entitlement:空配列(キーだけ置く) Extension (.appex) entitlement:protocol IDを⼊れる com.apple.developer.media-device-extension EffectDeck commit b6a15a8 / bb1ccd5 30
  20. 入力を使っていないのに16 kHzになる A2DP ⾳楽⽤・出⼒だけ HFP 通話⽤・マイクも使う ⾼⾳質ステレオ ⼊⼒を使っていなくても .playAndRecord だと

    ⼊⼒経路がある 16 / 32 kHz モノラル ⼊⼒にBTマイクが 選ばれる setPreferredInput(builtInMic) EffectDeck commit da9ed59 31
  21. Spotifyで Unable to Connect 曲によって成功 / 失敗が変わる Canvas のある曲で失敗しやすい 前面

    / 背面だけでは説明できない Canvas = 再生画面の背景で流れる短いループ動画 34
  22. そこでMediaExperienceを逆アセンブルした 対象: iOS 27 RC / 実機dyld shared cache MXCustomRoutingController

    modifyCurrentSelectionIfNecessary:isPlayingVideoOutput: routingの判定を読む 36
  23. 実機ログではVIDEO=YESの観測は全敗だった 成功 17 VIDEO = NO VIDEO = YES 失敗

    3 失敗 3 成功 0 VIDEO=NO:MusicVADで通過 17 / 失敗 3 VIDEO=YES:0 / 3 小標本の観測結果 EffectDeck/docs/mde-routing-answer.md(A-10観測の集計) 38
  24. 決め手は2命令 cmp w0, #0x3 csinc w26, w22, wzr, ne ...

    tbz w26, #0x0, musicVAD_branch video-ishならMusicVAD branchへ行かない 39
  25. Spotify Canvas → AirPlay branch Canvas → video output →

    video-ish → AirPlay branch → EffectDeck切断 実用上は CanvasをOFF にする 一度Canvas付きの曲を流すと、Spotifyを再起動するまでVIDEO=YESが残る EffectDeck/docs/mde-routing-answer.md 40
  26. DSP core: EffeTune EffectDeckのDSP coreは EffeTune real-time audio effect processor

    エフェクトチェーンを組める multi-channel processingにも 対応 Frieve-A/effetune — MIT licensed DSP core / 画像: EffeTune README EffeTune(PC / Web版) 43
  27. EffectDeckで使えるエフェクタ Parametric EQ Dynamics / Compressor IR Reverb(Convolver) Delay /

    Reverb系 Stereo / multichannel processing 解析系エフェクト ※ エフェクトはEffeTune本家のもの(103種)。EffectDeckが足したのはAUv3 / JSFXのホスト 44
  28. EQってなに? +12 dB 低⾳を持ち上げる 0 dB -12 dB 20 ⽿に刺さる帯域を下げる

    100 1k 周波数ごとに音量を上げ下げする 10k 20k 周波数 (Hz) 45
  29. Convolver / IR ① 部屋やヘッドホンの「クセ」を測る 部屋 / 機器 パン! 響き⽅

    = IR ② その響きを⾳楽に掛ける ⾳楽 × その場所で鳴らしたような⾳ headphone correction / room・speaker IR / BRIR EffeTuneでは IR Reverb(最大16ch・4ch True Stereo対応) 46
  30. Debugでは動くのにApp Store版だけ壊れた Debug Release(出荷版) シンボル表 シンボル表 et_instance_asset_begin… dlsym() … stripされて空

    dlsym() … ⾒つかる → 動く nm EffectDeck commit 364f940 ⾒つからない → 7種が無効 で対象symbolは0件 47
  31. AUv3対応 iPhone インストール済みのプラグイン Plugin App A AU Plugin App B

    AU Plugin App C AU DAW / ⾳楽アプリ 普通の使い⽅ EffectDeck 同じAUv3を読み込む Spotifyの⾳ に掛かる iOSには既にAUv3プラグインのエコシステムがある Apple Developer Documentation: Audio Unit Extensions 53
  32. AUv3をchainの好きな位置に挿す ( から) PCM Extension ↓ EffeTune chain EQ →

    AUv3 → Comp → … ↓ AVAudioSourceNode → MainMixer ↓ Output chain内のAUv3 EffectDeck commit 3a80364 / ETAUExternalBridge.swift 55
  33. 例えばこんな感じ desc: simple gain slider1:0<-24,24,0.1>Gain (dB) @slider g = 10^(slider1/20);

    @sample spl0 *= g; spl1 *= g; スライダー定義 REAPERと同じUIが出る @slider つまみを動かしたときに1回 @sample 1サンプルごと(48,000回/秒 × ch) これだけでゲイン調整のエフェクトになる 60
  34. portable EEL2でもそのままでは ビルドできなかった Undefined symbols for architecture arm64 ___clear_cache でもaarch64用のcache処理が残っていた

    Linux / Android ARMではlibgcc側にある iOSではそのsymbolがない EEL_TARGET_PORTABLE JITなしなのにJIT由来の処理でlink failure 実行可能メモリが不要なときは をcompileしないよう修正 __clear_cache EffectDeck commit 8aea8a3(link failure)/ 5766fed(修正) 62
  35. EffectDeckのJSFX host portable EEL2 interpreter を 組み込む single-file JSFXをimport filesystem

    / MIDIなどは未対応 JITなし REAPERのDSP資産をiPhoneへ ※ JSFXは現在 TestFlight ベータ版のみ (App Store版では無効) EffectDeck commit 48ed5cf 63
  36. 対応範囲は意図的に絞る 項目 @init / @slider / @sample slider single-file import

    / include() filesystem MIDI JIT EffectDeck 対応 対応 対応 非対応 非対応 非対応 なし 64
  37. EffectDeckのDSPは3種類を組み合わせる EffeTune内蔵 AUv3 JSFX 用意するもの EffectDeck内蔵 インストール済みAUv3 .jsfx 1ファイル 実行

    DSP core AUAudioUnit EEL2 interpreter chain内の位置 基本chain 任意の位置 任意の位置 同じ再生音に用途の違うDSPを重ねられる 65
  38. 使い道 リスニング EQ headphone correction BRIR(4ch IR) analyzer DTM /

    実験 AUv3 JSFX multichannel custom DSP prototype 68
  39. 最後のデモ:ChatGPTにJSFXを書いてもらう Spotifyに JSFX.md → ChatGPT → .jsfx → EffectDeck にimport

    → 掛かる JSFX.md = EffectDeckで動くJSFXの書き方 1ファイル / include禁止 / filesystem・MIDIなし / JITなし … を全部書いてある EffectDeck/JSFX.md 70
  40. まとめ 1. iOS 27で Media Device Extension が追加された 2. EffectDeckが出力デバイスを名乗り、他アプリのメディア音声を

    受け取った 3. その上に EffeTune / AUv3 / JSFX のDSP環境を作った iPhoneの中にiPhone用のDSP付きSpeakerを 作った 71