コード例 #1
0
ファイル: seq.c プロジェクト: gillspice/mios32
/////////////////////////////////////////////////////////////////////////////
// Should be called whenever a Note event has been received.
// We expect, that velocity is 0 on a Note Off event
/////////////////////////////////////////////////////////////////////////////
s32 SEQ_NotifyNoteOn(u8 note, u8 velocity)
{
  u8 clear_stack = 0;

  if( velocity )
    // push note into note stack
    NOTESTACK_Push(&notestack, note, velocity);
  else {
    // remove note from note stack
    // function returns 2 if no note played anymore (all keys depressed)
    if( NOTESTACK_Pop(&notestack, note) == 2 )
      clear_stack = 1;
  }

  // At least one note played?
  if( !clear_stack && notestack.len > 0 ) {
    // start sequencer if it isn't already running
    if( !SEQ_BPM_IsRunning() )
      SEQ_BPM_Start();
  } else {
    // clear stack
    NOTESTACK_Clear(&notestack);

    // no key is pressed anymore: stop sequencer
    SEQ_BPM_Stop();
  }


#if 1
  // optional debug messages
  NOTESTACK_SendDebugMessage(&notestack);
#endif

  return 0; // no error
}
コード例 #2
0
ファイル: app.c プロジェクト: JKcompute/395_midi_controller
/////////////////////////////////////////////////////////////////////////////
// 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)
{
  // if note event over MIDI channel #1 controls note of both oscillators
  // Note On received?
  if( midi_package.chn == Chn1 && 
      (midi_package.type == NoteOn || midi_package.type == NoteOff) ) {

    // branch depending on Note On/Off event
    if( midi_package.event == NoteOn && midi_package.velocity > 0 ) {
      // push note into note stack
      NOTESTACK_Push(&notestack, midi_package.note, midi_package.velocity);
    } else {
      // remove note from note stack
      NOTESTACK_Pop(&notestack, midi_package.note);
    }


    // still a note in stack?
    if( notestack.len ) {
      // take first note of stack
      u8 note = notestack_items[0].note;
      u8 velocity = notestack_items[0].tag;

      // set frequency for both oscillators
      int chn;
      for(chn=0; chn<2; ++chn) {
	SYNTH_FrequencySet(chn, frqtab[note]);
	SYNTH_VelocitySet(chn, velocity);
      }

      // set board LED
      MIOS32_BOARD_LED_Set(1, 1);
    } else {
      // turn off LED (can also be used as a gate output!)
      MIOS32_BOARD_LED_Set(1, 0);

      // set velocity to 0 for all oscillators
      int chn;
      for(chn=0; chn<2; ++chn)
	SYNTH_VelocitySet(chn, 0x00);
    }

#if 0
    // optional debug messages
    NOTESTACK_SendDebugMessage(&notestack);
#endif

  // CC#1 over MIDI channel #1 controls waveform
  } else if( midi_package.event == CC && midi_package.chn == Chn1 ) {
    int chn;
    for(chn=0; chn<2; ++chn)
      SYNTH_WaveformSet(chn, midi_package.value >> 5);
    // print selection
    print_msg = PRINT_MSG_SELECTIONS;
  }
コード例 #3
0
ファイル: seq_midi_in.c プロジェクト: gillspice/mios32
/////////////////////////////////////////////////////////////////////////////
// For Section Changes
// If velocity == 0, Note Off event has been received, otherwise Note On event
/////////////////////////////////////////////////////////////////////////////
static s32 SEQ_MIDI_IN_Receive_NoteSC(u8 note, u8 velocity)
{
  int octave = note / 12;
  int octave_taken = 0;

  int group;
  for(group=0; group<4; ++group) {
    if( octave == (seq_midi_in_sect_note[group] / 12) ) {
      octave_taken = 1;
      notestack_t *n = &section_changer_notestack[group];

      int section = -1;
      if( velocity ) { // Note On
	NOTESTACK_Push(n, note, velocity);
	section = n->note_items[0].note % 12;
      } else { // Note Off
	if( NOTESTACK_Pop(n, note) > 0 && n->len ) {
	  section = n->note_items[0].note % 12;
	}
      }

      // switch to new section if required
      if( section >= 0 && section < 12 ) {
#if DEBUG_VERBOSE_LEVEL >= 1
	DEBUG_MSG("Group %d Section %d\n", group, section);
#endif

	// following operation should be atomic!
	u8 track;
	seq_core_trk_t *t = &seq_core_trk[group*SEQ_CORE_NUM_TRACKS_PER_GROUP];
	MIOS32_IRQ_Disable();
	for(track=0; track<SEQ_CORE_NUM_TRACKS_PER_GROUP; ++track, ++t)
	  t->play_section = section;
	MIOS32_IRQ_Enable();
      }

#if DEBUG_VERBOSE_LEVEL >= 1
      DEBUG_MSG("NOTESTACK_SECTION_CHANGER_G%d:\n", group+1);
      NOTESTACK_SendDebugMessage(n);
#endif
    }
  }

  return octave_taken; // return 1 if octave has been taken, otherwise 0
}
コード例 #4
0
ファイル: seq_midi_in.c プロジェクト: gillspice/mios32
static s32 SEQ_MIDI_IN_Receive_NotePC(u8 note, u8 velocity)
{
  int octave = note / 12;
  int octave_taken = 0;

  int group;
  for(group=0; group<4; ++group) {
    if( octave == (seq_midi_in_sect_note[group] / 12) ) {
      octave_taken = 1;
      notestack_t *n = &patch_changer_notestack[group];

      int patch = -1;
      if( velocity ) { // Note On
	NOTESTACK_Push(n, note, velocity);
	patch = n->note_items[0].note % 12;
      } else { // Note Off
	if( NOTESTACK_Pop(n, note) > 0 && n->len ) {
	  patch = n->note_items[0].note % 12;
	}
      }

      // switch to new patch if required
      if( patch >= 0 && patch < 8 ) {
	seq_pattern_t pattern = seq_pattern[group];
	if( pattern.num != patch ) {
	  pattern.num = patch;
	  pattern.DISABLED = 0;
	  pattern.SYNCHED = 0;
	  SEQ_PATTERN_Change(group, pattern);
	}
      }

#if DEBUG_VERBOSE_LEVEL >= 0
      DEBUG_MSG("NOTESTACK_PATCH_CHANGER_G%d:\n", group+1);
      NOTESTACK_SendDebugMessage(n);
#endif
    }
  }

  return octave_taken; // return 1 if octave has been taken, otherwise 0
}
コード例 #5
0
ファイル: seq_midi_in.c プロジェクト: gillspice/mios32
/////////////////////////////////////////////////////////////////////////////
// If velocity == 0, Note Off event has been received, otherwise Note On event
/////////////////////////////////////////////////////////////////////////////
static s32 SEQ_MIDI_IN_Receive_Note(u8 bus, u8 note, u8 velocity)
{
  notestack_t *n;

  if( bus >= SEQ_MIDI_IN_NUM_BUSSES )
    return -1;

  ///////////////////////////////////////////////////////////////////////////
  // Transposer
  ///////////////////////////////////////////////////////////////////////////

  n = &bus_notestack[bus][BUS_NOTESTACK_TRANSPOSER];
  if( velocity ) { // Note On
    NOTESTACK_Push(n, note, velocity);
    transposer_hold_note[bus] = n->note_items[0].note;

    // will only be used for Bus1 and if enabled in OPT menu
    if( bus == 0 )
      seq_core_keyb_scale_root = note % 12;
  } else { // Note Off
    if( NOTESTACK_Pop(n, note) > 0 && n->len ) {
      transposer_hold_note[bus] = n->note_items[0].note;
    }
  }
#if DEBUG_VERBOSE_LEVEL >= 1
  DEBUG_MSG("NOTESTACK_TRANSPOSER[%d]:\n", bus);
  NOTESTACK_SendDebugMessage(&bus_notestack[bus][BUS_NOTESTACK_TRANSPOSER]);
#endif


  ///////////////////////////////////////////////////////////////////////////
  // Arpeggiator
  ///////////////////////////////////////////////////////////////////////////

  if( velocity ) { // Note On
    // if no note in note stack anymore, reset position of all tracks with RESTART flag set
    if( !bus_notestack[bus][BUS_NOTESTACK_ARP_UNSORTED].len ) {
      u8 track;
      for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track)
	if( seq_cc_trk[track].mode.RESTART ) {
	  portENTER_CRITICAL();
	  seq_core_trk[track].state.POS_RESET = 1;
	  portEXIT_CRITICAL();
	}

      // and invalidate hold stacks
      int i;
      for(i=0; i<4; ++i)
	arp_sorted_hold[bus][i].ALL = arp_unsorted_hold[bus][i].ALL = 0;
    }

    // add to stacks
    NOTESTACK_Push(&bus_notestack[bus][BUS_NOTESTACK_ARP_SORTED], note, velocity);
    NOTESTACK_Push(&bus_notestack[bus][BUS_NOTESTACK_ARP_UNSORTED], note, velocity);

    // copy to hold stack
    int i;
    for(i=0; i<4; ++i) {
      arp_unsorted_hold[bus][i].ALL = (i < bus_notestack[bus][BUS_NOTESTACK_ARP_UNSORTED].len) ? bus_notestack[bus][BUS_NOTESTACK_ARP_UNSORTED].note_items[i].ALL : 0;
      arp_sorted_hold[bus][i].ALL = (i < bus_notestack[bus][BUS_NOTESTACK_ARP_SORTED].len) ? bus_notestack[bus][BUS_NOTESTACK_ARP_SORTED].note_items[i].ALL : 0;
    }

  } else { // Note Off
    // remove note from sorted/unsorted stack (not hold stacks)
    NOTESTACK_Pop(&bus_notestack[bus][BUS_NOTESTACK_ARP_SORTED], note);
    NOTESTACK_Pop(&bus_notestack[bus][BUS_NOTESTACK_ARP_UNSORTED], note);
  }

#if DEBUG_VERBOSE_LEVEL >= 1
  DEBUG_MSG("NOTESTACK_ARP_SORTED[%d]:\n", bus);
  NOTESTACK_SendDebugMessage(&bus_notestack[bus][BUS_NOTESTACK_ARP_SORTED]);
  DEBUG_MSG("NOTESTACK_ARP_UNSORTED[%d]:\n", bus);
  NOTESTACK_SendDebugMessage(&bus_notestack[bus][BUS_NOTESTACK_ARP_UNSORTED]);
#endif

  return 0; // no error
}
コード例 #6
0
ファイル: app.c プロジェクト: JKcompute/395_midi_controller
/////////////////////////////////////////////////////////////////////////////
// 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)
{
  // if note event over MIDI channel #1 controls note of both oscillators
  // Note On received?
  if( midi_package.chn == Chn1 && 
      (midi_package.type == NoteOn || midi_package.type == NoteOff) ) {

    // branch depending on Note On/Off event
    if( midi_package.event == NoteOn && midi_package.velocity > 0 ) {
      // push note into note stack
      NOTESTACK_Push(&notestack, midi_package.note, midi_package.velocity);
    } else {
      // remove note from note stack
      NOTESTACK_Pop(&notestack, midi_package.note);
    }


    // still a note in stack?
    if( notestack.len ) {
      // take first note of stack
      u8 note = notestack_items[0].note;
      u8 velocity = notestack_items[0].tag;

#if 0
      // set frequency for both oscillators
      int chn;
      for(chn=0; chn<2; ++chn) {
	SYNTH_FrequencySet(chn, frqtab[note]);
	SYNTH_VelocitySet(chn, velocity);
      }
#endif

      // play note
      int phrase_num = note - PHRASE_NOTE_OFFSET;
      while( phrase_num < 0)
	phrase_num += SYNTH_NUM_PHRASES;
      while( phrase_num > SYNTH_NUM_PHRASES )
	phrase_num -= SYNTH_NUM_PHRASES;

      // legato...
      if( notestack.len == 1 )
	SYNTH_PhraseStop(phrase_num);

      SYNTH_PhrasePlay(phrase_num, velocity);
      
      // set board LED
      MIOS32_BOARD_LED_Set(1, 1);
    } else {
      // turn off LED (can also be used as a gate output!)
      MIOS32_BOARD_LED_Set(1, 0);

#if 0
      // set velocity to 0 for all oscillators
      int chn;
      for(chn=0; chn<2; ++chn)
	SYNTH_VelocitySet(chn, 0x00);
#endif
    }

#if 0
    // optional debug messages
    NOTESTACK_SendDebugMessage(&notestack);
#endif
  } else if( midi_package.type == CC ) {
    u8 phrase_num = 0;
    u8 phoneme_ix = midi_package.chn;
    u32 value = midi_package.value;

    if( midi_package.cc_number < 16 ) {
    } else if( midi_package.cc_number < 32 ) {
      u8 phoneme_par = midi_package.cc_number - 16;
      SYNTH_PhonemeParSet(phrase_num, phoneme_ix, phoneme_par, value);
    } else if( midi_package.cc_number < 48 ) {
      u8 phrase_par = midi_package.cc_number - 32;
      SYNTH_PhraseParSet(phrase_num, phrase_par, value);
    } else if( midi_package.cc_number < 64 ) {
      u8 global_par = midi_package.cc_number - 48;
      SYNTH_GlobalParSet(global_par, value);
    }
  }

}