Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
0
/*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();	
}
Ejemplo n.º 4
0
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, &note_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;
        }
    }
}
Ejemplo n.º 5
0
/* 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();
}
Ejemplo n.º 6
0
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, &note_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;
        }
    }
}
Ejemplo n.º 7
0
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)
  {
  }
}
Ejemplo n.º 8
0
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);
            }
        }
    }
}
Ejemplo n.º 9
0
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;
}
Ejemplo n.º 10
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;
}
Ejemplo n.º 11
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;
}
Ejemplo n.º 12
0
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;
    }
}