int SynthNote::button_press_event() { if(BC_Toggle::button_press_event()) { // printf("SynthNote::button_press_event %d %d %d\n", // __LINE__, // ctrl_down(), // window->synth->freq_exists(keyboard_freqs[number])); window->starting_notes = 1; if((ctrl_down() || shift_down()) && window->synth->freq_exists(keyboard_freqs[number])) { //printf("SynthNote::button_press_event %d\n", __LINE__); stop_note(); window->starting_notes = 0; } else { //printf("SynthNote::button_press_event %d\n", __LINE__); start_note(); window->starting_notes = 1; } window->current_note = number; return 1; } return 0; }
int SynthNote::cursor_motion_event() { int result = 0; if(window->current_note > -1) { int cursor_x = get_relative_cursor_x(); int cursor_y = get_relative_cursor_y(); if(cursor_x >= 0 && cursor_x < get_w() && cursor_y >= 0 && cursor_y < get_h()) { if(window->starting_notes) { start_note(); } else { stop_note(); } window->current_note = number; result = 1; } } return result; }
static void example(void) { if(button_clicked(LEFT)) { set_note(NOTE_C, 4); wait_ms(500); set_note(NOTE_D, 4); wait_ms(500); stop_note(); } if(button_clicked(RIGHT)) { set_note(NOTE_D, 4); wait_ms(500); set_note(NOTE_C, 4); wait_ms(500); stop_note(); } }
int SynthNote::keyrelease_event() { if(note_on && window->synth->config.momentary_notes) { stop_note(); set_value(0); return 1; } return 0; }
void process_action_user(keyrecord_t *record) { if (IS_LAYER_ON(_MUSIC)) { if (record->event.pressed) { play_note(((double)220.0)*pow(2.0, -4.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row)), 0xF); } else { stop_note(((double)220.0)*pow(2.0, -4.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row))); } } }
void stop_sound() { int i; endflag = -1; for (i = 0; i < NUM_CHANNELS; i++) stop_note(i); if (playing_sound != -1) { game.sounds[playing_sound].flags &= ~SOUND_PLAYING; playing_sound = -1; } }
void scan_keys() { PORTB &= ~(_BV(PB0) | _BV(PB1)); PORTB |= _BV(PB0); PORTB &= ~_BV(PB0); PORTB |= _BV(PB1); #ifdef SHIFT_74HC595 // I use the simpler 74HC164, but you can use a 595 by tying the two // clock inputs together. You'll need this extra clock pulse to load the first bit. PORTB |= _BV(PB0); PORTB &= ~_BV(PB0); #endif uint8_t col; for (col = 11; col > 3; --col) { uint8_t rows = PIND | 0x01; PORTB |= _BV(PB0); PORTB &= ~_BV(PB0); uint8_t note; uint8_t col_start = (col & 7) + key_octave_transpose; uint8_t col_end = KEY_SIZE + key_octave_transpose; if (rows != 0xFF) { for (note = col_start; note < col_end; note += 8) { if (!(rows & 0x80)) start_note(BANK_KEYS, note); else stop_note(BANK_KEYS, note); rows = rows << 1; } } else { for (note = col_start; note < col_end; note += 8) { stop_note(BANK_KEYS, note); } } } }
void matrix_scan_user(void) { #ifdef AUDIO_ENABLE if (muse_mode) { if (muse_counter == 0) { uint8_t muse_note = muse_offset + SCALE[muse_clock_pulse()]; if (muse_note != last_muse_note) { stop_note(compute_freq_for_midi_note(last_muse_note)); play_note(compute_freq_for_midi_note(muse_note), 0xF); last_muse_note = muse_note; } } muse_counter = (muse_counter + 1) % muse_tempo; } #endif }
static void stop_note(int i) { chn[i].adsr = AGI_SOUND_ENV_RELEASE; #ifdef USE_CHORUS /* Stop chorus ;) */ if (chn[i].type == AGI_SOUND_4CHN && opt.soundemu == SOUND_EMU_NONE && i < 3) { stop_note(i + 4); } #endif #ifdef __TURBOC__ if (i == 0) nosound(); #endif }
int SynthNote::button_release_event() { // Change frequency permanently if(window->current_note == number) { if(window->synth->config.momentary_notes) { // Mute on button release stop_note(); set_value(0); } window->current_note = -1; } return BC_Toggle::button_release_event(); }
int SynthNote::keypress_event() { if(number >= FIRST_TITLE && number < LAST_TITLE) { if(get_keypress() == keyboard_map[number - FIRST_TITLE][0]) { if((ctrl_down() || shift_down()) && window->synth->freq_exists(keyboard_freqs[number])) { stop_note(); } else { start_note(); set_value(1); } // Key releases are repeated, so momentary notes may not work return 1; } } return 0; }
void ToneAlarm::next_note() { // do we have an inter-note gap to wait for? if (_silence_length > 0) { stop_note(); hrt_call_after(&_note_call, (hrt_abstime)_silence_length, (hrt_callout)next_trampoline, this); _silence_length = 0; return; } // make sure we still have a tune - may be removed by the write / ioctl handler if ((_next == nullptr) || (_tune == nullptr)) { stop_note(); return; } // parse characters out of the string until we have resolved a note unsigned note = 0; unsigned note_length = _note_length; unsigned duration; while (note == 0) { // we always need at least one character from the string int c = next_char(); if (c == 0) { goto tune_end; } _next++; switch (c) { case 'L': // select note length _note_length = next_number(); if (_note_length < 1) { goto tune_error; } break; case 'O': // select octave _octave = next_number(); if (_octave > 6) { _octave = 6; } break; case '<': // decrease octave if (_octave > 0) { _octave--; } break; case '>': // increase octave if (_octave < 6) { _octave++; } break; case 'M': // select inter-note gap c = next_char(); if (c == 0) { goto tune_error; } _next++; switch (c) { case 'N': _note_mode = MODE_NORMAL; break; case 'L': _note_mode = MODE_LEGATO; break; case 'S': _note_mode = MODE_STACCATO; break; case 'F': _repeat = false; break; case 'B': _repeat = true; break; default: goto tune_error; } break; case 'P': // pause for a note length stop_note(); hrt_call_after(&_note_call, (hrt_abstime)rest_duration(next_number(), next_dots()), (hrt_callout)next_trampoline, this); return; case 'T': { // change tempo unsigned nt = next_number(); if ((nt >= 32) && (nt <= 255)) { _tempo = nt; } else { goto tune_error; } break; } case 'N': // play an arbitrary note note = next_number(); if (note > 84) { goto tune_error; } if (note == 0) { // this is a rest - pause for the current note length hrt_call_after(&_note_call, (hrt_abstime)rest_duration(_note_length, next_dots()), (hrt_callout)next_trampoline, this); return; } break; case 'A'...'G': // play a note in the current octave note = _note_tab[c - 'A'] + (_octave * 12) + 1; c = next_char(); switch (c) { case '#': // up a semitone case '+': if (note < 84) { note++; } _next++; break; case '-': // down a semitone if (note > 1) { note--; } _next++; break; default: // 0 / no next char here is OK break; } // shorthand length notation note_length = next_number(); if (note_length == 0) { note_length = _note_length; } break; default: goto tune_error; } } // compute the duration of the note and the following silence (if any) duration = note_duration(_silence_length, note_length, next_dots()); // start playing the note start_note(note); // and arrange a callback when the note should stop hrt_call_after(&_note_call, (hrt_abstime)duration, (hrt_callout)next_trampoline, this); return; // tune looks bad (unexpected EOF, bad character, etc.) tune_error: syslog(LOG_ERR, "tune error\n"); _repeat = false; // don't loop on error // stop (and potentially restart) the tune tune_end: stop_note(); if (_repeat) { start_tune(_tune); } else { _tune = nullptr; _default_tune_number = 0; } return; }
static void run(void) { if(ir_recv()) { // receive a ir signal, react motor_on(); led_on(RIGHT); set_note(NOTE_B, 5); wait_ms(200); set_note(NOTE_F, 5); wait_ms(100); led_off(RIGHT); led_on(LEFT); set_note(NOTE_G, 5); wait_ms(100); set_note(NOTE_Ab, 5); wait_ms(100); set_note(NOTE_A, 5); wait_ms(100); led_off(LEFT); motor_off(); } else if(button_clicked(RIGHT)) { // button clicked, send ir signal and do some stuff led_on(RIGHT); set_note(NOTE_A, 5); wait_ms(100); set_note(NOTE_Ab, 5); wait_ms(100); set_note(NOTE_G, 5); wait_ms(100); led_off(RIGHT); led_on(LEFT); set_note(NOTE_F, 5); wait_ms(100); set_note(NOTE_B, 5); wait_ms(200); stop_note(); led_off(LEFT); ir_on(); wait_ms(400); ir_off(); wait_ms(10); } else { // regular bug behaviour uint8_t light = photons_measure(); pentatonic_all_led_set(light >> 3); motor_set(biased_random(light) > BASELINE + 0x40); led_set(RIGHT, biased_random(light) > BASELINE + 0x00); led_set(LEFT, biased_random(light) > BASELINE + 0x00); if(biased_random(light) > BASELINE + 0x20) { uint16_t tone = (biased_random(light) * 2) + 500; set_note(tone, 0); } else { stop_note(); } wait_ms(200); } }
void scan_midi() { uint8_t data = midi_ring_buffer[midi_next_message++]; /* Status messages */ if (data & 0x80) { midi_data_index = 0; switch(data & 0xF0) { case 0x90: midi_status = MIDI_NOTE_ON; break; case 0x80: midi_status = MIDI_NOTE_OFF; break; case 0xC0: midi_status = MIDI_PROGRAM_CHANGE; break; case 0xB0: midi_status = MIDI_CONTROL_CHANGE; break; default: midi_status = MIDI_IDLE; } } /* Data messages */ else { midi_data_index += 1; switch (midi_status) { case MIDI_NOTE_ON: if (midi_data_index == 2) { if (midi_sustain && data) { if (midi_sustain && midi_last_data == MIDI_NOTE_OFFSET) key_octave_down(); else if (midi_sustain && midi_last_data == MIDI_NOTE_OFFSET + 87) key_octave_up(); else add_record_pitch_change(midi_last_data - MIDI_NOTE_OFFSET); } else { if (data) { start_note(BANK_MIDI, MIDI_NOTE(midi_last_data)); if (banks[BANK_MIDI].mode & MODE_PEDAL && midi_last_data >= (MIDI_NOTE_OFFSET+12)) start_note(BANK_MIDI, MIDI_NOTE(midi_last_data - 12)); } else { stop_note(BANK_MIDI, MIDI_NOTE(midi_last_data)); if (banks[BANK_MIDI].mode & MODE_PEDAL && midi_last_data >= (MIDI_NOTE_OFFSET+12)) stop_note(BANK_MIDI, MIDI_NOTE(midi_last_data - 12)); } } midi_data_index = 0; } break; case MIDI_NOTE_OFF: if (midi_data_index == 2) { stop_note(BANK_MIDI, MIDI_NOTE(midi_last_data)); if (banks[BANK_MIDI].mode & MODE_PEDAL && midi_last_data >= (MIDI_NOTE_OFFSET+12)) stop_note(BANK_MIDI, MIDI_NOTE(midi_last_data - 12)); midi_data_index = 0; } break; case MIDI_PROGRAM_CHANGE: midi_program_change(data); midi_data_index = 0; break; case MIDI_CONTROL_CHANGE: if (midi_data_index == 2) { if (midi_last_data == 0x40) midi_sustain = data & 0x40; // <64 off, >=64 on midi_data_index = 0; } break; } midi_last_data = data; } }
// Defines actions tor my global custom keycodes. Defined in drashna.h file // Then runs the _keymap's recod handier if not processed here bool process_record_user(uint16_t keycode, keyrecord_t *record) { #ifdef CONSOLE_ENABLE xprintf("KL: row: %u, column: %u, pressed: %u\n", record->event.key.col, record->event.key.row, record->event.pressed); #endif #ifdef AUDIO_ENABLE if (faux_click_enabled) { if (record->event.pressed) { PLAY_SONG(fauxclicky_pressed); } else { stop_note(NOTE_A6); PLAY_SONG(fauxclicky_released); } } #endif switch (keycode) { case KC_QWERTY: if (record->event.pressed) { #ifdef AUDIO_ENABLE PLAY_SONG(tone_qwerty); #endif persistent_default_layer_set(1UL << _QWERTY); } return false; break; case KC_COLEMAK: if (record->event.pressed) { #ifdef AUDIO_ENABLE PLAY_SONG(tone_colemak); #endif persistent_default_layer_set(1UL << _COLEMAK); } return false; break; case KC_DVORAK: if (record->event.pressed) { #ifdef AUDIO_ENABLE PLAY_SONG(tone_dvorak); #endif persistent_default_layer_set(1UL << _DVORAK); } return false; break; case KC_WORKMAN: if (record->event.pressed) { #ifdef AUDIO_ENABLE PLAY_SONG(tone_workman); #endif persistent_default_layer_set(1UL << _WORKMAN); } return false; break; case LOWER: if (record->event.pressed) { layer_on(_LOWER); update_tri_layer(_LOWER, _RAISE, _ADJUST); } else { layer_off(_LOWER); update_tri_layer(_LOWER, _RAISE, _ADJUST); } return false; break; case RAISE: if (record->event.pressed) { layer_on(_RAISE); update_tri_layer(_LOWER, _RAISE, _ADJUST); } else { layer_off(_RAISE); update_tri_layer(_LOWER, _RAISE, _ADJUST); } return false; break; case ADJUST: if (record->event.pressed) { layer_on(_ADJUST); } else { layer_off(_ADJUST); } return false; break; #if !(defined(KEYBOARD_orthodox_rev1) || defined(KEYBOARD_orthodox_rev3) || defined(KEYBOARD_ergodox_ez)) case KC_OVERWATCH: if (record->event.pressed) { is_overwatch = !is_overwatch; } #ifdef RGBLIGHT_ENABLE is_overwatch ? rgblight_mode(17) : rgblight_mode(18); #endif return false; break; case KC_SALT: if (!record->event.pressed) { register_code(is_overwatch ? KC_BSPC : KC_ENTER); unregister_code(is_overwatch ? KC_BSPC : KC_ENTER); wait_ms(50); SEND_STRING("Salt, salt, salt..."); register_code(KC_ENTER); unregister_code(KC_ENTER); } return false; break; case KC_MORESALT: if (!record->event.pressed) { register_code(is_overwatch ? KC_BSPC : KC_ENTER); unregister_code(is_overwatch ? KC_BSPC : KC_ENTER); wait_ms(50); SEND_STRING("Please sir, can I have some more salt?!"); register_code(KC_ENTER); unregister_code(KC_ENTER); } return false; break; case KC_SALTHARD: if (!record->event.pressed) { register_code(is_overwatch ? KC_BSPC : KC_ENTER); unregister_code(is_overwatch ? KC_BSPC : KC_ENTER); wait_ms(50); SEND_STRING("Your salt only makes me harder, and even more aggressive!"); register_code(KC_ENTER); unregister_code(KC_ENTER); } return false; break; case KC_GOODGAME: if (!record->event.pressed) { register_code(is_overwatch ? KC_BSPC : KC_ENTER); unregister_code(is_overwatch ? KC_BSPC : KC_ENTER); wait_ms(50); SEND_STRING("Good game, everyone!"); register_code(KC_ENTER); unregister_code(KC_ENTER); } return false; break; case KC_GLHF: if (!record->event.pressed) { register_code(is_overwatch ? KC_BSPC : KC_ENTER); unregister_code(is_overwatch ? KC_BSPC : KC_ENTER); wait_ms(50); SEND_STRING("Good luck, have fun!!!"); register_code(KC_ENTER); unregister_code(KC_ENTER); } return false; break; case KC_SYMM: if (!record->event.pressed) { register_code(is_overwatch ? KC_BSPC : KC_ENTER); unregister_code(is_overwatch ? KC_BSPC : KC_ENTER); wait_ms(50); SEND_STRING("Left click to win!"); register_code(KC_ENTER); unregister_code(KC_ENTER); } return false; break; case KC_JUSTGAME: if (!record->event.pressed) { register_code(is_overwatch ? KC_BSPC : KC_ENTER); unregister_code(is_overwatch ? KC_BSPC : KC_ENTER); wait_ms(50); SEND_STRING("It may be a game, but if you don't want to actually try, please go play AI, so that people that actually want to take the game seriously and \"get good\" have a place to do so without trolls like you throwing games."); register_code(KC_ENTER); unregister_code(KC_ENTER); } return false; break; case KC_TORB: if (!record->event.pressed) { register_code(is_overwatch ? KC_BSPC : KC_ENTER); unregister_code(is_overwatch ? KC_BSPC : KC_ENTER); wait_ms(50); SEND_STRING("That was positively riveting!"); register_code(KC_ENTER); unregister_code(KC_ENTER); } return false; break; case KC_AIM: if (!record->event.pressed) { register_code(is_overwatch ? KC_BSPC : KC_ENTER); unregister_code(is_overwatch ? KC_BSPC : KC_ENTER); wait_ms(50); SEND_STRING("That aim is absolutely amazing. It's almost like you're a machine!" SS_TAP(X_ENTER)); wait_ms(3000); register_code(is_overwatch ? KC_BSPC : KC_ENTER); unregister_code(is_overwatch ? KC_BSPC : KC_ENTER); SEND_STRING("Wait! That aim is TOO good! You're clearly using an aim hack! CHEATER!" SS_TAP(X_ENTER)); } return false; break; case KC_C9: if (!record->event.pressed) { register_code(is_overwatch ? KC_BSPC : KC_ENTER); unregister_code(is_overwatch ? KC_BSPC : KC_ENTER); wait_ms(50); SEND_STRING("OMG!!! C9!!!"); register_code(KC_ENTER); unregister_code(KC_ENTER); } return false; break; case KC_GGEZ: if (!record->event.pressed) { register_code(is_overwatch ? KC_BSPC : KC_ENTER); unregister_code(is_overwatch ? KC_BSPC : KC_ENTER); wait_ms(50); SEND_STRING("That was a fantastic game, though it was a bit easy. Try harder next time!"); register_code(KC_ENTER); unregister_code(KC_ENTER); } return false; break; #endif #ifdef TAP_DANCE_ENABLE case KC_DIABLO_CLEAR: // reset all Diable timers, disabling them if (record->event.pressed) { uint8_t dtime; for (dtime = 0; dtime < 4; dtime++) { diablo_key_time[dtime] = diablo_times[0]; } } return false; break; #endif case KC_MAKE: if (!record->event.pressed) { SEND_STRING("make " QMK_KEYBOARD ":" QMK_KEYMAP #if (defined(BOOTLOADER_DFU) || defined(BOOTLOADER_LUFA_DFU) || defined(BOOTLOADER_QMK_DFU)) ":dfu" #elif defined(BOOTLOADER_HALFKAY) ":teensy" //#elif defined(BOOTLOADER_CATERINA) // ":avrdude" #endif SS_TAP(X_ENTER)); } return false; break; case KC_RESET: if (!record->event.pressed) { #ifdef RGBLIGHT_ENABLE rgblight_enable(); rgblight_mode(1); rgblight_setrgb(0xff, 0x00, 0x00); #endif reset_keyboard(); } return false; break; case EPRM: if (record->event.pressed) { eeconfig_init(); } return false; break; case VRSN: if (record->event.pressed) { SEND_STRING(QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION); } return false; break; case KC_SECRET_1 ... KC_SECRET_5: if (!record->event.pressed) { send_string_P(secret[keycode - KC_SECRET_1]); } return false; break; case KC_FXCL: if (!record->event.pressed) { faux_click_enabled = !faux_click_enabled; } return false; break; case KC_RGB_T: // Because I want the option to go back to normal RGB mode rather than always layer indication #ifdef RGBLIGHT_ENABLE if (record->event.pressed) { rgb_layer_change = !rgb_layer_change; } #endif return false; break; #ifdef RGBLIGHT_ENABLE case RGB_MODE_FORWARD ... RGB_MODE_GRADIENT: // quantum_keycodes.h L400 for definitions if (record->event.pressed) { //This disrables layer indication, as it's assumed that if you're changing this ... you want that disabled rgb_layer_change = false; } return true; break; #endif } return process_record_keymap(keycode, record); }
int do_track_event(unsigned char *data, int *pos) { char channel; unsigned char buf[5]; buf[0]=data[*pos]; *pos +=1; channel = buf[0] & 0xf; #ifdef WANT_MPU401 if (card_info.synth_type==SYNTH_TYPE_MIDI) { switch((buf[0]&0xf0)) { case 0x80: case 0x90: case 0xa0: case 0xb0: case 0xe0: buf[1]=data[*pos]; *pos+=1; buf[2]=data[*pos]; *pos+=1; MIDI_MESSAGE3(buf[0],buf[1],buf[2]); break; case 0xc0: case 0xd0: buf[1]=data[*pos]; *pos+=1; MIDI_MESSAGE3(buf[0],0,buf[1]); break; case 0xf0: return 1; default: return 3; } seqbuf_dump(); return 0; } #endif switch((buf[0] & 0xf0)) { case 0x80: buf[1]=data[*pos]; *pos +=1; buf[2]=data[*pos]; *pos +=1; stop_note((int) channel, (int) buf[1], (int) buf[2]); break; case 0x90: buf[1]=data[*pos]; *pos +=1; buf[2]=data[*pos]; *pos +=1; if(buf[2] == 0) { stop_note((int) channel, (int) buf[1], (int) buf[2]); } else { start_note((int) channel, (int) buf[1], (int) buf[2]); } break; case 0xa0: buf[1]=data[*pos]; *pos +=1; buf[2]=data[*pos]; *pos +=1; set_key_pressure((int) channel, (int) buf[1], (int) buf[2]); break; case 0xb0: buf[1]=data[*pos]; *pos +=1; buf[2]=data[*pos]; *pos +=1; set_control((int) channel, (int) buf[1], (int) buf[2]); break; case 0xe0: buf[1]=data[*pos]; *pos +=1; buf[2]=data[*pos]; *pos +=1; set_pitchbend((int) channel, (int) ((buf[2] << 7) + buf[1]); break; case 0xc0: buf[1]=data[*pos]; *pos +=1; set_program((int) channel, (int) buf[1] ); break; case 0xd0: buf[1]=data[*pos]; *pos +=1; set_chn_pressure((int) channel, (int) buf[1]); break; case 0xf0: return 1; default: return 3; } seqbuf_dump(); return 0; }
void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) { if (id != 0) { if (record->event.pressed) { midi_send_noteon(&midi_device, opt, (id & 0xFF), 127); } else { midi_send_noteoff(&midi_device, opt, (id & 0xFF), 127); } } if (record->event.key.col == (MATRIX_COLS - 1) && record->event.key.row == (MATRIX_ROWS - 1)) { if (record->event.pressed) { starting_note++; play_note(((double)261.626)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[0 + offset])/12.0+(MATRIX_ROWS - 1)), 0xC); midi_send_cc(&midi_device, 0, 0x7B, 0); midi_send_cc(&midi_device, 1, 0x7B, 0); midi_send_cc(&midi_device, 2, 0x7B, 0); midi_send_cc(&midi_device, 3, 0x7B, 0); midi_send_cc(&midi_device, 4, 0x7B, 0); return; } else { stop_note(((double)261.626)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[0 + offset])/12.0+(MATRIX_ROWS - 1))); stop_all_notes(); return; } } if (record->event.key.col == (MATRIX_COLS - 2) && record->event.key.row == (MATRIX_ROWS - 1)) { if (record->event.pressed) { starting_note--; play_note(((double)261.626)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[0 + offset])/12.0+(MATRIX_ROWS - 1)), 0xC); midi_send_cc(&midi_device, 0, 0x7B, 0); midi_send_cc(&midi_device, 1, 0x7B, 0); midi_send_cc(&midi_device, 2, 0x7B, 0); midi_send_cc(&midi_device, 3, 0x7B, 0); midi_send_cc(&midi_device, 4, 0x7B, 0); return; } else { stop_note(((double)261.626)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[0 + offset])/12.0+(MATRIX_ROWS - 1))); stop_all_notes(); return; } } if (record->event.key.col == (MATRIX_COLS - 3) && record->event.key.row == (MATRIX_ROWS - 1) && record->event.pressed) { offset++; midi_send_cc(&midi_device, 0, 0x7B, 0); midi_send_cc(&midi_device, 1, 0x7B, 0); midi_send_cc(&midi_device, 2, 0x7B, 0); midi_send_cc(&midi_device, 3, 0x7B, 0); midi_send_cc(&midi_device, 4, 0x7B, 0); stop_all_notes(); for (int i = 0; i <= 7; i++) { play_note(((double)261.626)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[i + offset])/12.0+(MATRIX_ROWS - 1)), 0xC); _delay_us(80000); stop_note(((double)261.626)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[i + offset])/12.0+(MATRIX_ROWS - 1))); _delay_us(8000); } return; } if (record->event.key.col == (MATRIX_COLS - 4) && record->event.key.row == (MATRIX_ROWS - 1) && record->event.pressed) { offset--; midi_send_cc(&midi_device, 0, 0x7B, 0); midi_send_cc(&midi_device, 1, 0x7B, 0); midi_send_cc(&midi_device, 2, 0x7B, 0); midi_send_cc(&midi_device, 3, 0x7B, 0); midi_send_cc(&midi_device, 4, 0x7B, 0); stop_all_notes(); for (int i = 0; i <= 7; i++) { play_note(((double)261.626)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[i + offset])/12.0+(MATRIX_ROWS - 1)), 0xC); _delay_us(80000); stop_note(((double)261.626)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[i + offset])/12.0+(MATRIX_ROWS - 1))); _delay_us(8000); } return; } if (record->event.pressed) { // midi_send_noteon(&midi_device, record->event.key.row, starting_note + SCALE[record->event.key.col], 127); midi_send_noteon(&midi_device, 0, (starting_note + SCALE[record->event.key.col + offset])+12*(MATRIX_ROWS - record->event.key.row), 127); play_note(((double)261.626)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row)), 0xF); } else { // midi_send_noteoff(&midi_device, record->event.key.row, starting_note + SCALE[record->event.key.col], 127); midi_send_noteoff(&midi_device, 0, (starting_note + SCALE[record->event.key.col + offset])+12*(MATRIX_ROWS - record->event.key.row), 127); stop_note(((double)261.626)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row))); } }