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

codec_adpcm.c - translate between signed linear and Dialogic ADPCM More...

#include "asterisk.h"
#include "asterisk/lock.h"
#include "asterisk/linkedlists.h"
#include "asterisk/module.h"
#include "asterisk/config.h"
#include "asterisk/translate.h"
#include "asterisk/utils.h"
#include "asterisk/slin.h"
#include "ex_adpcm.h"
Include dependency graph for codec_adpcm.c:

Go to the source code of this file.

Data Structures

struct  adpcm_decoder_pvt
 Workspace for translating ADPCM signals to signed linear. More...
 
struct  adpcm_encoder_pvt
 Workspace for translating signed linear signals to ADPCM. More...
 
struct  adpcm_state
 

Macros

#define BUFFER_SAMPLES   8096 /* size for the translation buffers */
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
static int adpcm (short csig, struct adpcm_state *state)
 
static int adpcmtolin_framein (struct ast_trans_pvt *pvt, struct ast_frame *f)
 decode 4-bit adpcm frame data and store in output buffer More...
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static short decode (int encoded, struct adpcm_state *state)
 
static int lintoadpcm_framein (struct ast_trans_pvt *pvt, struct ast_frame *f)
 fill input buffer with 16-bit signed linear PCM values. More...
 
static struct ast_framelintoadpcm_frameout (struct ast_trans_pvt *pvt)
 convert inbuf and store into frame More...
 
static int load_module (void)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Adaptive Differential PCM 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, }
 
static struct ast_translator adpcmtolin
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static int indsft [8] = { -1, -1, -1, -1, 2, 4, 6, 8 }
 
static struct ast_translator lintoadpcm
 
static int stpsz [49]
 

Detailed Description

codec_adpcm.c - translate between signed linear and Dialogic ADPCM

Definition in file codec_adpcm.c.

Macro Definition Documentation

◆ BUFFER_SAMPLES

#define BUFFER_SAMPLES   8096 /* size for the translation buffers */

Definition at line 46 of file codec_adpcm.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 359 of file codec_adpcm.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 359 of file codec_adpcm.c.

◆ adpcm()

static int adpcm ( short  csig,
struct adpcm_state state 
)
inlinestatic

Definition at line 164 of file codec_adpcm.c.

References decode(), adpcm_state::signal, adpcm_state::ssindex, and stpsz.

Referenced by lintoadpcm_frameout().

165 {
166  int diff;
167  int step;
168  int encoded;
169 
170  /*
171  * Clip csig if too large or too small
172  */
173  csig >>= 4;
174 
175  step = stpsz[state->ssindex];
176  diff = csig - state->signal;
177 
178 #ifdef NOT_BLI
179  if (diff < 0) {
180  encoded = (-diff << 2) / step;
181  if (encoded > 7)
182  encoded = 7;
183  encoded |= 0x08;
184  } else {
185  encoded = (diff << 2) / step;
186  if (encoded > 7)
187  encoded = 7;
188  }
189 #else /* BLI code */
190  if (diff < 0) {
191  encoded = 8;
192  diff = -diff;
193  } else
194  encoded = 0;
195  if (diff >= step) {
196  encoded |= 4;
197  diff -= step;
198  }
199  step >>= 1;
200  if (diff >= step) {
201  encoded |= 2;
202  diff -= step;
203  }
204  step >>= 1;
205  if (diff >= step)
206  encoded |= 1;
207 #endif /* NOT_BLI */
208 
209  /* feedback to state */
210  decode(encoded, state);
211 
212  return encoded;
213 }
static int stpsz[49]
Definition: codec_adpcm.c:62
static short decode(int encoded, struct adpcm_state *state)
Definition: codec_adpcm.c:91

◆ adpcmtolin_framein()

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

decode 4-bit adpcm frame data and store in output buffer

Definition at line 229 of file codec_adpcm.c.

References ast_frame::data, ast_frame::datalen, ast_trans_pvt::datalen, decode(), ast_trans_pvt::i16, ast_trans_pvt::outbuf, ast_frame::ptr, ast_trans_pvt::pvt, ast_frame::samples, ast_trans_pvt::samples, adpcm_decoder_pvt::state, and tmp().

230 {
231  struct adpcm_decoder_pvt *tmp = pvt->pvt;
232  int x = f->datalen;
233  unsigned char *src = f->data.ptr;
234  int16_t *dst = pvt->outbuf.i16 + pvt->samples;
235 
236  while (x--) {
237  *dst++ = decode((*src >> 4) & 0xf, &tmp->state);
238  *dst++ = decode(*src++ & 0x0f, &tmp->state);
239  }
240  pvt->samples += f->samples;
241  pvt->datalen += 2*f->samples;
242  return 0;
243 }
int datalen
actual space used in outbuf
Definition: translate.h:218
Workspace for translating ADPCM signals to signed linear.
Definition: codec_adpcm.c:224
short int16_t
Definition: db.h:59
static int tmp()
Definition: bt_open.c:389
void * pvt
Definition: translate.h:219
int16_t * i16
Definition: translate.h:223
union ast_trans_pvt::@327 outbuf
union ast_frame::@263 data
struct adpcm_state state
Definition: codec_adpcm.c:225
static short decode(int encoded, struct adpcm_state *state)
Definition: codec_adpcm.c:91

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 359 of file codec_adpcm.c.

◆ decode()

static short decode ( int  encoded,
struct adpcm_state state 
)
inlinestatic

Definition at line 91 of file codec_adpcm.c.

References indsft, adpcm_state::next_flag, adpcm_state::signal, adpcm_state::ssindex, stpsz, and adpcm_state::zero_count.

Referenced by adpcm(), and adpcmtolin_framein().

92 {
93  int diff;
94  int step;
95  int sign;
96 
97  step = stpsz[state->ssindex];
98 
99  sign = encoded & 0x08;
100  encoded &= 0x07;
101 #ifdef NOT_BLI
102  diff = (((encoded << 1) + 1) * step) >> 3;
103 #else /* BLI code */
104  diff = step >> 3;
105  if (encoded & 4)
106  diff += step;
107  if (encoded & 2)
108  diff += step >> 1;
109  if (encoded & 1)
110  diff += step >> 2;
111  if ((encoded >> 1) & step & 0x1)
112  diff++;
113 #endif
114  if (sign)
115  diff = -diff;
116 
117  if (state->next_flag & 0x1)
118  state->signal -= 8;
119  else if (state->next_flag & 0x2)
120  state->signal += 8;
121 
122  state->signal += diff;
123 
124  if (state->signal > 2047)
125  state->signal = 2047;
126  else if (state->signal < -2047)
127  state->signal = -2047;
128 
129  state->next_flag = 0;
130 
131 #ifdef AUTO_RETURN
132  if (encoded)
133  state->zero_count = 0;
134  else if (++(state->zero_count) == 24) {
135  state->zero_count = 0;
136  if (state->signal > 0)
137  state->next_flag = 0x1;
138  else if (state->signal < 0)
139  state->next_flag = 0x2;
140  }
141 #endif
142 
143  state->ssindex += indsft[encoded];
144  if (state->ssindex < 0)
145  state->ssindex = 0;
146  else if (state->ssindex > 48)
147  state->ssindex = 48;
148 
149  return state->signal << 4;
150 }
static int indsft[8]
Definition: codec_adpcm.c:56
int zero_count
Definition: codec_adpcm.c:76
static int stpsz[49]
Definition: codec_adpcm.c:62

◆ lintoadpcm_framein()

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

fill input buffer with 16-bit signed linear PCM values.

Definition at line 246 of file codec_adpcm.c.

References ast_frame::data, ast_frame::datalen, adpcm_encoder_pvt::inbuf, ast_frame::ptr, ast_trans_pvt::pvt, ast_frame::samples, ast_trans_pvt::samples, and tmp().

247 {
248  struct adpcm_encoder_pvt *tmp = pvt->pvt;
249 
250  memcpy(&tmp->inbuf[pvt->samples], f->data.ptr, f->datalen);
251  pvt->samples += f->samples;
252  return 0;
253 }
static int tmp()
Definition: bt_open.c:389
void * pvt
Definition: translate.h:219
Workspace for translating signed linear signals to ADPCM.
Definition: codec_adpcm.c:218
union ast_frame::@263 data
int16_t inbuf[BUFFER_SAMPLES]
Definition: codec_adpcm.c:220

◆ lintoadpcm_frameout()

static struct ast_frame* lintoadpcm_frameout ( struct ast_trans_pvt pvt)
static

convert inbuf and store into frame

Definition at line 256 of file codec_adpcm.c.

References adpcm(), ast_trans_frameout(), ast_trans_pvt::c, adpcm_encoder_pvt::inbuf, NULL, ast_trans_pvt::outbuf, ast_trans_pvt::pvt, ast_frame::samples, ast_trans_pvt::samples, adpcm_encoder_pvt::state, and tmp().

257 {
258  struct adpcm_encoder_pvt *tmp = pvt->pvt;
259  struct ast_frame *f;
260  int i;
261  int samples = pvt->samples; /* save original number */
262 
263  if (samples < 2)
264  return NULL;
265 
266  pvt->samples &= ~1; /* atomic size is 2 samples */
267 
268  for (i = 0; i < pvt->samples; i += 2) {
269  pvt->outbuf.c[i/2] =
270  (adpcm(tmp->inbuf[i ], &tmp->state) << 4) |
271  (adpcm(tmp->inbuf[i+1], &tmp->state) );
272  };
273 
274  f = ast_trans_frameout(pvt, pvt->samples/2, 0);
275 
276  /*
277  * If there is a left over sample, move it to the beginning
278  * of the input buffer.
279  */
280 
281  if (samples & 1) { /* move the leftover sample at beginning */
282  tmp->inbuf[0] = tmp->inbuf[samples - 1];
283  pvt->samples = 1;
284  }
285  return f;
286 }
struct ast_frame * ast_trans_frameout(struct ast_trans_pvt *pvt, int datalen, int samples)
generic frameout function
Definition: translate.c:438
static int tmp()
Definition: bt_open.c:389
static int adpcm(short csig, struct adpcm_state *state)
Definition: codec_adpcm.c:164
#define NULL
Definition: resample.c:96
void * pvt
Definition: translate.h:219
union ast_trans_pvt::@327 outbuf
Data structure associated with a single frame of data.
Workspace for translating signed linear signals to ADPCM.
Definition: codec_adpcm.c:218
int16_t inbuf[BUFFER_SAMPLES]
Definition: codec_adpcm.c:220
struct adpcm_state state
Definition: codec_adpcm.c:219

◆ load_module()

static int load_module ( void  )
static

Definition at line 340 of file codec_adpcm.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, and unload_module().

341 {
342  int res = 0;
343 
346 
347  if (res) {
348  unload_module();
350  }
351 
353 }
static struct ast_translator lintoadpcm
Definition: codec_adpcm.c:309
#define ast_register_translator(t)
See __ast_register_translator()
Definition: translate.h:257
static struct ast_translator adpcmtolin
Definition: codec_adpcm.c:289
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
static int unload_module(void)
Definition: codec_adpcm.c:330

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 330 of file codec_adpcm.c.

References ast_unregister_translator().

Referenced by load_module().

331 {
332  int res;
333 
336 
337  return res;
338 }
static struct ast_translator lintoadpcm
Definition: codec_adpcm.c:309
int ast_unregister_translator(struct ast_translator *t)
Unregister a translator Unregisters the given tranlator.
Definition: translate.c:1333
static struct ast_translator adpcmtolin
Definition: codec_adpcm.c:289

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Adaptive Differential PCM 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, }
static

Definition at line 359 of file codec_adpcm.c.

◆ adpcmtolin

struct ast_translator adpcmtolin
static

Definition at line 289 of file codec_adpcm.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 359 of file codec_adpcm.c.

◆ indsft

int indsft[8] = { -1, -1, -1, -1, 2, 4, 6, 8 }
static

Definition at line 56 of file codec_adpcm.c.

Referenced by decode().

◆ lintoadpcm

struct ast_translator lintoadpcm
static

Definition at line 309 of file codec_adpcm.c.

◆ stpsz

int stpsz[49]
static

Definition at line 62 of file codec_adpcm.c.

Referenced by adpcm(), and decode().