2019-07-29 02:13:03 +02:00
|
|
|
#pragma once
|
2019-08-05 01:32:01 +02:00
|
|
|
#include "StereoBuffer.h"
|
2019-08-23 01:27:39 +02:00
|
|
|
#include "Globals.h"
|
|
|
|
|
#include "Region.h"
|
2019-08-05 01:32:01 +02:00
|
|
|
#include <atomic>
|
|
|
|
|
#include <memory>
|
2019-07-29 02:13:03 +02:00
|
|
|
|
|
|
|
|
namespace sfz
|
|
|
|
|
{
|
|
|
|
|
class Voice
|
|
|
|
|
{
|
|
|
|
|
public:
|
2019-08-23 01:27:39 +02:00
|
|
|
enum class TriggerType { NoteOn, NoteOff, CC };
|
|
|
|
|
void startVoice(Region* region, int channel, int number, uint8_t value, TriggerType triggerType)
|
|
|
|
|
{
|
|
|
|
|
this->triggerType = triggerType;
|
|
|
|
|
triggerNumber = number;
|
|
|
|
|
triggerChannel = channel;
|
|
|
|
|
triggerValue = value;
|
|
|
|
|
|
|
|
|
|
this->region = region;
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-05 01:32:01 +02:00
|
|
|
void setFileData(std::unique_ptr<StereoBuffer<float>> file)
|
|
|
|
|
{
|
|
|
|
|
fileData = std::move(file);
|
|
|
|
|
dataReady.store(true);
|
|
|
|
|
}
|
2019-08-23 01:27:39 +02:00
|
|
|
|
2019-08-23 14:16:33 +02:00
|
|
|
bool isFree()
|
|
|
|
|
{
|
|
|
|
|
return (region == nullptr);
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-23 20:48:44 +02:00
|
|
|
void registerNoteOff(int delay, int channel, int noteNumber, uint8_t velocity);
|
2019-08-23 01:27:39 +02:00
|
|
|
bool registerCC(int delay, int channel, int ccNumber, uint8_t ccValue);
|
|
|
|
|
void registerPitchWheel(int delay, int channel, int pitch);
|
|
|
|
|
void registerAftertouch(int delay, int channel, uint8_t aftertouch);
|
|
|
|
|
void registerTempo(int delay, float secondsPerQuarter);
|
|
|
|
|
|
|
|
|
|
void prepareToPlay(int samplesPerBlock, double sampleRate);
|
|
|
|
|
void renderBlock(StereoBuffer<float>& buffer)
|
|
|
|
|
{
|
|
|
|
|
buffer.fill(0.0f);
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-23 20:48:44 +02:00
|
|
|
bool checkOffGroup(int delay [[maybe_unused]], uint32_t group) noexcept
|
|
|
|
|
{
|
|
|
|
|
if (region != nullptr && triggerType == TriggerType::NoteOn && region->offBy && *region->offBy == group )
|
|
|
|
|
{
|
|
|
|
|
// TODO: release
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int getTriggerNumber() const
|
|
|
|
|
{
|
|
|
|
|
return triggerNumber;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int getTriggerChannel() const
|
|
|
|
|
{
|
|
|
|
|
return triggerNumber;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint8_t getTriggerValue() const
|
|
|
|
|
{
|
|
|
|
|
return triggerNumber;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TriggerType getTriggerType() const
|
|
|
|
|
{
|
|
|
|
|
return triggerType;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2019-08-23 01:27:39 +02:00
|
|
|
void reset()
|
|
|
|
|
{
|
|
|
|
|
dataReady.store(false);
|
|
|
|
|
}
|
2019-07-29 02:13:03 +02:00
|
|
|
private:
|
2019-08-23 01:27:39 +02:00
|
|
|
Region* region;
|
|
|
|
|
|
|
|
|
|
TriggerType triggerType;
|
|
|
|
|
int triggerNumber;
|
|
|
|
|
int triggerChannel;
|
|
|
|
|
uint8_t triggerValue;
|
|
|
|
|
|
2019-08-05 01:32:01 +02:00
|
|
|
std::atomic<bool> dataReady;
|
|
|
|
|
std::unique_ptr<StereoBuffer<float>> fileData;
|
2019-08-23 01:27:39 +02:00
|
|
|
|
|
|
|
|
int samplesPerBlock { config::defaultSamplesPerBlock };
|
|
|
|
|
double sampleRate { config::defaultSampleRate };
|
2019-07-29 02:13:03 +02:00
|
|
|
};
|
2019-08-23 01:27:39 +02:00
|
|
|
|
2019-07-29 02:13:03 +02:00
|
|
|
}
|