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