Wed Jan 8 2020 09:50:13

Asterisk developer's documentation


func_pitchshift.c File Reference

Pitch Shift Audio Effect. More...

#include "asterisk.h"
#include "asterisk/module.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/utils.h"
#include "asterisk/audiohook.h"
#include <math.h>

Go to the source code of this file.

Data Structures

struct  fft_data
 
struct  pitchshift_data
 

Macros

#define HIGH   1.25
 
#define HIGHER   1.5
 
#define HIGHEST   2
 
#define LOW   .85
 
#define LOWER   .7
 
#define LOWEST   .5
 
#define M_PI   3.14159265358979323846
 
#define MAX_FRAME_LENGTH   256
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
static void destroy_callback (void *data)
 
static int load_module (void)
 
static int pitch_shift (struct ast_frame *f, float amount, struct fft_data *fft_data)
 
static int pitchshift_cb (struct ast_audiohook *audiohook, struct ast_channel *chan, struct ast_frame *f, enum ast_audiohook_direction direction)
 
static int pitchshift_helper (struct ast_channel *chan, const char *cmd, char *data, const char *value)
 
static void smb_fft (float *fft_buffer, long fft_frame_size, long sign)
 
static void smb_pitch_shift (float pitchShift, long num_samps_to_process, long fft_frame_size, long osamp, float sample_rate, int16_t *indata, int16_t *outdata, struct fft_data *fft_data)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Audio Effects Dialplan Functions" , .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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, }
 
static struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_custom_function pitch_shift_function
 
static struct ast_datastore_info pitchshift_datastore
 

Detailed Description

Pitch Shift Audio Effect.

Author
David Vossel dvoss.nosp@m.el@d.nosp@m.igium.nosp@m..com

Definition in file func_pitchshift.c.

Macro Definition Documentation

#define HIGH   1.25

Definition at line 122 of file func_pitchshift.c.

Referenced by pitchshift_helper().

#define HIGHER   1.5

Definition at line 121 of file func_pitchshift.c.

Referenced by pitchshift_helper().

#define HIGHEST   2

Definition at line 120 of file func_pitchshift.c.

Referenced by pitchshift_helper().

#define LOW   .85

Definition at line 123 of file func_pitchshift.c.

Referenced by pitchshift_helper().

#define LOWER   .7

Definition at line 124 of file func_pitchshift.c.

Referenced by pitchshift_helper().

#define LOWEST   .5

Definition at line 125 of file func_pitchshift.c.

Referenced by pitchshift_helper().

#define M_PI   3.14159265358979323846
#define MAX_FRAME_LENGTH   256

Definition at line 118 of file func_pitchshift.c.

Referenced by pitch_shift().

Function Documentation

static void __reg_module ( void  )
static

Definition at line 515 of file func_pitchshift.c.

static void __unreg_module ( void  )
static

Definition at line 515 of file func_pitchshift.c.

static void destroy_callback ( void *  data)
static

Definition at line 153 of file func_pitchshift.c.

References ast_audiohook_destroy(), ast_free, and pitchshift_data::audiohook.

154 {
155  struct pitchshift_data *shift = data;
156 
158  ast_free(shift);
159 };
struct ast_audiohook audiohook
int ast_audiohook_destroy(struct ast_audiohook *audiohook)
Destroys an audiohook structure.
Definition: audiohook.c:96
#define ast_free(a)
Definition: astmm.h:97
static int load_module ( void  )
static

Definition at line 509 of file func_pitchshift.c.

References ast_custom_function_register, AST_MODULE_LOAD_DECLINE, and AST_MODULE_LOAD_SUCCESS.

510 {
513 }
static struct ast_custom_function pitch_shift_function
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1164
static int pitch_shift ( struct ast_frame f,
float  amount,
struct fft_data fft_data 
)
static

Definition at line 483 of file func_pitchshift.c.

References ast_format_rate(), ast_frame_subclass::codec, ast_frame::data, if(), MAX_FRAME_LENGTH, ast_frame::ptr, ast_frame::samples, smb_pitch_shift(), and ast_frame::subclass.

Referenced by pitchshift_cb().

484 {
485  int16_t *fun = (int16_t *) f->data.ptr;
486  int samples;
487 
488  /* an amount of 1 has no effect */
489  if (!amount || amount == 1 || !fun || (f->samples % 32)) {
490  return 0;
491  }
492  for (samples = 0; samples < f->samples; samples += 32) {
493  smb_pitch_shift(amount, 32, MAX_FRAME_LENGTH, 32, ast_format_rate(f->subclass.codec), fun+samples, fun+samples, fft);
494  }
495 
496  return 0;
497 }
#define MAX_FRAME_LENGTH
union ast_frame_subclass subclass
Definition: frame.h:146
void * ptr
Definition: frame.h:160
static force_inline int ast_format_rate(format_t format)
Get the sample rate for a given format.
Definition: frame.h:809
format_t codec
Definition: frame.h:137
static void smb_pitch_shift(float pitchShift, long num_samps_to_process, long fft_frame_size, long osamp, float sample_rate, int16_t *indata, int16_t *outdata, struct fft_data *fft_data)
if(yyss+yystacksize-1<=yyssp)
Definition: ast_expr2.c:1874
union ast_frame::@172 data
int samples
Definition: frame.h:150
static int pitchshift_cb ( struct ast_audiohook audiohook,
struct ast_channel chan,
struct ast_frame f,
enum ast_audiohook_direction  direction 
)
static

Definition at line 166 of file func_pitchshift.c.

References AST_AUDIOHOOK_DIRECTION_WRITE, AST_AUDIOHOOK_STATUS_DONE, ast_channel_datastore_find(), AST_FORMAT_SLINEAR, AST_FORMAT_SLINEAR16, AST_FRAME_VOICE, ast_frame_subclass::codec, ast_datastore::data, ast_frame::frametype, pitch_shift(), pitchshift_data::rx, fft_data::shift_amount, ast_audiohook::status, ast_frame::subclass, and pitchshift_data::tx.

Referenced by pitchshift_helper().

167 {
168  struct ast_datastore *datastore = NULL;
169  struct pitchshift_data *shift = NULL;
170 
171 
172  if (!f) {
173  return 0;
174  }
175  if ((audiohook->status == AST_AUDIOHOOK_STATUS_DONE) ||
176  (f->frametype != AST_FRAME_VOICE) ||
177  ((f->subclass.codec != AST_FORMAT_SLINEAR) &&
179  return -1;
180  }
181 
182  if (!(datastore = ast_channel_datastore_find(chan, &pitchshift_datastore, NULL))) {
183  return -1;
184  }
185 
186  shift = datastore->data;
187 
188  if (direction == AST_AUDIOHOOK_DIRECTION_WRITE) {
189  pitch_shift(f, shift->tx.shift_amount, &shift->tx);
190  } else {
191  pitch_shift(f, shift->rx.shift_amount, &shift->rx);
192  }
193 
194  return 0;
195 }
union ast_frame_subclass subclass
Definition: frame.h:146
Structure for a data store object.
Definition: datastore.h:54
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
Definition: channel.c:2604
format_t codec
Definition: frame.h:137
float shift_amount
#define AST_FORMAT_SLINEAR16
Definition: frame.h:272
struct fft_data tx
static int pitch_shift(struct ast_frame *f, float amount, struct fft_data *fft_data)
static struct ast_datastore_info pitchshift_datastore
void * data
Definition: datastore.h:56
#define AST_FORMAT_SLINEAR
Definition: frame.h:254
enum ast_audiohook_status status
Definition: audiohook.h:107
enum ast_frame_type frametype
Definition: frame.h:144
struct fft_data rx
static int pitchshift_helper ( struct ast_channel chan,
const char *  cmd,
char *  data,
const char *  value 
)
static

Definition at line 197 of file func_pitchshift.c.

References ast_audiohook_attach(), ast_audiohook_init(), AST_AUDIOHOOK_TYPE_MANIPULATE, ast_calloc, ast_channel_datastore_add(), ast_channel_datastore_find(), ast_channel_lock, ast_channel_unlock, ast_datastore_alloc(), ast_datastore_free(), ast_log(), pitchshift_data::audiohook, ast_datastore::data, HIGH, HIGHER, HIGHEST, LOG_ERROR, LOG_WARNING, LOW, LOWER, LOWEST, ast_audiohook::manipulate_callback, pitchshift_cb(), pitchshift_data::rx, fft_data::shift_amount, and pitchshift_data::tx.

198 {
199  struct ast_datastore *datastore = NULL;
200  struct pitchshift_data *shift = NULL;
201  int new = 0;
202  float amount = 0;
203 
204  if (!chan) {
205  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
206  return -1;
207  }
208 
209  ast_channel_lock(chan);
210  if (!(datastore = ast_channel_datastore_find(chan, &pitchshift_datastore, NULL))) {
211  ast_channel_unlock(chan);
212 
213  if (!(datastore = ast_datastore_alloc(&pitchshift_datastore, NULL))) {
214  return 0;
215  }
216  if (!(shift = ast_calloc(1, sizeof(*shift)))) {
217  ast_datastore_free(datastore);
218  return 0;
219  }
220 
223  datastore->data = shift;
224  new = 1;
225  } else {
226  ast_channel_unlock(chan);
227  shift = datastore->data;
228  }
229 
230 
231  if (!strcasecmp(value, "highest")) {
232  amount = HIGHEST;
233  } else if (!strcasecmp(value, "higher")) {
234  amount = HIGHER;
235  } else if (!strcasecmp(value, "high")) {
236  amount = HIGH;
237  } else if (!strcasecmp(value, "lowest")) {
238  amount = LOWEST;
239  } else if (!strcasecmp(value, "lower")) {
240  amount = LOWER;
241  } else if (!strcasecmp(value, "low")) {
242  amount = LOW;
243  } else {
244  if (!sscanf(value, "%30f", &amount) || (amount <= 0) || (amount > 4)) {
245  goto cleanup_error;
246  }
247  }
248 
249  if (!strcasecmp(data, "rx")) {
250  shift->rx.shift_amount = amount;
251  } else if (!strcasecmp(data, "tx")) {
252  shift->tx.shift_amount = amount;
253  } else if (!strcasecmp(data, "both")) {
254  shift->rx.shift_amount = amount;
255  shift->tx.shift_amount = amount;
256  } else {
257  goto cleanup_error;
258  }
259 
260  if (new) {
261  ast_channel_lock(chan);
262  ast_channel_datastore_add(chan, datastore);
263  ast_channel_unlock(chan);
264  ast_audiohook_attach(chan, &shift->audiohook);
265  }
266 
267  return 0;
268 
269 cleanup_error:
270 
271  ast_log(LOG_ERROR, "Invalid argument provided to the %s function\n", cmd);
272  if (new) {
273  ast_datastore_free(datastore);
274  }
275  return -1;
276 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
struct ast_audiohook audiohook
int ast_audiohook_init(struct ast_audiohook *audiohook, enum ast_audiohook_type type, const char *source)
Initialize an audiohook structure.
Definition: audiohook.c:64
#define LOG_WARNING
Definition: logger.h:144
int ast_audiohook_attach(struct ast_channel *chan, struct ast_audiohook *audiohook)
Attach audiohook to channel.
Definition: audiohook.c:348
static int pitchshift_cb(struct ast_audiohook *audiohook, struct ast_channel *chan, struct ast_frame *f, enum ast_audiohook_direction direction)
Structure for a data store object.
Definition: datastore.h:54
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
Definition: channel.c:2604
int value
Definition: syslog.c:39
#define HIGH
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:65
ast_audiohook_manipulate_callback manipulate_callback
Definition: audiohook.h:116
float shift_amount
#define LOW
#define HIGHER
#define HIGHEST
#define LOG_ERROR
Definition: logger.h:155
struct fft_data tx
#define LOWER
#define LOWEST
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
struct ast_datastore * ast_datastore_alloc(const struct ast_datastore_info *info, const char *uid)
Definition: datastore.c:98
#define ast_channel_unlock(chan)
Definition: channel.h:2467
static struct ast_datastore_info pitchshift_datastore
void * data
Definition: datastore.h:56
#define ast_calloc(a, b)
Definition: astmm.h:82
struct fft_data rx
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2590
static void smb_fft ( float *  fft_buffer,
long  fft_frame_size,
long  sign 
)
static

Definition at line 278 of file func_pitchshift.c.

References cos, and M_PI.

Referenced by smb_pitch_shift().

279 {
280  float wr, wi, arg, *p1, *p2, temp;
281  float tr, ti, ur, ui, *p1r, *p1i, *p2r, *p2i;
282  long i, bitm, j, le, le2, k;
283 
284  for (i = 2; i < 2 * fft_frame_size - 2; i += 2) {
285  for (bitm = 2, j = 0; bitm < 2 * fft_frame_size; bitm <<= 1) {
286  if (i & bitm) {
287  j++;
288  }
289  j <<= 1;
290  }
291  if (i < j) {
292  p1 = fft_buffer + i; p2 = fft_buffer + j;
293  temp = *p1; *(p1++) = *p2;
294  *(p2++) = temp; temp = *p1;
295  *p1 = *p2; *p2 = temp;
296  }
297  }
298  for (k = 0, le = 2; k < (long) (log(fft_frame_size) / log(2.) + .5); k++) {
299  le <<= 1;
300  le2 = le>>1;
301  ur = 1.0;
302  ui = 0.0;
303  arg = M_PI / (le2>>1);
304  wr = cos(arg);
305  wi = sign * sin(arg);
306  for (j = 0; j < le2; j += 2) {
307  p1r = fft_buffer+j; p1i = p1r + 1;
308  p2r = p1r + le2; p2i = p2r + 1;
309  for (i = j; i < 2 * fft_frame_size; i += le) {
310  tr = *p2r * ur - *p2i * ui;
311  ti = *p2r * ui + *p2i * ur;
312  *p2r = *p1r - tr; *p2i = *p1i - ti;
313  *p1r += tr; *p1i += ti;
314  p1r += le; p1i += le;
315  p2r += le; p2i += le;
316  }
317  tr = ur * wr - ui * wi;
318  ui = ur * wi + ui * wr;
319  ur = tr;
320  }
321  }
322 }
#define M_PI
static unsigned int cos
Definition: chan_h323.c:147
static void smb_pitch_shift ( float  pitchShift,
long  num_samps_to_process,
long  fft_frame_size,
long  osamp,
float  sample_rate,
int16_t *  indata,
int16_t *  outdata,
struct fft_data fft_data 
)
static

Definition at line 324 of file func_pitchshift.c.

References fft_data::ana_freq, fft_data::ana_magn, cos, fft_data::fft_worksp, fft_data::gRover, fft_data::in_fifo, fft_data::last_phase, M_PI, fft_data::out_fifo, fft_data::output_accum, smb_fft(), step_size(), fft_data::sum_phase, fft_data::syn_freq, and fft_data::sys_magn.

Referenced by pitch_shift().

325 {
326  float *in_fifo = fft_data->in_fifo;
327  float *out_fifo = fft_data->out_fifo;
328  float *fft_worksp = fft_data->fft_worksp;
329  float *last_phase = fft_data->last_phase;
330  float *sum_phase = fft_data->sum_phase;
331  float *output_accum = fft_data->output_accum;
332  float *ana_freq = fft_data->ana_freq;
333  float *ana_magn = fft_data->ana_magn;
334  float *syn_freq = fft_data->syn_freq;
335  float *sys_magn = fft_data->sys_magn;
336 
337  double magn, phase, tmp, window, real, imag;
338  double freq_per_bin, expct;
339  long i,k, qpd, index, in_fifo_latency, step_size, fft_frame_size2;
340 
341  /* set up some handy variables */
342  fft_frame_size2 = fft_frame_size / 2;
343  step_size = fft_frame_size / osamp;
344  freq_per_bin = sample_rate / (double) fft_frame_size;
345  expct = 2. * M_PI * (double) step_size / (double) fft_frame_size;
346  in_fifo_latency = fft_frame_size-step_size;
347 
348  if (fft_data->gRover == 0) {
349  fft_data->gRover = in_fifo_latency;
350  }
351 
352  /* main processing loop */
353  for (i = 0; i < num_samps_to_process; i++){
354 
355  /* As long as we have not yet collected enough data just read in */
356  in_fifo[fft_data->gRover] = indata[i];
357  outdata[i] = out_fifo[fft_data->gRover - in_fifo_latency];
358  fft_data->gRover++;
359 
360  /* now we have enough data for processing */
361  if (fft_data->gRover >= fft_frame_size) {
362  fft_data->gRover = in_fifo_latency;
363 
364  /* do windowing and re,im interleave */
365  for (k = 0; k < fft_frame_size;k++) {
366  window = -.5 * cos(2. * M_PI * (double) k / (double) fft_frame_size) + .5;
367  fft_worksp[2*k] = in_fifo[k] * window;
368  fft_worksp[2*k+1] = 0.;
369  }
370 
371  /* ***************** ANALYSIS ******************* */
372  /* do transform */
373  smb_fft(fft_worksp, fft_frame_size, -1);
374 
375  /* this is the analysis step */
376  for (k = 0; k <= fft_frame_size2; k++) {
377 
378  /* de-interlace FFT buffer */
379  real = fft_worksp[2*k];
380  imag = fft_worksp[2*k+1];
381 
382  /* compute magnitude and phase */
383  magn = 2. * sqrt(real * real + imag * imag);
384  phase = atan2(imag, real);
385 
386  /* compute phase difference */
387  tmp = phase - last_phase[k];
388  last_phase[k] = phase;
389 
390  /* subtract expected phase difference */
391  tmp -= (double) k * expct;
392 
393  /* map delta phase into +/- Pi interval */
394  qpd = tmp / M_PI;
395  if (qpd >= 0) {
396  qpd += qpd & 1;
397  } else {
398  qpd -= qpd & 1;
399  }
400  tmp -= M_PI * (double) qpd;
401 
402  /* get deviation from bin frequency from the +/- Pi interval */
403  tmp = osamp * tmp / (2. * M_PI);
404 
405  /* compute the k-th partials' true frequency */
406  tmp = (double) k * freq_per_bin + tmp * freq_per_bin;
407 
408  /* store magnitude and true frequency in analysis arrays */
409  ana_magn[k] = magn;
410  ana_freq[k] = tmp;
411 
412  }
413 
414  /* ***************** PROCESSING ******************* */
415  /* this does the actual pitch shifting */
416  memset(sys_magn, 0, fft_frame_size * sizeof(float));
417  memset(syn_freq, 0, fft_frame_size * sizeof(float));
418  for (k = 0; k <= fft_frame_size2; k++) {
419  index = k * pitchShift;
420  if (index <= fft_frame_size2) {
421  sys_magn[index] += ana_magn[k];
422  syn_freq[index] = ana_freq[k] * pitchShift;
423  }
424  }
425 
426  /* ***************** SYNTHESIS ******************* */
427  /* this is the synthesis step */
428  for (k = 0; k <= fft_frame_size2; k++) {
429 
430  /* get magnitude and true frequency from synthesis arrays */
431  magn = sys_magn[k];
432  tmp = syn_freq[k];
433 
434  /* subtract bin mid frequency */
435  tmp -= (double) k * freq_per_bin;
436 
437  /* get bin deviation from freq deviation */
438  tmp /= freq_per_bin;
439 
440  /* take osamp into account */
441  tmp = 2. * M_PI * tmp / osamp;
442 
443  /* add the overlap phase advance back in */
444  tmp += (double) k * expct;
445 
446  /* accumulate delta phase to get bin phase */
447  sum_phase[k] += tmp;
448  phase = sum_phase[k];
449 
450  /* get real and imag part and re-interleave */
451  fft_worksp[2*k] = magn * cos(phase);
452  fft_worksp[2*k+1] = magn * sin(phase);
453  }
454 
455  /* zero negative frequencies */
456  for (k = fft_frame_size + 2; k < 2 * fft_frame_size; k++) {
457  fft_worksp[k] = 0.;
458  }
459 
460  /* do inverse transform */
461  smb_fft(fft_worksp, fft_frame_size, 1);
462 
463  /* do windowing and add to output accumulator */
464  for (k = 0; k < fft_frame_size; k++) {
465  window = -.5 * cos(2. * M_PI * (double) k / (double) fft_frame_size) + .5;
466  output_accum[k] += 2. * window * fft_worksp[2*k] / (fft_frame_size2 * osamp);
467  }
468  for (k = 0; k < step_size; k++) {
469  out_fifo[k] = output_accum[k];
470  }
471 
472  /* shift accumulator */
473  memmove(output_accum, output_accum+step_size, fft_frame_size * sizeof(float));
474 
475  /* move input FIFO */
476  for (k = 0; k < in_fifo_latency; k++) {
477  in_fifo[k] = in_fifo[k+step_size];
478  }
479  }
480  }
481 }
float out_fifo[MAX_FRAME_LENGTH]
float ana_magn[MAX_FRAME_LENGTH]
float output_accum[2 *MAX_FRAME_LENGTH]
float ana_freq[MAX_FRAME_LENGTH]
static int step_size(struct g726_state *state_ptr)
Definition: codec_g726.c:249
float sum_phase[MAX_FRAME_LENGTH/2+1]
float in_fifo[MAX_FRAME_LENGTH]
#define M_PI
float fft_worksp[2 *MAX_FRAME_LENGTH]
float syn_freq[MAX_FRAME_LENGTH]
float sys_magn[MAX_FRAME_LENGTH]
if(yyss+yystacksize-1<=yyssp)
Definition: ast_expr2.c:1874
float last_phase[MAX_FRAME_LENGTH/2+1]
static unsigned int cos
Definition: chan_h323.c:147
static void smb_fft(float *fft_buffer, long fft_frame_size, long sign)
static int unload_module ( void  )
static

Definition at line 504 of file func_pitchshift.c.

References ast_custom_function_unregister().

505 {
507 }
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
Definition: pbx.c:3814
static struct ast_custom_function pitch_shift_function

Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Audio Effects Dialplan Functions" , .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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, }
static

Definition at line 515 of file func_pitchshift.c.

Definition at line 515 of file func_pitchshift.c.

struct ast_custom_function pitch_shift_function
static
Initial value:
= {
.name = "PITCH_SHIFT",
}
static int pitchshift_helper(struct ast_channel *chan, const char *cmd, char *data, const char *value)

Definition at line 499 of file func_pitchshift.c.

struct ast_datastore_info pitchshift_datastore
static
Initial value:
= {
.type = "pitchshift",
.destroy = destroy_callback
}
static void destroy_callback(void *data)

Definition at line 161 of file func_pitchshift.c.