Channel assignment changes in audioIOCallback on the fly? (arm / linux)

Hi,

I’m using Juce 3.1.1 (commit 8b3935f12154767d37c65c1612d1bfeb93a5965f is the latest in my git log) on ARM. Everything is going well but since I updated my code to use multiple input and output channels, it seems like I’m only getting one channel out, the other channel of my main stereo out is silent. I’ve checked there is data in the output buffers I’m writing. I’m using the AudioIODeviceCallback Class directly (I’ve implemented audioDeviceIOCallback). I’ve double checked that I open the device correctly with multiple outputs and inputs. I’ve also verified there is no hardware problem.

Is it possible that this commit or version of Juce I’m using has a bug relating to multiple inputs or outputs, or could it be that there is a missing memory barrier in the Juce code such that one of the channels is lost between when I fill the output buffer and Juce hands it to ALSA? (I’m using ALSA as device type in Juce, using the direct hardware driver for the audio interface).

Thanks!
B

EDIT: I’ve done some more testing and it seems that if I put code at the beginning of the audioDeviceIOCallback to copy inputs to outputs,

            for (int i=0; i<numSamples; i++) {
                    outputChannelData[0][i] = inputChannelData[0][i];
                    outputChannelData[1][i] = inputChannelData[1][i];
                    outputChannelData[2][i] = 0.00f;
                    outputChannelData[3][i] = 0.00f;
                    outputChannelData[4][i] = 0.00f;
                    outputChannelData[5][i] = 0.00f;
            }

The input sound actually shows up at outputs 0 and 3 and not 0 and 1. However, if I do a bunch of processing and write the result at the END of the callback, the signals show up at outputs 0 and 2!

So my question is: why does the channel assignment change, or is this an effect of the lack of a memory barrier somewhere in the juce ALSA implementation or perhaps the ALSA library itself? Or is it normal that the channel assignment changes over the course of the callback and you have to deal with this in the code?

Really can’t help you with such an incredibly old version, I’m afraid! I don’t think anyone here would be able to remember what bugs might have been in there 2 years ago.

If you can replicate it with the latest codebase, we’ll take a look. Perhaps if you can’t easily update your whole app, you could write a simple test app that replicates this.

Just updated my juce tree to tag 4.3.1, right before the 5 release. I opened my project and saved it again using the projucer. This is what I get:

make V=1 CONFIG=Debug CC=arm-linux-gnueabihf-gcc CXX=arm-linux-gnueabihf-g++ TARGET_ARCH=-march=armv7-a -j4

In file included from /usr/include/x86_64-linux-gnu/sys/select.h:30:0,
                 from /usr/include/x86_64-linux-gnu/sys/time.h:29,
                 from ../../../../juce/modules/juce_core/native/juce_BasicNativeHeaders.h:216,
                 from ../../../../juce/modules/juce_core/juce_core.h:179,
                 from ../../../../juce/modules/juce_events/juce_events.h:60,
                 from ../../../../juce/modules/juce_events/juce_events.cpp:45,
                 from ../../JuceLibraryCode/juce_events.cpp:9:
../../../../juce/modules/juce_events/native/juce_linux_Messaging.cpp: In member function 'bool juce::InternalMessageQueue::sleepUntilEvent(int)':
/usr/include/x86_64-linux-gnu/bits/select.h:41:17: error: impossible constraint in 'asm'
      : "memory");           \
                 ^

I’ve just now checked out tag 5.0.0 and this is what I get when I try to build the projucer on my debian stretch system:

Compiling include_juce_gui_extra.cpp
g++ -MMD -DLINUX=1 -DNDEBUG=1 -DJUCER_LINUX_MAKE_6D53C8B4=1 -DJUCE_APP_VERSION=5.0.0 -DJUCE_APP_VERSION_HEX=0x50000 -pthread -I/usr/include/gtk-3.0 -I/usr/include/x86_64-linux-gnu -I/usr/include/webkitgtk-4.0 -I/usr/include/gtk-3.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/dbus-1.0 -I/usr/lib/x86_64-linux-gnu/dbus-1.0/include -I/usr/include/gtk-3.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/harfbuzz -I/usr/include/pango-1.0 -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/libpng16 -I/usr/include/libsoup-2.4 -I/usr/include/libxml2 -I/usr/include/webkitgtk-4.0 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -pthread -I…/…/JuceLibraryCode -I…/…/…/…/modules -march=native -O3 -std=c++11 -std=c++11 -DJucePlugin_Build_VST=0 -DJucePlugin_Build_VST3=0 -DJucePlugin_Build_AU=0 -DJucePlugin_Build_AUv3=0 -DJucePlugin_Build_RTAS=0 -DJucePlugin_Build_AAX=0 -DJucePlugin_Build_Standalone=0 -o “build/intermediate/Release/include_juce_gui_extra_6dee1c1a.o” -c "…/…/JuceLibraryCode/include_juce_gui_extra.cpp"
In file included from …/…/…/…/modules/juce_gui_extra/juce_gui_extra.cpp:140:0,
from …/…/JuceLibraryCode/include_juce_gui_extra.cpp:9:
…/…/…/…/modules/juce_gui_extra/native/juce_linux_X11_WebBrowserComponent.cpp: In member function ‘int juce::GtkChildProcess::entry()’:
…/…/…/…/modules/juce_gui_extra/native/juce_linux_X11_WebBrowserComponent.cpp:166:69: error: ‘WEBKIT_HARDWARE_ACCELERATION_POLICY_NEVER’ was not declared in this scope
webkit_settings_set_hardware_acceleration_policy (settings, WEBKIT_HARDWARE_ACCELERATION_POLICY_NEVER);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
…/…/…/…/modules/juce_gui_extra/native/juce_linux_X11_WebBrowserComponent.cpp:166:110: error: ‘webkit_settings_set_hardware_acceleration_policy’ was not declared in this scope
webkit_settings_set_hardware_acceleration_policy (settings, WEBKIT_HARDWARE_ACCELERATION_POLICY_NEVER);
^
Makefile:417: recipe for target ‘build/intermediate/Release/include_juce_gui_extra_6dee1c1a.o’ failed
make: *** [build/intermediate/Release/include_juce_gui_extra_6dee1c1a.o] Error 1

This is now fixed on develop. Thanks for reporting.

thanks, which of the above did you fix?

The latter post on WEBKIT_HARDWARE_ACCELERATION_POLICY_NEVER.

The error:

 error: impossible constraint in 'asm'
  : "memory")

is not an error in JUCE land. Seems like something is strange in your libc.

that impossible constraint error probably has to do with pkg-config using the wrong path to search for .pc files. It should use the path relating to arm-linux-gnueabihf but instead it is using the x86_64-linux-gnu one? what is the recommended way to deal with that?

Ahh you are cross-compiling: then you want to make sure that you set the environment variable PKG_CONFIG_LIBDIR to the lib folder of the target system.

It might be easier, however, to follow the instructions here:

thanks - is the support for embedded linux only there for juce v5 and later?

Yes, JUCE v5 and later contain some important improvements/fixes so that JUCE can run on headless embedded systems.