/* Haarnet.h - Friction Music library Copyright (c) 2014 Science Friction. All right reserved. This library is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser Public License as published by the Free Software Foundation, either version 3 of the License, or (at your optionosc1modShape_ptr) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser Public License for more details. You should have received a copy of the GNU Lesser Public License along with Foobar. If not, see . +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + author: gauthiier + contact: d@gauthiier.info */ #include "Sequencer.h" #include #include MSequencer Sequencer; iSequencer iSeq; // instrument sequencer //extern iSeq; //int iSeq0,iSeq1; //iSeq.iSeqInit(120); IntervalTimer sequencerTimer; IntervalTimer iSeqTimer; boolean sequencerTimerRunning = false; boolean iSeqTimerRunning = false; #ifndef SAMPLE_RATE unsigned int sampleRate = 48000; #endif void sequencer_isr(void) { if(sequencerTimerRunning) Sequencer.clock(); } void iSeq_isr(void) { iSeq.clockTick++; } void MSequencer::init(int bpm) { setbpm(bpm); midiClock = false; for(int i = 0; i < MAX_SEQ; i++) { _sequences[i] = NULL; } if(!sequencerTimerRunning) { sequencerTimerRunning = true; clockTick = 0; sequencerTimer.begin(sequencer_isr, 60.0 * 1000000.0 / (float(_bpm * TICKS_PER_QUARTER_NOTE))); } } void iSequencer::init(int bpm) { for(int i = 0; i < ISEQ_NBR_STEPS; i++) { // _notes[i] = i; // _velocity[i] = 127; // _CCnumbers[i] = 100; // _CCvalues[i] = 0; } setbpm(bpm); for(int i = 0; i < INSTR_SEQ; i++) { _sequences[i] = NULL; } if(!iSeqTimerRunning) { iSeqTimerRunning = true; clockTick = 0; iSeqTimer.begin(iSeq_isr, 60.0 * 1000000.0 / (float(_bpm * TICKS_PER_QUARTER_NOTE))); } } // // int iSeq_indx0 = 0; // int iSeq_indx1 = 0; //#define ISEQ_NBR_STEPS 32 // const int iSeq_nbr_notes = 32; // const int iSeq_nbr_steps = 32; // // int iSeq_notes[ISEQ_NBR_STEPS]; // int iSeq_velocity[ISEQ_NBR_STEPS]; // int iSeq_midi_numbers[ISEQ_NBR_STEPS]; // int iSeq_midi_values[ISEQ_NBR_STEPS]; // // void iSeqNote() { // // Music.noteOn(iSeq_notes[iSeq_indx0++] + Music.notePlayed, Music.velocityPlayed); // // if(iSeq_indx0 >= iSeq_nbr_notes) iSeq_indx0 = 0; // } // // void iSeqController() { // // Midi.controller(MIDI_CHANNEL - 1, iSeq_midi_numbers[iSeq_indx1], iSeq_midi_values[iSeq_indx1]); // // iSeq_indx1++; // // if(iSeq_indx1 >= iSeq_nbr_steps) iSeq_indx1 = 0; // } // // for(int i = 0; i < ISEQ_NBR_STEPS; i++) { // // iSeq_notes[i] = i; // // iSeq_velocity[i] = 127; // // iSeq_midi_numbers[i] = 100; // // iSeq_midi_values[i] = 0; // } void MSequencer::clock() { clockTick++; } void MSequencer::setMidiClock(bool c) { midiClock = c; } void MSequencer::update() { for(int i = 0; i < MAX_SEQ; i++) { seq* s = _sequences[i]; if(s == NULL || s->_stopped) continue; if(clockTick >= s -> step) { //boom! s->_callback(); // add to queue??? s->step += s -> _subdiv; // Serial.println(s -> step); } } // queue goes here } void MSequencer::start() { clockTick = 0; for(int i = 0; i < MAX_SEQ; i++) { seq* s = _sequences[i]; if(s == NULL || s->_stopped) continue; if(clockTick >= s -> step) { //boom! s->_callback(); // add to queue??? s->step += s -> _subdiv; // Serial.println(s -> step); } } sequencerTimerRunning = true; } void MSequencer::continue() { sequencerTimerRunning = true; } void MSequencer::stop() { sequencerTimerRunning = false; } void iSequencer::update() { for(int i = 0; i < INSTR_SEQ; i++) { iseq* s = _sequences[i]; if(s == NULL || s->_stopped) continue; if(clockTick >= s -> step) { //boom! // s->_callback(); // add to queue??? s->step += s -> _subdiv; // Serial.println(s -> step); } } // queue goes here } int MSequencer::newSequence(func_cb cb, SUBDIV subdiv) { int j = -1; for(int i = 0; i < MAX_SEQ; i++) { if(_sequences[i] == NULL) j = i; } if(j >= 0) { seq* s = new seq(j, cb, subdiv); _sequences[j] = s; Serial.print("Created sequence "); Serial.println(j); } return j; } int iSequencer::newSequence(SUBDIV subdiv, int steps, SEQ_LOOP_TYPE loop) { int j = -1; for(int i = 0; i < MAX_SEQ; i++) { if(_sequences[i] == NULL) j = i; } if(j >= 0) { iseq* s = new iseq(j, subdiv, steps, loop); _sequences[j] = s; Serial.print("Created sequence "); Serial.println(j); } return j; } bool MSequencer::stopSequence(int index) { if(index >= 0 && index < MAX_SEQ) { _sequences[index]->_stopped = true; // _sequences[index]-> step = 0; return true; } return false; } bool MSequencer::startSequence(int index) { if(index >= 0 && index < MAX_SEQ && _sequences[index] != NULL) { _sequences[index]->_stopped = false; _sequences[index]-> step = 0; return true; } return false; } void MSequencer::setbpm(int bpm) { _bpm = bpm; _bpmInclockTicks = _bpm * 24; } int MSequencer::getbpm() { return _bpm; } void iSequencer::setbpm(int bpm) { _bpm = bpm; _bpmInclockTicks = _bpm * 24; } int iSequencer::getbpm() { return _bpm; } bool MSequencer::setSequenceSubdiv(int index, SUBDIV subdiv) { if(index >= 0 && index < MAX_SEQ && _sequences[index] != NULL) { _sequences[index]->setsubdiv(subdiv); return true; } return false; } int MSequencer::getSequenceSubdiv(int index) { if(index >= 0 && index < MAX_SEQ && _sequences[index] != NULL) { return _sequences[index]->getsubdiv(); } return -1; } bool MSequencer::setCallback(int index, func_cb cb) { if(index >= 0 && index < MAX_SEQ && _sequences[index] != NULL) { _sequences[index]->callback(cb); return true; } return false; } func_cb MSequencer::getCallback(int index) { if(index >= 0 && index < MAX_SEQ && _sequences[index] != NULL) { return _sequences[index]->_callback; } return NULL; } // seq seq::seq(int id, func_cb cb, SUBDIV subdiv) : _id(id), _stopped(true) { setsubdiv(subdiv); callback(cb); } void seq::setsubdiv(SUBDIV v) { _subdiv = v; } SUBDIV seq::getsubdiv() { return _subdiv; } void seq::callback(func_cb cb) { _callback = cb; } // iseq iseq::iseq(int id, SUBDIV subdiv, int steps, SEQ_LOOP_TYPE loop) : _id(id), _stopped(true) { setsubdiv(subdiv); setsteps(steps); setlooptype(loop); } void iseq::setsteps(int steps) { _steps = steps; } int iseq::getsteps() { return _steps; } void iseq::setsubdiv(SUBDIV v) { _subdiv = v; } SUBDIV iseq::getsubdiv() { return _subdiv; } void iseq::setlooptype(SEQ_LOOP_TYPE loop) { _loop = loop; } SEQ_LOOP_TYPE iseq::getlooptype() { return _loop; }