0

誰かが ALSA ドライバーの使用を安全に停止する方法を説明できますか? 私は snd_pcm_writei() を使用して、ALSA リング バッファーに "期間" バッファー サイズのチャンクで書き込みます。かなり単純です。書き込み後、すべてのサンプルがリング バッファー (ドライバー内) から再生された後に終了する必要があるという点で、安全に終了するのが難しいことがわかりました。

再生後、残りのリング バッファーを再生する必要があるため、ストリームがまだ SND_PCM_STATE_RUNNING 状態 (enum 3) であることがわかりました。だから私は状態をプールしようとしました

do
{
    err = snd_pcm_state(handle);
}while(err==3);

printf("\nDone.\n\n"); // never gets here

わかりました、オーディオ ストリームを排出する関数があります。

snd_pcm_drain(handle);
    do
    {
        err = snd_pcm_state(handle);
    }while(err==3);

    printf("\nDone.\n\n");

これはコード 1 で終わります。これは、SND_PCM_STATE_SETUP が STOP などではないことを意味します。とにかく、ストリームは最後まで再生されません。テストする唯一の方法は、

while(1);

これにより、オーディオ全体が確実に再生されます。何かご意見は?

よろしくお願いします。

問題を発見しましたが、解決するには支援が必要です:

関数 snd_pcm_writei() には const void* バッファーが必要で、動的に割り当てられたバッファーを使用します。

snd_pcm_sframes_t snd_pcm_writei    (   snd_pcm_t *     pcm,
        const void *    buffer,
        snd_pcm_uframes_t   size 
    ) 

frames = snd_pcm_writei (handle, buff, period_size);

static short buf[240]; // this works

// this is not working
if ((buff = calloc(0,period_size)) == NULL) {
        printf("No enough memory for period buffer\n");
        exit(EXIT_FAILURE);
}   

動的に割り当てられたバッファで snd_pcm_writei() を使用する方法について何か考えはありますか?

4

1 に答える 1

0

バッファが再生されるのを待つにはsnd_pcm_drain、ブロッキング モードで呼び出す必要があります。つまり、snd_pcm_nonblock(handle, 0)前に呼び出す必要があります。

の 1 つのパラメーターcallocを 0 に設定すると、0 バイトが割り当てられます。1 周期のサンプル データを保持できるバッファを割り当てるには、 を使用しますcalloc(period_size, frame_size)

于 2013-08-09T16:32:25.623 に答える