Esempio n. 1
0
/////////////////////////////////////////////////////////////////////////////
// Initialisation
/////////////////////////////////////////////////////////////////////////////
s32 SEQ_Init(u32 mode)
{
  // initialize the Notestack
#if 0
  NOTESTACK_Init(&notestack, NOTESTACK_MODE_PUSH_TOP, &notestack_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(&notestack, NOTESTACK_MODE_SORT_HOLD, &notestack_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
}
Esempio n. 2
0
/////////////////////////////////////////////////////////////////////////////
// This hook is called when a MIDI package has been received
/////////////////////////////////////////////////////////////////////////////
void APP_MIDI_NotifyPackage(mios32_midi_port_t port, mios32_midi_package_t midi_package)
{
  // Note On received?
  if( midi_package.type == NoteOn &&
      midi_package.chn == Chn1 &&
      midi_package.velocity > 0 ) {

    // determine base key number (0=C, 1=C#, 2=D, ...)
    u8 base_key = midi_package.note % 12;

    // branch depending on note
    switch( base_key ) {
      case 0: // "C" starts the sequencer
	MIOS32_MIDI_SendDebugMessage("Start\n");
	// if in auto mode and BPM generator is clocked in slave mode:
	// change to master mode
	SEQ_BPM_CheckAutoMaster();
	// start sequencer
	SEQ_BPM_Start();
	break;

      case 2: // "D" stops the sequencer. If pressed twice, the sequencer will be reset
	MIOS32_MIDI_SendDebugMessage("Stop\n");
	if( SEQ_BPM_IsRunning() )
	  SEQ_BPM_Stop();          // stop sequencer
	else
	  SEQ_Reset(1);            // reset sequencer
	break;

      case 4: // "E" pauses the sequencer
	// if in auto mode and BPM generator is clocked in slave mode:
	// change to master mode
	SEQ_BPM_CheckAutoMaster();

	// toggle pause mode
	seq_pause ^= 1;

	MIOS32_MIDI_SendDebugMessage("Pause %s\n", seq_pause ? "on" : "off");

	// execute stop/continue depending on new mode
	if( seq_pause )
	  SEQ_BPM_Stop();         // stop sequencer
	else
	  SEQ_BPM_Cont();         // continue sequencer
	break;

      case 5: // "F" switches to next file
	MIOS32_MIDI_SendDebugMessage("Next File\n");
	SEQ_PlayFileReq(1);
	break;
    }
  }
}
Esempio n. 3
0
/////////////////////////////////////////////////////////////////////////////
// this sequencer handler is called periodically to check for new requests
// from BPM generator
/////////////////////////////////////////////////////////////////////////////
s32 SEQ_Handler(void)
{
  // a lower priority task requested to play the next file
  if( next_file_req ) {
    SEQ_PlayFile(next_file_req-1);
    next_file_req = 0;
  };


  // handle BPM requests
  u8 num_loops = 0;
  u8 again = 0;
  do {
    ++num_loops;

    // note: don't remove any request check - clocks won't be propagated
    // so long any Stop/Cont/Start/SongPos event hasn't been flagged to the sequencer
    if( SEQ_BPM_ChkReqStop() ) {
      SEQ_PlayOffEvents();
    }

    if( SEQ_BPM_ChkReqCont() ) {
      // release pause mode
      seq_pause = 0;
    }

    if( SEQ_BPM_ChkReqStart() ) {
      SEQ_Reset(1);
      SEQ_SongPos(0);
    }

    u16 new_song_pos;
    if( SEQ_BPM_ChkReqSongPos(&new_song_pos) ) {
      SEQ_SongPos(new_song_pos);
    }

    u32 bpm_tick;
    if( SEQ_BPM_ChkReqClk(&bpm_tick) > 0 ) {
      again = 1; // check all requests again after execution of this part

      SEQ_Tick(bpm_tick);
    }
  } while( again && num_loops < 10 );

  return 0; // no error
}
Esempio n. 4
0
/////////////////////////////////////////////////////////////////////////////
// Initialisation
/////////////////////////////////////////////////////////////////////////////
s32 SEQ_Init(u32 mode)
{
  // init MIDI file handler
  MID_FILE_Init(0);

  // init MIDI parser module
  MID_PARSER_Init(0);

  // install callback functions
  MID_PARSER_InstallFileCallbacks(&MID_FILE_read, &MID_FILE_eof, &MID_FILE_seek);
  MID_PARSER_InstallEventCallbacks(&SEQ_PlayEvent, &SEQ_PlayMeta);

  // reset sequencer
  SEQ_Reset(0);

  // init BPM generator
  SEQ_BPM_Init(0);

  return 0; // no error
}
Esempio n. 5
0
/////////////////////////////////////////////////////////////////////////////
// This task is called periodically each mS to handle sequencer requests
/////////////////////////////////////////////////////////////////////////////
static void TASK_SEQ(void *pvParameters)
{
  portTickType xLastExecutionTime;
  u16 sdcard_check_ctr = 0;

  // Initialise the xLastExecutionTime variable on task entry
  xLastExecutionTime = xTaskGetTickCount();

  while( 1 ) {
    vTaskDelayUntil(&xLastExecutionTime, 1 / portTICK_RATE_MS);

    // execute sequencer handler
    SEQ_Handler();

    // send timestamped MIDI events
    SEQ_MIDI_OUT_Handler();

    // each second: check if SD Card (still) available
    if( ++sdcard_check_ctr >= 1000 ) {
      sdcard_check_ctr = 0;

      // use a mutex if multiple tasks access the SD Card!
      MUTEX_SDCARD_TAKE;
      s32 status = FILE_CheckSDCard();

      if( status == 1 ) {
	MIOS32_MIDI_SendDebugMessage("SD Card connected: %s\n", FILE_VolumeLabel());
      } else if( status == 2 ) {
	MIOS32_MIDI_SendDebugMessage("SD Card disconnected\n");

	// stop sequencer
	SEQ_BPM_Stop();

	// change filename
	sprintf(MID_FILE_UI_NameGet(), "No SD Card");
      } else if( status == 3 ) {
	if( !FILE_SDCardAvailable() ) {
	  MIOS32_MIDI_SendDebugMessage("SD Card not found\n");
	  // change filename
	  sprintf(MID_FILE_UI_NameGet(), "No SD Card");
	} else if( !FILE_VolumeAvailable() ) {
	  MIOS32_MIDI_SendDebugMessage("ERROR: SD Card contains invalid FAT!\n");
	  MIOS32_BOARD_LED_Set(0x1, 0x0); // turn off LED
	  // change filename
	  sprintf(MID_FILE_UI_NameGet(), "No FAT");
	  // stop sequencer
	  SEQ_BPM_Stop();
	} else {
	  // change filename
	  sprintf(MID_FILE_UI_NameGet(), "SDCard found");
	  // if in auto mode and BPM generator is clocked in slave mode:
	  // change to master mode
	  SEQ_BPM_CheckAutoMaster();
	  // reset sequencer
	  SEQ_Reset(1);
	  // request to play the first file
	  SEQ_PlayFileReq(0);
	  // start sequencer
	  SEQ_BPM_Start();
	}
      }
      MUTEX_SDCARD_GIVE;
    }
  }
}