// Copyright (c) 2022-2023 Robin Davies // // Permission is hereby granted, free of charge, to any person obtaining a copy of // this software and associated documentation files (the "Software"), to deal in // the Software without restriction, including without limitation the rights to // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of // the Software, and to permit persons to whom the Software is furnished to do so, // subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #pragma once #include "JackConfiguration.hpp" #include "Lv2Pedalboard.hpp" #include "VuUpdate.hpp" #include "json.hpp" #include "AudioHost.hpp" #include "JackServerSettings.hpp" #include #include "PiPedalAlsa.hpp" #include "Promise.hpp" #include "json_variant.hpp" #include "RealtimeMidiEventType.hpp" namespace pipedal { struct RealtimeMidiProgramRequest; struct RealtimeNextMidiProgramRequest; using PortMonitorCallback = std::function; class MonitorPortUpdate { public: PortMonitorCallback *callbackPtr; // pointer because function<>'s probably aren't POD. int64_t subscriptionHandle; float value; }; class RealtimePatchPropertyRequest { public: int64_t clientId; int64_t instanceId; LV2_URID uridUri; enum class RequestType { PatchGet, PatchSet }; RequestType requestType; std::function onPatchRequestComplete; std::function onSuccess; std::function onError; const char*errorMessage = nullptr; std::string jsonResponse; RealtimePatchPropertyRequest *pNext = nullptr; void SetSize(size_t size) { responseLength = size; if (responseLength > sizeof(atomBuffer)) { longAtomBuffer.resize(size); } } size_t GetSize() const { return responseLength; } uint8_t *GetBuffer() { if (responseLength > sizeof(atomBuffer)) { return &(longAtomBuffer[0]); } return atomBuffer; } private: int responseLength = 0; uint8_t atomBuffer[2048]; std::vector longAtomBuffer; public: RealtimePatchPropertyRequest( std::function onPatchRequestcomplete_, int64_t clientId_, int64_t instanceId_, LV2_URID uridUri_, std::function onSuccess_, std::function onError_ ) : onPatchRequestComplete(onPatchRequestcomplete_), clientId(clientId_), instanceId(instanceId_), uridUri(uridUri_), onSuccess(onSuccess_), onError(onError_) { requestType = RequestType::PatchGet; } RealtimePatchPropertyRequest( std::function onPatchRequestcomplete_, int64_t clientId_, int64_t instanceId_, LV2_URID uridUri_, LV2_Atom*atomValue, std::function onSuccess_, std::function onError_ ) : onPatchRequestComplete(onPatchRequestcomplete_), clientId(clientId_), instanceId(instanceId_), uridUri(uridUri_), onSuccess(onSuccess_), onError(onError_) { requestType = RequestType::PatchSet; size_t size = atomValue->size+ sizeof(LV2_Atom); SetSize(size); memcpy(GetBuffer(),atomValue,size); } }; class MonitorPortSubscription { public: int64_t subscriptionHandle; int64_t instanceid; std::string key; float updateInterval; PortMonitorCallback onUpdate; }; class IAudioHostCallbacks { public: virtual void OnNotifyLv2StateChanged(uint64_t instanceId) = 0; virtual void OnNotifyMaybeLv2StateChanged(uint64_t instanceId) = 0; virtual void OnNotifyVusSubscription(const std::vector & updates) = 0; virtual void OnNotifyMonitorPort(const MonitorPortUpdate &update) = 0; virtual void OnNotifyMidiValueChanged(int64_t instanceId, int portIndex, float value) = 0; virtual void OnNotifyMidiListen(bool isNote, uint8_t noteOrControl) = 0; virtual void OnPatchSetReply(uint64_t instanceId, LV2_URID patchSetProperty, const LV2_Atom*atomValue) = 0; //virtual bool WantsAtomOutput(uint64_t instanceId,LV2_URID patchSetProperty) = 0; //virtual void OnNotifyPatchProperty(uint64_t instanceId, LV2_URID patchSetProperty, const std::string&atomJson) = 0; virtual void OnNotifyMidiProgramChange(RealtimeMidiProgramRequest&midiProgramRequest) = 0; virtual void OnNotifyNextMidiProgram(const RealtimeNextMidiProgramRequest&request) = 0; virtual void OnNotifyLv2RealtimeError(int64_t instanceId,const std::string &error) = 0; virtual void OnNotifyMidiRealtimeEvent(RealtimeMidiEventType eventType) = 0; }; class JackHostStatus { public: bool active_ = false; std::string errorMessage_; bool restarting_; uint64_t underruns_; float cpuUsage_ = 0; uint64_t msSinceLastUnderrun_ = 0; int32_t temperaturemC_ = -100000; uint64_t cpuFreqMax_ = 0; uint64_t cpuFreqMin_ = 0; std::string governor_; DECLARE_JSON_MAP(JackHostStatus); }; class IHost; class AudioHost { protected: AudioHost() { } public: static AudioHost*CreateInstance(IHost *pHost); virtual ~AudioHost() { }; virtual void UpdateServerConfiguration(const JackServerSettings & jackServerSettings, std::function onComplete) = 0; virtual void SetNotificationCallbacks(IAudioHostCallbacks *pNotifyCallbacks) = 0; virtual void SetListenForMidiEvent(bool listen) = 0; virtual void SetListenForAtomOutput(bool listen) = 0; virtual bool UpdatePluginStates(Pedalboard& pedalboard) = 0; virtual bool UpdatePluginState(PedalboardItem& pedalboardItem) = 0; virtual std::string AtomToJson(const LV2_Atom*atom) = 0; virtual void Open(const JackServerSettings&jackServerSettings,const JackChannelSelection & channelSelection) = 0; virtual void Close() = 0; virtual uint32_t GetSampleRate() = 0; virtual JackConfiguration GetServerConfiguration() = 0; virtual void SetPedalboard(const std::shared_ptr &pedalboard) = 0; virtual void SetControlValue(uint64_t instanceId,const std::string&symbol, float value) = 0; virtual void SetInputVolume(float value) = 0; virtual void SetOutputVolume(float value) = 0; virtual void SetPluginPreset(uint64_t instanceId, const std::vector &values) = 0; virtual void SetBypass(uint64_t instanceId, bool enabled) = 0; virtual bool IsOpen() const = 0; virtual void SetVuSubscriptions(const std::vector &instanceIds) = 0; virtual void SetMonitorPortSubscriptions(const std::vector &subscriptions) = 0; virtual void SetSystemMidiBindings(const std::vector&bindings) = 0; virtual void sendRealtimeParameterRequest(RealtimePatchPropertyRequest*pParameterRequest) = 0; virtual void AckMidiProgramRequest(uint64_t requestId) = 0; virtual JackHostStatus getJackStatus() = 0; }; } //namespace pipedal.