Skip to content

Commit

Permalink
Merge pull request #9 from risgk/develop
Browse files Browse the repository at this point in the history
v0.3.1 (Prototype)
  • Loading branch information
risgk authored Aug 20, 2023
2 parents 18d44c3 + 78266e1 commit dc7d0b3
Show file tree
Hide file tree
Showing 15 changed files with 116 additions and 86 deletions.
19 changes: 13 additions & 6 deletions Digital-Synth-PRA32-U/pra32-u-amp.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,37 @@
#include "pra32-u-common.h"

class PRA32_U_Amp {
uint8_t m_gain[2];
uint8_t m_gain;
uint8_t m_gain_effective;
int16_t m_gain_mod_input;

public:
PRA32_U_Amp()
: m_gain()
, m_gain_effective()
, m_gain_mod_input()
{
set_gain<0>(127);
set_gain<1>(127);
set_gain(127);
}

template <uint8_t N>
INLINE void set_gain(uint8_t controller_value) {
m_gain[N] = (controller_value + 1) >> 1;
m_gain = (controller_value + 1) >> 1;
}

INLINE void process_at_low_rate(int16_t gain_mod_input) {
update_gain_effective();
m_gain_mod_input = gain_mod_input;
}

INLINE int16_t process(int16_t audio_input) {
int16_t audio_output = (audio_input * m_gain_mod_input) >> 14;
audio_output = (audio_output * (m_gain[0] * m_gain[1])) >> 12;
audio_output = (audio_output * m_gain) >> 6;
return audio_output;
}

private:
INLINE void update_gain_effective() {
m_gain_effective += (m_gain_effective < m_gain);
m_gain_effective -= (m_gain_effective > m_gain);
}
};
51 changes: 28 additions & 23 deletions Digital-Synth-PRA32-U/pra32-u-chorus-fx.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ class PRA32_U_ChorusFx {

uint8_t m_gain;

uint8_t m_chorus_depth_control;
uint16_t m_chorus_depth_control;
uint16_t m_chorus_depth_control_effective;
uint32_t m_chorus_rate;
uint8_t m_chorus_delay_time_control;
uint8_t m_chorus_delay_time_control_effective;
uint16_t m_chorus_delay_time_control;
uint16_t m_chorus_delay_time_control_effective;
uint8_t m_param_chorus_mode;
boolean m_param_chorus_bypass;
uint8_t m_effective_chorus_mode;
Expand All @@ -36,13 +37,13 @@ class PRA32_U_ChorusFx {
, m_gain()

, m_chorus_depth_control()
, m_chorus_depth_control_effective()
, m_chorus_rate()
, m_chorus_delay_time_control()
, m_chorus_delay_time_control_effective()
, m_param_chorus_mode()
, m_param_chorus_bypass()
, m_effective_chorus_mode()
, m_chorus_depth_control_actual()
, m_chorus_lfo_phase()
, m_chorus_delay_time()
{
Expand All @@ -57,14 +58,15 @@ class PRA32_U_ChorusFx {
m_effective_chorus_mode = CHORUS_MODE_OFF;
set_gain(90);

m_chorus_depth_control_actual = 64;
m_chorus_depth_control_effective = 64 << 6;
m_chorus_delay_time_control_effective = 64 << 6;
}

INLINE void set_chorus_depth(uint8_t controller_value) {
if (controller_value < 126) {
m_chorus_depth_control = controller_value;
m_chorus_depth_control = controller_value << 6;
} else {
m_chorus_depth_control = 126;
m_chorus_depth_control = 126 << 6;
}
}

Expand All @@ -73,7 +75,7 @@ class PRA32_U_ChorusFx {
}

INLINE void set_chorus_delay_time(uint8_t controller_value) {
m_chorus_delay_time_control = controller_value;
m_chorus_delay_time_control = controller_value << 6;
}

INLINE void set_chorus_mode(uint8_t controller_value) {
Expand Down Expand Up @@ -129,23 +131,28 @@ class PRA32_U_ChorusFx {
return m_chorus_delay_time[N];
}

INLINE void process_at_low_rate() {
INLINE void process_at_low_rate(uint8_t count) {
#if 1
// todo
static_cast<void>(count);

m_chorus_depth_control_effective += (m_chorus_depth_control_effective < m_chorus_depth_control);
m_chorus_depth_control_effective -= (m_chorus_depth_control_effective > m_chorus_depth_control);

m_chorus_delay_time_control_effective += (m_chorus_delay_time_control_effective < m_chorus_delay_time_control);
m_chorus_delay_time_control_effective -= (m_chorus_delay_time_control_effective > m_chorus_delay_time_control);

if (m_chorus_delay_time_control_effective < 64) {
if (m_chorus_depth_control > (m_chorus_delay_time_control_effective << 1)) {
m_chorus_depth_control_actual = (m_chorus_delay_time_control_effective << 1);
uint16_t chorus_depth_control_effective_limited;
if (m_chorus_delay_time_control_effective < (64 << 6)) {
if (m_chorus_depth_control_effective > (m_chorus_delay_time_control_effective << 1)) {
chorus_depth_control_effective_limited = (m_chorus_delay_time_control_effective << 1);
} else {
m_chorus_depth_control_actual = m_chorus_depth_control;
chorus_depth_control_effective_limited = m_chorus_depth_control_effective;
}
} else {
if (m_chorus_depth_control > ((127 - m_chorus_delay_time_control_effective) << 1)) {
m_chorus_depth_control_actual = ((127 - m_chorus_delay_time_control_effective) << 1);
if (m_chorus_depth_control_effective > (((127 << 6) - m_chorus_delay_time_control_effective) << 1)) {
chorus_depth_control_effective_limited = (((127 << 6) - m_chorus_delay_time_control_effective) << 1);
} else {
m_chorus_depth_control_actual = m_chorus_depth_control;
chorus_depth_control_effective_limited = m_chorus_depth_control_effective;
}
}

Expand All @@ -154,7 +161,7 @@ class PRA32_U_ChorusFx {

int16_t chorus_lfo_wave_level = get_chorus_lfo_wave_level(m_chorus_lfo_phase);

int16_t chorus_lfo_level = (chorus_lfo_wave_level * m_chorus_depth_control_actual) >> 8;
int16_t chorus_lfo_level = (chorus_lfo_wave_level * chorus_depth_control_effective_limited) >> 14;

switch (m_effective_chorus_mode) {
case CHORUS_MODE_BYPASS :
Expand All @@ -168,16 +175,14 @@ class PRA32_U_ChorusFx {
case CHORUS_MODE_P_STEREO :
case CHORUS_MODE_MONO :
{
uint16_t chorus_delay_time_control_mul_4 = m_chorus_delay_time_control_effective * 4;
m_chorus_delay_time[0] = (chorus_delay_time_control_mul_4 << 4) + chorus_lfo_level;
m_chorus_delay_time[0] = m_chorus_delay_time_control_effective + chorus_lfo_level;
m_chorus_delay_time[1] = m_chorus_delay_time[0];
}
break;
case CHORUS_MODE_STEREO_2 :
{
uint16_t chorus_delay_time_control_mul_4 = m_chorus_delay_time_control_effective * 4;
m_chorus_delay_time[0] = (chorus_delay_time_control_mul_4 << 4) - chorus_lfo_level;
m_chorus_delay_time[1] = (chorus_delay_time_control_mul_4 << 4) + chorus_lfo_level;
m_chorus_delay_time[0] = m_chorus_delay_time_control_effective - chorus_lfo_level;
m_chorus_delay_time[1] = m_chorus_delay_time_control_effective + chorus_lfo_level;
}
break;
}
Expand Down
8 changes: 4 additions & 4 deletions Digital-Synth-PRA32-U/pra32-u-filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class PRA32_U_Filter {
m_resonance_index = (controller_value + 4) >> 4;
}

INLINE int8_t get_cutoff_eg_amt(uint8_t controller_value) {
INLINE int8_t get_cutoff_mod_amt(uint8_t controller_value) {
static int8_t cutoff_mod_amt_table[128] = {
-120, -120, -120, -120, -120, -118, -116, -114,
-112, -110, -108, -106, -104, -102, -100, -98,
Expand All @@ -93,11 +93,11 @@ class PRA32_U_Filter {
}

INLINE void set_cutoff_eg_amt(uint8_t controller_value) {
m_cutoff_eg_amt = get_cutoff_eg_amt(controller_value);
m_cutoff_eg_amt = get_cutoff_mod_amt(controller_value);
}

INLINE void set_cutoff_lfo_amt(uint8_t controller_value) {
m_cutoff_lfo_amt = get_cutoff_eg_amt(controller_value);
m_cutoff_lfo_amt = get_cutoff_mod_amt(controller_value);
}

INLINE void set_cutoff_pitch_amt(uint8_t controller_value) {
Expand All @@ -117,7 +117,7 @@ class PRA32_U_Filter {
}

INLINE void process_at_low_rate(uint8_t count, int16_t eg_input, int16_t lfo_input, uint16_t osc_pitch) {
switch (count & (0x08 - 1)) {
switch (count & (0x04 - 1)) {
case 0x00:
update_cutoff_control_effective();
break;
Expand Down
2 changes: 1 addition & 1 deletion Digital-Synth-PRA32-U/pra32-u-lfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,6 @@ class PRA32_U_LFO {
}
lfo_depth <<= 1;

m_lfo_level = (lfo_depth * m_lfo_wave_level) >> 9;
m_lfo_level = (lfo_depth * m_lfo_wave_level) >> 7;
}
};
59 changes: 38 additions & 21 deletions Digital-Synth-PRA32-U/pra32-u-osc.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,20 @@ class PRA32_U_Osc {

boolean m_mono_mode;
boolean m_gate_enabled;
uint8_t m_osc2_mix;
uint8_t m_mixer_osc_mix_control;
uint8_t m_mixer_osc_mix_control_effective;
int8_t m_osc2_pitch;
int8_t m_osc2_detune;

uint8_t m_phase_high;
int8_t m_osc1_shape_control;
int8_t m_osc1_shape_control_effective;
int8_t m_osc1_morph_control;
int8_t m_osc1_morph_control_effective;
int32_t m_osc1_shape[4];
int32_t m_osc1_shape_effective[4];
int8_t m_mixer_noise_sub_osc_control;
int8_t m_mixer_noise_sub_osc_control_effective;
int16_t m_mix_table[OSC_MIX_TABLE_LENGTH];
int8_t m_shape_eg_amt;
int8_t m_shape_lfo_amt;
Expand Down Expand Up @@ -77,17 +80,20 @@ class PRA32_U_Osc {

, m_mono_mode()
, m_gate_enabled()
, m_osc2_mix()
, m_mixer_osc_mix_control()
, m_mixer_osc_mix_control_effective()
, m_osc2_pitch()
, m_osc2_detune()

, m_phase_high()
, m_osc1_shape_control()
, m_osc1_shape_control_effective()
, m_osc1_morph_control()
, m_osc1_morph_control_effective()
, m_osc1_shape()
, m_osc1_shape_effective()
, m_mixer_noise_sub_osc_control()
, m_mixer_noise_sub_osc_control_effective()
, m_mix_table()
, m_shape_eg_amt()
, m_shape_lfo_amt()
Expand All @@ -97,11 +103,11 @@ class PRA32_U_Osc {
m_portamento_coef[2] = 0;
m_portamento_coef[3] = 0;

set_mono_mode (false);
set_gate_enabled(false);
set_osc2_mix (0);
set_osc2_pitch (0);
set_osc2_detune (0);
set_mono_mode (false);
set_gate_enabled (false);
set_mixer_osc_mix(0);
set_osc2_pitch (0);
set_osc2_detune (0);

m_waveform[0] = WAVEFORM_SAW;
m_waveform[1] = WAVEFORM_SAW;
Expand Down Expand Up @@ -213,8 +219,7 @@ class PRA32_U_Osc {
}

INLINE void set_mixer_sub_osc_control(uint8_t controller_value) {
controller_value = (controller_value < 127) ? controller_value : 128;
m_mixer_noise_sub_osc_control = controller_value - 64;
m_mixer_noise_sub_osc_control = (((controller_value - 63) >> 1) << 1);
}

INLINE int16_t get_pitch_mod_amt_table(uint8_t controller_value) {
Expand Down Expand Up @@ -272,8 +277,8 @@ class PRA32_U_Osc {
m_gate_enabled = gate_enabled;
}

INLINE void set_osc2_mix(uint8_t controller_value) {
m_osc2_mix = (controller_value + 1) >> 1;
INLINE void set_mixer_osc_mix(uint8_t controller_value) {
m_mixer_osc_mix_control = ((controller_value + 1) >> 1) << 1;
}

INLINE void set_osc2_pitch(uint8_t controller_value) {
Expand Down Expand Up @@ -369,6 +374,7 @@ class PRA32_U_Osc {
break;
case 0x03:
update_freq_offset<5>(noise_int15);
update_mixer_control_effective();
break;
case 0x04:
update_freq_offset<2>(noise_int15);
Expand All @@ -383,7 +389,7 @@ class PRA32_U_Osc {
break;
case 0x07:
update_freq_offset<7>(noise_int15);
update_osc1_shape_control_effective();
update_osc1_control_effective();
break;
}
}
Expand Down Expand Up @@ -440,8 +446,8 @@ class PRA32_U_Osc {
INLINE int32_t process_osc(int16_t noise_int15, bool halve_noise_level) {
int32_t result = 0;

int16_t osc1_gain = m_mix_table[(OSC_MIX_TABLE_LENGTH - 1) - m_osc2_mix];
int16_t osc2_gain = m_mix_table[ m_osc2_mix];
int16_t osc1_gain = m_mix_table[(OSC_MIX_TABLE_LENGTH - 1) - (m_mixer_osc_mix_control_effective >> 1)];
int16_t osc2_gain = m_mix_table[ (m_mixer_osc_mix_control_effective >> 1)];

m_phase[N] += m_freq[N];
boolean new_period_osc1 = (m_phase[N] & 0x00FFFFFF) < m_freq[N]; // crossing the begin of a osc 1 wave, the begin or the middle of a sub osc wave
Expand All @@ -461,17 +467,17 @@ class PRA32_U_Osc {
m_wave_table[N + 8] = reinterpret_cast<const int16_t*>( reinterpret_cast<const uint8_t*>( m_wave_table[N + 8]) +
(reinterpret_cast<const uintptr_t>(m_wave_table_temp[N]) * new_period_osc1_add));
int16_t wave_3 = get_wave_level(m_wave_table[N + 8], phase_3);
result += ((((wave_3 * osc1_gain * m_osc_gain_effective[N]) >> 10) * -m_osc1_morph_control) >> 6) * (m_waveform[0] == WAVEFORM_1_PULSE);
result += ((((wave_3 * osc1_gain * m_osc_gain_effective[N]) >> 10) * -m_osc1_morph_control_effective) >> 6) * (m_waveform[0] == WAVEFORM_1_PULSE);

if (m_mixer_noise_sub_osc_control >= 0) {
if (m_mixer_noise_sub_osc_control_effective >= 0) {
// Sub Osc (wave_1)
int16_t wave_1 = get_wave_level(m_wave_table[N + 12], m_phase[N] >> 1);
result += (wave_1 * m_mixer_noise_sub_osc_control * m_osc_gain_effective[N]) >> 6;
} else if (m_waveform[1] != WAVEFORM_2_NOISE) {
// Noise (wave_1)
int16_t wave_1 = -OSC_WAVE_TABLE_AMPLITUDE
+(OSC_WAVE_TABLE_AMPLITUDE << 1) * (noise_int15 & 0x1);
result += (wave_1 * -m_mixer_noise_sub_osc_control * m_osc_gain_effective[N]) >> (6 + halve_noise_level);
result += (wave_1 * -m_mixer_noise_sub_osc_control_effective * m_osc_gain_effective[N]) >> (6 + halve_noise_level);
}

m_phase[N + 4] += m_freq[N + 4];
Expand Down Expand Up @@ -521,10 +527,10 @@ class PRA32_U_Osc {
}

if (N >= 4) {
pitch_temp += (lfo_level * m_pitch_lfo_amt[1]) >> 9;
pitch_temp += (lfo_level * m_pitch_lfo_amt[1]) >> 10;
pitch_temp += (m_osc2_pitch << 8) + m_osc2_detune + m_osc2_detune;
} else {
pitch_temp += (lfo_level * m_pitch_lfo_amt[0]) >> 9;
pitch_temp += (lfo_level * m_pitch_lfo_amt[0]) >> 10;
}

coarse = high_byte(pitch_temp);
Expand Down Expand Up @@ -594,15 +600,26 @@ class PRA32_U_Osc {
}
}

INLINE void update_osc1_shape_control_effective() {
INLINE void update_osc1_control_effective() {
m_osc1_shape_control_effective += (m_osc1_shape_control_effective < m_osc1_shape_control);
m_osc1_shape_control_effective -= (m_osc1_shape_control_effective > m_osc1_shape_control);

m_osc1_morph_control_effective += (m_osc1_morph_control_effective < m_osc1_morph_control);
m_osc1_morph_control_effective -= (m_osc1_morph_control_effective > m_osc1_morph_control);
}

INLINE void update_mixer_control_effective() {
m_mixer_osc_mix_control_effective += (m_mixer_osc_mix_control_effective < m_mixer_osc_mix_control);
m_mixer_osc_mix_control_effective -= (m_mixer_osc_mix_control_effective > m_mixer_osc_mix_control);

m_mixer_noise_sub_osc_control_effective += (m_mixer_noise_sub_osc_control_effective < m_mixer_noise_sub_osc_control);
m_mixer_noise_sub_osc_control_effective -= (m_mixer_noise_sub_osc_control_effective > m_mixer_noise_sub_osc_control);
}

template <uint8_t N>
INLINE void update_osc1_shape(int16_t lfo_level, int16_t eg_level) {
int32_t osc1_shape = 0x8000u - (m_osc1_shape_control_effective << 8)
+ ((eg_level * m_shape_eg_amt) >> 5) - ((lfo_level * m_shape_lfo_amt) >> 3);
+ ((eg_level * m_shape_eg_amt) >> 5) - ((lfo_level * m_shape_lfo_amt) >> 5);

#if 0
// osc1_shape = clamp(osc1_shape, 0x0, 0x10000)
Expand Down
Loading

0 comments on commit dc7d0b3

Please sign in to comment.