AIvoices/firmware-arduino/src/PitchShift.cpp
2025-06-03 16:03:42 +01:00

54 lines
1.4 KiB
C++

#include "PitchShift.h"
#define GRAINSIZE 1024ul
static int16_t buf1[GRAINSIZE];
static int16_t buf2[GRAINSIZE];
static int16_t* buf = buf1;
static int16_t* buf_ = buf2;
static unsigned long readAddress = 0;
static unsigned long writeAddress = 0;
bool PitchShiftFixedOutput::begin(PitchShiftInfo info) {
TRACED();
cfg = info;
AudioOutput::setAudioInfo(info);
this->pitchMul = (uint32_t)(info.pitch_shift * 256.0f + 0.5f);
//this->secondaryOffset = (uint32_t)( (1.0f - (info.pitch_shift - (int)(info.pitch_shift))) * GRAINSIZE + 0.5f);
this->secondaryOffset = GRAINSIZE - ((( this->pitchMul * GRAINSIZE ) >> 8 ) % GRAINSIZE);
return true;
}
int16_t PitchShiftFixedOutput::pitchShift(int16_t value) {
buf_[writeAddress] = value;
int ii1 = (writeAddress * this->pitchMul) >> 8;
int output1 = buf[ii1 % GRAINSIZE];
int ii2 = ii1 + secondaryOffset;
int output2 = buf[ii2 % GRAINSIZE];
unsigned long f = 0;
if ( writeAddress >= GRAINSIZE*3/4 )
{
f = GRAINSIZE;
}
else if ( writeAddress >= GRAINSIZE/4 )
{
f = (writeAddress - GRAINSIZE/4) * 2;
}
int output = ( output1 * (GRAINSIZE - f ) + output2 * f ) /GRAINSIZE;
writeAddress++;
if (writeAddress >= GRAINSIZE)
{
writeAddress = 0; // loop around to beginning of grain
readAddress = 0;
buf_ = buf;
buf = buf == buf1 ? buf2 : buf1;
}
return output;
}