0

I have implemented a host of the SuperpoweredFX classes and have had no issues, however, whilst implementing a pitch shifter using SuperpoweredTimeStretching I have run into some trouble.

    static bool audioProcessing(void * __unused clientdata, short int *audioInputOutput, int numberOfSamples, int __unused samplerate) {

    float *floatBuffer = (float *)malloc(numberOfSamples * 2 * sizeof(float) + 1024);

    SuperpoweredShortIntToFloat(audioInputOutput, floatBuffer, numberOfSamples);

    if(isFX_PitchShifter_1){
        __android_log_print(ANDROID_LOG_ERROR, "FrequencyDomain", "audioProcessing - isFX_PitchShifter_1 - fx_PitchShift_1");    
        SuperpoweredAudiopointerList *outputBuffers = new SuperpoweredAudiopointerList( 4 , 0 );//POSSIBLE MEMORY PROBLEM   
        SuperpoweredAudiobufferlistElement inputBuffer;
        inputBuffer.startSample = 0;
        inputBuffer.samplesUsed = 0;
        inputBuffer.endSample = numberOfSamples;
        inputBuffer.buffers[0] = SuperpoweredAudiobufferPool::getBuffer((unsigned int) (numberOfSamples * 8 + 64));           
        inputBuffer.buffers[1] = inputBuffer.buffers[2] = inputBuffer.buffers[3] = NULL;            
        SuperpoweredShortIntToFloat(audioInputOutput, (float *)inputBuffer.buffers[0], (unsigned int) numberOfSamples);

        if(fx_PitchShift_1!=NULL){
            fx_PitchShift_1->process(&inputBuffer, outputBuffers);

            if (outputBuffers->makeSlice(0, outputBuffers->sampleLength)) {
                while (true) { // Iterate on every output slice.                      
                    int numSamples = 0;
                    float *temp_floatBuffer = (float *)outputBuffers->nextSliceItem(&numSamples);
                    if (!temp_floatBuffer) {
                        break;
                    }

                    SuperpoweredFloatToShortInt(temp_floatBuffer, audioInputOutput, numSamples);

                }                   
                outputBuffers->clear();
            }

        }

        SuperpoweredShortIntToFloat(audioInputOutput, floatBuffer, numberOfSamples);    

    }           
    SuperpoweredFloatToShortInt(floatBuffer, audioInputOutput, numberOfSamples);      
    return true;
}

The above is my processing function, I am using the SuperpoweredAndroidAudioIO from the FrequencyDomain example.

I declare the SuperpoweredTimeStretching class like so:

fx_PitchShift_1 = new SuperpoweredTimeStretching((unsigned int)thisSampleRate);
fx_PitchShift_1->setRateAndPitchShift(1.0f, (int)pitchShiftOctaves);

The same app is using the SuperpoweredFX classes just fine, however, when the pitch shift is thrown into the mix the output becomes a mess. A sample file can be found here: https://drive.google.com/file/d/1Hy52SsgOYxlkxFq5CCsK5sCKX3Y_9G8J/view?usp=sharing

I calculate the sample rate like so:

samplerateString = null;
    buffersizeString = null;
    if (Build.VERSION.SDK_INT >= 17) {
        AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
        samplerateString = audioManager.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE);
        buffersizeString = audioManager.getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER);
    }
    if (samplerateString == null) samplerateString = "44100";
    if (buffersizeString == null) buffersizeString = "512";
user3192649
  • 313
  • 1
  • 4
  • 13

1 Answers1

0

The pitch shifter works in the frequency domain with the FFT size of 2048. That doesn't align well with your current buffer size.

You also create a new output buffer list on every turn of the audio processing callback, then discard all the content the pitch shifter provided.

You correctly submit all the input samples to the pitch shifter, but you need to handle the output list globally. It will store the pitch shifter's output, and you can remove the number of samples needed for the output, if that amount of samples is available in the output list.

Gabor Szanto
  • 1,329
  • 8
  • 12
  • I have rectified the outputbuffer issue but I am not sure how to rectify the FFT 2048/Buffer size. Can you provide some further assistance on that front? – user3192649 Feb 28 '18 at 03:57
  • Just submit all input you have, call process() on the pitch shifter and check if the output list has enough samples for the output. If not, output silence. – Gabor Szanto Feb 28 '18 at 06:27