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; }
/*Abstraction of press note button actions */ void pressNote(uint8_t n) { /* set current note */ note = n; /* set frequency (notes.h) */ start_note(); /* print out note (serial.h) */ output_note(); }
void microbit_music_tick(void) { if (music_data == NULL) { // music module not yet imported return; } if (music_data->async_state == ASYNC_MUSIC_STATE_IDLE) { // nothing to do return; } if (ticks < music_data->async_wait_ticks) { // need to wait for timeout to expire return; } if (music_data->async_state == ASYNC_MUSIC_STATE_ARTICULATE) { // turn off output and rest pwm_set_duty_cycle(music_data->async_pin->name, 0); music_data->async_wait_ticks = ticks + ARTICULATION_MS; music_data->async_state = ASYNC_MUSIC_STATE_NEXT_NOTE; } else if (music_data->async_state == ASYNC_MUSIC_STATE_NEXT_NOTE) { // play next note if (music_data->async_notes_index >= music_data->async_notes_len) { if (music_data->async_loop) { music_data->async_notes_index = 0; } else { music_data->async_state = ASYNC_MUSIC_STATE_IDLE; microbit_obj_pin_free(music_data->async_pin); music_data->async_pin = NULL; return; } } mp_obj_t note; if (music_data->async_notes_len == 1) { note = music_data->async_note; } else { note = ((mp_obj_t*)music_data->async_note)[music_data->async_notes_index]; } if (note == mp_const_none) { // a rest (is this even used anymore?) pwm_set_duty_cycle(music_data->async_pin->name, 0); music_data->async_wait_ticks = 60000 / music_data->bpm; music_data->async_state = ASYNC_MUSIC_STATE_NEXT_NOTE; } else { // a note mp_uint_t note_len; const char *note_str = mp_obj_str_get_data(note, ¬e_len); uint32_t delay_on = start_note(note_str, note_len, music_data->async_pin); music_data->async_wait_ticks = ticks + delay_on; music_data->async_notes_index += 1; music_data->async_state = ASYNC_MUSIC_STATE_ARTICULATE; } } }
/* Set the currently used note waveform */ void set_waveform(uint8_t wavetype) { //0==square, 1==triangle, 2=sin /* Stop the current note */ quiet(); /* Toggle the waveform */ if (waveform != wavetype) { waveform = wavetype; } else { waveform = 0; } /* Continue the current note */ start_note(); }
void microbit_music_tick(void) { if (async_music_state == ASYNC_MUSIC_STATE_IDLE) { // nothing to do return; } if (ticks < async_music_wait_ticks) { // need to wait for timeout to expire return; } if (async_music_state == ASYNC_MUSIC_STATE_ARTICULATE) { // turn off output and rest async_music_pin->setAnalogValue(0); async_music_wait_ticks = ticks + ARTICULATION_MS; async_music_state = ASYNC_MUSIC_STATE_NEXT_NOTE; } else if (async_music_state == ASYNC_MUSIC_STATE_NEXT_NOTE) { // play next note if (async_music_notes_index >= async_music_notes_len) { if (async_music_loop) { async_music_notes_index = 0; } else { async_music_state = ASYNC_MUSIC_STATE_IDLE; return; } } mp_obj_t note = async_music_notes_items[async_music_notes_index]; if (note == mp_const_none) { // a rest (is this even used anymore?) async_music_pin->setAnalogValue(0); async_music_wait_ticks = 60000 / music_state.bpm; async_music_state = ASYNC_MUSIC_STATE_NEXT_NOTE; } else { // a note mp_uint_t note_len; const char *note_str = mp_obj_str_get_data(note, ¬e_len); uint32_t delay_on = start_note(note_str, note_len, async_music_pin); async_music_wait_ticks = ticks + delay_on; async_music_notes_index += 1; async_music_state = ASYNC_MUSIC_STATE_ARTICULATE; } } }
void processMidiEvent(unsigned char evt0, unsigned char evt1, unsigned char evt2) { if ((evt0 & 0xF0) == MIDI_NOTE_ON) { // if velocity is 0 then fake it as a note off if (evt2 != 0) { start_note(); } else { end_note(); } } if ((evt0 & 0xF0) == MIDI_NOTE_OFF) { end_note(); } else if ((evt0 & 0xF0) == MIDI_CONTROL_CHANGE) { } }
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); } } } }
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; }
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 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; }
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; } }