Asterisk - The Open Source Telephony Project  18.5.0
Data Structures | Macros | Functions | Variables
codec_speex.c File Reference

Translate between signed linear and Speex (Open Codec) More...

#include "asterisk.h"
#include <speex/speex.h>
#include "asterisk/translate.h"
#include "asterisk/module.h"
#include "asterisk/config.h"
#include "asterisk/utils.h"
#include "asterisk/frame.h"
#include "asterisk/linkedlists.h"
#include "asterisk/rtp_engine.h"
#include "asterisk/slin.h"
#include "ex_speex.h"
Include dependency graph for codec_speex.c:

Go to the source code of this file.

Data Structures

struct  speex_coder_pvt
 

Macros

#define BUFFER_SAMPLES   8000
 
#define SPEEX_SAMPLES   160
 
#define TYPE_HIGH   0x0
 
#define TYPE_LOW   0x1
 
#define TYPE_MASK   0x3
 
#define TYPE_SILENCE   0x2
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static int lin16tospeexwb_new (struct ast_trans_pvt *pvt)
 
static int lin32tospeexuwb_new (struct ast_trans_pvt *pvt)
 
static void lintospeex_destroy (struct ast_trans_pvt *arg)
 
static void lintospeex_feedback (struct ast_trans_pvt *pvt, struct ast_frame *feedback)
 handle incoming RTCP feedback and possibly edit encoder settings More...
 
static int lintospeex_framein (struct ast_trans_pvt *pvt, struct ast_frame *f)
 store input frame in work buffer More...
 
static struct ast_framelintospeex_frameout (struct ast_trans_pvt *pvt)
 convert work buffer and produce output frame More...
 
static int lintospeex_new (struct ast_trans_pvt *pvt)
 
static int load_module (void)
 
static int parse_config (int reload)
 
static int reload (void)
 
static int speex_decoder_construct (struct ast_trans_pvt *pvt, const SpeexMode *profile)
 
static int speex_encoder_construct (struct ast_trans_pvt *pvt, const SpeexMode *profile, int sampling_rate)
 
static void speextolin_destroy (struct ast_trans_pvt *arg)
 
static int speextolin_framein (struct ast_trans_pvt *pvt, struct ast_frame *f)
 convert and store into outbuf More...
 
static int speextolin_new (struct ast_trans_pvt *pvt)
 
static int speexuwbtolin32_new (struct ast_trans_pvt *pvt)
 
static int speexwbtolin16_new (struct ast_trans_pvt *pvt)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Speex Coder/Decoder" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "30ef0c93b36035ec78c9cfd712d36d9b" , .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload, }
 
static int abr = 0
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static int complexity = 2
 
static int dtx = 0
 
static int enhancement = 0
 
static int exp_rtcp_fb = 0
 
static struct ast_translator lin16tospeexwb
 
static struct ast_translator lin32tospeexuwb
 
static struct ast_translator lintospeex
 
static int pp_agc = 0
 
static float pp_agc_level = 8000
 
static int pp_denoise = 0
 
static int pp_dereverb = 0
 
static float pp_dereverb_decay = 0.4
 
static float pp_dereverb_level = 0.3
 
static int pp_vad = 0
 
static int preproc = 0
 
static int quality = 3
 
static struct ast_translator speextolin
 
static struct ast_translator speexuwbtolin32
 
static struct ast_translator speexwbtolin16
 
static int vad = 0
 
static int vbr = 0
 
static float vbr_quality = 4
 

Detailed Description

Translate between signed linear and Speex (Open Codec)

Note
This work was motivated by Jeremy McNamara hacked to be configurable by anthm and bkw 9/28/2004

The Speex library - http://www.speex.org

Definition in file codec_speex.c.

Macro Definition Documentation

◆ BUFFER_SAMPLES

#define BUFFER_SAMPLES   8000

Definition at line 86 of file codec_speex.c.

Referenced by speextolin_framein().

◆ SPEEX_SAMPLES

#define SPEEX_SAMPLES   160

Definition at line 87 of file codec_speex.c.

Referenced by speex16_sample(), and speex_sample().

◆ TYPE_HIGH

#define TYPE_HIGH   0x0

Definition at line 82 of file codec_speex.c.

◆ TYPE_LOW

#define TYPE_LOW   0x1

Definition at line 83 of file codec_speex.c.

◆ TYPE_MASK

#define TYPE_MASK   0x3

Definition at line 84 of file codec_speex.c.

◆ TYPE_SILENCE

#define TYPE_SILENCE   0x2

Definition at line 81 of file codec_speex.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 730 of file codec_speex.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 730 of file codec_speex.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 730 of file codec_speex.c.

◆ lin16tospeexwb_new()

static int lin16tospeexwb_new ( struct ast_trans_pvt pvt)
static

Definition at line 162 of file codec_speex.c.

References speex_encoder_construct().

163 {
164  return speex_encoder_construct(pvt, &speex_wb_mode, 16000);
165 }
static int speex_encoder_construct(struct ast_trans_pvt *pvt, const SpeexMode *profile, int sampling_rate)
Definition: codec_speex.c:111

◆ lin32tospeexuwb_new()

static int lin32tospeexuwb_new ( struct ast_trans_pvt pvt)
static

Definition at line 167 of file codec_speex.c.

References speex_encoder_construct().

168 {
169  return speex_encoder_construct(pvt, &speex_uwb_mode, 32000);
170 }
static int speex_encoder_construct(struct ast_trans_pvt *pvt, const SpeexMode *profile, int sampling_rate)
Definition: codec_speex.c:111

◆ lintospeex_destroy()

static void lintospeex_destroy ( struct ast_trans_pvt arg)
static

Definition at line 435 of file codec_speex.c.

References speex_coder_pvt::bits, preproc, ast_trans_pvt::pvt, and speex_coder_pvt::speex.

436 {
437  struct speex_coder_pvt *pvt = arg->pvt;
438 #ifdef _SPEEX_TYPES_H
439  if (preproc)
440  speex_preprocess_state_destroy(pvt->pp);
441 #endif
442  speex_encoder_destroy(pvt->speex);
443  speex_bits_destroy(&pvt->bits);
444 }
static int preproc
Definition: codec_speex.c:72
SpeexBits bits
Definition: codec_speex.c:95
void * pvt
Definition: translate.h:219

◆ lintospeex_feedback()

static void lintospeex_feedback ( struct ast_trans_pvt pvt,
struct ast_frame feedback 
)
static

handle incoming RTCP feedback and possibly edit encoder settings

Definition at line 360 of file codec_speex.c.

References ast_debug, AST_RTP_RTCP_RR, AST_RTP_RTCP_SR, ast_frame::data, speex_coder_pvt::default_quality, exp_rtcp_fb, ast_rtp_rtcp_report_block::fraction, speex_coder_pvt::fraction_lost, if(), ast_frame_subclass::integer, ast_rtp_rtcp_report_block::lost_count, ast_frame::ptr, ast_trans_pvt::pvt, speex_coder_pvt::quality, ast_rtp_rtcp_report::reception_report_count, ast_rtp_rtcp_report::report_block, speex_coder_pvt::speex, ast_frame::subclass, tmp(), and vbr.

361 {
362  struct speex_coder_pvt *tmp = pvt->pvt;
363 
364  struct ast_rtp_rtcp_report *rtcp_report;
365  struct ast_rtp_rtcp_report_block *report_block;
366 
367  int fraction_lost;
368  int percent;
369  int bitrate;
370  int q;
371 
372  if(!exp_rtcp_fb)
373  return;
374 
375  /* We only accept feedback information in the form of SR and RR reports */
376  if (feedback->subclass.integer != AST_RTP_RTCP_SR && feedback->subclass.integer != AST_RTP_RTCP_RR) {
377  return;
378  }
379 
380  rtcp_report = (struct ast_rtp_rtcp_report *)feedback->data.ptr;
381  if (rtcp_report->reception_report_count == 0)
382  return;
383  report_block = rtcp_report->report_block[0];
384  fraction_lost = report_block->lost_count.fraction;
385  if (fraction_lost == tmp->fraction_lost)
386  return;
387  /* Per RFC3550, fraction lost is defined to be the number of packets lost
388  * divided by the number of packets expected. Since it's a 8-bit value,
389  * and we want a percentage value, we multiply by 100 and divide by 256. */
390  percent = (fraction_lost*100)/256;
391  bitrate = 0;
392  q = -1;
393  ast_debug(3, "Fraction lost changed: %d --> %d percent loss\n", fraction_lost, percent);
394  /* Handle change */
395  speex_encoder_ctl(tmp->speex, SPEEX_GET_BITRATE, &bitrate);
396  ast_debug(3, "Current bitrate: %d\n", bitrate);
397  ast_debug(3, "Current quality: %d/%d\n", tmp->quality, tmp->default_quality);
398  /* FIXME BADLY Very ugly example of how this could be handled: probably sucks */
399  if (percent < 10) {
400  /* Not that bad, default quality is fine */
401  q = tmp->default_quality;
402  } else if (percent < 20) {
403  /* Quite bad, let's go down a bit */
404  q = tmp->default_quality-1;
405  } else if (percent < 30) {
406  /* Very bad, let's go down even more */
407  q = tmp->default_quality-2;
408  } else {
409  /* Really bad, use the lowest quality possible */
410  q = 0;
411  }
412  if (q < 0)
413  q = 0;
414  if (q != tmp->quality) {
415  ast_debug(3, " -- Setting to %d\n", q);
416  if (vbr) {
417  float vbr_q = q;
418  speex_encoder_ctl(tmp->speex, SPEEX_SET_VBR_QUALITY, &vbr_q);
419  } else {
420  speex_encoder_ctl(tmp->speex, SPEEX_SET_QUALITY, &q);
421  }
422  tmp->quality = q;
423  }
424  tmp->fraction_lost = fraction_lost;
425 }
An object that represents data sent during a SR/RR RTCP report.
Definition: rtp_engine.h:331
static int exp_rtcp_fb
Definition: codec_speex.c:70
static int tmp()
Definition: bt_open.c:389
unsigned short reception_report_count
Definition: rtp_engine.h:332
struct ast_rtp_rtcp_report_block * report_block[0]
Definition: rtp_engine.h:344
if(!yyg->yy_init)
Definition: ast_expr2f.c:868
A report block within a SR/RR report.
Definition: rtp_engine.h:316
void * pvt
Definition: translate.h:219
struct ast_frame_subclass subclass
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
unsigned short fraction
Definition: rtp_engine.h:319
static int vbr
Definition: codec_speex.c:66
#define AST_RTP_RTCP_RR
Definition: rtp_engine.h:295
#define AST_RTP_RTCP_SR
Definition: rtp_engine.h:293
union ast_frame::@263 data
struct ast_rtp_rtcp_report_block::@314 lost_count

◆ lintospeex_framein()

static int lintospeex_framein ( struct ast_trans_pvt pvt,
struct ast_frame f 
)
static

store input frame in work buffer

Definition at line 260 of file codec_speex.c.

References speex_coder_pvt::buf, ast_frame::data, ast_frame::datalen, ast_frame::ptr, ast_trans_pvt::pvt, ast_frame::samples, ast_trans_pvt::samples, and tmp().

261 {
262  struct speex_coder_pvt *tmp = pvt->pvt;
263 
264  /* XXX We should look at how old the rest of our stream is, and if it
265  is too old, then we should overwrite it entirely, otherwise we can
266  get artifacts of earlier talk that do not belong */
267  memcpy(tmp->buf + pvt->samples, f->data.ptr, f->datalen);
268  pvt->samples += f->samples;
269  return 0;
270 }
static int tmp()
Definition: bt_open.c:389
int16_t buf[BUFFER_SAMPLES]
Definition: codec_speex.c:107
void * pvt
Definition: translate.h:219
union ast_frame::@263 data

◆ lintospeex_frameout()

static struct ast_frame* lintospeex_frameout ( struct ast_trans_pvt pvt)
static

convert work buffer and produce output frame

Definition at line 273 of file codec_speex.c.

References AST_FRAME_CNG, ast_frisolate, AST_LIST_NEXT, ast_trans_frameout(), speex_coder_pvt::bits, speex_coder_pvt::buf, ast_translator::buf_size, ast_trans_pvt::c, ast_frame::datalen, dtx, speex_coder_pvt::framesize, ast_frame::frametype, last, ast_translator::name, NULL, ast_trans_pvt::outbuf, preproc, ast_trans_pvt::pvt, result, ast_frame::samples, ast_trans_pvt::samples, speex_coder_pvt::silent_state, speex_coder_pvt::speex, ast_trans_pvt::t, and tmp().

274 {
275  struct speex_coder_pvt *tmp = pvt->pvt;
276  struct ast_frame *result = NULL;
277  struct ast_frame *last = NULL;
278  int samples = 0; /* output samples */
279 
280  while (pvt->samples >= tmp->framesize) {
281  struct ast_frame *current;
282  int is_speech = 1;
283 
284  speex_bits_reset(&tmp->bits);
285 
286 #ifdef _SPEEX_TYPES_H
287  /* Preprocess audio */
288  if (preproc)
289  is_speech = speex_preprocess(tmp->pp, tmp->buf + samples, NULL);
290  /* Encode a frame of data */
291  if (is_speech) {
292  /* If DTX enabled speex_encode returns 0 during silence */
293  is_speech = speex_encode_int(tmp->speex, tmp->buf + samples, &tmp->bits) || !dtx;
294  } else {
295  /* 5 zeros interpreted by Speex as silence (submode 0) */
296  speex_bits_pack(&tmp->bits, 0, 5);
297  }
298 #else
299  {
300  float fbuf[1024];
301  int x;
302  /* Convert to floating point */
303  for (x = 0; x < tmp->framesize; x++)
304  fbuf[x] = tmp->buf[samples + x];
305  /* Encode a frame of data */
306  is_speech = speex_encode(tmp->speex, fbuf, &tmp->bits) || !dtx;
307  }
308 #endif
309  samples += tmp->framesize;
310  pvt->samples -= tmp->framesize;
311 
312  /* Use AST_FRAME_CNG to signify the start of any silence period */
313  if (is_speech) {
314  int datalen = 0; /* output bytes */
315 
316  tmp->silent_state = 0;
317  /* Terminate bit stream */
318  speex_bits_pack(&tmp->bits, 15, 5);
319  datalen = speex_bits_write(&tmp->bits, pvt->outbuf.c, pvt->t->buf_size);
320  current = ast_trans_frameout(pvt, datalen, tmp->framesize);
321  } else if (tmp->silent_state) {
322  current = NULL;
323  } else {
324  struct ast_frame frm = {
326  .src = pvt->t->name,
327  };
328 
329  /*
330  * XXX I don't think the AST_FRAME_CNG code has ever
331  * really worked for speex. There doesn't seem to be
332  * any consumers of the frame type. Everyone that
333  * references the type seems to pass the frame on.
334  */
335  tmp->silent_state = 1;
336 
337  /* XXX what now ? format etc... */
338  current = ast_frisolate(&frm);
339  }
340 
341  if (!current) {
342  continue;
343  } else if (last) {
344  AST_LIST_NEXT(last, frame_list) = current;
345  } else {
346  result = current;
347  }
348  last = current;
349  }
350 
351  /* Move the data at the end of the buffer to the front */
352  if (samples) {
353  memmove(tmp->buf, tmp->buf + samples, pvt->samples * 2);
354  }
355 
356  return result;
357 }
struct ast_frame * ast_trans_frameout(struct ast_trans_pvt *pvt, int datalen, int samples)
generic frameout function
Definition: translate.c:438
static int preproc
Definition: codec_speex.c:72
SpeexBits bits
Definition: codec_speex.c:95
static int tmp()
Definition: bt_open.c:389
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:438
int16_t buf[BUFFER_SAMPLES]
Definition: codec_speex.c:107
#define NULL
Definition: resample.c:96
void * pvt
Definition: translate.h:219
struct sla_ringing_trunk * last
Definition: app_meetme.c:1092
int buf_size
size of outbuf, in bytes. Mandatory. The wrapper code will also allocate an AST_FRIENDLY_OFFSET space...
Definition: translate.h:182
union ast_trans_pvt::@327 outbuf
static int dtx
Definition: codec_speex.c:69
#define ast_frisolate(fr)
Makes a frame independent of any static storage.
static PGresult * result
Definition: cel_pgsql.c:88
Data structure associated with a single frame of data.
struct ast_translator * t
Definition: translate.h:214
enum ast_frame_type frametype
char name[80]
Definition: translate.h:138

◆ lintospeex_new()

static int lintospeex_new ( struct ast_trans_pvt pvt)
static

Definition at line 157 of file codec_speex.c.

References speex_encoder_construct().

158 {
159  return speex_encoder_construct(pvt, &speex_nb_mode, 8000);
160 }
static int speex_encoder_construct(struct ast_trans_pvt *pvt, const SpeexMode *profile, int sampling_rate)
Definition: codec_speex.c:111

◆ load_module()

static int load_module ( void  )
static

Definition at line 702 of file codec_speex.c.

References AST_MODFLAG_DEFAULT, AST_MODULE_INFO(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, AST_MODULE_SUPPORT_CORE, ast_register_translator, ASTERISK_GPL_KEY, parse_config(), reload(), and unload_module().

703 {
704  int res = 0;
705 
706  if (parse_config(0)) {
708  }
709 
710  /* XXX It is most likely a bug in this module if we fail to register a translator */
717  if (res) {
718  unload_module();
720  }
721 
723 }
static struct ast_translator lin16tospeexwb
Definition: codec_speex.c:516
static struct ast_translator lin32tospeexuwb
Definition: codec_speex.c:562
static int parse_config(int reload)
Definition: codec_speex.c:585
#define ast_register_translator(t)
See __ast_register_translator()
Definition: translate.h:257
static struct ast_translator speexuwbtolin32
Definition: codec_speex.c:540
static int unload_module(void)
Definition: codec_speex.c:690
static struct ast_translator lintospeex
Definition: codec_speex.c:469
static struct ast_translator speexwbtolin16
Definition: codec_speex.c:493
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
static struct ast_translator speextolin
Definition: codec_speex.c:446

◆ parse_config()

static int parse_config ( int  reload)
static

Definition at line 585 of file codec_speex.c.

References abr, abs, ast_config_destroy(), ast_config_load, ast_log, ast_true(), ast_variable_browse(), ast_verb, complexity, CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, CONFIG_STATUS_FILEUNCHANGED, dtx, enhancement, exp_rtcp_fb, LOG_ERROR, ast_variable::name, ast_variable::next, pp_agc, pp_agc_level, pp_denoise, pp_dereverb, pp_dereverb_decay, pp_dereverb_level, pp_vad, preproc, speex_coder_pvt::quality, vad, ast_variable::value, var, vbr, and vbr_quality.

Referenced by load_module(), and reload().

586 {
587  struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
588  struct ast_config *cfg = ast_config_load("codecs.conf", config_flags);
589  struct ast_variable *var;
590  int res;
591  float res_f;
592 
594  return 0;
595 
596  for (var = ast_variable_browse(cfg, "speex"); var; var = var->next) {
597  if (!strcasecmp(var->name, "quality")) {
598  res = abs(atoi(var->value));
599  if (res > -1 && res < 11) {
600  ast_verb(3, "CODEC SPEEX: Setting Quality to %d\n",res);
601  quality = res;
602  } else
603  ast_log(LOG_ERROR,"Error Quality must be 0-10\n");
604  } else if (!strcasecmp(var->name, "complexity")) {
605  res = abs(atoi(var->value));
606  if (res > -1 && res < 11) {
607  ast_verb(3, "CODEC SPEEX: Setting Complexity to %d\n",res);
608  complexity = res;
609  } else
610  ast_log(LOG_ERROR,"Error! Complexity must be 0-10\n");
611  } else if (!strcasecmp(var->name, "vbr_quality")) {
612  if (sscanf(var->value, "%30f", &res_f) == 1 && res_f >= 0 && res_f <= 10) {
613  ast_verb(3, "CODEC SPEEX: Setting VBR Quality to %f\n",res_f);
614  vbr_quality = res_f;
615  } else
616  ast_log(LOG_ERROR,"Error! VBR Quality must be 0-10\n");
617  } else if (!strcasecmp(var->name, "abr_quality")) {
618  ast_log(LOG_ERROR,"Error! ABR Quality setting obsolete, set ABR to desired bitrate\n");
619  } else if (!strcasecmp(var->name, "enhancement")) {
620  enhancement = ast_true(var->value) ? 1 : 0;
621  ast_verb(3, "CODEC SPEEX: Perceptual Enhancement Mode. [%s]\n",enhancement ? "on" : "off");
622  } else if (!strcasecmp(var->name, "vbr")) {
623  vbr = ast_true(var->value) ? 1 : 0;
624  ast_verb(3, "CODEC SPEEX: VBR Mode. [%s]\n",vbr ? "on" : "off");
625  } else if (!strcasecmp(var->name, "abr")) {
626  res = abs(atoi(var->value));
627  if (res >= 0) {
628  if (res > 0)
629  ast_verb(3, "CODEC SPEEX: Setting ABR target bitrate to %d\n",res);
630  else
631  ast_verb(3, "CODEC SPEEX: Disabling ABR\n");
632  abr = res;
633  } else
634  ast_log(LOG_ERROR,"Error! ABR target bitrate must be >= 0\n");
635  } else if (!strcasecmp(var->name, "vad")) {
636  vad = ast_true(var->value) ? 1 : 0;
637  ast_verb(3, "CODEC SPEEX: VAD Mode. [%s]\n",vad ? "on" : "off");
638  } else if (!strcasecmp(var->name, "dtx")) {
639  dtx = ast_true(var->value) ? 1 : 0;
640  ast_verb(3, "CODEC SPEEX: DTX Mode. [%s]\n",dtx ? "on" : "off");
641  } else if (!strcasecmp(var->name, "preprocess")) {
642  preproc = ast_true(var->value) ? 1 : 0;
643  ast_verb(3, "CODEC SPEEX: Preprocessing. [%s]\n",preproc ? "on" : "off");
644  } else if (!strcasecmp(var->name, "pp_vad")) {
645  pp_vad = ast_true(var->value) ? 1 : 0;
646  ast_verb(3, "CODEC SPEEX: Preprocessor VAD. [%s]\n",pp_vad ? "on" : "off");
647  } else if (!strcasecmp(var->name, "pp_agc")) {
648  pp_agc = ast_true(var->value) ? 1 : 0;
649  ast_verb(3, "CODEC SPEEX: Preprocessor AGC. [%s]\n",pp_agc ? "on" : "off");
650  } else if (!strcasecmp(var->name, "pp_agc_level")) {
651  if (sscanf(var->value, "%30f", &res_f) == 1 && res_f >= 0) {
652  ast_verb(3, "CODEC SPEEX: Setting preprocessor AGC Level to %f\n",res_f);
653  pp_agc_level = res_f;
654  } else
655  ast_log(LOG_ERROR,"Error! Preprocessor AGC Level must be >= 0\n");
656  } else if (!strcasecmp(var->name, "pp_denoise")) {
657  pp_denoise = ast_true(var->value) ? 1 : 0;
658  ast_verb(3, "CODEC SPEEX: Preprocessor Denoise. [%s]\n",pp_denoise ? "on" : "off");
659  } else if (!strcasecmp(var->name, "pp_dereverb")) {
660  pp_dereverb = ast_true(var->value) ? 1 : 0;
661  ast_verb(3, "CODEC SPEEX: Preprocessor Dereverb. [%s]\n",pp_dereverb ? "on" : "off");
662  } else if (!strcasecmp(var->name, "pp_dereverb_decay")) {
663  if (sscanf(var->value, "%30f", &res_f) == 1 && res_f >= 0) {
664  ast_verb(3, "CODEC SPEEX: Setting preprocessor Dereverb Decay to %f\n",res_f);
665  pp_dereverb_decay = res_f;
666  } else
667  ast_log(LOG_ERROR,"Error! Preprocessor Dereverb Decay must be >= 0\n");
668  } else if (!strcasecmp(var->name, "pp_dereverb_level")) {
669  if (sscanf(var->value, "%30f", &res_f) == 1 && res_f >= 0) {
670  ast_verb(3, "CODEC SPEEX: Setting preprocessor Dereverb Level to %f\n",res_f);
671  pp_dereverb_level = res_f;
672  } else
673  ast_log(LOG_ERROR,"Error! Preprocessor Dereverb Level must be >= 0\n");
674  } else if (!strcasecmp(var->name, "experimental_rtcp_feedback")) {
675  exp_rtcp_fb = ast_true(var->value) ? 1 : 0;
676  ast_verb(3, "CODEC SPEEX: Experimental RTCP Feedback. [%s]\n",exp_rtcp_fb ? "on" : "off");
677  }
678  }
679  ast_config_destroy(cfg);
680  return 0;
681 }
struct ast_variable * next
static float pp_dereverb_decay
Definition: codec_speex.c:78
static int exp_rtcp_fb
Definition: codec_speex.c:70
static int quality
Definition: codec_speex.c:62
static int preproc
Definition: codec_speex.c:72
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1216
#define CONFIG_STATUS_FILEINVALID
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614
#define ast_verb(level,...)
Definition: logger.h:463
static int reload(void)
Definition: codec_speex.c:683
static int complexity
Definition: codec_speex.c:63
#define ast_log
Definition: astobj2.c:42
#define ast_config_load(filename, flags)
Load a config file.
static float pp_dereverb_level
Definition: codec_speex.c:79
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: extconf.c:1290
static int vbr
Definition: codec_speex.c:66
static int pp_vad
Definition: codec_speex.c:73
#define CONFIG_STATUS_FILEUNCHANGED
static int pp_dereverb
Definition: codec_speex.c:77
#define LOG_ERROR
Definition: logger.h:285
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
Definition: main/utils.c:1951
static int vad
Definition: codec_speex.c:65
static int dtx
Definition: codec_speex.c:69
static int pp_denoise
Definition: codec_speex.c:76
Structure used to handle boolean flags.
Definition: utils.h:199
#define CONFIG_STATUS_FILEMISSING
#define abs(x)
Definition: f2c.h:195
static int enhancement
Definition: codec_speex.c:64
static float vbr_quality
Definition: codec_speex.c:67
static float pp_agc_level
Definition: codec_speex.c:75
static int abr
Definition: codec_speex.c:68
static int pp_agc
Definition: codec_speex.c:74

◆ reload()

static int reload ( void  )
static

Definition at line 683 of file codec_speex.c.

References AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, and parse_config().

Referenced by load_module().

684 {
685  if (parse_config(1))
688 }
static int parse_config(int reload)
Definition: codec_speex.c:585
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78

◆ speex_decoder_construct()

static int speex_decoder_construct ( struct ast_trans_pvt pvt,
const SpeexMode *  profile 
)
static

Definition at line 172 of file codec_speex.c.

References speex_coder_pvt::bits, enhancement, speex_coder_pvt::framesize, ast_trans_pvt::pvt, speex_coder_pvt::speex, and tmp().

Referenced by speextolin_new(), speexuwbtolin32_new(), and speexwbtolin16_new().

173 {
174  struct speex_coder_pvt *tmp = pvt->pvt;
175 
176  if (!(tmp->speex = speex_decoder_init(profile)))
177  return -1;
178 
179  speex_bits_init(&tmp->bits);
180  speex_decoder_ctl(tmp->speex, SPEEX_GET_FRAME_SIZE, &tmp->framesize);
181  if (enhancement)
182  speex_decoder_ctl(tmp->speex, SPEEX_SET_ENH, &enhancement);
183 
184  return 0;
185 }
SpeexBits bits
Definition: codec_speex.c:95
static int tmp()
Definition: bt_open.c:389
void * pvt
Definition: translate.h:219
static int enhancement
Definition: codec_speex.c:64

◆ speex_encoder_construct()

static int speex_encoder_construct ( struct ast_trans_pvt pvt,
const SpeexMode *  profile,
int  sampling_rate 
)
static

Definition at line 111 of file codec_speex.c.

References abr, ast_debug, speex_coder_pvt::bits, complexity, speex_coder_pvt::default_quality, dtx, speex_coder_pvt::fraction_lost, speex_coder_pvt::framesize, pp_agc, pp_agc_level, pp_denoise, pp_dereverb, pp_dereverb_decay, pp_dereverb_level, pp_vad, preproc, ast_trans_pvt::pvt, speex_coder_pvt::quality, speex_coder_pvt::silent_state, speex_coder_pvt::speex, tmp(), vad, vbr, and vbr_quality.

Referenced by lin16tospeexwb_new(), lin32tospeexuwb_new(), and lintospeex_new().

112 {
113  struct speex_coder_pvt *tmp = pvt->pvt;
114 
115  if (!(tmp->speex = speex_encoder_init(profile)))
116  return -1;
117 
118  speex_bits_init(&tmp->bits);
119  speex_bits_reset(&tmp->bits);
120  speex_encoder_ctl(tmp->speex, SPEEX_GET_FRAME_SIZE, &tmp->framesize);
121  speex_encoder_ctl(tmp->speex, SPEEX_SET_COMPLEXITY, &complexity);
122 #ifdef _SPEEX_TYPES_H
123  if (preproc) {
124  tmp->pp = speex_preprocess_state_init(tmp->framesize, sampling_rate);
125  speex_preprocess_ctl(tmp->pp, SPEEX_PREPROCESS_SET_VAD, &pp_vad);
126  speex_preprocess_ctl(tmp->pp, SPEEX_PREPROCESS_SET_AGC, &pp_agc);
127  speex_preprocess_ctl(tmp->pp, SPEEX_PREPROCESS_SET_AGC_LEVEL, &pp_agc_level);
128  speex_preprocess_ctl(tmp->pp, SPEEX_PREPROCESS_SET_DENOISE, &pp_denoise);
129  speex_preprocess_ctl(tmp->pp, SPEEX_PREPROCESS_SET_DEREVERB, &pp_dereverb);
130  speex_preprocess_ctl(tmp->pp, SPEEX_PREPROCESS_SET_DEREVERB_DECAY, &pp_dereverb_decay);
131  speex_preprocess_ctl(tmp->pp, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &pp_dereverb_level);
132  }
133 #endif
134  if (!abr && !vbr) {
135  speex_encoder_ctl(tmp->speex, SPEEX_SET_QUALITY, &quality);
136  if (vad)
137  speex_encoder_ctl(tmp->speex, SPEEX_SET_VAD, &vad);
138  }
139  if (vbr) {
140  speex_encoder_ctl(tmp->speex, SPEEX_SET_VBR, &vbr);
141  speex_encoder_ctl(tmp->speex, SPEEX_SET_VBR_QUALITY, &vbr_quality);
142  }
143  if (abr)
144  speex_encoder_ctl(tmp->speex, SPEEX_SET_ABR, &abr);
145  if (dtx)
146  speex_encoder_ctl(tmp->speex, SPEEX_SET_DTX, &dtx);
147  tmp->silent_state = 0;
148 
149  tmp->fraction_lost = 0;
151  tmp->quality = tmp->default_quality;
152  ast_debug(3, "Default quality (%s): %d\n", vbr ? "vbr" : "cbr", tmp->default_quality);
153 
154  return 0;
155 }
static float pp_dereverb_decay
Definition: codec_speex.c:78
static int quality
Definition: codec_speex.c:62
static int preproc
Definition: codec_speex.c:72
SpeexBits bits
Definition: codec_speex.c:95
static int tmp()
Definition: bt_open.c:389
void * pvt
Definition: translate.h:219
static int complexity
Definition: codec_speex.c:63
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static float pp_dereverb_level
Definition: codec_speex.c:79
static int vbr
Definition: codec_speex.c:66
static int pp_vad
Definition: codec_speex.c:73
static int pp_dereverb
Definition: codec_speex.c:77
static int vad
Definition: codec_speex.c:65
static int dtx
Definition: codec_speex.c:69
static int pp_denoise
Definition: codec_speex.c:76
static float vbr_quality
Definition: codec_speex.c:67
static float pp_agc_level
Definition: codec_speex.c:75
static int abr
Definition: codec_speex.c:68
static int pp_agc
Definition: codec_speex.c:74

◆ speextolin_destroy()

static void speextolin_destroy ( struct ast_trans_pvt arg)
static

Definition at line 427 of file codec_speex.c.

References speex_coder_pvt::bits, ast_trans_pvt::pvt, and speex_coder_pvt::speex.

428 {
429  struct speex_coder_pvt *pvt = arg->pvt;
430 
431  speex_decoder_destroy(pvt->speex);
432  speex_bits_destroy(&pvt->bits);
433 }
SpeexBits bits
Definition: codec_speex.c:95
void * pvt
Definition: translate.h:219

◆ speextolin_framein()

static int speextolin_framein ( struct ast_trans_pvt pvt,
struct ast_frame f 
)
static

convert and store into outbuf

Definition at line 203 of file codec_speex.c.

References ast_log, speex_coder_pvt::bits, BUFFER_SAMPLES, ast_frame::data, ast_frame::datalen, ast_trans_pvt::datalen, speex_coder_pvt::framesize, ast_trans_pvt::i16, LOG_WARNING, NULL, ast_trans_pvt::outbuf, ast_frame::ptr, ast_trans_pvt::pvt, ast_trans_pvt::samples, speex_coder_pvt::speex, and tmp().

204 {
205  struct speex_coder_pvt *tmp = pvt->pvt;
206 
207  /* Assuming there's space left, decode into the current buffer at
208  the tail location. Read in as many frames as there are */
209  int x;
210  int res;
211  int16_t *dst = pvt->outbuf.i16;
212  /* XXX fout is a temporary buffer, may have different types */
213 #ifdef _SPEEX_TYPES_H
214  spx_int16_t fout[1024];
215 #else
216  float fout[1024];
217 #endif
218 
219  if (f->datalen == 0) { /* Native PLC interpolation */
220  if (pvt->samples + tmp->framesize > BUFFER_SAMPLES) {
221  ast_log(LOG_WARNING, "Out of buffer space\n");
222  return -1;
223  }
224 #ifdef _SPEEX_TYPES_H
225  speex_decode_int(tmp->speex, NULL, dst + pvt->samples);
226 #else
227  speex_decode(tmp->speex, NULL, fout);
228  for (x=0;x<tmp->framesize;x++) {
229  dst[pvt->samples + x] = (int16_t)fout[x];
230  }
231 #endif
232  pvt->samples += tmp->framesize;
233  pvt->datalen += 2 * tmp->framesize; /* 2 bytes/sample */
234  return 0;
235  }
236 
237  /* Read in bits */
238  speex_bits_read_from(&tmp->bits, f->data.ptr, f->datalen);
239  for (;;) {
240 #ifdef _SPEEX_TYPES_H
241  res = speex_decode_int(tmp->speex, &tmp->bits, fout);
242 #else
243  res = speex_decode(tmp->speex, &tmp->bits, fout);
244 #endif
245  if (res < 0)
246  break;
247  if (pvt->samples + tmp->framesize > BUFFER_SAMPLES) {
248  ast_log(LOG_WARNING, "Out of buffer space\n");
249  return -1;
250  }
251  for (x = 0 ; x < tmp->framesize; x++)
252  dst[pvt->samples + x] = (int16_t)fout[x];
253  pvt->samples += tmp->framesize;
254  pvt->datalen += 2 * tmp->framesize; /* 2 bytes/sample */
255  }
256  return 0;
257 }
int datalen
actual space used in outbuf
Definition: translate.h:218
short int16_t
Definition: db.h:59
SpeexBits bits
Definition: codec_speex.c:95
#define LOG_WARNING
Definition: logger.h:274
static int tmp()
Definition: bt_open.c:389
#define NULL
Definition: resample.c:96
void * pvt
Definition: translate.h:219
int16_t * i16
Definition: translate.h:223
#define ast_log
Definition: astobj2.c:42
union ast_trans_pvt::@327 outbuf
#define BUFFER_SAMPLES
Definition: codec_speex.c:86
union ast_frame::@263 data

◆ speextolin_new()

static int speextolin_new ( struct ast_trans_pvt pvt)
static

Definition at line 187 of file codec_speex.c.

References speex_decoder_construct().

188 {
189  return speex_decoder_construct(pvt, &speex_nb_mode);
190 }
static int speex_decoder_construct(struct ast_trans_pvt *pvt, const SpeexMode *profile)
Definition: codec_speex.c:172

◆ speexuwbtolin32_new()

static int speexuwbtolin32_new ( struct ast_trans_pvt pvt)
static

Definition at line 197 of file codec_speex.c.

References speex_decoder_construct().

198 {
199  return speex_decoder_construct(pvt, &speex_uwb_mode);
200 }
static int speex_decoder_construct(struct ast_trans_pvt *pvt, const SpeexMode *profile)
Definition: codec_speex.c:172

◆ speexwbtolin16_new()

static int speexwbtolin16_new ( struct ast_trans_pvt pvt)
static

Definition at line 192 of file codec_speex.c.

References speex_decoder_construct().

193 {
194  return speex_decoder_construct(pvt, &speex_wb_mode);
195 }
static int speex_decoder_construct(struct ast_trans_pvt *pvt, const SpeexMode *profile)
Definition: codec_speex.c:172

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 690 of file codec_speex.c.

References ast_unregister_translator().

Referenced by load_module().

691 {
698 
699  return 0;
700 }
static struct ast_translator lin16tospeexwb
Definition: codec_speex.c:516
static struct ast_translator lin32tospeexuwb
Definition: codec_speex.c:562
int ast_unregister_translator(struct ast_translator *t)
Unregister a translator Unregisters the given tranlator.
Definition: translate.c:1333
static struct ast_translator speexuwbtolin32
Definition: codec_speex.c:540
static struct ast_translator lintospeex
Definition: codec_speex.c:469
static struct ast_translator speexwbtolin16
Definition: codec_speex.c:493
static struct ast_translator speextolin
Definition: codec_speex.c:446

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Speex Coder/Decoder" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "30ef0c93b36035ec78c9cfd712d36d9b" , .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload, }
static

Definition at line 730 of file codec_speex.c.

◆ abr

int abr = 0
static

Definition at line 68 of file codec_speex.c.

Referenced by parse_config(), and speex_encoder_construct().

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 730 of file codec_speex.c.

◆ complexity

int complexity = 2
static

Definition at line 63 of file codec_speex.c.

Referenced by parse_config(), and speex_encoder_construct().

◆ dtx

int dtx = 0
static

Definition at line 69 of file codec_speex.c.

Referenced by lintospeex_frameout(), parse_config(), and speex_encoder_construct().

◆ enhancement

int enhancement = 0
static

Definition at line 64 of file codec_speex.c.

Referenced by parse_config(), and speex_decoder_construct().

◆ exp_rtcp_fb

int exp_rtcp_fb = 0
static

Definition at line 70 of file codec_speex.c.

Referenced by lintospeex_feedback(), and parse_config().

◆ lin16tospeexwb

struct ast_translator lin16tospeexwb
static

Definition at line 516 of file codec_speex.c.

◆ lin32tospeexuwb

struct ast_translator lin32tospeexuwb
static

Definition at line 562 of file codec_speex.c.

◆ lintospeex

struct ast_translator lintospeex
static

Definition at line 469 of file codec_speex.c.

◆ pp_agc

int pp_agc = 0
static

Definition at line 74 of file codec_speex.c.

Referenced by parse_config(), and speex_encoder_construct().

◆ pp_agc_level

float pp_agc_level = 8000
static

Definition at line 75 of file codec_speex.c.

Referenced by parse_config(), and speex_encoder_construct().

◆ pp_denoise

int pp_denoise = 0
static

Definition at line 76 of file codec_speex.c.

Referenced by parse_config(), and speex_encoder_construct().

◆ pp_dereverb

int pp_dereverb = 0
static

Definition at line 77 of file codec_speex.c.

Referenced by parse_config(), and speex_encoder_construct().

◆ pp_dereverb_decay

float pp_dereverb_decay = 0.4
static

Definition at line 78 of file codec_speex.c.

Referenced by parse_config(), and speex_encoder_construct().

◆ pp_dereverb_level

float pp_dereverb_level = 0.3
static

Definition at line 79 of file codec_speex.c.

Referenced by parse_config(), and speex_encoder_construct().

◆ pp_vad

int pp_vad = 0
static

Definition at line 73 of file codec_speex.c.

Referenced by parse_config(), and speex_encoder_construct().

◆ preproc

int preproc = 0
static

◆ quality

int quality = 3
static

Definition at line 62 of file codec_speex.c.

Referenced by ast_rtp_instance_set_stats_vars(), handle_request_bye(), and sip_hangup().

◆ speextolin

struct ast_translator speextolin
static

Definition at line 446 of file codec_speex.c.

◆ speexuwbtolin32

struct ast_translator speexuwbtolin32
static

Definition at line 540 of file codec_speex.c.

◆ speexwbtolin16

struct ast_translator speexwbtolin16
static

Definition at line 493 of file codec_speex.c.

◆ vad

int vad = 0
static

Definition at line 65 of file codec_speex.c.

Referenced by parse_config(), and speex_encoder_construct().

◆ vbr

int vbr = 0
static

Definition at line 66 of file codec_speex.c.

Referenced by lintospeex_feedback(), parse_config(), and speex_encoder_construct().

◆ vbr_quality

float vbr_quality = 4
static

Definition at line 67 of file codec_speex.c.

Referenced by parse_config(), and speex_encoder_construct().