Wed Aug 18 22:34:33 2010

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 an 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 an slinfactory.
void ast_slinfactory_flush (struct ast_slinfactory *sf)
 Flush the contents of an slinfactory.
void ast_slinfactory_init (struct ast_slinfactory *sf)
 Initialize an slinfactory.
int ast_slinfactory_read (struct ast_slinfactory *sf, short *buf, size_t samples)
 Read samples from an 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 an slinfactory.

Returns:
Number of samples in slinfactory

Definition at line 213 of file slinfactory.c.

References ast_slinfactory::size.

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

00214 {
00215    return sf->size;
00216 }

void ast_slinfactory_destroy ( struct ast_slinfactory sf  ) 

Destroy the contents of a slinfactory.

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

00060 {
00061    struct ast_frame *f;
00062 
00063    if (sf->trans) {
00064       ast_translator_free_path(sf->trans);
00065       sf->trans = NULL;
00066    }
00067 
00068    while ((f = AST_LIST_REMOVE_HEAD(&sf->queue, frame_list)))
00069       ast_frfree(f);
00070 }

int ast_slinfactory_feed ( struct ast_slinfactory sf,
struct ast_frame f 
)

Feed audio into an slinfactory.

Returns:
Number of frames currently in factory

Definition at line 80 of file slinfactory.c.

References AST_FORMAT_G722, AST_FORMAT_SLINEAR, AST_FORMAT_SLINEAR16, 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_frame::samples, ast_slinfactory::size, and ast_slinfactory::trans.

Referenced by ast_audiohook_write_frame().

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

void ast_slinfactory_flush ( struct ast_slinfactory sf  ) 

Flush the contents of an slinfactory.

Returns:
Nothing

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

00226 {
00227    struct ast_frame *fr = NULL;
00228 
00229    if (sf->trans) {
00230       ast_translator_free_path(sf->trans);
00231       sf->trans = NULL;
00232    }
00233 
00234    while ((fr = AST_LIST_REMOVE_HEAD(&sf->queue, frame_list)))
00235       ast_frfree(fr);
00236 
00237    sf->size = sf->holdlen = 0;
00238    sf->offset = sf->hold;
00239 
00240    return;
00241 }

void ast_slinfactory_init ( struct ast_slinfactory sf  ) 

Initialize an slinfactory.

Returns:
Nothing

Definition at line 42 of file slinfactory.c.

Referenced by ast_audiohook_init().

00043 {
00044    memset(sf, 0, sizeof(*sf));
00045    sf->offset = sf->hold;
00046 }

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

Read samples from an slinfactory.

Returns:
Number of samples read

Definition at line 152 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_frame::offset, ast_slinfactory::offset, ast_frame::ptr, ast_frame::samples, and ast_slinfactory::size.

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

00153 {
00154    struct ast_frame *frame_ptr;
00155    unsigned int sofar = 0, ineed, remain;
00156    short *frame_data, *offset = buf;
00157 
00158    while (sofar < samples) {
00159       ineed = samples - sofar;
00160 
00161       if (sf->holdlen) {
00162          if (sf->holdlen <= ineed) {
00163             memcpy(offset, sf->hold, sf->holdlen * sizeof(*offset));
00164             sofar += sf->holdlen;
00165             offset += sf->holdlen;
00166             sf->holdlen = 0;
00167             sf->offset = sf->hold;
00168          } else {
00169             remain = sf->holdlen - ineed;
00170             memcpy(offset, sf->offset, ineed * sizeof(*offset));
00171             sofar += ineed;
00172             sf->offset += ineed;
00173             sf->holdlen = remain;
00174          }
00175          continue;
00176       }
00177       
00178       if ((frame_ptr = AST_LIST_REMOVE_HEAD(&sf->queue, frame_list))) {
00179          frame_data = frame_ptr->data.ptr;
00180          
00181          if (frame_ptr->samples <= ineed) {
00182             memcpy(offset, frame_data, frame_ptr->samples * sizeof(*offset));
00183             sofar += frame_ptr->samples;
00184             offset += frame_ptr->samples;
00185          } else {
00186             remain = frame_ptr->samples - ineed;
00187             memcpy(offset, frame_data, ineed * sizeof(*offset));
00188             sofar += ineed;
00189             frame_data += ineed;
00190             if (remain > (AST_SLINFACTORY_MAX_HOLD - sf->holdlen)) {
00191                remain = AST_SLINFACTORY_MAX_HOLD - sf->holdlen;
00192             }
00193             memcpy(sf->hold, frame_data, remain * sizeof(*offset));
00194             sf->holdlen = remain;
00195          }
00196          ast_frfree(frame_ptr);
00197       } else {
00198          break;
00199       }
00200    }
00201 
00202    sf->size -= sofar;
00203    return sofar;
00204 }


Generated on Wed Aug 18 22:34:33 2010 for Asterisk - the Open Source PBX by  doxygen 1.4.7