Browse Source

Fix FM modulation of AudioSynthWaveformSineModulated

dds
PaulStoffregen 11 years ago
parent
commit
441fa091b4
2 changed files with 13 additions and 17 deletions
  1. +13
    -16
      synth_sine.cpp
  2. +0
    -1
      synth_sine.h

+ 13
- 16
synth_sine.cpp View File



#include "Audio.h" #include "Audio.h"
#include "arm_math.h" #include "arm_math.h"
#include "utility/dspinst.h"


// data_waveforms.c // data_waveforms.c
extern "C" { extern "C" {
} }





void AudioSynthWaveformSine::frequency(float f) void AudioSynthWaveformSine::frequency(float f)
{ {
if (f > AUDIO_SAMPLE_RATE_EXACT / 2 || f < 0.0) return; if (f > AUDIO_SAMPLE_RATE_EXACT / 2 || f < 0.0) return;
uint32_t i, ph, inc, index, scale; uint32_t i, ph, inc, index, scale;
int32_t val1, val2; int32_t val1, val2;


//Serial.println("AudioSynthWaveformSine::update");
block = allocate(); block = allocate();
if (block) { if (block) {
ph = phase; ph = phase;
val2 *= scale; val2 *= scale;
val1 *= 0xFFFF - scale; val1 *= 0xFFFF - scale;
block->data[i] = (val1 + val2) >> 16; block->data[i] = (val1 + val2) >> 16;
//Serial.print(block->data[i]);
//Serial.print(", ");
//if ((i % 12) == 11) Serial.println();
ph += inc; ph += inc;
} }
//Serial.println();
phase = ph; phase = ph;
transmit(block); transmit(block);
release(block); release(block);


void AudioSynthWaveformSineModulated::frequency(float f) void AudioSynthWaveformSineModulated::frequency(float f)
{ {
if (f > AUDIO_SAMPLE_RATE_EXACT / 2 || f < 0.0) return;
// maximum unmodulated carrier frequency is 11025 Hz
// input = +1.0 doubles carrier
// input = -1.0 DC output
if (f >= AUDIO_SAMPLE_RATE_EXACT / 4 || f < 0.0) return;
phase_increment = (f / AUDIO_SAMPLE_RATE_EXACT) * 4294967296.0f; phase_increment = (f / AUDIO_SAMPLE_RATE_EXACT) * 4294967296.0f;
} }


audio_block_t *block, *modinput; audio_block_t *block, *modinput;
uint32_t i, ph, inc, index, scale; uint32_t i, ph, inc, index, scale;
int32_t val1, val2; int32_t val1, val2;
int16_t mod;


//Serial.println("AudioSynthWaveformSineModulated::update");
modinput = receiveReadOnly(); modinput = receiveReadOnly();
ph = phase; ph = phase;
inc = phase_increment; inc = phase_increment;
if (modinput) { if (modinput) {
// but if we got modulation data, update the phase // but if we got modulation data, update the phase
for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) { for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
ph += inc + modinput->data[i] * modulation_factor;
mod = modinput->data[i];
ph += inc + (multiply_32x32_rshift32(inc, mod << 16) << 1);
} }
release(modinput); release(modinput);
} else { } else {
val2 *= scale; val2 *= scale;
val1 *= 0xFFFF - scale; val1 *= 0xFFFF - scale;
block->data[i] = (val1 + val2) >> 16; block->data[i] = (val1 + val2) >> 16;
//Serial.print(block->data[i]);
//Serial.print(", ");
//if ((i % 12) == 11) Serial.println();
ph += inc + modinput->data[i] * modulation_factor;
// -32768 = no phase increment
// 32767 = double phase increment
mod = modinput->data[i];
ph += inc + (multiply_32x32_rshift32(inc, mod << 16) << 1);
//ph += inc + (((int64_t)inc * (mod << 16)) >> 31);
} }
release(modinput); release(modinput);
} else { } else {
val2 *= scale; val2 *= scale;
val1 *= 0xFFFF - scale; val1 *= 0xFFFF - scale;
block->data[i] = (val1 + val2) >> 16; block->data[i] = (val1 + val2) >> 16;
//Serial.print(block->data[i]);
//Serial.print(", ");
//if ((i % 12) == 11) Serial.println();
ph += inc; ph += inc;
} }
} }

+ 0
- 1
synth_sine.h View File

private: private:
uint32_t phase; uint32_t phase;
uint32_t phase_increment; uint32_t phase_increment;
uint32_t modulation_factor;
audio_block_t *inputQueueArray[1]; audio_block_t *inputQueueArray[1];
}; };



Loading…
Cancel
Save