Browse Source

Add waveform phase modulation

dds
PaulStoffregen 6 years ago
parent
commit
8cea4b3f2c
2 changed files with 19 additions and 12 deletions
  1. +16
    -9
      synth_waveform.cpp
  2. +3
    -3
      synth_waveform.h

+ 16
- 9
synth_waveform.cpp View File

moddata = receiveReadOnly(0); moddata = receiveReadOnly(0);
shapedata = receiveReadOnly(1); shapedata = receiveReadOnly(1);


// Pre-compute the phase angle for every output sample of this update
ph = phase_accumulator; ph = phase_accumulator;
priorphase = phasedata[AUDIO_BLOCK_SAMPLES-1]; priorphase = phasedata[AUDIO_BLOCK_SAMPLES-1];
if (moddata && modulation_type == 0) { if (moddata && modulation_type == 0) {
release(moddata); release(moddata);
} else if (moddata) { } else if (moddata) {
// Phase Modulation // Phase Modulation

// TODO.....

bp = moddata->data;
for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
// more than +/- 180 deg shift by 32 bit overflow of "n"
uint32_t n = (uint16_t)(*bp++) * modulation_factor;
phasedata[i] = ph + n;
ph += inc;
}
release(moddata); release(moddata);
} else { } else {
// No Modulation Input // No Modulation Input
} }
phase_accumulator = ph; phase_accumulator = ph;


// If the amplitude is zero, no output, but phase still increments properly
if (magnitude == 0) { if (magnitude == 0) {
if (shapedata) release(shapedata); if (shapedata) release(shapedata);
return; return;
} }
bp = block->data; bp = block->data;


// Now generate the output samples using the pre-computed phase angles
switch(tone_type) { switch(tone_type) {
case WAVEFORM_SINE: case WAVEFORM_SINE:
for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) { for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
uint32_t width = (shapedata->data[i] + 0x8000) & 0xFFFF; uint32_t width = (shapedata->data[i] + 0x8000) & 0xFFFF;
uint32_t rise = 0xFFFFFFFF / width; uint32_t rise = 0xFFFFFFFF / width;
uint32_t fall = 0xFFFFFFFF / (0xFFFF - width); uint32_t fall = 0xFFFFFFFF / (0xFFFF - width);
width = width << 15;
uint32_t halfwidth = width << 15;
uint32_t n; uint32_t n;
ph = phasedata[i]; ph = phasedata[i];
if (ph < width) {
if (ph < halfwidth) {
n = (ph >> 16) * rise; n = (ph >> 16) * rise;
*bp++ = ((n >> 16) * magnitude) >> 16; *bp++ = ((n >> 16) * magnitude) >> 16;
} else if (ph < 0xFFFFFFFF - width) {
n = 0x7FFFFFFF - (((ph - width) >> 16) * fall);
} else if (ph < 0xFFFFFFFF - halfwidth) {
n = 0x7FFFFFFF - (((ph - halfwidth) >> 16) * fall);
*bp++ = ((n >> 16) * magnitude) >> 16; *bp++ = ((n >> 16) * magnitude) >> 16;
} else { } else {
n = ((ph + width) >> 16) * rise + 0x80000000;
n = ((ph + halfwidth) >> 16) * rise + 0x80000000;
*bp++ = ((n >> 16) * magnitude) >> 16; *bp++ = ((n >> 16) * magnitude) >> 16;
} }
ph += inc; ph += inc;
case WAVEFORM_SAMPLE_HOLD: case WAVEFORM_SAMPLE_HOLD:
for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) { for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
ph = phasedata[i]; ph = phasedata[i];
if (ph < priorphase) {
if (ph < priorphase) { // does not work for phase modulation
sample = random(magnitude) - (magnitude >> 1); sample = random(magnitude) - (magnitude >> 1);
} }
priorphase = ph; priorphase = ph;

+ 3
- 3
synth_waveform.h View File

modulation_type = 0; modulation_type = 0;
} }
void phaseModulation(float degrees) { void phaseModulation(float degrees) {
if (degrees > 18000.0) {
degrees = 18000.0;
if (degrees > 9000.0) {
degrees = 9000.0;
} else if (degrees < 30.0) { } else if (degrees < 30.0) {
degrees = 30.0; degrees = 30.0;
} }
modulation_factor = degrees * (65536.0 / 360.0);
modulation_factor = degrees * (65536.0 / 180.0);
modulation_type = 1; modulation_type = 1;
} }
virtual void update(void); virtual void update(void);

Loading…
Cancel
Save