summaryrefslogtreecommitdiffstats
path: root/CheapSynth_SeqMode_v0_9_0.ino
diff options
context:
space:
mode:
Diffstat (limited to 'CheapSynth_SeqMode_v0_9_0.ino')
-rw-r--r--CheapSynth_SeqMode_v0_9_0.ino300
1 files changed, 0 insertions, 300 deletions
diff --git a/CheapSynth_SeqMode_v0_9_0.ino b/CheapSynth_SeqMode_v0_9_0.ino
deleted file mode 100644
index b6bbbc2..0000000
--- a/CheapSynth_SeqMode_v0_9_0.ino
+++ /dev/null
@@ -1,300 +0,0 @@
-// CheapSynth "sequencer" mode 2013 - quite clumsily stuck (by Dave Green) on top of
-// "A very simple MIDI synth."
-// Greg Kennedy 2011
-// http://forum.arduino.cc/index.php?topic=79326.0
-//
-// You should be able to spot the note arrays further down, and can use the modulation MIDI control
-// to adjust the "modulation depth" (ie how grainy the notes sound)
-//
-// Other controls: Program Up + Down = change tempo
-// Continue = "Pause"
-
-#include <avr/pgmspace.h>
-
-#include <MozziGuts.h>
-#include <Oscil.h>
-#include <tables/cos256_int8.h> // table for Oscils to play
-#include <tables/saw256_int8.h> // table for Oscils to play
-#include <tables/square_analogue512_int8.h> // table for Oscils to play
-#include <mozzi_midi.h> // for mtof
-
-#define CONTROL_RATE 128 // powers of 2 please
-
-// Mozzi example uses COS waves for carrier and modulator
-// gets brutal very fast if you use a saw/square carrier
-// gets subtly more brutal if you use smaller wavetables (fewer samples per cycle)
-Oscil<SQUARE_ANALOGUE512_NUM_CELLS, AUDIO_RATE> oscCarrier(SQUARE_ANALOGUE512_DATA);
-Oscil<COS256_NUM_CELLS, AUDIO_RATE> oscModulator(COS256_DATA);
-
-int midiNotes[] = {
-//these are MIDI note values, ie 12 = C, 24 = next C up
-//NB note values of 25+ currently considered as absolute (ie don't change with keypress)
-/*
-16,16,28,28,16,16,26,28,//lee coombs
-16,16,28,28,16,16,26,28,
-16,16,28,28,16,16,26,28,
-16,16,28,28,16,16,26,28,
-*/
-//octaves - blue mon, hung up, erasure? etc
-12,24,12,24,12,24,12,24,12,24,12,24,12,24,12,24,
-12,24,12,24,12,24,12,24,12,24,12,24,12,24,12,24,
-
-//descending bass (eg Bowie's Heroes)
-24,24,21,19,24,24,21,19,24,24,21,19,24,24,21,19,
-24,24,21,19,24,24,21,19,24,24,21,19,24,24,21,19,
-
-//different accented octaves (similar to OMD's Enola Gay)
-12,12,24,12,12,24,12,24,
-12,12,24,12,12,24,12,24,
-12,12,24,12,12,24,12,24,
-12,12,24,12,12,24,12,24,
-
-/// 12/8 shuffle rhythm (eg Muse)
-12,12,24,12,12,24,12,12,24,12,12,24,
-12,12,24,12,12,24,12,12,24,12,12,24,
-};
-
-int modOffsets[] = {
-/*
-//lee C
-12, 12, 12, 12, 12, 19, 12, 12,
-12, 12, 12, 12, 12, 19, 12, 12,
-12, 12, 12, 12, 12, 19, 12, 12,
-12, 12, 12, 12, 12, 19, 12, 12,
-*/
-12, 12, 12, 12, 12, 12, 12, 12, //octaves
-12, 12, 12, 12, 12, 12, 12, 12,
-12, 12, 12, 12, 12, 12, 12, 12,
-12, 12, 12, 12, 12, 12, 12, 12,
-
-// here I'm using different modulation offsets to distinguish between adjacent notes
-// (probably also easy to devise a system to play a rest (ie amplitude=0) if note value=0??
-0,12,0,0,12,0,0,0,0,12,0,0,12,0,0,0,//descending bass
-0,12,0,0,12,0,0,0,0,12,0,0,12,0,0,0,
-
-0,12,0,0,12,0,0,0,0,12,0,0,12,0,0,0,//accented octaves
-0,12,0,0,12,0,0,0,0,12,0,0,12,0,0,0,
-
-12, 12, 12, 12, 12, 12, 12, 12, // shuffle
-12, 12, 12, 12, 12, 12, 12, 12,
-12, 12, 12, 12, 12, 12, 12, 12,
-12, 12, 12, 12, 12, 12, 12, 12,
-};
-
-//float modDepths[] = {
-// 0, 1, 3, 0.5, 6, 2, 1, 2,
-// 0.5, 8, 3, 0.5, 2, 2, 1, 0.125
-//};
-
-float note = 24;
-int lastByte;
-float bendByte =50;
-
-int tuneOffset = 0;
-int tickLengthConverter = 26;
-int arraySize = 32;
-int controlTick = 0;
-int arrayIndex = 0;
-int sequenced;
-int playflag = 1;
-
-float carrierFreq = 10.f;
-float modFreq = 10.f;
-float bendRead = 10.f;
-long modDepth = 1;
-
-float amplitude = 1.f;
-
-void setParams(){
- // mtof converts MIDI note range to Hz freq
-sequenced=midiNotes[arrayIndex + (arraySize*tuneOffset)];
-
-if (sequenced<25) {sequenced += note; } else {sequenced += 36; }
-//if (tuneOffset >0) {sequenced -= 12; }
-
-carrierFreq = mtof(sequenced);
-
-// FM harmonics are most musical when modulator's @ simple musical offsets from carrier
-// EG +12 semitones (1 oct), -24 semitones (-2 oct), +19 semitones (+1 octave and a fifth)
-modFreq = mtof( ( sequenced + modOffsets[arrayIndex+ (arraySize*tuneOffset)] ) );
-
-// I like to make modulation depth (in Hz) some ratio of the carrier's freq
-// That way, the perceived intensity of the FM is the same throughout the note range
-// modDepth = (long) 6;
-bendRead=(bendByte / 30);
-modDepth = (long) carrierFreq * bendRead * bendRead; // 7 was good
-
- // Set oscillator frequencies
- oscCarrier.setFreq(carrierFreq);
- oscModulator.setFreq(modFreq);
-}
-
-// Move on to the next note
-void incrementIndexes(){
- arrayIndex ++;
- int sizelimit=arraySize-1;
-
-//Sample code on how to view what's going on
-Serial.end();
-Serial.begin(115200);
-Serial.print(" arrayIndex:");
-Serial.println( arrayIndex
- );
-Serial.println();
-Serial.end();
-Serial.begin(31250);
-
-if (tuneOffset==3) {sizelimit = 23;} // hack to allow patterns of different length
-if(arrayIndex>sizelimit){
- arrayIndex = 0;
- }
-}
-
-// NOW BACK TO YOUR REGULARLY SCHEDULED MIDI SCAN - comments by Greg Kennedy 2011
-
-#define statusLed 13
-#define tonePin 8
-
-// MIDI channel to answer to, 0x00 - 0x0F
-#define myChannel 0x00
-// set to TRUE and the device will respond to all channels
-#define respondAllChannels true
-
-// midi commands
-#define MIDI_CMD_NOTE_OFF 0x80
-#define MIDI_CMD_NOTE_ON 0x90
-#define MIDI_CMD_KEY_PRESSURE 0xA0
-#define MIDI_CMD_CONTROLLER_CHANGE 0xB0
-#define MIDI_CMD_PROGRAM_CHANGE 0xC0
-#define MIDI_CMD_CHANNEL_PRESSURE 0xD0
-#define MIDI_CMD_PITCH_BEND 0xB0
-
-// this is a placeholder: there are
-// in fact real midi commands from F0-FF which
-// are not channel specific.
-// this simple synth will just ignore those though.
-#define MIDI_CMD_SYSEX 0xF0
-
-// a dummy "ignore" state for commands which
-// we wish to ignore.
-#define MIDI_IGNORE 0x00
-
-// midi "state" - which data byte we are receiving
-#define MIDI_STATE_BYTE1 0x00
-#define MIDI_STATE_BYTE2 0x01
-
-// MIDI note to frequency
-// This isn't exact and may sound a bit detuned at lower notes, because
-// the floating point values have been rounded to uint16.
-// Based on A440 tuning.
-
-// I would prefer to use the typedef for this (prog_uint16_t), but alas that triggers a gcc bug
-// and does not put anything into the flash memory.
-
-// Also note the limitations of tone() which at 16mhz specifies a minimum frequency of 31hz - in other words, notes below
-// B0 will play at the wrong frequency since the timer can't run that slowly!
-uint16_t frequency[128] PROGMEM = {8, 9, 9, 10, 10, 11, 12, 12, 13, 14, 15, 15, 16, 17, 18, 19, 21, 22, 23, 24, 26, 28, 29, 31, 33, 35, 37, 39, 41, 44, 46, 49, 52, 55, 58, 62, 65, 69, 73, 78, 82, 87, 92, 98, 104, 110, 117, 123, 131, 139, 147, 156, 165, 175, 185, 196, 208, 220, 233, 247, 262, 277, 294, 311, 330, 349, 370, 392, 415, 440, 466, 494, 523, 554, 587, 622, 659, 698, 740, 784, 831, 880, 932, 988, 1047, 1109, 1175, 1245, 1319, 1397, 1480, 1568, 1661, 1760, 1865, 1976, 2093, 2217, 2349, 2489, 2637, 2794, 2960, 3136, 3322, 3520, 3729, 3951, 4186, 4435, 4699, 4978, 5274, 5588, 5920, 5920, 6645, 7040, 7459, 7902, 8372, 8870, 9397, 9956, 10548, 11175, 11840, 12544};
-
-//setup: declaring iputs and outputs and begin serial
-void setup() {
- startMozzi(CONTROL_RATE);
-
- pinMode(statusLed,OUTPUT); // declare the LED's pin as output
-
- pinMode(tonePin,OUTPUT); // setup tone output pin
-
- //start serial with midi baudrate 31250
- // or 38400 for debugging (eg MIDI over serial from PC)
- Serial.begin(31250);
-
- // indicate we are ready to receive data!
- digitalWrite(statusLed,HIGH);
-}
-
-//loop: wait for serial data - DG: in hindsight, this should really go in updateControl()
-// (impressed that it even works this way round!)
-void loop () {
- audioHook();
- static byte lastCommand = MIDI_IGNORE;
- static byte state;
-
- while (Serial.available()) {
-
- // read the incoming byte:
- byte incomingByte = Serial.read();
-
- // Command byte?
- if (incomingByte & 0b10000000) {
- if (respondAllChannels ||
- (incomingByte & 0x0F) == myChannel) { // See if this is our channel
-
- if (incomingByte==0xFC) {tuneOffset--; {if (tuneOffset<0) tuneOffset=3;} }
- if (incomingByte==0xFA) {tuneOffset++; {if (tuneOffset>3) tuneOffset=0;} }
- if (incomingByte==0xFB) {playflag++; {if (playflag>1) playflag=0;} }
-
- lastCommand = incomingByte & 0xF0;
- } else { // Not our channel. Ignore command.
- lastCommand = MIDI_IGNORE;
- }
- state = MIDI_STATE_BYTE1; // Reset our state to byte1.
- } else if (state == MIDI_STATE_BYTE1) { // process first data byte
- if ( lastCommand==MIDI_CMD_NOTE_OFF )
- { // if we received a "note off", make sure that is what is currently playing
- if (note == incomingByte) noTone(tonePin);
- state = MIDI_STATE_BYTE2; // expect to receive a velocity byte
- } else if ( lastCommand == MIDI_CMD_NOTE_ON ){ // if we received a "note on", we wait for the note (databyte)
- lastByte=incomingByte; // save the current note
- state = MIDI_STATE_BYTE2; // expect to receive a velocity byte
- }
- // implement whatever further commands you want here
- else if ( lastCommand == MIDI_CMD_PITCH_BEND ){
- bendByte=incomingByte; // save the current note
- state = MIDI_STATE_BYTE1; // expect to receive a velocity byte
- }
-
- else if ( lastCommand == MIDI_CMD_PROGRAM_CHANGE )
- {
-tickLengthConverter = 31 - (incomingByte % 32);
-
- // save the current note
- state = MIDI_STATE_BYTE1; // expect to receive a velocity byte
- }
-
-
- } else { // process second data byte
- if (lastCommand == MIDI_CMD_NOTE_ON) {
- if (incomingByte != 0) {
- note = lastByte;
-// tone(tonePin,(unsigned int)pgm_read_word(&frequency[note]));
-// NB ToneMIDISynth generally good for diagnosing MIDI activity
-// setParams();
- } else if (note == lastByte) {
- noTone(tonePin);
- }
- }
- state = MIDI_STATE_BYTE1; // message data complete
- // This should be changed for SysEx
- }
- }
-}
-
-void updateControl(){
- if(controlTick == 0)
- {
- setParams();
- incrementIndexes();
- }
-
- // Update controlTick
- controlTick +=playflag;
-
- if(controlTick > tickLengthConverter)
- {
- controlTick = 0;
- }
-}
-
-int updateAudio(){
- long vibrato = modDepth * oscModulator.next();
- return (int) (oscCarrier.phMod(vibrato)) * amplitude;
-}