static bool PlayTrackItem(MIDI_MusicTrack *track, unsigned int currTimeMs, uint8_t channel) { uint32_t beatsPerSecond = 2; /* 120 bpm */ uint32_t currentMillis; uint32_t ppqn; /* ticks per beat/quarter note */ uint32_t tempo = 110; uint8_t event; unsigned int itemNo; ppqn = track->nofTicksPerQuarterNote; for(;;) { /* breaks */ itemNo = track->currLine; if (itemNo>=track->nofLines) { /* out of list */ return FALSE; /* do not continue any more */ } currentMillis = ((uint32_t)track->lines[itemNo].beat*1000UL)/beatsPerSecond; currentMillis += ((uint32_t)track->lines[itemNo].tick*60000UL)/ppqn/tempo; if (currentMillis>currTimeMs) { return TRUE; /* continue */ } event = track->lines[itemNo].event; switch(event) { case MIDI_BANK: VS1_MIDI_SetBank(channel, track->lines[itemNo].val1); break; case MIDI_NOTE_ON: if (track->lines[itemNo].val2==0) { /* note on with velocity zero is a note off */ VS1_MIDI_NoteOff(channel, track->lines[itemNo].val1, 0); } else { VS1_MIDI_NoteOn(channel, track->lines[itemNo].val1, track->lines[itemNo].val2); } break; case MIDI_NOTE_OFF: VS1_MIDI_NoteOff(channel, track->lines[itemNo].val1, track->lines[itemNo].val2); break; case MIDI_PATCH: VS1_MIDI_SetInstrument(channel, track->lines[itemNo].val1); break; case MIDI_VOLUME: VS1_MIDI_SetVolume(channel, track->lines[itemNo].val1); break; case MIDI_PAN: VS1_MIDI_SetPan(channel, track->lines[itemNo].val1); break; case MIDI_END_OF_TRACK: VS1_MIDI_AllSoundOff(channel); break; } track->currLine++; } /* for */ return TRUE; }
static void PlayMIDI(void) { int instrument, note; VS1_MIDI_SetBank(0, 0); for(instrument=0; instrument<127; instrument++) { VS1_MIDI_SetInstrument(0, instrument); for(note=30; note<40; note++) { VS1_MIDI_NoteOn(0, note, 127); FRTOS1_vTaskDelay(200/portTICK_RATE_MS); VS1_MIDI_NoteOff(0, note, 127); FRTOS1_vTaskDelay(50/portTICK_RATE_MS); } FRTOS1_vTaskDelay(100/portTICK_RATE_MS); } }