/* * DISTRHO Cardinal Plugin * Copyright (C) 2021 Filipe Coelho * * 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 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. * * For a full copy of the GNU General Public License see the LICENSE file. */ #pragma once #include "PluginContext.hpp" START_NAMESPACE_DISTRHO // ----------------------------------------------------------------------------------------------------------- struct CardinalAudioDevice : rack::audio::Device { CardinalBasePlugin* const fPlugin; CardinalAudioDevice(CardinalBasePlugin* const plugin) : fPlugin(plugin) {} std::string getName() override { return "Cardinal"; } int getNumInputs() override { return DISTRHO_PLUGIN_NUM_INPUTS; } int getNumOutputs() override { return DISTRHO_PLUGIN_NUM_OUTPUTS; } int getBlockSize() override { return fPlugin->getBufferSize(); } float getSampleRate() override { return fPlugin->getSampleRate(); } std::set getBlockSizes() override { return std::set({ getBlockSize() }); } std::set getSampleRates() override { return std::set({ getSampleRate() }); } void setBlockSize(int) override {} void setSampleRate(float) override {} }; // ----------------------------------------------------------------------------------------------------------- struct CardinalAudioDriver : rack::audio::Driver { CardinalAudioDriver() {} std::string getName() override { return "Plugin Driver"; } std::vector getDeviceIds() override { return std::vector({ 0 }); } int getDefaultDeviceId() override { return 0; } std::string getDeviceName(int) override { return "Plugin Device"; } int getDeviceNumInputs(int) override { return DISTRHO_PLUGIN_NUM_INPUTS; } int getDeviceNumOutputs(int) override { return DISTRHO_PLUGIN_NUM_OUTPUTS; } rack::audio::Device* subscribe(int, rack::audio::Port* const port) override { CardinalPluginContext* const pluginContext = reinterpret_cast(port->context); DISTRHO_SAFE_ASSERT_RETURN(pluginContext != nullptr, nullptr); CardinalBasePlugin* const plugin = reinterpret_cast(pluginContext->plugin); DISTRHO_SAFE_ASSERT_RETURN(plugin != nullptr, nullptr); if (! plugin->canAssignDevice()) throw rack::Exception("Plugin driver only allows one audio device to be used simultaneously"); CardinalAudioDevice* const device = new CardinalAudioDevice(plugin); device->subscribe(port); if (plugin->isActive()) device->onStartStream(); plugin->assignDevice(device); return device; } void unsubscribe(int, rack::audio::Port* const port) override { CardinalAudioDevice* const device = reinterpret_cast(port->device); DISTRHO_SAFE_ASSERT_RETURN(device != nullptr,); CardinalPluginContext* const pluginContext = reinterpret_cast(port->context); DISTRHO_SAFE_ASSERT_RETURN(pluginContext != nullptr,); CardinalBasePlugin* const plugin = reinterpret_cast(pluginContext->plugin); DISTRHO_SAFE_ASSERT_RETURN(plugin != nullptr,); if (plugin->clearDevice(device)) { device->onStopStream(); device->unsubscribe(port); delete device; } } }; // ----------------------------------------------------------------------------------------------------------- struct CardinalMidiInputDevice : rack::midi::InputDevice { CardinalBasePlugin* const fPlugin; rack::midi::Message msg; CardinalMidiInputDevice(CardinalBasePlugin* const plugin) : fPlugin(plugin) { msg.bytes.reserve(0xff); } std::string getName() override { return "Cardinal"; } void handleMessagesFromHost(const MidiEvent* const midiEvents, const uint32_t midiEventCount) { if (subscribed.size() == 0) return; for (uint32_t i=0; i MidiEvent::kDataSize) { data = midiEvent.dataExt; msg.bytes.reserve(midiEvent.size); } else { data = midiEvent.data; } msg.frame = midiEvent.frame; std::memcpy(msg.bytes.data(), data, midiEvent.size); onMessage(msg); } } }; // ----------------------------------------------------------------------------------------------------------- struct CardinalMidiOutputDevice : rack::midi::OutputDevice { CardinalBasePlugin* const fPlugin; CardinalMidiOutputDevice(CardinalBasePlugin* const plugin) : fPlugin(plugin) {} std::string getName() override { return "Cardinal"; } void sendMessage(const rack::midi::Message& message) override { } }; // ----------------------------------------------------------------------------------------------------------- struct CardinalMidiDriver : rack::midi::Driver { CardinalMidiDriver() {} std::string getName() override { return "Plugin Driver"; } std::vector getInputDeviceIds() override { return std::vector({ 0 }); } std::vector getOutputDeviceIds() override { return std::vector({ 0 }); } int getDefaultInputDeviceId() override { return 0; } int getDefaultOutputDeviceId() override { return 0; } std::string getInputDeviceName(int) override { return "Plugin Device"; } std::string getOutputDeviceName(int) override { return "Plugin Device"; } rack::midi::InputDevice* subscribeInput(int, rack::midi::Input* const input) override { CardinalPluginContext* const pluginContext = reinterpret_cast(input->context); DISTRHO_SAFE_ASSERT_RETURN(pluginContext != nullptr, nullptr); CardinalBasePlugin* const plugin = reinterpret_cast(pluginContext->plugin); DISTRHO_SAFE_ASSERT_RETURN(plugin != nullptr, nullptr); CardinalMidiInputDevice* const device = new CardinalMidiInputDevice(plugin); device->subscribe(input); plugin->addMidiInput(device); return device; } rack::midi::OutputDevice* subscribeOutput(int, rack::midi::Output* const output) override { CardinalPluginContext* const pluginContext = reinterpret_cast(output->context); DISTRHO_SAFE_ASSERT_RETURN(pluginContext != nullptr, nullptr); CardinalBasePlugin* const plugin = reinterpret_cast(pluginContext->plugin); DISTRHO_SAFE_ASSERT_RETURN(plugin != nullptr, nullptr); CardinalMidiOutputDevice* const device = new CardinalMidiOutputDevice(plugin); device->subscribe(output); return device; } void unsubscribeInput(int, rack::midi::Input* const input) override { CardinalMidiInputDevice* const device = reinterpret_cast(input->device); DISTRHO_SAFE_ASSERT_RETURN(device != nullptr,); CardinalPluginContext* const pluginContext = reinterpret_cast(input->context); DISTRHO_SAFE_ASSERT_RETURN(pluginContext != nullptr,); CardinalBasePlugin* const plugin = reinterpret_cast(pluginContext->plugin); DISTRHO_SAFE_ASSERT_RETURN(plugin != nullptr,); plugin->removeMidiInput(device); device->unsubscribe(input); delete device; } void unsubscribeOutput(int, rack::midi::Output* const output) override { CardinalMidiOutputDevice* const device = reinterpret_cast(output->device); DISTRHO_SAFE_ASSERT_RETURN(device != nullptr,); device->unsubscribe(output); delete device; } }; // ----------------------------------------------------------------------------------------------------------- END_NAMESPACE_DISTRHO