# Programmatically changing input/output audio device doesn't always work

**URL:** <https://forum.juce.com/t/programmatically-changing-input-output-audio-device-doesnt-always-work/45433>\
**Category:** MacOSX and iOS\
**Created:** [April 9, 2021, 7:43am UTC](https://forum.juce.com/t/programmatically-changing-input-output-audio-device-doesnt-always-work/45433 "2021-04-09T07:43:12Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![gbernardi](https://avatars.discourse-cdn.com/v4/letter/g/7feea3/32.png) [@gbernardi](https://forum.juce.com/u/gbernardi)\
**Post date:** [April 9, 2021, 7:43am UTC](https://forum.juce.com/t/programmatically-changing-input-output-audio-device-doesnt-always-work/45433/1 "2021-04-09T07:43:13Z")

</div>

Hello,  
I’ve been working on a project in JUCE (Audio app using `AudioAppComponent`) for a while and I’ve stumbled upon a problem that I can’t understand.  
The app uses custom input/output audio devices (`myInputDevice` and `myOutputDevice`) made using Device Aggregation (through Audio MIDI Setup) on MacOSx; both input and output audio devices have 4 channels.  
Neither of these devices is used a system audio device, as I want to keep using my headphones for that.

For this reason, in the constructor of my `AudioAppComponent` object (named `MainComponent`), I included some code I took from the JUCE `DemoRunner` demo about Audio Settings (`AudioSettingsDemo.h`). This code should programmatically set the audio device used in the `AudioAppComponent` to my custom input/output devices in place of the system audio device (i.e. my headphones).

The code below, showing both a snippet of the `h` and the `cpp` files works most times but sometimes yields an error at the following `jassert`:

```
const Type* getReadPointer (int channelNumber, int sampleIndex) const noexcept
{
    jassert (isPositiveAndBelow (channelNumber, numChannels));
    ...
}

```

I tried to trace back the reason of this and it seems to be related to the fact that when calling the `setAudioChannels()` function, the system device is used in place of my custom devices and the former doesn’t have 4 channels, so that when the `copyFrom` method within `getNextAudioBlock()` is called, the error occurs.  
However, this doesn’t happen all the time, which makes it quite a nuisance to debug…

Now I must admit that I don’t understand some of the details going on in the code, e.g. I tried to call `setAudioChannels()` after actually setting up the custom audio device using `setAudioDeviceSetup` but that doesn’t get me any audio in or out the app.  
Hopefully, some of you can see what I’m doing wrong.

```
//============================================================
class MainComponent : public AudioAppComponent
{
public:
    MainComponent();
    ~MainComponent();
    // --------
    void prepareToPlay (int samplesPerBlockExpected, double sampleRate) override;
    void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill) override;
    void releaseResources() override;

private:

    // ------ audioDeviceArea
    AudioDeviceManager::AudioDeviceSetup currentAudioSetup;
    AudioDeviceSelectorComponent audioSetupComp;
    
    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainComponent)
};

//============================================================

MainComponent::MainComponent() :
                 audioSetupComp (deviceManager,
                      0, // minimum input channels
                      4, // maximum input channels
                      0, // minimum output channels
                      4, // maximum output channels
                      false, // ability to select midi inputs
                      false, // ability to select midi output device
                      false, // treat channels as stereo pairs
                      false), // hide advanced options
{
...
    // --------------------------------
    // Setup device manager
    deviceManager.getAudioDeviceSetup(currentAudioSetup);

    // I need to make sure that IN/OUT have (or can have) the same sampling freq!!!!
    currentAudioSetup.inputDeviceName = "myInputDevice";
    currentAudioSetup.outputDeviceName = "myOutputDevice";
            
    // Define IN/OUT channels
    numChannelIN = 4;
    numChannelOUT = 4;
        
    // Set audio device (I/O) buffer size and fs
    currentAudioSetup.bufferSize = currBuffSize;
    currentAudioSetup.sampleRate = currFs;

        
    // Some platforms require permissions to open input channels so request that here
    if (juce::RuntimePermissions::isRequired (juce::RuntimePermissions::recordAudio)
       && ! juce::RuntimePermissions::isGranted (juce::RuntimePermissions::recordAudio))
    {
       juce::RuntimePermissions::request (juce::RuntimePermissions::recordAudio,
                                          [&] (bool granted) { setAudioChannels (granted ? 2 : 0, 2); });
    }
    else
    {
       // Specify the number of input and output channels that we want to open
       setAudioChannels (numChannelIN, numChannelOUT);
    }

    // Use custom bufferSize and sampleRate [must come after setAudioChannels()]
    deviceManager.setAudioDeviceSetup(currentAudioSetup, true);
    // --------------------------------
...
}

void MainComponent::getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill)
{
    ...
    // Get audio from input 4 
    myBuffer.copyFrom(0, 0, bufferToFill.buffer->getReadPointer( 3, bufferToFill.startSample), currBuffSize);
    ...
}
```

---

<div class="post-metadata">

**Author:** ![NaughtiusMaximus](https://avatars.discourse-cdn.com/v4/letter/n/74df32/32.png) [@NaughtiusMaximus](https://forum.juce.com/u/NaughtiusMaximus)\
**Post date:** [January 19, 2025, 12:41pm UTC](https://forum.juce.com/t/programmatically-changing-input-output-audio-device-doesnt-always-work/45433/2 "2025-01-19T12:41:15Z")

</div>

> [@gbernardi](#):
>
> `setAudioChannels`

Hi, have you been able to solve this issue since? I have just posted a similar question to the forum then I noticed your post from 4 years ago. I am not using setAudioChannels, but my code is very similar to what setAudioChannels does in AudioAppComponent. And I am getting the same result as you, as in no audio from my inputs.

---

<div class="post-metadata">

**Author:** ![gbernardi](https://avatars.discourse-cdn.com/v4/letter/g/7feea3/32.png) [@gbernardi](https://forum.juce.com/u/gbernardi)\
**Post date:** [January 20, 2025, 11:08am UTC](https://forum.juce.com/t/programmatically-changing-input-output-audio-device-doesnt-always-work/45433/3 "2025-01-20T11:08:38Z")

</div>

Hey, I honestly can’t recall if I found a specific solution for this very problem. 😅

But what I’m sure of is that, for the project I was working on, I ended up using a different strategy (i.e. I stopped using the aggregated device). That’s most likely due to the fact that, among other things, I could not solve this very problem.

Sorry about that

---

<div class="post-metadata">

**Author:** ![NaughtiusMaximus](https://avatars.discourse-cdn.com/v4/letter/n/74df32/32.png) [@NaughtiusMaximus](https://forum.juce.com/u/NaughtiusMaximus)\
**Post date:** [January 22, 2025, 5:35am UTC](https://forum.juce.com/t/programmatically-changing-input-output-audio-device-doesnt-always-work/45433/4 "2025-01-22T05:35:06Z")

</div>

Hi, thanks for your reply. I have rolled back my code to a stage when the above setup attempt was still working for me, to see exactly what I was doing then. I think the main difference between that stage and my current one is that I did not have various async event handlers dealing with my AudioDeviceManager object, but all the setup happened in once single function in one single thread, from beginning to end. I think it is mainly important for the functions that end up calling AudioIODeviceCallback::audioDeviceAboutToStart and AudioProcessor::prepareToPlay functions.  
At least for now I have two codebases, one does what I need, the other doesn’t. When I find out more I will post it here.

---

<div class="post-metadata">

**Author:** ![NaughtiusMaximus](https://avatars.discourse-cdn.com/v4/letter/n/74df32/32.png) [@NaughtiusMaximus](https://forum.juce.com/u/NaughtiusMaximus)\
**Post date:** [February 12, 2025, 1:56pm UTC](https://forum.juce.com/t/programmatically-changing-input-output-audio-device-doesnt-always-work/45433/5 "2025-02-12T13:56:16Z")

</div>

Hi, I have finally found what caused my problems, I am posting in your thread too just in case it helps anyone.

The issue was caused by one line in my CMakeLists.txt file, which caused my audio to stop working:

This is the line because of which my audio got muted:  
set (CMAKE\_OSX\_ARCHITECTURES arm64 x86\_64)

And this fixes it (as I am on an Intel Mac):  
set (CMAKE\_OSX\_ARCHITECTURES x86\_64)

I have no idea why this was an issue though, and I would still need to see how it affects a potential Apple silicon build.
