Determine position where audio starts


#1

Hi, I’m working on an audio plugin that loads and plays .wav files. Some of these files start with silence, and what I would like to do is determine what time (in seconds) the audio actually starts and begin playing from there. My current code looks like this:

deviceManager.initialiseWithDefaultDevices(0, 2);
transportSource.setSource(nullptr);
readerSource = new AudioFormatReaderSource(formatManager.createReaderFor(file), true);
transportSource.setSource(readerSource, 0, nullptr, 44100.0, 2);
transportSource.setPosition(0.0);
transportSource.start();
m_IsCurrentlyPlaying = true;

I have looked through the documentation for all the audio components I am using but have not been able to figure out how I can accomplish this. Any advice would be greatly appreciated!


#2

You need something to read through the audio and look for the first position the audio level is above a threshold (as the silence is maybe not exactly zero but background noise or dither).

Maybe “playing” through the file into a AudioBuffer then using AudioBuffer::getMagnitude is a good way to start, but that won’t tell you the exact start point (if there is one…) if it’s in the middle of a buffer.


#3

It will be tricky to find a 100% automatic and foolproof method. The threshold approach will work well if your sample files satisfy certain assumptions, like being recorded at a certain level. But if that’s the case, you might rather create your sample files properly in the first place, that they start after small number of samples.

The term to google for is “transient detection”.

A side note: in a plugin you don’t use the deviceManager, since the audio device is managed by the host. Also AudioTransportSource is not the best choice, since it is meant for players, where it doesn’t matter, at which ms you pressed play.


#4

Thanks for the advice!
I was hoping that there would be some JUCE libraries that would help me with transient detection… Luckily, I have access to .mid files which are transcriptions of these single track .wav files so my backup solution is to go through the midiSequence and determine the timeStamp where the song starts (first noteOn event && velocity > 0)

I had originally setup the deviceManager so that I could test my plugin as a standalone app but I see now that it will cause problems when the device manager is the host. What is the correct component to use in this case? If I want to continue testing my plugin as a standalone app will I need to determine the wrapperType on execution and then initialize the appropriate deviceManager accordingly?


#5

If you activate in the Projucer the “Standalone” plugin type, JUCE will create a minimal app from a boilerplate, that allows you to run and test the plugin without a host. You will find it amongst the other build targets. When you select that target, the app is automatically selected as executable (I assume it’s the same on windows). If not, use the debuggers “Select executable” function and select the built app.


#6

I have already been using the “Standalone” build option in Projucer which is how I have been able to test my plugin without a host. When I remove the deviceManager, neither the Standalone build or the VST build produce any sound. Is there something that I should use in place of the deviceManager? Is the idea to determine what output device the host is using and set the plugin output device to be the same? I’m not exactly sure what I should use instead of the deviceManager but it seems like I will need to initialize a deviceManager if my program is a Standalone app or I will need to connect to whatever output device my host is using if running the VST. How can I connect to my host device and stay connected if the host changes the output device?


#7

In a plugin you don’t connect to the device. Instead you get the audio delivered into the processBlock().
If the host changes the output device, usually you get another prepareToPlay call with the new values for samplerate and buffersize, apart from that nothing changes.

If you run the plugin as standalone, there is the options button added to your GUI automatically: