///////////////////////////////////////////////////////////////////////////// // Initialisation ///////////////////////////////////////////////////////////////////////////// s32 SEQ_Init(u32 mode) { // initialize the Notestack #if 0 NOTESTACK_Init(¬estack, NOTESTACK_MODE_PUSH_TOP, ¬estack_items[0], NOTESTACK_SIZE); #else // for an arpeggiator we prefer sorted mode // activate hold mode as well. Stack will be cleared whenever no note is played anymore NOTESTACK_Init(¬estack, NOTESTACK_MODE_SORT_HOLD, ¬estack_items[0], NOTESTACK_SIZE); #endif // and the arp counter arp_counter = 0; // reset sequencer SEQ_Reset(); // init BPM generator SEQ_BPM_Init(0); SEQ_BPM_PPQN_Set(384); SEQ_BPM_Set(120.0); return 0; // no error }
///////////////////////////////////////////////////////////////////////////// // Resets song position of sequencer ///////////////////////////////////////////////////////////////////////////// s32 SEQ_Reset(u8 play_off_events) { // since timebase has been changed, ensure that Off-Events are played // (otherwise they will be played much later...) if( play_off_events ) SEQ_PlayOffEvents(); // release pause and FFWD mode seq_pause = 0; ffwd_silent_mode = 0; next_prefetch = 0; prefetch_offset = 0; // restart song MID_PARSER_RestartSong(); // set initial BPM (according to MIDI file spec) SEQ_BPM_PPQN_Set(384); // not specified SEQ_BPM_Set(120.0); // reset BPM tick SEQ_BPM_TickSet(0); return 0; // no error }
void Clocks_Init(void) { SEQ_BPM_TickSet(0); // reset sequencer SEQ_BPM_Init(0); // initialize SEQ module sequencer SEQ_BPM_PPQN_Set(VXPPQN); // set internal clock resolution as per the define (usually 384) MClock_SetBPM(100.0); // Master BPM mClock.status.all = 0; // bit 7 is run/stop mClock.ticked = 0; // we haven't gotten that far yet mClock.timesigu = 4; // Upper value of the Master Time Signature, min 2 mClock.timesigl = 4; // Lower value of the Master Time Signature, min 2 mClock.res = SEQ_BPM_PPQN_Get(); // fill this from the SEQ_BPM module to be safe mClock.rt_latency = VXLATENCY; // initialise from define MClock_Init(); // init the vX master clock MClock_Reset(); }
///////////////////////////////////////////////////////////////////////////// // called when a Meta event should be played/processed at a given tick ///////////////////////////////////////////////////////////////////////////// static s32 SEQ_PlayMeta(u8 track, u8 meta, u32 len, u8 *buffer, u32 tick) { switch( meta ) { case 0x00: // Sequence Number if( len == 2 ) { u32 seq_number = (buffer[0] << 8) | buffer[1]; #if DEBUG_VERBOSE_LEVEL >= 2 DEBUG_MSG("[SEQ:%d:%u] Meta - Sequence Number %u\n", track, tick, seq_number); #endif } else { #if DEBUG_VERBOSE_LEVEL >= 2 DEBUG_MSG("[SEQ:%d:%u] Meta - Sequence Number with %d bytes -- ERROR: expecting 2 bytes!\n", track, tick, len); #endif } break; case 0x01: // Text Event #if DEBUG_VERBOSE_LEVEL >= 2 DEBUG_MSG("[SEQ:%d:%u] Meta - Text: %s\n", track, tick, buffer); #endif break; case 0x02: // Copyright Notice #if DEBUG_VERBOSE_LEVEL >= 2 DEBUG_MSG("[SEQ:%d:%u] Meta - Copyright: %s\n", track, tick, buffer); #endif break; case 0x03: // Sequence/Track Name #if DEBUG_VERBOSE_LEVEL >= 2 DEBUG_MSG("[SEQ:%d:%u] Meta - Track Name: %s\n", track, tick, buffer); #endif break; case 0x04: // Instrument Name #if DEBUG_VERBOSE_LEVEL >= 2 DEBUG_MSG("[SEQ:%d:%u] Meta - Instr. Name: %s\n", track, tick, buffer); #endif break; case 0x05: // Lyric #if DEBUG_VERBOSE_LEVEL >= 2 DEBUG_MSG("[SEQ:%d:%u] Meta - Lyric: %s\n", track, tick, buffer); #endif break; case 0x06: // Marker #if DEBUG_VERBOSE_LEVEL >= 2 DEBUG_MSG("[SEQ:%d:%u] Meta - Marker: %s\n", track, tick, buffer); #endif break; case 0x07: // Cue Point #if DEBUG_VERBOSE_LEVEL >= 2 DEBUG_MSG("[SEQ:%d:%u] Meta - Cue Point: %s\n", track, tick, buffer); #endif break; case 0x20: // Channel Prefix if( len == 1 ) { u32 prefix = *buffer; #if DEBUG_VERBOSE_LEVEL >= 2 DEBUG_MSG("[SEQ:%d:%u] Meta - Channel Prefix %u\n", track, tick, prefix); #endif } else { #if DEBUG_VERBOSE_LEVEL >= 2 DEBUG_MSG("[SEQ:%d:%u] Meta - Channel Prefix with %d bytes -- ERROR: expecting 1 byte!\n", track, tick, len); #endif } break; case 0x2f: // End of Track #if DEBUG_VERBOSE_LEVEL >= 2 DEBUG_MSG("[SEQ:%d:%u] Meta - End of Track\n", track, tick, meta); #endif break; case 0x51: // Set Tempo if( len == 3 ) { u32 tempo_us = (buffer[0] << 16) | (buffer[1] << 8) | buffer[2]; float bpm = 60.0 * (1E6 / (float)tempo_us); SEQ_BPM_PPQN_Set(MIDI_PARSER_PPQN_Get()); // set tempo immediately on first tick if( tick == 0 ) { SEQ_BPM_Set(bpm); } else { // put tempo change request into the queue mios32_midi_package_t tempo_package; // or Softis? tempo_package.ALL = (u32)bpm; SEQ_MIDI_OUT_Send(DEFAULT, tempo_package, SEQ_MIDI_OUT_TempoEvent, tick, 0); } #if DEBUG_VERBOSE_LEVEL >= 2 DEBUG_MSG("[SEQ:%d:%u] Meta - Tempo to %u uS -> %u BPM\n", track, tick, tempo_us, (u32)bpm); #endif } else { #if DEBUG_VERBOSE_LEVEL >= 2 DEBUG_MSG("[SEQ:%d:%u] Meta - Tempo with %u bytes -- ERROR: expecting 3 bytes!\n", track, tick, len); #endif } break; // other known events which are not handled here: // 0x54: SMPTE offset // 0x58: Time Signature // 0x59: Key Signature // 0x7f: Sequencer Specific Meta Event #if DEBUG_VERBOSE_LEVEL >= 2 default: DEBUG_MSG("[SEQ:%d:%u] Meta Event 0x%02x with length %u not processed\n", track, tick, meta, len); #endif } return 0; }