コンテンツにスキップ

Audio Serverとバッファリング

オーディオインターフェースと製品での利用方法をオーディオ概要で確認した後に、本ページを参照してください。アプリケーションコード、Audio Serverのセッション、DMAバッファー、ハードウェアのオーディオ経路が実行時にどう連携するかを説明します。

SDK固有の動作範囲: 以下のAPI仕様は、SiFli SDKの現行SF32LB52x向けドキュメントに記載された内容です。実際に使用する製品ファミリーとSDKリリースのaudio_server.h、実装、設定を確認してください。バッファーサイズ、スケジューリング、キャッシュ管理に関する記述はエンジニアリング上の指針であり、全ターゲットで同じ動作やバッファー所有権が保証されるわけではありません。

セッションの責務分担

アプリケーション側の制御方針とストリーミング処理を分けてください。再生・録音の開始や停止、状態の変更はアプリケーションが判断し、Audio Serverがセッションを調整します。DMAはサンプルブロックを転送し、ドライバーはハードウェアを設定します。ストリーム動作中に、UI、Bluetoothコールバック、ファイルシステムの読み取り処理からコーデックレジスターを直接操作しないでください。

表: バッファーの所有権
責任境界 担当 確認項目
ソースデータ アプリケーション、デコーダー、またはストレージタスク 再生キューが空になる前にデータを補充できるか。
Audio Serverの書き込みキャッシュ(設定時) Audio Server(サイズはアプリケーション側で設定) write_cache_sizeが対象SDKで有効な値か。アプリケーションがaudio_write()のすべての戻り値を処理しているか。
転送中のバッファー DMA/オーディオドライバー 転送中、バッファーは安定し、キャッシュ整合性が保たれているか。
転送完了後のバッファー アプリケーションまたは処理タスク DMAが同じ領域を再利用する前に、再生データの補充または収録データの処理が完了するか。
セッション状態 Audio Serverとアプリケーションポリシー 開始、停止、エラー処理、終了の要求が繰り返されても、二重クローズやリソースの二重解放を防げるか。

バッファー戦略を選ぶ

ドライバーが対応していれば、ダブルバッファリングが実用的な出発点になります。DMAが一方の領域を転送している間に、ソフトウェアはもう一方で再生データを準備するか、収録済みのデータを処理します。アプリケーションのPCMキューとドライバーのDMAバッファーは区別してください。Audio Serverへの書き込みが、そのままゼロコピーのDMA転送になるとは限りません。

ストレージのレイテンシ、デコード時間、Bluetooth転送のジッター、スケジューリングのばらつきに対応するために必要な場合のみ、キュー容量を増やします。容量はメモリーを消費しますが、待ち時間を決めるのは実際にキューに入っている音声データの量です。バッファーを追加で確保するだけで、レイテンシが必ず増えるわけではありません。オーディオ概要のフレーム単位の計算では、チャネル数と各サンプルの格納バイト数を考慮してください。

ブロック時間、準備または処理にかかる最悪時間、許容するエンドツーエンドのレイテンシを測定します。各処理の期限は、対象ドライバーが通知するバッファー補充と転送完了、およびバッファー再利用の順序に基づいて決めてください。半転送・全転送コールバックがある場合は、その切り替わりに合わせて処理をスケジュールし、現在の転送終了だけを唯一の期限としないでください。再生データはDMAが必要とする前に用意し、収録データはDMAが上書きする前に処理またはコピーします。スケジューリングの余裕を確保し、まれなアンダーランやオーバーランも原因を調査してください。

アプリケーションまたはドライバーがDMAに直接渡すメモリーについては、対象プラットフォームのキャッシュ管理と所有権の規則に従います。CPUが書き込んだ再生データをDMAが読む前に、必要な場合は変更済みのキャッシュラインをメモリーへ書き戻し(クリーン)、受信バッファーも指定された手順で準備します。対象が要求する場合は、収録完了後にキャッシュを無効化してからCPUで読みます。これらの要件はSoC、メモリー領域、ドライバーAPIによって異なります。APIで求められていないのに、Audio Serverやドライバーが所有するバッファーを手動でキャッシュ管理しないでください。DMAが所有する領域を変更、解放、再利用してはいけません。

SF32LB52x向けAudio Serverドキュメントによると、コールバックはAudio Serverのスレッドで実行されます。audio_open()のコールバック内ではaudio_close()を呼び出してはいけません。呼び出すとデッドロックを招く可能性があります。コールバックは短時間で完了させ、ブロッキングするストレージアクセスや処理はワーカースレッドに通知してください。録音コールバックには1フレーム分のデータポインターと長さが渡されますが、引用したドキュメントでは、コールバック終了後もポインターが有効かどうかは規定されていません。対象SDKがより長い有効期間を明示していない限り、コールバックから戻る前にデータをコピーしてください。

SF32LB52x向けの同ドキュメントには、audio_write()の戻り値が次のように記載されています。

表: audio_write() の戻り値(SF32LB52x SDKドキュメント)
戻り値 ドキュメントに記載された意味
> 0 戻り値はdata_lenと等しく、データは書き込みキャッシュに格納されています。
0 書き込みキャッシュが満杯です。要求サイズが設定済みキャッシュ容量を超える場合も、データは書き込まれず0が返ります。
-1 クライアントが一時停止または中断中で、送信データは破棄されます。
-2 パラメーターが無効です。

このAPIでは、write_cache_sizeの上限は0x7FFFバイトで、ping-pong形式で書き込む場合は1回のaudio_write()のデータ量の2倍以上にすることが推奨されています。これはAudio Serverのソフトウェア書き込みキャッシュであり、ドライバーの物理DMAバッファー配置を保証するものではありません。これらの制限を適用する前に、対象ファミリーのSDKを確認してください。クライアントの優先度、ミキシング、利用可能なオーディオ経路もSDK設定に依存します。セッションを開けても、チップの全オーディオインターフェースがAudio Serverに接続されているとは限りません。

製品負荷の下で検証する

ディスプレイ更新、Bluetoothの通知やオーディオ、ストレージの読み書き、ログ記録、低消費電力状態への遷移など、製品で同時に動く処理と組み合わせてテストします。再生のアンダーラン、録音のオーバーラン、キュー使用量、コールバックからワーカー実行までの遅延、音切れ、再接続、スリープとウェイクの遷移を記録してください。優先度による割り込み、中断と再開、起動失敗、停止要求の繰り返しも試し、データ損失を見逃さず、意図した復旧方針どおりに動くことを確認します。

終了時はドライバーの転送が停止し、未処理のコールバックが解放済みバッファーにアクセスしないことを確認します。ハードウェアの手順に従って、オーディオ関連の電源管理要求を解除し、外付け部品を停止してください。システムの電力検証は低消費電力設計の概要、無線との共存はBluetooth概要を参照してください。

最終更新: