Spencer Russell | 21 Aug 18:28 2014

Waiting on a file descriptor for reading?

I'm looking into the read/write API rather than the gymnastics I'm currently doing to get the callback API working in my Julia wrapper. I'm trying to figure out the best way to periodically run my audio task to process input and supply output.

I don't want to use the blocking versions because if there's no audio available to process I'd like to hand control back to the Julia event loop so other tasks can run. 

One option is to just poll on a timer and check to see if there's data to handle. This seems pretty feasible and simple but feels sloppy.

Julia tasks can wait on a file descriptor, so what I'd love to do is get a file descriptor from PortAudio that would get written to whenever there was new input data, so my task would immediately wake up and handle the new input.

It looks like exposing a file descriptor was discussed way back in 2003:

Is there a good way to do this, or should I just stick to the polling approach?

Portaudio mailing list
Portaudio <at> music.columbia.edu
Sebastian Gesemann | 21 Aug 17:49 2014

Version Problem, Portaudio-Binding for Rust


I've written a Portaudio binding for the Rust programming language.
This means, I don't use the header portaudio.h during compilation. And
that makes me a little concerned about different versions of
Portaudio. For example, if some Portaudio structs or enums change with
a newer Portaudio version, my binding will still link successfully but
probably stop working and possibly crash.

I'm open for suggestions. Ideally, these discrepancies are detected at
compile-time or at link-time of the binding. But I'm also fine with a
runtime check that simply uses Portaudio's version to tell whether
it's compatible or not. But to implement this, I would have to know
the policy around Portaudio's versioning. For example, it would be
incredibly helpful, if someone told me something along the lines of
"Every version below 2000 should be binary-backwards compatible to
programs you build using a V19 header" or something like this.

Also, is there any important difference between version 1899 and 1900?
The lbportaudio2 I have installed on my system reports version 1899 to
me while the accompanioning header says in the comments that I should
expect something like 1900 as version number.

matthew coleman | 19 Aug 10:37 2014

Faster initialization of alsa

<at> Alan,  Thanks for your support.  I would have replied sooner had I not
been so novice at using this basic mailing list.

My ubuntu 12.04 decided to spontaneously upgrade itself to 14.04 oblivion.
 So much for LTS!  Mint cinnamon is now installed and that does not have
the alsa waiting problems.  I am still missing some bluetooth rfcomm
settings that might slow it down again.

If I get stuck again then I will investigate a software modification.

Portaudio mailing list
Portaudio <at> music.columbia.edu
Stephen Blinkhorn | 18 Aug 03:07 2014

Bus error when calling Pa_StartStream


First post here. I have adapted one of the examples with the intention of creating a pass-thru effect for an
installation on OS X. I’m using the latest stable build. I can successfully route audio from my input
source to the built-in output, however, when I attempt to address my Digidesign Mbox card I get a bus error
when calling Pa_StartStream.

I use two other PortAudio apps (PD, Audacity) and they both successfully address this hardware on this
system. So I’m wondering if anything has changed in recent builds or if there is something obviously
wrong with my code? Here’s the code I am using:

Thanks in advance for any help (and yes, I know the Mbox is rather old now :)

static int patestCallback2( const void *inputBuffer, void *outputBuffer,
                           unsigned long framesPerBuffer,
                           const PaStreamCallbackTimeInfo* timeInfo,
                           PaStreamCallbackFlags statusFlags,
                           void *userData )
	float *in = (float*)inputBuffer;
	float *out = (float*)outputBuffer;
	for( int i=0; i<framesPerBuffer*2; i++ )
    	*out++ = *in++;
    return 0;

int main(void);
int main(void)
    PaStream *stream;
    PaError err;

    printf("PortAudio Test: input to output routing.\n");
    /* Initialize our data for use by callback. */
    data.left_phase = data.right_phase = 0.0;
    /* Initialize library before making any other calls. */
    err = Pa_Initialize();
    if( err != paNoError ) goto error;
	int numDevices;
	numDevices = Pa_GetDeviceCount();
	int inputDeviceIdx = 4;
	int outputDeviceIdx = 2;

    // setup device
	double srate = Pa_GetDeviceInfo( outputDeviceIdx )->defaultSampleRate;
	srate = 44100.0;
	unsigned long framesPerBuffer = 512;

	PaSampleFormat fmt = paFloat32 | paNonInterleaved;
	PaStreamParameters inputParameters;
	bzero( &inputParameters, sizeof( inputParameters ) );
	inputParameters.channelCount = Pa_GetDeviceInfo( inputDeviceIdx )->maxInputChannels;
	inputParameters.device = inputDeviceIdx;
	inputParameters.sampleFormat = paFloat32;
	inputParameters.suggestedLatency = Pa_GetDeviceInfo(inputDeviceIdx)->defaultLowInputLatency ;
	inputParameters.hostApiSpecificStreamInfo = NULL;
	PaStreamParameters outputParameters;
	bzero( &outputParameters, sizeof( outputParameters ) );
	outputParameters.channelCount = Pa_GetDeviceInfo( outputDeviceIdx )->maxOutputChannels;;
	outputParameters.device = outputDeviceIdx;
	outputParameters.sampleFormat = paFloat32;
	outputParameters.suggestedLatency =
Pa_GetDeviceInfo(outputDeviceIdx)->defaultLowOutputLatency ;
	outputParameters.hostApiSpecificStreamInfo = NULL;
	err = Pa_IsFormatSupported(&inputParameters, &outputParameters, srate);
    if (err != paFormatIsSupported) {
    	printf("Error: stream format invalid.\n");
    	return err;

	err = Pa_OpenStream(	&stream,
							&inputParameters, &outputParameters,
							srate, framesPerBuffer, paNoFlag,
    if( err != paNoError ) goto error;
    err = Pa_StartStream( stream );
    if( err != paNoError ) goto error;

    /* Sleep for several seconds. */
    err = Pa_StopStream( stream );
    if( err != paNoError ) goto error;
    err = Pa_CloseStream( stream );
    if( err != paNoError ) goto error;
    printf("Test finished.\n");
    return err;
    fprintf( stderr, "An error occured while using the portaudio stream\n" );
    fprintf( stderr, "Error number: %d\n", err );
    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
    return err;
Sebastian Gesemann | 17 Aug 19:14 2014

Library versions, struct versions, C header, compatibility


I've started a project of creating a Portaudio binding for the Rust
programming language [1] and I'm wondering how I should deal with the
possibility of linking against incompatible Portaudio versions.

I ran into the following situation: According to the portaudio.h I
have installed on my Xubuntu 14.04 (package "portaudio19-dev") the
PaStreamInfo struct should have a structVersion field with the value
of one. The package portaudio19-dev depends on libportaudio2 (=
19+svn20140130-1) which contains the library's binaries. However, if I
create a stream and ask for a PaStreamInfo pointer, the value of the
structVersion field seems to be zero instead of one.

After browsing the Portaudio wiki I learned that the plan is to get
rid of the structVersion fields and that version checking should be
done via Pa_GetVersion.

Therefore, I would like to know the semantics of this version number.
At what point should I consider the installed Pulseaudio library to be
incompatible even if my binding manages to link successfully? Since I
sort of rewrote the portaudio.h header myself in Rust for the binding
I think I have to rely on some kind of version number to catch other
errors like mismatching enums, or changed function parameters that
would otherwise lead to a crash probably.


[1] https://github.com/sellibitze/rustaudio
Robert Bielik | 15 Aug 08:41 2014

Re: Assert FALSE at pa_win_wdmks.c:1036 FindStartConnectionFrom()

Hi Stefan, Leland et al,

"Shortly" is a very relative measurement :) Anyway, I have tested Lelands patch and this should at least fix
some of the problems you've seen Stefan.

It is committed to the trunk (https://www.assembla.com/code/portaudio/subversion/changesets/1932)

Let us know how it turns out.


-------- Ursprungligt meddelande --------
Ämne: Re: Fwd: Re: [Portaudio] WDM/KS PinRegisterNotificationHandle and PinUnregisterNotificationHandle
Datum: Wed, 09 Apr 2014 10:49:10 -0500
Från: Leland <portaudio <at> homerow.net>
Till: Robert Bielik <robert.bielik <at> dirac.se>

On 4/9/2014 9:43 AM, Robert Bielik wrote:
> Hi Leland,
> Finally I've had the time to apply/test the patch, and I'll commit it
> shortly to the trunk.

Cool...and I know what you mean about time...never can get enough of it. 

Spencer Russell | 14 Aug 19:40 2014

Callback sometimes goes into overdrive (100% CPU)

My system is a bit complex at the moment and I'm having trouble getting to something more minimal to reproduce the problem, but I'm hoping someone can point me in the right direction.

On my Linux machine, sometimes the audio process callback starts getting called as fast as it can, instead of once per block of audio, as I'd expect. I added some timing to the callback to measure how long the calling period is, and when everything's normal it was around every 30ms and CPU usage was low. When it starts going crazy the callback is getting called every 10 microseconds or so, and my CPU usage is pegged at 100%.

Part of what makes this complicated is that on my main workstation the chain goes Portaudio -> PulseAudio -> Jackd -> firewire -> Echo AudioFire4, so it's hard to nail down where the issue is.

When I try to disable Jack and go pulse -> ALSA, i get:

ALSA lib pcm.c:7843:(snd_pcm_recover) underrun occurred
Expression 'err' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 3286
Expression 'ContinuePoll( self, StreamDirection_In, &pollTimeout, &pollCapture )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 3813
Expression 'PaAlsaStream_WaitForFrames( stream, &framesAvail, &xrun )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 4185

And when I run using `pasuspender` to disable pulseaudio and go direct ALSA, I get no errors but no sound, probably because I'm using the default device and it's probably not hooked up to sound.

I don't have this issue on my OSX laptop, going PortAudio -> CoreAudio.

Sorry for the complicated setup, I'm mostly looking for pointers into the most probable direction to hunt in.

As far as concrete questions:
  1. In the Portaudio -> PulseAudio -> Jackd -> firewire -> Echo AudioFire4 setup, who is ultimately in charge of calling the callback?
  2. How bad is it to miss the callback deadline? My expectation is that I should get dropouts, which is obviously bad, but can missing those deadlines actually break things? It seems like when I go Pulse -> ALSA, missing the deadline is actually crashing the stream.

Portaudio mailing list
Portaudio <at> music.columbia.edu
Spencer Russell | 14 Aug 18:39 2014

Julia interface to PortAudio

I'm likely going to be asking some questions (I have one in the hopper already) so I figured i'd send a little introductory email with what I'm working on.

I'm the maintainer of AudioIO.jl, which is the audio library for Julia (a newish language, mostly for fast but high-level scientific computing).

The main use case is just having an easy way to play back audio in arrays or files, but I'm also playing around with a modular approach so you can plug together nodes into a graph a la PureData or SuperCollider. The benefit being that you can write your high-level and low-level code in the same language instead of dropping down to C or C++, and there are lots of nice linear algebra and other libraries to lean on.

Julia has really nice C integration, but there are several issues interfacing with PortAudio. One is that Julia is not thread-safe, so while I can easily create a C-callable function and pass a function pointer, that function can't be called safely from another thread.

My solution to this is to write a small C shim for the callback handler, and synchronize it with a Julia Task. So when the callback function gets called, the first thing it does is wait on a semaphore which is how Julia notifies it that audio data is available. If Julia is keeping up then the data should actually already be there and the callback won't have to wait. After the callback copies the data it writes to a file descriptor that the Julia task is waiting on, and the dance continues.

As far as I can tell this is similar to how CSound's portaudio interface works.

This seems like a good time to point out that I know there's a difference between fast and real-time safe, and what I'm doing is a horrible abomination. Julia is currently not intended to provide real-time guarantees, though there's work being done to better control memory allocation, and work on a bounded pause-time incremental GC which is improving performance quite a bit.

Anyways, thanks for PortAudio, which has vastly simplified the process of getting up and running on a variety of systems and platforms.

Portaudio mailing list
Portaudio <at> music.columbia.edu
Kenneth Ciszewski | 13 Aug 16:59 2014

Alsa, Linux, Wolfson Audio Card and Raspberry PI

I thought I saw a post for Alsa on Raspberri PI for use with Port Audio.  Does anyone have this running?  I'm
interested in getting digital audio on ethernet networks using Raspberry PI.  I have a Wolfson audio
board--I'm trying to find source code to work with.
matthew coleman | 13 Aug 16:56 2014

Faster initialization of alsa

Alsa BuildDeviceList is taking an age to scan through some unsupported bluetooth channels.  I had a quick scan through BuildDeviceList code but I am non the wiser.  Is there a way to ignore specific devices/device names?.

Portaudio mailing list
Portaudio <at> music.columbia.edu
Hisaya Nakashige | 11 Aug 12:13 2014

How to get unique device ID

Hi all,

I want to save and load audio device settings.
However, in some cases, it can't restore which device is used.
The device index may be change, if any devices are connected or  
The device name in PaDeviceInfo is not unique, when more than one same
devices are connected.

So my question is: Is there a way to get a unique device ID?

I don't mind if I need platform-dependent code.
For example, in case of DirectSound,
Is the following code OK?

PaDeviceInfo* deviceInfo = current_device;
PaHostApiInfo* hostInfo = Pa_GetHostApiInfo(deviceInfo->hostApi);
if( hostInfo->type == paDirectSound )
     PaWinDsDeviceInfo* winDsDeviceInfo = (PaWinDsDeviceInfo*)deviceInfo;
     //save winDsDeviceInfo->guid;

The problem is that PaWinDsDeviceInfo is declared in pa_win_ds.c and is  
not public.

In case of WASAPI, it looks more harder to get unique id, since  
PaWasapiDeviceInfo is
separated from PaDeviceInfo.

Best regards,
Hisaya Nakashige