Asterisk - The Open Source Telephony Project  18.5.0
Functions
slinfactory.c File Reference

A machine to gather up arbitrary frames and convert them to raw slinear on demand. More...

#include "asterisk.h"
#include "asterisk/frame.h"
#include "asterisk/format_cache.h"
#include "asterisk/slinfactory.h"
#include "asterisk/translate.h"
#include "asterisk/astobj2.h"
Include dependency graph for slinfactory.c:

Go to the source code of this file.

Functions

unsigned int ast_slinfactory_available (const struct ast_slinfactory *sf)
 Retrieve number of samples currently in a slinfactory. More...
 
void ast_slinfactory_destroy (struct ast_slinfactory *sf)
 Destroy the contents of a slinfactory. More...
 
int ast_slinfactory_feed (struct ast_slinfactory *sf, struct ast_frame *f)
 Feed audio into a slinfactory. More...
 
void ast_slinfactory_flush (struct ast_slinfactory *sf)
 Flush the contents of a slinfactory. More...
 
void ast_slinfactory_init (struct ast_slinfactory *sf)
 Initialize a slinfactory. More...
 
int ast_slinfactory_init_with_format (struct ast_slinfactory *sf, struct ast_format *slin_out)
 Initialize a slinfactory. More...
 
int ast_slinfactory_read (struct ast_slinfactory *sf, short *buf, size_t samples)
 Read samples from a slinfactory. More...
 

Detailed Description

A machine to gather up arbitrary frames and convert them to raw slinear on demand.

Author
Anthony Minessale anthm.nosp@m.ct@y.nosp@m.ahoo..nosp@m.com

Definition in file slinfactory.c.

Function Documentation

◆ ast_slinfactory_available()

unsigned int ast_slinfactory_available ( const struct ast_slinfactory sf)

Retrieve number of samples currently in a slinfactory.

Parameters
sfThe slinfactory to peek into
Returns
Number of samples in slinfactory

Definition at line 199 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_voice(), and softmix_process_read_audio().

200 {
201  return sf->size;
202 }
unsigned int size
Definition: slinfactory.h:41

◆ ast_slinfactory_destroy()

void ast_slinfactory_destroy ( struct ast_slinfactory sf)

Destroy the contents of a slinfactory.

Parameters
sfThe 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.

Returns
Nothing

Definition at line 58 of file slinfactory.c.

References ao2_cleanup, ast_frfree, AST_LIST_REMOVE_HEAD, ast_translator_free_path(), ast_slinfactory::format, NULL, ast_slinfactory::output_format, and ast_slinfactory::trans.

Referenced by ast_audiohook_destroy(), audiohook_set_internal_rate(), set_softmix_bridge_data(), and softmix_bridge_leave().

59 {
60  struct ast_frame *f;
61 
62  if (sf->trans) {
64  sf->trans = NULL;
65  }
66 
67  while ((f = AST_LIST_REMOVE_HEAD(&sf->queue, frame_list))) {
68  ast_frfree(f);
69  }
70 
72  sf->output_format = NULL;
73  ao2_cleanup(sf->format);
74  sf->format = NULL;
75 }
#define NULL
Definition: resample.c:96
struct ast_trans_pvt * trans
Definition: slinfactory.h:37
struct ast_format * format
Definition: slinfactory.h:42
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
#define ast_frfree(fr)
Data structure associated with a single frame of data.
void ast_translator_free_path(struct ast_trans_pvt *tr)
Frees a translator path Frees the given translator path structure.
Definition: translate.c:475
struct ast_format * output_format
Definition: slinfactory.h:43

◆ ast_slinfactory_feed()

int ast_slinfactory_feed ( struct ast_slinfactory sf,
struct ast_frame f 
)

Feed audio into a slinfactory.

Parameters
sfThe slinfactory to feed into
fFrame containing audio to feed in
Returns
Number of frames currently in factory

Definition at line 77 of file slinfactory.c.

References ao2_replace, ast_format_cmp(), AST_FORMAT_CMP_NOT_EQUAL, ast_format_get_codec_id(), ast_format_get_name(), ast_frdup, ast_frfree, ast_frisolate, 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_subclass::format, LOG_WARNING, NULL, 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_voice().

78 {
79  struct ast_frame *begin_frame = f, *duped_frame = NULL, *frame_ptr;
80  unsigned int x = 0;
81 
82  /* In some cases, we can be passed a frame which has no data in it, but
83  * which has a positive number of samples defined. Once such situation is
84  * when a jitter buffer is in use and the jitter buffer interpolates a frame.
85  * The frame it produces has data set to NULL, datalen set to 0, and samples
86  * set to either 160 or 240.
87  */
88  if (!f->data.ptr) {
89  return 0;
90  }
91 
95  sf->trans = NULL;
96  }
97 
98  if (!sf->trans) {
100  ast_log(LOG_WARNING, "Cannot build a path from %s (%u)to %s (%u)\n",
105  return 0;
106  }
108  }
109 
110  if (!(begin_frame = ast_translate(sf->trans, f, 0))) {
111  return 0;
112  }
113 
114  if (!(duped_frame = ast_frisolate(begin_frame))) {
115  return 0;
116  }
117 
118  if (duped_frame != begin_frame) {
119  ast_frfree(begin_frame);
120  }
121  } else {
122  if (sf->trans) {
124  sf->trans = NULL;
125  }
126  if (!(duped_frame = ast_frdup(f)))
127  return 0;
128  }
129 
130  AST_LIST_TRAVERSE(&sf->queue, frame_ptr, frame_list) {
131  x++;
132  }
133 
134  /* if the frame was translated, the translator may have returned multiple
135  frames, so process each of them
136  */
137  for (begin_frame = duped_frame; begin_frame; begin_frame = AST_LIST_NEXT(begin_frame, frame_list)) {
138  AST_LIST_INSERT_TAIL(&sf->queue, begin_frame, frame_list);
139  sf->size += begin_frame->samples;
140  }
141 
142  return x;
143 }
#define ast_frdup(fr)
Copies a frame.
unsigned int size
Definition: slinfactory.h:41
#define LOG_WARNING
Definition: logger.h:274
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:438
struct ast_frame * ast_translate(struct ast_trans_pvt *tr, struct ast_frame *f, int consume)
translates one or more frames Apply an input frame into the translator and receive zero or one output...
Definition: translate.c:565
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
#define NULL
Definition: resample.c:96
struct ast_trans_pvt * trans
Definition: slinfactory.h:37
struct ast_format * format
Definition: slinfactory.h:42
struct ast_frame_subclass subclass
#define ast_log
Definition: astobj2.c:42
enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
Compare two formats.
Definition: format.c:201
struct ast_trans_pvt * ast_translator_build_path(struct ast_format *dest, struct ast_format *source)
Builds a translator path Build a path (possibly NULL) from source to dest.
Definition: translate.c:485
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ast_frisolate(fr)
Makes a frame independent of any static storage.
#define ao2_replace(dst, src)
Definition: astobj2.h:517
#define ast_frfree(fr)
Data structure associated with a single frame of data.
union ast_frame::@263 data
struct ast_format * format
unsigned int ast_format_get_codec_id(const struct ast_format *format)
Get the codec identifier associated with a format.
Definition: format.c:329
void ast_translator_free_path(struct ast_trans_pvt *tr)
Frees a translator path Frees the given translator path structure.
Definition: translate.c:475
struct ast_format * output_format
Definition: slinfactory.h:43

◆ ast_slinfactory_flush()

void ast_slinfactory_flush ( struct ast_slinfactory sf)

Flush the contents of a slinfactory.

Parameters
sfThe slinfactory to flush
Returns
Nothing

Definition at line 204 of file slinfactory.c.

References ast_frfree, AST_LIST_REMOVE_HEAD, ast_translator_free_path(), ast_slinfactory::hold, ast_slinfactory::holdlen, NULL, ast_slinfactory::offset, ast_slinfactory::size, and ast_slinfactory::trans.

Referenced by ast_audiohook_write_frame(), clear_talking(), and softmix_bridge_write_voice().

205 {
206  struct ast_frame *fr = NULL;
207 
208  if (sf->trans) {
210  sf->trans = NULL;
211  }
212 
213  while ((fr = AST_LIST_REMOVE_HEAD(&sf->queue, frame_list)))
214  ast_frfree(fr);
215 
216  sf->size = sf->holdlen = 0;
217  sf->offset = sf->hold;
218 
219  return;
220 }
unsigned int size
Definition: slinfactory.h:41
short hold[AST_SLINFACTORY_MAX_HOLD]
Definition: slinfactory.h:38
#define NULL
Definition: resample.c:96
struct ast_trans_pvt * trans
Definition: slinfactory.h:37
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
short * offset
Definition: slinfactory.h:39
#define ast_frfree(fr)
Data structure associated with a single frame of data.
void ast_translator_free_path(struct ast_trans_pvt *tr)
Frees a translator path Frees the given translator path structure.
Definition: translate.c:475

◆ ast_slinfactory_init()

void ast_slinfactory_init ( struct ast_slinfactory sf)

Initialize a slinfactory.

Parameters
sfThe slinfactory to initialize
Returns
Nothing

Definition at line 39 of file slinfactory.c.

References ao2_bump, ast_format_slin, ast_slinfactory::hold, ast_slinfactory::offset, and ast_slinfactory::output_format.

40 {
41  memset(sf, 0, sizeof(*sf));
42  sf->offset = sf->hold;
44 }
short hold[AST_SLINFACTORY_MAX_HOLD]
Definition: slinfactory.h:38
#define ao2_bump(obj)
Definition: astobj2.h:491
short * offset
Definition: slinfactory.h:39
struct ast_format * ast_format_slin
Built-in cached signed linear 8kHz format.
Definition: format_cache.c:41
struct ast_format * output_format
Definition: slinfactory.h:43

◆ ast_slinfactory_init_with_format()

int ast_slinfactory_init_with_format ( struct ast_slinfactory sf,
struct ast_format slin_out 
)

Initialize a slinfactory.

Parameters
sfThe slinfactory to initialize
slin_outthe slinear output format desired.
Returns
0 on success, non-zero on failure

Definition at line 46 of file slinfactory.c.

References ao2_bump, ast_format_cache_is_slinear(), ast_slinfactory::hold, ast_slinfactory::offset, and ast_slinfactory::output_format.

Referenced by audiohook_set_internal_rate(), and set_softmix_bridge_data().

47 {
48  memset(sf, 0, sizeof(*sf));
49  sf->offset = sf->hold;
50  if (!ast_format_cache_is_slinear(slin_out)) {
51  return -1;
52  }
53  sf->output_format = ao2_bump(slin_out);
54 
55  return 0;
56 }
short hold[AST_SLINFACTORY_MAX_HOLD]
Definition: slinfactory.h:38
#define ao2_bump(obj)
Definition: astobj2.h:491
int ast_format_cache_is_slinear(struct ast_format *format)
Determines if a format is one of the cached slin formats.
Definition: format_cache.c:542
short * offset
Definition: slinfactory.h:39
struct ast_format * output_format
Definition: slinfactory.h:43

◆ ast_slinfactory_read()

int ast_slinfactory_read ( struct ast_slinfactory sf,
short *  buf,
size_t  samples 
)

Read samples from a slinfactory.

Parameters
sfThe slinfactory to read from
bufBuffer to put samples into
samplesNumber of samples wanted
Returns
Number of samples read

Definition at line 145 of file slinfactory.c.

References ast_frfree, AST_LIST_REMOVE_HEAD, AST_SLINFACTORY_MAX_HOLD, buf, 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().

146 {
147  struct ast_frame *frame_ptr;
148  unsigned int sofar = 0, ineed, remain;
149  short *frame_data, *offset = buf;
150 
151  while (sofar < samples) {
152  ineed = samples - sofar;
153 
154  if (sf->holdlen) {
155  if (sf->holdlen <= ineed) {
156  memcpy(offset, sf->offset, sf->holdlen * sizeof(*offset));
157  sofar += sf->holdlen;
158  offset += sf->holdlen;
159  sf->holdlen = 0;
160  sf->offset = sf->hold;
161  } else {
162  remain = sf->holdlen - ineed;
163  memcpy(offset, sf->offset, ineed * sizeof(*offset));
164  sofar += ineed;
165  sf->offset += ineed;
166  sf->holdlen = remain;
167  }
168  continue;
169  }
170 
171  if ((frame_ptr = AST_LIST_REMOVE_HEAD(&sf->queue, frame_list))) {
172  frame_data = frame_ptr->data.ptr;
173 
174  if (frame_ptr->samples <= ineed) {
175  memcpy(offset, frame_data, frame_ptr->samples * sizeof(*offset));
176  sofar += frame_ptr->samples;
177  offset += frame_ptr->samples;
178  } else {
179  remain = frame_ptr->samples - ineed;
180  memcpy(offset, frame_data, ineed * sizeof(*offset));
181  sofar += ineed;
182  frame_data += ineed;
183  if (remain > (AST_SLINFACTORY_MAX_HOLD - sf->holdlen)) {
184  remain = AST_SLINFACTORY_MAX_HOLD - sf->holdlen;
185  }
186  memcpy(sf->hold, frame_data, remain * sizeof(*offset));
187  sf->holdlen = remain;
188  }
189  ast_frfree(frame_ptr);
190  } else {
191  break;
192  }
193  }
194 
195  sf->size -= sofar;
196  return sofar;
197 }
unsigned int size
Definition: slinfactory.h:41
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
short hold[AST_SLINFACTORY_MAX_HOLD]
Definition: slinfactory.h:38
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
short * offset
Definition: slinfactory.h:39
#define AST_SLINFACTORY_MAX_HOLD
Definition: slinfactory.h:33
#define ast_frfree(fr)
Data structure associated with a single frame of data.
union ast_frame::@263 data