Skip to content

Commit

Permalink
Expose and document operator parameters
Browse files Browse the repository at this point in the history
Also cleans up identifiers related to SSG envelope control.
Should be noted that the exact implementation of SSG
envelope control in SiON is custom and the available values
do not necessarily match OPNA.
  • Loading branch information
YuriSizov committed Nov 13, 2024
1 parent e143fdc commit 2961a4d
Show file tree
Hide file tree
Showing 9 changed files with 173 additions and 45 deletions.
66 changes: 65 additions & 1 deletion doc_classes/SiOPMOperatorParams.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,72 @@
Container for processing operator parameters within [SiOPMChannelParams].
</brief_description>
<description>
[b]Warning:[/b] This class currently has no intended use in the API. If you need this class and its unexposed methods in your project, please [b][url=https://github.com/YuriSizov/gdsion/issues]create a feature request with your use case[/url][/b]!
</description>
<tutorials>
</tutorials>
<members>
<member name="amplitude_modulation_shift" type="int" setter="set_amplitude_modulation_shift" getter="get_amplitude_modulation_shift">
Modulation shift for the amplitude.
</member>
<member name="attack_rate" type="int" setter="set_attack_rate" getter="get_attack_rate">
Attack rate of the pulse.
</member>
<member name="decay_rate" type="int" setter="set_decay_rate" getter="get_decay_rate">
Decay rate of the pulse.
</member>
<member name="detune1" type="int" setter="set_detune1" getter="get_detune1">
First detune factor of the pulse.
</member>
<member name="detune2" type="int" setter="set_detune2" getter="get_detune2">
Second detune factor of the pulse, typicaly a detune for pTSS.
</member>
<member name="envelope_reset_on_attack" type="bool" setter="set_envelope_reset_on_attack" getter="is_envelope_reset_on_attack">
Flag that enables envelope reset on attack.
</member>
<member name="fine_multiple" type="int" setter="set_fine_multiple" getter="get_fine_multiple">
Fine multiple factor.
</member>
<member name="fixed_pitch" type="int" setter="set_fixed_pitch" getter="get_fixed_pitch">
Fixed pitch value for the pulse. This makes the operator ignore the pitch/note played with the owner voice.
</member>
<member name="frequency_modulation_level" type="int" setter="set_frequency_modulation_level" getter="get_frequency_modulation_level">
Level for the frequency modulation. Value of [code]5[/code] means standard modulation.
</member>
<member name="initial_phase" type="int" setter="set_initial_phase" getter="get_initial_phase">
Initial phase of the pulse.
</member>
<member name="key_scaling_level" type="int" setter="set_key_scaling_level" getter="get_key_scaling_level">
Level for the key scaling.
</member>
<member name="key_scaling_rate" type="int" setter="set_key_scaling_rate" getter="get_key_scaling_rate">
Rate of the key scaling.
</member>
<member name="multiple" type="int" setter="set_multiple" getter="get_multiple">
Multiple factor.
</member>
<member name="mute" type="bool" setter="set_mute" getter="is_mute">
Mute flag.
</member>
<member name="pitch_table_type" type="int" setter="set_pitch_table_type" getter="get_pitch_table_type" enum="SiONPitchTableType">
Type of the pitch table used by the pulse.
</member>
<member name="pulse_generator_type" type="int" setter="set_pulse_generator_type" getter="get_pulse_generator_type">
Type of the pulse generator. Must be one of the [enum SiONPulseGeneratorType] values, or another value in the valid range.
</member>
<member name="release_rate" type="int" setter="set_release_rate" getter="get_release_rate">
Release rate of the pulse.
</member>
<member name="ssg_envelope_control" type="int" setter="set_ssg_envelope_control" getter="get_ssg_envelope_control">
Type of the SSG envelope control. This features uses the ADSR envelope to create a wave shape as the final envelope. The exact nature of the effect depends on this value.
</member>
<member name="sustain_level" type="int" setter="set_sustain_level" getter="get_sustain_level">
Sustain level of the pulse.
</member>
<member name="sustain_rate" type="int" setter="set_sustain_rate" getter="get_sustain_rate">
Sustain rate of the pulse. Allows for the pulse to change while being sustained.
</member>
<member name="total_level" type="int" setter="set_total_level" getter="get_total_level">
Total level of the pulse.
</member>
</members>
</class>
2 changes: 1 addition & 1 deletion src/chip/channels/siopm_channel_fm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -663,7 +663,7 @@ void SiOPMChannelFM::set_fixed_pitch(int p_value) {
}

void SiOPMChannelFM::set_ssg_envelope_control(int p_value) {
_active_operator->set_ssg_type_envelope_control(p_value);
_active_operator->set_ssg_type(p_value);
}

void SiOPMChannelFM::set_envelope_reset(bool p_reset) {
Expand Down
2 changes: 1 addition & 1 deletion src/chip/channels/siopm_channel_pcm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ void SiOPMChannelPCM::set_fixed_pitch(int p_value) {
}

void SiOPMChannelPCM::set_ssg_envelope_control(int p_value) {
_operator->set_ssg_type_envelope_control(p_value);
_operator->set_ssg_type(p_value);
}

void SiOPMChannelPCM::set_envelope_reset(bool p_reset) {
Expand Down
28 changes: 14 additions & 14 deletions src/chip/channels/siopm_operator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const int SiOPMOperator::_eg_next_state_table[2][EG_MAX] = {
void SiOPMOperator::set_attack_rate(int p_value) {
_attack_rate = p_value & 63;

if (_ssg_type_envelope_control == 8 || _ssg_type_envelope_control == 12) {
if (_ssg_type == 8 || _ssg_type == 12) {
_eg_ssgec_attack_rate = (_attack_rate >= 56) ? 1 : 0;
} else {
_eg_ssgec_attack_rate = (_attack_rate >= 60) ? 1 : 0;
Expand Down Expand Up @@ -151,16 +151,16 @@ void SiOPMOperator::set_mute(bool p_mute) {
_update_total_level();
}

void SiOPMOperator::set_ssg_type_envelope_control(int p_value) {
void SiOPMOperator::set_ssg_type(int p_value) {
if (p_value > 7) {
_eg_state_table_index = 1;
_ssg_type_envelope_control = p_value;
if (_ssg_type_envelope_control > 17) {
_ssg_type_envelope_control = 9;
_ssg_type = p_value;
if (_ssg_type > 17) {
_ssg_type = 9;
}
} else {
_eg_state_table_index = 0;
_ssg_type_envelope_control = 0;
_ssg_type = 0;
}
}

Expand Down Expand Up @@ -315,15 +315,15 @@ void SiOPMOperator::_shift_eg_state(EGState p_state) {
if (_eg_sustain_level) {
_eg_state = EG_DECAY;

if (_ssg_type_envelope_control != 0) {
if (_ssg_type != 0) {
_eg_level = 0;

_eg_state_shift_level = _eg_sustain_level >> 2;
if (_eg_state_shift_level > SiOPMRefTable::ENV_BOTTOM_SSGEC) {
_eg_state_shift_level = SiOPMRefTable::ENV_BOTTOM_SSGEC;
}

int level_index = _table->eg_ssg_table_index[_ssg_type_envelope_control - 8][_eg_ssgec_attack_rate][_eg_ssgec_state];
int level_index = _table->eg_ssg_table_index[_ssg_type - 8][_eg_ssgec_attack_rate][_eg_ssgec_state];
_eg_level_table = make_vector<int>(_table->eg_level_tables[level_index]);
} else {
_eg_level = 0;
Expand All @@ -342,11 +342,11 @@ void SiOPMOperator::_shift_eg_state(EGState p_state) {
case EG_SUSTAIN: {
_eg_state = EG_SUSTAIN;

if (_ssg_type_envelope_control != 0) {
if (_ssg_type != 0) {
_eg_level = _eg_sustain_level >> 2;
_eg_state_shift_level = SiOPMRefTable::ENV_BOTTOM_SSGEC;

int level_index = _table->eg_ssg_table_index[_ssg_type_envelope_control - 8][_eg_ssgec_attack_rate][_eg_ssgec_state];
int level_index = _table->eg_ssg_table_index[_ssg_type - 8][_eg_ssgec_attack_rate][_eg_ssgec_state];
_eg_level_table = make_vector<int>(_table->eg_level_tables[level_index]);
} else {
_eg_level = _eg_sustain_level;
Expand All @@ -363,7 +363,7 @@ void SiOPMOperator::_shift_eg_state(EGState p_state) {
if (_eg_level < SiOPMRefTable::ENV_BOTTOM) {
_eg_state = EG_RELEASE;
_eg_state_shift_level = SiOPMRefTable::ENV_BOTTOM;
_eg_level_table = make_vector<int>(_table->eg_level_tables[_ssg_type_envelope_control != 0 ? 1 : 0]);
_eg_level_table = make_vector<int>(_table->eg_level_tables[_ssg_type != 0 ? 1 : 0]);

int index = _release_rate + _eg_key_scale_rate;
_eg_increment_table = make_vector<int>(_table->eg_increment_tables[_table->eg_table_selector[index]]);
Expand Down Expand Up @@ -462,7 +462,7 @@ void SiOPMOperator::set_operator_params(const Ref<SiOPMOperatorParams> &p_params
_pitch_index_shift = p_params->get_detune2();

_mute = p_params->is_mute() ? SiOPMRefTable::ENV_BOTTOM : 0;
_ssg_type_envelope_control = p_params->get_ssg_type_envelope_control();
_ssg_type = p_params->get_ssg_envelope_control();
_envelope_reset_on_attack = p_params->is_envelope_reset_on_attack();

if (p_params->get_fixed_pitch() > 0) {
Expand Down Expand Up @@ -498,7 +498,7 @@ void SiOPMOperator::get_operator_params(const Ref<SiOPMOperatorParams> &r_params
r_params->set_detune2(get_ptss_detune());
r_params->set_amplitude_modulation_shift(get_amplitude_modulation_shift());

r_params->set_ssg_type_envelope_control(_ssg_type_envelope_control);
r_params->set_ssg_envelope_control(_ssg_type);
r_params->set_envelope_reset_on_attack(is_envelope_reset_on_attack());

r_params->set_initial_phase(get_key_on_phase());
Expand Down Expand Up @@ -611,7 +611,7 @@ String SiOPMOperator::_to_string() const {
params += "phase=" + itos(get_key_on_phase()) + ", ";
params += "note=" + String(is_pitch_fixed() ? "yes" : "no") + ", ";

params += "ssg=" + itos(_ssg_type_envelope_control) + ", ";
params += "ssgec=" + itos(_ssg_type) + ", ";
params += "mute=" + itos(_mute) + ", ";
params += "reset=" + String(_envelope_reset_on_attack ? "yes" : "no");

Expand Down
7 changes: 4 additions & 3 deletions src/chip/channels/siopm_operator.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ class SiOPMOperator : public Object {

// Mute [0 / SiOPMRefTable::ENV_BOTTOM].
int _mute = 0;
int _ssg_type_envelope_control = 0;
// SSG-type envelope control [0,17].
int _ssg_type = 0;
bool _envelope_reset_on_attack = false;

void _update_key_code(int p_value);
Expand Down Expand Up @@ -223,8 +224,8 @@ class SiOPMOperator : public Object {
bool is_mute() const;
void set_mute(bool p_mute);

int get_ssg_type_envelope_control() const { return _ssg_type_envelope_control; }
void set_ssg_type_envelope_control(int p_value);
int get_ssg_type() const { return _ssg_type; }
void set_ssg_type(int p_value);

bool is_envelope_reset_on_attack() const { return _envelope_reset_on_attack; }
void set_envelope_reset_on_attack(bool p_reset) { _envelope_reset_on_attack = p_reset; }
Expand Down
17 changes: 2 additions & 15 deletions src/chip/siopm_channel_params.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,25 +252,20 @@ void SiOPMChannelParams::_bind_methods() {

ClassDB::bind_method(D_METHOD("get_algorithm"), &SiOPMChannelParams::get_algorithm);
ClassDB::bind_method(D_METHOD("set_algorithm", "value"), &SiOPMChannelParams::set_algorithm);

ClassDB::bind_method(D_METHOD("get_feedback"), &SiOPMChannelParams::get_feedback);
ClassDB::bind_method(D_METHOD("set_feedback", "value"), &SiOPMChannelParams::set_feedback);

ClassDB::bind_method(D_METHOD("get_feedback_connection"), &SiOPMChannelParams::get_feedback_connection);
ClassDB::bind_method(D_METHOD("set_feedback_connection", "value"), &SiOPMChannelParams::set_feedback_connection);

ClassDB::bind_method(D_METHOD("get_envelope_frequency_ratio"), &SiOPMChannelParams::get_envelope_frequency_ratio);
ClassDB::bind_method(D_METHOD("set_envelope_frequency_ratio", "value"), &SiOPMChannelParams::set_envelope_frequency_ratio);

ClassDB::bind_method(D_METHOD("get_lfo_wave_shape"), &SiOPMChannelParams::get_lfo_wave_shape);
ClassDB::bind_method(D_METHOD("set_lfo_wave_shape", "value"), &SiOPMChannelParams::set_lfo_wave_shape);

ClassDB::bind_method(D_METHOD("get_lfo_frequency_step"), &SiOPMChannelParams::get_lfo_frequency_step);
ClassDB::bind_method(D_METHOD("set_lfo_frequency_step", "value"), &SiOPMChannelParams::set_lfo_frequency_step);

ClassDB::bind_method(D_METHOD("get_amplitude_modulation_depth"), &SiOPMChannelParams::get_amplitude_modulation_depth);
ClassDB::bind_method(D_METHOD("set_amplitude_modulation_depth", "value"), &SiOPMChannelParams::set_amplitude_modulation_depth);

ClassDB::bind_method(D_METHOD("get_pitch_modulation_depth"), &SiOPMChannelParams::get_pitch_modulation_depth);
ClassDB::bind_method(D_METHOD("set_pitch_modulation_depth", "value"), &SiOPMChannelParams::set_pitch_modulation_depth);

Expand All @@ -282,37 +277,29 @@ void SiOPMChannelParams::_bind_methods() {

ClassDB::bind_method(D_METHOD("get_filter_type"), &SiOPMChannelParams::get_filter_type);
ClassDB::bind_method(D_METHOD("set_filter_type", "value"), &SiOPMChannelParams::set_filter_type);

ClassDB::bind_method(D_METHOD("get_filter_cutoff"), &SiOPMChannelParams::get_filter_cutoff);
ClassDB::bind_method(D_METHOD("set_filter_cutoff", "value"), &SiOPMChannelParams::set_filter_cutoff);

ClassDB::bind_method(D_METHOD("get_filter_resonance"), &SiOPMChannelParams::get_filter_resonance);
ClassDB::bind_method(D_METHOD("set_filter_resonance", "value"), &SiOPMChannelParams::set_filter_resonance);

ClassDB::bind_method(D_METHOD("get_filter_attack_rate"), &SiOPMChannelParams::get_filter_attack_rate);
ClassDB::bind_method(D_METHOD("set_filter_attack_rate", "value"), &SiOPMChannelParams::set_filter_attack_rate);

ClassDB::bind_method(D_METHOD("get_filter_decay_rate1"), &SiOPMChannelParams::get_filter_decay_rate1);
ClassDB::bind_method(D_METHOD("set_filter_decay_rate1", "value"), &SiOPMChannelParams::set_filter_decay_rate1);

ClassDB::bind_method(D_METHOD("get_filter_decay_rate2"), &SiOPMChannelParams::get_filter_decay_rate2);
ClassDB::bind_method(D_METHOD("set_filter_decay_rate2", "value"), &SiOPMChannelParams::set_filter_decay_rate2);

ClassDB::bind_method(D_METHOD("get_filter_release_rate"), &SiOPMChannelParams::get_filter_release_rate);
ClassDB::bind_method(D_METHOD("set_filter_release_rate", "value"), &SiOPMChannelParams::set_filter_release_rate);

ClassDB::bind_method(D_METHOD("get_filter_decay_offset1"), &SiOPMChannelParams::get_filter_decay_offset1);
ClassDB::bind_method(D_METHOD("set_filter_decay_offset1", "value"), &SiOPMChannelParams::set_filter_decay_offset1);

ClassDB::bind_method(D_METHOD("get_filter_decay_offset2"), &SiOPMChannelParams::get_filter_decay_offset2);
ClassDB::bind_method(D_METHOD("set_filter_decay_offset2", "value"), &SiOPMChannelParams::set_filter_decay_offset2);

ClassDB::bind_method(D_METHOD("get_filter_sustain_offset"), &SiOPMChannelParams::get_filter_sustain_offset);
ClassDB::bind_method(D_METHOD("set_filter_sustain_offset", "value"), &SiOPMChannelParams::set_filter_sustain_offset);

ClassDB::bind_method(D_METHOD("get_filter_release_offset"), &SiOPMChannelParams::get_filter_release_offset);
ClassDB::bind_method(D_METHOD("set_filter_release_offset", "value"), &SiOPMChannelParams::set_filter_release_offset);

//

ClassDB::add_property("SiOPMChannelParams", PropertyInfo(Variant::INT, "operator_count"), "set_operator_count", "get_operator_count");
ClassDB::add_property("SiOPMChannelParams", PropertyInfo(Variant::BOOL, "analog_like"), "set_analog_like", "is_analog_like");

Expand Down
Loading

0 comments on commit 2961a4d

Please sign in to comment.