A machine to gather up arbitrary frames and convert them to raw slinear on demand. More...
#include "asterisk/format.h"

Go to the source code of this file.
Data Structures | |
| struct | ast_slinfactory |
Defines | |
| #define | AST_SLINFACTORY_MAX_HOLD 1280 |
Functions | |
| unsigned int | ast_slinfactory_available (const struct ast_slinfactory *sf) |
| Retrieve number of samples currently in a slinfactory. | |
| void | ast_slinfactory_destroy (struct ast_slinfactory *sf) |
| Destroy the contents of a slinfactory. | |
| int | ast_slinfactory_feed (struct ast_slinfactory *sf, struct ast_frame *f) |
| Feed audio into a slinfactory. | |
| void | ast_slinfactory_flush (struct ast_slinfactory *sf) |
| Flush the contents of a slinfactory. | |
| void | ast_slinfactory_init (struct ast_slinfactory *sf) |
| Initialize a slinfactory. | |
| int | ast_slinfactory_init_with_format (struct ast_slinfactory *sf, const struct ast_format *slin_out) |
| Initialize a slinfactory. | |
| int | ast_slinfactory_read (struct ast_slinfactory *sf, short *buf, size_t samples) |
| Read samples from a slinfactory. | |
A machine to gather up arbitrary frames and convert them to raw slinear on demand.
Definition in file slinfactory.h.
| #define AST_SLINFACTORY_MAX_HOLD 1280 |
Definition at line 33 of file slinfactory.h.
Referenced by ast_slinfactory_read().
| unsigned int ast_slinfactory_available | ( | const struct ast_slinfactory * | sf | ) |
Retrieve number of samples currently in a slinfactory.
| sf | The slinfactory to peek into |
Definition at line 193 of file slinfactory.c.
References ast_slinfactory::size.
Referenced by ast_audiohook_write_frame(), audio_audiohook_write_list(), audiohook_read_frame_both(), audiohook_read_frame_single(), softmix_bridge_write(), and softmix_process_read_audio().
{
return sf->size;
}
| void ast_slinfactory_destroy | ( | struct ast_slinfactory * | sf | ) |
Destroy the contents of a slinfactory.
| sf | The slinfactory that is no longer needed |
This function will free any memory allocated for the contents of the slinfactory. It does not free the slinfactory itself. If the sf is malloc'd, then it must be explicitly free'd after calling this function.
Definition at line 58 of file slinfactory.c.
References ast_frfree, AST_LIST_REMOVE_HEAD, ast_translator_free_path(), f, and ast_slinfactory::trans.
Referenced by ast_audiohook_destroy(), audiohook_set_internal_rate(), set_softmix_bridge_data(), and softmix_bridge_leave().
{
struct ast_frame *f;
if (sf->trans) {
ast_translator_free_path(sf->trans);
sf->trans = NULL;
}
while ((f = AST_LIST_REMOVE_HEAD(&sf->queue, frame_list)))
ast_frfree(f);
}
| int ast_slinfactory_feed | ( | struct ast_slinfactory * | sf, |
| struct ast_frame * | f | ||
| ) |
Feed audio into a slinfactory.
| sf | The slinfactory to feed into |
| f | Frame containing audio to feed in |
Definition at line 71 of file slinfactory.c.
References ast_format_cmp(), AST_FORMAT_CMP_NOT_EQUAL, ast_format_copy(), ast_frdup(), ast_frfree, ast_frisolate(), ast_getformatname(), AST_LIST_INSERT_TAIL, AST_LIST_NEXT, AST_LIST_TRAVERSE, ast_log(), ast_translate(), ast_translator_build_path(), ast_translator_free_path(), ast_frame::data, f, ast_slinfactory::format, ast_frame_subclass::format, ast_format::id, LOG_WARNING, ast_slinfactory::output_format, ast_frame::ptr, ast_frame::samples, ast_slinfactory::size, ast_frame::subclass, and ast_slinfactory::trans.
Referenced by ast_audiohook_write_frame(), and softmix_bridge_write().
{
struct ast_frame *begin_frame = f, *duped_frame = NULL, *frame_ptr;
unsigned int x = 0;
/* In some cases, we can be passed a frame which has no data in it, but
* which has a positive number of samples defined. Once such situation is
* when a jitter buffer is in use and the jitter buffer interpolates a frame.
* The frame it produces has data set to NULL, datalen set to 0, and samples
* set to either 160 or 240.
*/
if (!f->data.ptr) {
return 0;
}
if (ast_format_cmp(&f->subclass.format, &sf->output_format) == AST_FORMAT_CMP_NOT_EQUAL) {
if (sf->trans && (ast_format_cmp(&f->subclass.format, &sf->format) == AST_FORMAT_CMP_NOT_EQUAL)) {
ast_translator_free_path(sf->trans);
sf->trans = NULL;
}
if (!sf->trans) {
if (!(sf->trans = ast_translator_build_path(&sf->output_format, &f->subclass.format))) {
ast_log(LOG_WARNING, "Cannot build a path from %s (%d)to %s (%d)\n",
ast_getformatname(&f->subclass.format),
f->subclass.format.id,
ast_getformatname(&sf->output_format),
sf->output_format.id);
return 0;
}
ast_format_copy(&sf->format, &f->subclass.format);
}
if (!(begin_frame = ast_translate(sf->trans, f, 0))) {
return 0;
}
if (!(duped_frame = ast_frisolate(begin_frame))) {
return 0;
}
if (duped_frame != begin_frame) {
ast_frfree(begin_frame);
}
} else {
if (sf->trans) {
ast_translator_free_path(sf->trans);
sf->trans = NULL;
}
if (!(duped_frame = ast_frdup(f)))
return 0;
}
AST_LIST_TRAVERSE(&sf->queue, frame_ptr, frame_list) {
x++;
}
/* if the frame was translated, the translator may have returned multiple
frames, so process each of them
*/
for (begin_frame = duped_frame; begin_frame; begin_frame = AST_LIST_NEXT(begin_frame, frame_list)) {
AST_LIST_INSERT_TAIL(&sf->queue, begin_frame, frame_list);
sf->size += begin_frame->samples;
}
return x;
}
| void ast_slinfactory_flush | ( | struct ast_slinfactory * | sf | ) |
Flush the contents of a slinfactory.
| sf | The slinfactory to flush |
Definition at line 198 of file slinfactory.c.
References ast_frfree, AST_LIST_REMOVE_HEAD, ast_translator_free_path(), ast_slinfactory::hold, ast_slinfactory::holdlen, ast_slinfactory::offset, ast_slinfactory::size, and ast_slinfactory::trans.
Referenced by ast_audiohook_write_frame(), and softmix_bridge_write().
{
struct ast_frame *fr = NULL;
if (sf->trans) {
ast_translator_free_path(sf->trans);
sf->trans = NULL;
}
while ((fr = AST_LIST_REMOVE_HEAD(&sf->queue, frame_list)))
ast_frfree(fr);
sf->size = sf->holdlen = 0;
sf->offset = sf->hold;
return;
}
| void ast_slinfactory_init | ( | struct ast_slinfactory * | sf | ) |
Initialize a slinfactory.
| sf | The slinfactory to initialize |
Definition at line 39 of file slinfactory.c.
References ast_format_set(), AST_FORMAT_SLINEAR, ast_slinfactory::hold, ast_slinfactory::offset, and ast_slinfactory::output_format.
{
memset(sf, 0, sizeof(*sf));
sf->offset = sf->hold;
ast_format_set(&sf->output_format, AST_FORMAT_SLINEAR, 0);
}
| int ast_slinfactory_init_with_format | ( | struct ast_slinfactory * | sf, |
| const struct ast_format * | slin_out | ||
| ) |
Initialize a slinfactory.
| sf | The slinfactory to initialize |
| slin_out | the slinear output format desired. |
Definition at line 46 of file slinfactory.c.
References ast_format_copy(), ast_format_is_slinear(), ast_slinfactory::hold, ast_slinfactory::offset, and ast_slinfactory::output_format.
Referenced by audiohook_set_internal_rate(), and set_softmix_bridge_data().
{
memset(sf, 0, sizeof(*sf));
sf->offset = sf->hold;
if (!ast_format_is_slinear(slin_out)) {
return -1;
}
ast_format_copy(&sf->output_format, slin_out);
return 0;
}
| int ast_slinfactory_read | ( | struct ast_slinfactory * | sf, |
| short * | buf, | ||
| size_t | samples | ||
| ) |
Read samples from a slinfactory.
| sf | The slinfactory to read from |
| buf | Buffer to put samples into |
| samples | Number of samples wanted |
Definition at line 139 of file slinfactory.c.
References ast_frfree, AST_LIST_REMOVE_HEAD, AST_SLINFACTORY_MAX_HOLD, ast_frame::data, ast_slinfactory::hold, ast_slinfactory::holdlen, ast_slinfactory::offset, ast_frame::offset, ast_frame::ptr, ast_frame::samples, and ast_slinfactory::size.
Referenced by audio_audiohook_write_list(), audiohook_read_frame_both(), audiohook_read_frame_single(), and softmix_process_read_audio().
{
struct ast_frame *frame_ptr;
unsigned int sofar = 0, ineed, remain;
short *frame_data, *offset = buf;
while (sofar < samples) {
ineed = samples - sofar;
if (sf->holdlen) {
if (sf->holdlen <= ineed) {
memcpy(offset, sf->offset, sf->holdlen * sizeof(*offset));
sofar += sf->holdlen;
offset += sf->holdlen;
sf->holdlen = 0;
sf->offset = sf->hold;
} else {
remain = sf->holdlen - ineed;
memcpy(offset, sf->offset, ineed * sizeof(*offset));
sofar += ineed;
sf->offset += ineed;
sf->holdlen = remain;
}
continue;
}
if ((frame_ptr = AST_LIST_REMOVE_HEAD(&sf->queue, frame_list))) {
frame_data = frame_ptr->data.ptr;
if (frame_ptr->samples <= ineed) {
memcpy(offset, frame_data, frame_ptr->samples * sizeof(*offset));
sofar += frame_ptr->samples;
offset += frame_ptr->samples;
} else {
remain = frame_ptr->samples - ineed;
memcpy(offset, frame_data, ineed * sizeof(*offset));
sofar += ineed;
frame_data += ineed;
if (remain > (AST_SLINFACTORY_MAX_HOLD - sf->holdlen)) {
remain = AST_SLINFACTORY_MAX_HOLD - sf->holdlen;
}
memcpy(sf->hold, frame_data, remain * sizeof(*offset));
sf->holdlen = remain;
}
ast_frfree(frame_ptr);
} else {
break;
}
}
sf->size -= sofar;
return sofar;
}