[alsa-devel] io-plugin does not call start callback function
raulxiong at gmail.com
Mon Dec 7 08:18:18 CET 2009
I found it in snd_pcm_ioplug_create, it calls snd_pcm_set_hw_ptr to link
these two pointers. It's clear now.
2009/12/7 Raul Xiong <raulxiong at gmail.com>
> Hi Stefan
> What you said is basically right. I reviewed the code pcm.c in alsa-lib, it
> shows the call procedure. But now I'm a little confused. In
> snd_pcm_avail_update function, it computes with the pcm->hw.ptr value. And
> in the plug-in we will write, only pcm->hw_ptr is updated. But who will link
> these two value and when they are linking. I didn't find it.
> 2009/12/7 Stefan Schoenleitner <dev.c0debabe at gmail.com>
>> Raul Xiong wrote:
>> > Hi Stefan
>> > This is because your pointer callback function is not implemented
>> > "pointer" callback function should return the right position of the
>> > playback/capture buffer, apps over alsa framework will call
>> > snd_pcm_avail_update to get the position.
>> > Also, you should call snd_pcm_ioplug_set_param_minmax in your
>> > play_hw_constraint function to define the buffer size relevant
>> after a full day of experimenting and trying to find out why the start
>> callback function is not called I observed something interesting:
>> It seems that for the io plugin there is an application pointer
>> io->appl_ptr and the hardware pointer io->hw_ptr.
>> Once playback is started, the start callback function is *not* called,
>> but instead data transfer is started immediately.
>> More precisely, each time the pointer callback function is called to get
>> the current position of the hardware pointer and after that the transfer
>> function is called to do the actual data transfer.
>> After each call of the transfer function the number of transfered frames
>> is returned (i.e. the number of frames that have been written to some
>> buffer we would like to fill behind a file descriptor).
>> However, as data transfers have to be timed precisely, we can not just
>> increment the hw_ptr from inside the transfer callback function.
>> If the hw_ptr is not touched at all (thus it stays 0 at all times), a
>> few more transfers are performed until the application pointer appl_ptr
>> has reached a certain (high) amount of "transfered" frames.
>> Then, which is most interesting, the start callback function *is* called
>> followed by calls to the pointer and polling/revent callback functions.
>> As I am not incrementing the hw_ptr at any place right now, the revent
>> polling function is called endlessly.
>> After a full day of even more experiments I think I know how it is
>> supposed to work:
>> In the beginning a certain amount of frames (I guess this is the
>> "start_threshold") is transfered (or more precisely prefilled in the
>> output buffer).
>> As soon as this start threshold is reached the start callback function
>> is called and alsa waits until the hardware pointer hw_ptr has reached a
>> certain position so that the next data transfers can be performed.
>> For this reason it seems that the hw_ptr can be seen as the pointer that
>> indicates how many frames already have been received (and maybe even
>> processed) at the receiving end.
>> Besides it also polls the filedescriptor(s) to check if the next data
>> transfers can be performed (without blocking actually).
>> At the moment I'm not sure if my assumptions above are close enough to
>> reality, but at least I think that I understand what is going on now.
>> If something like this would have been in the alsa documentation I guess
>> it would have saved me like a week of work.
More information about the Alsa-devel