/teensy-quencer

my attemp to make a little sequencer using teensy audio library... work in progress!!!

Primary LanguageC++MIT LicenseMIT

teensyquencer

wip teensy40 Ubuntu-x64

Experimental multi-channel sequencer for teensy

  • each channel has a number of patterns. each pattern has its own length
  • setting next pattern on a channel will take effect once current pattern on that channel is complete.
  • Im using an akai apc40 controller to select patterns for channels - please fork and adapt to your own controller...
  • comming soon - star this repo if you want to see these features
    • midi import and export
    • playing samples at different pitches
    • parameter, midi, audio recording and playback

Audio signal path

dependencies

teensy-quencer on youtube youtube: 10cc - Dreadlock Holiday played on a Teensy 4.0

code

  • define multisequencer:
tempo tempo(120.0f);
multisequencer multisequencer(tempo);
midisequenceadapter adapter(multisequencer); // to read midi files into the a sequencer pattern
  • add sequencer channel(s):
  sequencer *sequencer1 = multisequencer.newSequencer();
  sequencer *sequencer2 = multisequencer.newSequencer();
  • add event callbacks:
  sequencer1->onevent = [] (sequencerevent *event) {
      switch(event->channel) {
        case 0: triggerAudioEvent(event, playSdRaw1, "KICK.WAV"); break;
        case 1: triggerAudioEvent(event, playSdRaw2, "SNARE.WAV"); break;      
        default: break;
      }
  };
  
  sequencer2->onevent = [] (sequencerevent *event) {
      switch(event->channel) {
        case 0: 
          if (event->isNoteStartEvent) {
            sine1.frequency( event->rate * 65.41);
            envelope1.noteOn();
          } else {
            envelope1.noteOff();
          }
        default: break;
      }
  };
  
  • add pattern:
  //                        !               !               !               !      
  const char* pattern4x4 = "X...X...X...X...X...X...X...X...X...X...X...X...X...X...X...X..."; 
  const char* patternSnr = "....x.......x.......x.......x.......x.......x.......x.......x..."; 

  // sequencer1
  pattern *pat = sequencer1->addPattern(4);         // empty pattern: 4 bars;
  
  pat = sequencer1->addPattern(4);                  // empty pattern: 4 bars;
  
  pat = sequencer1->readPattern(pattern4x4, 0, 54); // kick 4x4, channel 0, note 54
 
  // load 'snare.mid' smf into next pattern of sequencer1
  adapter.loadMidi("snare.mid");
  adapter.loadMidifileToNextChannelPattern(0, 0, 8);  // multisequencer channel number=0 (==sequencer1), midi track number=0, 8 bars long
  adapter.close();

  // sequencer2
  pat = sequencer2->addPattern(4); // empty pattern: 4 bars;

  // load 'dredbass.mid' smf into next pattern of sequencer2
  adapter.loadMidi("dredbass.mid");
  adapter.loadMidifileToNextChannelPattern(1, 0, 128, 24); // multisequencer channel number=1 (==sequencer2), midi track number=0, 128 bars long, transpose 24 notes
  adapter.close();