@@ -1184,11 +1184,11 @@ static std::list<ExtendedNSVGimage> loadedLightSVGs; | |||||
static inline | static inline | ||||
void nsvg__duplicatePaint(NSVGpaint& dst, NSVGpaint& src) | void nsvg__duplicatePaint(NSVGpaint& dst, NSVGpaint& src) | ||||
{ | { | ||||
if (dst.type == NSVG_PAINT_LINEAR_GRADIENT || dst.type == NSVG_PAINT_RADIAL_GRADIENT) | |||||
if (dst.type == NSVG_PAINT_LINEAR_GRADIENT || dst.type == NSVG_PAINT_RADIAL_GRADIENT) | |||||
{ | { | ||||
const size_t size = sizeof(NSVGgradient) + sizeof(NSVGgradientStop)*(src.gradient->nstops-1); | const size_t size = sizeof(NSVGgradient) + sizeof(NSVGgradientStop)*(src.gradient->nstops-1); | ||||
dst.gradient = static_cast<NSVGgradient*>(malloc(size)); | |||||
std::memcpy(dst.gradient, src.gradient, size); | |||||
dst.gradient = static_cast<NSVGgradient*>(malloc(size)); | |||||
std::memcpy(dst.gradient, src.gradient, size); | |||||
} | } | ||||
} | } | ||||
@@ -1260,6 +1260,31 @@ NSVGimage* nsvgParseFromFileCardinal(const char* const filename, const char* con | |||||
{ | { | ||||
if (NSVGimage* const handle = nsvgParseFromFile(filename, units, dpi)) | if (NSVGimage* const handle = nsvgParseFromFile(filename, units, dpi)) | ||||
{ | { | ||||
/* | |||||
if (NSVGshape* const shapes = handle->shapes) | |||||
{ | |||||
for (NSVGshape *next, *shape = shapes;;) | |||||
{ | |||||
next = shape->next; | |||||
nsvg__deletePaint(&shape->fill); | |||||
nsvg__deletePaint(&shape->stroke); | |||||
std::free(shape); | |||||
if (next == nullptr) | |||||
break; | |||||
shape = next; | |||||
} | |||||
} | |||||
handle->shapes = static_cast<NSVGshape*>(std::calloc(1, sizeof(NSVGshape))); | |||||
handle->shapes->stroke.color = 0xff00ff00; | |||||
handle->shapes->stroke.type = NSVG_PAINT_COLOR; | |||||
handle->shapes->fill.color = 0xff000000; | |||||
handle->shapes->fill.type = NSVG_PAINT_COLOR; | |||||
return handle; | |||||
*/ | |||||
#ifndef HEADLESS | #ifndef HEADLESS | ||||
const size_t filenamelen = std::strlen(filename); | const size_t filenamelen = std::strlen(filename); | ||||
@@ -2,7 +2,13 @@ | |||||
cd $(dirname ${0}) | cd $(dirname ${0}) | ||||
diff -U3 ../Rack/include/midi.hpp ../../include/midi.hpp > diffs/midi.hpp.diff | |||||
diff -U3 ../Rack/include/dsp/fir.hpp ../../include/dsp/fir.hpp > diffs/dsp-fir.hpp.diff | |||||
diff -U3 ../Rack/include/engine/Port.hpp ../../include/engine/Port.hpp > diffs/engine-Port.hpp.diff | |||||
diff -U3 ../Rack/include/simd/Vector.hpp ../../include/simd/Vector.hpp > diffs/simd-Vector.hpp.diff | |||||
diff -U3 ../Rack/dep/oui-blendish/blendish.c blendish.c > diffs/blendish.c.diff | diff -U3 ../Rack/dep/oui-blendish/blendish.c blendish.c > diffs/blendish.c.diff | ||||
diff -U3 ../Rack/src/common.cpp common.cpp > diffs/common.cpp.diff | diff -U3 ../Rack/src/common.cpp common.cpp > diffs/common.cpp.diff | ||||
diff -U3 ../Rack/src/context.cpp context.cpp > diffs/context.cpp.diff | diff -U3 ../Rack/src/context.cpp context.cpp > diffs/context.cpp.diff | ||||
diff -U3 ../Rack/src/plugin.cpp plugin.cpp > diffs/plugin.cpp.diff | diff -U3 ../Rack/src/plugin.cpp plugin.cpp > diffs/plugin.cpp.diff | ||||
@@ -1,4 +1,4 @@ | |||||
--- ../Rack/src/engine/Engine.cpp 2023-05-20 17:03:33.006081772 +0200 | |||||
--- ../Rack/src/engine/Engine.cpp 2023-09-10 12:59:02.631898592 +0200 | |||||
+++ Engine.cpp 2023-05-22 04:26:39.902464764 +0200 | +++ Engine.cpp 2023-05-22 04:26:39.902464764 +0200 | ||||
@@ -1,3 +1,30 @@ | @@ -1,3 +1,30 @@ | ||||
+/* | +/* | ||||
@@ -1,4 +1,4 @@ | |||||
--- ../Rack/src/app/MenuBar.cpp 2023-05-20 17:03:33.005081737 +0200 | |||||
--- ../Rack/src/app/MenuBar.cpp 2023-09-10 12:59:02.630898560 +0200 | |||||
+++ MenuBar.cpp 2023-08-15 17:56:23.782915145 +0200 | +++ MenuBar.cpp 2023-08-15 17:56:23.782915145 +0200 | ||||
@@ -1,8 +1,33 @@ | @@ -1,8 +1,33 @@ | ||||
+/* | +/* | ||||
@@ -1,4 +1,4 @@ | |||||
--- ../Rack/src/app/ModuleWidget.cpp 2023-05-20 17:03:33.005081737 +0200 | |||||
--- ../Rack/src/app/ModuleWidget.cpp 2023-09-10 12:59:02.630898560 +0200 | |||||
+++ ModuleWidget.cpp 2023-05-20 18:40:08.948302802 +0200 | +++ ModuleWidget.cpp 2023-05-20 18:40:08.948302802 +0200 | ||||
@@ -1,8 +1,35 @@ | @@ -1,8 +1,35 @@ | ||||
+/* | +/* | ||||
@@ -1,4 +1,4 @@ | |||||
--- ../Rack/src/window/Window.cpp 2023-05-20 17:03:33.007081806 +0200 | |||||
--- ../Rack/src/window/Window.cpp 2023-09-10 12:59:02.631898592 +0200 | |||||
+++ Window.cpp 2023-08-28 09:55:57.292032175 +0200 | +++ Window.cpp 2023-08-28 09:55:57.292032175 +0200 | ||||
@@ -1,33 +1,94 @@ | @@ -1,33 +1,94 @@ | ||||
+/* | +/* | ||||
@@ -1,4 +1,4 @@ | |||||
--- ../Rack/src/context.cpp 2023-05-20 17:03:33.006081772 +0200 | |||||
--- ../Rack/src/context.cpp 2023-09-10 12:59:02.630898560 +0200 | |||||
+++ context.cpp 2023-05-20 18:08:56.497736615 +0200 | +++ context.cpp 2023-05-20 18:08:56.497736615 +0200 | ||||
@@ -1,14 +1,44 @@ | @@ -1,14 +1,44 @@ | ||||
+/* | +/* | ||||
@@ -0,0 +1,56 @@ | |||||
--- ../Rack/include/dsp/fir.hpp 2022-09-21 20:49:12.181540170 +0200 | |||||
+++ ../../include/dsp/fir.hpp 2022-09-21 20:41:45.860647778 +0200 | |||||
@@ -1,4 +1,32 @@ | |||||
+/* | |||||
+ * DISTRHO Cardinal Plugin | |||||
+ * Copyright (C) 2021-2022 Filipe Coelho <falktx@falktx.com> | |||||
+ * | |||||
+ * 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. | |||||
+ */ | |||||
+ | |||||
+/** | |||||
+ * This file is an edited version of VCVRack's dsp/fir.hpp | |||||
+ * Copyright (C) 2016-2021 VCV. | |||||
+ * | |||||
+ * 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 (at your option) any later version. | |||||
+ */ | |||||
+ | |||||
#pragma once | |||||
+ | |||||
#include <pffft.h> | |||||
#include <dsp/common.hpp> | |||||
@@ -42,16 +70,16 @@ | |||||
RealTimeConvolver(size_t blockSize) { | |||||
this->blockSize = blockSize; | |||||
pffft = pffft_new_setup(blockSize * 2, PFFFT_REAL); | |||||
- outputTail = new float[blockSize]; | |||||
+ outputTail = (float*) pffft_aligned_malloc(sizeof(float) * blockSize); | |||||
std::memset(outputTail, 0, blockSize * sizeof(float)); | |||||
- tmpBlock = new float[blockSize * 2]; | |||||
+ tmpBlock = (float*) pffft_aligned_malloc(sizeof(float) * blockSize * 2); | |||||
std::memset(tmpBlock, 0, blockSize * 2 * sizeof(float)); | |||||
} | |||||
~RealTimeConvolver() { | |||||
setKernel(NULL, 0); | |||||
- delete[] outputTail; | |||||
- delete[] tmpBlock; | |||||
+ pffft_aligned_free(outputTail); | |||||
+ pffft_aligned_free(tmpBlock); | |||||
pffft_destroy_setup(pffft); | |||||
} | |||||
@@ -0,0 +1,226 @@ | |||||
--- ../Rack/include/engine/Port.hpp 2023-09-10 12:59:02.629898529 +0200 | |||||
+++ ../../include/engine/Port.hpp 2023-07-07 18:20:12.030329564 +0200 | |||||
@@ -1,19 +1,57 @@ | |||||
+/* | |||||
+ * DISTRHO Cardinal Plugin | |||||
+ * Copyright (C) 2021-2022 Filipe Coelho <falktx@falktx.com> | |||||
+ * | |||||
+ * 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. | |||||
+ */ | |||||
+ | |||||
+/** | |||||
+ * This file is an edited version of VCVRack's engine/Port.hpp | |||||
+ * Copyright (C) 2016-2021 VCV. | |||||
+ * | |||||
+ * 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 (at your option) any later version. | |||||
+ */ | |||||
+ | |||||
#pragma once | |||||
+ | |||||
#include <common.hpp> | |||||
#include <engine/Light.hpp> | |||||
+#include <list> | |||||
+ | |||||
+/** NOTE alignas is required in some systems in order to allow SSE usage. */ | |||||
+#define SIMD_ALIGN alignas(16) | |||||
+ | |||||
namespace rack { | |||||
namespace engine { | |||||
/** This is inspired by the number of MIDI channels. */ | |||||
-static const int PORT_MAX_CHANNELS = 16; | |||||
+static constexpr const int PORT_MAX_CHANNELS = 16; | |||||
+ | |||||
+ | |||||
+struct Cable; | |||||
struct Port { | |||||
/** Voltage of the port. */ | |||||
- union { | |||||
+ /** NOTE alignas is required in order to allow SSE usage. | |||||
+ Consecutive data (like in a vector) would otherwise pack Ports in a way that breaks SSE. */ | |||||
+ union SIMD_ALIGN { | |||||
/** Unstable API. Use getVoltage() and setVoltage() instead. */ | |||||
float voltages[PORT_MAX_CHANNELS] = {}; | |||||
/** DEPRECATED. Unstable API. Use getVoltage() and setVoltage() instead. */ | |||||
@@ -40,40 +78,40 @@ | |||||
}; | |||||
/** Sets the voltage of the given channel. */ | |||||
- void setVoltage(float voltage, int channel = 0) { | |||||
+ void setVoltage(float voltage, int channel = 0) noexcept { | |||||
voltages[channel] = voltage; | |||||
} | |||||
/** Returns the voltage of the given channel. | |||||
Because of proper bookkeeping, all channels higher than the input port's number of channels should be 0V. | |||||
*/ | |||||
- float getVoltage(int channel = 0) { | |||||
+ float getVoltage(int channel = 0) const noexcept { | |||||
return voltages[channel]; | |||||
} | |||||
/** Returns the given channel's voltage if the port is polyphonic, otherwise returns the first voltage (channel 0). */ | |||||
- float getPolyVoltage(int channel) { | |||||
+ float getPolyVoltage(int channel) const noexcept { | |||||
return isMonophonic() ? getVoltage(0) : getVoltage(channel); | |||||
} | |||||
/** Returns the voltage if a cable is connected, otherwise returns the given normal voltage. */ | |||||
- float getNormalVoltage(float normalVoltage, int channel = 0) { | |||||
+ float getNormalVoltage(float normalVoltage, int channel = 0) const noexcept { | |||||
return isConnected() ? getVoltage(channel) : normalVoltage; | |||||
} | |||||
- float getNormalPolyVoltage(float normalVoltage, int channel) { | |||||
+ float getNormalPolyVoltage(float normalVoltage, int channel) const noexcept { | |||||
return isConnected() ? getPolyVoltage(channel) : normalVoltage; | |||||
} | |||||
/** Returns a pointer to the array of voltages beginning with firstChannel. | |||||
The pointer can be used for reading and writing. | |||||
*/ | |||||
- float* getVoltages(int firstChannel = 0) { | |||||
+ float* getVoltages(int firstChannel = 0) noexcept { | |||||
return &voltages[firstChannel]; | |||||
} | |||||
/** Copies the port's voltages to an array of size at least `channels`. */ | |||||
- void readVoltages(float* v) { | |||||
+ void readVoltages(float* v) const noexcept { | |||||
for (int c = 0; c < channels; c++) { | |||||
v[c] = voltages[c]; | |||||
} | |||||
@@ -89,14 +127,14 @@ | |||||
} | |||||
/** Sets all voltages to 0. */ | |||||
- void clearVoltages() { | |||||
+ void clearVoltages() noexcept { | |||||
for (int c = 0; c < channels; c++) { | |||||
voltages[c] = 0.f; | |||||
} | |||||
} | |||||
/** Returns the sum of all voltages. */ | |||||
- float getVoltageSum() { | |||||
+ float getVoltageSum() const noexcept { | |||||
float sum = 0.f; | |||||
for (int c = 0; c < channels; c++) { | |||||
sum += voltages[c]; | |||||
@@ -107,7 +145,7 @@ | |||||
/** Returns the root-mean-square of all voltages. | |||||
Uses sqrt() which is slow, so use a custom approximation if calling frequently. | |||||
*/ | |||||
- float getVoltageRMS() { | |||||
+ float getVoltageRMS() const { | |||||
if (channels == 0) { | |||||
return 0.f; | |||||
} | |||||
@@ -124,22 +162,22 @@ | |||||
} | |||||
template <typename T> | |||||
- T getVoltageSimd(int firstChannel) { | |||||
+ T getVoltageSimd(int firstChannel) const noexcept { | |||||
return T::load(&voltages[firstChannel]); | |||||
} | |||||
template <typename T> | |||||
- T getPolyVoltageSimd(int firstChannel) { | |||||
+ T getPolyVoltageSimd(int firstChannel) const noexcept { | |||||
return isMonophonic() ? getVoltage(0) : getVoltageSimd<T>(firstChannel); | |||||
} | |||||
template <typename T> | |||||
- T getNormalVoltageSimd(T normalVoltage, int firstChannel) { | |||||
+ T getNormalVoltageSimd(T normalVoltage, int firstChannel) const noexcept { | |||||
return isConnected() ? getVoltageSimd<T>(firstChannel) : normalVoltage; | |||||
} | |||||
template <typename T> | |||||
- T getNormalPolyVoltageSimd(T normalVoltage, int firstChannel) { | |||||
+ T getNormalPolyVoltageSimd(T normalVoltage, int firstChannel) const noexcept { | |||||
return isConnected() ? getPolyVoltageSimd<T>(firstChannel) : normalVoltage; | |||||
} | |||||
@@ -153,13 +191,15 @@ | |||||
If disconnected, this does nothing (`channels` remains 0). | |||||
If 0 is given, `channels` is set to 1 but all voltages are cleared. | |||||
*/ | |||||
- void setChannels(int channels) { | |||||
+ void setChannels(int channels) noexcept { | |||||
// If disconnected, keep the number of channels at 0. | |||||
if (this->channels == 0) { | |||||
return; | |||||
} | |||||
// Set higher channel voltages to 0 | |||||
for (int c = channels; c < this->channels; c++) { | |||||
+ if (c >= PORT_MAX_CHANNELS) | |||||
+ __builtin_unreachable(); | |||||
voltages[c] = 0.f; | |||||
} | |||||
// Don't allow caller to set port as disconnected | |||||
@@ -172,35 +212,39 @@ | |||||
/** Returns the number of channels. | |||||
If the port is disconnected, it has 0 channels. | |||||
*/ | |||||
- int getChannels() { | |||||
+ int getChannels() const noexcept { | |||||
return channels; | |||||
} | |||||
/** Returns whether a cable is connected to the Port. | |||||
You can use this for skipping code that generates output voltages. | |||||
*/ | |||||
- bool isConnected() { | |||||
+ bool isConnected() const noexcept { | |||||
return channels > 0; | |||||
} | |||||
/** Returns whether the cable exists and has 1 channel. */ | |||||
- bool isMonophonic() { | |||||
+ bool isMonophonic() const noexcept { | |||||
return channels == 1; | |||||
} | |||||
/** Returns whether the cable exists and has more than 1 channel. */ | |||||
- bool isPolyphonic() { | |||||
+ bool isPolyphonic() const noexcept { | |||||
return channels > 1; | |||||
} | |||||
/** Use getNormalVoltage() instead. */ | |||||
- DEPRECATED float normalize(float normalVoltage) { | |||||
+ DEPRECATED float normalize(float normalVoltage) const noexcept { | |||||
return getNormalVoltage(normalVoltage); | |||||
} | |||||
}; | |||||
-struct Output : Port {}; | |||||
+struct Output : Port { | |||||
+ /** List of cables connected to this port. */ | |||||
+ std::list<Cable*> cables; | |||||
+}; | |||||
+ | |||||
struct Input : Port {}; | |||||
@@ -0,0 +1,280 @@ | |||||
--- ../Rack/include/midi.hpp 2022-09-21 20:49:12.182540200 +0200 | |||||
+++ ../../include/midi.hpp 2022-09-21 20:41:45.861647821 +0200 | |||||
@@ -1,12 +1,33 @@ | |||||
-#pragma once | |||||
-#include <vector> | |||||
-#include <set> | |||||
- | |||||
-#include <jansson.h> | |||||
+/* | |||||
+ * DISTRHO Cardinal Plugin | |||||
+ * Copyright (C) 2021-2022 Filipe Coelho <falktx@falktx.com> | |||||
+ * | |||||
+ * 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. | |||||
+ */ | |||||
+ | |||||
+/** | |||||
+ * This file is an edited version of VCVRack's midi.hpp | |||||
+ * Copyright (C) 2016-2021 VCV. | |||||
+ * | |||||
+ * 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 (at your option) any later version. | |||||
+ */ | |||||
-#include <common.hpp> | |||||
-#include <context.hpp> | |||||
+#pragma once | |||||
+#include "choc/choc_SmallVector.h" | |||||
namespace rack { | |||||
/** Abstraction for all MIDI drivers in Rack */ | |||||
@@ -15,7 +36,7 @@ | |||||
struct Message { | |||||
/** Initialized to 3 empty bytes. */ | |||||
- std::vector<uint8_t> bytes; | |||||
+ choc::SmallVector<uint8_t, 3> bytes; | |||||
/** The Engine frame timestamp of the Message. | |||||
For output messages, the frame when the message was generated. | |||||
For input messages, the frame when it is intended to be processed. | |||||
@@ -23,7 +44,9 @@ | |||||
*/ | |||||
int64_t frame = -1; | |||||
- Message() : bytes(3) {} | |||||
+ Message() { | |||||
+ bytes.resize(3); | |||||
+ } | |||||
int getSize() const { | |||||
return bytes.size(); | |||||
@@ -87,213 +110,10 @@ | |||||
} | |||||
}; | |||||
-//////////////////// | |||||
-// Driver | |||||
-//////////////////// | |||||
- | |||||
-struct InputDevice; | |||||
-struct Input; | |||||
-struct OutputDevice; | |||||
-struct Output; | |||||
- | |||||
-/** Wraps a MIDI driver API containing any number of MIDI devices. | |||||
-*/ | |||||
-struct Driver { | |||||
- virtual ~Driver() {} | |||||
- /** Returns the name of the driver. E.g. "ALSA". */ | |||||
- virtual std::string getName() { | |||||
- return ""; | |||||
- } | |||||
- /** Returns a list of all input device IDs that can be subscribed to. */ | |||||
- virtual std::vector<int> getInputDeviceIds() { | |||||
- return {}; | |||||
- } | |||||
- /** Returns the default device to use when the driver is selected, or -1 for none. */ | |||||
- virtual int getDefaultInputDeviceId() { | |||||
- return -1; | |||||
- } | |||||
- /** Returns the name of an input device without obtaining it. */ | |||||
- virtual std::string getInputDeviceName(int deviceId) { | |||||
- return ""; | |||||
- } | |||||
- /** Adds the given port as a reference holder of a device and returns the it. | |||||
- Creates the Device if no ports are subscribed before calling. | |||||
- */ | |||||
- virtual InputDevice* subscribeInput(int deviceId, Input* input) { | |||||
- return NULL; | |||||
- } | |||||
- /** Removes the give port as a reference holder of a device. | |||||
- Deletes the Device if no ports are subscribed after calling. | |||||
- */ | |||||
- virtual void unsubscribeInput(int deviceId, Input* input) {} | |||||
- | |||||
- // The following behave identically as the above methods except for outputs. | |||||
- | |||||
- virtual std::vector<int> getOutputDeviceIds() { | |||||
- return {}; | |||||
- } | |||||
- virtual int getDefaultOutputDeviceId() { | |||||
- return -1; | |||||
- } | |||||
- virtual std::string getOutputDeviceName(int deviceId) { | |||||
- return ""; | |||||
- } | |||||
- virtual OutputDevice* subscribeOutput(int deviceId, Output* output) { | |||||
- return NULL; | |||||
- } | |||||
- virtual void unsubscribeOutput(int deviceId, Output* output) {} | |||||
-}; | |||||
- | |||||
-//////////////////// | |||||
-// Device | |||||
-//////////////////// | |||||
- | |||||
-/** A single MIDI device of a driver API. | |||||
- | |||||
-Modules and the UI should not interact with this API directly. Use Port instead. | |||||
- | |||||
-Methods throw `rack::Exception` if the driver API has an exception. | |||||
-*/ | |||||
-struct Device { | |||||
- virtual ~Device() {} | |||||
- virtual std::string getName() { | |||||
- return ""; | |||||
- } | |||||
-}; | |||||
- | |||||
-struct InputDevice : Device { | |||||
- std::set<Input*> subscribed; | |||||
- /** Not public. Use Driver::subscribeInput(). */ | |||||
- void subscribe(Input* input); | |||||
- /** Not public. Use Driver::unsubscribeInput(). */ | |||||
- void unsubscribe(Input* input); | |||||
- /** Called when a MIDI message is received from the device. */ | |||||
- void onMessage(const Message& message); | |||||
-}; | |||||
- | |||||
-struct OutputDevice : Device { | |||||
- std::set<Output*> subscribed; | |||||
- /** Not public. Use Driver::subscribeOutput(). */ | |||||
- void subscribe(Output* output); | |||||
- /** Not public. Use Driver::unsubscribeOutput(). */ | |||||
- void unsubscribe(Output* output); | |||||
- /** Sends a MIDI message to the device. */ | |||||
- virtual void sendMessage(const Message& message) {} | |||||
-}; | |||||
- | |||||
-//////////////////// | |||||
-// Port | |||||
-//////////////////// | |||||
- | |||||
-/** A handle to a Device, typically owned by modules to have shared access to a single Device. | |||||
- | |||||
-All Port methods safely wrap Drivers methods. | |||||
-That is, if the active Device throws a `rack::Exception`, it is caught and logged inside all Port methods, so they do not throw exceptions. | |||||
- | |||||
-Use Input or Output subclasses in your module, not Port directly. | |||||
-*/ | |||||
-struct Port { | |||||
- /** For MIDI output, the channel to automatically set outbound messages. | |||||
- If -1, the channel is not overwritten and must be set by MIDI generator. | |||||
- | |||||
- For MIDI input, messages will be filtered by the channel. | |||||
- If -1, all MIDI channels pass through. | |||||
- */ | |||||
- int channel = -1; | |||||
- | |||||
- // private | |||||
- int driverId = -1; | |||||
- int deviceId = -1; | |||||
- /** Not owned */ | |||||
- Driver* driver = NULL; | |||||
- Device* device = NULL; | |||||
- Context* context; | |||||
- | |||||
- Port(); | |||||
- virtual ~Port(); | |||||
- | |||||
- Driver* getDriver(); | |||||
- int getDriverId(); | |||||
- void setDriverId(int driverId); | |||||
- | |||||
- Device* getDevice(); | |||||
- virtual std::vector<int> getDeviceIds() = 0; | |||||
- virtual int getDefaultDeviceId() = 0; | |||||
- int getDeviceId(); | |||||
- virtual void setDeviceId(int deviceId) = 0; | |||||
- virtual std::string getDeviceName(int deviceId) = 0; | |||||
- | |||||
- virtual std::vector<int> getChannels() = 0; | |||||
- int getChannel(); | |||||
- void setChannel(int channel); | |||||
- std::string getChannelName(int channel); | |||||
- | |||||
- json_t* toJson(); | |||||
- void fromJson(json_t* rootJ); | |||||
-}; | |||||
- | |||||
- | |||||
-struct Input : Port { | |||||
- /** Not owned */ | |||||
- InputDevice* inputDevice = NULL; | |||||
- | |||||
- Input(); | |||||
- ~Input(); | |||||
- void reset(); | |||||
- | |||||
- std::vector<int> getDeviceIds() override; | |||||
- int getDefaultDeviceId() override; | |||||
- void setDeviceId(int deviceId) override; | |||||
- std::string getDeviceName(int deviceId) override; | |||||
- | |||||
- std::vector<int> getChannels() override; | |||||
- | |||||
- virtual void onMessage(const Message& message) {} | |||||
-}; | |||||
- | |||||
- | |||||
-/** An Input port that stores incoming MIDI messages and releases them when ready according to their frame timestamp. | |||||
-*/ | |||||
-struct InputQueue : Input { | |||||
- struct Internal; | |||||
- Internal* internal; | |||||
- | |||||
- InputQueue(); | |||||
- ~InputQueue(); | |||||
- void onMessage(const Message& message) override; | |||||
- /** Pops and returns the next message (by setting `messageOut`) if its frame timestamp is `maxFrame` or earlier. | |||||
- Returns whether a message was returned. | |||||
- */ | |||||
- bool tryPop(Message* messageOut, int64_t maxFrame); | |||||
- size_t size(); | |||||
-}; | |||||
- | |||||
- | |||||
-struct Output : Port { | |||||
- /** Not owned */ | |||||
- OutputDevice* outputDevice = NULL; | |||||
- | |||||
- Output(); | |||||
- ~Output(); | |||||
- void reset(); | |||||
- | |||||
- std::vector<int> getDeviceIds() override; | |||||
- int getDefaultDeviceId() override; | |||||
- void setDeviceId(int deviceId) override; | |||||
- std::string getDeviceName(int deviceId) override; | |||||
- | |||||
- std::vector<int> getChannels() override; | |||||
- | |||||
- void sendMessage(const Message& message); | |||||
-}; | |||||
- | |||||
-PRIVATE void init(); | |||||
-PRIVATE void destroy(); | |||||
-/** Registers a new MIDI driver. Takes pointer ownership. */ | |||||
-void addDriver(int driverId, Driver* driver); | |||||
-std::vector<int> getDriverIds(); | |||||
-Driver* getDriver(int driverId); | |||||
+/* NOTE all the other MIDI stuff (drivers, ports etc) is purposefully missing here, unwanted in Cardinal | |||||
+ */ | |||||
+struct Port; | |||||
} // namespace midi |
@@ -1,4 +1,4 @@ | |||||
--- ../Rack/src/plugin.cpp 2023-05-20 17:03:33.006081772 +0200 | |||||
--- ../Rack/src/plugin.cpp 2023-09-10 12:59:02.631898592 +0200 | |||||
+++ plugin.cpp 2023-05-20 18:43:27.496323540 +0200 | +++ plugin.cpp 2023-05-20 18:43:27.496323540 +0200 | ||||
@@ -1,356 +1,46 @@ | @@ -1,356 +1,46 @@ | ||||
-#include <thread> | -#include <thread> | ||||
@@ -0,0 +1,59 @@ | |||||
--- ../Rack/include/simd/Vector.hpp 2023-05-20 17:03:33.004081703 +0200 | |||||
+++ ../../include/simd/Vector.hpp 2022-12-02 20:11:45.779215949 +0100 | |||||
@@ -1,6 +1,37 @@ | |||||
+/* | |||||
+ * DISTRHO Cardinal Plugin | |||||
+ * Copyright (C) 2021-2022 Filipe Coelho <falktx@falktx.com> | |||||
+ * | |||||
+ * 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. | |||||
+ */ | |||||
+ | |||||
+/** | |||||
+ * This file is an edited version of VCVRack's simd/Vector.hpp | |||||
+ * Copyright (C) 2016-2021 VCV. | |||||
+ * | |||||
+ * 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 (at your option) any later version. | |||||
+ */ | |||||
+ | |||||
#pragma once | |||||
+ | |||||
#include <cstring> | |||||
-#include "common.hpp" | |||||
+#include <pmmintrin.h> | |||||
+ | |||||
+/** NOTE alignas is required in some systems in order to allow SSE usage. */ | |||||
+#define SIMD_ALIGN alignas(16) | |||||
namespace rack { | |||||
@@ -34,7 +65,7 @@ | |||||
using type = float; | |||||
constexpr static int size = 4; | |||||
- union { | |||||
+ union SIMD_ALIGN { | |||||
__m128 v; | |||||
/** Accessing this array of scalars is slow and defeats the purpose of vectorizing. | |||||
*/ | |||||
@@ -108,7 +139,7 @@ | |||||
using type = int32_t; | |||||
constexpr static int size = 4; | |||||
- union { | |||||
+ union SIMD_ALIGN { | |||||
__m128i v; | |||||
int32_t s[4]; | |||||
}; |