Selaa lähdekoodia

Fix various issues with bandlimit pulse after testing with changing/modulating pulse width and freq, also invert phase of square and pulse to match existing tone types

dds
user 4 vuotta sitten
vanhempi
commit
563a899378
2 muutettua tiedostoa jossa 38 lisäystä ja 17 poistoa
  1. +23
    -5
      synth_waveform.cpp
  2. +15
    -12
      synth_waveform.h

+ 23
- 5
synth_waveform.cpp Näytä tiedosto

@@ -486,6 +486,7 @@ void AudioSynthWaveformModulated::update(void)

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

#define DEG90 0x40000000u
#define DEG180 0x80000000u

#define PHASE_SCALE (0x100000000L / (2 * BASE_AMPLITUDE))
@@ -578,19 +579,27 @@ int32_t BandLimitedWaveform::process_active_steps_saw (uint32_t new_phase)

void BandLimitedWaveform::new_step_check_pulse (uint32_t new_phase, uint32_t pulse_width, int i)
{
if (new_phase >= pulse_width && phase_word < pulse_width) // detect rising step
if (new_phase >= pulse_width && phase_word < pulse_width) // detect falling step
{
int32_t offset = (int32_t) ((uint64_t) (SCALE<<GUARD_BITS) * (pulse_width - phase_word) / (new_phase - phase_word)) ;
if (offset == SCALE<<GUARD_BITS)
offset -- ;
insert_step (- offset, true, i) ;
if (pulse_state) // guard against two falling steps in a row (if pulse width changing for instance)
{
insert_step (- offset, false, i) ;
pulse_state = false ;
}
}
if (new_phase < pulse_width && phase_word >= pulse_width) // detect wrap around, falling step
if (new_phase < pulse_width && phase_word >= pulse_width) // detect wrap around, rising step
{
int32_t offset = (int32_t) ((uint64_t) (SCALE<<GUARD_BITS) * (- phase_word) / (new_phase - phase_word)) ;
if (offset == SCALE<<GUARD_BITS)
offset -- ;
insert_step (- offset, false, i) ;
if (!pulse_state) // guard against two rising steps in a row (if pulse width changing for instance)
{
insert_step (- offset, true, i) ;
pulse_state = true ;
}
}
}

@@ -668,7 +677,16 @@ void BandLimitedWaveform::init_pulse (uint32_t freq_word, uint32_t pulse_width)
for (int i = 0 ; i < 2*SUPPORT ; i++)
phase_word -= freq_word ;

dc_offset = phase_word < DEG180 ? -BASE_AMPLITUDE : BASE_AMPLITUDE ;
if (phase_word < DEG90)
{
dc_offset = BASE_AMPLITUDE ;
pulse_state = true ;
}
else
{
dc_offset = -BASE_AMPLITUDE ;
pulse_state = false ;
}
for (int i = 0 ; i < 2*SUPPORT ; i++)
{

+ 15
- 12
synth_waveform.h Näytä tiedosto

@@ -49,7 +49,7 @@ extern const int16_t AudioWaveformSine[257];
#define WAVEFORM_BANDLIMIT_SAWTOOTH 9
#define WAVEFORM_BANDLIMIT_SAWTOOTH_REVERSE 10
#define WAVEFORM_BANDLIMIT_SQUARE 11
#define WAVEFORM_BANDLIMIT_PULSE 12
#define WAVEFORM_BANDLIMIT_PULSE 12


typedef struct step_state
@@ -87,6 +87,7 @@ private:
int newptr ; // buffer pointers into states, AND'd with PTRMASK to keep in buffer range.
int delptr ;
int32_t cyclic[16] ; // circular buffer of output samples
bool pulse_state ;
};


@@ -108,6 +109,7 @@ public:
}
phase_increment = freq * (4294967296.0 / AUDIO_SAMPLE_RATE_EXACT);
if (phase_increment > 0x7FFE0000u) phase_increment = 0x7FFE0000;
ensure_pulse_width_ok () ;
}
void phase(float angle) {
if (angle < 0.0) {
@@ -141,13 +143,7 @@ public:
n = 1.0;
}
pulse_width = n * 4294967296.0;
if (tone_type == WAVEFORM_BANDLIMIT_PULSE)
{
if (pulse_width < phase_increment) // ensure pulse never narrow enough to glitch out of existence.
pulse_width = phase_increment ;
else if (pulse_width > -phase_increment)
pulse_width = -phase_increment;
}
ensure_pulse_width_ok () ;
}
void begin(short t_type) {
phase_offset = 0;
@@ -156,10 +152,7 @@ public:
band_limit_waveform.init_square (phase_increment) ;
else if (t_type == WAVEFORM_BANDLIMIT_PULSE)
{
if (pulse_width < phase_increment) // ensure pulse never narrow enough to glitch out of existence.
pulse_width = phase_increment ;
else if (pulse_width > -phase_increment)
pulse_width = -phase_increment;
ensure_pulse_width_ok () ;
band_limit_waveform.init_pulse (phase_increment, pulse_width) ;
}
else if (t_type == WAVEFORM_BANDLIMIT_SAWTOOTH || t_type == WAVEFORM_BANDLIMIT_SAWTOOTH_REVERSE)
@@ -177,6 +170,16 @@ public:
virtual void update(void);

private:
void ensure_pulse_width_ok()
{
if (tone_type == WAVEFORM_BANDLIMIT_PULSE)
{
if (pulse_width < phase_increment) // ensure pulse never narrow enough to glitch out of existence.
pulse_width = phase_increment ;
else if (pulse_width > -phase_increment)
pulse_width = -phase_increment;
}
}
uint32_t phase_accumulator;
uint32_t phase_increment;
uint32_t phase_offset;

Loading…
Peruuta
Tallenna