Mon Aug 31 12:30:46 2015

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

Detailed Description

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

Author:
Anthony Minessale <anthmct@yahoo.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:
sf The 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().

00197 {
00198    return sf->size;
00199 }

void ast_slinfactory_destroy ( struct ast_slinfactory sf  ) 

Destroy the contents of a slinfactory.

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

Returns:
Nothing

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.

Parameters:
sf The slinfactory to feed into
f Frame 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, 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.

Parameters:
sf The 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::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.

Parameters:
sf The 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().

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.

Parameters:
sf The slinfactory to initialize
sample_rate The 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.

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.

Parameters:
sf The slinfactory to read from
buf Buffer to put samples into
samples Number 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_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->offset, 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 }


Generated on 31 Aug 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1