Files
-
blinds / hardware_design / pcb / blinds_v60.brd
-
blinds / hardware_design / pcb / blinds_v60.sch
-
braids / hardware_design / pcb / braids_v50.brd
-
braids / hardware_design / pcb / braids_v50.sch
-
branches / hardware_design / pcb / branches_v40.brd
-
branches / hardware_design / pcb / branches_v40.sch
-
clouds / hardware_design / pcb / clouds_v30.brd
-
clouds / hardware_design / pcb / clouds_v30.sch
-
ears / hardware_design / panel / ears_panel_v30.brd
-
ears / hardware_design / panel / ears_panel_v30.sch
-
ears / hardware_design / pcb / ears_v40.brd
-
ears / hardware_design / pcb / ears_v40.sch
-
edges / hardware_design / pcb / edges_expander_v01.brd
-
edges / hardware_design / pcb / edges_expander_v01.sch
-
edges / hardware_design / pcb / edges_v20.brd
-
edges / hardware_design / pcb / edges_v20.sch
-
elements / hardware_design / pcb / elements_v02.brd
-
elements / hardware_design / pcb / elements_v02.sch
-
frames / hardware_design / pcb / frames_v03.brd
-
frames / hardware_design / pcb / frames_v03.sch
-
grids / hardware_design / pcb / grids_v02.brd
-
grids / hardware_design / pcb / grids_v02.sch
-
kinks / hardware_design / pcb / kinks_v41.brd
-
kinks / hardware_design / pcb / kinks_v41.sch
-
links / hardware_design / pcb / links_v40.brd
-
links / hardware_design / pcb / links_v40.sch
-
marbles / hardware_design / pcb / marbles_v70.brd
-
marbles / hardware_design / pcb / marbles_v70.sch
-
peaks / hardware_design / pcb / peaks_v30.brd
-
peaks / hardware_design / pcb / peaks_v30.sch
-
plaits / hardware_design / pcb / plaits_v50.brd
-
plaits / hardware_design / pcb / plaits_v50.sch
-
rings / hardware_design / pcb / rings_v30.brd
-
rings / hardware_design / pcb / rings_v30.sch
-
ripples / hardware_design / pcb / ripples_v40.brd
-
ripples / hardware_design / pcb / ripples_v40.sch
-
shades / hardware_design / pcb / shades_v30.brd
-
shades / hardware_design / pcb / shades_v30.sch
-
shelves / hardware_design / pcb / shelves_expander_v10.brd
-
shelves / hardware_design / pcb / shelves_expander_v10.sch
-
shelves / hardware_design / pcb / shelves_v05.brd
-
shelves / hardware_design / pcb / shelves_v05.sch
-
stages / hardware_design / pcb / stages_v70.brd
-
stages / hardware_design / pcb / stages_v70.sch
-
streams / hardware_design / pcb / streams_v02_bargraph.brd
-
streams / hardware_design / pcb / streams_v02_bargraph.sch
-
streams / hardware_design / pcb / streams_v05.brd
-
streams / hardware_design / pcb / streams_v05.sch
-
tides / hardware_design / pcb / tides_v40.brd
-
tides / hardware_design / pcb / tides_v40.sch
-
veils / hardware_design / pcb / veils_v40.brd
-
veils / hardware_design / pcb / veils_v40.sch
-
volts / hardware_design / pcb / volts_v01.brd
-
volts / hardware_design / pcb / volts_v01.sch
-
warps / hardware_design / pcb / warps_v30.brd
-
warps / hardware_design / pcb / warps_v30.sch
-
yarns / hardware_design / pcb / yarns_v03.brd
-
yarns / hardware_design / pcb / yarns_v03.sch
Last update 6 years 1 month
by
Olivier Gillet
settings.h// Copyright 2012 Olivier Gillet. // // Author: Olivier Gillet (ol.gillet@gmail.com) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // // See http://creativecommons.org/licenses/MIT/ for more information. // // ----------------------------------------------------------------------------- // // Settings #ifndef BRAIDS_SETTINGS_H_ #define BRAIDS_SETTINGS_H_ #include "stmlib/stmlib.h" namespace braids { enum MacroOscillatorShape { MACRO_OSC_SHAPE_CSAW, MACRO_OSC_SHAPE_MORPH, MACRO_OSC_SHAPE_SAW_SQUARE, MACRO_OSC_SHAPE_SINE_TRIANGLE, MACRO_OSC_SHAPE_BUZZ, MACRO_OSC_SHAPE_SQUARE_SUB, MACRO_OSC_SHAPE_SAW_SUB, MACRO_OSC_SHAPE_SQUARE_SYNC, MACRO_OSC_SHAPE_SAW_SYNC, MACRO_OSC_SHAPE_TRIPLE_SAW, MACRO_OSC_SHAPE_TRIPLE_SQUARE, MACRO_OSC_SHAPE_TRIPLE_TRIANGLE, MACRO_OSC_SHAPE_TRIPLE_SINE, MACRO_OSC_SHAPE_TRIPLE_RING_MOD, MACRO_OSC_SHAPE_SAW_SWARM, MACRO_OSC_SHAPE_SAW_COMB, MACRO_OSC_SHAPE_TOY, MACRO_OSC_SHAPE_DIGITAL_FILTER_LP, MACRO_OSC_SHAPE_DIGITAL_FILTER_PK, MACRO_OSC_SHAPE_DIGITAL_FILTER_BP, MACRO_OSC_SHAPE_DIGITAL_FILTER_HP, MACRO_OSC_SHAPE_VOSIM, MACRO_OSC_SHAPE_VOWEL, MACRO_OSC_SHAPE_VOWEL_FOF, MACRO_OSC_SHAPE_HARMONICS, MACRO_OSC_SHAPE_FM, MACRO_OSC_SHAPE_FEEDBACK_FM, MACRO_OSC_SHAPE_CHAOTIC_FEEDBACK_FM, MACRO_OSC_SHAPE_PLUCKED, MACRO_OSC_SHAPE_BOWED, MACRO_OSC_SHAPE_BLOWN, MACRO_OSC_SHAPE_FLUTED, MACRO_OSC_SHAPE_STRUCK_BELL, MACRO_OSC_SHAPE_STRUCK_DRUM, MACRO_OSC_SHAPE_KICK, MACRO_OSC_SHAPE_CYMBAL, MACRO_OSC_SHAPE_SNARE, MACRO_OSC_SHAPE_WAVETABLES, MACRO_OSC_SHAPE_WAVE_MAP, MACRO_OSC_SHAPE_WAVE_LINE, MACRO_OSC_SHAPE_WAVE_PARAPHONIC, MACRO_OSC_SHAPE_FILTERED_NOISE, MACRO_OSC_SHAPE_TWIN_PEAKS_NOISE, MACRO_OSC_SHAPE_CLOCKED_NOISE, MACRO_OSC_SHAPE_GRANULAR_CLOUD, MACRO_OSC_SHAPE_PARTICLE_NOISE, MACRO_OSC_SHAPE_DIGITAL_MODULATION, MACRO_OSC_SHAPE_QUESTION_MARK, // MACRO_OSC_SHAPE_YOUR_ALGO MACRO_OSC_SHAPE_LAST, MACRO_OSC_SHAPE_LAST_ACCESSIBLE_FROM_META = MACRO_OSC_SHAPE_DIGITAL_MODULATION }; enum Resolution { RESOLUTION_2_BIT, RESOLUTION_3_BIT, RESOLUTION_4_BIT, RESOLUTION_6_BIT, RESOLUTION_8_BIT, RESOLUTION_12_BIT, RESOLUTION_16_BIT, RESOLUTION_LAST }; enum SampleRate { SAMPLE_RATE_4K, SAMPLE_RATE_8K, SAMPLE_RATE_16K, SAMPLE_RATE_24k, SAMPLE_RATE_32k, SAMPLE_RATE_48K, SAMPLE_RATE_96K, SAMPLE_RATE_LAST }; enum PitchRange { PITCH_RANGE_EXTERNAL, PITCH_RANGE_FREE, PITCH_RANGE_EXTENDED, PITCH_RANGE_440, PITCH_RANGE_LFO // This setting is hidden by default! }; enum Setting { SETTING_OSCILLATOR_SHAPE, SETTING_RESOLUTION, SETTING_SAMPLE_RATE, SETTING_AD_TIMBRE, SETTING_TRIG_SOURCE, SETTING_TRIG_DELAY, SETTING_META_MODULATION, SETTING_PITCH_RANGE, SETTING_PITCH_OCTAVE, SETTING_QUANTIZER_SCALE, SETTING_VCO_FLATTEN, SETTING_VCO_DRIFT, SETTING_SIGNATURE, SETTING_BRIGHTNESS, SETTING_AD_ATTACK, SETTING_AD_DECAY, SETTING_AD_FM, SETTING_AD_COLOR, SETTING_AD_VCA, SETTING_QUANTIZER_ROOT, SETTING_LAST_EDITABLE_SETTING = SETTING_QUANTIZER_ROOT, // Not settings per-se, but used for menu display! SETTING_CALIBRATION, SETTING_CV_TESTER, SETTING_MARQUEE, SETTING_VERSION, SETTING_LAST }; struct SettingsData { uint8_t shape; uint8_t resolution; uint8_t sample_rate; uint8_t ad_timbre; uint8_t auto_trig; uint8_t trig_delay; uint8_t meta_modulation; uint8_t pitch_range; uint8_t pitch_octave; uint8_t quantizer_scale; uint8_t vco_flatten; uint8_t vco_drift; uint8_t signature; uint8_t brightness; uint8_t ad_attack; uint8_t ad_decay; uint8_t ad_fm; uint8_t ad_color; uint8_t ad_vca; uint8_t quantizer_root; int32_t pitch_cv_offset; int32_t pitch_cv_scale; int32_t fm_cv_offset; int16_t parameter_cv_offset[2]; uint16_t parameter_cv_scale[2]; char marquee_text[55]; char magic_byte; }; struct SettingMetadata { uint8_t min_value; uint8_t max_value; const char name[5]; const char* const* strings; int16_t Clip(int16_t value) const { if (value > max_value) { value = max_value; } else if (value < min_value) { value = min_value; } return value; } }; class Settings { public: Settings() { } ~Settings() { } void Init(); void Save(); void Reset(); void SetValue(Setting setting, uint8_t value) { uint8_t* data = static_cast<uint8_t*>(static_cast<void*>(&data_)); data[setting] = value; } uint8_t GetValue(Setting setting) const { const uint8_t* data = static_cast<const uint8_t*>( static_cast<const void*>(&data_)); return data[setting]; } inline MacroOscillatorShape shape() const { return static_cast<MacroOscillatorShape>(data_.shape); } inline Resolution resolution() const { return static_cast<Resolution>(data_.resolution); } inline SampleRate sample_rate() const { return static_cast<SampleRate>(data_.sample_rate); } inline bool vco_flatten() const { return data_.vco_flatten; } inline uint8_t vco_drift() const { return data_.vco_drift; } inline uint8_t signature() const { return data_.signature; } inline bool meta_modulation() const { return data_.meta_modulation; } inline uint8_t trig_delay() const { return data_.trig_delay; } inline int32_t quantizer_root() const { return data_.quantizer_root; } inline const char* marquee_text() const { return data_.marquee_text; } inline char* mutable_marquee_text() { return data_.marquee_text; } inline const SettingsData& data() const { return data_; } inline SettingsData* mutable_data() { return &data_; } void Calibrate( int32_t adc_code_c2, int32_t adc_code_c4, int32_t adc_code_fm, int32_t adc_code_p0_min, int32_t adc_code_p0_max, int32_t adc_code_p1_min, int32_t adc_code_p1_max) { if (adc_code_c4 != adc_code_c2) { int32_t scale = (24 * 128 * 4096L) / (adc_code_c4 - adc_code_c2); data_.pitch_cv_scale = scale; data_.pitch_cv_offset = (60 << 7) - (scale * ((adc_code_c2 + adc_code_c4) >> 1) >> 12); data_.fm_cv_offset = adc_code_fm; } // int32_t min_code[2] = { adc_code_p0_min, adc_code_p1_min }; // int32_t max_code[2] = { adc_code_p0_max, adc_code_p1_max }; // // for (int i = 0; i < 2; ++i) { // int32_t d = max_code[i] - min_code[i]; // if (d > 3700) { // int32_t scale = (32768 * 4106) / d; // int32_t offset = -(min_code[i] * scale >> 12) - 40; // data_.parameter_cv_offset[i] = offset; // data_.parameter_cv_scale[i] = scale; // } // } Save(); } inline int32_t adc_to_pitch(int32_t pitch_adc_code) const { if (data_.pitch_range == PITCH_RANGE_EXTERNAL || data_.pitch_range == PITCH_RANGE_LFO) { pitch_adc_code = pitch_adc_code * data_.pitch_cv_scale >> 12; pitch_adc_code += data_.pitch_cv_offset; } else if (data_.pitch_range == PITCH_RANGE_FREE) { pitch_adc_code = (pitch_adc_code - 1638); pitch_adc_code = pitch_adc_code * data_.pitch_cv_scale >> 12; pitch_adc_code += 60 << 7; } else if (data_.pitch_range == PITCH_RANGE_440) { pitch_adc_code = 69 << 7; } else { pitch_adc_code = (pitch_adc_code - 1638) * 9 >> 1; pitch_adc_code += 60 << 7; } return pitch_adc_code; } inline int32_t pitch_transposition() const { int32_t t = data_.pitch_range == PITCH_RANGE_LFO ? -36 << 7 : 0; t += (static_cast<int32_t>(data_.pitch_octave) - 2) * 12 * 128; return t; } inline int32_t adc_to_fm(int32_t fm_adc_code) const { fm_adc_code -= data_.fm_cv_offset; fm_adc_code = fm_adc_code * 7680 >> 12; if (data_.pitch_range == PITCH_RANGE_440) { fm_adc_code = 0; } return fm_adc_code; } inline int32_t adc_to_parameter(int index, int32_t adc_code) const { int32_t scale = static_cast<int32_t>(data_.parameter_cv_scale[index]); int32_t offset = static_cast<int32_t>(data_.parameter_cv_offset[index]); return (scale * adc_code >> 12) + offset; } inline bool paques() const { return paques_; } static const SettingMetadata& metadata(Setting setting) { return metadata_[setting]; } static const Setting setting_at_index(int16_t index) { return settings_order_[index]; } private: void CheckPaques(); SettingsData data_; uint16_t version_token_; bool paques_; static const SettingMetadata metadata_[SETTING_LAST]; static const Setting settings_order_[SETTING_LAST]; DISALLOW_COPY_AND_ASSIGN(Settings); }; extern Settings settings; } // namespace braids #endif // BRAIDS_SETTINGS_H_