Asterisk - The Open Source Telephony Project  18.5.0
codec_resample.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2011, Digium, Inc.
5  *
6  * Russell Bryant <[email protected]>
7  * David Vossel <[email protected]>
8  *
9  * See http://www.asterisk.org for more information about
10  * the Asterisk project. Please do not directly contact
11  * any of the maintainers of this project for assistance;
12  * the project provides a web site, mailing lists and IRC
13  * channels for your use.
14  *
15  * This program is free software, distributed under the terms of
16  * the GNU General Public License Version 2. See the LICENSE file
17  * at the top of the source tree.
18  */
19 
20 /*!
21  * \file
22  *
23  * \brief Resample slinear audio
24  *
25  * \ingroup codecs
26  */
27 
28 /*** MODULEINFO
29  <support_level>core</support_level>
30  ***/
31 
32 #include "asterisk.h"
33 #include "speex/speex_resampler.h"
34 
35 #include "asterisk/module.h"
36 #include "asterisk/translate.h"
37 #include "asterisk/slin.h"
38 
39 #define OUTBUF_SAMPLES 11520
40 
41 static struct ast_translator *translators;
42 static int trans_size;
43 static struct ast_codec codec_list[] = {
44  {
45  .name = "slin",
46  .type = AST_MEDIA_TYPE_AUDIO,
47  .sample_rate = 8000,
48  },
49  {
50  .name = "slin",
51  .type = AST_MEDIA_TYPE_AUDIO,
52  .sample_rate = 12000,
53  },
54  {
55  .name = "slin",
56  .type = AST_MEDIA_TYPE_AUDIO,
57  .sample_rate = 16000,
58  },
59  {
60  .name = "slin",
61  .type = AST_MEDIA_TYPE_AUDIO,
62  .sample_rate = 24000,
63  },
64  {
65  .name = "slin",
66  .type = AST_MEDIA_TYPE_AUDIO,
67  .sample_rate = 32000,
68  },
69  {
70  .name = "slin",
71  .type = AST_MEDIA_TYPE_AUDIO,
72  .sample_rate = 44100,
73  },
74  {
75  .name = "slin",
76  .type = AST_MEDIA_TYPE_AUDIO,
77  .sample_rate = 48000,
78  },
79  {
80  .name = "slin",
81  .type = AST_MEDIA_TYPE_AUDIO,
82  .sample_rate = 96000,
83  },
84  {
85  .name = "slin",
86  .type = AST_MEDIA_TYPE_AUDIO,
87  .sample_rate = 192000,
88  },
89 };
90 
91 static int resamp_new(struct ast_trans_pvt *pvt)
92 {
93  int err;
94 
95  if (!(pvt->pvt = speex_resampler_init(1, pvt->t->src_codec.sample_rate, pvt->t->dst_codec.sample_rate, 5, &err))) {
96  return -1;
97  }
98 
99  ast_assert(pvt->f.subclass.format == NULL);
101 
102  return 0;
103 }
104 
105 static void resamp_destroy(struct ast_trans_pvt *pvt)
106 {
107  SpeexResamplerState *resamp_pvt = pvt->pvt;
108 
109  speex_resampler_destroy(resamp_pvt);
110 }
111 
112 static int resamp_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
113 {
114  SpeexResamplerState *resamp_pvt = pvt->pvt;
115  unsigned int out_samples = OUTBUF_SAMPLES - pvt->samples;
116  unsigned int in_samples;
117 
118  if (!f->datalen) {
119  return -1;
120  }
121  in_samples = f->datalen / 2;
122 
123  speex_resampler_process_int(resamp_pvt,
124  0,
125  f->data.ptr,
126  &in_samples,
127  pvt->outbuf.i16 + pvt->samples,
128  &out_samples);
129 
130  pvt->samples += out_samples;
131  pvt->datalen += out_samples * 2;
132 
133  return 0;
134 }
135 
136 static int unload_module(void)
137 {
138  int res = 0;
139  int idx;
140 
141  for (idx = 0; idx < trans_size; idx++) {
142  res |= ast_unregister_translator(&translators[idx]);
143  }
144  ast_free(translators);
145 
146  return res;
147 }
148 
149 static int load_module(void)
150 {
151  int res = 0;
152  int x, y, idx = 0;
153 
154  trans_size = ARRAY_LEN(codec_list) * (ARRAY_LEN(codec_list) - 1);
155  if (!(translators = ast_calloc(1, sizeof(struct ast_translator) * trans_size))) {
157  }
158 
159  for (x = 0; x < ARRAY_LEN(codec_list); x++) {
160  for (y = 0; y < ARRAY_LEN(codec_list); y++) {
161  if (x == y) {
162  continue;
163  }
164  translators[idx].newpvt = resamp_new;
165  translators[idx].destroy = resamp_destroy;
166  translators[idx].framein = resamp_framein;
167  translators[idx].desc_size = 0;
168  translators[idx].buffer_samples = OUTBUF_SAMPLES;
169  translators[idx].buf_size = (OUTBUF_SAMPLES * sizeof(int16_t));
170  memcpy(&translators[idx].src_codec, &codec_list[x], sizeof(struct ast_codec));
171  memcpy(&translators[idx].dst_codec, &codec_list[y], sizeof(struct ast_codec));
172  snprintf(translators[idx].name, sizeof(translators[idx].name), "slin %ukhz -> %ukhz",
173  translators[idx].src_codec.sample_rate, translators[idx].dst_codec.sample_rate);
174  res |= ast_register_translator(&translators[idx]);
175  idx++;
176  }
177 
178  }
179  /* in case ast_register_translator() failed, we call unload_module() and
180  ast_unregister_translator won't fail.*/
181  if (res) {
182  unload_module();
184  }
185 
187 }
188 
189 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "SLIN Resampling Codec");
static int trans_size
int datalen
actual space used in outbuf
Definition: translate.h:218
#define AST_MODULE_INFO_STANDARD(keystr, desc)
Definition: module.h:567
const char * name
Name for this codec.
Definition: codec.h:46
Asterisk main include file. File version handling, generic pbx functions.
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
int(* newpvt)(struct ast_trans_pvt *)
Definition: translate.h:151
Descriptor of a translator.
Definition: translate.h:137
short int16_t
Definition: db.h:59
Support for translation of data formats. translate.c.
struct ast_frame f
Definition: translate.h:215
static void resamp_destroy(struct ast_trans_pvt *pvt)
EXPORT SpeexResamplerState * speex_resampler_init(spx_uint32_t nb_channels, spx_uint32_t in_rate, spx_uint32_t out_rate, int quality, int *err)
Create a new resampler with integer input and output rates.
Definition: resample.c:783
#define ast_assert(a)
Definition: utils.h:695
static int resamp_new(struct ast_trans_pvt *pvt)
#define NULL
Definition: resample.c:96
void * pvt
Definition: translate.h:219
static int load_module(void)
struct ast_frame_subclass subclass
int16_t * i16
Definition: translate.h:223
#define ao2_bump(obj)
Definition: astobj2.h:491
#define ast_register_translator(t)
See __ast_register_translator()
Definition: translate.h:257
int ast_unregister_translator(struct ast_translator *t)
Unregister a translator Unregisters the given tranlator.
Definition: translate.c:1333
static int resamp_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
static struct ast_codec codec_list[]
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
void(* destroy)(struct ast_trans_pvt *pvt)
Definition: translate.h:166
struct ast_codec dst_codec
Definition: translate.h:140
#define OUTBUF_SAMPLES
Default structure for translators, with the basic fields and buffers, all allocated as part of the sa...
Definition: translate.h:213
struct ast_codec src_codec
Definition: translate.h:139
static struct ast_translator * translators
static const char name[]
Definition: cdr_mysql.c:74
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
unsigned int sample_rate
Sample rate (number of samples carried in a second)
Definition: codec.h:52
EXPORT void speex_resampler_destroy(SpeexResamplerState *st)
Definition: resample.c:849
static int unload_module(void)
Data structure associated with a single frame of data.
struct ast_translator * t
Definition: translate.h:214
union ast_frame::@263 data
struct ast_format * format
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
Asterisk module definitions.
Represents a media codec within Asterisk.
Definition: codec.h:42
EXPORT int speex_resampler_process_int(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_int16_t *in, spx_uint32_t *in_len, spx_int16_t *out, spx_uint32_t *out_len)
Definition: resample.c:906
struct ast_format * ast_format_cache_get_slin_by_rate(unsigned int rate)
Retrieve the best signed linear format given a sample rate.
Definition: format_cache.c:520
int(* framein)(struct ast_trans_pvt *pvt, struct ast_frame *in)
Definition: translate.h:154
int buffer_samples
size of outbuf, in samples. Leave it 0 if you want the framein callback deal with the frame...
Definition: translate.h:177