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