From 6b2a929ca7743da84148b18ed6519ce91d0b9680 Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 28 Feb 2014 00:56:10 +0100 Subject: ao: document some functions --- audio/out/ao.c | 23 +++++++++++++++++++++++ audio/out/ao.h | 15 ++++++++++++--- 2 files changed, 35 insertions(+), 3 deletions(-) (limited to 'audio') diff --git a/audio/out/ao.c b/audio/out/ao.c index 8f70865afa..02415b0f2d 100644 --- a/audio/out/ao.c +++ b/audio/out/ao.c @@ -209,12 +209,21 @@ done: return ao; } +// Uninitialize and destroy the AO. +// cut_audio: if false, block until all remaining audio was played. void ao_uninit(struct ao *ao, bool cut_audio) { ao->driver->uninit(ao, cut_audio); talloc_free(ao); } +// Queue the given audio data. Start playback if it hasn't started yet. Return +// the number of samples that was accepted (the core will try to queue the rest +// again later). Should never block. +// data: start pointer for each plane. If the audio data is packed, only +// data[0] is valid, otherwise there is a plane for each channel. +// samples: size of the audio data (see ao->sstride) +// flags: currently AOPLAY_FINAL_CHUNK can be set int ao_play(struct ao *ao, void **data, int samples, int flags) { return ao->driver->play(ao, data, samples, flags); @@ -227,6 +236,11 @@ int ao_control(struct ao *ao, enum aocontrol cmd, void *arg) return CONTROL_UNKNOWN; } +// Return size of the buffered data in seconds. Can include the device latency. +// Basically, this returns how much data there is still to play, and how long +// it takes until the last sample in the buffer reaches the speakers. This is +// used for audio/video synchronization, so it's very important to implement +// this correctly. double ao_get_delay(struct ao *ao) { if (!ao->driver->get_delay) { @@ -236,23 +250,32 @@ double ao_get_delay(struct ao *ao) return ao->driver->get_delay(ao); } +// Return free size of the internal audio buffer. This controls how much audio +// the core should decode and try to queue with ao_play(). int ao_get_space(struct ao *ao) { return ao->driver->get_space(ao); } +// Stop playback and empty buffers. Essentially go back to the state after +// ao->init(). void ao_reset(struct ao *ao) { if (ao->driver->reset) ao->driver->reset(ao); } +// Pause playback. Keep the current buffer. ao_get_delay() must return the +// same value as before pausing. void ao_pause(struct ao *ao) { if (ao->driver->pause) ao->driver->pause(ao); } +// Resume playback. Play the remaining buffer. If the driver doesn't support +// pausing, it has to work around this and e.g. use ao_play_silence() to fill +// the lost audio. void ao_resume(struct ao *ao) { if (ao->driver->resume) diff --git a/audio/out/ao.h b/audio/out/ao.h index 81737e094d..73a7cdfa61 100644 --- a/audio/out/ao.h +++ b/audio/out/ao.h @@ -38,6 +38,8 @@ enum aocontrol { AOCONTROL_UPDATE_STREAM_TITLE, }; +// If set, then the queued audio data is the last. Note that after a while, new +// data might be written again, instead of closing the AO. #define AOPLAY_FINAL_CHUNK 1 typedef struct ao_control_vol { @@ -48,11 +50,18 @@ typedef struct ao_control_vol { struct ao; struct ao_driver { + // If true, use with encoding only. bool encode; + // Name used for --ao. const char *name; + // Description shown with --ao=help. const char *description; - int (*control)(struct ao *ao, enum aocontrol cmd, void *arg); + // Init the device using ao->format/ao->channels/ao->samplerate. If the + // device doesn't accept these parameters, you can attempt to negotiate + // fallback parameters, and set the ao format fields accordingly. int (*init)(struct ao *ao); + // See ao_control() etc. in ao.c + int (*control)(struct ao *ao, enum aocontrol cmd, void *arg); void (*uninit)(struct ao *ao, bool cut_audio); void (*reset)(struct ao*ao); int (*get_space)(struct ao *ao); @@ -71,7 +80,7 @@ struct ao_driver { struct ao { int samplerate; struct mp_chmap channels; - int format; + int format; // one of AF_FORMAT_... int bps; // bytes per second int sstride; // size of a sample on each plane // (format_size*num_channels/num_planes) @@ -80,7 +89,7 @@ struct ao { int buffer_playable_samples;// part of the part of the buffer the AO hasn't // accepted yet with play() bool probing; // if true, don't fail loudly on init - bool untimed; + bool untimed; // don't assume realtime playback bool no_persistent_volume; // the AO does the equivalent of af_volume bool per_application_mixer; // like above, but volume persists (per app) const struct ao_driver *driver; -- cgit v1.2.3