Hendrik Langer
5 years ago
3 changed files with 0 additions and 530 deletions
@ -1,21 +0,0 @@ |
|||||
/*!
|
|
||||
* \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" |
|
@ -1,391 +0,0 @@ |
|||||
/*!
|
|
||||
* \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
|
|
||||
} |
|
@ -1,118 +0,0 @@ |
|||||
/*************************************************
|
|
||||
* 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 |
|
||||
#define NOTE_E8 5274 |
|
||||
#define NOTE_F8 5588 |
|
||||
#define NOTE_FS8 5920 |
|
||||
#define NOTE_G8 6272 |
|
||||
#define NOTE_GS8 6645 |
|
||||
#define NOTE_A8 7040 |
|
||||
#define NOTE_AS8 7459 |
|
||||
#define NOTE_B8 7902 |
|
||||
|
|
||||
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, NOTE_E8, NOTE_F8, NOTE_FS8, NOTE_G8, NOTE_GS8, NOTE_A8, NOTE_AS8, |
|
||||
NOTE_B8 |
|
||||
}; |
|
Loading…
Reference in new issue