New experimental release using JAudioLibs for IO

245 views
Skip to first unread message

Oliver Bown

unread,
Jan 11, 2012, 12:14:33 AM1/11/12
to beadsp...@googlegroups.com
Greetings,

after much dithering and distraction I have now incorporated Neil Smith's JAudioLibs into Beads as the one-stop-shop for AudioIO. I'm posting an experimental release here:

http://www.beadsproject.net/downloads/beads_processing_jaudiolibs_experimental_release20120111.zip

There is one essential difference. The constructor "new AudioContext()" is no longer allowed and AudioContext must be passed an AudioIO in its constructor. However, I've put together two convenience factory methods as follows for the two audio IO solutions provided, so you can just replace the constructor in your projects with one of the following:

AudioContext ac = Beads.javaSound();
AudioContext ac = Beads.jack();

Or for a bit more control do it yourself:

AudioContext ac = new AudioContext(AudioServerIO.JavaSound(), 512, myIOAudioFormat());

I have to admit that this refactoring took ages for no good reason except that I got completely paralysed deciding the best way to implement this. I hope I've cracked this now and can get back to making improvements to the library. Many thanks to Neil! I'm really grateful for being able to use Jack without requiring Java to load any native libraries, and for getting rid of the JavaSound clicks on OS X.

A few other notes:

This is a branch of the SVN repository, source code is here:
http://www.beadsproject.net/svn/beads/Branches/RefactorAudioIO

The source code has been shuffled around so that the various IO options are stored in a separate src folder called src/beads_io. The core Beads library (in src/beads_main) has no dependencies on any particular IO, but the compiled package beads.jar contains the current preferred options (as above). (Next step will be to do the same with JavaSound dependencies concerning file IO).

I haven't responded to Evan's requests to create a decent interface for selecting devices via JavaSound. Neil's JavasoundAudioServer.create() method does accept a String arg called device but I haven't played with that yet. Could it be the answer?

This error is thrown when the system is killed (JavaSound, haven't tried Jack):
java(2445,0xb19b7000) malloc: *** error for object 0x71696e55: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug

I was being inconsistent about numbering input channels in the past. The rule is (should be) that when you refer to an input channel by a number the numbering starts from 1, as you would on a mixing desk. The method getAudioInput(int[]); in AudioContext should never get given a zero. Typically you'd want something like: ac.getAudioInput(new int[] {1,2}); Hopefully those inconsistencies are gone now (except probably in my own projects, and yours).

To use the Jack audio IO you need to install Jack and run the Jack server. At present Jack is run with whatever signal vector size you choose and Beads has to conform to that vector size in order to work, otherwise… well not much.

On my Mac, JavaSound vector sizes less than 256 are buzzy, but 512 is click free (an improvement!). Low latency programs should use Jack anyway so this will be considered acceptable.

Evan Merz

unread,
Jan 11, 2012, 12:27:50 AM1/11/12
to beadsp...@googlegroups.com
Thanks Ollie & Neil!

I won't have a chance to try this out for a bit, but I'm glad to see this step.

-Evan


From: Oliver Bown <ol...@icarus.nu>
To: beadsp...@googlegroups.com
Sent: Tuesday, January 10, 2012 9:14 PM
Subject: [beadsproject] New experimental release using JAudioLibs for IO
--
You received this message because you are subscribed to the Google Groups "beadsproject" group.
To post to this group, send email to beadsp...@googlegroups.com.
To unsubscribe from this group, send email to beadsproject+unsub...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/beadsproject?hl=en.



Neil C Smith

unread,
Jan 11, 2012, 5:48:54 AM1/11/12
to beadsp...@googlegroups.com
Hi,

Great news! I won't have a chance to have a detailed look for a
little while, but initial thoughts look good. I'm particularly
pleased that you've not hidden the capability of using alternative
AudioServer implementations, because I'm hoping we'll get some more
soon. This also opens up the possibility to embed Beads within the
Praxis audio graph - I might finally get around to that live-coding
Beads experiment now! :-)

Few comments interspersed below -

On 11 January 2012 05:14, Oliver Bown <ol...@icarus.nu> wrote:
> Greetings,
>
> after much dithering and distraction I have now incorporated Neil Smith's JAudioLibs into Beads as the one-stop-shop for AudioIO. I'm posting an experimental release here:
>
> http://www.beadsproject.net/downloads/beads_processing_jaudiolibs_experimental_release20120111.zip
>

Is this missing JNA?

> There is one essential difference. The constructor "new AudioContext()" is no longer allowed and AudioContext must be passed an AudioIO in its constructor. However, I've put together two convenience factory methods as follows for the two audio IO solutions provided, so you can just replace the constructor in your projects with one of the following:
>

What about deprecating "new AudioContext()" but using reflection to
load the JavaSound server - no direct dependencies, but also no
breakage of older code?

> AudioContext ac = Beads.javaSound();
> AudioContext ac = Beads.jack();
>
> Or for a bit more control do it yourself:
>
> AudioContext ac = new AudioContext(AudioServerIO.JavaSound(), 512, myIOAudioFormat());
>

For clarification for anyone reading the above, there's a slight typo
I think - need a 'new' in front of AudioServerIO.JavaSound()

> I have to admit that this refactoring took ages for no good reason except that I got completely paralysed deciding the best way to implement this.

Now ain't that a familiar feeling! :-)

> I hope I've cracked this now and can get back to making improvements to the library. Many thanks to Neil! I'm really grateful for being able to use Jack without requiring Java to load any native libraries, and for getting rid > of the JavaSound clicks on OS X.

No problem. And I knew you'd get around to integrating it eventually! :-P

To clarify something for others. Use of JNA doesn't mean that Java is
not loading native libraries - it means that neither JAudioLibs, Beads
or you have to worry about it - you just have to have JNA on the
classpath, which loads its single native library automatically from
its own jar. What this does mean is that if you want to use Jack, you
still need permissions to load native code - eg. Jack output won't
work from an unsigned applet for a start, though why you'd want to do
that I don't know.

> I haven't responded to Evan's requests to create a decent interface for selecting devices via JavaSound. Neil's JavasoundAudioServer.create() method does accept a String arg called device but I haven't played with that yet. Could it be the answer?
>

Yep! You've already got it. If you use the
AudioServerIO.JavaSound(String device) constructor, you can pass in
the name of an audio mixer (ie. equivalent to JavaSound's
MixerInfo.getName() ) Actually, you don't have to pass in the whole
mixer name - it checks if the mixer name contains the String you
passed in.

The lookup code is here -
http://code.google.com/p/praxis/source/browse/audio.servers.javasound/src/org/jaudiolibs/audioservers/javasound/JavasoundAudioServer.java#407
if you're interested in how it works (no, no idea why those methods
throw different Exceptions!)

The code handles the fact that input & output mixers are different on
Windows, though you have to be careful that the String you pass in
matches both. There is also a create method in JavasoundAudioServer
which takes the actual input and output Mixer objects - this isn't
wrapped in Beads yet though.


> This error is thrown when the system is killed (JavaSound, haven't tried Jack):
> java(2445,0xb19b7000) malloc: *** error for object 0x71696e55: pointer being freed was not allocated
> *** set a breakpoint in malloc_error_break to debug
>

This is probably a JavaSound issue, and by recollection a known one,
which I saw when testing Praxis on a Mac. If you didn't see this with
your previous JavaSound code in Beads, then we may need to do some
hunting to find out why it's being triggered now. It seems to happen
when the line is closed.

> To use the Jack audio IO you need to install Jack and run the Jack server. At present Jack is run with whatever signal vector size you choose and Beads has to conform to that vector size in order to work, otherwise… well not much.
>

That seemed like the right (and simplest) thing to do for now, but
there may be options to allow the user to choose what action to take
ie. fail, run Beads with Jack's vector size, or attempt to change
Jack's vector size.

> On my Mac, JavaSound vector sizes less than 256 are buzzy, but 512 is click free (an improvement!). Low latency programs should use Jack anyway so this will be considered acceptable.
>

That's good news, as long as we can get that malloc bug fixed above,
that gives fairly useful latency on all 3 JavaSound platforms.

Did you have to shift to TimingMode.FramePosition to achieve that,
though? If so, we might need to consider checking the OS at runtime -
TimingMode.Estimated may be better on Windows and Linux. I'll try to
do some more testing.

On my laptop, I can get down to vector sizes of 128 (and sometimes 64)
on Linux and Windows 7. I have to say that Windows feels slightly
less responsive though, which makes me think there's a little extra
buffering in the OS. Need to code a latency checker sometime.

If you want to play with hacking on the JavaSound code, you could see
if replacing Thread.sleep(1) with Thread.yield() (or nothing at all)
in the loops here -
http://code.google.com/p/praxis/source/browse/audio.servers.javasound/src/org/jaudiolibs/audioservers/javasound/JavasoundAudioServer.java#219
- gives you better performance on Mac.


Best wishes,

Neil

--
Neil C Smith
Artist : Technologist : Adviser
http://neilcsmith.net

Andrew Lucia

unread,
Mar 5, 2012, 10:25:28 AM3/5/12
to beadsp...@googlegroups.com
Hello Ollie & Neil et. al.
Thank you for compiling this new experimental library!  I am still pursuing multichannel inputs, though I had given it a rest for a bit while you guys were sorting this out.

I've been playing around with the new experimental library (on a mac, finally) and I am getting signals in using the AudioContext ac = Beads.javaSound() with Jack, but only 2.  When I try using AudioContext ac = Beads.jack(); the Jack pilot sees Beads, but again only 2 channels and I can't seem to get the signal into Beads.  I know that 2 channels is the default, but I also know that I should be able to get more than this. 

So, my questions are: 
1.) With this new experimental library, do I still need to alter code in preferences in Processing and/or monkey around with putting the .dll files in my classpaths?  Or is this new library the one stop shop for everything? 

2.) Similarly, though for the most part I get the idea of what you guys are speaking about in this thread, some of it is slightly over my head.  Would you be able to provide a simple bit of example code for Processing that would demonstrate hour to instantiate a multi-channel AudioIO set-up with this new experimental library. 

Many thanks.  You guys are wonderful. 

Best,
Andrew



--
You received this message because you are subscribed to the Google Groups "beadsproject" group.
To post to this group, send email to beadsp...@googlegroups.com.
To unsubscribe from this group, send email to beadsproject...@googlegroups.com.

Neil C Smith

unread,
Mar 5, 2012, 11:00:17 AM3/5/12
to beadsp...@googlegroups.com
Hi,

Bearing in mind I wrote that code a good few months ago and haven't
looked at it since! :-)

It should pick up the number of input and output channels from the
Beads IOAudioFormat. However, it looks like you'll have to use the
longer constructor for the AudioContext.

Replace Beads.jack() with something like -

new AudioContext(new AudioServerIO.Jack(), bufferSize, new
IOAudioFormat(sampleRate, bitDepth, inputs, outputs));

Make sure that the bufferSize and sampleRate match JACK. Set inputs
and outputs to how many channels you want. Put 16 for bitDepth - it
should be ignored anyway.

Hopefully that's correct - not tested!

In answer to your question #1, use of JNA should remove all need to
fiddle with dll's, as long as you've got JNA in the classpath. Not
sure what all the preferences were used for. Main thing not possible
at the moment is autoconnect - coming soon in JAudioLibs though Ollie
will need to integrate with Beads.

Best wishes,

Neil

Andrew Lucia

unread,
Mar 5, 2012, 1:54:35 PM3/5/12
to beadsp...@googlegroups.com
Hi Neil,
Thank you for the prompt reply.

OK.  That's kind of what I figured, however when I use:

new AudioContext(new AudioServerIO.Jack(), 512, new IOAudioFormat(44100, 16, 8, 6));

I keep getting an error "Cannot find a class or type named "AudioServerIO""

Am I missing something simple?

Many thanks,
Andrew



On Mon, Mar 5, 2012 at 11:00 AM, Neil C Smith <ne...@neilcsmith.net> wrote:
Hi,

Bearing in mind I wrote that code a good few months ago and haven't
looked at it since! :-)

It should pick up the number of input and output channels from the
Beads IOAudioFormat.  However, it looks like you'll have to use the
longer constructor for the AudioContext.

Replace Beads.jack() with something like -



Neil C Smith

unread,
Mar 5, 2012, 2:33:44 PM3/5/12
to beadsp...@googlegroups.com
On 5 March 2012 18:54, Andrew Lucia <dau.p...@gmail.com> wrote:
> Am I missing something simple?
>

Hopefully! :-)

Try adding -

import org.jaudiolibs.beads.*;


N

Andrew Lucia

unread,
Mar 5, 2012, 2:58:54 PM3/5/12
to beadsp...@googlegroups.com
BINGO!

getting 8 discrete channels in!

AWESOME!



Neil C Smith

unread,
Apr 16, 2012, 5:31:41 AM4/16/12
to beadsp...@googlegroups.com
Hi All,

Anyone playing with this experimental release, please see the
forwarded email from the JAudioLibs mailing list below. In
particular, the new release provides much improved performance with
JACK, when used with JNA 3.4.0+ Anyone using this might benefit from
joining the JAudioLibs mailing list at
http://groups.google.com/group/jaudiolibs

Ollie - any thoughts on making this release more official?

Best wishes,

Neil
------
Hi All,

JAudioLibs v1.0.120123 is now available from
http://code.google.com/p/java-audio-utils

There's only one major change in this release - the addition of
JNAJack support for JNA's new CallbackThreadInitializer, which was
specifically requested for JNAJack, and brings a huge performance
boost. Use of JNA 3.4.0+ is now highly recommended, and JNAJack will
emit a warning if an earlier version of JNA is detected (though it
will still work).

There are no API changes.

Full release notes are available at
http://code.google.com/p/java-audio-utils/wiki/ReleaseNotes

As you may have guessed from the version number, this is actually the
code from the January release of Praxis. The delay in releasing
separately was caused by a) the desire to test and b) a manic couple
of months! ;-)

Barring bug fixes, this will probably be the last 1.0 version. Some
major API improvements and additional sub-projects are in the works,
of which more in the near future.

Oliver Bown

unread,
Apr 16, 2012, 5:45:47 AM4/16/12
to beadsp...@googlegroups.com
Hi Neil,

yes let's do it. Next week is relatively clear so I'll have an attack at it. I've been getting very good performance with the RefactorAudioIO branch on my new machine, with 100s of oscillators running easily at low frame sizes, and very friendly behaviour in terms of the interaction between Jack and Beads. All good.

Ollie

Neil C Smith

unread,
Apr 16, 2012, 6:17:03 AM4/16/12
to beadsp...@googlegroups.com
Hi Ollie,

Great news! :-)

I'm coding myself most of this week and next (new Praxis release in
the offing), so drop me an email if you want to check anything.

One addition that would be useful would be an easier way of specifying
the number of input and output channels, as per Andrew's issue last
month. This would work for JavaSound too, though I think it may only
be Linux that offers multichannel JavaSound devices. There was also
my earlier suggestion to not break existing code by making the no-arg
AudioContext constructor use the JavaSound IO, possibly using
reflection to try and find it?

If you get a chance while looking at this, could you also have a look
at CPU / min-latency difference between the new version of JNAJack
(with JNA 3.4.0) and the older version. I've only done a comparison
on Linux so far, so be interesting to know what sort of improvement it
gives elsewhere.

Once the next Praxis is out, I'll have a look at a PortAudioIO - promise! :-)

Best wishes,

Neil

Oliver Bown

unread,
Apr 16, 2012, 6:23:57 AM4/16/12
to beadsp...@googlegroups.com
OK, I'm coming around to the reflection/no arg constructor idea. Likewise, we've got auto connect in the Jack IO but are we able to specify connections (e.g, connect input 8 of my sound card to input 1 of Beads)?

Neil C Smith

unread,
Apr 16, 2012, 6:38:50 AM4/16/12
to beadsp...@googlegroups.com
Not at the moment. In general, I'd say that's the sort of
functionality that should be left to another application - eg. the
patchbay in QJackCtl / JackControl - see
http://www.rncbc.org/drupal/node/76 In general, the view on the JACK
mailing list seems to be against applications managing their own
connections, or at least being able to switch autoconnect off.

Having said that, I have some plans for JAudioLibs 1.1 that would
allow arbitrary extensions in the configuration data passed between
client and server. There will be some sort of class to control
autoconnect behaviour, but I had also been wondering about some sort
of connection matrix object that could handle arbitrary connections.

Best wishes,

Neil

Reply all
Reply to author
Forward
0 new messages