Change device buffer size in prepareToPlay - JUCEApplication


#1

Hello,
I created simply application in JUCE, with template “Audio Application”.
But in void prepareToPlay (int samplesPerBlockExpected, double sampleRate) as I understand samplesPerBlockExpected means buffer size. But it’s always the same, on my Mac it’s always 512, but on my Windows computer it’s always 441. As I understand it’s depend on audio device in my computer. But for testing my the code I need to be able to change it. Could anyone help me?


#2

To reconfigure your current audio interface setup, I think something like this should work if it’s called from a member function of your AudioAppComponent (to make it simple just put it into the constructor):

AudioDeviceManager::AudioDeviceSetup currentAudioSetup;
deviceManager.getAudioDeviceSetup (currentAudioSetup);
currentAudioSetup.bufferSize = A_VALUE_YOU_PREFER;
deviceManager.setAudioDeviceSetup (currentAudioSetup, true);

deviceManager is a public member of your AudioAppComponent. There is also a AudioDeviceSelectorComponent which allows you to configure the audio interface through a GUI Component. You might also be interested in this tutorial: https://docs.juce.com/master/tutorial_audio_device_manager.html


#3

Your MainComponent inherits from AudioAppComponent (https://docs.juce.com/master/classAudioAppComponent.html), which has a AudioDeviceManager deviceManager, which again you can initialize with an AudioDeviceSetup. You can set a bufferSize there.

Edit: or what @PluginPenguin said


#4

Thanks for reply, but as I understand I should call those methods in my Main.cpp? Or in MainComponent.cpp?


#5

As only your MainComponent class inherits from AudioAppComponent, deviceManager will only be accessible from within that class.


#6

Yes but actually I even can’t find where is initialized my MainComponent (which inherits from AudioAppComponent).
In the main.cpp I see only that small line of code:
setContentOwned (new MainComponent(), true);
And nothing more about MainComponent.


#7

OK, I tried that:

AudioDeviceManager::AudioDeviceSetup currentAudioSetup;
deviceManager.getAudioDeviceSetup (currentAudioSetup);
currentAudioSetup.bufferSize = 1024;
deviceManager.setAudioDeviceSetup (currentAudioSetup, true);

Icalled it in the constructor of MainComponent()
But in the prepareToPlay samplesPerBlockExpected is still 512.


#8

Well, that’s where your AudioApp is created.
Actually, you don’t need to change anything in Main.cpp (unless you want to do something fancy).

Just focus on MainComponent.h and .cpp


#9

So why code from PluginPenguin doesn’t work?
And currentAudioSetup.bufferSize = A_VALUE_YOU_PREFER; What value should be A_VALUE_YOU_PREFER? Could it be anything? Even 199, or 11?


#10

Anything your audio device (soundcard) can handle.
You can call getCurrentAudioDevice() to further find out about the available bufferSize. Look at the doc https://docs.juce.com/master/classAudioDeviceManager.html#aef0249d178aa5448ad2e949ae059c461

You can get a return String with an error message, you can debug.


#11

OK, great thanks I will try to find it out


#12

Why do you even need to attempt to change the buffer size?


#13

To test my code with other buffer sizes.


#14

Changing the bufferSize during runtime can be quite convenient, to balance between latency and performance. See the standalone settings dialog. I used it in a guitar looper app which does quite a lot of processing (beat detection with automatic drum playback). When my laptop is disconnected from power, I had to change the buffersize to make it run without dropouts :slight_smile:


#15

I make app to realtime pitch shifting, based on FFT. And I have mixed radix FFT, so I can set FFT buff size for example 1000, but it’s 1000/512 is not integer and pitch shifting doesn’t work well. It works well only for buffer sizes which are integer multiply of device buffer size. And I am not sure if it’s something wrong with my FFT, or maybe I do something wrong in getNextAudioBlock. If I couldchange device buffer size I could make more reliable testing


#16

I don’t need to change buffer size during runtime, it could be changed before compilation and build the app, but I need to be able to change it at all. I read some of documentation, and your advices, but I still can’t figure it out.


#17

To be honest, those three lines of code I pasted above came from one of my first JUCE projects - definitively no masterpiece, however it worked on Mac OS and Linux (including the buffer size adjustment). After this project I haven’t worked on any Audio Application template based JUCE app anymore, so there might be more experienced people with the AudioDeviceManager out there, but as Daniel pointed out, some basic debugging shouldn’t be too hard.

However, if you only want to test if your code works at a given buffer size and if you want to be independent of your hardware capabilities, why don’t you just use an audio file as source and take blocks of the desired length out of it to put it into the algorithm. Of course, this is not real-time, but it will show if your code can handle this buffer size.


#18

@pajczur: Debug that return string. Only you can do that, we can’t help you with that.

String ret = deviceManager.setAudioDeviceSetup(...);
DBG(ret);

#19

The different audio hardwares often have a collection of buffer sizes that they accept, you usually can’t set arbitrary buffer sizes. Put an AudioDeviceSelectorComponent so the user can test and choose a buffer size that works with their hardware in the first place. And you should make your algorithm work independent of the hardware buffer size anyway.


#20

I am trying to do that, but there is problem with (...) I have no idea what to put as “…” I know it should be something like that <#const juce::AudioDeviceManager::AudioDeviceSetup &newSetup#> But I also have no idea what is that? I know there is documentation but it’s realy hard to understand for me