132#define M_PI 3.14159265358979323846 
  134#define MAX_FRAME_LENGTH 256 
  165static void smb_fft(
float *fft_buffer, 
long fft_frame_size, 
long sign);
 
  166static 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);
 
  178    .
type = 
"pitchshift",
 
 
  199    shift = datastore->
data;
 
 
  229        if (!(shift = 
ast_calloc(1, 
sizeof(*shift)))) {
 
  236        datastore->
data = shift;
 
  240        shift = datastore->
data;
 
  244    if (!strcasecmp(
value, 
"highest")) {
 
  246    } 
else if (!strcasecmp(
value, 
"higher")) {
 
  248    } 
else if (!strcasecmp(
value, 
"high")) {
 
  250    } 
else if (!strcasecmp(
value, 
"lowest")) {
 
  252    } 
else if (!strcasecmp(
value, 
"lower")) {
 
  254    } 
else if (!strcasecmp(
value, 
"low")) {
 
  257        if (!sscanf(
value, 
"%30f", &amount) || (amount <= 0) || (amount > 4)) {
 
  262    if (!strcasecmp(data, 
"rx")) {
 
  264    } 
else if (!strcasecmp(data, 
"tx")) {
 
  266    } 
else if (!strcasecmp(data, 
"both")) {
 
 
  291static void smb_fft(
float *fft_buffer, 
long fft_frame_size, 
long sign)
 
  293    float wr, wi, arg, *p1, *p2, temp;
 
  294    float tr, ti, ur, ui, *p1r, *p1i, *p2r, *p2i;
 
  295    long i, bitm, j, le, le2, k;
 
  297    for (i = 2; i < 2 * fft_frame_size - 2; i += 2) {
 
  298        for (bitm = 2, j = 0; bitm < 2 * fft_frame_size; bitm <<= 1) {
 
  305            p1 = fft_buffer + i; p2 = fft_buffer + j;
 
  306            temp = *p1; *(p1++) = *p2;
 
  307            *(p2++) = temp; temp = *p1;
 
  308            *p1 = *p2; *p2 = temp;
 
  311    for (k = 0, le = 2; k < (long) (log(fft_frame_size) / log(2.) + .5); k++) {
 
  316        arg = 
M_PI / (le2>>1);
 
  318        wi = sign * sin(arg);
 
  319        for (j = 0; j < le2; j += 2) {
 
  320            p1r = fft_buffer+j; p1i = p1r + 1;
 
  321            p2r = p1r + le2; p2i = p2r + 1;
 
  322            for (i = j; i < 2 * fft_frame_size; i += le) {
 
  323                tr = *p2r * ur - *p2i * ui;
 
  324                ti = *p2r * ui + *p2i * ur;
 
  325                *p2r = *p1r - tr; *p2i = *p1i - ti;
 
  326                *p1r += tr; *p1i += ti;
 
  327                p1r += le; p1i += le;
 
  328                p2r += le; p2i += le;
 
  330            tr = ur * wr - ui * wi;
 
  331            ui = ur * wi + ui * wr;
 
 
  337static 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)
 
  351    double freq_per_bin, expect;
 
  352    long i,k, qpd, index, in_fifo_latency, 
step_size, fft_frame_size2;
 
  355    fft_frame_size2 = fft_frame_size / 2;
 
  357    freq_per_bin = sample_rate / (double) fft_frame_size;
 
  358    expect = 2. * 
M_PI * (double) 
step_size / (
double) fft_frame_size;
 
  359    in_fifo_latency = fft_frame_size-
step_size;
 
  366    for (i = 0; i < num_samps_to_process; i++){
 
  378            for (k = 0; k < fft_frame_size;k++) {
 
  379                window = -.5 * 
cos(2. * 
M_PI * (
double) k / (
double) fft_frame_size) + .5;
 
  380                fft_worksp[2*k] = in_fifo[k] * 
window;
 
  381                fft_worksp[2*k+1] = 0.;
 
  386            smb_fft(fft_worksp, fft_frame_size, -1);
 
  389            for (k = 0; k <= fft_frame_size2; k++) {
 
  392                real = fft_worksp[2*k];
 
  393                imag = fft_worksp[2*k+1];
 
  396                magn = 2. * sqrt(
real * 
real + imag * imag);
 
  397                phase = atan2(imag, 
real);
 
  400                tmp = phase - last_phase[k];
 
  401                last_phase[k] = phase;
 
  404                tmp -= (double) k * expect;
 
  413                tmp -= 
M_PI * (double) qpd;
 
  416                tmp = osamp * tmp / (2. * 
M_PI);
 
  419                tmp = (double) k * freq_per_bin + tmp * freq_per_bin;
 
  429            memset(sys_magn, 0, fft_frame_size * 
sizeof(
float));
 
  430            memset(syn_freq, 0, fft_frame_size * 
sizeof(
float));
 
  431            for (k = 0; k <= fft_frame_size2; k++) {
 
  432                index = k * pitchShift;
 
  433                if (index <= fft_frame_size2) {
 
  434                    sys_magn[index] += ana_magn[k];
 
  435                    syn_freq[index] = ana_freq[k] * pitchShift;
 
  441            for (k = 0; k <= fft_frame_size2; k++) {
 
  448                tmp -= (double) k * freq_per_bin;
 
  454                tmp = 2. * 
M_PI * tmp / osamp;
 
  457                tmp += (double) k * expect;
 
  461                phase = sum_phase[k];
 
  464                fft_worksp[2*k] = magn * 
cos(phase);
 
  465                fft_worksp[2*k+1] = magn * sin(phase);
 
  469            for (k = fft_frame_size + 2; k < 2 * fft_frame_size; k++) {
 
  474            smb_fft(fft_worksp, fft_frame_size, 1);
 
  477            for (k = 0; k < fft_frame_size; k++) {
 
  478                window = -.5 * 
cos(2. * 
M_PI * (
double) k / (
double) fft_frame_size) + .5;
 
  479                output_accum[k] += 2. * 
window * fft_worksp[2*k] / (fft_frame_size2 * osamp);
 
  482                out_fifo[k] = output_accum[k];
 
  486            memmove(output_accum, output_accum+
step_size, fft_frame_size * 
sizeof(
float));
 
  489            for (k = 0; k < in_fifo_latency; k++) {
 
 
  498    int16_t *fun = (int16_t *) f->
data.
ptr;
 
  502    if (!amount || amount == 1 || !fun || (f->
samples % 32)) {
 
  505    for (samples = 0; samples < f->
samples; samples += 32) {
 
 
  513    .
name = 
"PITCH_SHIFT",
 
 
Asterisk main include file. File version handling, generic pbx functions.
#define ast_calloc(num, len)
A wrapper for calloc()
@ AST_AUDIOHOOK_MANIPULATE_ALL_RATES
int ast_audiohook_init(struct ast_audiohook *audiohook, enum ast_audiohook_type type, const char *source, enum ast_audiohook_init_flags flags)
Initialize an audiohook structure.
@ AST_AUDIOHOOK_DIRECTION_WRITE
int ast_audiohook_attach(struct ast_channel *chan, struct ast_audiohook *audiohook)
Attach audiohook to channel.
int ast_audiohook_destroy(struct ast_audiohook *audiohook)
Destroys an audiohook structure.
@ AST_AUDIOHOOK_TYPE_MANIPULATE
@ AST_AUDIOHOOK_STATUS_DONE
General Asterisk PBX channel definitions.
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
#define ast_channel_lock(chan)
#define ast_channel_unlock(chan)
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.
static int step_size(struct g726_state *state_ptr)
#define ast_datastore_alloc(info, uid)
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
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 struct ast_custom_function pitch_shift_function
static const struct ast_datastore_info pitchshift_datastore
static void smb_fft(float *fft_buffer, long fft_frame_size, long sign)
static void destroy_callback(void *data)
static int load_module(void)
static int unload_module(void)
static int pitchshift_cb(struct ast_audiohook *audiohook, struct ast_channel *chan, struct ast_frame *f, enum ast_audiohook_direction direction)
static int pitch_shift(struct ast_frame *f, float amount, struct fft_data *fft_data)
static int pitchshift_helper(struct ast_channel *chan, const char *cmd, char *data, const char *value)
Asterisk module definitions.
#define ASTERISK_GPL_KEY
The text the key() function should return.
#define AST_MODULE_INFO_STANDARD_EXTENDED(keystr, desc)
@ AST_MODULE_LOAD_SUCCESS
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Core PBX routines and definitions.
#define ast_custom_function_register(acf)
Register a custom function.
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
ast_audiohook_manipulate_callback manipulate_callback
enum ast_audiohook_status status
Main Channel structure associated with a channel.
Data structure associated with a custom dialplan function.
Structure for a data store type.
Structure for a data store object.
struct ast_format * format
Data structure associated with a single frame of data.
struct ast_frame_subclass subclass
union ast_frame::@239 data
float output_accum[2 *MAX_FRAME_LENGTH]
float out_fifo[MAX_FRAME_LENGTH]
float ana_freq[MAX_FRAME_LENGTH]
float sum_phase[MAX_FRAME_LENGTH/2+1]
float in_fifo[MAX_FRAME_LENGTH]
float sys_magn[MAX_FRAME_LENGTH]
float fft_worksp[2 *MAX_FRAME_LENGTH]
float ana_magn[MAX_FRAME_LENGTH]
float syn_freq[MAX_FRAME_LENGTH]
float last_phase[MAX_FRAME_LENGTH/2+1]
struct ast_audiohook audiohook