Chip plugin API #2383
jrmoserbaltimore
started this conversation in
Suggestions
Chip plugin API
#2383
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
There are some things I want to do with Furnace that aren't exactly things you'd probably want in mainline, including a chip that outputs MIDI messages to interface with a firmware that is connected to a real chip.
An API to add new chips would be helpful. That API would need to do a few things:
This would create the channel in the GUI, and set up all the data structures to handle the channel.
This is event based. Furnace plays back the pattern, and whatever's on that line in the channel is bluntly sent to the plug-in. The plug-in has no concept of timing, it just reacts by doing things.
This could potentially include sending a pointer to an array of entries from the channel line; in the interest of thread safety, that list should be allocated and the information copied into it. This would only be called on rows where something is actually played, and it would be called by passing how many entries there are along with a pointer to the array.
The plug-in would also need a callback to say it's done with this array. It should not
delete[]
the array. Allocations are inefficient, and it may be worth having a ring buffer that doesn't cross a 4096 byte boundary (TLB lookup) and is a multiple of 64 bytes in size (cache line).Some chips have effects that are titled with stuff like "set operator 1 parameters." Those are specific to the chip. There would need to be a way to indicate effect IDs and ranges; part of the API is defining which ranges are for plugin-specific effects.
Send audio back to Furnace. May be multiple samples. Audio is sent back per-channel (the summing is in Furnace) and at the sample rate of Furnace's output, so it may be an array of arrays. Upon receiving any message from any channel, the plugin makes note of the timing of the message (i.e. which row/tick), and an audio output call must not cross over this boundary. This is for synchronization: the first sample related to an event on a row will occur on a call to output sound. An example function might be
OutputSound(int16_t num_samples, int16_t num_channels, int16_t* channels, int16_t** samples, int8_t sync)
; thesync
parameter doesn't need to be an actual tick, it just needs to be identifiable by furnace, e.g. in a look-up table storing the real ticks. This is obviously a bad function call but you get the picture. Maybe Furnace frees the memory for the data sent, maybe a ring buffer is actually used to pass the data back and Furnace and the plugin keep track of the position in that.The above might be sufficient for a "trivial" API; more complex APIs may be advantageous for whatever reason. I am not familiar with the code base and haven't thought about this much.
Beta Was this translation helpful? Give feedback.
All reactions