[pulseaudio-discuss] Querying the number of samples played
kevin.mescher at gmail.com
Tue Feb 13 07:08:14 PST 2007
Thanks for the quick response. PulseAudio looks like a very robust API, and
the cross-platform nature makes my job MUCH easier.
I'm going to do a sanity check on my thinking here:
Where each frame is a single sample from one or more channels:
The number of "samples" (in this case, frames) = pa_get_stream_time(...) *
sampling_rate / 1000000
So instead of using info.play.samples, I would use the above formula.
The program was mostly written to play data at an 8kHz sampling rate, so
1000 samples was 325msec. I may adjust it to try and load 325msec of data,
no matter what the sampling rate is. I may use the stream latency to adjust
the amount to send.
Should I use PA_STREAM_INTERPOLATE_TIMING and PA_STREAM_AUTO_TIMING_UPDATE
to save on network traffic?
The current model of the application is not very good. Later on, I may
recode to use the pa_mainloop API, and only send data when required.
Currently the model goes like this:
XtAppMainLoop runs the playback procedure every iteration. The playback
procedure has a hard delay built in (I'm guessing) to regulate the speed of
the loop. The playback queries the audio device to see if there less than
1000 samples to be played. If there are, load an additional 1000 samples
and update the waveform marker.
For later development, I'd like to change the model to this:
In the playback procedure, run pa_mainloop_iterate, and use a
pa_stream_write callback to set the "needs more data" flag, rather than
using a sample count method. If the flag is set, send more data, and update
the waveform marker.
When loading data, I would send (325 + msec_latency) msec worth of data. Or
is there a way to calculate the optimum chunk size to send?
On 2/13/07, Pierre Ossman <ossman at cendio.se> wrote:
> Kevin Mescher wrote:
> > The application sent data synchronously to the audio device, and used
> > sample count (accessed via Solaris' info.play.samples) to determine
> > where to
> > put the marker on its waveform display. It was pretty simple, and the
> > logic
> > went:
> The equivalent of info.play.samples is pa_stream_get_time(). Note the
> comments about it though:
> /** Return the current playback/recording time. This is based on the
> * data in the timing info structure returned by
> * pa_stream_get_timing_info(). This function will usually only return
> * new data if a timing info update has been recieved. Only if timing
> * interpolation has been requested (PA_STREAM_INTERPOLATE_TIMING)
> * the data from the last timing update is used for an estimation of
> * the current playback/recording time based on the local time that
> * passed since the timing info structure has been acquired. The time
> * value returned by this function is guaranteed to increase
> * monotonically. (that means: the returned value is always greater or
> * equal to the value returned on the last call) This behaviour can
> * be disabled by using PA_STREAM_NOT_MONOTONOUS. This may be
> * desirable to deal better with bad estimations of transport
> * latencies, but may have strange effects if the application is not
> * able to deal with time going 'backwards'. \since 0.6 */
> > if there are less than 1000 samples remaining to be played (samples sent
> > the value of info.play.samples), send more data.
> Now this is a bad model. 1000 samples is just 23 ms at 44100 Hz, a delay
> that is easily achievable on a network.
> Pierre Ossman OpenSource-based Thin Client Technology
> System Developer Telephone: +46-13-21 46 00
> Cendio AB Web: http://www.cendio.com
> pulseaudio-discuss mailing list
> pulseaudio-discuss at mail.0pointer.de
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the pulseaudio-discuss