diff --git a/software/o_c_REV/APP_ENVGEN.ino b/software/o_c_REV/APP_ENVGEN.ino index 48504c0b..4bafeb23 100644 --- a/software/o_c_REV/APP_ENVGEN.ino +++ b/software/o_c_REV/APP_ENVGEN.ino @@ -85,6 +85,7 @@ enum CVMapping { CV_MAPPING_SEG2, CV_MAPPING_SEG3, CV_MAPPING_SEG4, + CV_MAPPING_ADR, CV_MAPPING_EUCLIDEAN_LENGTH, CV_MAPPING_EUCLIDEAN_FILL, CV_MAPPING_EUCLIDEAN_OFFSET, @@ -101,9 +102,11 @@ enum EnvelopeType { ENV_TYPE_AR, ENV_TYPE_ADSAR, ENV_TYPE_ADAR, - ENV_TYPE_AD_LOOP, - ENV_TYPE_ADR_LOOP, - ENV_TYPE_ADAR_LOOP, + ENV_TYPE_ADL2, + ENV_TYPE_ADRL3, + ENV_TYPE_ADL2R, + ENV_TYPE_ADAL2R, + ENV_TYPE_ADARL4, ENV_TYPE_LAST, ENV_TYPE_FIRST = ENV_TYPE_AD }; @@ -139,7 +142,7 @@ public: static constexpr int kEuclideanParams = 3; static constexpr int kDelayParams = 1; static constexpr int kAmplitudeParams = 2; // incremented to 2 to cover the MAX_LOOPS parameter - static constexpr size_t kMaxDelayedTriggers = 32; + static constexpr size_t kMaxDelayedTriggers = 24; struct DelayedTrigger { uint32_t delay; @@ -297,14 +300,16 @@ public: switch (get_type()) { case ENV_TYPE_AD: case ENV_TYPE_AR: - case ENV_TYPE_AD_LOOP: + case ENV_TYPE_ADL2: return 2; case ENV_TYPE_ADR: case ENV_TYPE_ADSR: case ENV_TYPE_ADSAR: case ENV_TYPE_ADAR: - case ENV_TYPE_ADR_LOOP: - case ENV_TYPE_ADAR_LOOP: + case ENV_TYPE_ADRL3: + case ENV_TYPE_ADL2R: + case ENV_TYPE_ADARL4: + case ENV_TYPE_ADAL2R: return 4; default: break; } @@ -320,6 +325,11 @@ public: case CV_MAPPING_SEG4: segments[mapping - CV_MAPPING_SEG1] += (cvs[cv_setting - ENV_SETTING_CV1] * 65536) >> 12; break; + case CV_MAPPING_ADR: + segments[CV_MAPPING_SEG1 - CV_MAPPING_SEG1] += (cvs[cv_setting - ENV_SETTING_CV1] * 65536) >> 12; + segments[CV_MAPPING_SEG2 - CV_MAPPING_SEG1] += (cvs[cv_setting - ENV_SETTING_CV1] * 65536) >> 12; + segments[CV_MAPPING_SEG4 - CV_MAPPING_SEG1] += (cvs[cv_setting - ENV_SETTING_CV1] * 65536) >> 12; + break; case CV_MAPPING_EUCLIDEAN_LENGTH: case CV_MAPPING_EUCLIDEAN_FILL: case CV_MAPPING_EUCLIDEAN_OFFSET: @@ -439,15 +449,17 @@ public: EnvelopeType type = get_type(); switch (type) { - case ENV_TYPE_AD: env_.set_ad(s[0], s[1]); break; + case ENV_TYPE_AD: env_.set_ad(s[0], s[1], 0, 0); break; case ENV_TYPE_ADSR: env_.set_adsr(s[0], s[1], s[2]>>1, s[3]); break; - case ENV_TYPE_ADR: env_.set_adr(s[0], s[1], s[2]>>1, s[3]); break; + case ENV_TYPE_ADR: env_.set_adr(s[0], s[1], s[2]>>1, s[3], 0, 0 ); break; case ENV_TYPE_AR: env_.set_ar(s[0], s[1]); break; case ENV_TYPE_ADSAR: env_.set_adsar(s[0], s[1], s[2]>>1, s[3]); break; - case ENV_TYPE_ADAR: env_.set_adar(s[0], s[1], s[2]>>1, s[3]); break; - case ENV_TYPE_AD_LOOP: env_.set_ad_loop(s[0], s[1]); break; - case ENV_TYPE_ADR_LOOP: env_.set_adr_loop(s[0], s[1], s[2]>>1, s[3]); break; - case ENV_TYPE_ADAR_LOOP: env_.set_adar_loop(s[0], s[1], s[2]>>1, s[3]); break; + case ENV_TYPE_ADAR: env_.set_adar(s[0], s[1], s[2]>>1, s[3], 0, 0); break; + case ENV_TYPE_ADL2: env_.set_ad(s[0], s[1], 0, 2); break; + case ENV_TYPE_ADRL3: env_.set_adr(s[0], s[1], s[2]>>1, s[3], 0, 3); break; + case ENV_TYPE_ADL2R: env_.set_adr(s[0], s[1], s[2]>>1, s[3], 0, 2); break; + case ENV_TYPE_ADARL4: env_.set_adar(s[0], s[1], s[2]>>1, s[3], 0, 4); break; + case ENV_TYPE_ADAL2R: env_.set_adar(s[0], s[1], s[2]>>1, s[3], 1, 3); break; // was 2, 4 default: break; } @@ -502,14 +514,16 @@ public: // Process Euclidean pattern reset uint8_t euclidean_reset_trigger_input = get_euclidean_reset_trigger_input(); if (euclidean_reset_trigger_input) { - if (DIGITAL_INPUT_MASK(static_cast(euclidean_reset_trigger_input - 1))) ++euclidean_reset_counter_; - if (euclidean_reset_counter_ % get_euclidean_reset_clock_div() == 0) { - euclidean_counter_ = 0; - euclidean_reset_counter_= 0; + if (triggers & DIGITAL_INPUT_MASK(static_cast(euclidean_reset_trigger_input - 1))) { + ++euclidean_reset_counter_; + if (euclidean_reset_counter_ >= get_euclidean_reset_clock_div()) { + euclidean_counter_ = 0; + euclidean_reset_counter_= 0; + } } } - if (get_euclidean_length() && !EuclideanFilter(euclidean_length, euclidean_fill, euclidean_offset, euclidean_counter_)) { + if (triggered && get_euclidean_length() && !EuclideanFilter(euclidean_length, euclidean_fill, euclidean_offset, euclidean_counter_)) { triggered = false; } @@ -554,7 +568,7 @@ public: if (!is_inverted()) value = OC::DAC::get_zero_offset(dac_channel) + env_.ProcessSingleSample(gate_state); else - value = OC::DAC::MAX_VALUE - (OC::DAC::get_zero_offset(dac_channel) >> 1) - env_.ProcessSingleSample(gate_state); + value = OC::DAC::get_zero_offset(dac_channel) + 32767 - env_.ProcessSingleSample(gate_state); OC::DAC::set(value); } @@ -673,7 +687,7 @@ void EnvelopeGenerator::Init(OC::DigitalInput default_trigger) { } const char* const envelope_types[ENV_TYPE_LAST] = { - "AD", "ADSR", "ADR", "ASR", "ADSAR", "ADAR", "AD loop", "ADR loop", "ADAR loop" + "AD", "ADSR", "ADR", "ASR", "ADSAR", "ADAR", "ADL2", "ADRL3", "ADL2R", "ADAL2R", "ADARL4" }; const char* const segment_names[] = { @@ -685,7 +699,7 @@ const char* const envelope_shapes[peaks::ENV_SHAPE_LAST] = { }; const char* const cv_mapping_names[CV_MAPPING_LAST] = { - "None", "Att", "Dec", "Sus", "Rel", "Eleng", "Efill", "Eoffs", "Delay", "Ampl", "Loops" + "None", "Att", "Dec", "Sus", "Rel", "ADR", "Eleng", "Efill", "Eoffs", "Delay", "Ampl", "Loops" }; const char* const trigger_delay_modes[TRIGGER_DELAY_LAST] = { @@ -729,7 +743,7 @@ SETTINGS_DECLARE(EnvelopeGenerator, ENV_SETTING_LAST) { { 0, 0, 31, "Eucl length", euclidean_lengths, settings::STORAGE_TYPE_U8 }, { 1, 0, 32, "Fill", NULL, settings::STORAGE_TYPE_U8 }, { 0, 0, 32, "Offset", NULL, settings::STORAGE_TYPE_U8 }, - { 0, 0, 5, "Eucl reset", OC::Strings::trigger_input_names_none, settings::STORAGE_TYPE_U4 }, + { 0, 0, 4, "Eucl reset", OC::Strings::trigger_input_names_none, settings::STORAGE_TYPE_U8 }, { 1, 1, 255, "Eucl reset div", NULL, settings::STORAGE_TYPE_U8 }, { CV_MAPPING_NONE, CV_MAPPING_NONE, CV_MAPPING_LAST - 1, "CV1 -> ", cv_mapping_names, settings::STORAGE_TYPE_U4 }, { CV_MAPPING_NONE, CV_MAPPING_NONE, CV_MAPPING_LAST - 1, "CV2 -> ", cv_mapping_names, settings::STORAGE_TYPE_U4 }, diff --git a/software/o_c_REV/APP_LORENZ.ino b/software/o_c_REV/APP_LORENZ.ino index e9005887..f32380cd 100644 --- a/software/o_c_REV/APP_LORENZ.ino +++ b/software/o_c_REV/APP_LORENZ.ino @@ -157,8 +157,8 @@ SETTINGS_DECLARE(LorenzGenerator, LORENZ_SETTING_LAST) { #endif { 63, 4, 127, "Rho/c 1", NULL, settings::STORAGE_TYPE_U8 }, { 63, 4, 127, "Rho/c 2", NULL, settings::STORAGE_TYPE_U8 }, - { 0, 0, 4, "LFreq 1 Rng", lorenz_freq_range_names, settings::STORAGE_TYPE_U4 }, - { 0, 0, 4, "LFreq 2 Rng", lorenz_freq_range_names, settings::STORAGE_TYPE_U4 }, + { 2, 0, 4, "LFreq 1 Rng", lorenz_freq_range_names, settings::STORAGE_TYPE_U4 }, + { 2, 0, 4, "LFreq 2 Rng", lorenz_freq_range_names, settings::STORAGE_TYPE_U4 }, {streams::LORENZ_OUTPUT_X1, streams::LORENZ_OUTPUT_X1, streams::LORENZ_OUTPUT_LAST - 1, "Out A ", lorenz_output_names, settings::STORAGE_TYPE_U8}, {streams::LORENZ_OUTPUT_Y1, streams::LORENZ_OUTPUT_X1, streams::LORENZ_OUTPUT_LAST - 1, "Out B ", lorenz_output_names, settings::STORAGE_TYPE_U8}, {streams::LORENZ_OUTPUT_X2, streams::LORENZ_OUTPUT_X1, streams::LORENZ_OUTPUT_LAST - 1, "Out C ", lorenz_output_names, settings::STORAGE_TYPE_U8}, diff --git a/software/o_c_REV/APP_REFS.ino b/software/o_c_REV/APP_REFS.ino index 8a531ef3..38f852ef 100644 --- a/software/o_c_REV/APP_REFS.ino +++ b/software/o_c_REV/APP_REFS.ino @@ -30,11 +30,48 @@ #include "OC_autotuner.h" #include "src/drivers/FreqMeasure/OC_FreqMeasure.h" -static constexpr double kAaboveMidCtoC0 = 0.03716272234383494188492; +// autotune constants: #define FREQ_MEASURE_TIMEOUT 512 #define ERROR_TIMEOUT (FREQ_MEASURE_TIMEOUT << 0x4) #define MAX_NUM_PASSES 1500 #define CONVERGE_PASSES 5 +// +static constexpr double kAaboveMidCtoC0 = 0.03716272234383494188492; + +// +#ifdef BUCHLA_4U + const float target_multipliers[OCTAVES] = { 1.0f, 2.0f, 4.0f, 8.0f, 16.0f, 32.0f, 64.0f, 128.0f, 256.0f, 512.0f }; +#else + const float target_multipliers[OCTAVES] = { 0.125f, 0.25f, 0.5f, 1.0f, 2.0f, 4.0f, 8.0f, 16.0f, 32.0f, 64.0f }; +#endif + +#ifdef BUCHLA_SUPPORT + const float target_multipliers_1V2[OCTAVES] = { + 0.1767766952966368931843f, + 0.3149802624737182976666f, + 0.5612310241546865086093f, + 1.0f, + 1.7817974362806785482150f, + 3.1748021039363991668836f, + 5.6568542494923805818985f, + 10.0793683991589855253324f, + 17.9593927729499718282113f, + 32.0f + }; + + const float target_multipliers_2V0[OCTAVES] = { + 0.3535533905932737863687f, + 0.5f, + 0.7071067811865475727373f, + 1.0f, + 1.4142135623730951454746f, + 2.0f, + 2.8284271247461902909492f, + 4.0f, + 5.6568542494923805818985f, + 8.0f + }; +#endif const uint8_t NUM_REF_CHANNELS = DAC_CHANNEL_LAST; @@ -66,22 +103,6 @@ enum ChannelPpqn { CHANNEL_PPQN_LAST }; -enum AUTO_CALIBRATION_STEP { - DAC_VOLT_0_ARM, - DAC_VOLT_0_BASELINE, - DAC_VOLT_3m, - DAC_VOLT_2m, - DAC_VOLT_1m, - DAC_VOLT_0, - DAC_VOLT_1, - DAC_VOLT_2, - DAC_VOLT_3, - DAC_VOLT_4, - DAC_VOLT_5, - DAC_VOLT_6, - AUTO_CALIBRATION_STEP_LAST -}; - class ReferenceChannel : public settings::SettingsBase { public: @@ -94,7 +115,7 @@ public: mod_offset_ = 0; last_pitch_ = 0; autotuner_ = false; - autotuner_step_ = DAC_VOLT_0_ARM; + autotuner_step_ = OC::DAC_VOLT_0_ARM; dac_channel_ = dac_channel; auto_DAC_offset_error_ = 0; auto_frequency_ = 0; @@ -181,8 +202,8 @@ public: } void autotuner_run() { - autotuner_step_ = autotuner_ ? DAC_VOLT_0_BASELINE : DAC_VOLT_0_ARM; - if (autotuner_step_ == DAC_VOLT_0_BASELINE) + autotuner_step_ = autotuner_ ? OC::DAC_VOLT_0_BASELINE : OC::DAC_VOLT_0_ARM; + if (autotuner_step_ == OC::DAC_VOLT_0_BASELINE) // we start, so reset data to defaults: OC::DAC::set_default_channel_calibration_data(dac_channel_); } @@ -281,10 +302,10 @@ public: switch(autotuner_step_) { - case DAC_VOLT_0_ARM: + case OC::DAC_VOLT_0_ARM: // do nothing break; - case DAC_VOLT_0_BASELINE: + case OC::DAC_VOLT_0_BASELINE: // 0V baseline / calibration point: in this case, we don't correct. { bool _update = auto_frequency(); @@ -297,101 +318,60 @@ public: history_->Read(history); for (uint8_t i = 0; i < kHistoryDepth; i++) average += history[i]; - // ... and derive target frequencies - float target_frequency = ((auto_frequency_ + average) / (float)(kHistoryDepth + 1)); // 0V - - #ifdef BUCHLA_SUPPORT - switch(OC::DAC::get_voltage_scaling(dac_channel_)) { - - case VOLTAGE_SCALING_1_2V_PER_OCT: // 1.2V/octave - auto_target_frequencies_[0] = target_frequency * 0.1767766952966368931843f; // -3V = 2**(-3.0/1.2) - auto_target_frequencies_[1] = target_frequency * 0.3149802624737182976666f; // -2V = 2**(-2.0/1.2) - auto_target_frequencies_[2] = target_frequency * 0.5612310241546865086093f; // -1V = 2**(-1.0/1.2) - auto_target_frequencies_[3] = target_frequency * 1.0f; // 0V = 2**(0.0/1.2) - auto_target_frequencies_[4] = target_frequency * 1.7817974362806785482150f; // +1V = 2**(1.0/1.2) - auto_target_frequencies_[5] = target_frequency * 3.1748021039363991668836f; // +2V = 2**(2.0/1.2) - auto_target_frequencies_[6] = target_frequency * 5.6568542494923805818985f; // +3V = 2**(3.0/1.2) - auto_target_frequencies_[7] = target_frequency * 10.0793683991589855253324f; // +4V = 2**(4.0/1.2) - auto_target_frequencies_[8] = target_frequency * 17.9593927729499718282113f; // +5V = 2**(5.0/1.2) - auto_target_frequencies_[9] = target_frequency * 32.0f; // +6V = 2**(6.0/1.2) - break; - case VOLTAGE_SCALING_2V_PER_OCT: // 2V/octave - auto_target_frequencies_[0] = target_frequency * 0.3535533905932737863687f; // -3V - 2**(-3.0/2.0) - auto_target_frequencies_[1] = target_frequency * 0.5f; // -2V = 2**(-2.0/2.0) - auto_target_frequencies_[2] = target_frequency * 0.7071067811865475727373f; // -1V = 2**(-1.0/2.0) - auto_target_frequencies_[3] = target_frequency * 1.0f; // 0V = 2**(0.0/2.0) - auto_target_frequencies_[4] = target_frequency * 1.4142135623730951454746f; // +1V = 2**(1.0/2.0) - auto_target_frequencies_[5] = target_frequency * 2.0f; // +2V = 2**(2.0/2.0) - auto_target_frequencies_[6] = target_frequency * 2.8284271247461902909492f; // +3V = 2**(3.0/2.0) - auto_target_frequencies_[7] = target_frequency * 4.0f; // +4V = 2**(4.0/2.0) - auto_target_frequencies_[8] = target_frequency * 5.6568542494923805818985f; // +5V = 2**(5.0/2.0) - auto_target_frequencies_[9] = target_frequency * 8.0f; // +6V = 2**(6.0/2.0) - break; - case VOLTAGE_SCALING_1V_PER_OCT: // 1V/octave - default: - auto_target_frequencies_[0] = target_frequency * 0.125f; // -3V - auto_target_frequencies_[1] = target_frequency * 0.25f; // -2V - auto_target_frequencies_[2] = target_frequency * 0.5f; // -1V - auto_target_frequencies_[3] = target_frequency * 1.0f; // 0V - auto_target_frequencies_[4] = target_frequency * 2.0f; // +1V - auto_target_frequencies_[5] = target_frequency * 4.0f; // +2V - auto_target_frequencies_[6] = target_frequency * 8.0f; // +3V - auto_target_frequencies_[7] = target_frequency * 16.0f; // +4V - auto_target_frequencies_[8] = target_frequency * 32.0f; // +5V - auto_target_frequencies_[9] = target_frequency * 64.0f; // +6V - break; - } - #elif defined(BUCHLA_4U) - /* can't use pow (busts the available memory at this point), so we unroll ... */ - auto_target_frequencies_[0] = target_frequency * 1.0f; // 0V - auto_target_frequencies_[1] = target_frequency * 2.0f; // +1.2V - auto_target_frequencies_[2] = target_frequency * 4.0f; // +2.4V - auto_target_frequencies_[3] = target_frequency * 8.0f; // +3.6V - auto_target_frequencies_[4] = target_frequency * 16.0f; // +4.8V - auto_target_frequencies_[5] = target_frequency * 32.0f; // +6.0V - auto_target_frequencies_[6] = target_frequency * 64.0f; // +7.2V - auto_target_frequencies_[7] = target_frequency * 128.0f; // +8.4V - auto_target_frequencies_[8] = target_frequency * 256.0f; // +9.6V - auto_target_frequencies_[9] = target_frequency * 512.0f; // +10.8V - #else - /* can't use pow (busts the available memory at this point), so we unroll ... */ - auto_target_frequencies_[0] = target_frequency * 0.125f; // -3V - auto_target_frequencies_[1] = target_frequency * 0.25f; // -2V - auto_target_frequencies_[2] = target_frequency * 0.5f; // -1V - auto_target_frequencies_[3] = target_frequency * 1.0f; // 0V - auto_target_frequencies_[4] = target_frequency * 2.0f; // +1V - auto_target_frequencies_[5] = target_frequency * 4.0f; // +2V - auto_target_frequencies_[6] = target_frequency * 8.0f; // +3V - auto_target_frequencies_[7] = target_frequency * 16.0f; // +4V - auto_target_frequencies_[8] = target_frequency * 32.0f; // +5V - auto_target_frequencies_[9] = target_frequency * 64.0f; // +6V - #endif - + // ... and derive target frequency at 0V + auto_frequency_ = (uint32_t) (0.5f + ((auto_frequency_ + average) / (float)(kHistoryDepth + 1))); // 0V // reset step, and proceed: auto_reset_step(); - autotuner_step_++; + autotuner_step_++; } else if (_update) auto_num_passes_++; } break; - case DAC_VOLT_3m: - case DAC_VOLT_2m: - case DAC_VOLT_1m: - case DAC_VOLT_0: - case DAC_VOLT_1: - case DAC_VOLT_2: - case DAC_VOLT_3: - case DAC_VOLT_4: - case DAC_VOLT_5: - case DAC_VOLT_6: + case OC::DAC_VOLT_TARGET_FREQUENCIES: + { + #ifdef BUCHLA_SUPPORT + + switch(OC::DAC::get_voltage_scaling(dac_channel_)) { + + case VOLTAGE_SCALING_1_2V_PER_OCT: // 1.2V/octave + auto_target_frequencies_[octaves_cnt_] = auto_frequency_ * target_multipliers_1V2[octaves_cnt_]; + break; + case VOLTAGE_SCALING_2V_PER_OCT: // 2V/octave + auto_target_frequencies_[octaves_cnt_] = auto_frequency_ * target_multipliers_2V0[octaves_cnt_]; + break; + default: // 1V/octave + auto_target_frequencies_[octaves_cnt_] = auto_frequency_ * target_multipliers[octaves_cnt_]; + break; + } + #else + auto_target_frequencies_[octaves_cnt_] = auto_frequency_ * target_multipliers[octaves_cnt_]; + #endif + octaves_cnt_++; + // go to next step, if done: + if (octaves_cnt_ >= OCTAVES) { + octaves_cnt_ = 0x0; + autotuner_step_++; + } + } + break; + case OC::DAC_VOLT_3m: + case OC::DAC_VOLT_2m: + case OC::DAC_VOLT_1m: + case OC::DAC_VOLT_0: + case OC::DAC_VOLT_1: + case OC::DAC_VOLT_2: + case OC::DAC_VOLT_3: + case OC::DAC_VOLT_4: + case OC::DAC_VOLT_5: + case OC::DAC_VOLT_6: { bool _update = auto_frequency(); if (_update && (auto_num_passes_ > MAX_NUM_PASSES)) { /* target frequency reached */ - if ((autotuner_step_ > DAC_VOLT_2m) && (auto_last_frequency_ * 1.25f > auto_frequency_)) + if ((autotuner_step_ > OC::DAC_VOLT_2m) && (auto_last_frequency_ * 1.25f > auto_frequency_)) auto_error_ = true; // throw error, if things don't seem to double ... // average: float history[kHistoryDepth]; @@ -402,7 +382,7 @@ public: // store last frequency: auto_last_frequency_ = ((auto_frequency_ + average) / (float)(kHistoryDepth + 1)); // and DAC correction value: - auto_calibration_data_[autotuner_step_ - DAC_VOLT_3m] = auto_DAC_offset_error_; + auto_calibration_data_[autotuner_step_ - OC::DAC_VOLT_3m] = auto_DAC_offset_error_; // and reset step: auto_reset_step(); autotuner_step_++; @@ -413,7 +393,7 @@ public: // count passes auto_num_passes_++; // and correct frequency - if (auto_target_frequencies_[autotuner_step_ - DAC_VOLT_3m] > auto_frequency_) { + if (auto_target_frequencies_[autotuner_step_ - OC::DAC_VOLT_3m] > auto_frequency_) { // update correction factor? if (!correction_direction_) F_correction_factor_ = (F_correction_factor_ >> 1) | 1u; @@ -424,7 +404,7 @@ public: if (F_correction_factor_ == 0x1) correction_cnt_positive_++; } - else if (auto_target_frequencies_[autotuner_step_ - DAC_VOLT_3m] < auto_frequency_) { + else if (auto_target_frequencies_[autotuner_step_ - OC::DAC_VOLT_3m] < auto_frequency_) { // update correction factor? if (correction_direction_) F_correction_factor_ = (F_correction_factor_ >> 1) | 1u; @@ -442,7 +422,7 @@ public: } } break; - case AUTO_CALIBRATION_STEP_LAST: + case OC::AUTO_CALIBRATION_STEP_LAST: // step through the octaves: if (ticks_since_last_freq_ > 2000) { int32_t new_auto_calibration_point = OC::calibration_data.dac.calibrated_octaves[dac_channel_][octaves_cnt_] + auto_calibration_data_[octaves_cnt_]; @@ -467,7 +447,7 @@ public: } break; default: - autotuner_step_ = DAC_VOLT_0_ARM; + autotuner_step_ = OC::DAC_VOLT_0_ARM; autotuner_ = 0x0; break; } @@ -477,24 +457,25 @@ public: switch(autotuner_step_) { - case DAC_VOLT_0_ARM: + case OC::DAC_VOLT_0_ARM: { F_correction_factor_ = 0x1; // don't go so fast auto_frequency(); OC::DAC::set(dac_channel_, OC::calibration_data.dac.calibrated_octaves[dac_channel_][OC::DAC::kOctaveZero]); } break; - case DAC_VOLT_0_BASELINE: + case OC::DAC_VOLT_0_BASELINE: // set DAC to 0.000V, default calibration: OC::DAC::set(dac_channel_, OC::calibration_data.dac.calibrated_octaves[dac_channel_][OC::DAC::kOctaveZero]); break; - case AUTO_CALIBRATION_STEP_LAST: + case OC::DAC_VOLT_TARGET_FREQUENCIES: + case OC::AUTO_CALIBRATION_STEP_LAST: // do nothing break; default: // set DAC to calibration point + error { - int32_t _default_calibration_point = OC::calibration_data.dac.calibrated_octaves[dac_channel_][autotuner_step_ - DAC_VOLT_3m]; // substract first two steps + int32_t _default_calibration_point = OC::calibration_data.dac.calibrated_octaves[dac_channel_][autotuner_step_ - OC::DAC_VOLT_3m]; OC::DAC::set(dac_channel_, _default_calibration_point + auto_DAC_offset_error_); } break; @@ -639,10 +620,6 @@ public: freq_sum_ = 0; freq_count_ = 0; frequency_ = 0; - freq_decicents_deviation_ = 0; - freq_octave_ = 0; - freq_note_ = 0; - freq_decicents_residual_ = 0; autotuner.Init(); } @@ -669,10 +646,6 @@ public: freq_sum_ = 0; freq_count_ = 0; milliseconds_since_last_freq_ = 0; - freq_decicents_deviation_ = round(12000.0 * log2f(frequency_ / get_C0_freq())) + 500; - freq_octave_ = -2 + ((freq_decicents_deviation_)/ 12000) ; - freq_note_ = (freq_decicents_deviation_ - ((freq_octave_ + 2) * 12000)) / 1000; - freq_decicents_residual_ = ((freq_decicents_deviation_ - ((freq_octave_ - 1) * 12000)) % 1000) - 500; } } else if (milliseconds_since_last_freq_ > 100000) { frequency_ = 0.0f; @@ -746,31 +719,11 @@ public: return(static_cast(channels_[DAC_CHANNEL_D].get_a_above_mid_c() * kAaboveMidCtoC0)); } - float get_cents_deviation( ) { - return(static_cast(freq_decicents_deviation_) / 10.0) ; - } - - float get_cents_residual( ) { - return(static_cast(freq_decicents_residual_) / 10.0) ; - } - - int8_t get_octave( ) { - return(freq_octave_) ; - } - - int8_t get_note( ) { - return(freq_note_) ; - } - private: double freq_sum_; uint32_t freq_count_; float frequency_ ; elapsedMillis milliseconds_since_last_freq_; - int32_t freq_decicents_deviation_; - int8_t freq_octave_ ; - int8_t freq_note_; - int32_t freq_decicents_residual_; }; ReferencesApp references_app; @@ -954,13 +907,23 @@ void REFS_screensaver() { references_app.channels_[2].RenderScreensaver(64, 2); references_app.channels_[3].RenderScreensaver(96, 3); graphics.setPrintPos(2, 44); - if (references_app.get_frequency() > 0.0) { - graphics.printf("TR4 %7.3f Hz", references_app.get_frequency()) ; + + float frequency_ = references_app.get_frequency() ; + float c0_freq_ = references_app.get_C0_freq() ; + float bpm_ = (60.0 * frequency_)/references_app.get_ppqn() ; + + int32_t freq_decicents_deviation_ = round(12000.0 * log2f(frequency_ / c0_freq_)) + 500; + int8_t freq_octave_ = -2 + ((freq_decicents_deviation_)/ 12000) ; + int8_t freq_note_ = (freq_decicents_deviation_ - ((freq_octave_ + 2) * 12000)) / 1000; + int32_t freq_decicents_residual_ = ((freq_decicents_deviation_ - ((freq_octave_ - 1) * 12000)) % 1000) - 500; + + if (frequency_ > 0.0) { + graphics.printf("TR4 %7.3f Hz", frequency_) ; graphics.setPrintPos(2, 56); if (references_app.get_notes_or_bpm()) { - graphics.printf("%7.2f bpm %2.0fppqn", references_app.get_bpm(), references_app.get_ppqn()); - } else if(references_app.get_frequency() >= references_app.get_C0_freq()) { - graphics.printf("%+i %s %+7.1fc", references_app.get_octave(), OC::Strings::note_names[references_app.get_note()], references_app.get_cents_residual()) ; + graphics.printf("%7.2f bpm %2.0fppqn", bpm_, references_app.get_ppqn()); + } else if(frequency_ >= c0_freq_) { + graphics.printf("%+i %s %+7.1fc", freq_octave_, OC::Strings::note_names[freq_note_], freq_decicents_residual_ / 10.0) ; } } else { graphics.print("TR4 no input") ; diff --git a/software/o_c_REV/OC_autotuner.h b/software/o_c_REV/OC_autotuner.h index 0ccd9775..543817a4 100644 --- a/software/o_c_REV/OC_autotuner.h +++ b/software/o_c_REV/OC_autotuner.h @@ -6,11 +6,11 @@ #ifdef BUCHLA_4U const char* const AT_steps[] = { - "0.0V", "0.0V", "0.0V", "1.2V", "2.4V", "3.6V", "4.8V", "6.0V", "7.2V", "8.4V", "9.6V", "10.8V", " " + "0.0V", "1.2V", "2.4V", "3.6V", "4.8V", "6.0V", "7.2V", "8.4V", "9.6V", "10.8V", " " }; #else const char* const AT_steps[] = { - " 0V", " 0V", "-3V", "-2V", "-1V", " 0V", "+1V", "+2V", "+3V", "+4V", "+5V", "+6V", " " + "-3V", "-2V", "-1V", " 0V", "+1V", "+2V", "+3V", "+4V", "+5V", "+6V", " " }; #endif @@ -32,6 +32,23 @@ enum AT_STATUS { AT_LAST, }; +enum AUTO_CALIBRATION_STEP { + DAC_VOLT_0_ARM, + DAC_VOLT_0_BASELINE, + DAC_VOLT_TARGET_FREQUENCIES, + DAC_VOLT_3m, + DAC_VOLT_2m, + DAC_VOLT_1m, + DAC_VOLT_0, + DAC_VOLT_1, + DAC_VOLT_2, + DAC_VOLT_3, + DAC_VOLT_4, + DAC_VOLT_5, + DAC_VOLT_6, + AUTO_CALIBRATION_STEP_LAST +}; + template class Autotuner { @@ -145,10 +162,10 @@ class Autotuner { for (int i = 0; i <= _octave; i++, x += 6) graphics.drawBitmap8(x + 18, y + 4, 4, OC::bitmap_indicator_4x8); } - else if (owner_->auto_tune_step() == 0x1) // this goes too quick, so ... + else if (owner_->auto_tune_step() == DAC_VOLT_0_BASELINE || owner_->auto_tune_step() == DAC_VOLT_TARGET_FREQUENCIES) // this goes too quick, so ... graphics.print(" 0.0V baseline"); else { - graphics.print(AT_steps[owner_->auto_tune_step()]); + graphics.print(AT_steps[owner_->auto_tune_step() - DAC_VOLT_3m]); if (!owner_->_ready()) graphics.print(" "); else diff --git a/software/o_c_REV/OC_version.h b/software/o_c_REV/OC_version.h index 36952602..06e19b0d 100644 --- a/software/o_c_REV/OC_version.h +++ b/software/o_c_REV/OC_version.h @@ -3,5 +3,5 @@ // // GENERATED FILE, DO NOT EDIT // -#define OC_VERSION "v1.3.0" +#define OC_VERSION "v1.3.1" #endif diff --git a/software/o_c_REV/frames_poly_lfo.cpp b/software/o_c_REV/frames_poly_lfo.cpp index 0c793738..e21ced01 100644 --- a/software/o_c_REV/frames_poly_lfo.cpp +++ b/software/o_c_REV/frames_poly_lfo.cpp @@ -163,27 +163,26 @@ void PolyLfo::Render(int32_t frequency, bool reset_phase, bool tempo_sync) { if (FreqDivs[i] == POLYLFO_FREQ_MULT_NONE) { phase_[i] += phase_increment_ch1_; } else { - phase_[i] += multiply_u32xu32_rshift24(phase_increment_ch1_, PolyLfoFreqMultNumerators[FreqDivs[i]]) ; + phase_[i] += multiply_u32xu32_rshift24(phase_increment_ch1_, PolyLfoFreqMultNumerators[FreqDivs[i]]) ; } } // Advance phasors. - if (!(freq_div_b_ || freq_div_c_ || freq_div_c_ || sync_)) { + if (freq_div_b_ == POLYLFO_FREQ_MULT_NONE && freq_div_c_ && POLYLFO_FREQ_MULT_NONE && freq_div_c_ == POLYLFO_FREQ_MULT_NONE && !sync_) { // original Frames behaviour if (spread_ >= 0) { - phase_[0] += FrequencyToPhaseIncrement(frequency, freq_range_); uint32_t phase_difference = static_cast(spread_) << 15; phase_[1] = phase_[0] + phase_difference; phase_[2] = phase_[1] + phase_difference; phase_[3] = phase_[2] + phase_difference; } else { - for (uint8_t i = 0; i < kNumChannels; ++i) { + for (uint8_t i = 1; i < kNumChannels; ++i) { phase_[i] += FrequencyToPhaseIncrement(frequency, freq_range_); frequency -= 5040 * spread_ >> 15; } } } else { - // if frequency division is in use + // if frequency division or tap-tempo is in use if (spread_ > 10) { uint32_t phase_difference = static_cast(spread_ - 10) << 2; phase_[1] = phase_[1] + phase_difference; diff --git a/software/o_c_REV/peaks_multistage_envelope.h b/software/o_c_REV/peaks_multistage_envelope.h index cbb42f0e..26b9e02e 100644 --- a/software/o_c_REV/peaks_multistage_envelope.h +++ b/software/o_c_REV/peaks_multistage_envelope.h @@ -84,7 +84,7 @@ class MultistageEnvelope { void Configure(uint16_t* parameter, ControlMode control_mode) { if (control_mode == CONTROL_MODE_HALF) { - set_ad(parameter[0], parameter[1]); + set_ad(parameter[0], parameter[1], 0, 0); } else { set_adsr(parameter[0], parameter[1], parameter[2] >> 1, parameter[3]); } @@ -144,7 +144,7 @@ class MultistageEnvelope { loop_start_ = loop_end_ = 0; } - inline void set_ad(uint16_t attack, uint16_t decay) { + inline void set_ad(uint16_t attack, uint16_t decay, uint16_t loop_start, uint16_t loop_end) { num_segments_ = 2; sustain_point_ = 0; sustain_index_ = 0; @@ -162,14 +162,17 @@ class MultistageEnvelope { time_multiplier_[0] = attack_multiplier_; time_multiplier_[1] = decay_multiplier_; - loop_start_ = loop_end_ = 0; + loop_start_ = loop_start; + loop_end_ = loop_end; } - + inline void set_adr( uint16_t attack, uint16_t decay, uint16_t sustain, - uint16_t release) { + uint16_t release, + uint16_t loop_start, + uint16_t loop_end) { num_segments_ = 3; sustain_point_ = 0; sustain_index_ = 2; @@ -191,9 +194,10 @@ class MultistageEnvelope { time_multiplier_[1] = decay_multiplier_; time_multiplier_[2] = release_multiplier_; - loop_start_ = loop_end_ = 0; + loop_start_ = loop_start ; + loop_end_ = loop_end ; } - + inline void set_ar(uint16_t attack, uint16_t release) { num_segments_ = 2; sustain_point_ = 1; @@ -252,7 +256,9 @@ class MultistageEnvelope { uint16_t attack, uint16_t decay, uint16_t sustain, - uint16_t release) { + uint16_t release, + uint16_t loop_start, + uint16_t loop_end) { num_segments_ = 4; sustain_point_ = 0; sustain_index_ = 2; @@ -278,95 +284,10 @@ class MultistageEnvelope { time_multiplier_[2] = attack_multiplier_; time_multiplier_[3] = release_multiplier_; - loop_start_ = loop_end_ = 0; - } - - inline void set_ad_loop(uint16_t attack, uint16_t decay) { - num_segments_ = 2; - sustain_point_ = 0; - sustain_index_ = 0; - - level_[0] = 0; - level_[1] = 32767; - level_[2] = 0; - - time_[0] = attack; - time_[1] = decay; - - shape_[0] = attack_shape_; - shape_[1] = decay_shape_; - - time_multiplier_[0] = attack_multiplier_; - time_multiplier_[1] = decay_multiplier_; - - loop_start_ = 0; - loop_end_ = 2; + loop_start_ = loop_start; + loop_end_ = loop_end; } - - inline void set_adr_loop( - uint16_t attack, - uint16_t decay, - uint16_t sustain, - uint16_t release) { - num_segments_ = 3; - sustain_point_ = 0; - sustain_index_ = 2; - - level_[0] = 0; - level_[1] = 32767; - level_[2] = sustain; - level_[3] = 0; - - time_[0] = attack; - time_[1] = decay; - time_[2] = release; - - shape_[0] = attack_shape_; - shape_[1] = decay_shape_; - shape_[2] = release_shape_; - - time_multiplier_[0] = attack_multiplier_; - time_multiplier_[1] = decay_multiplier_; - time_multiplier_[2] = release_multiplier_; - - loop_start_ = 0; - loop_end_ = 3; - } - - inline void set_adar_loop( - uint16_t attack, - uint16_t decay, - uint16_t sustain, - uint16_t release) { - num_segments_ = 4; - sustain_point_ = 0; - sustain_index_ = 2; - - level_[0] = 0; - level_[1] = 32767; - level_[2] = sustain; - level_[3] = 32767; - level_[4] = 0; - - time_[0] = attack; - time_[1] = decay; - time_[2] = attack; - time_[3] = release; - - shape_[0] = attack_shape_; - shape_[1] = decay_shape_; - shape_[2] = attack_shape_; - shape_[3] = release_shape_; - - time_multiplier_[0] = attack_multiplier_; - time_multiplier_[1] = decay_multiplier_; - time_multiplier_[2] = attack_multiplier_; - time_multiplier_[3] = release_multiplier_; - - loop_start_ = 0; - loop_end_ = 4; - } - + inline void set_attack_reset_behaviour(EnvResetBehaviour reset_behaviour) { attack_reset_behaviour_ = reset_behaviour; }