Testing Tool for Board written.
This commit is contained in:
BIN
main/libraries/MIDI/examples/.DS_Store
vendored
Normal file
BIN
main/libraries/MIDI/examples/.DS_Store
vendored
Normal file
Binary file not shown.
27
main/libraries/MIDI/examples/MIDI_Basic_IO/MIDI_Basic_IO.ino
Normal file
27
main/libraries/MIDI/examples/MIDI_Basic_IO/MIDI_Basic_IO.ino
Normal file
@@ -0,0 +1,27 @@
|
||||
#include <MIDI.h>
|
||||
|
||||
// Simple tutorial on how to receive and send MIDI messages.
|
||||
// Here, when receiving any message on channel 4, the Arduino
|
||||
// will blink a led and play back a note for 1 second.
|
||||
|
||||
MIDI_CREATE_DEFAULT_INSTANCE();
|
||||
|
||||
#define LED 13 // LED pin on Arduino Uno
|
||||
|
||||
void setup()
|
||||
{
|
||||
pinMode(LED, OUTPUT);
|
||||
MIDI.begin(4); // Launch MIDI and listen to channel 4
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (MIDI.read()) // If we have received a message
|
||||
{
|
||||
digitalWrite(LED,HIGH);
|
||||
MIDI.sendNoteOn(42,127,1); // Send a Note (pitch 42, velo 127 on channel 1)
|
||||
delay(1000); // Wait for a second
|
||||
MIDI.sendNoteOff(42,0,1); // Stop the note
|
||||
digitalWrite(LED,LOW);
|
||||
}
|
||||
}
|
||||
85
main/libraries/MIDI/examples/MIDI_Bench/MIDI_Bench.ino
Normal file
85
main/libraries/MIDI/examples/MIDI_Bench/MIDI_Bench.ino
Normal file
@@ -0,0 +1,85 @@
|
||||
#include <MIDI.h>
|
||||
|
||||
// This program will measure the time needed to receive, parse and process a
|
||||
// NoteOn message.
|
||||
// For it to work, please connect RX and TX on the MIDI port:
|
||||
// Due, Leonardo and other USB-native Arduinos: Serial1
|
||||
// All other Arduinos: Connect pins 2 and 3.
|
||||
// The program will then wait for 100 loops and print the results.
|
||||
|
||||
#if defined(ARDUINO_SAM_DUE) || defined(USBCON)
|
||||
// Print through USB and bench with Hardware serial
|
||||
MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, midiBench);
|
||||
#else
|
||||
#include <SoftwareSerial.h>
|
||||
SoftwareSerial midiSerial(2,3);
|
||||
MIDI_CREATE_INSTANCE(SoftwareSerial, midiSerial, midiBench);
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
unsigned long gTime_start = 0;
|
||||
unsigned long gTime_stop = 0;
|
||||
unsigned gCounter = 0;
|
||||
unsigned long gTime_sum = 0;
|
||||
unsigned long gTime_min = -1;
|
||||
unsigned long gTime_max = 0;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void handleNoteOn(byte inChannel, byte inNote, byte inVelocity)
|
||||
{
|
||||
gTime_stop = micros();
|
||||
|
||||
const unsigned long diff = gTime_stop - gTime_start;
|
||||
gTime_sum += diff;
|
||||
|
||||
if (diff > gTime_max) gTime_max = diff;
|
||||
if (diff < gTime_min) gTime_min = diff;
|
||||
|
||||
if (gCounter++ >= 1000)
|
||||
{
|
||||
const unsigned long average = gTime_sum / (float)gCounter;
|
||||
|
||||
Serial.println("Time to receive NoteOn: ");
|
||||
|
||||
Serial.print("Average: ");
|
||||
Serial.print(average);
|
||||
Serial.println(" microsecs");
|
||||
|
||||
Serial.print("Min: ");
|
||||
Serial.print(gTime_min);
|
||||
Serial.println(" microsecs");
|
||||
|
||||
Serial.print("Max: ");
|
||||
Serial.print(gTime_max);
|
||||
Serial.println(" microsecs");
|
||||
|
||||
gCounter = 0;
|
||||
gTime_sum = 0;
|
||||
gTime_max = 0;
|
||||
gTime_min = -1;
|
||||
|
||||
midiBench.turnThruOff();
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void setup()
|
||||
{
|
||||
midiBench.setHandleNoteOn(handleNoteOn);
|
||||
midiBench.begin();
|
||||
|
||||
while(!Serial);
|
||||
Serial.begin(115200);
|
||||
Serial.println("Arduino Ready");
|
||||
|
||||
midiBench.sendNoteOn(69,127,1);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
gTime_start = micros();
|
||||
midiBench.read();
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
#include <MIDI.h>
|
||||
|
||||
MIDI_CREATE_DEFAULT_INSTANCE();
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// This function will be automatically called when a NoteOn is received.
|
||||
// It must be a void-returning function with the correct parameters,
|
||||
// see documentation here:
|
||||
// http://arduinomidilib.fortyseveneffects.com/a00022.html
|
||||
|
||||
void handleNoteOn(byte channel, byte pitch, byte velocity)
|
||||
{
|
||||
// Do whatever you want when a note is pressed.
|
||||
|
||||
// Try to keep your callbacks short (no delays ect)
|
||||
// otherwise it would slow down the loop() and have a bad impact
|
||||
// on real-time performance.
|
||||
}
|
||||
|
||||
void handleNoteOff(byte channel, byte pitch, byte velocity)
|
||||
{
|
||||
// Do something when the note is released.
|
||||
// Note that NoteOn messages with 0 velocity are interpreted as NoteOffs.
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void setup()
|
||||
{
|
||||
// Connect the handleNoteOn function to the library,
|
||||
// so it is called upon reception of a NoteOn.
|
||||
MIDI.setHandleNoteOn(handleNoteOn); // Put only the name of the function
|
||||
|
||||
// Do the same for NoteOffs
|
||||
MIDI.setHandleNoteOff(handleNoteOff);
|
||||
|
||||
// Initiate MIDI communications, listen to all channels
|
||||
MIDI.begin(MIDI_CHANNEL_OMNI);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Call MIDI.read the fastest you can for real-time performance.
|
||||
MIDI.read();
|
||||
|
||||
// There is no need to check if there are messages incoming
|
||||
// if they are bound to a Callback function.
|
||||
// The attached method will be called automatically
|
||||
// when the corresponding message has been received.
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
#include <MIDI.h>
|
||||
|
||||
// This example shows how to create two instances of the library to create a merger.
|
||||
// There are two MIDI couples of IO, A and B, each using thru and merging with the
|
||||
// input from the other node. The result is the following:
|
||||
// A out = A in + B in
|
||||
// B out = B in + A in
|
||||
|
||||
#ifdef ARDUINO_SAM_DUE
|
||||
MIDI_CREATE_INSTANCE(HardwareSerial, Serial, midiA);
|
||||
MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, midiB);
|
||||
#else
|
||||
#include <SoftwareSerial.h>
|
||||
SoftwareSerial softSerial(2,3);
|
||||
MIDI_CREATE_INSTANCE(HardwareSerial, Serial, midiA);
|
||||
MIDI_CREATE_INSTANCE(SoftwareSerial, softSerial, midiB);
|
||||
#endif
|
||||
|
||||
void setup()
|
||||
{
|
||||
// Initiate MIDI communications, listen to all channels
|
||||
midiA.begin(MIDI_CHANNEL_OMNI);
|
||||
midiB.begin(MIDI_CHANNEL_OMNI);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (midiA.read())
|
||||
{
|
||||
// Thru on A has already pushed the input message to out A.
|
||||
// Forward the message to out B as well.
|
||||
midiB.send(midiA.getType(),
|
||||
midiA.getData1(),
|
||||
midiA.getData2(),
|
||||
midiA.getChannel());
|
||||
}
|
||||
|
||||
if (midiB.read())
|
||||
{
|
||||
// Thru on B has already pushed the input message to out B.
|
||||
// Forward the message to out A as well.
|
||||
midiA.send(midiB.getType(),
|
||||
midiB.getData1(),
|
||||
midiB.getData2(),
|
||||
midiB.getChannel());
|
||||
}
|
||||
}
|
||||
49
main/libraries/MIDI/examples/MIDI_Input/MIDI_Input.ino
Normal file
49
main/libraries/MIDI/examples/MIDI_Input/MIDI_Input.ino
Normal file
@@ -0,0 +1,49 @@
|
||||
#include <MIDI.h>
|
||||
|
||||
MIDI_CREATE_DEFAULT_INSTANCE();
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// This example shows the old way of checking for input messages.
|
||||
// It's simpler to use the callbacks now, check out the dedicated example.
|
||||
|
||||
#define LED 13 // LED pin on Arduino Uno
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void BlinkLed(byte num) // Basic blink function
|
||||
{
|
||||
for (byte i=0;i<num;i++)
|
||||
{
|
||||
digitalWrite(LED,HIGH);
|
||||
delay(50);
|
||||
digitalWrite(LED,LOW);
|
||||
delay(50);
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void setup()
|
||||
{
|
||||
pinMode(LED, OUTPUT);
|
||||
MIDI.begin(); // Launch MIDI, by default listening to channel 1.
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (MIDI.read()) // Is there a MIDI message incoming ?
|
||||
{
|
||||
switch(MIDI.getType()) // Get the type of the message we caught
|
||||
{
|
||||
case midi::ProgramChange: // If it is a Program Change,
|
||||
BlinkLed(MIDI.getData1()); // blink the LED a number of times
|
||||
// correponding to the program number
|
||||
// (0 to 127, it can last a while..)
|
||||
break;
|
||||
// See the online reference for other message types
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
main/libraries/MIDI/examples/MIDI_SimpleSynth/.DS_Store
vendored
Normal file
BIN
main/libraries/MIDI/examples/MIDI_SimpleSynth/.DS_Store
vendored
Normal file
Binary file not shown.
@@ -0,0 +1,97 @@
|
||||
#include <MIDI.h>
|
||||
#include "noteList.h"
|
||||
#include "pitches.h"
|
||||
|
||||
MIDI_CREATE_DEFAULT_INSTANCE();
|
||||
|
||||
#ifdef ARDUINO_SAM_DUE // Due has no tone function (yet), overriden to prevent build errors.
|
||||
#define tone(...)
|
||||
#define noTone(...)
|
||||
#endif
|
||||
|
||||
// This example shows how to make a simple synth out of an Arduino, using the
|
||||
// tone() function. It also outputs a gate signal for controlling external
|
||||
// analog synth components (like envelopes).
|
||||
|
||||
static const unsigned sGatePin = 13;
|
||||
static const unsigned sAudioOutPin = 10;
|
||||
static const unsigned sMaxNumNotes = 16;
|
||||
MidiNoteList<sMaxNumNotes> midiNotes;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
inline void handleGateChanged(bool inGateActive)
|
||||
{
|
||||
digitalWrite(sGatePin, inGateActive ? HIGH : LOW);
|
||||
}
|
||||
|
||||
inline void pulseGate()
|
||||
{
|
||||
handleGateChanged(false);
|
||||
delay(1);
|
||||
handleGateChanged(true);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void handleNotesChanged(bool isFirstNote = false)
|
||||
{
|
||||
if (midiNotes.empty())
|
||||
{
|
||||
handleGateChanged(false);
|
||||
noTone(sAudioOutPin);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Possible playing modes:
|
||||
// Mono Low: use midiNotes.getLow
|
||||
// Mono High: use midiNotes.getHigh
|
||||
// Mono Last: use midiNotes.getLast
|
||||
|
||||
byte currentNote = 0;
|
||||
if (midiNotes.getLast(currentNote))
|
||||
{
|
||||
tone(sAudioOutPin, sNotePitches[currentNote]);
|
||||
|
||||
if (isFirstNote)
|
||||
{
|
||||
handleGateChanged(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
pulseGate(); // Retrigger envelopes. Remove for legato effect.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void handleNoteOn(byte inChannel, byte inNote, byte inVelocity)
|
||||
{
|
||||
const bool firstNote = midiNotes.empty();
|
||||
midiNotes.add(MidiNote(inNote, inVelocity));
|
||||
handleNotesChanged(firstNote);
|
||||
}
|
||||
|
||||
void handleNoteOff(byte inChannel, byte inNote, byte inVelocity)
|
||||
{
|
||||
midiNotes.remove(inNote);
|
||||
handleNotesChanged();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void setup()
|
||||
{
|
||||
pinMode(sGatePin, OUTPUT);
|
||||
pinMode(sAudioOutPin, OUTPUT);
|
||||
MIDI.setHandleNoteOn(handleNoteOn);
|
||||
MIDI.setHandleNoteOff(handleNoteOff);
|
||||
MIDI.begin();
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
MIDI.read();
|
||||
}
|
||||
21
main/libraries/MIDI/examples/MIDI_SimpleSynth/noteList.cpp
Normal file
21
main/libraries/MIDI/examples/MIDI_SimpleSynth/noteList.cpp
Normal file
@@ -0,0 +1,21 @@
|
||||
/*!
|
||||
* \file synth-core_NoteList.h
|
||||
* \author Francois Best
|
||||
* \date 24/05/2013
|
||||
* \license GPL v3.0 - Copyright Forty Seven Effects 2013
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "noteList.h"
|
||||
391
main/libraries/MIDI/examples/MIDI_SimpleSynth/noteList.h
Normal file
391
main/libraries/MIDI/examples/MIDI_SimpleSynth/noteList.h
Normal file
@@ -0,0 +1,391 @@
|
||||
/*!
|
||||
* \file noteList.h
|
||||
* \author Francois Best
|
||||
* \date 24/05/2013
|
||||
* \brief Linked list of notes, for Low, Last & High playing modes.
|
||||
* \license GPL v3.0 - Copyright Forty Seven Effects 2013
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
typedef uint8_t byte;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
struct MidiNote
|
||||
{
|
||||
inline MidiNote();
|
||||
inline MidiNote(byte inPitch, byte inVelocity);
|
||||
inline MidiNote(const MidiNote& inOther);
|
||||
inline MidiNote& operator= (const MidiNote& inOther);
|
||||
|
||||
byte pitch;
|
||||
byte velocity;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
template<byte Size>
|
||||
class MidiNoteList
|
||||
{
|
||||
private:
|
||||
struct Cell
|
||||
{
|
||||
inline Cell();
|
||||
inline Cell(const Cell& inOther);
|
||||
inline Cell& operator= (const Cell& inOther);
|
||||
|
||||
MidiNote note;
|
||||
bool active;
|
||||
Cell* next;
|
||||
Cell* prev;
|
||||
};
|
||||
|
||||
public:
|
||||
inline MidiNoteList();
|
||||
inline ~MidiNoteList();
|
||||
|
||||
public:
|
||||
inline void add(const MidiNote& inNote);
|
||||
inline void remove(byte inPitch);
|
||||
|
||||
public:
|
||||
inline bool get(byte inIndex, byte& outPitch) const;
|
||||
inline bool getLast(byte& outPitch) const;
|
||||
inline bool getHigh(byte& outPitch) const;
|
||||
inline bool getLow(byte& outPitch) const;
|
||||
|
||||
public:
|
||||
inline bool empty() const;
|
||||
inline byte size() const;
|
||||
|
||||
private:
|
||||
inline Cell* getFirstEmptyCell();
|
||||
inline void print() const;
|
||||
|
||||
private:
|
||||
Cell mArray[Size];
|
||||
Cell* mHead;
|
||||
Cell* mTail;
|
||||
byte mSize;
|
||||
};
|
||||
|
||||
// ########################################################################## //
|
||||
// Inline implementation
|
||||
|
||||
inline MidiNote::MidiNote()
|
||||
: pitch(0)
|
||||
, velocity(0)
|
||||
{
|
||||
}
|
||||
|
||||
inline MidiNote::MidiNote(byte inPitch, byte inVelocity)
|
||||
: pitch(inPitch)
|
||||
, velocity(inVelocity)
|
||||
{
|
||||
}
|
||||
|
||||
inline MidiNote::MidiNote(const MidiNote& inOther)
|
||||
: pitch(inOther.pitch)
|
||||
, velocity(inOther.velocity)
|
||||
{
|
||||
}
|
||||
|
||||
inline MidiNote& MidiNote::operator= (const MidiNote& inOther)
|
||||
{
|
||||
pitch = inOther.pitch;
|
||||
velocity = inOther.velocity;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ########################################################################## //
|
||||
|
||||
template<byte Size>
|
||||
inline MidiNoteList<Size>::Cell::Cell()
|
||||
: note()
|
||||
, active(false)
|
||||
, next(0)
|
||||
, prev(0)
|
||||
{
|
||||
}
|
||||
|
||||
template<byte Size>
|
||||
inline MidiNoteList<Size>::Cell::Cell(const Cell& inOther)
|
||||
: note(inOther.note)
|
||||
, active(inOther.active)
|
||||
, next(inOther.next)
|
||||
, prev(inOther.prev)
|
||||
{
|
||||
}
|
||||
|
||||
template<byte Size>
|
||||
inline typename MidiNoteList<Size>::Cell& MidiNoteList<Size>::Cell::operator= (const Cell& inOther)
|
||||
{
|
||||
note = inOther.note;
|
||||
active = inOther.active;
|
||||
next = inOther.next;
|
||||
prev = inOther.prev;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ########################################################################## //
|
||||
|
||||
template<byte Size>
|
||||
inline MidiNoteList<Size>::MidiNoteList()
|
||||
{
|
||||
}
|
||||
|
||||
template<byte Size>
|
||||
inline MidiNoteList<Size>::~MidiNoteList()
|
||||
{
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/*! \brief Add a note, sorting it by time.
|
||||
Call this when receiving a NoteOn event. This will add the new note as the tail
|
||||
of the list.
|
||||
*/
|
||||
template<byte Size>
|
||||
inline void MidiNoteList<Size>::add(const MidiNote& inNote)
|
||||
{
|
||||
if (mHead == 0)
|
||||
{
|
||||
mArray[0].note = inNote;
|
||||
mArray[0].active = true;
|
||||
mArray[0].next = 0;
|
||||
mArray[0].prev = 0;
|
||||
mHead = mArray;
|
||||
mTail = mArray;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Find the first inactive cell, and use it as tail.
|
||||
Cell* const oldTail = mTail;
|
||||
Cell* const newTail = getFirstEmptyCell();
|
||||
|
||||
newTail->active = true;
|
||||
newTail->note = inNote;
|
||||
|
||||
oldTail->next = newTail;
|
||||
newTail->prev = oldTail;
|
||||
newTail->next = 0;
|
||||
mTail = newTail;
|
||||
}
|
||||
mSize++;
|
||||
print();
|
||||
}
|
||||
|
||||
/*! \brief Remove a note
|
||||
Call this when receiving a NoteOff event.
|
||||
*/
|
||||
template<byte Size>
|
||||
inline void MidiNoteList<Size>::remove(byte inPitch)
|
||||
{
|
||||
if (mTail != 0)
|
||||
{
|
||||
for (Cell* it = mTail; it != 0; it = it->prev)
|
||||
{
|
||||
if (it->note.pitch == inPitch)
|
||||
{
|
||||
Cell* const prev = it->prev;
|
||||
Cell* const next = it->next;
|
||||
|
||||
it->active = false;
|
||||
it->next = 0;
|
||||
it->prev = 0;
|
||||
|
||||
// Reconnect both ends
|
||||
if (it == mHead)
|
||||
{
|
||||
//AVR_ASSERT(prev == 0);
|
||||
mHead = next;
|
||||
}
|
||||
else
|
||||
{
|
||||
//AVR_ASSERT(prev != 0);
|
||||
prev->next = next;
|
||||
}
|
||||
|
||||
if (it == mTail)
|
||||
{
|
||||
//AVR_ASSERT(next == 0);
|
||||
mTail = prev;
|
||||
}
|
||||
else
|
||||
{
|
||||
//AVR_ASSERT(next != 0);
|
||||
next->prev = prev;
|
||||
}
|
||||
|
||||
mSize--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
print();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/*! \brief Get a note at an arbitrary position
|
||||
This can be interesting for duo/multi/polyphony operations.
|
||||
*/
|
||||
template<byte Size>
|
||||
inline bool MidiNoteList<Size>::get(byte inIndex, byte& outPitch) const
|
||||
{
|
||||
if (mTail)
|
||||
{
|
||||
const Cell* it = mTail;
|
||||
for (byte i = 0; i < inIndex; ++i)
|
||||
{
|
||||
if (it->prev)
|
||||
{
|
||||
it = it->prev;
|
||||
}
|
||||
}
|
||||
|
||||
print();
|
||||
//AVR_LOG("Index " << inIndex << ": " << it->note.pitch);
|
||||
|
||||
outPitch = it->note.pitch;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*! \brief Get the last active note played
|
||||
This implements the Mono Last playing mode.
|
||||
*/
|
||||
template<byte Size>
|
||||
inline bool MidiNoteList<Size>::getLast(byte& outPitch) const
|
||||
{
|
||||
if (!mTail)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
outPitch = mTail->note.pitch;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*! \brief Get the highest pitched active note
|
||||
This implements the Mono High playing mode.
|
||||
*/
|
||||
template<byte Size>
|
||||
inline bool MidiNoteList<Size>::getHigh(byte& outPitch) const
|
||||
{
|
||||
if (!mTail)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
outPitch = 0;
|
||||
const Cell* it = mTail;
|
||||
for (byte i = 0; i < mSize; ++i)
|
||||
{
|
||||
if (it->note.pitch > outPitch)
|
||||
{
|
||||
outPitch = it->note.pitch;
|
||||
}
|
||||
|
||||
if (it->prev)
|
||||
{
|
||||
it = it->prev;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*! \brief Get the lowest pitched active note
|
||||
This implements the Mono Low playing mode.
|
||||
*/
|
||||
template<byte Size>
|
||||
inline bool MidiNoteList<Size>::getLow(byte& outPitch) const
|
||||
{
|
||||
if (!mTail)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
outPitch = 0xff;
|
||||
const Cell* it = mTail;
|
||||
for (byte i = 0; i < mSize; ++i)
|
||||
{
|
||||
if (it->note.pitch < outPitch)
|
||||
{
|
||||
outPitch = it->note.pitch;
|
||||
}
|
||||
|
||||
if (it->prev)
|
||||
{
|
||||
it = it->prev;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
template<byte Size>
|
||||
inline bool MidiNoteList<Size>::empty() const
|
||||
{
|
||||
return mSize == 0;
|
||||
}
|
||||
|
||||
/*! \brief Get the number of active notes.
|
||||
*/
|
||||
template<byte Size>
|
||||
inline byte MidiNoteList<Size>::size() const
|
||||
{
|
||||
return mSize;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Private implementations, for internal use only.
|
||||
|
||||
template<byte Size>
|
||||
inline typename MidiNoteList<Size>::Cell* MidiNoteList<Size>::getFirstEmptyCell()
|
||||
{
|
||||
for (byte i = 0; i < Size; ++i)
|
||||
{
|
||||
if (mArray[i].active == false)
|
||||
{
|
||||
return mArray + i;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<byte Size>
|
||||
inline void MidiNoteList<Size>::print() const
|
||||
{
|
||||
//#ifndef NDEBUG
|
||||
// AVR_DBG("Note List: [ ");
|
||||
// if (mHead)
|
||||
// {
|
||||
// for (const Cell* it = mHead; it != 0; it = it->next)
|
||||
// {
|
||||
// AVR_DBG(it->note.pitch);
|
||||
// if (it->next)
|
||||
// AVR_DBG(" -> ");
|
||||
// }
|
||||
// }
|
||||
// AVR_LOG(" ]");
|
||||
//#endif
|
||||
}
|
||||
108
main/libraries/MIDI/examples/MIDI_SimpleSynth/pitches.h
Normal file
108
main/libraries/MIDI/examples/MIDI_SimpleSynth/pitches.h
Normal file
@@ -0,0 +1,108 @@
|
||||
/*************************************************
|
||||
* Public Constants
|
||||
*************************************************/
|
||||
#include <inttypes.h>
|
||||
|
||||
#define NOTE_B0 31
|
||||
#define NOTE_C1 33
|
||||
#define NOTE_CS1 35
|
||||
#define NOTE_D1 37
|
||||
#define NOTE_DS1 39
|
||||
#define NOTE_E1 41
|
||||
#define NOTE_F1 44
|
||||
#define NOTE_FS1 46
|
||||
#define NOTE_G1 49
|
||||
#define NOTE_GS1 52
|
||||
#define NOTE_A1 55
|
||||
#define NOTE_AS1 58
|
||||
#define NOTE_B1 62
|
||||
#define NOTE_C2 65
|
||||
#define NOTE_CS2 69
|
||||
#define NOTE_D2 73
|
||||
#define NOTE_DS2 78
|
||||
#define NOTE_E2 82
|
||||
#define NOTE_F2 87
|
||||
#define NOTE_FS2 93
|
||||
#define NOTE_G2 98
|
||||
#define NOTE_GS2 104
|
||||
#define NOTE_A2 110
|
||||
#define NOTE_AS2 117
|
||||
#define NOTE_B2 123
|
||||
#define NOTE_C3 131
|
||||
#define NOTE_CS3 139
|
||||
#define NOTE_D3 147
|
||||
#define NOTE_DS3 156
|
||||
#define NOTE_E3 165
|
||||
#define NOTE_F3 175
|
||||
#define NOTE_FS3 185
|
||||
#define NOTE_G3 196
|
||||
#define NOTE_GS3 208
|
||||
#define NOTE_A3 220
|
||||
#define NOTE_AS3 233
|
||||
#define NOTE_B3 247
|
||||
#define NOTE_C4 262
|
||||
#define NOTE_CS4 277
|
||||
#define NOTE_D4 294
|
||||
#define NOTE_DS4 311
|
||||
#define NOTE_E4 330
|
||||
#define NOTE_F4 349
|
||||
#define NOTE_FS4 370
|
||||
#define NOTE_G4 392
|
||||
#define NOTE_GS4 415
|
||||
#define NOTE_A4 440
|
||||
#define NOTE_AS4 466
|
||||
#define NOTE_B4 494
|
||||
#define NOTE_C5 523
|
||||
#define NOTE_CS5 554
|
||||
#define NOTE_D5 587
|
||||
#define NOTE_DS5 622
|
||||
#define NOTE_E5 659
|
||||
#define NOTE_F5 698
|
||||
#define NOTE_FS5 740
|
||||
#define NOTE_G5 784
|
||||
#define NOTE_GS5 831
|
||||
#define NOTE_A5 880
|
||||
#define NOTE_AS5 932
|
||||
#define NOTE_B5 988
|
||||
#define NOTE_C6 1047
|
||||
#define NOTE_CS6 1109
|
||||
#define NOTE_D6 1175
|
||||
#define NOTE_DS6 1245
|
||||
#define NOTE_E6 1319
|
||||
#define NOTE_F6 1397
|
||||
#define NOTE_FS6 1480
|
||||
#define NOTE_G6 1568
|
||||
#define NOTE_GS6 1661
|
||||
#define NOTE_A6 1760
|
||||
#define NOTE_AS6 1865
|
||||
#define NOTE_B6 1976
|
||||
#define NOTE_C7 2093
|
||||
#define NOTE_CS7 2217
|
||||
#define NOTE_D7 2349
|
||||
#define NOTE_DS7 2489
|
||||
#define NOTE_E7 2637
|
||||
#define NOTE_F7 2794
|
||||
#define NOTE_FS7 2960
|
||||
#define NOTE_G7 3136
|
||||
#define NOTE_GS7 3322
|
||||
#define NOTE_A7 3520
|
||||
#define NOTE_AS7 3729
|
||||
#define NOTE_B7 3951
|
||||
#define NOTE_C8 4186
|
||||
#define NOTE_CS8 4435
|
||||
#define NOTE_D8 4699
|
||||
#define NOTE_DS8 4978
|
||||
|
||||
static const uint16_t sNotePitches[] = {
|
||||
NOTE_B0, NOTE_C1, NOTE_CS1, NOTE_D1, NOTE_DS1, NOTE_E1, NOTE_F1, NOTE_FS1,
|
||||
NOTE_G1, NOTE_GS1, NOTE_A1, NOTE_AS1, NOTE_B1, NOTE_C2, NOTE_CS2, NOTE_D2,
|
||||
NOTE_DS2, NOTE_E2, NOTE_F2, NOTE_FS2, NOTE_G2, NOTE_GS2, NOTE_A2, NOTE_AS2,
|
||||
NOTE_B2, NOTE_C3, NOTE_CS3, NOTE_D3, NOTE_DS3, NOTE_E3, NOTE_F3, NOTE_FS3,
|
||||
NOTE_G3, NOTE_GS3, NOTE_A3, NOTE_AS3, NOTE_B3, NOTE_C4, NOTE_CS4, NOTE_D4,
|
||||
NOTE_DS4, NOTE_E4, NOTE_F4, NOTE_FS4, NOTE_G4, NOTE_GS4, NOTE_A4, NOTE_AS4,
|
||||
NOTE_B4, NOTE_C5, NOTE_CS5, NOTE_D5, NOTE_DS5, NOTE_E5, NOTE_F5, NOTE_FS5,
|
||||
NOTE_G5, NOTE_GS5, NOTE_A5, NOTE_AS5, NOTE_B5, NOTE_C6, NOTE_CS6, NOTE_D6,
|
||||
NOTE_DS6, NOTE_E6, NOTE_F6, NOTE_FS6, NOTE_G6, NOTE_GS6, NOTE_A6, NOTE_AS6,
|
||||
NOTE_B6, NOTE_C7, NOTE_CS7, NOTE_D7, NOTE_DS7, NOTE_E7, NOTE_F7, NOTE_FS7,
|
||||
NOTE_G7, NOTE_GS7, NOTE_A7, NOTE_AS7, NOTE_B7, NOTE_C8, NOTE_CS8, NOTE_D8, NOTE_DS8,
|
||||
};
|
||||
Reference in New Issue
Block a user