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

AI駆動で「他アプリの音を加工できる」アプリを作った

Avatar for Masahiro Masahiro
October 16, 2026

 AI駆動で「他アプリの音を加工できる」アプリを作った

AI駆動開発勉強会 遠州支部 #2 LT 2026/10/16

EffectDeck https://github.com/satomasahiro2005/EffectDeck

Avatar for Masahiro

Masahiro

October 16, 2026

More Decks by Masahiro

Other Decks in Technology

Transcript

  1. PCでEffeTuneを使い始めるまで 4 1 VB-CABLEを管理者で入れて再起動 2 既定の出力がCABLE Inputに変わったらスピーカーかDACに戻す 3 音量ミキサーでSpotify.exeの出力をCABLE Inputに

    macOSはSoundSource 4 EffeTuneのAudio Configuration 入力CABLE Output 出力DAC 96kHz 5 Spotifyを鳴らしたままON/OFFを切り替えて音が変わるか確かめる 任意 折り返しノイズが出たらCABLEの形式とInternal Sample Rateを96000Hzに 出典: Frieve-A/effetune docs/faq.md 1 Initial Setup for Streaming
  2. 最初の設定と聞くときの手間 PC+EffeTune 最初の設定 VB-CABLEを入れる iPhone+EffectDeck 7 手順 最初の設定 EffectDeckを入れる 1

    再起動 既定の出力をスピーカーかDACに戻す Spotify.exeの出力をCABLE Inputへ EffeTuneの入力をCABLE Outputへ EffeTuneの出力をDACへ 96kHzを選ぶ 聞くとき EffeTuneを開く 再生する 5 出典: Frieve-A/effetune docs/faq.md 1 / EffectDeck site/src/guide.js 聞くとき 再生する コントロールセンターでEffectDeckを選ぶ 手順
  3. iOS 26以前は脱獄なしで他のアプリの音を 置き換えられない iPhone 他のアプリ 他のアプリ 内蔵スピーカー 内蔵スピーカー イヤホン イヤホン

    画面収録で写す 画面収録で写す 元の再生を止めて受け取る 元の再生を止めて受け取る 元の音は止まらない 元の音は止まらない com.apple.coreaudio.app-tap entitlement 取れない entitlement 取れない E ectDeck E ectDeck 6
  4. 外の再生機器向けの拡張をiPhone自身の 出力先にした 本来の使い方 本来の使い方 iPhone 出力先に選 出力先に選 MediaDevice MediaDevice Extension

    Extension 他のアプリ 他のアプリ TCP 127.0.0.1:47101 E ectDeck E ectDeck E eTuneのDSP E eTuneのDSP 8 外の再生機器 外の再生機器 内蔵スピーカー 内蔵スピーカー イヤホン イヤホン
  5. 実装はClaude Codeに任せた 何を作るか決める 実機で確かめる 人 動いた 動いた 動かない 動かない 実装

    Claude Code Macで フレームワークを逆アセン MediaExperience 10 ル ルド App Storeへ提出 実機ロ を読む
  6. 9/16にAltStore PALで配信を始めた 1日20時間 9/17 22:44 App Store 2026.09.17 9/15 02:00

    iOS 27公開 9/15 20:57 e2e0e85 9/16 22:07 ddb6eba 最初のコミット 9/16 03:45 b6a15a8 アプリを1本に 9/15 11 12コミット 9/16 AltStore PAL 2.9.0 build 10 34コミット 9/17 App Storeの審査 App Storeの審査 73コミット
  7. 逆アセンブルで1アプリ構成を実現 MediaExperience -[MXCoreSession hasMediaDeviceEntitlement] 見るのは本体アプリの署名entitlementただ1つ 2本 9/15 e2e0e85 拡張を運ぶ Bridge

    鳴らす Live 1本 9/16 b6a15a8 受け取って鳴らす EffeTuneLive media-device-extension 拡張 media-device-extension '!pla' 14 TCP 拡張 media-device-extension TCP
  8. 出力先の選択ボタンを置くだけで音が ループする 出力 9/16 02:14 3f1e56c RoutePicker.swift AVRoutePickerView -import AVKit

    自分の入力 float32 のまま回る TCP 16 -struct RoutePicker: UIViewRepresentable { ドライバ - let v = AVRoutePickerView() +struct RoutePicker: View { + var body: some View { EmptyView() } AVRoutePickerViewを外して解決
  9. 31日で153億トークン 153 億 トークン 19 2,282 17 日 セッション cache読み込み97.8%

    API従量課金に換算 31 回の指示 それ以外 8,423 ドル ≒ 133 3.4億 万円
  10. 人だけで作った場合との比較 工数 実際 1 × 31 会社で作る 289 1人+Claude Code

    推定 18 費用 人だけで95,817行 人 日 ≒1人月 人月 21.5か月 平均13.4人 約 220 2.26 ドル 税込 ≒3.5万円 億円 78.4万円/人月
  11. 日ごとのコミット数とモデル main 662コミット Opus 5 全28 ランチとタ 739コミット Opus 5.5

    73 73 72 72 Claudeのモデル名が 622 Opus系 分かるコミット 653 件のうち 95.3 % Opus が 系 622 ÷ 653 Sonnet系31 Codex系35 9/15 19 9/22 9/29 10/6 10/13 未記録51
  12. 大規模CIの構築 CI Linuxとmacの試験 ASan UBSan TSan Fuzz 生成物のずれ DSP 上流のDSPの試験

    毎晩の長いFuzz CodeQL C/C++とActionsの Canary 静的解析 最新のXcodeベータで 毎日ビルド Release ASC ops TestFlight Badges 署名 出荷物の検査 App Storeへ提出 プロファイルの 作り直し TestFlight審査へ 既存ビルドを 内部グループへ ダウンロード数と評価 9/28〜10/16の実行 20 314 回 READMEの
  13. AIが不要なUI説明を増やし続けた Sourcesの Sources の footer:の数 の数 説明文を減らす指示 説明文を減らす指示 15 15

    13 13 02:46 → 02:46 → 02:54 02:54 10 10 3cb7da7 99 説明文を 52か所削除 44 66 088e891 Statusの説明を戻す 9/17 9/17 24 9/19 9/19 9/21 9/21 9/23 9/23 9/25 9/25 9/27 9/27 10/15 10/15
  14. ログを読み違えて件数を誤った ビルドのエラー 9/20 確かめたもの 確かめたもの build-run.log 0 run.shが拾った最後の組 2 件

    実際 2 試験の件数 9/28 xcodebuild build.log BandFIRPEQDesigner.magnitudeが無い 件 ExternalProcessorViewにnodeが無い 件 実際 682 Executed 682 tests, with 1 test skipped and … 件 4d0fa78 9/20 22:20 FiveBandFIRPEQView.swift fe0b3b9 9/28 12:39 Tests/Linux/run.sh - BandFIRPEQDesigner.magnitude(of: band, at: hz, - … with [0-9]+ failures?" + BandFIRPEQCore.magnitude(of: band, at: hz, + … with ([0-9]+ tests? skipped and )?[0-9]+ failures?" 25
  15. 配布用IPAで7種類のエフェクトが動かなかった dlsym(UnsafeMutableRawPointer(bitPattern: -2), "et_instance_asset_begin_ptr") strip 配布用IPA Debugと plain build App

    Store シンボル消失 0件 Releaseで nmで シンボル表を消す asset_begin stripしない シンボルが残る 2026.09.17 9/17 22:44 2026.09.18 9/18 15:11 dlsym失敗 名前で探して NULLが返る 見つかる 2026.09.19 2026.09.20 9/18 22:01 9/20 02:43 5日 26 AssetUpload.swift 7 種類が動かない IR Reverb FIR Crossover 5Band FIR PEQ Group Delay EQ Group Delay PEQ Room EQ Crosstalk Cancellation 動く 直す前のコードでも TestFlight build 23 364f940 9/22 09:23 9/21
  16. Releaseバイナリを自動で検査する Scripts/check_release_binary.sh 9/27 4216323 試験36件 strip lookup abiname plist entitle

    debugonly test_364f940_replay_red_then_green 364f940の前 exit 1 FAIL 2 364f940の後 exit 0 FAIL 0 FAIL lookup Sources/EffeTuneLive/DSP/AssetUpload.swift:10 dlsym("et_instance_asset_begin_ptr") → EffectDeck: export されていない FAIL abiname EffectDeck: 自前の口の名前 "et_instance_asset_begin_ptr" が字として入っているのに export されていない PASS PASS lookup 名前で引く口はソースに無い(5 本を読んだ) abiname 自前の C の口の名前(3 個)はどの実行ファイルにも字として入っていない test_unstripped_binary_fails_unless_allowed stripしていない本体 exit 1 FAIL EffectDeck: ローカルシンボル 500 個 strip されていない(plain build か Debug) FAIL 1 配布用IPAにも掛ける release.yml 27 strip bd5a49d 10/3
  17. 修正済みのバグが何度も再発 帯を置く 帯を置く 入らない 入らない 当たりと高さ 当たりと高さ 空の鎖 空の鎖 入らない

    入らない 脇と間 脇と間 消えた行 消えた行 2列の左 2列の左 07:19 07:19 23:29 23:29 00:49 00:49 11:11 11:11 22:49 22:49 23:41 23:41 23:51 23:51 01:49 01:49 9/17 9/17 9/20 9/20 42859d4 e7d7dfa 末尾の帯にドロップしても入らない 末尾の帯にドロップしても入らない Color.clearは当たりを取らない 帯が在ってもドロップを受けない e7d7dfa 9/21 00:49 Color.clear .frame(height: 96) + + 28 .frame(height: tailHeight) .contentShape(Rectangle()) 95966e4 9/21 9/21 カードを消すと末尾の帯 カードを消すと末尾の帯 消えた行の高さ 10/5 10/5 d253e5e 効かない 効かない 合計に残る 帯 = 器 − 行の高さの合計 帯が最小の96ptに縮む 5045ce0 10/5 23:51 } action: { measured(row.node.id, $0) } + .onDisappear { unmeasured(row.node.id) } 5045ce0 80c05b8 10/8 10/8
  18. XCUITestでドロップを点ごとに自動で試す DropProbe Volume Tests/UI/DropProbe.swift Tone Control XCUITest 2列 iPad 12点

    1列 iPhoneの幅 10点 10/5 d253e5e 10/8 80c05b8 長押し1.2秒 Volume Output Correction miniCorrection leftFar gap Tone Control leftPad card miniTail tail 2列の左の一覧 2列の左の一覧 鎖の列 鎖の列 点まで運ぶ rightFar 1.0秒留めて放す rightPad emptySide No e ects emptyText emptyBelow 鎖 鎖 空 空 電源の数が増えたか XCTAssertGreaterThan(after, before) 修正前のmain 10/5 2列 修正後 10/5 2列 DROPPROBE wide leftFar FAIL point=(294,380) before=2 after=2 DROPPROBE wide rightFar PASS point=(998,380) before=2 after=4 DROPPROBE wide leftPad FAIL point=(317,380) before=2 after=2 DROPPROBE wide rightPad FAIL point=(975,380) before=2 after=2 DROPPROBE wide rightFar FAIL point=(998,380) before=2 after=2 DROPPROBE wide gap FAIL point=(646,343) before=2 after=2 DROPPROBE wide tail PASS point=(646,1296) before=2 after=4 DROPPROBE wide card PASS point=(646,380) before=2 after=4 29 DROPPROBE wide leftPad PASS point=(317,380) before=2 after=4 DROPPROBE wide gap PASS point=(646,343) before=2 after=4 DROPPROBE wide tail PASS point=(646,1296) before=2 after=4 DROPPROBE wide card PASS point=(646,380) before=2 after=4 DROPPROBE wide emptyText PASS point=(646,239) before=0 after=2 ** TEST SUCCEEDED **