Browse Source

Fix dc offset for pulse waveform to match the duty cycle, to stop pumping on note attack/release

dds
user 4 years ago
parent
commit
5457aedfab
1 changed files with 5 additions and 3 deletions
  1. +5
    -3
      synth_waveform.cpp

+ 5
- 3
synth_waveform.cpp View File



// uncomment for more accurate but more computationally expensive frequency modulation // uncomment for more accurate but more computationally expensive frequency modulation
//#define IMPROVE_EXPONENTIAL_ACCURACY //#define IMPROVE_EXPONENTIAL_ACCURACY
#define BASE_AMPLITUDE 0x6000 // 0x7fff won't work due to Gibb's phenomenon, so use 3/4 of full range.





void AudioSynthWaveform::update(void) void AudioSynthWaveform::update(void)
{ {
int32_t new_ph = ph + inc ; int32_t new_ph = ph + inc ;
int32_t val = band_limit_waveform.generate_pulse (new_ph, pulse_width, i) ; int32_t val = band_limit_waveform.generate_pulse (new_ph, pulse_width, i) ;
val += BASE_AMPLITUDE/2 - pulse_width / (0x100000000L / BASE_AMPLITUDE) ; // correct DC offset for duty cycle
*bp++ = (int16_t) ((val * magnitude) >> 16) ; *bp++ = (int16_t) ((val * magnitude) >> 16) ;
ph = new_ph ; ph = new_ph ;
} }
{ {
uint32_t width = ((shapedata->data[i] + 0x8000) & 0xFFFF) << 16; uint32_t width = ((shapedata->data[i] + 0x8000) & 0xFFFF) << 16;
int32_t val = band_limit_waveform.generate_pulse (phasedata[i], width, i) ; int32_t val = band_limit_waveform.generate_pulse (phasedata[i], width, i) ;
val += BASE_AMPLITUDE/2 - width / (0x100000000L / BASE_AMPLITUDE) ; // correct DC offset for duty cycle
*bp++ = (int16_t) ((val * magnitude) >> 16) ; *bp++ = (int16_t) ((val * magnitude) >> 16) ;
} }
break; break;
#define HALF_GUARD (1 << (GUARD_BITS-1)) #define HALF_GUARD (1 << (GUARD_BITS-1))




#define BASE_AMPLITUDE 0x6000 // 0x7fff won't work due to Gibb's phenomenon, so use 3/4 of full range.

#define DEG90 0x40000000u #define DEG90 0x40000000u
#define DEG180 0x80000000u #define DEG180 0x80000000u


int32_t sample = cyclic [i&15] ; int32_t sample = cyclic [i&15] ;
cyclic [i&15] = val ; cyclic [i&15] = val ;
phase_word = new_phase ; phase_word = new_phase ;
return (int16_t) (sample - (sample >> 2)) ; // scale down a bit to avoid overflow on narrow pulses
return (int16_t) (sample >> 1) ; // scale down to avoid overflow on narrow pulses, where the DC shift is big
} }


void BandLimitedWaveform::init_sawtooth (uint32_t freq_word) void BandLimitedWaveform::init_sawtooth (uint32_t freq_word)

Loading…
Cancel
Save