Channel problem


#1

Hi, I just have a problem of channel (I think).

I am trying to implement a phase vocoder and in particular a robotization effect. However when I try the plugin, I have a clipping (or just some samples missing, I'm not really sure) of the output. Now the stange thing is that when I try the effect on only one channel, so by removing

 for (channel = 0; channel < getNumInputChannels(); ++channel)

and replacing it with channel =0 or channel = 1, I don't have the clipping output anymore and the effect works correctly but only on the left or right ear of course. I thought it was caused by the fft and the inverse fft here :     

                //perform operation

                forwFft_.performRealOnlyForwardTransform(RawData_);
                for(fftIdx=64;fftIdx<128;fftIdx++)
                {
                    RawData_[fftIdx] = 0;
                }
                invFft_.performRealOnlyInverseTransform(RawData_);*/

But even when I remove this part (So when no effect is performed and only an overlap-add is performed with a window length of 128 samples and a hopsize of 64 samples) I still have the clipping.

If someone have an idea of what could cause this clipping/missing of samples it would be really cool. Here's the full processBlock function :

// How many input channels 

    const int numInputChannels = getNumInputChannels();

    // How many output channels 

    const int numOutputChannels = getNumOutputChannels();

    // How many samples in the buffer for this block

    const int numSamples = buffer.getNumSamples();

    

    // input and output write and read index

    int channel, iwp , irp, owp, orp;

    

    //index of fft

    int  lastfft, fftIdx;

   
    for (int i = numInputChannels; i < numOutputChannels; ++i)

        buffer.clear (i, 0, buffer.getNumSamples());


    for (channel = 0; channel < getNumInputChannels(); ++channel)

    {   
        float* channelData = buffer.getWritePointer(channel);

    
        //Input, output and window buffer

        float *InBuff = InBuffer_.getWritePointer(jmin(channel,InBuffer_.getNumChannels() - 1));

        float *OutBuff = OutBuffer_.getWritePointer(jmin(channel,OutBuffer_.getNumChannels() - 1));

        float *WinBuff = WinBuffer_.getWritePointer(jmin(channel,WinBuffer_.getNumChannels() - 1));


        iwp = InWritepos_;

        irp = InReadpos_;

        owp = OutWritepos_;

        orp = OutReadpos_;

        lastfft = performfft_;

      
     
        for (int i = 0; i < numSamples; ++i)

        {

            const float in = channelData[i];
            InBuff[iwp] = in;

            if (iwp++ >= InBuffLength_)
            iwp = 0;

   
            // Store the output in the buffer, replacing input

            channelData[i] = OutBuff[orp];

            OutBuff[orp] = 0.0;


            if (orp++ >= OutBuffLength_)

            orp = 0;

 

            //Check whether the hopsize has been reach to perform the algorithm

            if (++lastfft >= hopsize_)

            {

                lastfft= 0;
                irp = iwp;

                //Windowing of the samples

                for(fftIdx=0;fftIdx<WinLength_;fftIdx++)

                {

                    WinBuff[fftIdx]=InBuff[irp]*hanning[fftIdx];

                      RawData_[fftIdx] = WinBuff[fftIdx];


                     if (irp++ >= InBuffLength_)

                    irp = 0;

                    

                }

                

                owp = orp;

                

                //perform operation

                forwFft_.performRealOnlyForwardTransform(RawData_);

    
                for(fftIdx=64;fftIdx<128;fftIdx++)

                {

                    RawData_[fftIdx] = 0;
                }

                

                invFft_.performRealOnlyInverseTransform(RawData_);


                

                for(fftIdx=0;fftIdx<WinLength_;fftIdx++)

                {

                    OutBuff[owp] = OutBuff[owp] + RawData_[fftIdx];

                    if (owp++ >= OutBuffLength_)

                    owp = 0;

                    

                }

            

            }

         

        }

    }


    InWritepos_ = iwp;

    InReadpos_ = irp;

    OutWritepos_ = owp;

    OutReadpos_ = orp;

    performfft_ = lastfft;

    

}

I'm running on Mac OSX 10.8.5 with Xcode 4.5.2


#2

This is probably one of the most common beginner problems we see on here.

Painfully often we see code where people are looping through their channels, and pumping each one's data into the same filter or other stateful algorithm.

Obviously if you're processing multiple channels then each one needs its own separate state - if you push them all through the same FFT or other effect, then it'll clearly sound messed up.


#3

Someone else just had this same problem. Don't worry, we've probably all done it once. 

http://www.juce.com/forum/topic/problem-storing-values/1-sample-delay-noobquestion