Skip to content

Commit

Permalink
Merge pull request #73 from mxmxmx/1.3.4dev
Browse files Browse the repository at this point in the history
[OC] 1.3.4
  • Loading branch information
mxmxmx authored Mar 7, 2018
2 parents c404ac1 + 4006f99 commit 7c5c45f
Show file tree
Hide file tree
Showing 16 changed files with 555 additions and 79 deletions.
2 changes: 1 addition & 1 deletion software/o_c_REV/APP_A_SEQ.ino
Original file line number Diff line number Diff line change
Expand Up @@ -1513,7 +1513,7 @@ public:
break;
case PENDULUM1:
case BROWNIAN:
if (BROWNIAN == get_direction()) {
if (BROWNIAN == _direction) {
// Compare Brownian probability and reverse direction if needed
int16_t brown_prb = get_brownian_probability();

Expand Down
14 changes: 10 additions & 4 deletions software/o_c_REV/APP_DQ.ino
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@
#include "OC_scale_edit.h"
#include "OC_strings.h"

#ifdef BUCHLA_4U
#define DQ_OFFSET_X 22
#else
#define DQ_OFFSET_X 47
#endif

const uint8_t NUMCHANNELS = 2;
const uint8_t NUM_SCALE_SLOTS = 4;

Expand Down Expand Up @@ -1482,15 +1488,15 @@ void DQ_QuantizerChannel::RenderScreensaver(weegfx::coord_t start_x) const {
menu::DrawMask<true, 16, 8, 1>(start_x + 58, 1, get_shift_register(), get_turing_display_length());
break;
default: {
graphics.setPixel(start_x + 47 - 16, 4);
graphics.setPixel(start_x + DQ_OFFSET_X - 16, 4);
int32_t cv = OC::ADC::value(static_cast<ADC_CHANNEL>(source));
cv = (cv * 20 + 2047) >> 11;
if (cv < 0)
graphics.drawRect(start_x + 47 - 16 + cv, 6, -cv, 2);
graphics.drawRect(start_x + DQ_OFFSET_X - 16 + cv, 6, -cv, 2);
else if (cv > 0)
graphics.drawRect(start_x + 47 - 16, 6, cv, 2);
graphics.drawRect(start_x + DQ_OFFSET_X - 16, 6, cv, 2);
else
graphics.drawRect(start_x + 47 - 16, 6, 1, 2);
graphics.drawRect(start_x + DQ_OFFSET_X - 16, 6, 1, 2);
}
break;
}
Expand Down
98 changes: 50 additions & 48 deletions software/o_c_REV/APP_ENVGEN.ino
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// Copyright (c) 2016 Patrick Dowling, Tim Churches
//
// Initial app implementation: Patrick Dowling ([email protected])
// Modifications by: Tim Churches ([email protected])
Expand Down Expand Up @@ -316,33 +315,34 @@ public:
return 0;
}

inline void apply_cv_mapping(EnvelopeSettings cv_setting, const int32_t cvs[ADC_CHANNEL_LAST], int32_t segments[kMaxSegments + kEuclideanParams + kDelayParams + kAmplitudeParams]) {
inline void apply_cv_mapping(EnvelopeSettings cv_setting, const int32_t cvs[ADC_CHANNEL_LAST], int32_t segments[CV_MAPPING_LAST]) {
// segments is indexed directly with CVMapping enum values
int mapping = values_[cv_setting];
switch (mapping) {
case CV_MAPPING_SEG1:
case CV_MAPPING_SEG2:
case CV_MAPPING_SEG3:
case CV_MAPPING_SEG4:
segments[mapping - CV_MAPPING_SEG1] += (cvs[cv_setting - ENV_SETTING_CV1] * 65536) >> 12;
segments[mapping] += (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;
segments[CV_MAPPING_SEG1] += (cvs[cv_setting - ENV_SETTING_CV1] * 65536) >> 12;
segments[CV_MAPPING_SEG2] += (cvs[cv_setting - ENV_SETTING_CV1] * 65536) >> 12;
segments[CV_MAPPING_SEG4] += (cvs[cv_setting - ENV_SETTING_CV1] * 65536) >> 12;
break;
case CV_MAPPING_EUCLIDEAN_LENGTH:
case CV_MAPPING_EUCLIDEAN_FILL:
case CV_MAPPING_EUCLIDEAN_OFFSET:
segments[mapping - CV_MAPPING_SEG1] += cvs[cv_setting - ENV_SETTING_CV1] >> 6;
segments[mapping] += cvs[cv_setting - ENV_SETTING_CV1] >> 6;
break;
case CV_MAPPING_DELAY_MSEC:
segments[mapping - CV_MAPPING_SEG1] += cvs[cv_setting - ENV_SETTING_CV1] >> 2;
segments[mapping] += cvs[cv_setting - ENV_SETTING_CV1] >> 2;
break;
case CV_MAPPING_AMPLITUDE:
segments[mapping - CV_MAPPING_SEG1] += cvs[cv_setting - ENV_SETTING_CV1] << 5 ;
segments[mapping] += cvs[cv_setting - ENV_SETTING_CV1] << 5 ;
break;
case CV_MAPPING_MAX_LOOPS:
segments[mapping - CV_MAPPING_SEG1] += cvs[cv_setting - ENV_SETTING_CV1] << 2 ;
segments[mapping] += cvs[cv_setting - ENV_SETTING_CV1] << 2 ;
break;
default:
break;
Expand Down Expand Up @@ -419,53 +419,55 @@ public:

template <DAC_CHANNEL dac_channel>
void Update(uint32_t triggers, uint32_t internal_trigger_mask, const int32_t cvs[ADC_CHANNEL_LAST]) {
int32_t s[kMaxSegments + kEuclideanParams + kDelayParams + kAmplitudeParams];
s[0] = SCALE8_16(static_cast<int32_t>(get_segment_value(0)));
s[1] = SCALE8_16(static_cast<int32_t>(get_segment_value(1)));
s[2] = SCALE8_16(static_cast<int32_t>(get_segment_value(2)));
s[3] = SCALE8_16(static_cast<int32_t>(get_segment_value(3)));
s[4] = static_cast<int32_t>(get_euclidean_length());
s[5] = static_cast<int32_t>(get_euclidean_fill());
s[6] = static_cast<int32_t>(get_euclidean_offset());
s[7] = get_trigger_delay_ms();
s[8] = get_amplitude();
s[9] = get_max_loops();
int32_t s[CV_MAPPING_LAST];
s[CV_MAPPING_NONE] = 0; // unused, but needs a placeholder to align with enum CVMapping
s[CV_MAPPING_SEG1] = SCALE8_16(static_cast<int32_t>(get_segment_value(0)));
s[CV_MAPPING_SEG2] = SCALE8_16(static_cast<int32_t>(get_segment_value(1)));
s[CV_MAPPING_SEG3] = SCALE8_16(static_cast<int32_t>(get_segment_value(2)));
s[CV_MAPPING_SEG4] = SCALE8_16(static_cast<int32_t>(get_segment_value(3)));
s[CV_MAPPING_ADR] = 0; // unused, but needs a placeholder to align with enum CVMapping
s[CV_MAPPING_EUCLIDEAN_LENGTH] = static_cast<int32_t>(get_euclidean_length());
s[CV_MAPPING_EUCLIDEAN_FILL] = static_cast<int32_t>(get_euclidean_fill());
s[CV_MAPPING_EUCLIDEAN_OFFSET] = static_cast<int32_t>(get_euclidean_offset());
s[CV_MAPPING_DELAY_MSEC] = get_trigger_delay_ms();
s[CV_MAPPING_AMPLITUDE] = get_amplitude();
s[CV_MAPPING_MAX_LOOPS] = get_max_loops();

apply_cv_mapping(ENV_SETTING_CV1, cvs, s);
apply_cv_mapping(ENV_SETTING_CV2, cvs, s);
apply_cv_mapping(ENV_SETTING_CV3, cvs, s);
apply_cv_mapping(ENV_SETTING_CV4, cvs, s);

s[0] = USAT16(s[0]);
s[1] = USAT16(s[1]);
s[2] = USAT16(s[2]);
s[3] = USAT16(s[3]);
CONSTRAIN(s[4], 0, 31);
CONSTRAIN(s[5], 0, 32);
CONSTRAIN(s[6], 0, 32);
CONSTRAIN(s[7], 0, 65535);
CONSTRAIN(s[8], 0, 65535);
CONSTRAIN(s[9], 0, 65535);
s[CV_MAPPING_SEG1] = USAT16(s[CV_MAPPING_SEG1]);
s[CV_MAPPING_SEG2] = USAT16(s[CV_MAPPING_SEG2]);
s[CV_MAPPING_SEG3] = USAT16(s[CV_MAPPING_SEG3]);
s[CV_MAPPING_SEG4] = USAT16(s[CV_MAPPING_SEG4]);
CONSTRAIN(s[CV_MAPPING_EUCLIDEAN_LENGTH], 0, 31);
CONSTRAIN(s[CV_MAPPING_EUCLIDEAN_FILL], 0, 32);
CONSTRAIN(s[CV_MAPPING_EUCLIDEAN_OFFSET], 0, 32);
CONSTRAIN(s[CV_MAPPING_DELAY_MSEC], 0, 65535);
CONSTRAIN(s[CV_MAPPING_AMPLITUDE], 0, 65535);
CONSTRAIN(s[CV_MAPPING_MAX_LOOPS], 0, 65535);

EnvelopeType type = get_type();
switch (type) {
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], 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], 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
case ENV_TYPE_AD: env_.set_ad(s[CV_MAPPING_SEG1], s[CV_MAPPING_SEG2], 0, 0); break;
case ENV_TYPE_ADSR: env_.set_adsr(s[CV_MAPPING_SEG1], s[CV_MAPPING_SEG2], s[CV_MAPPING_SEG3]>>1, s[CV_MAPPING_SEG4]); break;
case ENV_TYPE_ADR: env_.set_adr(s[CV_MAPPING_SEG1], s[CV_MAPPING_SEG2], s[CV_MAPPING_SEG3]>>1, s[CV_MAPPING_SEG4], 0, 0 ); break;
case ENV_TYPE_AR: env_.set_ar(s[CV_MAPPING_SEG1], s[CV_MAPPING_SEG2]); break;
case ENV_TYPE_ADSAR: env_.set_adsar(s[CV_MAPPING_SEG1], s[CV_MAPPING_SEG2], s[CV_MAPPING_SEG3]>>1, s[CV_MAPPING_SEG4]); break;
case ENV_TYPE_ADAR: env_.set_adar(s[CV_MAPPING_SEG1], s[CV_MAPPING_SEG2], s[CV_MAPPING_SEG3]>>1, s[CV_MAPPING_SEG4], 0, 0); break;
case ENV_TYPE_ADL2: env_.set_ad(s[CV_MAPPING_SEG1], s[CV_MAPPING_SEG2], 0, 2); break;
case ENV_TYPE_ADRL3: env_.set_adr(s[CV_MAPPING_SEG1], s[CV_MAPPING_SEG2], s[CV_MAPPING_SEG3]>>1, s[CV_MAPPING_SEG4], 0, 3); break;
case ENV_TYPE_ADL2R: env_.set_adr(s[CV_MAPPING_SEG1], s[CV_MAPPING_SEG2], s[CV_MAPPING_SEG3]>>1, s[CV_MAPPING_SEG4], 0, 2); break;
case ENV_TYPE_ADARL4: env_.set_adar(s[CV_MAPPING_SEG1], s[CV_MAPPING_SEG2], s[CV_MAPPING_SEG3]>>1, s[CV_MAPPING_SEG4], 0, 4); break;
case ENV_TYPE_ADAL2R: env_.set_adar(s[CV_MAPPING_SEG1], s[CV_MAPPING_SEG2], s[CV_MAPPING_SEG3]>>1, s[CV_MAPPING_SEG4], 1, 3); break; // was 2, 4
default:
break;
}

// set the amplitude
env_.set_amplitude(s[8], is_amplitude_sampled()) ;
env_.set_amplitude(s[CV_MAPPING_AMPLITUDE], is_amplitude_sampled()) ;

if (type != last_type_) {
last_type_ = type;
Expand All @@ -488,7 +490,7 @@ public:
env_.set_release_time_multiplier(get_release_time_multiplier());

// set the looping envelope maximum number of loops
env_.set_max_loops(s[9]);
env_.set_max_loops(s[CV_MAPPING_MAX_LOOPS]);

int trigger_input = get_trigger_input();
bool triggered = false;
Expand All @@ -507,9 +509,9 @@ public:
trigger_display_.Update(1, triggered || gate_raised_);

if (triggered) ++euclidean_counter_;
uint8_t euclidean_length = static_cast<uint8_t>(s[4]);
uint8_t euclidean_fill = static_cast<uint8_t>(s[5]);
uint8_t euclidean_offset = static_cast<uint8_t>(s[6]);
uint8_t euclidean_length = static_cast<uint8_t>(s[CV_MAPPING_EUCLIDEAN_LENGTH]);
uint8_t euclidean_fill = static_cast<uint8_t>(s[CV_MAPPING_EUCLIDEAN_FILL]);
uint8_t euclidean_offset = static_cast<uint8_t>(s[CV_MAPPING_EUCLIDEAN_OFFSET]);

// Process Euclidean pattern reset
uint8_t euclidean_reset_trigger_input = get_euclidean_reset_trigger_input();
Expand All @@ -534,7 +536,7 @@ public:
if (triggered) {
TriggerDelayMode delay_mode = get_trigger_delay_mode();
// uint32_t delay = get_trigger_delay_ms() * 1000U;
uint32_t delay = static_cast<uint32_t>(s[7] * 1000U);
uint32_t delay = static_cast<uint32_t>(s[CV_MAPPING_DELAY_MSEC] * 1000U);
if (delay_mode && delay) {
triggered = false;
if (TRIGGER_DELAY_QUEUE == delay_mode) {
Expand Down
6 changes: 3 additions & 3 deletions software/o_c_REV/APP_H1200.ino
Original file line number Diff line number Diff line change
Expand Up @@ -1045,11 +1045,11 @@ void H1200_handleButtonEvent(const UI::Event &event) {
if (UI::EVENT_BUTTON_PRESS == event.type) {
switch (event.control) {
case OC::CONTROL_BUTTON_UP:
if (h1200_settings.change_value(H1200_SETTING_INVERSION, 1))
if (h1200_settings.change_value(H1200_SETTING_OCTAVE, 1))
h1200_state.force_update();
break;
case OC::CONTROL_BUTTON_DOWN:
if (h1200_settings.change_value(H1200_SETTING_INVERSION, -1))
if (h1200_settings.change_value(H1200_SETTING_OCTAVE, -1))
h1200_state.force_update();
break;
case OC::CONTROL_BUTTON_L:
Expand All @@ -1070,7 +1070,7 @@ void H1200_handleButtonEvent(const UI::Event &event) {
void H1200_handleEncoderEvent(const UI::Event &event) {

if (OC::CONTROL_ENCODER_L == event.control) {
if (h1200_settings.change_value(H1200_SETTING_ROOT_OFFSET, event.value))
if (h1200_settings.change_value(H1200_SETTING_INVERSION, event.value))
h1200_state.force_update();
} else if (OC::CONTROL_ENCODER_R == event.control) {
if (h1200_state.cursor.editing()) {
Expand Down
16 changes: 12 additions & 4 deletions software/o_c_REV/APP_QQ.ino
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@
#include "OC_scale_edit.h"
#include "OC_strings.h"


#ifdef BUCHLA_4U
#define QQ_OFFSET_X 20
#else
#define QQ_OFFSET_X 31
#endif

enum ChannelSetting {
CHANNEL_SETTING_SCALE,
CHANNEL_SETTING_ROOT,
Expand Down Expand Up @@ -992,6 +999,7 @@ public:
*settings++ = CHANNEL_SETTING_CLKDIV;
*settings++ = CHANNEL_SETTING_DELAY;
}
*settings++ = CHANNEL_SETTING_OCTAVE;
*settings++ = CHANNEL_SETTING_TRANSPOSE;
*settings++ = CHANNEL_SETTING_FINE;

Expand Down Expand Up @@ -1489,15 +1497,15 @@ void QuantizerChannel::RenderScreensaver(weegfx::coord_t start_x) const {
// menu::DrawMask<true, 8, 8, 1>(start_x + 31, 1, get_int_seq_register(), 8);
break;
default: {
graphics.setPixel(start_x + 31 - 16, 4);
graphics.setPixel(start_x + QQ_OFFSET_X - 16, 4);
int32_t cv = OC::ADC::value(static_cast<ADC_CHANNEL>(source));
cv = (cv * 24 + 2047) >> 12;
if (cv < 0)
graphics.drawRect(start_x + 31 - 16 + cv, 6, -cv, 2);
graphics.drawRect(start_x + QQ_OFFSET_X - 16 + cv, 6, -cv, 2);
else if (cv > 0)
graphics.drawRect(start_x + 31 - 16, 6, cv, 2);
graphics.drawRect(start_x + QQ_OFFSET_X - 16, 6, cv, 2);
else
graphics.drawRect(start_x + 31 - 16, 6, 1, 2);
graphics.drawRect(start_x + QQ_OFFSET_X - 16, 6, 1, 2);
}
break;
}
Expand Down
22 changes: 17 additions & 5 deletions software/o_c_REV/OC_DAC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
*
*/

#include <SPIFIFO.h>
#include "util/util_SPIFIFO.h"
#include "OC_DAC.h"
#include "OC_gpio.h"
#include "OC_options.h"
Expand All @@ -42,7 +42,6 @@
#include "OC_autotune.h"

#define SPICLOCK_30MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(60 / 2) * ((1+1)/2) = 30 MHz (= 24MHz, when F_BUS == 48000000)
//#define DAC8564 // <-- uncomment, if using DAC8564

namespace OC {

Expand Down Expand Up @@ -207,7 +206,11 @@ uint8_t DAC::DAC_scaling[DAC_CHANNEL_LAST];
}; // namespace OC

void set8565_CHA(uint32_t data) {
#ifdef BUCHLA_cOC
uint32_t _data = data;
#else
uint32_t _data = OC::DAC::MAX_VALUE - data;
#endif
#ifdef FLIP_180
SPIFIFO.write(0b00010110, SPI_CONTINUE);
#else
Expand All @@ -219,8 +222,11 @@ void set8565_CHA(uint32_t data) {
}

void set8565_CHB(uint32_t data) {
#ifdef BUCHLA_cOC
uint32_t _data = data;
#else
uint32_t _data = OC::DAC::MAX_VALUE - data;

#endif
#ifdef FLIP_180
SPIFIFO.write(0b00010100, SPI_CONTINUE);
#else
Expand All @@ -232,8 +238,11 @@ void set8565_CHB(uint32_t data) {
}

void set8565_CHC(uint32_t data) {
#ifdef BUCHLA_cOC
uint32_t _data = data;
#else
uint32_t _data = OC::DAC::MAX_VALUE - data;

#endif
#ifdef FLIP_180
SPIFIFO.write(0b00010010, SPI_CONTINUE);
#else
Expand All @@ -245,8 +254,11 @@ void set8565_CHC(uint32_t data) {
}

void set8565_CHD(uint32_t data) {
#ifdef BUCHLA_cOC
uint32_t _data = data;
#else
uint32_t _data = OC::DAC::MAX_VALUE - data;

#endif
#ifdef FLIP_180
SPIFIFO.write(0b00010000, SPI_CONTINUE);
#else
Expand Down
15 changes: 14 additions & 1 deletion software/o_c_REV/OC_calibration.ino
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@

using OC::DAC;

#ifdef BUCHLA_cOC
static constexpr uint16_t DAC_OFFSET = 0; // DAC offset, initial approx., ish (Easel card)
#else
static constexpr uint16_t DAC_OFFSET = 4890; // DAC offset, initial approx., ish --> -3.5V to 6V
#endif

#ifdef BUCHLA_4U
static constexpr uint16_t _ADC_OFFSET = (uint16_t)((float)pow(2,OC::ADC::kAdcResolution)*1.0f); // ADC offset @3.3V
#else
Expand All @@ -28,10 +33,18 @@ bool calibration_data_loaded = false;
const OC::CalibrationData kCalibrationDefaults = {
// DAC
{ {
#ifdef BUCHLA_cOC
{197, 6634, 13083, 19517, 25966, 32417, 38850, 45301, 51733, 58180, 64400},
{197, 6634, 13083, 19517, 25966, 32417, 38850, 45301, 51733, 58180, 64400},
{197, 6634, 13083, 19517, 25966, 32417, 38850, 45301, 51733, 58180, 64400},
{197, 6634, 13083, 19517, 25966, 32417, 38850, 45301, 51733, 58180, 64400}
#else
{0, 6553, 13107, 19661, 26214, 32768, 39321, 45875, 52428, 58981, 65535},
{0, 6553, 13107, 19661, 26214, 32768, 39321, 45875, 52428, 58981, 65535},
{0, 6553, 13107, 19661, 26214, 32768, 39321, 45875, 52428, 58981, 65535},
{0, 6553, 13107, 19661, 26214, 32768, 39321, 45875, 52428, 58981, 65535} },
{0, 6553, 13107, 19661, 26214, 32768, 39321, 45875, 52428, 58981, 65535}
#endif
},
},
// ADC
{ { _ADC_OFFSET, _ADC_OFFSET, _ADC_OFFSET, _ADC_OFFSET },
Expand Down
Loading

0 comments on commit 7c5c45f

Please sign in to comment.