sfizz/plugins/vst/SfizzVstProcessor.h

117 lines
3.7 KiB
C
Raw Normal View History

2020-03-05 11:16:47 +01:00
// SPDX-License-Identifier: BSD-2-Clause
// This code is part of the sfizz library and is licensed under a BSD 2-clause
// license. You should have receive a LICENSE.md file along with the code.
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
#pragma once
2020-03-05 18:21:46 +01:00
#include "SfizzVstState.h"
#include "sfizz/RTSemaphore.h"
2020-03-28 17:00:07 +01:00
#include "ring_buffer/ring_buffer.h"
2020-03-05 11:16:47 +01:00
#include "public.sdk/source/vst/vstaudioeffect.h"
#include <sfizz.hpp>
2021-02-01 22:51:24 +01:00
#include <SpinMutex.h>
2021-02-23 09:27:20 +01:00
#include <array>
2020-03-05 11:16:47 +01:00
#include <thread>
#include <memory>
2020-03-28 17:00:07 +01:00
#include <cstdlib>
2020-03-05 11:16:47 +01:00
using namespace Steinberg;
class SfizzVstProcessor : public Vst::AudioEffect {
public:
SfizzVstProcessor();
~SfizzVstProcessor();
tresult PLUGIN_API initialize(FUnknown* context) override;
tresult PLUGIN_API setBusArrangements(Vst::SpeakerArrangement* inputs, int32 numIns, Vst::SpeakerArrangement* outputs, int32 numOuts) override;
2021-04-02 04:05:14 +02:00
tresult PLUGIN_API connect(IConnectionPoint* other) override;
2020-03-05 18:21:46 +01:00
tresult PLUGIN_API setState(IBStream* stream) override;
tresult PLUGIN_API getState(IBStream* stream) override;
void syncStateToSynth();
2020-03-05 11:16:47 +01:00
tresult PLUGIN_API canProcessSampleSize(int32 symbolicSampleSize) override;
tresult PLUGIN_API setActive(TBool state) override;
tresult PLUGIN_API process(Vst::ProcessData& data) override;
2020-03-05 18:21:46 +01:00
void processParameterChanges(Vst::IParameterChanges& pc);
void processControllerChanges(Vst::IParameterChanges& pc);
void processEvents(Vst::IEventList& events);
2020-10-19 02:58:01 +02:00
void processMessagesFromUi();
2020-03-05 18:21:46 +01:00
static int convertVelocityFromFloat(float x);
2020-03-05 11:16:47 +01:00
tresult PLUGIN_API notify(Vst::IMessage* message) override;
static FUnknown* createInstance(void*);
static FUID cid;
// --- Sfizz stuff here below ---
private:
2020-03-05 18:21:46 +01:00
// synth state. acquire processMutex before accessing
2020-03-05 11:16:47 +01:00
std::unique_ptr<sfz::Sfizz> _synth;
2021-04-02 04:05:14 +02:00
Steinberg::IPtr<Vst::IMessage> _loadedSfzMessage;
bool _isActive = false;
2020-03-05 18:21:46 +01:00
SfizzVstState _state;
2020-06-20 05:49:00 +02:00
float _currentStretchedTuning = 0;
2020-03-05 18:21:46 +01:00
2020-10-19 02:58:01 +02:00
// client
sfz::ClientPtr _client;
std::unique_ptr<uint8_t[]> _oscTemp;
void receiveMessage(int delay, const char* path, const char* sig, const sfizz_arg_t* args);
2020-06-20 13:01:38 +02:00
// misc
2021-04-02 04:05:14 +02:00
void loadSfzFileOrDefault(const std::string& filePath);
2020-06-20 13:01:38 +02:00
2021-02-23 09:27:20 +01:00
// note event tracking
std::array<float, 128> _noteEventsCurrentCycle; // 0: off, >0: on, <0: no change
2020-03-05 18:21:46 +01:00
// worker and thread sync
2020-03-05 11:16:47 +01:00
std::thread _worker;
volatile bool _workRunning = false;
2020-03-28 17:00:07 +01:00
Ring_Buffer _fifoToWorker;
2020-03-05 11:16:47 +01:00
RTSemaphore _semaToWorker;
2020-10-19 02:58:01 +02:00
Ring_Buffer _fifoMessageFromUi;
2021-02-01 22:51:24 +01:00
SpinMutex _processMutex;
2020-03-05 11:16:47 +01:00
2020-08-11 15:31:23 +02:00
// time info
int _timeSigNumerator = 0;
int _timeSigDenominator = 0;
void updateTimeInfo(const Vst::ProcessContext& context);
2020-03-28 17:00:07 +01:00
// messaging
struct RTMessage {
const char* type;
uintptr_t size;
// 32-bit aligned data after header
template <class T> const T* payload() const;
};
struct RTMessageDelete {
void operator()(RTMessage* x) const noexcept { std::free(x); }
};
typedef std::unique_ptr<RTMessage, RTMessageDelete> RTMessagePtr;
2020-03-05 11:16:47 +01:00
// worker
void doBackgroundWork();
void doBackgroundIdle(size_t idleCounter);
void startBackgroundWork();
2020-03-05 11:16:47 +01:00
void stopBackgroundWork();
2020-03-28 17:00:07 +01:00
// writer
bool writeWorkerMessage(const char* type, const void* data, uintptr_t size);
// reader
RTMessagePtr readWorkerMessage();
bool discardWorkerMessage();
2020-10-19 02:58:01 +02:00
// generic
static bool writeMessage(Ring_Buffer& fifo, const char* type, const void* data, uintptr_t size);
2020-03-05 11:16:47 +01:00
};
2020-03-28 17:00:07 +01:00
//------------------------------------------------------------------------------
template <class T> const T* SfizzVstProcessor::RTMessage::payload() const
{
return reinterpret_cast<const T*>(
reinterpret_cast<const uint8*>(this) + sizeof(*this));
}