Wed Jan 8 2020 09:50:21

Asterisk developer's documentation


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/slinfactory.h"
#include "asterisk/translate.h"

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_rate (struct ast_slinfactory *sf, unsigned int sample_rate)
 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

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 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().

197 {
198  return sf->size;
199 }
unsigned int size
Definition: slinfactory.h:39
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 64 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(), and softmix_bridge_leave().

65 {
66  struct ast_frame *f;
67 
68  if (sf->trans) {
70  sf->trans = NULL;
71  }
72 
73  while ((f = AST_LIST_REMOVE_HEAD(&sf->queue, frame_list)))
74  ast_frfree(f);
75 }
struct ast_trans_pvt * trans
Definition: slinfactory.h:35
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:818
static struct ast_format f[]
Definition: format_g726.c:181
Data structure associated with a single frame of data.
Definition: frame.h:142
#define ast_frfree(fr)
Definition: frame.h:583
void ast_translator_free_path(struct ast_trans_pvt *tr)
Frees a translator path Frees the given translator path structure.
Definition: translate.c:272
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 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, f, ast_slinfactory::format, 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().

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 
92  if (f->subclass.codec != sf->output_format) {
93  if (sf->trans && f->subclass.codec != sf->format) {
95  sf->trans = NULL;
96  }
97 
98  if (!sf->trans) {
100  ast_log(LOG_WARNING, "Cannot build a path from %s to %s\n", ast_getformatname(f->subclass.codec),
102  return 0;
103  }
104  sf->format = f->subclass.codec;
105  }
106 
107  if (!(begin_frame = ast_translate(sf->trans, f, 0))) {
108  return 0;
109  }
110 
111  if (!(duped_frame = ast_frisolate(begin_frame))) {
112  return 0;
113  }
114 
115  if (duped_frame != begin_frame) {
116  ast_frfree(begin_frame);
117  }
118  } else {
119  if (sf->trans) {
121  sf->trans = NULL;
122  }
123  if (!(duped_frame = ast_frdup(f)))
124  return 0;
125  }
126 
127  AST_LIST_TRAVERSE(&sf->queue, frame_ptr, frame_list) {
128  x++;
129  }
130 
131  /* if the frame was translated, the translator may have returned multiple
132  frames, so process each of them
133  */
134  for (begin_frame = duped_frame; begin_frame; begin_frame = AST_LIST_NEXT(begin_frame, frame_list)) {
135  AST_LIST_INSERT_TAIL(&sf->queue, begin_frame, frame_list);
136  sf->size += begin_frame->samples;
137  }
138 
139  return x;
140 }
union ast_frame_subclass subclass
Definition: frame.h:146
unsigned int size
Definition: slinfactory.h:39
void * ptr
Definition: frame.h:160
#define LOG_WARNING
Definition: logger.h:144
#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:328
struct ast_frame * ast_frisolate(struct ast_frame *fr)
Makes a frame independent of any static storage.
Definition: frame.c:391
format_t codec
Definition: frame.h:137
struct ast_trans_pvt * trans
Definition: slinfactory.h:35
struct ast_trans_pvt * ast_translator_build_path(format_t dest, format_t source)
Builds a translator path Build a path (possibly NULL) from source to dest.
Definition: translate.c:282
char * ast_getformatname(format_t format)
Get the name of a format.
Definition: frame.c:578
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:716
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
format_t output_format
Definition: slinfactory.h:41
static struct ast_format f[]
Definition: format_g726.c:181
format_t format
Definition: slinfactory.h:40
Data structure associated with a single frame of data.
Definition: frame.h:142
#define ast_frfree(fr)
Definition: frame.h:583
union ast_frame::@172 data
struct ast_frame * ast_frdup(const struct ast_frame *fr)
Copies a frame.
Definition: frame.c:474
void ast_translator_free_path(struct ast_trans_pvt *tr)
Frees a translator path Frees the given translator path structure.
Definition: translate.c:272
int samples
Definition: frame.h:150
void ast_slinfactory_flush ( struct ast_slinfactory sf)

Flush the contents of a slinfactory.

Parameters
sfThe slinfactory to flush
Returns
Nothing

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::size, and ast_slinfactory::trans.

Referenced by ast_audiohook_write_frame().

202 {
203  struct ast_frame *fr = NULL;
204 
205  if (sf->trans) {
207  sf->trans = NULL;
208  }
209 
210  while ((fr = AST_LIST_REMOVE_HEAD(&sf->queue, frame_list)))
211  ast_frfree(fr);
212 
213  sf->size = sf->holdlen = 0;
214  sf->offset = sf->hold;
215 
216  return;
217 }
unsigned int size
Definition: slinfactory.h:39
short hold[AST_SLINFACTORY_MAX_HOLD]
Definition: slinfactory.h:36
struct ast_trans_pvt * trans
Definition: slinfactory.h:35
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:818
short * offset
Definition: slinfactory.h:37
Data structure associated with a single frame of data.
Definition: frame.h:142
#define ast_frfree(fr)
Definition: frame.h:583
void ast_translator_free_path(struct ast_trans_pvt *tr)
Frees a translator path Frees the given translator path structure.
Definition: translate.c:272
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 AST_FORMAT_SLINEAR, ast_slinfactory::hold, ast_slinfactory::offset, and ast_slinfactory::output_format.

Referenced by ast_audiohook_init(), and softmix_bridge_join().

40 {
41  memset(sf, 0, sizeof(*sf));
42  sf->offset = sf->hold;
44 }
short hold[AST_SLINFACTORY_MAX_HOLD]
Definition: slinfactory.h:36
short * offset
Definition: slinfactory.h:37
format_t output_format
Definition: slinfactory.h:41
#define AST_FORMAT_SLINEAR
Definition: frame.h:254
int ast_slinfactory_init_rate ( struct ast_slinfactory sf,
unsigned int  sample_rate 
)

Initialize a slinfactory.

Parameters
sfThe slinfactory to initialize
sample_rateThe output sample rate desired
Returns
0 on success, non-zero on failure

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.

47 {
48  memset(sf, 0, sizeof(*sf));
49  sf->offset = sf->hold;
50  switch (sample_rate) {
51  case 8000:
53  break;
54  case 16000:
56  break;
57  default:
58  return -1;
59  }
60 
61  return 0;
62 }
short hold[AST_SLINFACTORY_MAX_HOLD]
Definition: slinfactory.h:36
#define AST_FORMAT_SLINEAR16
Definition: frame.h:272
short * offset
Definition: slinfactory.h:37
format_t output_format
Definition: slinfactory.h:41
#define AST_FORMAT_SLINEAR
Definition: frame.h:254
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 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_frame::samples, and ast_slinfactory::size.

Referenced by audio_audiohook_write_list(), audiohook_read_frame_both(), audiohook_read_frame_single(), and softmix_bridge_thread().

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