生成AIと作るリアルタイム音声ビジュアライザー (実装編)

はじめに

前回(生成AIと作るリアルタイム音声ビジュアライザー (準備編))では、
実装を行うための環境構築を行いました。
この記事では、実際にCodexに渡したプロンプトの説明を行いつつ、
実際に生成されたコードを動かし、修正を行っていきます。

Codexに渡すプロンプト

ここからは、実際に Codexへどのような指示を出したか を整理していきます。

今回のようにAIを使用して作成するアプリでは、最初のプロンプト設計がかなり重要です。
理由は、AIに対して曖昧な依頼をすると、

  • 不要に複雑な構成になる
  • UIKitベースの実装が混ざる
  • FFTまわりが雑になる
  • 動いても記事にしづらいコードになる

といった問題が起きやすいためです。
そのため今回は、最初から役割と制約を明示したプロンプト を使用します。

おまけ:
実際の開発や継続的なメンテナンスにおいてはAGENTS.mdに主要なルールを記載し、
プロジェクト特有のルールを mdファイルとして配下のディレクトリに設置するなどします。

興味があればハーネスエンジニアリング(Harness Engineering)で調べてみてください。
(この言葉は元々違う分野で一般的に使用される言葉でしたが、
2026年段階で主にAIAgent系の記事で頻出するようになってきています。)

今回のプロンプトで意識したこと

今回Codexに依頼するにあたって、特に意識したポイントは次の通りです。

「まず動くもの」を優先する

最初から理想的な設計を求めるのではなく、
まずは 小さくても動くサンプル を作ることを優先します。

音声処理まわりは、設計をきれいにしようとすると一気に複雑になりやすいため、
初回はあくまで

  • マイク入力が取れる
  • スペクトラムが表示される
  • SwiftUIで動く

という最低限の成立を目標にします。


過剰な抽象化を避ける

AIは放っておくと、

  • Protocol
  • Manager
  • Coordinator
  • Utility層

のようなものを増やしがちです。

もちろん実務では有効な場合もありますが、今回の記事の目的は 学習用サンプルを作ること です。

そのため、

  • ファイル数は少なめ
  • 責務は分かれている
  • ただし過剰設計はしない

というバランスを狙います。


SwiftUI / AVAudioEngine / Accelerate を明示する

今回の技術スタックは最初から決めています。

  • UIは SwiftUI
  • 音声入力は AVAudioEngine
  • 解析は Accelerate / vDSP

このあたりを曖昧にすると、AIが別の実装方式を混ぜてくることがあります。

特に音声系では、

  • AVAudioRecorder
  • AudioKit風の構成
  • UIKitベースのView
  • 必要以上に複雑なDSP処理

などに寄ってしまう可能性があるため、使う技術は明確に指定しておきます。


記事向けの読みやすさを重視する

今回作りたいのは「製品コード」ではなく、
技術記事の中で解説しやすいサンプルコード です。

そのため、プロンプトの中でも

  • 小さい構成にする
  • 読みやすい命名にする
  • コメントを適度に入れる
  • デバッグしやすい構造にする

といった点を明示しています。


実際に渡したプロンプト

以下のような意図を踏まえたうえで、Codexには次のような依頼を行いました。
(プロンプトは英語に翻訳したうえで投入しています)

Create a small but working iOS sample app using SwiftUI that visualizes live microphone input in real time.

Goal:
- Build a technical sample app for a blog article
- Keep the code easy to read and easy to debug
- Prioritize a simple working implementation over advanced architecture

Tech requirements:
- SwiftUI for UI
- AVAudioEngine for microphone capture
- Accelerate / vDSP for FFT or frequency-domain magnitude analysis
- iOS 17+
- Swift
- No third-party libraries
- No UIKit

App behavior:
- Request microphone permission
- Capture live microphone input
- Analyze the input continuously
- Display a real-time spectrum visualizer using vertical bars
- Use a reasonable number of bars such as 32 or 48
- Normalize the values so the bars look visually stable
- Add light smoothing to reduce flicker

Architecture:
- AudioAnalyzer: ObservableObject responsible for AVAudioEngine setup, audio tap, FFT, normalization, smoothing, and publishing spectrum data
- SpectrumBarView: SwiftUI view that renders the bar graph
- ContentView: owns AudioAnalyzer with @StateObject and starts/stops audio analysis
- App entry point

Implementation constraints:
- Keep the project intentionally small
- Avoid unnecessary protocols, managers, coordinators, or excessive abstraction
- Prefer beginner-friendly naming
- Add concise comments around important learning points
- Publish UI updates on the main thread
- Avoid expensive work on the main thread when possible
- Keep the code structured for a technical article

Deliverables:
1. Full source code for all files
2. File structure
3. Notes for Info.plist microphone permission key
4. Short explanation of key implementation decisions
5. Mention likely pitfalls

Important:
- The output must be real compilable Swift code
- Do not use placeholder pseudocode
- Do not over-engineer
- Make the first version easy to iterate on after bugs are found

このプロンプトで狙ったこと

このプロンプトでは、単に「音声ビジュアライザーを作って」と依頼するのではなく、
次の点を最初から固定しています。

  • SwiftUIで作る
  • AVAudioEngineを使う
  • FFTはAccelerate系で行う
  • 表示はバーグラフ形式にする
  • 32〜48本程度の見やすい本数にする
  • 正規化と平滑化を入れる
  • 小さく読みやすい構成にする

特に重要なのは、最初から「小さく・動く・読みやすい」ことを優先している点です。

音声処理のような題材では、AIに自由度を与えすぎると
「一見すごそうに見えるが、実際には直しにくいコード」が出てくることがあります。

今回は技術記事化も前提にしているため、
完成度よりもまず 反復しやすさ を重視しました。


ここでのゴール

この段階でのゴールは、完成品を一発で得ることではありません。

  • まず動く最初の版を出してもらう
  • Xcodeでビルドする
  • エラーや不具合を確認する
  • 必要な修正を再度依頼する

という流れを前提にしています。

今回のCodexの使い方は 一発生成型ではなく、反復改善型の使い方 です。

この方が実際の開発にも近く、記事としても再現しやすい構成になります。


実際になげてみる

しばらく待ってみると以下のように ファイルが生成されます

更に実機でデバッグ実行してみる

特にエラーが起きることもなく以下のような画面が表示されます。

出力されたアプリの状況

何も手を加える事なく起動し、音声も取れていますが、常に左側のバーが高い状態のため、
ノイズをそのまま出力してる状態の様に見えます。

今の状態をまとめると

  • ビルドOK
  • 起動OK
  • マイク入力OK
  • ただし表示が期待どおりでない。

なので、ビルドエラーなどの対処はありませんでしたが、修正したい部分があったので、
「表示安定化」 を考えた上で修正を行っていきます。

考えられる原因

この現象の原因は、FFT(高速フーリエ変換:Fast Fourier Transform)結果の扱い方にありそうです。

FFTの出力は、そのまま使用すると非常に変動が大きく、
フレームごとに値が大きく上下します。

特にマイク入力では、

  • マイク自体のノイズ
  • 空調音
  • 微小な環境音

などもすべて数値として現れます。

そのため、FFTの値をそのまま表示するとスペクトラムが過敏に反応してしまうことがあります。

音声ビジュアライザーでは、解析の正確さだけでなく視覚的な安定性も重要になります。

そのため多くの実装では次のような処理が行われます。

  • 値の平滑化(Smoothing)
  • 微小ノイズの除去(Noise Floor)
  • 表示用の正規化(Normalization)

ここまでのまとめ

実際にAIに生成してもらったコードで、基本的な機能は実装できていましたが、
表示に不満が発生し、何が原因なのかを考えました。

この原因となる部分に関しては、
世間にあるアプリを見ても各社さまざまな調整がされており差が発生している部分であり、
こういった部分が人間が考慮したうえで調整を行う必要があります。

次回はこの問題をCodexに依頼することで修正していきます。

参考記事

生成AIと作るリアルタイム音声ビジュアライザー (準備編)

一覧に戻る

contact

お問い合わせ

サービスに関するお問い合わせはこちら

採用・求人に関する情報はこちら