В настоящее время я сталкиваюсь с проблемами с анализом LPC и извлечением формант, где данные оказываются постоянно неверными. Я приложил дамп данных и кода. Любая помощь будет принята с благодарностью!
Код: Выделить всё
#include // ARM DSP extensions. https://www.keil.com/pack/doc/CMSIS/DSP/html/index.html
#include
class AudioEffectFormantShifter : public AudioStream_F32 {
public:
// Constructor
AudioEffectFormantShifter(void) : AudioStream_F32(1, inputQueueArray_f32) {
Serial.println("Starting formant shifter");
generateHanningWindow(window, FRAME_SIZE);
srand(1000);
}
void AudioEffectFormantShifter::update(void) {
audio_block_f32_t* audio_block = AudioStream_F32::receiveWritable_f32();
if (!audio_block) {
Serial.println("No audio block received");
return;
}
//applyGain(audio_block, 10.0); -- Testing to see if modifying the audio block and transmitting works (it does!)
processAudioBlock(audio_block);
AudioStream_F32::transmit(audio_block);
AudioStream_F32::release(audio_block);
//Serial.println("Audio block transmitted");
}
void applyGain(audio_block_f32_t* audio_block, float gain) {
for (int i = 0; i < AUDIO_BLOCK_SAMPLES; i++) {
audio_block->data[i] *= gain;
}
}
void generateHanningWindow(float32_t* window, int size) {
const float32_t pi = 3.14159265358979323846;
for (int i = 0; i < size; i++) {
window[i] = 0.5f * (1.0f - arm_cos_f32(2.0f * pi * i / (size - 1)));
}
}
void processAudioBlock(audio_block_f32_t *audio_block) {
//Serial.println("Starting processAudioBlock");
Serial.println("Audio block data:");
debugPrintBuffer(audio_block->data, BLOCK_SIZE);
manageBuffer(inputBuffer, audio_block->data, BLOCK_SIZE, FRAME_SIZE, OVERLAP_SIZE);
Serial.println("After manageBuffer");
debugPrintBuffer(inputBuffer, FRAME_SIZE);
applyWindowFunction(inputBuffer, window, FRAME_SIZE);
Serial.println("After applyWindowFunction");
debugPrintBuffer(inputBuffer, FRAME_SIZE);
performLPCAnalysis(inputBuffer, LPC_ORDER, lpcCoeffs, autocorr, reflectionCoeffs);
Serial.println("After performLPCAnalysis");
debugPrintLPCResults(lpcCoeffs, autocorr, LPC_ORDER);
int numFormants = 0;
extractFormants(lpcCoeffs, LPC_ORDER, formants, numFormants);
Serial.println("After extractFormants");
debugPrintFormants(formants, numFormants);
shiftFormantFrequencies(formants, numFormants, formantShiftFactor);
Serial.println("After shiftFormantFrequencies");
debugPrintFormants(formants, numFormants);
synthesizeModifiedSignal(lpcCoeffs, LPC_ORDER, outputBuffer, FRAME_SIZE);
Serial.println("After synthesizeModifiedSignal");
debugPrintBuffer(outputBuffer, FRAME_SIZE);
applyOverlapAdd(outputBuffer, outputBuffer, FRAME_SIZE, BLOCK_SIZE, OVERLAP_SIZE);
Serial.println("After applyOverlapAdd");
debugPrintBuffer(outputBuffer, FRAME_SIZE);
for (int i = 0; i < BLOCK_SIZE; i++) {
audio_block->data[i] = outputBuffer[i + OVERLAP_SIZE];
}
delay(10000);
//Serial.println("Finished processAudioBlock");
}
float32_t setFormantShiftFactor(float32_t factor) {
formantShiftFactor = factor;
return formantShiftFactor;
}
void debugPrintBuffer(const float32_t* buffer, int size) {
for (int i = 0; i < size; i++) {
Serial.print(buffer[i]);
Serial.print(", ");
}
Serial.println();
}
void debugPrintLPCResults(const float32_t* lpcCoeffs, const float32_t* autocorr, int order) {
Serial.println("LPC Coefficients:");
for (int i = 0; i
Подробнее здесь: [url]https://stackoverflow.com/questions/78532949/teensy-based-lpc-linear-predictive-coding-formant-shifter[/url]