2009年7月23日

[alsa-user] Re: ALSA ドライバについて

At Wed, 22 Jul 2009 18:02:19 +0900,
Kuninori Morimoto wrote:
>
>
> ALSA 向けのサウンドドライバを開発しています
> 森本と申します
>
> 現在解決できない問題を抱えており,

> いろいろ調べましたが分からなかったので質問させて下さい
>
> 現在,SH アーキテクチャを使っており
> 内臓のモジュールを使って音を出そうとしてます
>
> プレイヤーには aplay を使用していて,
> 音データには wav を使用しています
>
> とりあえず音は出る状況まで来ていますが,
> 再生してみると
>
> underrun!!! (at least 0.000 ms long)
> underrun!!! (at least 0.000 ms long)
> underrun!!! (at least 0.000 ms long)
> underrun!!! (at least 0.000 ms long)
>
> と出てきて,
> 0.000 ms の部分が一向に変化する様子がありません
>
> aplay のソースを見てみましたが,
> snd_pcm_status_get_state 関数の戻り値がどうやって
> 変化するかがよく分かりませんでした
>
> また,Linux カーネルの soc-core.c :: soc_pcm_trigger
> で音データが渡されてくるタイミングが遅いために音が
> 途切れ途切れになっています
>
> 私のドライバが原因である事は間違いないと思うのですが,
>
> ・snd_pcm_status_get_state の戻り値はドライバのどの部分に
>  依存して変化するものなのでしょうか?

PCM runtime state は PCM core が管理します。
lowlevel driver に依存しません。
逆に言えば、lowlevel driver で prepare コールバックが呼ばれる時は、
runtime->state が PREPARE に変わる時で、trigger コールバックが呼ばれる
時は RUNNING や SETUP などに変わる時です。

> ・trigger で音データが届くタイミングが遅いのですが,
>  どのようにすれば早くなるのでしょうか?

タイミングの問題は全て lowlevel ドライバの問題です。

> また,ドライバを書いていて,よく分からない箇所なのですが
>
> ・snd_pcm_period_elapsed 関数はどのタイミングで呼び出せば
>  いいのでしょうか?
>  私は trigger 関数で渡ってきた substream 内のデータを
>  すべて転送し終えた段階で呼び出すものだと思っていましたが
>  間違いでしょうか?

snd_pcm_period_elapsed() は設定された period (OSS では fragment と
呼ばれていました) が処理された時点で呼び出します。
「すべて転送」ではありません。
通常、ドライバは period_size 処理後にハードウェア割り込みなどを起こす
ように設定を行います。その割り込みハンドラからこの関数を呼びます。

> ・snd_pcm_ops :: pointer 関数が返す値は
>  trigger 関数で渡ってきた substream のデータをどれだけ
>  転送終了したか? を返すものだと思っていたのですが
>  間違いでしょうか?
>  (素直に転送済みデータ量を bytes_to_frames で返すと
>   aplay が止まってしまいます)

正しくは、転送済みデータ量ではなく、現在演奏または処理中のデータポイン
トを指します。転送 != 処理な点に注意。
また、トータルの値ではなく、ring buffer 内のオフセットです。
ですから、返り値は 0 〜 buffer_size-1 になります。


後は alsa-devel ML にポストしてください。
ASoC だと、それ固有の問題もあり得ますし。
また、ソースコードを添付して頂ければ、より具体的に答えられますので、
次回は添付お願いします。

--
Takashi Iwai <tiwai@xxxxx>


投稿者 xml-rpc : 2009年7月23日 15:01
役に立ちました?:
過去のフィードバック 平均:(0) 総合:(0) 投票回数:(0)
本記事へのTrackback: http://hoop.euqset.org/blog/mt-tb2006.cgi/86896
トラックバック
コメント
コメントする




画像の中に見える文字を入力してください。