8

signed shortALSAを使用してUSBオーディオデバイスから入力を取得し、一連の値としてディスクに書き出そうとしています。私が最終的に得ているのは、ゼロの大きなブロックが点在する有効なデータのように見えるブロックです。バッファが正しく設定されておらず、メモリマッピングが適切に使用されていないと推測しています。

私が試していること:

  • サンプルレート:8K(これはデバイスによって強制されます)
  • バッファサイズ:2048
  • 期間サイズ:512
  • 1つのチャネル

デバイスは正しく開かれているように見え、さまざまなパラメータを受け入れます。いくつかのセットアップの後、ループは次のように実行されます。

snd_pcm_avail_update   
snd_pcm_mmap_begin   
   memcpy data from mmap buffer to array of short   
snd_pcm_mmap_commit   

memcpyは、shortの配列へのポインターであり、パスごとに返されるフレーム数によって増分されます。

この記録が数秒間続いた後、それを閉じて、後続のバッファーを各行の単一の短い値としてディスクに書き込みます。私が期待しているのは、1200〜2300Hzの間で変化するPCMデータの1秒または2秒です。私が得ているのは、ゼロがたくさんあるデータです。

私が疑問に思っているのは、バッファと期間の値は合理的ですか?ALSAからのメモリマップ出力を使用することに成功した人はいますか?

編集:いくつかのコード

const snd_pcm_channel_area_t *areas;  
snd_pcm_uframes_t offset, frames, size;   
short* pCID = (short*)malloc( 50000 * sizeof( short ));  
short* ppCID = pCID;
while( size > 0 )  
{  
   frames = size;  
   snd_pcm_mmap_begin (device, &areas, &offset, &frames);     
   short* pd = (short*)areas[0].addr;   
   memcpy( ppCID, (pd + (offset*sizeof(short))), frames * sizeof( short ));  
   ppCID += frames;  
   snd_pcm_mmap_commit(device, offset, frames);  

   size -= frames;
}

(わかりやすくするためにエラーチェックは削除されました)
すべてが完了したら、pCIDをループしてディスクに書き込みます。1行に1つの値。

4

2 に答える 2

6

ARMのUSBオーディオドライバーには既知のバグがあり、同じバッファーのカーネルとアプリケーションのマップがキャッシュコヒーレントではない可能性があります。

ALSAメモリマッピング関数の使用は、コードがサンプルを別のバッファーにコピーせずに直接処理できる場合にのみ意味があります。それらをコピーする場合は、すでに行っているのとまったく同じことを行っsnd_pcm_readiています。つまり、メモリマッピングを使用しないでください。

キャプチャする場合、バッファサイズはレイテンシに影響を与えないため、オーバーランの可能性を回避するために、バッファサイズをできるだけ大きくする必要があります。

期間サイズを小さくするとレイテンシが低くなりますが、プログラムはリアルタイムに関連することを何も行わないため、期間サイズを大きくすると電力を少し節約できます。

于 2013-02-08T08:28:05.270 に答える
1

ドキュメントから:「この呼び出しの直前にsnd_pcm_avail_update()関数を呼び出す必要があります。そうしないと、この関数は使用可能なフレームの誤った数を返す可能性があります。」問題は、snd_pcm_mmap_beginが使用可能なフレームの数を誤って報告しているため、まだ書き込まれていない領域から読み取っているということだと思います。

また、私は前向きではありませんが、データが得られるまでalsa mmap関数がブロックされるとは思いませんが、ここには表示されていない他のコードでカバーされている可能性があります。これはファイルmmapとはまったく同じではないので、そうだと思い始めないでください。ファンが夢中になり始めてすべてが遅くなった場合、コードがアプリケーションからカーネルコンテキストに切り替わり、読み取られるバイトがゼロになると再び継続的に戻る可能性があります。

前の投稿者が指摘したように、これはとにかくsnd_pcm_readiの完璧なユースケースなので、それを使用してください。

于 2013-02-08T22:34:56.157 に答える