Synth (drum) plugin: too many voices?


#1

Hello,
I’m having some voice issues with my drum plugin (using the Synthesiser class), and I have a feeling it’s because it’s using too many voices. Each note that’s played has 7-10 sounds (.wav files) playing at the same time, and I have separate voices playing each sound, so that’s 7-10 voices at a time for each note played. Since it’s drums, I ignore incoming note off messages, so it has to keep rendering until either the voice is stolen or the sound ends.

So in this case, during playback, there are generally dozens of voices playing sounds at the same time. When I restrict it to only 1 voice per sound, there are no issues, but when I add only 1 or 2 more voices to each sound, the cpu usage increases and the sound begins to crackle. When it reaches a section with fewer or slower notes (so fewer voices needed), the cpu usage decreases and the sound stops crackling. So I’m assuming there are way too many voices to handle at a time. There is a reason I have the sounds on each note separated, so I have to keep it that way. Also, just to make sure it’s clear, when I have more than 1 voice per sound on each note, I made sure that only one is used at a time. So if I have 4 voices per sound on a note, only 1 voice per sound will be used for each noteOn message.

The only possible solution that I can think of is combining all of the sounds of each note into one sound/buffer before (or after?) finding a voice to render it, so that only 1 voice plays all of the sounds on each note instead of having a separate voice for each sound. Does that sound right or will I run into a similar issue? Any suggestions?


#2

Have you tried profiling your code? Sometimes the bottleneck is not what you expected, or you can figure out exactly what’s causing the issue.

eg on macOS:

  1. build your plugin without stripping the symbols (eg debug build)
  2. load in your favorite DAW
  3. launch /Applications/Xcode.app/Contents/Applications/Instruments.app
  4. attach to your DAW process
  5. hit the record button in Instruments.app while your DAW is running audio and receiving note data
  6. now you should be able to click on the different threads and get a much more clear picture of what’s going on

#3

Yeah I agree with @RustyPine, you really need to debug this issue to find a proper way to optimize it. I don’t see how moving all the samples to one voice would really make a difference, unless your voices are passing the raw samples through heavy audio processing which could happen once on the entire group instead of per voice. In that case it’s obvious switching to one voice will be a big improvement. But if you’re essentially just summing now to avoid summing later, you haven’t really done anything but move the calculation from one place to another.

Try using the timer profiler, if you go to the xcode preferences and do a release build, but then set the release build to generate debug symbols, and not stripe them on release, it can be a decent testing scenario to get some insight into the performance of the release build, but also see the specific code lines which the timer detects the processor is running most


#4

Thank you both for the advice. I’ll debug it based on the method you each suggested and I’ll see what comes up.

@Jake_Penn
Yeah I was worried I’d end up running into the same problem. To make sure I understand, you’re saying that instead of passing the raw samples of each sound in a group through the same audio processing but in their individual voices, combine them into one sound so that the audio processing happens only once instead of 7-10 times, since it’s the same processing for all sounds in that group, right? Yes in that case it would definitely be a waste to keep the sounds separate.

In my case, parameter values are applied to each sound in each voice while rendering. Every sound in each group has different values, so they have to be applied individually, per voice.


#5

@Jake_Penn good point about using release builds without the symbols stripped, that should give a more accurate production-build grade profile.


#6

The OP needs to rethink his design… he’s going to run out of file handles by using separate sound files for different tracks for all his samples.

Rail