#include #include prog_uint16_t PROGMEM prog_octave; prog_int16_t PROGMEM prog_offset; enum { MODE_LFO = 0, MODE_OCTAVE_ADJUST, MODE_COUNT }; uint8_t mode; uint8_t octave; int8_t offset; int8_t transpose; uint32_t ms_buttons; LFO::Handle lfo; // 初期化 void setup() { Ongaku::initialize(); // オンガクシールド・ドライバの初期化 LFO::initialize( lfo, 150 ); mode = MODE_LFO; octave = EEPROM.read(0x0); offset = EEPROM.read(0x1); transpose = 0; ms_buttons = 0; } void transitMode(uint8_t newMode) { if (mode == MODE_OCTAVE_ADJUST && newMode != MODE_OCTAVE_ADJUST) { // copy back the adjusted parameters to flash memory EEPROM.write(0x0, octave); EEPROM.write(0x1, offset); } mode = newMode; switch(mode) { case MODE_LFO: LFO::initialize( lfo, 150 ); break; case MODE_OCTAVE_ADJUST: //LFO::initialize( lfo, 2000 ); LED::on(led_red); LED::on(led_green); break; } } void checkModeChange() { static bool button_prev_red = false; static bool button_prev_blue = false; bool button_current_red = Button::isOn( button_red ); bool button_current_blue = Button::isOn( button_blue ); if (button_current_red && button_current_blue) { transpose = 0; if (! button_prev_red || ! button_prev_blue) { ms_buttons = millis(); } else if (millis() - ms_buttons > 2000) { // transitMode(MODE_OCTAVE_ADJUST); uint8_t newMode = (mode + 1) % MODE_COUNT; transitMode(newMode); ms_buttons = millis(); } } else { if (button_current_red && ! button_prev_red) { --transpose; if (transpose < -1) { transpose = -1; } } if (button_current_blue && ! button_prev_blue) { ++transpose; if (transpose > 1) { transpose = 1; } } } button_prev_red = button_current_red; button_prev_blue = button_current_blue; } #define DELTA 32 int32_t bend_current = 512; int16_t modulation = 0; void updateBend(uint16_t& xx, uint16_t& yy) { if (xx > 40) { uint16_t depth = VR::getValue(vr1); if (xx > 512 + DELTA) { int32_t delta = xx - 512 - DELTA; bend_current = 512 + octave / 2 * depth / 192 * delta / (512 - DELTA); } else if (xx < 512 - DELTA) { int32_t delta = 512 - DELTA - xx; bend_current = 512 - octave / 2 * depth / 192 * delta / (512 - DELTA); } } else { if (bend_current > 512) { --bend_current; } else { ++bend_current; } } } void lfo_modulation(uint16_t& yy) { int16_t interval = 45 - VR::getValue(vr2) / 12; if (interval < 1) { interval = 1; } interval *= interval; LFO::setInterval(lfo, interval); if (yy < 512 && yy > 40) { modulation = octave * (int32_t)LFO::getValue( lfo ) / 512 * (512 - yy) / 512 * (512 - yy) / 512; } else { modulation = 0; } } void octave_adjust() { octave = 128 + VR::getValue(vr2) / 8; offset = 96 - VR::getValue(vr1) / 4; //modulation = LFO::getDirection( lfo ) > 0 ? -octave : 0; } // 処理ループ void loop() { Ongaku::update(); // オンガクシールドのデバイスを読み取る LFO::update( lfo ); //////////////////////// checkModeChange(); uint16_t xx = TouchScreen::getValue( touch_screen_x ); uint16_t yy = TouchScreen::getValue( touch_screen_y ); updateBend(xx, yy); switch(mode) { case MODE_LFO: lfo_modulation(yy); LED::set(led_red, (transpose < 0)); LED::set(led_green, (transpose > 0)); break; case MODE_OCTAVE_ADJUST: octave_adjust(); break; } uint16_t cv = bend_current + offset; cv += modulation; cv += transpose * octave; CV::setValue( cv ); } // オンガクシールドの更新チェック namespace Ongaku { void check() { LFO::check( lfo ); } };