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

はじめに

前回(生成AIと作るリアルタイム音声ビジュアライザー (実装編))では、
実際にCodexにプロンプトを渡して、実機で動作するアプリを作成出来ましたが、
スペクトラムバーの表示に納得行かない部分が発生しました。

今回の記事ではその原因を元に、対応方法を考えCodexに依頼して修正していきます。

前回まとめた原因

FFT(高速フーリエ変換:Fast Fourier Transform)の出力は、
そのまま使用すると非常に変動が大きく、フレームごとに値が大きく上下します。

マイク入力では、

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

などもすべて数値として現れるため、
そのまま表示するとスペクトラムが過敏に反応してしまうことがあります。

多くの実装では次のような処理が行われているので、同様の処理をCodexに依頼して修正していきます。

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

Codexに安定化を依頼する

それではCodexに対して表示の安定化を依頼するプロンプトを作成していきます。

ここで重要なのは、AIに対して「全面的な書き直し」を依頼しないことです。

今回のコードはすでに、

  • マイク入力の取得
  • FFT解析
  • SwiftUIによる表示

といった基本構造は正しく動作しています。

そのため、コードをすべて作り直すのではなく、

  • 平滑化の追加
  • ノイズの抑制
  • 正規化の改善

といった 局所的な修正のみを依頼する方針にします。

AIに修正を依頼する際は、このように 変更範囲を明確に指定することが重要です。

もし「改善してください」とだけ書くと、AIが

  • アーキテクチャを変更する
  • ファイル構成を変える
  • 不要な抽象化を追加する

といった大きな変更を行ってしまうことがあります。

今回はそうした事態を避けるため、既存構造を維持したまま表示を安定化させるように依頼します。

修正を依頼したプロンプト

今回Codexには次のような指示を渡しました。

The app builds and runs correctly, and microphone input is being captured. However, the spectrum bars are too unstable and flicker heavily.

Please improve the current implementation by:
 • increasing smoothing for the spectrum values
 • adding a simple noise floor threshold to suppress very small fluctuations
 • improving normalization so the bars are visually more stable
 • aggregating FFT bins into display bars more smoothly if needed

Constraints:
 • keep the current architecture
 • do not rewrite the whole project
 • preserve SwiftUI + AVAudioEngine + Accelerate
 • keep the implementation simple and educational
 • show focused code changes only
 • briefly explain why each change improves visual stability

上記のプロンプトでは、次の点を意識しています。

現在の状態を明確に伝える

  • ビルドは成功している
  • 音声入力は取得できている

という状態を明示しています。

これにより、AIが不要な部分を作り直す可能性を減らします。

修正内容を具体的に指定する

今回の問題に対して必要な処理は、主に次の3つです。

  • 平滑化(Smoothing)
  • ノイズ除去(Noise Floor)
  • 正規化(Normalization)

この3点を明確に指定することで、AIが意図した方向に修正を行いやすくなります。

変更範囲を制限する

特に重要なのが次の部分です。

keep the current architecture do not rewrite the whole project

AIに対してこの制約を入れておかないと、既存コードを大きく変更してしまうことがあります。
今回は 安定化だけを行うことが目的なので、アーキテクチャは維持するように指示しています。

修正後の動作確認

Codexによる修正を適用したあと、再度ビルドと動作確認を行いました。

結果として、ビルドは引き続き成功し、アプリの基本機能も問題なく動作しています。

  • ビルド結果:BUILD SUCCEEDED
  • アプリ起動:正常
  • マイク入力:正常に取得
  • スペクトラム表示:安定化

修正前の状態では、スペクトラムバーがフレームごとに激しく揺れてしまい、
無音に近い状態でも細かい変動が発生していました。

しかし今回の修正によって、

  • バーの動きが滑らかになった
  • 無音時の微小な揺れがほぼ消えた
  • 音量の変化に対する反応が自然になった

といった改善が確認できました。

特に効果が大きかったのは、次の処理です。

  • 上昇・下降で異なる係数を使う時間的平滑化
  • ノイズフロアによる微小入力の抑制
  • 動的正規化によるスケールの安定化
  • FFTビンの平均化と空間的平滑化

これらの処理により、
スペクトラム表示はリアルタイム音声ビジュアライザーとして十分に安定した挙動になりました。

初回生成のコードでも基本機能は成立していましたが、
今回の調整によって 実際に見やすいスペクトラム表示 に近づいた形になります。

しかし、自分の環境ではまだ雑音が入っているのか左側のバーが常に動いているため
更に修正を加えます。

追加調整:環境ノイズへの対策

前節の修正により、スペクトラム表示はかなり安定しました。
バーの動きも滑らかになり、無音時の微小な揺れも大幅に減っています。

しかし実際にアプリを動かしてみると、
完全な無音状態でもわずかにバーが反応することが確認できました。

これはバグというより、音声入力を扱うアプリではよくある現象です。

マイク入力には、

  • マイク自体のノイズ
  • 空調やPCファンなどの環境音
  • A/D変換時の量子化ノイズ

などが含まれるため、完全なゼロ値になることはほとんどありません。

そのため、FFT解析を行うと
人間には聞こえないレベルのノイズでもスペクトラムに現れることがあります。

今回の実装でも、ノイズフロアを導入していましたが、
実機環境ではまだわずかな変動が残っていました。

そこで追加の対策として、

  • ノイズフロアを少し引き上げる
  • 低レベル入力をより強く抑制する

という調整を行いました。

ノイズフロアの調整

修正前は次の値を使用していました。

noiseFloorDb = -62

この値をやや高めに設定することで、環境ノイズの影響をさらに抑えることができます。

例えば次のように調整します。

noiseFloorDb = -25

この変更により、

  • 小さすぎる入力はスペクトラムに表示されない
  • 無音時のバーの揺れがほぼ消える

という効果が得られました。

実装で重要なポイント

音声ビジュアライザーでは、解析結果の正確さよりも視覚的な安定性が重要になる場合があります。

そのため多くの実装では、

  • ノイズフロア
  • 平滑化
  • 正規化
  • バンド平均化

といった処理を組み合わせて、見やすいスペクトラム表示を作っています。

追加調整:ノイズフロア変更による副作用

前節では環境ノイズの影響を減らすためにノイズフロアを引き上げました。
実機環境でテストした結果、ノイズフロアを -12 dB に設定すると、
ほとんどの環境ノイズを抑えることができました。

この変更により次の改善が確認できました。

  • 無音状態でのバーの揺れがほぼ消える
  • PCファンや空調などの微小ノイズを拾わない
  • スペクトラム表示がより安定する

音声解析では、FFTによって音声を周波数成分に分解しますが、
マイク入力には必ず微小な環境ノイズが含まれます。
これらのノイズは周波数領域でも小さな揺らぎとして現れるため、
可視化では微小なバーの動きとして表示されることがあります。

このような問題を防ぐため、一定以下のレベルを無視する ノイズフロア処理 を導入しました。


発生した問題

しかし、この調整には副作用がありました。

ノイズフロアを高く設定したことで、スペクトラム表示に次の変化が現れました。

  • バーが全体的に高い位置に集中する
  • 周波数ごとの差が小さくなる
  • スペクトラムの形状が分かりにくくなる

つまり、ノイズは抑えられたものの、
スペクトラムのダイナミックレンジが圧縮されてしまった状態です。

今回の実装では、FFT結果をデシベル値へ変換し、
その値を一定の範囲で正規化してバーの高さへ変換しています。

ノイズフロアを大きく変更すると、

  • 最小値が上がる
  • 正規化範囲が狭くなる
  • 全体の値が上側へ寄る

という現象が発生します。

その結果、スペクトラムバーが 高い位置でまとまる表示 になってしまいました。


対応方針

この問題を解決するため、次の調整を行うことにしました。

  • 正規化レンジの再調整
  • ノイズフロア適用後のスケーリング改善
  • スペクトラム分布を自然にする補正

つまり

  • ノイズは抑える
  • スペクトラムの形状は維持する

というバランスを取る形です。


Codexへの修正依頼

この調整はアルゴリズムの細かい部分に関係するため、
既存のコード構造を維持したまま 局所的な修正 をCodexへ依頼しました。

実際に渡したプロンプトは次の通りです。

The app runs correctly and the noise floor adjustment successfully suppresses ambient noise.  
However, after setting the noise floor to -12 dB, the spectrum bars tend to cluster at high positions and the spectral shape becomes less distinguishable.

Please improve the normalization and scaling so that:

- the bars use a wider dynamic range  
- spectral differences between frequency bands remain visible  
- the spectrum does not collapse into a narrow high-level band  

Constraints:

- keep the current architecture  
- preserve SwiftUI + AVAudioEngine + Accelerate  
- do not rewrite the project  
- adjust normalization or scaling logic only  
- keep the implementation simple and suitable for educational purposes  

Briefly explain the reasoning behind the changes.

AIとの反復改善

今回のケースは、AIを使った開発の特徴がよく表れている例です。

初回生成では

  • 音声入力
  • FFT解析
  • スペクトラム表示

といった基本機能は問題なく実装されていました。

しかし実際にアプリを動かしてみると、

  • ノイズ抑制
  • 正規化のバランス
  • 視覚的な分かりやすさ

といった 体験品質に関わる部分は、細かな調整が必要でした。

そのため今回の開発では

AIが土台を生成する

実機で挙動を確認する

問題を整理する

AIに局所的修正を依頼する

という反復プロセスで改善を進めています。

まとめ

今回は SwiftUI・AVAudioEngine・Accelerate を使った
リアルタイム音声ビジュアライザーのサンプルアプリを、Codexと協力して作成しました。

開発の流れを振り返ると、次のようなステップで進んでいます。

  • SwiftUIプロジェクトを作成
  • マイク権限を設定
  • Codexに実装を依頼
  • 初回生成コードをビルドして動作確認
  • スペクトラム表示の不安定さを修正
  • ノイズフロアを導入して環境ノイズを抑制
  • 正規化やスケーリングを調整して表示品質を改善

初回生成の段階でも、Codexは

  • 音声入力の取得
  • FFTによる周波数解析
  • SwiftUIによるスペクトラム表示

といった基本機能を正しく実装していました。

しかし実際にアプリを動かしてみると、

  • バーの揺れ
  • 環境ノイズの影響
  • 正規化による表示バランス

など、動作品質に関する細かな問題が見えてきます。

今回の開発では、

AIが土台を生成する

人間が実機で挙動を確認する

問題点を整理する

AIに局所的な修正を依頼する

という 反復的な開発プロセスで改善を進めました。

これは実際の開発でもよく見られるスタイルで、
AIを「自動コード生成ツール」として使うというよりも、

設計や問題分析を人間が行い、実装の補助をAIに任せる

という役割分担で作業を進めるものです。

昨今、すべてをAIAgentに任せて最終製品を作れるという記事は増えていますが、
結局の所、最終的な製品の調整は人間が担う事になります。

その時、どういった制限をプロンプトにいれながら進めれば破綻しないのか、
といった部分の理解の一助になれば幸いです。

参考記事

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

一覧に戻る

contact

お問い合わせ

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

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