麻烦让我的相位声码器Pd外部工作

时间:2017-06-16 19:33:45

标签: c external puredata

我正在尝试使用相位声码器算法编写一个执行音高变换的Pd外部电路。这是我第一次写外部,我不是一个C程序员,所以我希望你们可以帮助我解决这个问题。我只是附上了执行方法。

当我改变要转置的半音的数量时,我得到了一个奇怪的行为。它确实有音高变换,但有许多奇怪的伪像,而不是我设定的数量。我认为代码是对的,但显然不是;任何人都可以给我一些关于问题可能是什么的提示吗?我知道这是一段很长的代码而且我的问题很模糊,但我发现使用Pd进行调试是不可能的,而且我已经没有想法来测试代码了。

 int i, j, n, frame_size, frame_size_half, overlap_in, overlap_chunk, hop_in, hop_out;
int semitones;
t_float amp_scalar, alpha;

t_pitchShifter_tilde *x = (t_pitchShifter_tilde *)(w[1]);

t_sample *in = (t_float *)(w[2]);
t_sample *out = (t_float *)(w[3]);
n = w[4];   //Tamaño del buffer de entrada
semitones = x->semitones;
frame_size = x->frame_size;
frame_size_half = x->frame_size_half;
overlap_in = x->overlap_in;
overlap_chunk = x->hop_in;
hop_in = x->hop_in;
alpha = pow(2.0,semitones/12.0);//x->alpha;
hop_out =  round(alpha*hop_in);//x->hop_out; 
amp_scalar = x->amp_scalar;

// shift previous contents back
for(i=0; i<(frame_size-n); i++)
    x->input_buf[i] = x->input_buf[n+i];

// buffer most recent block
for(i=0; i<n; i++)
    x->input_buf[frame_size-n+i] = in[i]; // C


if(x->dsp_tick>=x->buffer_limit) 
{
    x->dsp_tick = 0;

    // ANALYSIS

    // window the signal
    for(i=0; i<frame_size; i++){
        x->input_buf_windowed[i] = x->input_buf[i] * x->hann[i];
    }

    // take FT of window
    mayer_realfft(frame_size, x->input_buf_windowed);

    //Debug:
    if(debug){
        for(i=0; i<frame_size; i++){

            post("fft output %i: %f", i, x->input_buf_windowed[i]);
        }
    }

    // unpack mayer_realfft results into R&I arrays
    for(i=0; i<=frame_size_half; i++)
    {
        x->signal_R[i] = x->input_buf_windowed[i];
        if(fabs(x->signal_R[i]) < 0.0001)
            x->signal_R[i] = 0.0;
    }

    x->signal_I[0]=0;  // DC

    for(i=(frame_size-1), j=1; i>frame_size_half; i--, j++)
    {
        x->signal_I[j] = x->input_buf_windowed[i];
        if(fabs(x->signal_I[j]) < 0.0001)
            x->signal_I[j] = 0.0;
    }
    x->signal_I[frame_size_half]=0;  // Nyquist

    // PROCESSING

    for(i=0; i<=frame_size_half; i++)
    {
        // Calculate the magnitude
        x->signal_mag[i] = cabsf(x->signal_R[i]+I*x->signal_I[i]); //sqrt(x->signal_R[i]*x->signal_R[i]+x->signal_I[i]*x->signal_I[i]);

        // Calculate the phase
        x->signal_phase[i] = cargf(x->signal_R[i]+I*x->signal_I[i]); //sqrt

        // Calculate the phase difference between consecutive frames
        x->phase_dif[i] = x->signal_phase[i] - x->prev_signal_phase[i];

        //Store current frame's phase for next frame's processing
        x->prev_signal_mag[i] = x->signal_mag[i];
        x->prev_signal_phase[i] = x->signal_phase[i];

        // Remove the expected phase difference
        x->phase_dif[i] -= hop_in*2*M_PI*i/frame_size;    //2*M_PI*i/x->overlap_in;

        // Wrap around
        x->phase_dif[i] = x->phase_dif[i] + M_PI;
        x->phase_dif[i] = (x->phase_dif[i]-floor(x->phase_dif[i]/(2*M_PI)) * 2*M_PI) - M_PI;

        // Calculate true frequency
        x->true_freq[i] = 2*M_PI*i/frame_size + x->phase_dif[i]/hop_in; //W_bin + deltaW

        // Get the cumulative phase
        x->cumulative_phase[i] += (hop_out)* x->true_freq[i];

        // Wrap around
        x->cumulative_phase[i] += M_PI;
        x->cumulative_phase[i] -= floor(x->cumulative_phase[i]/(2*M_PI))*2*M_PI - M_PI;

        // Save the real and imaginary part
        x->signal_R[i] = x->signal_mag[i] * cos(x->cumulative_phase[i]);
        x->signal_I[i] = x->signal_mag[i] * sin(x->cumulative_phase[i]);   
    }

    // SYNTHESIS

    // pack real and imaginary parts in correct order for mayer_realifft
    for(i=0; i<=frame_size_half; i++)
        x->input_buf_windowed[i] = x->signal_R[i];

    for(i=(frame_size_half+1), j=(frame_size_half-1); i<frame_size; i++, j--)
        x->input_buf_windowed[i] = x->signal_I[j];

    // resynth
    mayer_realifft(frame_size, x->input_buf_windowed);    

    // window
    for(i=0; i<frame_size; i++)
    {
        x->input_buf_windowed[i] *= x->hann[i];
        x->input_buf_windowed[i] *= amp_scalar;
    }

    // Overlap/Add:

    // shift overlap/add buffer's previous contents back
    for(i=0; i<( 2*frame_size - hop_out); i++)
        x->overlap_add_buffer[i] = x->overlap_add_buffer[i+hop_out];

    // Set to 0 last overlap chunk:
    for(i= (2*frame_size - hop_out); i< 2*frame_size; i++)
        x->overlap_add_buffer[i] = 0;

    // Overlap/add most recent block
    for(i=0; i<frame_size; i++)
        x->overlap_add_buffer[frame_size + i] += x->input_buf_windowed[i];

    // Put out a hop_out size array
    for(i=0; i<hop_out; i++)
        x->vocoder_output[i] = x->overlap_add_buffer[frame_size - hop_out + i];

    // RE-SAMPLING

    int index_floor, index_ceil;
    for(i=0; i<hop_in; i++)
    {
        index_floor = floor(alpha*i);
        index_ceil = index_floor + 1;
        x->final_output[i] = x->vocoder_output[ index_floor];
        x->final_output[i] += ( x->vocoder_output[index_ceil] - x->vocoder_output[index_floor] )*(alpha*i - index_floor);

    }

}; // If

// OUTPUT
for(i=0; i<n; i++, out++)
    *out = x->final_output[(x->dsp_tick*n)+i];

x->dsp_tick++;

return (w+5);}

0 个答案:

没有答案