FreeSWITCH API Documentation  1.7.0
Data Structures | Typedefs | Functions | Variables
switch_speex.c File Reference
#include <switch.h>
#include <speex/speex.h>
#include <speex/speex_preprocess.h>
+ Include dependency graph for switch_speex.c:

Go to the source code of this file.

Data Structures

struct  speex_codec_settings
 Various codec settings (currently only relevant to speex) More...
 
struct  speex_context
 

Typedefs

typedef struct speex_codec_settings speex_codec_settings_t
 

Functions

 SWITCH_MODULE_LOAD_FUNCTION (core_speex_load)
 
 SWITCH_MODULE_DEFINITION (CORE_SPEEX_MODULE, core_speex_load, NULL, NULL)
 
static switch_status_t switch_speex_fmtp_parse (const char *fmtp, switch_codec_fmtp_t *codec_fmtp)
 
static switch_status_t switch_speex_init (switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings)
 
static switch_status_t switch_speex_encode (switch_codec_t *codec, switch_codec_t *other_codec, void *decoded_data, uint32_t decoded_data_len, uint32_t decoded_rate, void *encoded_data, uint32_t *encoded_data_len, uint32_t *encoded_rate, unsigned int *flag)
 
static switch_status_t switch_speex_decode (switch_codec_t *codec, switch_codec_t *other_codec, void *encoded_data, uint32_t encoded_data_len, uint32_t encoded_rate, void *decoded_data, uint32_t *decoded_data_len, uint32_t *decoded_rate, unsigned int *flag)
 
static switch_status_t switch_speex_destroy (switch_codec_t *codec)
 
static void load_configuration ()
 

Variables

static speex_codec_settings_t default_codec_settings
 

Typedef Documentation

Definition at line 82 of file switch_speex.c.

Function Documentation

static void load_configuration ( )
static

read default settings from speex.conf

Definition at line 473 of file switch_speex.c.

References speex_codec_settings::abr, speex_codec_settings::complexity, speex_codec_settings::dtx, speex_codec_settings::enhancement, switch_xml::next, speex_codec_settings::pp_agc, speex_codec_settings::pp_agc_level, speex_codec_settings::pp_denoise, speex_codec_settings::pp_dereverb, speex_codec_settings::pp_dereverb_decay, speex_codec_settings::pp_dereverb_level, speex_codec_settings::pp_vad, speex_codec_settings::preproc, speex_codec_settings::quality, SWITCH_CHANNEL_LOG, switch_is_number(), SWITCH_LOG_DEBUG, SWITCH_LOG_ERROR, switch_log_printf(), switch_true(), switch_xml_attr(), switch_xml_child(), switch_xml_free(), switch_xml_open_cfg(), speex_codec_settings::vad, speex_codec_settings::vbr, speex_codec_settings::vbr_quality, and zstr.

Referenced by SWITCH_MODULE_LOAD_FUNCTION().

474 {
475  switch_xml_t xml = NULL, cfg = NULL;
476 
477  if ((xml = switch_xml_open_cfg("speex.conf", &cfg, NULL))) {
478  switch_xml_t x_lists;
479  if ((x_lists = switch_xml_child(cfg, "settings"))) {
480  const char *settings_name = switch_xml_attr(x_lists, "name");
481  switch_xml_t x_list;
482  if (zstr(settings_name)) {
483  settings_name = "";
484  }
485  for (x_list = switch_xml_child(x_lists, "param"); x_list; x_list = x_list->next) {
486  const char *name = switch_xml_attr(x_list, "name");
487  const char *value = switch_xml_attr(x_list, "value");
488  if (zstr(name)) {
489  continue;
490  }
491 
492  if (zstr(value)) {
493  continue;
494  }
495 
496  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s %s = %s\n", settings_name, name, value);
497 
498  if (!strcasecmp("quality", name)) {
499  /* compression quality, integer 0-10 */
500  int tmp = atoi(value);
501  if (switch_is_number(value) && tmp >= 0 && tmp <= 10) {
503  } else {
504  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ignoring invalid quality value: %s\n", value);
505  }
506  } else if (!strcasecmp("complexity", name)) {
507  /* compression complexity, integer 1-10 */
508  int tmp = atoi(value);
509  if (switch_is_number(value) && tmp >= 1 && tmp <= 10) {
511  } else {
512  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ignoring invalid complexity value: %s\n", value);
513  }
514  } else if (!strcasecmp("enhancement", name)) {
515  /* enable perceptual enhancement, boolean */
517  } else if (!strcasecmp("vad", name)) {
518  /* enable voice activity detection, boolean */
520  } else if (!strcasecmp("vbr", name)) {
521  /* enable variable bit rate, boolean */
523  } else if (!strcasecmp("vbr-quality", name)) {
524  /* variable bit rate quality, float 0-10 */
525  float tmp = (float)atof(value);
526  if (switch_is_number(value) && tmp >= 0 && tmp <= 10) {
528  } else {
529  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ignoring invalid vbr-quality value: %s\n", value);
530  }
531  } else if (!strcasecmp("abr", name)) {
532  /* average bit rate, integer bits per sec */
533  int tmp = atoi(value);
534  if (switch_is_number(value) && tmp >= 0) {
536  } else {
537  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ignoring invalid abr value: %s\n", value);
538  }
539  } else if (!strcasecmp("dtx", name)) {
540  /* discontinuous transmit, boolean */
542  } else if (!strcasecmp("preproc", name)) {
543  /* enable preprocessor, boolean */
545  } else if (!strcasecmp("pp-vad", name)) {
546  /* enable preprocessor VAD, boolean */
548  } else if (!strcasecmp("pp-agc", name)) {
549  /* enable preprocessor automatic gain control, boolean */
551  } else if (!strcasecmp("pp-agc-level", name)) {
552  /* agc level, float */
553  float tmp = (float)atof(value);
554  if (switch_is_number(value) && tmp >= 0.0f) {
556  } else {
557  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ignoring invalid pp-agc-level value: %s\n", value);
558  }
559  } else if (!strcasecmp("pp-denoise", name)) {
560  /* enable preprocessor denoiser, boolean */
562  } else if (!strcasecmp("pp-dereverb", name)) {
563  /* enable preprocessor reverberation removal, boolean */
565  } else if (!strcasecmp("pp-dereverb-decay", name)) {
566  /* reverberation removal decay, float */
567  float tmp = (float)atof(value);
568  if (switch_is_number(value) && tmp >= 0.0f) {
570  } else {
571  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ignoring invalid pp-dereverb-decay value: %s\n", value);
572  }
573  } else if (!strcasecmp("pp-dereverb-level", name)) {
574  /* reverberation removal level, float */
575  float tmp = (float)atof(value);
576  if (switch_is_number(value) && tmp >= 0.0f) {
578  } else {
579  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ignoring invalid pp-dereverb-level value: %s\n", value);
580  }
581  } else {
582  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ignoring invalid unknown param: %s = %s\n", name, value);
583  }
584  }
585  }
586  switch_xml_free(xml);
587  }
588 }
void switch_xml_free(_In_opt_ switch_xml_t xml)
frees the memory allocated for an switch_xml structure
#define SWITCH_CHANNEL_LOG
const char * switch_xml_attr(_In_opt_ switch_xml_t xml, _In_opt_z_ const char *attr)
returns the value of the requested tag attribute, or NULL if not found
switch_bool_t switch_is_number(const char *str)
A representation of an XML tree.
Definition: switch_xml.h:76
static int switch_true(const char *expr)
Evaluate the truthfullness of a string expression.
Definition: switch_utils.h:450
#define zstr(x)
Definition: switch_utils.h:281
switch_xml_t next
Definition: switch_xml.h:88
switch_xml_t switch_xml_open_cfg(_In_z_ const char *file_path, _Out_ switch_xml_t *node, _In_opt_ switch_event_t *params)
open a config in the core registry
switch_xml_t switch_xml_child(_In_ switch_xml_t xml, _In_z_ const char *name)
returns the first child tag (one level deeper) with the given name or NULL \ if not found ...
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
static speex_codec_settings_t default_codec_settings
Definition: switch_speex.c:84
SWITCH_MODULE_DEFINITION ( CORE_SPEEX_MODULE  ,
core_speex_load  ,
NULL  ,
NULL   
)
SWITCH_MODULE_LOAD_FUNCTION ( core_speex_load  )

Definition at line 590 of file switch_speex.c.

References load_configuration(), switch_codec_interface::parse_fmtp, pool, SWITCH_ADD_CODEC, SWITCH_CODEC_TYPE_AUDIO, switch_core_codec_add_implementation(), switch_loadable_module_create_module_interface(), switch_speex_decode(), switch_speex_destroy(), switch_speex_encode(), switch_speex_fmtp_parse(), switch_speex_init(), and SWITCH_STATUS_SUCCESS.

591 {
592  switch_codec_interface_t *codec_interface;
593  int mpf = 20000, spf = 160, bpf = 320, rate = 8000, counta, countb;
594  switch_payload_t ianacode[4] = { 0, 99, 99, 99 };
595  int bps[4] = { 0, 24600, 42200, 44000 };
596  /* connect my internal structure to the blank pointer passed to me */
597  *module_interface = switch_loadable_module_create_module_interface(pool, modname);
598 
600 
601  SWITCH_ADD_CODEC(codec_interface, "Speex");
602  codec_interface->parse_fmtp = switch_speex_fmtp_parse;
603  for (counta = 1; counta <= 3; counta++) {
604  for (countb = 1; countb > 0; countb--) {
605  switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
606  ianacode[counta], /* the IANA code number */
607  "SPEEX", /* the IANA code name */
608  NULL, /* default fmtp to send (can be overridden by the init function) */
609  rate, /* samples transferred per second */
610  rate, /* actual samples transferred per second */
611  bps[counta], /* bits transferred per second */
612  mpf * countb, /* number of microseconds per frame */
613  spf * countb, /* number of samples per frame */
614  bpf * countb, /* number of bytes per frame decompressed */
615  0, /* number of bytes per frame compressed */
616  1, /* number of channels represented */
617  1, /* number of frames per network packet */
618  switch_speex_init, /* function to initialize a codec handle using this implementation */
619  switch_speex_encode, /* function to encode raw data into encoded data */
620  switch_speex_decode, /* function to decode encoded data into raw data */
621  switch_speex_destroy); /* deinitalize a codec handle using this implementation */
622  }
623  rate = rate * 2;
624  spf = spf * 2;
625  bpf = bpf * 2;
626  }
627 
628 
629 
630 
631  /* indicate that the module should continue to be loaded */
632  return SWITCH_STATUS_SUCCESS;
633 }
switch_memory_pool_t * pool
static void switch_core_codec_add_implementation(switch_memory_pool_t *pool, switch_codec_interface_t *codec_interface, const switch_codec_type_t codec_type, switch_payload_t ianacode, const char *iananame, char *fmtp, uint32_t samples_per_second, uint32_t actual_samples_per_second, int bits_per_second, int microseconds_per_packet, uint32_t samples_per_packet, uint32_t decoded_bytes_per_packet, uint32_t encoded_bytes_per_packet, uint8_t number_of_channels, int codec_frames_per_packet, switch_core_codec_init_func_t init, switch_core_codec_encode_func_t encode, switch_core_codec_decode_func_t decode, switch_core_codec_destroy_func_t destroy)
static switch_status_t switch_speex_init(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings)
Definition: switch_speex.c:263
static switch_status_t switch_speex_encode(switch_codec_t *codec, switch_codec_t *other_codec, void *decoded_data, uint32_t decoded_data_len, uint32_t decoded_rate, void *encoded_data, uint32_t *encoded_data_len, uint32_t *encoded_rate, unsigned int *flag)
Definition: switch_speex.c:365
static switch_status_t switch_speex_decode(switch_codec_t *codec, switch_codec_t *other_codec, void *encoded_data, uint32_t encoded_data_len, uint32_t encoded_rate, void *decoded_data, uint32_t *decoded_data_len, uint32_t *decoded_rate, unsigned int *flag)
Definition: switch_speex.c:416
Top level module interface to implement a series of codec implementations.
#define SWITCH_ADD_CODEC(codec_int, int_name)
switch_core_codec_fmtp_parse_func_t parse_fmtp
static void load_configuration()
Definition: switch_speex.c:473
switch_loadable_module_interface_t * switch_loadable_module_create_module_interface(switch_memory_pool_t *pool, const char *name)
static switch_status_t switch_speex_fmtp_parse(const char *fmtp, switch_codec_fmtp_t *codec_fmtp)
Definition: switch_speex.c:122
static switch_status_t switch_speex_destroy(switch_codec_t *codec)
Definition: switch_speex.c:443
uint8_t switch_payload_t
static switch_status_t switch_speex_decode ( switch_codec_t codec,
switch_codec_t other_codec,
void *  encoded_data,
uint32_t  encoded_data_len,
uint32_t  encoded_rate,
void *  decoded_data,
uint32_t *  decoded_data_len,
uint32_t *  decoded_rate,
unsigned int *  flag 
)
static

Definition at line 416 of file switch_speex.c.

References buf, switch_codec_implementation::decoded_bytes_per_packet, speex_context::decoder_bits, speex_context::decoder_state, switch_codec::implementation, switch_codec::private_info, SWITCH_CODEC_FLAG_SILENCE, SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.

Referenced by SWITCH_MODULE_LOAD_FUNCTION().

422 {
423  struct speex_context *context = codec->private_info;
424  short *buf;
425 
426  if (!context) {
427  return SWITCH_STATUS_FALSE;
428  }
429 
430 
431  buf = decoded_data;
432  if (*flag & SWITCH_CODEC_FLAG_SILENCE) {
433  speex_decode_int(context->decoder_state, NULL, buf);
434  } else {
435  speex_bits_read_from(&context->decoder_bits, (char *) encoded_data, (int) encoded_data_len);
436  speex_decode_int(context->decoder_state, &context->decoder_bits, buf);
437  }
438  *decoded_data_len = codec->implementation->decoded_bytes_per_packet;
439 
440  return SWITCH_STATUS_SUCCESS;
441 }
void * decoder_state
Definition: switch_speex.c:116
struct SpeexBits decoder_bits
Definition: switch_speex.c:117
const switch_codec_implementation_t * implementation
switch_byte_t switch_byte_t * buf
static switch_status_t switch_speex_destroy ( switch_codec_t codec)
static

Definition at line 443 of file switch_speex.c.

References speex_context::decoder_bits, speex_context::decoder_state, speex_context::encoder_bits, speex_context::encoder_state, switch_codec::flags, switch_codec::private_info, SWITCH_CODEC_FLAG_DECODE, SWITCH_CODEC_FLAG_ENCODE, SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.

Referenced by SWITCH_MODULE_LOAD_FUNCTION().

444 {
445  int encoding, decoding;
446  struct speex_context *context = codec->private_info;
447 
448  if (!context) {
449  return SWITCH_STATUS_FALSE;
450  }
451 
452  encoding = (codec->flags & SWITCH_CODEC_FLAG_ENCODE);
453  decoding = (codec->flags & SWITCH_CODEC_FLAG_DECODE);
454 
455  if (encoding) {
456  speex_bits_destroy(&context->encoder_bits);
457  speex_encoder_destroy(context->encoder_state);
458  }
459 
460  if (decoding) {
461  speex_bits_destroy(&context->decoder_bits);
462  speex_decoder_destroy(context->decoder_state);
463  }
464 
465  codec->private_info = NULL;
466 
467  return SWITCH_STATUS_SUCCESS;
468 }
void * decoder_state
Definition: switch_speex.c:116
struct SpeexBits decoder_bits
Definition: switch_speex.c:117
void * encoder_state
Definition: switch_speex.c:109
struct SpeexBits encoder_bits
Definition: switch_speex.c:110
static switch_status_t switch_speex_encode ( switch_codec_t codec,
switch_codec_t other_codec,
void *  decoded_data,
uint32_t  decoded_data_len,
uint32_t  decoded_rate,
void *  encoded_data,
uint32_t *  encoded_data_len,
uint32_t *  encoded_rate,
unsigned int *  flag 
)
static

Definition at line 365 of file switch_speex.c.

References buf, speex_context::codec_settings, speex_codec_settings::dtx, speex_context::encoder_bits, speex_context::encoder_frame_size, speex_context::encoder_state, speex_context::pp, switch_codec::private_info, SFF_CNG, switch_clear_flag, SWITCH_CODEC_FLAG_SILENCE, switch_set_flag, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, and switch_test_flag.

Referenced by SWITCH_MODULE_LOAD_FUNCTION().

371 {
372  struct speex_context *context = codec->private_info;
373  short *buf;
374  int is_speech = 1;
375 
376  if (!context) {
377  return SWITCH_STATUS_FALSE;
378  }
379 
380  buf = decoded_data;
381 
382  if (context->pp) {
383  is_speech = speex_preprocess(context->pp, buf, NULL);
384  }
385 
386  if (is_speech) {
387  is_speech = speex_encode_int(context->encoder_state, buf, &context->encoder_bits)
388  || !context->codec_settings.dtx;
389  } else {
390  speex_bits_pack(&context->encoder_bits, 0, 5);
391  }
392 
393 
394  if (is_speech) {
396  *flag &= ~SFF_CNG;
397  } else {
399  *encoded_data_len = 0;
400  *flag |= SFF_CNG;
401  return SWITCH_STATUS_SUCCESS;
402  }
403 
405  }
406 
407 
408  speex_bits_pack(&context->encoder_bits, 15, 5);
409  *encoded_data_len = speex_bits_write(&context->encoder_bits, (char *) encoded_data, context->encoder_frame_size);
410  speex_bits_reset(&context->encoder_bits);
411  (*encoded_data_len)--;
412 
413  return SWITCH_STATUS_SUCCESS;
414 }
SpeexPreprocessState * pp
Definition: switch_speex.c:113
#define switch_set_flag(obj, flag)
Set a flag on an arbitrary object.
Definition: switch_utils.h:631
speex_codec_settings_t codec_settings
Definition: switch_speex.c:105
#define switch_clear_flag(obj, flag)
Clear a flag on an arbitrary object while locked.
Definition: switch_utils.h:655
switch_byte_t switch_byte_t * buf
void * encoder_state
Definition: switch_speex.c:109
unsigned int encoder_frame_size
Definition: switch_speex.c:111
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:624
struct SpeexBits encoder_bits
Definition: switch_speex.c:110
static switch_status_t switch_speex_fmtp_parse ( const char *  fmtp,
switch_codec_fmtp_t codec_fmtp 
)
static

Definition at line 122 of file switch_speex.c.

References switch_codec_fmtp::actual_samples_per_second, mode, speex_codec_settings::pp_vad, switch_codec_fmtp::private_info, speex_codec_settings::quality, switch_assert, SWITCH_CHANNEL_LOG, switch_is_number(), SWITCH_LOG_DEBUG1, switch_log_printf(), switch_separate_string(), SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_true(), speex_codec_settings::vad, speex_codec_settings::vbr, speex_codec_settings::vbr_quality, and zstr.

Referenced by SWITCH_MODULE_LOAD_FUNCTION(), and switch_speex_init().

123 {
125  int x, argc;
126  char *argv[10];
127  char *fmtp_dup = NULL;
128 
129  if (!codec_fmtp) {
130  return SWITCH_STATUS_FALSE;
131  }
132 
133  /* load default settings */
134  if (codec_fmtp->private_info) {
135  codec_settings = codec_fmtp->private_info;
136  memcpy(codec_settings, &default_codec_settings, sizeof(*codec_settings));
137  } else {
138  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "codec_fmtp->private_info is NULL\n");
139  return SWITCH_STATUS_SUCCESS;
140  }
141 
142  if (!fmtp) {
143  return SWITCH_STATUS_SUCCESS;
144  }
145 
146  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "got fmtp: %s\n", fmtp);
147 
148  fmtp_dup = strdup(fmtp);
149  switch_assert(fmtp_dup);
150 
151  /* parse ; separated fmtp args */
152  argc = switch_separate_string(fmtp_dup, ';', argv, (sizeof(argv) / sizeof(argv[0])));
153  for (x = 0; x < argc; x++) {
154  char *data = argv[x];
155  char *arg;
156  switch_assert(data);
157  while (*data == ' ') {
158  data++;
159  }
160  if (!(arg = strchr(data, '='))) {
161  continue;
162  }
163  *arg++ = '\0';
164  if (zstr(arg)) {
165  continue;
166  }
167 
168  if (!strcasecmp("vbr", data)) {
169  /* vbr can be on/off/vad */
170  if (!strcasecmp("vad", arg)) {
171  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "enabling speex vbr=vad\n");
172  codec_settings->vbr = 0;
173  codec_settings->vad = 1;
174  codec_settings->pp_vad = 1;
175  } else {
176  if (switch_true(arg)) {
177  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "enabling speex vbr\n");
178  codec_settings->vbr = 1;
179  codec_settings->vad = 0;
180  codec_settings->pp_vad = 1;
181  } else {
182  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "disabling speex vbr\n");
183  codec_settings->vbr = 0;
184  codec_settings->vad = 0;
185  codec_settings->pp_vad = 0;
186  }
187  }
188  } else if (!strcasecmp("cng", data)) {
189  /* TODO don't know how to turn on CNG */
190  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "speex cng is unsupported\n");
191  } else if (!strcasecmp("mode", data)) {
192  /* mode is a comma-separate list of preferred modes. Use the first mode in the list */
193  char *arg_dup;
194  char *mode[2];
195  if (!strncasecmp("any", arg, 3)) {
196  /* "any", keep the default setting */
197  continue;
198  }
199  arg_dup = strdup(arg);
200  if (switch_separate_string(arg_dup, ',', mode, (sizeof(mode) / sizeof(mode[0])))) {
201  int mode_num = -1;
202  char *mode_str = mode[0];
203  if (mode_str[0] == '"') {
204  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "mode starts with \"\n");
205  mode_str++;
206  }
207  if (switch_is_number(mode_str)) {
208  mode_num = atoi(mode_str);
209  }
210  /* TODO there might be a way to set the mode directly instead of changing the quality */
211  if (codec_fmtp->actual_samples_per_second == 8000) {
212  switch (mode_num) {
213  case 1:
214  codec_settings->quality = 0;
215  break;
216  case 2:
217  codec_settings->quality = 2;
218  break;
219  case 3:
220  codec_settings->quality = 4;
221  break;
222  case 4:
223  codec_settings->quality = 6;
224  break;
225  case 5:
226  codec_settings->quality = 8;
227  break;
228  case 6:
229  codec_settings->quality = 9;
230  break;
231  case 7:
232  codec_settings->quality = 10;
233  break;
234  case 8:
235  codec_settings->quality = 1;
236  break;
237  default:
238  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "ignoring invalid speex/8000 mode %s\n", mode_str);
239  continue;
240  }
241  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "choosing speex/8000 mode %s\n", mode_str);
242  codec_settings->vbr_quality = (float)codec_settings->quality;
243  } else {
244  if (mode_num >= 0 && mode_num <= 10) {
245  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "choosing speex/%d mode %s\n", codec_fmtp->actual_samples_per_second, mode_str);
246  codec_settings->quality = mode_num;
247  codec_settings->vbr_quality = (float)mode_num;
248  } else {
249  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "ignoring invalid speex/%d mode %s\n", codec_fmtp->actual_samples_per_second, mode_str);
250  continue;
251  }
252  }
253  }
254  free(arg_dup);
255  }
256  }
257  free(fmtp_dup);
258  /*codec_fmtp->bits_per_second = bit_rate;*/
259  return SWITCH_STATUS_SUCCESS;
260 }
#define SWITCH_CHANNEL_LOG
speex_codec_settings_t codec_settings
Definition: switch_speex.c:105
switch_bool_t switch_is_number(const char *str)
static int switch_true(const char *expr)
Evaluate the truthfullness of a string expression.
Definition: switch_utils.h:450
#define zstr(x)
Definition: switch_utils.h:281
unsigned int switch_separate_string(_In_ char *buf, char delim, _Post_count_(return) char **array, unsigned int arraylen)
Separate a string into an array based on a character delimiter.
switch_byte_t switch_byte_t uint32_t switch_bitpack_mode_t mode
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
#define switch_assert(expr)
Various codec settings (currently only relevant to speex)
Definition: switch_speex.c:47
static speex_codec_settings_t default_codec_settings
Definition: switch_speex.c:84
static switch_status_t switch_speex_init ( switch_codec_t codec,
switch_codec_flag_t  flags,
const switch_codec_settings_t codec_settings 
)
static

Definition at line 263 of file switch_speex.c.

References speex_codec_settings::abr, switch_codec_fmtp::actual_samples_per_second, switch_codec_implementation::actual_samples_per_second, speex_context::codec, speex_context::codec_settings, speex_codec_settings::complexity, speex_context::decoder_bits, speex_context::decoder_state, speex_codec_settings::dtx, speex_context::encoder_bits, speex_context::encoder_frame_size, speex_context::encoder_state, speex_codec_settings::enhancement, switch_codec::fmtp_in, switch_codec::implementation, switch_codec::memory_pool, memset(), mode, speex_context::pp, speex_codec_settings::pp_agc, speex_codec_settings::pp_agc_level, speex_codec_settings::pp_denoise, speex_codec_settings::pp_dereverb, speex_codec_settings::pp_dereverb_decay, speex_codec_settings::pp_dereverb_level, speex_codec_settings::pp_vad, speex_codec_settings::preproc, switch_codec_fmtp::private_info, switch_codec::private_info, speex_codec_settings::quality, SWITCH_CHANNEL_LOG, SWITCH_CODEC_FLAG_DECODE, SWITCH_CODEC_FLAG_ENCODE, switch_core_alloc, SWITCH_LOG_DEBUG1, switch_log_printf(), switch_speex_fmtp_parse(), SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, speex_codec_settings::vad, speex_codec_settings::vbr, and speex_codec_settings::vbr_quality.

Referenced by SWITCH_MODULE_LOAD_FUNCTION().

264 {
265  struct speex_context *context = NULL;
266  int encoding, decoding;
267 
268  encoding = (flags & SWITCH_CODEC_FLAG_ENCODE);
269  decoding = (flags & SWITCH_CODEC_FLAG_DECODE);
270 
271  if (!(encoding || decoding) || ((context = switch_core_alloc(codec->memory_pool, sizeof(*context))) == 0)) {
272  return SWITCH_STATUS_FALSE;
273  } else {
274  const SpeexMode *mode = NULL;
275  switch_codec_fmtp_t codec_fmtp;
277 
278  memset(&codec_fmtp, '\0', sizeof(struct switch_codec_fmtp));
279  codec_fmtp.private_info = &codec_settings;
281  switch_speex_fmtp_parse(codec->fmtp_in, &codec_fmtp);
282 
283  memcpy(&context->codec_settings, &codec_settings, sizeof(context->codec_settings));
284 
285  context->codec = codec;
286  if (codec->implementation->actual_samples_per_second == 8000) {
287  mode = &speex_nb_mode;
288  } else if (codec->implementation->actual_samples_per_second == 16000) {
289  mode = &speex_wb_mode;
290  } else if (codec->implementation->actual_samples_per_second == 32000) {
291  mode = &speex_uwb_mode;
292  }
293 
294  if (!mode) {
295  return SWITCH_STATUS_FALSE;
296  }
297 
298  if (encoding) {
299  speex_bits_init(&context->encoder_bits);
300  context->encoder_state = speex_encoder_init(mode);
301  speex_encoder_ctl(context->encoder_state, SPEEX_GET_FRAME_SIZE, &context->encoder_frame_size);
302  speex_encoder_ctl(context->encoder_state, SPEEX_SET_COMPLEXITY, &context->codec_settings.complexity);
303  if (context->codec_settings.preproc) {
305  context->pp = speex_preprocess_state_init(context->encoder_frame_size, codec->implementation->actual_samples_per_second);
306  if (context->codec_settings.pp_vad) {
307  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "preprocessor vad on\n");
308  }
309  speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_VAD, &context->codec_settings.pp_vad);
310  if (context->codec_settings.pp_agc) {
311  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "preprocessor agc on\n");
312  }
313  speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_AGC, &context->codec_settings.pp_agc);
314  speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_AGC_LEVEL, &context->codec_settings.pp_agc_level);
315  if (context->codec_settings.pp_denoise) {
316  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "preprocessor denoise on\n");
317  }
318  speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_DENOISE, &context->codec_settings.pp_denoise);
319  if (context->codec_settings.pp_dereverb) {
320  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "preprocessor dereverb on\n");
321  }
322  speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_DEREVERB, &context->codec_settings.pp_dereverb);
323  speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_DEREVERB_DECAY, &context->codec_settings.pp_dereverb_decay);
324  speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &context->codec_settings.pp_dereverb_level);
325  }
326 
327  if (!context->codec_settings.abr && !context->codec_settings.vbr) {
328  speex_encoder_ctl(context->encoder_state, SPEEX_SET_QUALITY, &context->codec_settings.quality);
329  if (context->codec_settings.vad) {
331  speex_encoder_ctl(context->encoder_state, SPEEX_SET_VAD, &context->codec_settings.vad);
332  }
333  }
334  if (context->codec_settings.vbr) {
336  speex_encoder_ctl(context->encoder_state, SPEEX_SET_VBR, &context->codec_settings.vbr);
337  speex_encoder_ctl(context->encoder_state, SPEEX_SET_VBR_QUALITY, &context->codec_settings.vbr_quality);
338  }
339  if (context->codec_settings.abr) {
341  speex_encoder_ctl(context->encoder_state, SPEEX_SET_ABR, &context->codec_settings.abr);
342  }
343  if (context->codec_settings.dtx) {
345  speex_encoder_ctl(context->encoder_state, SPEEX_SET_DTX, &context->codec_settings.dtx);
346  }
347  }
348 
349  if (decoding) {
350  speex_bits_init(&context->decoder_bits);
351  context->decoder_state = speex_decoder_init(mode);
352  if (context->codec_settings.enhancement) {
353  speex_decoder_ctl(context->decoder_state, SPEEX_SET_ENH, &context->codec_settings.enhancement);
354  }
355  }
356 
357 
358 
359  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "initialized Speex codec \n");
360  codec->private_info = context;
361  return SWITCH_STATUS_SUCCESS;
362  }
363 }
SpeexPreprocessState * pp
Definition: switch_speex.c:113
#define SWITCH_CHANNEL_LOG
void * decoder_state
Definition: switch_speex.c:116
speex_codec_settings_t codec_settings
Definition: switch_speex.c:105
struct SpeexBits decoder_bits
Definition: switch_speex.c:117
const switch_codec_implementation_t * implementation
#define switch_core_alloc(_pool, _mem)
Allocate memory directly from a memory pool.
Definition: switch_core.h:682
switch_memory_pool_t * memory_pool
void * encoder_state
Definition: switch_speex.c:109
unsigned int flags
Definition: switch_speex.c:106
switch_byte_t switch_byte_t uint32_t switch_bitpack_mode_t mode
unsigned int encoder_frame_size
Definition: switch_speex.c:111
switch_codec_t * codec
Definition: switch_speex.c:104
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
static switch_status_t switch_speex_fmtp_parse(const char *fmtp, switch_codec_fmtp_t *codec_fmtp)
Definition: switch_speex.c:122
memset(buf, 0, buflen)
Various codec settings (currently only relevant to speex)
Definition: switch_speex.c:47
struct SpeexBits encoder_bits
Definition: switch_speex.c:110

Variable Documentation

speex_codec_settings_t default_codec_settings
static
Initial value:
= {
5,
5,
1,
0,
0,
4,
0,
0,
0,
0,
0,
8000,
0,
0,
0.4f,
0.3f,
}

Definition at line 84 of file switch_speex.c.