libdragon
|
Sample buffer. More...
Macros | |
#define | MIXER_TRACE 0 |
Set to 1 to activate debug logs. | |
#define | tracef(fmt, ...) ({ }) |
like debugf(), but writes only if MIXER_TRACE is not 0 | |
Functions | |
void | samplebuffer_init (samplebuffer_t *buf, uint8_t *uncached_mem, int nbytes) |
void | samplebuffer_set_bps (samplebuffer_t *buf, int bits_per_sample) |
Configure the bit width of the samples stored in the buffer. | |
void | samplebuffer_set_waveform (samplebuffer_t *buf, WaveformRead read, void *ctx) |
bool | samplebuffer_is_inited (samplebuffer_t *buf) |
Return true if the samplebuffer is initialized. | |
void | samplebuffer_close (samplebuffer_t *buf) |
void * | samplebuffer_get (samplebuffer_t *buf, int wpos, int *wlen) |
Get a pointer to specific set of samples in the buffer (zero-copy). | |
void * | samplebuffer_append (samplebuffer_t *buf, int wlen) |
Append samples into the buffer (zero-copy). | |
void | samplebuffer_undo (samplebuffer_t *buf, int wlen) |
Remove the a specified number of samples from the tail of the buffer. | |
void | samplebuffer_discard (samplebuffer_t *buf, int wpos) |
void | samplebuffer_flush (samplebuffer_t *buf) |
Sample buffer.
void samplebuffer_init | ( | samplebuffer_t * | buf, |
uint8_t * | uncached_mem, | ||
int | size | ||
) |
Initialize the sample buffer by binding it to the specified memory buffer.
The sample buffer is guaranteed to be 8-bytes aligned, so the specified memory buffer must follow this constraint. Moreover, the buffer must be in the uncached segment and not loaded in any CPU cacheline. It is strongly advised to allocate the buffer via malloc_uncached, that takes care of these constraints.
[in] | buf | Sample buffer |
[in] | uncached_mem | Memory buffer to use. Must be 8-byte aligned, and in the uncached segment. |
[in] | size | Size of the memory buffer, in bytes. |
void samplebuffer_set_bps | ( | samplebuffer_t * | buf, |
int | bps | ||
) |
Configure the bit width of the samples stored in the buffer.
Valid values for "bps" are 1, 2, or 4: 1 can be used for 8-bit mono samples, 2 for either 8-bit interleaved stereo or 16-bit mono, and 4 for 16-bit interleaved stereo.
[in] | buf | Sample buffer |
[in] | bps | Bytes per sample. |
void samplebuffer_set_waveform | ( | samplebuffer_t * | buf, |
WaveformRead | read, | ||
void * | ctx | ||
) |
Connect a waveform reader callback to this sample buffer. The waveform will be use to produce samples whenever they are required by the mixer as playback progresses.
"read" is the main decoding function, that is invoked to produce a specified number of samples. Normally, the function is invoked by samplebuffer_get, whenever the mixer requests more samples. See WaveformRead for more information.
[in] | buf | Sample buffer |
[in] | read | Waveform reading function, that produces samples. |
[in] | ctx | Opaque context that will be passed to the read function. |
bool samplebuffer_is_inited | ( | samplebuffer_t * | buf | ) |
Return true if the samplebuffer is initialized.
buf | Sample buffer |
void samplebuffer_close | ( | samplebuffer_t * | buf | ) |
Close the sample buffer.
After calling close, the sample buffer must be initialized again before using it.
[in] | buf | Sample buffer. |
void * samplebuffer_get | ( | samplebuffer_t * | buf, |
int | wpos, | ||
int * | wlen | ||
) |
Get a pointer to specific set of samples in the buffer (zero-copy).
"wpos" is the absolute waveform position of the first sample that the caller needs access to. "wlen" is the number of requested samples.
The function returns a pointer within the sample buffer where the samples should be read, and optionally changes "wlen" with the maximum number of samples that can be read. "wlen" is always less or equal to the requested value.
If the samples are available in the buffer, they will be returned immediately. Otherwise, if the samplebuffer has a sample decoder registered via samplebuffer_set_decoder, the decoder "read" function is called once to produce the samples.
If "wlen" is changed with a value less than "wlen", it means that not all samples were available in the buffer and it was not possible to generate more, so the caller should not loop calling this function, but rather use what was obtained and possibly pad with silence.
[in] | buf | Sample buffer |
[in] | wpos | Absolute waveform position of the first samples to return. |
[in,out] | wlen | Number of samples to return. After return, it is modified with the actual number of samples that have been returned. |
void * samplebuffer_append | ( | samplebuffer_t * | buf, |
int | wlen | ||
) |
Append samples into the buffer (zero-copy).
"wlen" is the number of samples that the caller will append.
The function returns a pointer within the sample buffer where the samples should be written. The samples to be written to physical memory, not just CPU cache, and to enforce this, the function returns a pointer in the uncached segment. Most of the times, we expect samples to be generated or manipulated via RSP/DMA anyway.
The function is meant only to "append" samples, as in add samples that are consecutive within the waveform to the ones already stored in the sample buffer. This is necessary because samplebuffer_t can only store a single range of samples of the waveform; there is no way to hold two disjoint ranges.
For instance, if the sample buffer currently contains 50 samples starting from position 100 in the waverform, the next call to samplebuffer_append will append samples starting at 150.
If required, samplebuffer_append will discard older samples to make space for the new ones, through samplebuffer_discard. It will only discard samples that come before the "wpos" specified in the last samplebuffer_get call, so to make sure that nothing required for playback is discarded. If there is not enough space in the buffer, it will assert.
[in] | buf | Sample buffer |
[in] | wlen | Number of samples to append. |
void samplebuffer_undo | ( | samplebuffer_t * | buf, |
int | wlen | ||
) |
Remove the a specified number of samples from the tail of the buffer.
This function removes the last wlen samples from the buffer. It can be used to revert the behavior of a samplebuffer_append call, if the data written to the buffer was too much.
A common situation is an implementation of a waveform codec with fixed audio frames. The last frame at the end of the waveform will likely need to be truncated, but the compressor would have likely padded it with zeros to make it the same size as the others. In this case, at playing time, it is possible to call samplebuffer_append to append the whole frame, but then remove the unneeded padding with a call to samplebuffer_undo.
buf | Sample buffer |
wlen | Number of samples to remove |
void samplebuffer_discard | ( | samplebuffer_t * | buf, |
int | wpos | ||
) |
Discard all samples from the buffer that come before a specified absolute waveform position.
This function can be used to discard samples that are not needed anymore in the sample buffer. "wpos" specifies the absolute position of the first sample that should be kept: all samples that come before will be discarded. This function will silently do nothing if there are no samples to discard.
[in] | buf | Sample buffer |
[in] | wpos | Absolute waveform position of the first sample that must be kept. |
void samplebuffer_flush | ( | samplebuffer_t * | buf | ) |
Flush (reset) the sample buffer to empty status, discarding all samples.
[in] | buf | Sample buffer. |