Sat Feb 11 06:36:48 2012

Asterisk developer's documentation


slinfactory.h File Reference

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

#include "asterisk/format.h"

Include dependency graph for slinfactory.h:

This graph shows which files directly or indirectly include this file:

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_with_format (struct ast_slinfactory *sf, const struct ast_format *slin_out)
 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.

Definition in file slinfactory.h.


Define Documentation

#define AST_SLINFACTORY_MAX_HOLD   1280

Definition at line 33 of file slinfactory.h.

Referenced by ast_slinfactory_read().


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 189 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(), and softmix_process_read_audio().

00190 {
00191    return sf->size;
00192 }

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 54 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(), audiohook_set_internal_rate(), set_softmix_bridge_data(), and softmix_bridge_leave().

00055 {
00056    struct ast_frame *f;
00057 
00058    if (sf->trans) {
00059       ast_translator_free_path(sf->trans);
00060       sf->trans = NULL;
00061    }
00062 
00063    while ((f = AST_LIST_REMOVE_HEAD(&sf->queue, frame_list)))
00064       ast_frfree(f);
00065 }

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 67 of file slinfactory.c.

References ast_format_cmp(), AST_FORMAT_CMP_NOT_EQUAL, ast_format_copy(), 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_subclass::format, ast_format::id, 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().

00068 {
00069    struct ast_frame *begin_frame = f, *duped_frame = NULL, *frame_ptr;
00070    unsigned int x = 0;
00071 
00072    /* In some cases, we can be passed a frame which has no data in it, but
00073     * which has a positive number of samples defined. Once such situation is
00074     * when a jitter buffer is in use and the jitter buffer interpolates a frame.
00075     * The frame it produces has data set to NULL, datalen set to 0, and samples
00076     * set to either 160 or 240.
00077     */
00078    if (!f->data.ptr) {
00079       return 0;
00080    }
00081 
00082    if (ast_format_cmp(&f->subclass.format, &sf->output_format) == AST_FORMAT_CMP_NOT_EQUAL) {
00083       if (sf->trans && (ast_format_cmp(&f->subclass.format, &sf->format) == AST_FORMAT_CMP_NOT_EQUAL)) {
00084          ast_translator_free_path(sf->trans);
00085          sf->trans = NULL;
00086       }
00087 
00088       if (!sf->trans) {
00089          if (!(sf->trans = ast_translator_build_path(&sf->output_format, &f->subclass.format))) {
00090             ast_log(LOG_WARNING, "Cannot build a path from %s (%d)to %s (%d)\n",
00091                ast_getformatname(&f->subclass.format),
00092                f->subclass.format.id,
00093                ast_getformatname(&sf->output_format),
00094                sf->output_format.id);
00095             return 0;
00096          }
00097          ast_format_copy(&sf->format, &f->subclass.format);
00098       }
00099 
00100       if (!(begin_frame = ast_translate(sf->trans, f, 0))) {
00101          return 0;
00102       }
00103       
00104       if (!(duped_frame = ast_frisolate(begin_frame))) {
00105          return 0;
00106       }
00107 
00108       if (duped_frame != begin_frame) {
00109          ast_frfree(begin_frame);
00110       }
00111    } else {
00112       if (sf->trans) {
00113          ast_translator_free_path(sf->trans);
00114          sf->trans = NULL;
00115       }
00116       if (!(duped_frame = ast_frdup(f)))
00117          return 0;
00118    }
00119 
00120    AST_LIST_TRAVERSE(&sf->queue, frame_ptr, frame_list) {
00121       x++;
00122    }
00123 
00124    /* if the frame was translated, the translator may have returned multiple
00125       frames, so process each of them
00126    */
00127    for (begin_frame = duped_frame; begin_frame; begin_frame = AST_LIST_NEXT(begin_frame, frame_list)) {
00128       AST_LIST_INSERT_TAIL(&sf->queue, begin_frame, frame_list);
00129       sf->size += begin_frame->samples;
00130    }
00131 
00132    return x;
00133 }

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 194 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(), and softmix_bridge_write().

00195 {
00196    struct ast_frame *fr = NULL;
00197 
00198    if (sf->trans) {
00199       ast_translator_free_path(sf->trans);
00200       sf->trans = NULL;
00201    }
00202 
00203    while ((fr = AST_LIST_REMOVE_HEAD(&sf->queue, frame_list)))
00204       ast_frfree(fr);
00205 
00206    sf->size = sf->holdlen = 0;
00207    sf->offset = sf->hold;
00208 
00209    return;
00210 }

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_set(), AST_FORMAT_SLINEAR, ast_slinfactory::hold, ast_slinfactory::offset, and ast_slinfactory::output_format.

00036 {
00037    memset(sf, 0, sizeof(*sf));
00038    sf->offset = sf->hold;
00039    ast_format_set(&sf->output_format, AST_FORMAT_SLINEAR, 0);
00040 }

int ast_slinfactory_init_with_format ( struct ast_slinfactory sf,
const struct ast_format slin_out 
)

Initialize a slinfactory.

Parameters:
sf The slinfactory to initialize
slin_out the slinear output format desired.
Returns:
0 on success, non-zero on failure

Definition at line 42 of file slinfactory.c.

References ast_format_copy(), ast_format_is_slinear(), ast_slinfactory::hold, ast_slinfactory::offset, and ast_slinfactory::output_format.

Referenced by audiohook_set_internal_rate(), and set_softmix_bridge_data().

00043 {
00044    memset(sf, 0, sizeof(*sf));
00045    sf->offset = sf->hold;
00046    if (!ast_format_is_slinear(slin_out)) {
00047       return -1;
00048    }
00049    ast_format_copy(&sf->output_format, slin_out);
00050 
00051    return 0;
00052 }

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

00136 {
00137    struct ast_frame *frame_ptr;
00138    unsigned int sofar = 0, ineed, remain;
00139    short *frame_data, *offset = buf;
00140 
00141    while (sofar < samples) {
00142       ineed = samples - sofar;
00143 
00144       if (sf->holdlen) {
00145          if (sf->holdlen <= ineed) {
00146             memcpy(offset, sf->hold, sf->holdlen * sizeof(*offset));
00147             sofar += sf->holdlen;
00148             offset += sf->holdlen;
00149             sf->holdlen = 0;
00150             sf->offset = sf->hold;
00151          } else {
00152             remain = sf->holdlen - ineed;
00153             memcpy(offset, sf->offset, ineed * sizeof(*offset));
00154             sofar += ineed;
00155             sf->offset += ineed;
00156             sf->holdlen = remain;
00157          }
00158          continue;
00159       }
00160       
00161       if ((frame_ptr = AST_LIST_REMOVE_HEAD(&sf->queue, frame_list))) {
00162          frame_data = frame_ptr->data.ptr;
00163          
00164          if (frame_ptr->samples <= ineed) {
00165             memcpy(offset, frame_data, frame_ptr->samples * sizeof(*offset));
00166             sofar += frame_ptr->samples;
00167             offset += frame_ptr->samples;
00168          } else {
00169             remain = frame_ptr->samples - ineed;
00170             memcpy(offset, frame_data, ineed * sizeof(*offset));
00171             sofar += ineed;
00172             frame_data += ineed;
00173             if (remain > (AST_SLINFACTORY_MAX_HOLD - sf->holdlen)) {
00174                remain = AST_SLINFACTORY_MAX_HOLD - sf->holdlen;
00175             }
00176             memcpy(sf->hold, frame_data, remain * sizeof(*offset));
00177             sf->holdlen = remain;
00178          }
00179          ast_frfree(frame_ptr);
00180       } else {
00181          break;
00182       }
00183    }
00184 
00185    sf->size -= sofar;
00186    return sofar;
00187 }


Generated on Sat Feb 11 06:36:48 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6