A machine to gather up arbitrary frames and convert them to raw slinear on demand. More...
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_rate (struct ast_slinfactory *sf, unsigned int sample_rate) |
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 31 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 196 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(), and softmix_bridge_thread().
00197 { 00198 return sf->size; 00199 }
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 64 of file slinfactory.c.
References ast_frfree, AST_LIST_REMOVE_HEAD, ast_translator_free_path(), f, ast_slinfactory::queue, and ast_slinfactory::trans.
Referenced by ast_audiohook_destroy(), and softmix_bridge_leave().
00065 { 00066 struct ast_frame *f; 00067 00068 if (sf->trans) { 00069 ast_translator_free_path(sf->trans); 00070 sf->trans = NULL; 00071 } 00072 00073 while ((f = AST_LIST_REMOVE_HEAD(&sf->queue, frame_list))) 00074 ast_frfree(f); 00075 }
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 77 of file slinfactory.c.
References 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_subclass::codec, ast_frame::data, ast_slinfactory::format, LOG_WARNING, ast_slinfactory::output_format, ast_frame::ptr, ast_slinfactory::queue, ast_frame::samples, ast_slinfactory::size, ast_frame::subclass, and ast_slinfactory::trans.
Referenced by ast_audiohook_write_frame(), and softmix_bridge_write().
00078 { 00079 struct ast_frame *begin_frame = f, *duped_frame = NULL, *frame_ptr; 00080 unsigned int x = 0; 00081 00082 /* In some cases, we can be passed a frame which has no data in it, but 00083 * which has a positive number of samples defined. Once such situation is 00084 * when a jitter buffer is in use and the jitter buffer interpolates a frame. 00085 * The frame it produces has data set to NULL, datalen set to 0, and samples 00086 * set to either 160 or 240. 00087 */ 00088 if (!f->data.ptr) { 00089 return 0; 00090 } 00091 00092 if (f->subclass.codec != sf->output_format) { 00093 if (sf->trans && f->subclass.codec != sf->format) { 00094 ast_translator_free_path(sf->trans); 00095 sf->trans = NULL; 00096 } 00097 00098 if (!sf->trans) { 00099 if (!(sf->trans = ast_translator_build_path(sf->output_format, f->subclass.codec))) { 00100 ast_log(LOG_WARNING, "Cannot build a path from %s to %s\n", ast_getformatname(f->subclass.codec), 00101 ast_getformatname(sf->output_format)); 00102 return 0; 00103 } 00104 sf->format = f->subclass.codec; 00105 } 00106 00107 if (!(begin_frame = ast_translate(sf->trans, f, 0))) { 00108 return 0; 00109 } 00110 00111 if (!(duped_frame = ast_frisolate(begin_frame))) { 00112 return 0; 00113 } 00114 00115 if (duped_frame != begin_frame) { 00116 ast_frfree(begin_frame); 00117 } 00118 } else { 00119 if (sf->trans) { 00120 ast_translator_free_path(sf->trans); 00121 sf->trans = NULL; 00122 } 00123 if (!(duped_frame = ast_frdup(f))) 00124 return 0; 00125 } 00126 00127 AST_LIST_TRAVERSE(&sf->queue, frame_ptr, frame_list) { 00128 x++; 00129 } 00130 00131 /* if the frame was translated, the translator may have returned multiple 00132 frames, so process each of them 00133 */ 00134 for (begin_frame = duped_frame; begin_frame; begin_frame = AST_LIST_NEXT(begin_frame, frame_list)) { 00135 AST_LIST_INSERT_TAIL(&sf->queue, begin_frame, frame_list); 00136 sf->size += begin_frame->samples; 00137 } 00138 00139 return x; 00140 }
void ast_slinfactory_flush | ( | struct ast_slinfactory * | sf | ) |
Flush the contents of a slinfactory.
sf | The slinfactory to flush |
Definition at line 201 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::queue, ast_slinfactory::size, and ast_slinfactory::trans.
Referenced by ast_audiohook_write_frame().
00202 { 00203 struct ast_frame *fr = NULL; 00204 00205 if (sf->trans) { 00206 ast_translator_free_path(sf->trans); 00207 sf->trans = NULL; 00208 } 00209 00210 while ((fr = AST_LIST_REMOVE_HEAD(&sf->queue, frame_list))) 00211 ast_frfree(fr); 00212 00213 sf->size = sf->holdlen = 0; 00214 sf->offset = sf->hold; 00215 00216 return; 00217 }
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_SLINEAR, ast_slinfactory::hold, ast_slinfactory::offset, and ast_slinfactory::output_format.
Referenced by ast_audiohook_init(), and softmix_bridge_join().
00040 { 00041 memset(sf, 0, sizeof(*sf)); 00042 sf->offset = sf->hold; 00043 sf->output_format = AST_FORMAT_SLINEAR; 00044 }
int ast_slinfactory_init_rate | ( | struct ast_slinfactory * | sf, | |
unsigned int | sample_rate | |||
) |
Initialize a slinfactory.
sf | The slinfactory to initialize | |
sample_rate | The output sample rate desired |
Definition at line 46 of file slinfactory.c.
References AST_FORMAT_SLINEAR, AST_FORMAT_SLINEAR16, ast_slinfactory::hold, ast_slinfactory::offset, and ast_slinfactory::output_format.
00047 { 00048 memset(sf, 0, sizeof(*sf)); 00049 sf->offset = sf->hold; 00050 switch (sample_rate) { 00051 case 8000: 00052 sf->output_format = AST_FORMAT_SLINEAR; 00053 break; 00054 case 16000: 00055 sf->output_format = AST_FORMAT_SLINEAR16; 00056 break; 00057 default: 00058 return -1; 00059 } 00060 00061 return 0; 00062 }
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 142 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_slinfactory::queue, ast_frame::samples, and ast_slinfactory::size.
Referenced by audio_audiohook_write_list(), audiohook_read_frame_both(), audiohook_read_frame_single(), and softmix_bridge_thread().
00143 { 00144 struct ast_frame *frame_ptr; 00145 unsigned int sofar = 0, ineed, remain; 00146 short *frame_data, *offset = buf; 00147 00148 while (sofar < samples) { 00149 ineed = samples - sofar; 00150 00151 if (sf->holdlen) { 00152 if (sf->holdlen <= ineed) { 00153 memcpy(offset, sf->hold, sf->holdlen * sizeof(*offset)); 00154 sofar += sf->holdlen; 00155 offset += sf->holdlen; 00156 sf->holdlen = 0; 00157 sf->offset = sf->hold; 00158 } else { 00159 remain = sf->holdlen - ineed; 00160 memcpy(offset, sf->offset, ineed * sizeof(*offset)); 00161 sofar += ineed; 00162 sf->offset += ineed; 00163 sf->holdlen = remain; 00164 } 00165 continue; 00166 } 00167 00168 if ((frame_ptr = AST_LIST_REMOVE_HEAD(&sf->queue, frame_list))) { 00169 frame_data = frame_ptr->data.ptr; 00170 00171 if (frame_ptr->samples <= ineed) { 00172 memcpy(offset, frame_data, frame_ptr->samples * sizeof(*offset)); 00173 sofar += frame_ptr->samples; 00174 offset += frame_ptr->samples; 00175 } else { 00176 remain = frame_ptr->samples - ineed; 00177 memcpy(offset, frame_data, ineed * sizeof(*offset)); 00178 sofar += ineed; 00179 frame_data += ineed; 00180 if (remain > (AST_SLINFACTORY_MAX_HOLD - sf->holdlen)) { 00181 remain = AST_SLINFACTORY_MAX_HOLD - sf->holdlen; 00182 } 00183 memcpy(sf->hold, frame_data, remain * sizeof(*offset)); 00184 sf->holdlen = remain; 00185 } 00186 ast_frfree(frame_ptr); 00187 } else { 00188 break; 00189 } 00190 } 00191 00192 sf->size -= sofar; 00193 return sofar; 00194 }