103 lines
2.6 KiB
C++
103 lines
2.6 KiB
C++
#pragma once
|
|
|
|
#include <memory>
|
|
#include <functional>
|
|
#include <unordered_map>
|
|
|
|
#include "nodelib/basics.h"
|
|
|
|
#include "data/node.h"
|
|
|
|
namespace Xybrid::Data {
|
|
class CommandPort;
|
|
class AudioPort;
|
|
}
|
|
|
|
namespace Xybrid::NodeLib {
|
|
/*!
|
|
* \class InstrumentCore
|
|
*
|
|
* Helper class to form the core of an instrument node.
|
|
*
|
|
* Not mandatory by any means, but handles all the "standard" commands for you.
|
|
*/
|
|
class InstrumentCore {
|
|
double time;
|
|
double smpTime;
|
|
|
|
public:
|
|
class Note {
|
|
friend class InstrumentCore;
|
|
void* intern = nullptr;
|
|
public:
|
|
uint16_t id;
|
|
double note; // floating point to allow smooth pitch bends
|
|
double time = 0;
|
|
|
|
double volume = 1.0;
|
|
double pan = 0.0;
|
|
|
|
ADSR adsr;
|
|
|
|
double adsrTime = 0;
|
|
uint8_t adsrPhase = 0;
|
|
|
|
std::array<double, 5> scratch{0.0};
|
|
|
|
Note() = default;
|
|
Note(uint16_t id);
|
|
|
|
double ampMult() const;
|
|
};
|
|
|
|
class Tween {
|
|
friend class InstrumentCore;
|
|
public:
|
|
uint16_t noteId;
|
|
|
|
int16_t ticksLeft = -1;
|
|
|
|
uint8_t flags = 0;
|
|
|
|
double timeStart = 0.0;
|
|
double timeEnd = 0.0;
|
|
double valStart = 0.0;
|
|
double valEnd = 0.0;
|
|
|
|
double* op;
|
|
|
|
Tween(Note&, double*, double val, double time, int16_t ticks = -1);
|
|
|
|
void startTick(Note&, double tickTime);
|
|
void process(Note&);
|
|
};
|
|
|
|
std::unordered_map<uint16_t, Note> activeNotes;
|
|
std::unordered_multimap<uint16_t, Tween> activeTweens;
|
|
|
|
std::function<void(Note&, Data::AudioPort*)> processNote;
|
|
std::function<void(Note&)> onNoteOn;
|
|
std::function<void(Note&)> onNoteLegato;
|
|
std::function<void(Note&, bool)> onNoteOff;
|
|
std::function<void(Note&)> onDeleteNote;
|
|
|
|
InstrumentCore() = default;
|
|
|
|
inline double globalTime() const { return time; }
|
|
inline double sampleTime() const { return smpTime; }
|
|
|
|
void reset();
|
|
void process(Data::Node*);
|
|
void process(Data::CommandPort*, Data::AudioPort* = nullptr);
|
|
void advanceNote(Note&);
|
|
void deleteNote(Note&);
|
|
|
|
/// Removes tweens matching the specified note and target.
|
|
void removeTweens(Note&, double*);
|
|
/// Removes all tweens matching the specified note.
|
|
void removeTweens(Note&);
|
|
Tween& startTween(Note&, double*, double val, double time, int16_t ticks = -1);
|
|
|
|
};
|
|
}
|