Superpowered: real time pitch shift with timestretcher not working

前端 未结 2 1883
逝去的感伤
逝去的感伤 2020-12-11 11:09

I am using Superpowered for various real-time FX and they all work very straightforward. However the pitch shifting is a whole other story, I think in fact because it\'s bas

相关标签:
2条回答
  • 2020-12-11 11:35

    Implement the part marked with TODO. That's the point where you need to provide input for the timeStretcher. Also take care of separating the output from the input. Output could be written before the input is consumed.

    0 讨论(0)
  • 2020-12-11 11:55

    I finally got it working:

    static bool audioProcessing(void *clientdata,
                                    float **buffers,
                                    unsigned int inputChannels,
                                    unsigned int outputChannels,
                                    unsigned int numberOfSamples,
                                    unsigned int samplerate,
                                    uint64_t hostTime) {
        __unsafe_unretained Superpowered *self = (__bridge Superpowered *)clientdata;
    
        //timeStretching->setRateAndPitchShift(realTimeRate, realTimePitch);
        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;
    
        // Converting the 16-bit integer samples to 32-bit floating point.
        SuperpoweredInterleave(buffers[0], buffers[1], (float *)inputBuffer.buffers[0], numberOfSamples);
        //SuperpoweredShortIntToFloat(audioInputOutput, (float *)inputBuffer.buffers[0], (unsigned int) numberOfSamples);
    
        self->timeStretcher->process(&inputBuffer, self->outputBuffers);
    
        // Do we have some output?
        if (self->outputBuffers->makeSlice(0, self->outputBuffers->sampleLength)) {
            while (true) { // Iterate on every output slice.
                // Get pointer to the output samples.
                int numSamples = 0;
                float *timeStretchedAudio = (float *)self->outputBuffers->nextSliceItem(&numSamples);
                if (!timeStretchedAudio || *timeStretchedAudio == 0) {
                    break;
                }
    
                // Convert the time stretched PCM samples from 32-bit floating point to 16-bit integer.
                //SuperpoweredFloatToShortInt(timeStretchedAudio, audioInputOutput,
                //                            (unsigned int) numSamples);
                SuperpoweredDeInterleave(timeStretchedAudio, buffers[0], buffers[1], numSamples);
                self->recorder->process(timeStretchedAudio, numSamples);
    
                // Write the audio to disk.
                //fwrite(audioInputOutput, 1, numSamples * 4, fd);
            }
            // Clear the output buffer list.
            self->outputBuffers->clear();
            // If we have enough samples in the fifo output buffer, pass them to the audio output.
            //SuperpoweredFloatToShortInt((float *)inputBuffer.buffers[0], audioInputOutput, (unsigned int) numberOfSamples);
        }
    
        return true;
    }
    

    I am not sure if changing the rate also works, but I don't care for this application. YMMV.

    0 讨论(0)
提交回复
热议问题