Audio problems

Got it also on debian/amd64. Applying that change:

[code] if (failed (snd_pcm_sw_params_current (handle, swParams))
|| failed (snd_pcm_sw_params_set_silence_threshold (handle, swParams, 0))

  •        || failed (snd_pcm_sw_params_set_silence_size (handle, swParams, INT_MAX))
    
  •        || failed (snd_pcm_sw_params_set_silence_size (handle, swParams, 0))
           || failed (snd_pcm_sw_params_set_start_threshold (handle, swParams, samplesPerPeriod))
           || failed (snd_pcm_sw_params_set_stop_threshold (handle, swParams, INT_MAX))
           || failed (snd_pcm_sw_params (handle, swParams)))
    

[/code]

fixed it, now alsa output is working.

Btw kraken, what is the status of your jack output ? is it a dead project ?

it’s not dead but it has not transformed as an audio device already.
lately i lose all my free time for working on this :frowning:

here it is the juce_linux_JackAudio.cpp

actually it is tested under linux only, but since it is possible to write a jack client for windows and mac also, this could be easily moved in a shared place.

/*
==============================================================================

   This file is part of the JUCE library - "Jules' Utility Class Extensions
   Copyright 2004-7 by Raw Material Software ltd.

  ------------------------------------------------------------------------------

   JUCE can be redistributed and/or modified under the terms of the
   GNU General Public License, as published by the Free Software Foundation;
   either version 2 of the License, or (at your option) any later version.

   JUCE is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with JUCE; if not, visit www.gnu.org/licenses or write to the
   Free Software Foundation, Inc., 59 Temple Place, Suite 330,
   Boston, MA 02111-1307 USA

  ------------------------------------------------------------------------------

   If you'd like to release a closed-source product which uses JUCE, commercial
   licenses are also available: visit www.rawmaterialsoftware.com/juce for
   more information.

  ==============================================================================

*/

#include "../../../juce_Config.h"

#if JUCE_BUILD_GUI_CLASSES

#if JUCE_JACK

#include "linuxincludes.h"

//==============================================================================
/* Got an include error here? If so, you've either not got jack-audio-connection-kit
   installed, or you've not got your paths set up correctly to find its header files.

   If you don't have the jack-audio-connection-kit library and don't want to build
   Juce with low latency audio support, just disable the JUCE_JACK flag in juce_Config.h

*/
#include <jack/jack.h>
#include <jack/transport.h>

//==============================================================================
#include "../../../src/juce_core/basics/juce_StandardHeader.h"

BEGIN_JUCE_NAMESPACE

#include "../../../src/juce_appframework/audio/devices/juce_AudioIODeviceType.h"
#include "../../../src/juce_core/threads/juce_Thread.h"
#include "../../../src/juce_core/threads/juce_ScopedLock.h"
#include "../../../src/juce_core/basics/juce_Time.h"
#include "../../../src/juce_core/io/files/juce_File.h"
#include "../../../src/juce_core/io/files/juce_FileInputStream.h"
#include "../../../src/juce_core/basics/juce_Singleton.h"
#include "../../../src/juce_appframework/audio/dsp/juce_AudioDataConverters.h"
#include "../../../src/juce_appframework/audio/dsp/juce_AudioSampleBuffer.h"

static const int maxNumChans = 64;
static const char* defaultJackAudioDeviceName = "JuceJack";

//==============================================================================
class JackAudioIODevice   : public AudioIODevice
{
public:
    JackAudioIODevice (const String& deviceName)
        : AudioIODevice (deviceName, T("JACK")),
          isOpen_ (false),
          isStarted (false),
          selectedDeviceName (deviceName),
          callback (0),
          totalNumberOfInputChannels (0),
          totalNumberOfOutputChannels (0),
          client (0),
          emptyBuffer (1, 4096)
    {
        jack_status_t status;
        client = jack_client_open (defaultJackAudioDeviceName, JackNoStartServer, &status);

        if (client == 0)
        {
    		if (status & JackServerFailed || status & JackServerError)
    			printf ("Unable to connect to JACK server\n");
    		if (status & JackVersionError)
    			printf ("Client's protocol version does not match\n");
    		if (status & JackInvalidOption)
    			printf ("The operation contained an invalid or unsupported option\n");
    		if (status & JackNameNotUnique)
    			printf ("The desired client name was not unique\n");
    		if (status & JackNoSuchClient)
    			printf ("Requested client does not exist\n");
    		if (status & JackInitFailure)
    			printf ("Unable to initialize client\n");
        }
        else
        {
            jack_set_error_function (JackAudioIODevice::errorCallback);

            // open input ports
            StringArray inputChannels (getInputChannelNames());
            for (int i = 0; i < inputChannels.size(); i++)
            {
                String inputName;
                inputName << "in_" << (++totalNumberOfInputChannels);

                jack_port_t* input =
                        jack_port_register (client, (const char*) inputName, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);

                inputPorts.add (input);
            }

            // open output ports
            StringArray outputChannels (getOutputChannelNames());
            for (int i = 0; i < outputChannels.size (); i++)
            {
                String outputName;
                outputName << "out_" << (++totalNumberOfOutputChannels);

                jack_port_t* output =
                        jack_port_register (client, (const char*) outputName, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);

                /* XXX - HOW TO KNOW THIS HERE IF IT'S THE APPLICATION CALLBACK THAT IS INTRODUCING LATENCY ? */

                // jack_port_set_latency (output, 0);

                outputPorts.add (output);
            }
        }
    }

    ~JackAudioIODevice()
    {
        if (client)
        {
            close ();

            jack_client_close (client);
            client = 0;
        }
    }

    const StringArray getOutputChannelNames()
    {
        StringArray inputNames;
        
        const char** ports = jack_get_ports (client, 0, 0, /* JackPortIsPhysical | */ JackPortIsInput);

        if (ports && ports[0])
        {
            int j = 0;
            while (ports[j])
            {
                String portName (ports[j++]);
                
                if (portName.upToFirstOccurrenceOf (T(":"), false, false) == selectedDeviceName)
                    inputNames.add (portName.fromFirstOccurrenceOf (T(":"), false, false));
            }
            free (ports);
        }

        return inputNames;
    }

    const StringArray getInputChannelNames()
    {
        StringArray outputNames;
        
        const char** ports = jack_get_ports (client, 0, 0, /* JackPortIsPhysical | */ JackPortIsOutput);
        if (ports && ports[0])
        {
            int j = 0;
            while (ports[j])
            {
                String portName (ports[j++]);
                
                if (portName.upToFirstOccurrenceOf (T(":"), false, false) == selectedDeviceName)
                    outputNames.add (portName.fromFirstOccurrenceOf (T(":"), false, false));
            }
            free (ports);
        }

        return outputNames;
    }

    int getNumSampleRates()
    {
        return client ? 1 : 0;
    }

    double getSampleRate (int index)
    {
        return client ? jack_get_sample_rate (client) : 0;
    }

    int getNumBufferSizesAvailable()
    {
        return client ? 1 : 0;
    }

    int getBufferSizeSamples (int index)
    {
        return client ? jack_get_buffer_size (client) : 0;
    }

    int getDefaultBufferSize()
    {
        return client ? jack_get_buffer_size (client) : 0;
    }

    const String open (const BitArray& inputChannels,
                       const BitArray& outputChannels,
                       double sampleRate,
                       int bufferSizeSamples)

    {
        if (! client)
        {
            return T("JACK error: client not started as jack server running");
        }

        close();

        // activate client !        
        jack_set_process_callback (client, JackAudioIODevice::processCallback, this);

        jack_on_shutdown (client, JackAudioIODevice::shutdownCallback, this);

        jack_activate (client);
        isOpen_ = true;

        // auto connect inputs
        if (inputChannels.getHighestBit() >= 0)
        {
            const char** ports = jack_get_ports (client, 0, 0, /* JackPortIsPhysical | */ JackPortIsOutput);
            if (ports && ports[0])
            {
                int numInputChannels = inputChannels.getHighestBit () + 1;
                for (int i = 0; i < numInputChannels; ++i)
                {
                    if (ports[i])
                    {
                        String portName (ports[i]);
                        if (inputChannels[i] && portName.upToFirstOccurrenceOf (T(":"), false, false) == selectedDeviceName)
                        {
                            int error = jack_connect (client, ports[i], jack_port_name ((jack_port_t*) inputPorts[i]));
                            if (error)
                                printf ("Cannot connect input port %d (%s) >> %d \n", i, ports[i], error);
                        }
                    }
                }
                free (ports);
            }
        }

        // auto connect outputs
        if (outputChannels.getHighestBit() >= 0)
        {
            const char** ports = jack_get_ports (client, 0, 0, /* JackPortIsPhysical | */ JackPortIsInput);
            if (ports && ports[0])
            {
                int numOutputChannels = outputChannels.getHighestBit () + 1;
                for (int i = 0; i < numOutputChannels; ++i)
                {
                    if (ports[i])
                    {
                        String portName (ports[i]);
                        if (outputChannels[i] && portName.upToFirstOccurrenceOf (T(":"), false, false) == selectedDeviceName)
                        {
                            int error = jack_connect (client, jack_port_name ((jack_port_t*) outputPorts[i]), ports[i]);
                            if (error)
                                printf ("Cannot connect output port %d (%s) >> %d \n", i, ports[i], error);
                        }
                    }
                }
                free (ports);
            }
        }

        return String::empty;
    }

    void close()
    {
        stop();

        if (client)
        {
            jack_deactivate (client);

            jack_set_process_callback (client, JackAudioIODevice::processCallback, 0);
            jack_on_shutdown (client, JackAudioIODevice::shutdownCallback, 0);
        }

        isOpen_ = false;
    }

    bool isOpen()
    {
        return isOpen_;
    }

    int getCurrentBufferSizeSamples()
    {
        return getBufferSizeSamples (0);
    }

    double getCurrentSampleRate()
    {
        return getSampleRate (0);
    }

    int getCurrentBitDepth()
    {
        return 32;
    }

    const BitArray getActiveOutputChannels() const
    {
        BitArray outputBits;

        for (int i = 0; i < outputPorts.size(); i++) {
            if (jack_port_connected ((jack_port_t*) outputPorts [i]))
                outputBits.setBit (i);
        }
        
        return outputBits;
    }

    const BitArray getActiveInputChannels() const
    {
        BitArray inputBits;

        for (int i = 0; i < inputPorts.size(); i++) {
            if (jack_port_connected ((jack_port_t*) inputPorts [i]))
                inputBits.setBit (i);
        }
        
        return inputBits;
    }

    int getOutputLatencyInSamples()
    {
        int latency = 0;
        
        for (int i = 0; i < outputPorts.size(); i++)
            latency = jmax (latency, (int) jack_port_get_total_latency (client, (jack_port_t*) outputPorts [i]));
    
        return latency;
    }

    int getInputLatencyInSamples()
    {
        int latency = 0;
        
        for (int i = 0; i < inputPorts.size(); i++)
            latency = jmax (latency, (int) jack_port_get_total_latency (client, (jack_port_t*) inputPorts [i]));
    
        return latency;
    }

    void start (AudioIODeviceCallback* callback_)
    {
        if (! isOpen_)
            callback_ = 0;

        callback = callback_;

        if (callback != 0)
            callback->audioDeviceAboutToStart (this);

        isStarted = (callback != 0);
    }

    void process (int numSamples)
    {
        int i, numActiveInChans = 0, numActiveOutChans = 0;

        for (i = 0; i < totalNumberOfInputChannels; ++i)

        {
            jack_default_audio_sample_t *in =
                (jack_default_audio_sample_t *) jack_port_get_buffer (
                                                        (jack_port_t*) inputPorts.getUnchecked(i), numSamples);

            if (in != 0)
                inChans [numActiveInChans++] = (float*) in;
        }

        while (numActiveInChans < totalNumberOfInputChannels)
            inChans [numActiveInChans++] = emptyBuffer.getSampleData (0, 0);

        for (i = 0; i < totalNumberOfOutputChannels; ++i)
        {
            jack_default_audio_sample_t *out =
                (jack_default_audio_sample_t *) jack_port_get_buffer (
                                                        (jack_port_t*) outputPorts.getUnchecked(i), numSamples);

            if (out != 0)
                outChans [numActiveOutChans++] = (float*) out;
        }

        i = 0;
        while (numActiveOutChans < totalNumberOfOutputChannels)
            outChans [numActiveOutChans++] = emptyBuffer.getSampleData (++i, 0);

        if (callback != 0)
        {
            callback->audioDeviceIOCallback ((const float**) inChans,
                                             numActiveInChans,
                                             outChans,
                                             numActiveOutChans,
                                             numSamples);
        }
        else
        {
            for (int i = 0; i < totalNumberOfOutputChannels; ++i)
                zeromem (outChans[i], sizeof (float) * numSamples);
        }
    }

    void stop()
    {
        AudioIODeviceCallback* const oldCallback = callback;

        start (0);

        if (oldCallback != 0)
            oldCallback->audioDeviceStopped();
    }

    bool isPlaying()
    {
        return isStarted;
    }

    const String getLastError()
    {
        return String::empty;
    }

private:

    static void threadInitCallback (void* callbackArgument)
    {
        printf ("jack started");
    }
    
    static void shutdownCallback (void* callbackArgument)
    {
        printf ("jack shutdown");
    
        JackAudioIODevice* device = (JackAudioIODevice*) callbackArgument;
    
        if (device)
            device->close ();
    }
    
    static int processCallback (jack_nframes_t nframes, void* callbackArgument)
    {
        JackAudioIODevice* device = (JackAudioIODevice*) callbackArgument;

        if (device)
            device->process (nframes);

        return 0;
    }
    
    static void errorCallback (const char *msg)
    {
        printf ("%s\n", msg);
    }

    bool isOpen_, isStarted;

    String selectedDeviceName;
    AudioIODeviceCallback* callback;
    
    float* inChans [maxNumChans];
    int totalNumberOfInputChannels;
    float* outChans [maxNumChans];
    int totalNumberOfOutputChannels;

    jack_client_t *client;
    VoidArray inputPorts;
    VoidArray outputPorts;

    AudioSampleBuffer emptyBuffer;
};


//==============================================================================
class JackAudioIODeviceType  : public AudioIODeviceType
{
public:
    //==============================================================================
    JackAudioIODeviceType()
        : AudioIODeviceType (T("JACK")),
          hasScanned (false)
    {
    }

    ~JackAudioIODeviceType()
    {
    }
    //==============================================================================
    void scanForDevices()
    {
        printf ("JackAudioIODeviceType::scanForDevices\n");
    
        hasScanned = true;
        names.clear();

        // open a dummy client
        jack_status_t status;
        jack_client_t* client;
        const char** ports = 0;
        
        client = jack_client_open ("JackAndMrHide", JackNoStartServer, &status);
        if (client == 0)
        {
    		if (status & JackServerFailed || status & JackServerError)
    			printf ("Unable to connect to JACK server\n");
    		if (status & JackVersionError)
    			printf ("Client's protocol version does not match\n");
    		if (status & JackInvalidOption)
    			printf ("The operation contained an invalid or unsupported option\n");
    		if (status & JackNameNotUnique)
    			printf ("The desired client name was not unique\n");
    		if (status & JackNoSuchClient)
    			printf ("Requested client does not exist\n");
    		if (status & JackInitFailure)
    			printf ("Unable to initialize client\n");
        }
        else
        {
            // scan for output devices
            ports = jack_get_ports (client, 0, 0, /* JackPortIsPhysical | */ JackPortIsOutput);
            if (ports && ports[0])
            {
                int j = 0;
                while (ports [j])
                {
                    String clientName (ports [j++]);
                    clientName = clientName.upToFirstOccurrenceOf (T(":"), false, false);                    
                    if (clientName != String (defaultJackAudioDeviceName))
                        names.add (clientName);
                }

                free (ports);
            }

            // scan for input devices
            ports = jack_get_ports (client, 0, 0, /* JackPortIsPhysical | */ JackPortIsInput);
            if (ports && ports[0])
            {
                int j = 0;
                while (ports [j])
                {
                    String clientName (ports [j++]);
                    clientName = clientName.upToFirstOccurrenceOf (T(":"), false, false);                    
                    if (clientName != String (defaultJackAudioDeviceName))
                        names.add (clientName);
                }

                free (ports);
            }

            jack_client_close (client);
        }
    }

    const StringArray getDeviceNames (const bool /*preferInputNames*/) const
    {
        jassert (hasScanned); // need to call scanForDevices() before doing this

        StringArray namesCopy (names);
        namesCopy.removeDuplicates (true);
        return namesCopy;
    }

    const String getDefaultDeviceName (const bool /*preferInputNames*/,
                                       const int /*numInputChannelsNeeded*/,
                                       const int /*numOutputChannelsNeeded*/) const
    {
        jassert (hasScanned); // need to call scanForDevices() before doing this
        return names[0];
    }

    AudioIODevice* createDevice (const String& deviceName)
    {
        jassert (hasScanned); // need to call scanForDevices() before doing this
        const int index = names.indexOf (deviceName);

        if (index >= 0)
            return new JackAudioIODevice (deviceName);

        return 0;
    }
    //==============================================================================
    juce_UseDebuggingNewOperator

private:

    StringArray names;
    bool hasScanned;

    JackAudioIODeviceType (const JackAudioIODeviceType&);
    const JackAudioIODeviceType& operator= (const JackAudioIODeviceType&);
};

//==============================================================================
AudioIODeviceType* juce_createJackAudioIODeviceType()
{
    return new JackAudioIODeviceType();
}


END_JUCE_NAMESPACE


//==============================================================================
#else  // if JACK is turned off..

#include "../../../src/juce_core/basics/juce_StandardHeader.h"

BEGIN_JUCE_NAMESPACE

#include "../../../src/juce_appframework/audio/devices/juce_AudioIODeviceType.h"

AudioIODeviceType* juce_createJackAudioIODeviceType()    { return 0; }

END_JUCE_NAMESPACE

#endif

#endif

it needs also you put this lines in juce_AudioIODeviceType.cpp and tweaks juce_Config.h by putting JUCE_JACK define (besides JUCE_ALSA)

//==============================================================================
extern AudioIODeviceType* juce_createDefaultAudioIODeviceType();

#if JUCE_WIN32 && JUCE_ASIO
  extern AudioIODeviceType* juce_createASIOAudioIODeviceType();
#endif

#if JUCE_WIN32 && JUCE_WDM_AUDIO
  extern AudioIODeviceType* juce_createWDMAudioIODeviceType();
#endif


#if JUCE_LINUX && JUCE_JACK
  extern AudioIODeviceType* juce_createJackAudioIODeviceType();
#endif


//==============================================================================
void AudioIODeviceType::createDeviceTypes (OwnedArray <AudioIODeviceType>& list)
{
    AudioIODeviceType* const defaultDeviceType = juce_createDefaultAudioIODeviceType();

    if (defaultDeviceType != 0)
        list.add (defaultDeviceType);

#if JUCE_WIN32 && JUCE_ASIO
    list.add (juce_createASIOAudioIODeviceType());
#endif

#if JUCE_WIN32 && JUCE_WDM_AUDIO
    list.add (juce_createWDMAudioIODeviceType());
#endif

#if JUCE_LINUX && JUCE_JACK
    list.add (juce_createJackAudioIODeviceType());
#endif
}

hope it will be included in the main trunk :slight_smile:

(EDIT)

Thanks! I’ve actually already got a half-written jack audio driver that I wrote a while ago and never had time to finish. I’ll grab this stuff and use it as a sanity-check when I eventually get time to go through and sort it out.

there are only a couple of things to note.

  1. in auto connecting to device, when using jack_get_ports the real ports might come in wrong order, so you might end connecting JuceJack:out_1 with system:playback_2 and JuceJack:out_2 with system:playback_1… not a big deal (but could be handled in a better form, just a matter of StringArray and Comparable) but is better to connect a application left channel with your audio card left output :slight_smile:

  2. it actually lets you connect to a device that have input, outputs or both (like system device for example which is your actual card). but when you connect to that device, only its input/outputs ports will be displayed. would be cool to connect to a “generic” jack device, and then display EVERY device:port combination (even if could be a huge list) so i can connect to the output card while sampling from another application input.
    anyway for now i prefer this way (much more clean), as i usually use the patchbay feature of qjackctl for restoring complex patching…
    give a think about this !

cheers mate :slight_smile:

Asking for the boundary instead of guessing it seems to fix the alsa problems:

	if (failed(snd_pcm_sw_params_current(handle, swParams)))
	{
		return false;
	}
	snd_pcm_uframes_t boundary;
	if (failed(snd_pcm_sw_params_get_boundary(swParams, &boundary))) 
	{
		return false;
	}
	
    if (failed (snd_pcm_sw_params_set_silence_threshold (handle, swParams, 0))
		|| failed (snd_pcm_sw_params_set_silence_size (handle, swParams, boundary))
        || failed (snd_pcm_sw_params_set_start_threshold (handle, swParams, samplesPerPeriod))
		|| failed (snd_pcm_sw_params_set_stop_threshold (handle, swParams, boundary))
        || failed (snd_pcm_sw_params (handle, swParams)))
    {
        return false;
    }

Also, SND_PCM_FORMAT_S24_*E is actually 24 bit data sign extended to 32 bits so it looks like the wrong converter is used.

Good call on the boundary thing, I’ll get that sorted out.

Annoyingly I don’t already have a converter for a sign-extended 24-bit word, but I think the code will still be correct if I change it to SND_PCM_FORMAT_S24_3LE, which is a 3-byte 24 bit format. Hopefully most devices won’t be so restricted as to only be able to handle the 4-byte version!

To be honest I’m not sure it’s actually required to be sign extended, but it seems safest to assume that when writing data at least.

Dunno if SND_PCM_FORMAT_S24_3LE support is usual.
At least on some embedded systems, that kind of DMA transfer is impossible.

It is probably also a good idea to use the plughw: device instead of hw:.
plughw: is supposed to do the format conversions for you.
Using hw: might cause alsa to use 16 bit output even if 24 bit is possible if the 24 bit format is wrong.
Although you have taken care of that, the hw: device may not even use native endianness.

On the other hand, if you are targeting a particular embedded device, using hw: and only the exact format the hardware support is a good idea.
When profiling, I have seen the hw: device use a terribly inefficient float to int conversion with interleaving.

On the other hand, plughw: may do some kind of conversion you absolutely do not want, like sample rate conversion.

Maybe trying hw: first and then plughw: is the optimal solution?

Perhaps one should be happy with any sound at all using alsa :?

I did originally use plughw, and there were endless problems with it glitching, not opening, etc etc, but maybe as a second try it’d be good.

What I really need to do is get round to adding jack support. Been meaning to sort that out for ages now…

Strange, I haven’t had any such problem, but who knows what kind of weird and inefficient converter alsa may decide to use.

Maybe just hw is best then, but to avoid 16 bit output, it is probably a good idea to add SND_PCM_FORMAT_S24_*E again.

I do get sound in JUCE Demo on Gentoo AMD64 now anyway.
But for some reason the default device does not work, (the infamous: Invalid argument), I have to select it from Audio Settings first to make it work.

Today I made my first Linux experiences (Ubuntu 8.10). I built JUCE 1.46, but I also get the “Invalid Argument” message. I tried the #define DD “default” trick, it does not help. I also tried the other things, without success. My card is a Delta1010LT with an ICE1712 chip. [EDIT: Also my U46DJ USB soundcard doesn’t work].

Questions:

  • Does the tip provide some kind of audio support for this card, via ALSA? [EDIT: No it doesn’t. Still the same. It’s no ALSA, because other apps work with ALSA.]
  • Since I’m a LINUX newbie, and if anybody got some similar problems with a similar card, has anybody got some advice what I should do next?

Well, well. I figured out how to debug on Linux, so I debugged the ALSA code and found out where JUCE exactly fails with the “Invalid Argument” message.

It’s the line snd_pcm_hw_params_set_channels (handle, hwParams, numChannels) that fails! numChannels is 2, but my card has 10 outs and 12 ins, and I strongly suspect that it would work if numChannels was set to the real number of outs or ins.

Hope this helps, looking forward to see ALSA work in JUCE.

Bingo. I was right. I modified the JUCE Audio Demo in Line 452 to this:

[code]const String error (audioDeviceManager.initialise (12, /* number of input channels */

                                                       10, /* number of output channels */

                                                       0, /* no XML settings.. */

                                                       true  /* select default device on failure */))[/code]

and now my soundcard works!

It seems that this is a JUCE bug. In fact the output of AudioIODevice::testDevice() clearly prints that my soundcard has a minimum of 10 outs and a maximum of 10 outs, as well as a minimum of 12 inputs and a maximum of 12 inputs. So passing 1 as number of inputs and 2 as number of outputs to ALSA can only fail !?
By the way, if the failed() funciton would print the Line number where it failed or the function name that failed would also help a little bit to find out such bugs :roll:

use my version of the linux platform specific alsa code:

http://www.anticore.org/tmp/juce_linux_Audio.cpp

i can add also the LINE macro when you call the function.

cheers !

have already fixed the code for my purposes (just always uses all IO channels of the soundcard, worked well for me), cheers kraken.

So you’re suggesting that doing something like this would sort it out?

if (! outputDevice->setParameters ((unsigned int) sampleRate, jmax (minChansOut, currentOutputChans.getHighestBit() + 1), bufferSize)) {

?

(and obviously the same for the number of input channels)

I’d rather write:

if (! outputDevice->setParameters ((unsigned int) sampleRate, jlimit (minChansOut, maxChansOut, currentOutputChans.getHighestBit() + 1), bufferSize)) {

It’s safer I guess. Yes, that should work. At least on my PC this was the problem that made it impossible to open the ALSA device.

Ok, I’ll put that in and see if it works.