kopia lustrzana https://gitlab.com/eliggett/wfview
218 wiersze
6.0 KiB
C++
218 wiersze
6.0 KiB
C++
#ifndef AUDIOPLUGIN_H
|
|
#define AUDIOPLUGIN_H
|
|
|
|
#include <math.h>
|
|
|
|
#include <lv2.h>
|
|
#ifdef _WIN32
|
|
#include <lilv/lilv.h>
|
|
#include "lv2/event/event.h"
|
|
#include "lv2/atom/atom.h"
|
|
#include "lv2/worker/worker.h"
|
|
#else
|
|
#include <lilv-0/lilv/lilv.h>
|
|
#include <lv2/lv2plug.in/ns/ext/event/event.h>
|
|
#include <lv2/lv2plug.in/ns/ext/atom/atom.h>
|
|
#include <lv2/lv2plug.in/ns/ext/worker/worker.h>
|
|
#endif
|
|
|
|
#include <QObject>
|
|
#include <QMutex>
|
|
#include <QDebug>
|
|
|
|
|
|
enum pluginType {
|
|
pluginNone = 0,
|
|
pluginDynamics = 1,
|
|
pluginTimebase = 2,
|
|
pluginGenerator = 3,
|
|
pluginUtility = 4
|
|
};
|
|
|
|
enum pluginPathType {
|
|
pluginPathNone = 0,
|
|
pluginPathReceiveAudio,
|
|
pluginPathTransmitAudio,
|
|
pluginPathStreamingAudio,
|
|
pluginPathUtilityAudio
|
|
};
|
|
|
|
// A vector of controlsType will get sent to the UI for setup.
|
|
// We can also pass these back and forth, using the portIndex
|
|
// and value to set the controls locally.
|
|
|
|
struct controlsType {
|
|
uint64_t instanceId;
|
|
unsigned int controlsIndex = 0;
|
|
unsigned int portIndex = 0;
|
|
float value = 0.0f;
|
|
// Setup:
|
|
float min = 0.0f;
|
|
float max = 0.0f;
|
|
float def = 0.0f;
|
|
bool audioTaper = false;
|
|
QString label;
|
|
};
|
|
|
|
typedef struct URITable {
|
|
char** uris;
|
|
size_t n_uris;
|
|
} URITable;
|
|
|
|
|
|
typedef enum { TYPE_CONTROL, TYPE_AUDIO, TYPE_ATOM, TYPE_EVENT } PortType;
|
|
|
|
typedef struct Param {
|
|
const char* sym; ///< Port symbol
|
|
float value; ///< Control value
|
|
} Param;
|
|
|
|
typedef struct {
|
|
const LilvPort* lilv_port; ///< Port description
|
|
PortType type; ///< Datatype
|
|
uint32_t index; ///< Port index
|
|
float value; ///< Control value (if applicable)
|
|
bool is_input; ///< True iff an input port
|
|
bool optional; ///< True iff connection optional
|
|
} Port;
|
|
|
|
class audioPlugin : public QObject
|
|
{
|
|
Q_OBJECT
|
|
|
|
public:
|
|
explicit audioPlugin(int maxBufferSizeNeeded, QObject *parent = nullptr);
|
|
~audioPlugin();
|
|
|
|
void setupPlugin(char* pluginURI);
|
|
|
|
void setControlsPointer();
|
|
|
|
// Maybe these should be uint16 buffers, stereo interlaced?
|
|
void setInputBuffer(char* stereoInterlacedInputBuffer);
|
|
void setOutputBuffer(char* stereoInterlacedOutputBuffer);
|
|
uint16_t *getInputBuffer();
|
|
uint16_t *getOutputBuffer();
|
|
|
|
signals:
|
|
void pluginLoaded(bool loadOk);
|
|
void processedAudioReady(); // might not use this...
|
|
void pluginErrorMessage(QString errorMessage);
|
|
void pluginStatusMessage(QString statusMessage);
|
|
void haveAudioLevels(float inRMS, float inPeak, float outRMS, float outPeak);
|
|
void haveControlPorts(QVector<controlsType> controls);
|
|
|
|
public slots:
|
|
// For performance reasons, do not call runPlugin with the signal/slot mechanism.
|
|
// Only call this function if the buffers have already been connected.
|
|
// The function will load from the input buffer, and alter the output buffer.
|
|
void runPlugin(int samples);
|
|
|
|
void getPluginControlPorts();
|
|
void handleAdjustedPluginControls(controlsType control);
|
|
|
|
// These functions are not complete yet:
|
|
void selectPluginByName(QString pluginName);
|
|
void selectPluginByLabel(QString pluginLabel);
|
|
void selectPluginByID(int pluginId);
|
|
|
|
void debugThis(); // nice debug info here
|
|
|
|
private:
|
|
uint64_t instanceId;
|
|
QString instanceString;
|
|
pluginType kind;
|
|
pluginPathType path;
|
|
QMutex pluginRunLocker;
|
|
bool forceOutputMono = true;
|
|
bool computeLevels = false;
|
|
int bufferSize;
|
|
int externalBufferSize;
|
|
bool haveAllocatedInternalBuffers = false;
|
|
bool haveExternalSourceBuffer = false;
|
|
bool haveExternalSinkBuffer = false;
|
|
bool haveLoadedPlugin = false;
|
|
bool haveActivatedPlugin = false;
|
|
|
|
// These two buffers are allocated *external* to the audioPlugin class,
|
|
// and are expected to be acceptable size-wise, at minimum, per the argument to runPlugin.
|
|
// The format used internally here is unsigned 16-bit interleved stereo.
|
|
// The external format is split 8-8 interleved stereo.
|
|
int16_t *externalSourceBuffer;
|
|
int16_t *externalSinkBuffer;
|
|
|
|
float *inputBuffer[2];
|
|
float *outputBuffer[2];
|
|
void allocateBuffers();
|
|
void deallocateBuffers();
|
|
void convertInputBuffer();
|
|
void convertOutputBuffer();
|
|
|
|
uint16_t externalSampleCount; // from the interleved 8-8 QByteArray.length()
|
|
uint16_t sourceBufferSampleCount; // size of our 16-bit casted array of same data
|
|
uint16_t inputBufferSampleCount; // used size of the float buffers, per 16-bit channel.
|
|
|
|
float computeBufferRMS(float *buffer);
|
|
float inRMS = 0.0f;
|
|
float inPeak = 0.0f;
|
|
float outRMS = 0.0f;
|
|
float outPeak = 0.0f;
|
|
|
|
void unloadPlugin(); // deactivate, unload, and free
|
|
|
|
void initPluginWorld();
|
|
bool loadPlugin(char *pluginURI);
|
|
void findPlugin();
|
|
bool createPorts();
|
|
|
|
void createControls();
|
|
void deleteControls();
|
|
void copyControlsToPluginInterface();
|
|
|
|
bool activatePlugin();
|
|
// Plugin world items:
|
|
LilvNode* gControlPortClass;
|
|
LilvWorld* world = NULL;
|
|
const LilvPlugins *plugins;
|
|
const LilvPlugin *plugin;
|
|
LilvNode *uri = NULL;
|
|
LilvNode *pluginName;
|
|
QString pluginNameAsQString;
|
|
LilvInstance *instance;
|
|
unsigned int n_params;
|
|
Param *params;
|
|
unsigned int n_ports;
|
|
unsigned int n_audio_in;
|
|
unsigned int n_audio_out;
|
|
unsigned int sampleRate = 48000;
|
|
Port *ports;
|
|
Port *portsExternal; // ports for UI adjustments
|
|
QVector <controlsType> controls;
|
|
|
|
QString getPLuginControlInfo();
|
|
uint16_t byteTable[65535];
|
|
void makeByteTable();
|
|
uint16_t byteSwapper();
|
|
|
|
/* URID MAP FEATURE */
|
|
|
|
LV2_Feature *features[3];
|
|
|
|
static LV2_URID urid_map(void* handle, const char* uri);
|
|
static const char* urid_unmap(void* handle, LV2_URID urid);
|
|
|
|
std::map<std::string, LV2_URID> urid_map_data;
|
|
LV2_URID current_urid = 1; /* 0 is reserverd */
|
|
|
|
LV2_URID_Map feature_uri_map_data;
|
|
LV2_Feature feature_uri_map;
|
|
|
|
LV2_URID_Unmap feature_uri_unmap_data;
|
|
LV2_Feature feature_uri_unmap;
|
|
|
|
LV2_Feature feature_worker;
|
|
|
|
};
|
|
|
|
#endif // AUDIOPLUGIN_H
|