Mon Mar 19 11:30:55 2012

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

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

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.

Parameters:
sf The slinfactory to feed into
f Frame containing audio to feed in
Returns:
Number of frames currently in factory

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(), f, ast_slinfactory::format, LOG_WARNING, ast_slinfactory::output_format, ast_frame::samples, ast_slinfactory::size, 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.codec != sf->output_format) {
00089       if (sf->trans && f->subclass.codec != 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.codec))) {
00096             ast_log(LOG_WARNING, "Cannot build a path from %s to %s\n", ast_getformatname(f->subclass.codec),
00097                ast_getformatname(sf->output_format));
00098             return 0;
00099          }
00100          sf->format = f->subclass.codec;
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.

Parameters:
sf The slinfactory to flush
Returns:
Nothing

Definition at line 197 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().

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.

Parameters:
sf The slinfactory to initialize
Returns:
Nothing

Definition at line 35 of file slinfactory.c.

References AST_FORMAT_SLINEAR.

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.

Parameters:
sf The slinfactory to initialize
sample_rate The output sample rate desired
Returns:
0 on success, non-zero on failure

Definition at line 42 of file slinfactory.c.

References AST_FORMAT_SLINEAR, and AST_FORMAT_SLINEAR16.

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.

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

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 }


Generated on Mon Mar 19 11:30:55 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7