Audio plugin host

I’m getting build errors when I try to run make on the Audio plugin host? I updated my Juce tip yesterday. Any ideas?

Compiling juce_audio_processors.cpp
In file included from …/…/…/…/modules/juce_audio_processors/juce_audio_processors.cpp:74:0:
…/…/…/…/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp:1479:44: warning: multi-character character constant [-Wmultichar]
…/…/…/…/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp:1479:84: warning: multi-character character constant [-Wmultichar]
…/…/…/…/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp:1483:40: warning: multi-character character constant [-Wmultichar]
…/…/…/…/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp:1519:45: warning: multi-character character constant [-Wmultichar]
…/…/…/…/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp:1524:48: warning: multi-character character constant [-Wmultichar]
…/…/…/…/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp:1532:45: warning: multi-character character constant [-Wmultichar]
…/…/…/…/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp:1532:82: warning: multi-character character constant [-Wmultichar]
…/…/…/…/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp:1542:45: warning: multi-character character constant [-Wmultichar]
…/…/…/…/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp:1542:82: warning: multi-character character constant [-Wmultichar]
…/…/…/…/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp:1578:45: warning: multi-character character constant [-Wmultichar]
…/…/…/…/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp:1580:42: warning: multi-character character constant [-Wmultichar]
…/…/…/…/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp:1595:45: warning: multi-character character constant [-Wmultichar]
…/…/…/…/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp:1597:42: warning: multi-character character constant [-Wmultichar]
…/…/…/…/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp:1617:45: warning: multi-character character constant [-Wmultichar]
…/…/…/…/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp:1619:42: warning: multi-character character constant [-Wmultichar]
…/…/…/…/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp:1710:44: warning: multi-character character constant [-Wmultichar]
…/…/…/…/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp:1710:82: warning: multi-character character constant [-Wmultichar]
…/…/…/…/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp:1753:38: warning: multi-character character constant [-Wmultichar]
…/…/…/…/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp:1755:35: warning: multi-character character constant [-Wmultichar]
…/…/…/…/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp: In static member function ‘static juce::String juce::ModuleHandle::getDLLResource(const juce::File&, const juce::String&, int)’:
…/…/…/…/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp:460:9: error: ‘HMODULE’ was not declared in this scope
…/…/…/…/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp:460:17: error: expected ‘;’ before ‘dllModule’
…/…/…/…/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp:462:13: error: ‘dllModule’ was not declared in this scope
…/…/…/…/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp:462:26: error: ‘INVALID_HANDLE_VALUE’ was not declared in this scope
…/…/…/…/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp:464:13: error: ‘HRSRC’ was not declared in this scope
…/…/…/…/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp:464:19: error: expected ‘;’ before ‘res’
…/…/…/…/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp:466:17: error: ‘res’ was not declared in this scope
…/…/…/…/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp:468:17: error: ‘HGLOBAL’ was not declared in this scope
…/…/…/…/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp:468:25: error: expected ‘;’ before ‘hGlob’
…/…/…/…/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp:470:21: error: ‘hGlob’ was not declared in this scope
…/…/…/…/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp:472:86: error: ‘LockResource’ was not declared in this scope
…/…/…/…/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp:473:82: error: ‘SizeofResource’ was not declared in this scope
…/…/…/…/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp: In member function ‘void juce::VSTPluginWindow::openPluginWindow()’:
…/…/…/…/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp:2296:108: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
make: *** [build/intermediate/Debug/juce_audio_processors_eb9ae116.o] Error 1

Sorry, I don’t actively test the linux VST build myself. But I’ve checked in some changes that should hopefully fix this (untested).

It builds fine now, thanks for your quick fix.

Builds fine, but crashes on startup:

Builds/Linux/build$ gdb PluginHost
GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2) 7.4-2012.04
Copyright © 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and “show warranty” for details.
This GDB was configured as “x86_64-linux-gnu”.
For bug reporting instructions, please see:
http://bugs.launchpad.net/gdb-linaro/
Reading symbols from /home/rory/Sourcecode/julianstorer-JUCE-f02f1c3/extras/audio plugin host/Builds/Linux/build/PluginHost…done.
(gdb) run
Starting program: /home/rory/Sourcecode/julianstorer-JUCE-f02f1c3/extras/audio plugin host/Builds/Linux/build/PluginHost
[Thread debugging using libthread_db enabled]
Using host libthread_db library “/lib/x86_64-linux-gnu/libthread_db.so.1”.
JUCE v2.0.28
ALSA device: hw:PCH,0 outs=2-2 ins=2-2 rates=4
ALSA device: hw:PCH,3 outs=2-8 ins=0-0 rates=7
ALSA device: hw:PCH,7 outs=2-8 ins=0-0 rates=7
ALSA device: hw:PCH,8 outs=2-8 ins=0-0 rates=7
ALSA device: hw:UA25,0 outs=2-2 ins=2-2 rates=1
[New Thread 0x7ffff252d700 (LWP 4965)]

Program received signal SIGSEGV, Segmentation fault.
0x00000000005eff14 in juce::Component::sendMovedResizedMessages (
this=0x7ffff7f4a818, wasMoved=false, wasResized=true)
at …/…/…/…/modules/juce_gui_basics/components/juce_Component.cpp:1071
1071 resized();
(gdb) bt
#0 0x00000000005eff14 in juce::Component::sendMovedResizedMessages (
this=0x7ffff7f4a818, wasMoved=false, wasResized=true)
at …/…/…/…/modules/juce_gui_basics/components/juce_Component.cpp:1071
#1 0x00000000005efe92 in juce::Component::setBounds (this=0x7ffff7f4a818,
x=0, y=0, w=792, h=506)
at …/…/…/…/modules/juce_gui_basics/components/juce_Component.cpp:1053
#2 0x000000000040e578 in GraphDocumentComponent::resized (this=0xab2ae0)
at …/…/Source/GraphEditorPanel.cpp:1054
#3 0x00000000005eff20 in juce::Component::sendMovedResizedMessages (
this=0xab2ae0, wasMoved=true, wasResized=true)
at …/…/…/…/modules/juce_gui_basics/components/juce_Component.cpp:1071
#4 0x00000000005efe92 in juce::Component::setBounds (this=0xab2ae0, x=4,
y=30, w=792, h=566)
at …/…/…/…/modules/juce_gui_basics/components/juce_Component.cpp:1053
#5 0x00000000005f01f1 in juce::Component::setBounds (this=0xab2ae0, r=…)
at …/…/…/…/modules/juce_gui_basics/components/juce_Component.cpp:1117
#6 0x00000000005f04ec in juce::Component::setBoundsInset (this=0xab2ae0,
borders=…)
at …/…/…/…/modules/juce_gui_basics/components/juce_Component.cpp:1165
#7 0x000000000067069c in juce::ResizableWindow::resized (this=0xa93330)
at …/…/…/…/modules/juce_gui_basics/windows/juce_ResizableWindow.cpp:234
#8 0x000000000066ed8d in juce::DocumentWindow::resized (this=0xa93330)
at …/…/…/…/modules/juce_gui_basics/windows/juce_DocumentWindow.cpp:233
—Type to continue, or q to quit—
#9 0x00000000006700f7 in juce::ResizableWindow::setContent (this=0xa93330,
newContentComponent=0xab2ae0, takeOwnership=true,
resizeToFitWhenContentChangesSize=false)
at …/…/…/…/modules/juce_gui_basics/windows/juce_ResizableWindow.cpp:132
#10 0x000000000067012e in juce::ResizableWindow::setContentOwned (
this=0xa93330, newContentComponent=0xab2ae0,
resizeToFitWhenContentChangesSize=false)
at …/…/…/…/modules/juce_gui_basics/windows/juce_ResizableWindow.cpp:137
#11 0x0000000000414e30 in MainHostWindow::MainHostWindow (this=0xa93330)
at …/…/Source/MainHostWindow.cpp:91
#12 0x0000000000413c70 in PluginHostApp::initialise (this=0xa91760,
commandLine=…) at …/…/Source/HostStartup.cpp:62
#13 0x00000000006778a0 in juce::JUCEApplication::initialiseApp (this=0xa91760)
at …/…/…/…/modules/juce_gui_basics/application/juce_Application.cpp:181
#14 0x0000000000677b7a in juce::JUCEApplication::main ()
at …/…/…/…/modules/juce_gui_basics/application/juce_Application.cpp:236
#15 0x0000000000677db0 in juce::JUCEApplication::main (argc=1,
argv=0x7fffffffe1d8)
at …/…/…/…/modules/juce_gui_basics/application/juce_Application.cpp:297
#16 0x00000000004139c9 in main (argc=1, argv=0x7fffffffe1d8)
at …/…/Source/HostStartup.cpp:107

I tried to replicate. For me, it works fine when jackd is running. Without jackd I get a crash, but different from yours.

Did you try with jackd on/off?

[code]gdb Builds/Linux/build/Plugin\ Host
GNU gdb (Ubuntu/Linaro 7.2-1ubuntu11) 7.2
Copyright © 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and “show warranty” for details.
This GDB was configured as “x86_64-linux-gnu”.
For bug reporting instructions, please see:
http://www.gnu.org/software/gdb/bugs/
Reading symbols from /home/johan/projects/audio/juce/extras/audio plugin host/Builds/Linux/build/Plugin Host…done.
(gdb) run
Starting program: /home/johan/projects/audio/juce/extras/audio plugin host/Builds/Linux/build/Plugin Host
[Thread debugging using libthread_db enabled]
JUCE v2.0.28
ALSA device: hw:PCH,0 outs=2-6 ins=2-2 rates=4
ALSA device: hw:PCH,1 outs=0-0 ins=0-0 rates=0
[New Thread 0x7ffff25f0700 (LWP 976)]

Program received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ?? ()
(gdb) bt
#0 0x0000000000000000 in ?? ()
#1 0x00000000005f3745 in juce::Component::internalHierarchyChanged (this=0xae8d10) at …/…/…/…/modules/juce_gui_basics/components/juce_Component.cpp:1550
#2 0x00000000005f37d8 in juce::Component::internalHierarchyChanged (this=0xae32e0) at …/…/…/…/modules/juce_gui_basics/components/juce_Component.cpp:1562
#3 0x00000000005f37d8 in juce::Component::internalHierarchyChanged (this=0xae79d0) at …/…/…/…/modules/juce_gui_basics/components/juce_Component.cpp:1562
#4 0x00000000005f3031 in juce::Component::addChildComponent (this=0xa97990, child=0xae79d0, zOrder=4) at …/…/…/…/modules/juce_gui_basics/components/juce_Component.cpp:1373
#5 0x00000000005f308c in juce::Component::addAndMakeVisible (this=0xa97990, child=0xae79d0, zOrder=-1) at …/…/…/…/modules/juce_gui_basics/components/juce_Component.cpp:1383
#6 0x00000000006727fb in juce::ResizableWindow::setContent (this=0xa97990, newContentComponent=0xae79d0, takeOwnership=true, resizeToFitWhenContentChangesSize=false) at …/…/…/…/modules/juce_gui_basics/windows/juce_ResizableWindow.cpp:123
#7 0x000000000067289e in juce::ResizableWindow::setContentOwned (this=0xa97990, newContentComponent=0xae79d0, resizeToFitWhenContentChangesSize=false) at …/…/…/…/modules/juce_gui_basics/windows/juce_ResizableWindow.cpp:137
#8 0x0000000000414f2a in MainHostWindow::MainHostWindow (this=0xa97990) at …/…/Source/MainHostWindow.cpp:91
#9 0x0000000000413d27 in PluginHostApp::initialise (this=0xa96820, commandLine=…) at …/…/Source/HostStartup.cpp:62
#10 0x000000000067a058 in juce::JUCEApplication::initialiseApp (this=0xa96820) at …/…/…/…/modules/juce_gui_basics/application/juce_Application.cpp:181
#11 0x000000000067a332 in juce::JUCEApplication::main () at …/…/…/…/modules/juce_gui_basics/application/juce_Application.cpp:236
#12 0x000000000067a56e in juce::JUCEApplication::main (argc=1, argv=0x7fffffffe578) at …/…/…/…/modules/juce_gui_basics/application/juce_Application.cpp:297
#13 0x0000000000413a70 in main (argc=1, argv=0x7fffffffe578) at …/…/Source/HostStartup.cpp:107

[/code]

Please see post http://www.rawmaterialsoftware.com/viewtopic.php?f=5&t=10392, that fix also seems to solve the audio plugin host problem, at least everything works for me now.

Unfortunately that fix doesn’t work for me. But now I get a different flavoured crash.

(gdb) run
Starting program: /home/rory/Sourcecode/julianstorer-JUCE-a971f93/extras/audio plugin host/Builds/Linux/build/Plugin Host
[Thread debugging using libthread_db enabled]
Using host libthread_db library “/lib/x86_64-linux-gnu/libthread_db.so.1”.
JUCE v2.0.28
[New Thread 0x7ffff43fc700 (LWP 11365)]
[Thread 0x7ffff43fc700 (LWP 11365) exited]
ALSA device: hw:PCH,0 outs=2-2 ins=2-2 rates=4
ALSA device: hw:PCH,3 outs=2-8 ins=0-0 rates=7
ALSA device: hw:PCH,7 outs=2-8 ins=0-0 rates=7
ALSA device: hw:PCH,8 outs=2-8 ins=0-0 rates=7
ALSA device: hw:UA25,0 outs=0-0 ins=0-0 rates=0
[New Thread 0x7ffff43fc700 (LWP 11368)]

Program received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ?? ()
(gdb) bt
#0 0x0000000000000000 in ?? ()
#1 0x00000000005f4e49 in juce::Component::internalHierarchyChanged (
this=0xabaa70)
at …/…/…/…/modules/juce_gui_basics/components/juce_Component.cpp:1556
#2 0x00000000005f4edc in juce::Component::internalHierarchyChanged (
this=0xabcd30)
at …/…/…/…/modules/juce_gui_basics/components/juce_Component.cpp:1568
#3 0x00000000005f4edc in juce::Component::internalHierarchyChanged (
this=0xab9730)
at …/…/…/…/modules/juce_gui_basics/components/juce_Component.cpp:1568
#4 0x00000000005f4735 in juce::Component::addChildComponent (this=0xa99330,
child=0xab9730, zOrder=4)
at …/…/…/…/modules/juce_gui_basics/components/juce_Component.cpp:1379
#5 0x00000000005f4790 in juce::Component::addAndMakeVisible (this=0xa99330,
child=0xab9730, zOrder=-1)
at …/…/…/…/modules/juce_gui_basics/components/juce_Component.cpp:1389
#6 0x00000000006736f1 in juce::ResizableWindow::setContent (this=0xa99330,
newContentComponent=0xab9730, takeOwnership=true,
resizeToFitWhenContentChangesSize=false)
at …/…/…/…/modules/juce_gui_basics/windows/juce_ResizableWindow.cpp:123
#7 0x0000000000673794 in juce::ResizableWindow::setContentOwned (
this=0xa99330, newContentComponent=0xab9730,
resizeToFitWhenContentChangesSize=false)
—Type to continue, or q to quit—
at …/…/…/…/modules/juce_gui_basics/windows/juce_ResizableWindow.cpp:137
#8 0x0000000000414e30 in MainHostWindow::MainHostWindow (this=0xa99330)
at …/…/Source/MainHostWindow.cpp:91
#9 0x0000000000413c70 in PluginHostApp::initialise (this=0xa97760,
commandLine=…) at …/…/Source/HostStartup.cpp:62
#10 0x000000000067af06 in juce::JUCEApplication::initialiseApp (this=0xa97760)
at …/…/…/…/modules/juce_gui_basics/application/juce_Application.cpp:181
#11 0x000000000067b1e0 in juce::JUCEApplication::main ()
at …/…/…/…/modules/juce_gui_basics/application/juce_Application.cpp:236
#12 0x000000000067b416 in juce::JUCEApplication::main (argc=1,
argv=0x7fffffffe1d8)
at …/…/…/…/modules/juce_gui_basics/application/juce_Application.cpp:297
#13 0x00000000004139c9 in main (argc=1, argv=0x7fffffffe1d8)
at …/…/Source/HostStartup.cpp:107

That looks exactly like what I had before. To come further, I had to look at all threads:

Please clarify: is this using ALSA or JACK or both? Does any of them work?

Ok, reproduced the same as Rory with git tip, a971f93.

No crashes after commenting out the audioDeviceIOCallback call in juce_linux_ALSA.cpp around line 570. Will assume it’s ALSA related. Will try to debug later today or tomorrow.

Rory: you could help by enabling JACK in the build (Introjucer) and test, to see if it works with JACK.

The problem might not be ALSA at all but a bug in audio plugin host:

MainHostWindow.cpp initialises deviceManager with 256 in and 256 out channels.
juce_AudioProcessorPlayer.h defines a float* channels [128].
juce_AudioProcessorPlayer.cpp: AudioProcessorPlayer::audioDeviceIOCallback starts pushing all input and output channels to the float* array of size 128.
For some reason, ALSA actually gives you all the requested 256 input devices + 2 output, at least on my system. So we get memory corruption when data is written beyond the end off float* channels[128]

This explains why the bug only hits with ALSA, and why I was getting all sorts of weird results when putting debug statements in the code, and why the backtraces don’t make sense.

Rory: please try with the patch below. Patched files also attached.

[code]diff --git a/modules/juce_audio_utils/players/juce_AudioProcessorPlayer.cpp b/modules/juce_audio_utils/players/juce_AudioProcessorPlayer.cpp
index ff3a4a4…a160456 100644
— a/modules/juce_audio_utils/players/juce_AudioProcessorPlayer.cpp
+++ b/modules/juce_audio_utils/players/juce_AudioProcessorPlayer.cpp
@@ -149,6 +149,8 @@ void AudioProcessorPlayer::prepareToPlay (double newSampleRate, int newBlockSize
numInputChans = numChansIn;
numOutputChans = numChansOut;

  • jassert(numInputChans + numOutputChans <= MaxNumChannels);
  • messageCollector.reset (sampleRate);
    zeromem (channels, sizeof (channels));

diff --git a/modules/juce_audio_utils/players/juce_AudioProcessorPlayer.h b/modules/juce_audio_utils/players/juce_AudioProcessorPlayer.h
index 56b2de0…a378cfb 100644
— a/modules/juce_audio_utils/players/juce_AudioProcessorPlayer.h
+++ b/modules/juce_audio_utils/players/juce_AudioProcessorPlayer.h
@@ -94,7 +94,8 @@ private:
bool isPrepared;

 int numInputChans, numOutputChans;
  • float* channels [128];
  • enum { MaxNumChannels = 128 };

  • float* channels [MaxNumChannels];
    AudioSampleBuffer tempBuffer;

    MidiBuffer incomingMidi;
    piano:~/projects/audio/juce/extras/audio plugin host$
    piano:~/projects/audio/juce/extras/audio plugin host$ git diff
    diff --git a/extras/audio plugin host/Source/MainHostWindow.cpp b/extras/audio plugin host/Source/MainHostWindow.cpp
    index c816af8…0bd23ea 100644
    — a/extras/audio plugin host/Source/MainHostWindow.cpp
    +++ b/extras/audio plugin host/Source/MainHostWindow.cpp
    @@ -82,7 +82,7 @@ MainHostWindow::MainHostWindow()
    ScopedPointer savedAudioState (appProperties->getUserSettings()
    ->getXmlValue (“audioDeviceState”));

  • deviceManager.initialise (256, 256, savedAudioState, true);
  • deviceManager.initialise (64, 64, savedAudioState, true);

    setResizable (true, false);
    setResizeLimits (500, 400, 10000, 10000);
    [/code]

Oh, that’s a nasty looking fixed-size array. Thanks, I’ll make that more flexible.

Great, that did the trick. Only strange thing is that the the default audio IO processors in the host now have 64 inputs and 64 outputs? I had to use the fix you provided for jack in an earlier post. It doesn’t look like Jules has had time to add your changes to git yet. Thanks for this.

Rory.

Yeah, I’ve done the jack stuff too. Let me know if there’s anything missing.

thanks. looks to build and run now without any issues, apart from the default IO filters in the graph having 64 inputs and outputs. they’re just showing off I think.

Looking at juce_linux_JackAudio.cpp, I see my comment still there; it was meant as a question to you - is there any point in keeping it in the code? :? And do you know the answer?

[quote]+ void updateActivePorts()

  • {
  •    // This function is called on open(), and from jack as callback on external
    
  •    // jack port changes. Jules, is there any risk that this can happen in a
    
  •    // separate thread from the audio thread, meaning we need a critical section?
    
  •    // the below two activeOut/InputChannels are used in process()
    

[/quote]

Sorry, I think I was merging that code while on the train - I meant to come back to it, but clearly got distracted…

In fact, it can’t be done in that way at all - if the channels change, the device must stop and restart, otherwise the callbacks won’t be expecting the correct number of channels, and things will crash.

The correct thing to do is to call AudioIODeviceType::callDeviceChangeListeners() when the ports change - I’ve checked something in that should do that now if you want to try it.

[quote=“jules”]In fact, it can’t be done in that way at all - if the channels change, the device must stop and restart, otherwise the callbacks won’t be expecting the correct number of channels, and things will crash.
The correct thing to do is to call AudioIODeviceType::callDeviceChangeListeners() when the ports change - I’ve checked something in that should do that now if you want to try it.[/quote]
I see two problems with what you did here:

  1. External changes (ie from qjackctl or other jack patchbay) are not handled. Connecting two channels in an AudioDeviceSelectorComponent, and externaly disconnecting them, my audioDeviceIOCallback still thinks it’s getting two channels.

  2. What are you trying to do with activeDeviceTypes? It will always have zero size since there is no assignment to it anywhere?

Would you mind explaining in a little more detail how my solution is wrong? It works also for external changes and I haven’t been able to make it crash. What callbacks are you referring to, that would still believe they’re getting some other number of channels? How can I make my solution crash?

God, I wish I hadn’t got drawn into looking at this…

I forgot to register the device types… Done now.

Your code wouldn’t have worked because if it changed the active channel bits while the device was running, the actual AudioIODeviceCallback would suddenly start getting a different sized list of audio channel data pointers. All playback needs to be stopped and restarted so they know how many channels to expect.

That makes me sad. I hope we can fix this together, and I’m trying to help.

Ok, I get what you’re trying to do. Very very sad to say it doesn’t work. Apart from a typo that prevents it to build:

[code] ~JackAudioIODeviceType()
{

  •    activeDeviceTypes.removeFirstOccurrenceOf (this);
    
  •    activeDeviceTypes.removeFirstMatchingValue (this);
    
    }
    [/code]
    External changes do trigger AudioIODeviceType::callDeviceChangeListeners(), but that in turn doesn’t make playback restart. The callbacks audioDeviceStopped() and audioDeviceAboutToStart() are not called. Active channels are not updated. The AudioIODeviceCallback() keeps getting the same old number of channels and audio channel data pointers regardless of external changes.

I thought that was what numInputChannels/numOutputChannels arguments to AudioIODeviceCallback() were for - to know on each callback how many connected in/out channels to handle?

Even though you say I’m wrong, the fact remains that the code I sent you does in fact work. Yes - it does change the active channel bits while the device is running, but it does it in a callback on the same thread as AudioIODeviceCallback(), so there is no concurrency problem. Active channel bits are changed between calls to AudioIODeviceCallback(), which in turn always knows through numInputChannels/numOutputChannels how many active channels to handle on each call. How is that a problem? In addition, if you want it to also call AudioIODeviceType::callDeviceChangeListeners(), we could add that?

I appreciate that, I just expected this to be a 10 minute job and it’s becoming a bit of time-sink now.

This isn’t a concurrency problem. Let me try to explain again… Some callback code will not be able to cope with the list of channels changing in subsequent calls to their process method, because they expect that list to remain a constant size while running. Just because your test app can handle that doesn’t mean that all other callbacks will also work without crashing.