It is probably funny to mock others but it does not help anyone but your ego. Take a look at mystran's interface example, it has Opi prefix everywhere. Do you know why?BlitBit wrote: ↑Wed Jul 08, 2020 3:49 pm While the plugin format does not have a name yet there's at least a name for that: it's called bikeshedding.
Our Community Plugin Format
- KVRist
- 243 posts since 24 Aug, 2014
- Banned
- Topic Starter
- 697 posts since 29 Oct, 2016
Community.h has been updated with mystran's OPI code.
Github:
https://github.com/The-Originator/CommunityPlugin
I updated the repository. Please contribute with your own ideas and code, the more we do, the better the interface will become.
I will reset the poll with the new suggestions, and remove the names with zero votes.
Github:
https://github.com/The-Originator/CommunityPlugin
I updated the repository. Please contribute with your own ideas and code, the more we do, the better the interface will become.
I will reset the poll with the new suggestions, and remove the names with zero votes.
SLH - Yes, I am a woman, deal with it.
- KVRAF
- 7892 posts since 12 Feb, 2006 from Helsinki, Finland
Because as long as it's something sufficiently unique that you can do a search&replace job later, it ultimately doesn't really matter what the exact prefix happens to be.Vokbuz wrote: ↑Wed Jul 08, 2020 4:00 pmIt is probably funny to mock others but it does not help anyone but your ego. Take a look at mystran's interface example, it has Opi prefix everywhere. Do you know why?BlitBit wrote: ↑Wed Jul 08, 2020 3:49 pm While the plugin format does not have a name yet there's at least a name for that: it's called bikeshedding.
edit: Also "Open Plugin Interface" didn't seem to return any useful Google results.
- KVRist
- 384 posts since 28 Nov, 2013 from Germany
Please mind the smiley! I assumed that not everybody knows that term and it might be interesting to learn about it.Vokbuz wrote: ↑Wed Jul 08, 2020 4:00 pmIt is probably funny to mock others but it does not help anyone but your ego.BlitBit wrote: ↑Wed Jul 08, 2020 3:49 pm While the plugin format does not have a name yet there's at least a name for that: it's called bikeshedding.
Because it's a C interface and C does not have namespaces.
Passed 303 posts. Next stop: 808.
- KVRAF
- 7892 posts since 12 Feb, 2006 from Helsinki, Finland
A little more errata: entry point should also take "void*hostPtr" that the plugin should put into the OpiPlugin struct, so that the host can correctly identify the plugin even during initialization (ie. before the entrypoint returns).
- KVRist
- 384 posts since 28 Nov, 2013 from Germany
On a more productive note here's my request for the new plugin format. It would be great if it offered an implementation of real-time safe communication channels between the different threads (audio, GUI, etc.) so that developers would not have to reinvent the wheel over and over again (and potentially poorly).
There are many things one should/must not do when implementing audio plugins so it would be nice if the heavy lifting could be done by the plugin API/implementation.
In case people want the finer grained control it could be considered to provide a layered API, i.e. some developers could go the hardcore way and implement everything themselves while others would use the higher level communication channels.
On a related note it would also be great (if possible) to implement some of the protocol between the host and the plugins so that host developers can integrate the new API with as less effort as possible. This might also reduce the surface for problems a la "It works on that host X but does not work on host Y."
There are many things one should/must not do when implementing audio plugins so it would be nice if the heavy lifting could be done by the plugin API/implementation.
In case people want the finer grained control it could be considered to provide a layered API, i.e. some developers could go the hardcore way and implement everything themselves while others would use the higher level communication channels.
On a related note it would also be great (if possible) to implement some of the protocol between the host and the plugins so that host developers can integrate the new API with as less effort as possible. This might also reduce the surface for problems a la "It works on that host X but does not work on host Y."
Passed 303 posts. Next stop: 808.
-
- KVRAF
- 7401 posts since 17 Feb, 2005
Samplerate is still being represented as a float? Why not double?
I like the idea of automation being considered as another audio stream. With deltaTime serializing the automation buffer (I think I read that automation events would be buffered?), may there be some cases that the memory load presented to the system is increased by the addition of the deltaTime type?
I like the idea of automation being considered as another audio stream. With deltaTime serializing the automation buffer (I think I read that automation events would be buffered?), may there be some cases that the memory load presented to the system is increased by the addition of the deltaTime type?
- KVRAF
- 7892 posts since 12 Feb, 2006 from Helsinki, Finland
Minimal example of a gain plugin using the draft API. This compiles, but no idea if it actually works.
This is not an example of modern software development best-practice, but rather a minimal "hack" to try an implement a minimal plugin with support for the basics.
To be honest, I feel like this is sort of pointless effort, but .. I was bored.
This is not an example of modern software development best-practice, but rather a minimal "hack" to try an implement a minimal plugin with support for the basics.
Code: Select all
#include "plugin-opi.h"
#include <vector>
#include <cstdio>
struct OpiGain : public OpiPlugin
{
std::vector<char> stringBuffer;
int nChannels = 0;
float gain = 1;
OpiGain(OpiCallback hostCallback, void * ptr)
{
dispatchToHost = hostCallback;
dispatchToPlugin = &pluginDispatcher;
ptrHost = ptr;
}
void process(OpiProcessInfo * procInfo)
{
assert(procInfo->processInfoSize == sizeof(OpiProcessInfo));
int nFrames = procInfo->nFrames;
uint64_t silenceMask = procInfo->inputs[0].silenceMask;
uint64_t skipMask = silenceMask & procInfo->outputs[0].silenceMask;
for(int c = 0; c < nChannels; ++c)
{
if((1<<c) & skipMask) continue;
if((1<<c) & silenceMask)
{
for(int i = 0; i < nFrames; ++i)
{
procInfo->outputs[0].channels[c][i] = 0;
}
}
else
{
for(int i = 0; i < nFrames; ++i)
{
procInfo->outputs[0].channels[c][i]
= gain * procInfo->inputs[0].channels[c][i];
}
}
}
}
int configure(OpiConfig * config)
{
if(config->inBusChannels[0].nChannels
== config->inBusChannels[1].nChannels)
{
nChannels = config->inBusChannels[0].nChannels;
return 1;
}
else
{
return 0;
}
}
void setStringBuffer(const char * data, int size = -1)
{
if(size == -1) size = strlen(data);
stringBuffer.resize(size + 1);
memcpy(stringBuffer.data(), data, size);
stringBuffer[size] = 0;
}
static intptr_t pluginDispatcher(
struct OpiPlugin * ptr, int32_t op, int32_t idx, void*data)
{
OpiGain * plug = (OpiGain*) ptr;
if(!op)
{
plug->process((OpiProcessInfo*) data);
return 1;
}
switch(op)
{
case opiPlugDestroy: delete plug; return 1;
case opiPlugNumInputs: return 1; // one input
case opiPlugNumOutputs: return 1; // one output
case opiPlugMaxChannels: return 2; // up to 2 channels
case opiPlugInEventMask: return 0; // don't want events
case opiPlugOutEventMask: return 0; // don't emit events
case opiPlugGetLatency: return 0; // no latency
case opiPlugConfig: return plug->configure((OpiConfig*) data);
case opiPlugReset: return 1; // no-op
case opiPlugEnable: return 1; // no-op
case opiPlugDisable: return 1; // no-op
case opiPlugOpenEdit: return 0; // don't have editor
case opiPlugCloseEdit: return 0; // don't have editor
case opiPlugSaveChunk: return 0; // not implemented
case opiPlugLoadChunk: return 0; // not implemented
case opiPlugNumParam: return 1; // one parameter
case opiPlugGetParam:
switch(idx)
{
case 0: *((float*)data) = plug->gain; return 1;
default: return 0;
}
case opiPlugSetParam:
switch(idx)
{
case 0:
plug->gain = *((float*)data);
if(plug->gain < 0) plug->gain = 0;
if(plug->gain > 1) plug->gain = 1;
return 1;
default: return 0;
}
case opiPlugGetParamName:
switch(idx)
{
case 0: plug->setStringBuffer("Gain"); break;
default: return 0;
}
((OpiString*)data)->data = plug->stringBuffer.data();
((OpiString*)data)->size = plug->stringBuffer.size();
return 1;
case opiPlugValueToString:
{
switch(idx)
{
case 0:
// this is very naive
plug->stringBuffer.resize(32); // alloc "enough" space
plug->stringBuffer.resize(
sprintf(plug->stringBuffer.data(),
"%.2f", ((OpiParamString*)data)->value));
break;
default: return 0;
}
((OpiParamString*)data)->data = plug->stringBuffer.data();
((OpiParamString*)data)->size = plug->stringBuffer.size();
return 1;
}
case opiPlugStringToValue:
switch(idx)
{
case 0:
plug->setStringBuffer(
((OpiString*)data)->data,
((OpiString*)data)->size);
// this is even more naive, but .. whatever
sscanf(plug->stringBuffer.data(),
"%f", &(((OpiParamString*)data)->value));
break;
default: return 0;
}
return 1;
default: return 0;
}
}
};
DLLEXPORT OpiPlugin * OpiPluginEntrypoint(OpiCallback hostCallback, void * hostPtr)
{
return new OpiGain(hostCallback, hostPtr);
}
- Banned
- Topic Starter
- 697 posts since 29 Oct, 2016
GainExample.c added to repository.
Thank you Mystran! Excellent work!
I will close the naming poll this Friday at 11:59 PM EST, the most popular will be the name of our plugin format.
Let's keep marching forwards, once this builds momentum, more and more people will join us.
Every time I edit the poll it resets the vote count. I will simply look at thread posts for any additional votes for suggestions not on the poll. I really like:
CAT - Community Audio Technology
(Suggested by Chapelle)
Thank you Mystran! Excellent work!
I will close the naming poll this Friday at 11:59 PM EST, the most popular will be the name of our plugin format.
Let's keep marching forwards, once this builds momentum, more and more people will join us.
Every time I edit the poll it resets the vote count. I will simply look at thread posts for any additional votes for suggestions not on the poll. I really like:
CAT - Community Audio Technology
(Suggested by Chapelle)
SLH - Yes, I am a woman, deal with it.
- KVRAF
- 7892 posts since 12 Feb, 2006 from Helsinki, Finland
You should probably also fix my errata with regards to the entry point.
-
- KVRian
- 919 posts since 4 Jan, 2007
A function/opcode to return the plugin type from a predefined enum (reverb, filter, synth-wavetable, etc...) and optionally a list of strings (e.g. for a compressor: program-dependant, emulation, etc) would help DAWS presenting neat menus and offer plugin search functions. That could be added to the function that returns the plugin name and the author.
-
- KVRist
- 210 posts since 11 Feb, 2006
More name suggestions:
OAX - Open Audio Extension
OAS - Open Audio Suite
OAP - Open Audio API
CAX - Community Audio Extension
CAS - Community Audio Suite
CAP - Community Audio API
OAX - Open Audio Extension
OAS - Open Audio Suite
OAP - Open Audio API
CAX - Community Audio Extension
CAS - Community Audio Suite
CAP - Community Audio API
- KVRAF
- 7892 posts since 12 Feb, 2006 from Helsinki, Finland
I actually left this stuff out from my draft somewhat intentionally, because I feel like there should be a way to fetch that information without actually instantiating a plugin. Ideally you wouldn't even have to load the DLL (at least not all of it) since that alone can cause a couple of seconds worth of pointless delay if the required files are not in the cache... but I don't have a good answer for how to do it.rafa1981 wrote: ↑Wed Jul 08, 2020 9:00 pm A function/opcode to return the plugin type from a predefined enum (reverb, filter, synth-wavetable, etc...) and optionally a list of strings (e.g. for a compressor: program-dependant, emulation, etc) would help DAWS presenting neat menus and offer plugin search functions. That could be added to the function that returns the plugin name and the author.
- KVRian
- 1253 posts since 31 Dec, 2008
The None Such Community plugin format
www.solostuff.net
Advice is heavy. So don’t send it like a mountain.
Advice is heavy. So don’t send it like a mountain.