How do I actually add a ControlSignal to a SequenceTrack in the C API?

I'm trying to associate some ControlSignal events to a SequenceTrack for a pure C audio project. It appears that in the Lua API there is a track:addControlSignal function, but that appears to be missing in the C API. Is this something that can be exposed, or is there another way I can add a ControlSignal to a Track?


It also appears that the LFO SetGlobal function is also missing from the C API.

Thanks! I've added:

float playdate->sound->lfo->setGlobal(PDSynthLFO* lfo, int global);

If global is set, the LFO is continuously updated whether or not it’s currently in use.

void playdate->sound->track->getSignalForController(SequenceTrack* track, int controller, int create);

Returns the ControlSignal for MIDI controller number controller, creating it if the create flag is set and it doesn’t yet exist.

getSignalForController() is a little different from the Lua API but this is how I should have done it there, too. In a later update I'll add a function to get events from the signal, if you loaded the sequence from a MIDI file and you want to look inside.

1 Like

Hello again! I have updated to the latest SDK and after setting setGlobal on my LFOs and evaluating their values they don't appear to be continuously updating as described? I have a graph that reports the LFO values over time and they are staying at zero unless the synths they are assigned to are actually playing notes. I have a workaround that assigns the LFOs to a set of silent synths that are always playing a note, but that's not ideal.


Looks like it's working as expected for me.. Are you calling lfo:setGlobal() instead of lfo:setGlobal(true), by chance? How are you reading the LFO values? I don't see any accessor to the value in the docs, but I'm likely missing something.. It's been a while since I wrote this code. :slight_smile:

I'll file an issue to add specific checks for boolean arguments where it makes sense instead of letting Lua coerce other types to bools. Lua's lua_toboolean() function returns false only if the value is false or nil, otherwise true--which means the number 0 evaluates to true. :frowning: Requiring a boolean type there would dodge that weirdness as well as handling cases like setGlobal() where it looks like not passing an argument would imply true.

I'm doing this in the C API so I am forced to specify a value anyhow and I am definitely setting it to true. I'm reading the values with pd->sound->lfo->getValue. It would be great if I could get values for any other modulation type as well. I also have a bunch of other miscellaneous questions/feedback/possible bugs in the sound API too as I dig into all of the various features, but maybe I'll make another thread for those.

Here are some pictures in action.

If I just look at the LFO with global enabled (or disabled) it doesn't report a value:

If I assign it to the pan modulation on the instrument's channel (which always evaluates) I get a consistent LFO value:

However if I assign it to the volume modulation it only shows up when the synth is playing:

:man_facepalming: Of course, I forgot the whole thing was adding that function to C. Yep, I see what's going on--I'm setting the flag in the struct directly instead of calling the setter function, which means it's not adding the lfo to the list of global signals. I'll get that fixed in the next update. Sorry!