Processing + Beads on Raspberry Pi Zero, performance

541 views
Skip to first unread message

wellen...@gmail.com

unread,
Feb 12, 2017, 1:06:21 AM2/12/17
to beadsproject
Good afternoon,

# Platform
I'm currently running processing sketches (compiled on windows for linux ARM) on a minimalistic raspberry pi zero setup. Raspbian jessie lite and LXDE, with all unnecessary components removed, is used. The sketches are run with oracle jre 8. This all works fine and boots very quick.
Now i want to do some audio playback and tried several processing libraries. Beads turned out to be the most flexible, while all others had some basic things missing or wouldn't run properly on the raspberry. There is no doubt that the java virtual machine is not the optimum thing for the rapberry pi zero, but I want to try what's possible. Later probably a raspberry pi 3 will be used. If someone interested I could post a guide for this setup routine.

# Goal
I want to loop multiple audio files at once, where each volume can be controlled individually in real-time. Only 2-3 will be audible at the same time.
Here is a simplified processing code, which runs fine:

import beads.*;

// global variables, objects ...
String[] filepath = new String[5];
Sample[] sample = new Sample[5];
SamplePlayer[] player = new SamplePlayer[5];
Gain[] gain = new Gain[5];
AudioContext ac;

void setup() {
  size
(800,600,P2D);
  frameRate
(5);
  background
(0);
  ac
= new AudioContext();
 
for (int i = 0; i < filepath.length; i++) {
    filepath
[i] = sketchPath("sounds/sound ("+i+").wav");
    sample
[i] = SampleManager.sample(filepath[i]);
    player
[i] = new SamplePlayer(ac, sample[i]);
    player
[i].setKillOnEnd(false);
    player
[i].setLoopType(SamplePlayer.LoopType.LOOP_FORWARDS); // enable looping
    player
[i].pause(false); // pause playback
    gain
[i] = new Gain(ac, 1, 1.0); // construct gain object
    gain
[i].addInput(player[i]); // connect each sample player to each gain object
    ac
.out.addInput(gain[i]); // connect each gain to the main output
 
}
  ac
.start();
}

void draw(){
/* (...)
change and update volume
(...) */

}


# Q1
 So I create an array of multiple SamplePlayer. Each has its volume control and if the volume is 0, playback is paused. Does pausing playback save some CPU time?

#Q2
In the beads manuals' examples the sample manager is not used, samples are loaded directly:
(...)
SamplePlayer sp;
sp
= new SamplePlayer(ac, new Sample(sourceFile));
(...)
If I do it this way, I get an error "Unhandled exception type IOException".
Why? Do I have to use the SampleManager?

# Q3
When I load more files, audio starts to get distorted (clicks/stuttering). The gain of each SamplePlayer is already adjusted to 0.2. Running top shows that 200mb ram are free and java uses not more than 45% cpu time, pulse audio uses ~10%.
So what could cause this problem? It doesn't seem to be a performance problem.
I remember running PureData on an Rasberry Pi 2 and I could play many files at one time.

Sometimes it even gets stuck. Audio stops, cpu % drops and player[i].getPosition() won't increase anymore.

# Q4
When loading more and larger files, I get and Error. On my Windows machine I can reproduce it when placing a delay(5000) inside the setup() loop after calling frameRate().
If I place the frameRate() at the last line of setup() or delete it, gives me a similar erro, but works. Player[i].getPosition() increases, but audio output is very chopped and distorted.

RunnableTask.run(): A caught exception occured on thread main-Display-.x11_:0-2-EDT-1: RunnableTask[enqueued true[executed false, flushed false], tTotal 1 ms, tExec 0 ms, tQueue 1 ms, attachment null, throwable java.lang.RuntimeException: Waited 5000ms for: <d4edc0, 5797b5>[count 1, qsz 0, owner <main-FPSAWTAnimator#00-Timer0>] - <main-Display-.x11_:0-2-EDT-1>]
java.lang.RuntimeException: Waited 5000ms for: <d4edc0, 5797b5>[count 1, qsz 0, owner <main-FPSAWTAnimator#00-Timer0>] - <main-Display-.x11_:0-2-EDT-1>
        at jogamp.common.util.locks.RecursiveLockImpl01Unfairish.lock(RecursiveLockImpl01Unfairish.java:198)
        at jogamp.newt.WindowImpl.getLocationOnScreen(WindowImpl.java:1159)
        at jogamp.newt.driver.x11.X11UnderlayTracker.windowMoved(X11UnderlayTracker.java:141)
        at jogamp.newt.WindowImpl.consumeWindowEvent(WindowImpl.java:4386)
        at jogamp.newt.WindowImpl.sendWindowEvent(WindowImpl.java:4317)
        at jogamp.newt.WindowImpl.positionChanged(WindowImpl.java:4558)
        at jogamp.newt.WindowImpl.sizePosMaxInsetsVisibleChanged(WindowImpl.java:4865)
        at jogamp.newt.driver.x11.DisplayDriver.DispatchMessages0(Native Method)
        at jogamp.newt.driver.x11.DisplayDriver.dispatchMessagesNative(DisplayDriver.java:112)
        at jogamp.newt.WindowImpl.waitForVisible(WindowImpl.java:4449)
        at jogamp.newt.WindowImpl.waitForVisible(WindowImpl.java:4443)
        at jogamp.newt.WindowImpl.createNative(WindowImpl.java:777)
        at jogamp.newt.WindowImpl.setVisibleActionImpl(WindowImpl.java:1248)
        at jogamp.newt.WindowImpl$VisibleAction.run(WindowImpl.java:1318)
        at com.jogamp.common.util.RunnableTask.run(RunnableTask.java:127)
        at jogamp.newt.DefaultEDTUtil$NEDT.run(DefaultEDTUtil.java:375)
DefaultEDT.run(): Caught exception occured on thread main-Display-.x11_:0-2-EDT-1: RunnableTask[enqueued false[executed true, flushed false], tTotal 8185 ms, tExec 8184 ms, tQueue 1 ms, attachment null, throwable java.lang.RuntimeException: Waited 5000ms for: <d4edc0, 5797b5>[count 1, qsz 0, owner <main-FPSAWTAnimator#00-Timer0>] - <main-Display-.x11_:0-2-EDT-1>]
java.lang.RuntimeException: Waited 5000ms for: <d4edc0, 5797b5>[count 1, qsz 0, owner <main-FPSAWTAnimator#00-Timer0>] - <main-Display-.x11_:0-2-EDT-1>
        at jogamp.common.util.locks.RecursiveLockImpl01Unfairish.lock(RecursiveLockImpl01Unfairish.java:198)
        at jogamp.newt.WindowImpl.getLocationOnScreen(WindowImpl.java:1159)
        at jogamp.newt.driver.x11.X11UnderlayTracker.windowMoved(X11UnderlayTracker.java:141)
        at jogamp.newt.WindowImpl.consumeWindowEvent(WindowImpl.java:4386)
        at jogamp.newt.WindowImpl.sendWindowEvent(WindowImpl.java:4317)
        at jogamp.newt.WindowImpl.positionChanged(WindowImpl.java:4558)
        at jogamp.newt.WindowImpl.sizePosMaxInsetsVisibleChanged(WindowImpl.java:4865)
        at jogamp.newt.driver.x11.DisplayDriver.DispatchMessages0(Native Method)
        at jogamp.newt.driver.x11.DisplayDriver.dispatchMessagesNative(DisplayDriver.java:112)
        at jogamp.newt.WindowImpl.waitForVisible(WindowImpl.java:4449)
        at jogamp.newt.WindowImpl.waitForVisible(WindowImpl.java:4443)
        at jogamp.newt.WindowImpl.createNative(WindowImpl.java:777)
        at jogamp.newt.WindowImpl.setVisibleActionImpl(WindowImpl.java:1248)
        at jogamp.newt.WindowImpl$VisibleAction.run(WindowImpl.java:1318)
        at com.jogamp.common.util.RunnableTask.run(RunnableTask.java:127)
        at jogamp.newt.DefaultEDTUtil$NEDT.run(DefaultEDTUtil.java:375)
JavaSoundAudioIO: Chosen mixer is default [default].


# Q5
How can the audio context be change? For example I would need only 2 Output channels and 8-bit resolution. I tried this, but somethings is wrong:
ac = new AudioContext(new AudioIO, 512, new IOAudioFormat(44100.0, 16, 0, 2));


Are there any other Ideas on how to do this better? Could the chopped audio be a problem of pulseaudio instead?

Many many thank!


Oliver Bown

unread,
Feb 13, 2017, 5:56:46 PM2/13/17
to beadsp...@googlegroups.com
Hi! Answers below.

Yes, pausing will pause the UGen plus any UGens that are upstream of that one (if they are not connected downstream via another path). So if you have a SamplePlayer plugged into a Gain and you pause the Gain then you pause both. Note that this may disrupt the playback position of the SamplePlayer.


#Q2
In the beads manuals' examples the sample manager is not used, samples are loaded directly:
(...)
SamplePlayer sp;
sp
= new SamplePlayer(ac, new Sample(sourceFile));
(...)
If I do it this way, I get an error "Unhandled exception type IOException".
Why? Do I have to use the SampleManager?

You just have to know about Exceptions in Java. You need to surround the code in a try/catch block.
Using SampleManager does that bit for you. It’s for convenience. It works just the same.


# Q3
When I load more files, audio starts to get distorted (clicks/stuttering). The gain of each SamplePlayer is already adjusted to 0.2. Running top shows that 200mb ram are free and java uses not more than 45% cpu time, pulse audio uses ~10%.
So what could cause this problem? It doesn't seem to be a performance problem.
I remember running PureData on an Rasberry Pi 2 and I could play many files at one time.

Sometimes it even gets stuck. Audio stops, cpu % drops and player[i].getPosition() won't increase anymore.

It can still be a performance issue to do with audio input/output, even if the CPU isn’t maxed out. You should try running with a larger audio buffer size. e.g., “new AudioContext(2048);” and see if that helps. This will cause larger latency.

You could also try increasing the Java memory allocation just in case. Use Processing prefs or run with -Xmx1024m. 
Cripes! I can’t make head or tail of this. So do you also have the console output on the Pi? All this jogamp stuff is obviously Windows only.

# Q5
How can the audio context be change? For example I would need only 2 Output channels and 8-bit resolution. I tried this, but somethings is wrong:
ac = new AudioContext(new AudioIO, 512, new IOAudioFormat(44100.0, 16, 0, 2));

What is wrong? Errors? Um, there’s something wrong with new AudioIO. 
It should be something like…

AudioContext ac = new AudioContext(new AudioServerIO.JavaSound(), 1024, new IOAudioFormat(44100, 16, 2, 2));

You can also have a play with Jack as a solution. I use this a lot on Mac when I want multichannel and low latency. 

You can set up Beads to run with Jack like this...
AudioContext ac = new AudioContext(new AudioServerIO.Jack(), 1024, new IOAudioFormat(44100, 16, 2, 2));

You need Jack server running and you need to make sure it has the same buffer size and sample rate. It’s a bit of a nightmare. Jack seems to not be well supported on Mac. I forget the status on Windows. It is more commonly used on Linux but I haven’t tried it on the Pi (the Java audio IO on the Pi usually behaves quite well).

Also we have noted that when you run the Pi with one of the audio shields like the HiFiBerry then the audio performance improves. I don’t really understand what the difference is. 

Ollie


Are there any other Ideas on how to do this better? Could the chopped audio be a problem of pulseaudio instead?

Many many thank!



--
You received this message because you are subscribed to the Google Groups "beadsproject" group.
To unsubscribe from this group and stop receiving emails from it, send an email to beadsproject...@googlegroups.com.
To post to this group, send email to beadsp...@googlegroups.com.
Visit this group at https://groups.google.com/group/beadsproject.
For more options, visit https://groups.google.com/d/optout.

Neil C Smith

unread,
Feb 14, 2017, 6:02:05 AM2/14/17
to beadsp...@googlegroups.com
Hi,

Couple of thoughts on this below.

On 13 February 2017 at 22:56, Oliver Bown <ol...@icarus.nu> wrote:
> When loading more and larger files, I get and Error. On my Windows machine I
> can reproduce it when placing a delay(5000) inside the setup() loop after
> calling frameRate().
...
> Cripes! I can’t make head or tail of this. So do you also have the console
> output on the Pi? All this jogamp stuff is obviously Windows only.
>

This isn't Windows specific, it's the timeout protection in the JOGL
animation timer that is used by the OpenGL renderer. It's come up a
few times on the Processing forum in similar circumstances. Anything
that takes longer than a few (maybe ~7) seconds needs to be done
outside of setup(). It might work moving the Beads code into a
settings() method (need to move size() into that as well), if the
paths are correctly set up by then, or if not then you'd have to look
at threading this.

> You could also try increasing the Java memory allocation just in case. Use
> Processing prefs or run with -Xmx1024m.

hmmm ... I'd be careful with that - you want the Java memory to be as
high as required to run the project and no higher. Larger heaps take
more GC time.

Best wishes,

Neil

--
Neil C Smith
Artist & Technologist
www.neilcsmith.net

Praxis LIVE - hybrid visual IDE for creative coding - www.praxislive.org

Neil C Smith

unread,
Feb 14, 2017, 6:16:33 AM2/14/17
to beadsp...@googlegroups.com
On 14 February 2017 at 11:01, Neil C Smith <ne...@neilcsmith.net> wrote:
> This isn't Windows specific, it's the timeout protection in the JOGL
> animation timer that is used by the OpenGL renderer. It's come up a
> few times on the Processing forum in similar circumstances. Anything
> that takes longer than a few (maybe ~7) seconds needs to be done
> outside of setup(). It might work moving the Beads code into a
> settings() method (need to move size() into that as well), if the
> paths are correctly set up by then, or if not then you'd have to look
> at threading this.

OK, it's 5 seconds - see
https://forum.processing.org/two/discussion/comment/83112/ which is
also about a timeout during Beads sample loading. grrr ... bloody
Processing! ;-)

wellen...@gmail.com

unread,
Feb 14, 2017, 5:13:33 PM2/14/17
to beadsproject
@neilcsmith.net thanks, didn't find this post.

I managed to change the audio context, JavaSoundAudioIO(buffer_size) seemed to work.
final int buffer_size = 1024;
ac
= new AudioContext(new JavaSoundAudioIO(buffer_size), buffer_size, new IOAudioFormat(44100, 16, 0, 2, true, false));

@Ollie
Thanks for all the answers. Increasing the buffer sized improved it very little. Sound is still chopped and stuttering.
Right now I'm waiting for a Raspberry Pi 3 and than try it there with Jack audio. I'll post my results when its here.




Oliver Bown

unread,
Feb 14, 2017, 5:45:47 PM2/14/17
to beadsp...@googlegroups.com
We’ve been doing a lot of work with Beads on the Pi. It is certainly limited in terms of performance but getting say 5 sample players going at once should be fine. See the HappyBrackets project on Github if you’re interested… it gives you the option to write Java code in IntelliJ and deploy it directly to multiple Raspberry Pis (even adding new audio routines to a running program). It’s fun. We have a course on Kadenze.com about it.

Ollie

wellen...@gmail.com

unread,
Feb 17, 2017, 8:48:56 AM2/17/17
to beadsproject
Today I tried using Jack Audio + Beads on the raspberry, basically following this guide: Multichannel ...

I managed to install Jackaudio, but couldn't include the jjack library into the processing sketch, because the libjjack.so file not compiled for ARM.
Jjack was downloaded from here: JJack
But this (and a paper) seems to be everything being left from this project.
I tried compiling the libjjack.c file with gcc, but after some warning/notes it stops with an error:

/usr/lib/gcc/arm-linux-gnueabihf/4.9/../../../arm-linux-gnueabihf/crt1.o: In function `_start':
/build/glibc-g3vikB/glibc-2.19/csu/../ports/sysdeps/arm/start.S:119: undefined reference to `main'
/tmp/cccgfFid.o: In function `process':
libjjack.c:(.text+0xc78): undefined reference to `jack_port_get_buffer'
/tmp/cccgfFid.o: In function `Java_de_gulden_framework_jjack_JJackSystem_nativeInit':
libjjack.c:(.text+0xec0): undefined reference to `jack_client_new'
libjjack.c:(.text+0x1054): undefined reference to `jack_port_register'
libjjack.c:(.text+0x10d8): undefined reference to `jack_set_process_callback'
/tmp/cccgfFid.o: In function `Java_de_gulden_framework_jjack_JJackSystem_nativeStart':
libjjack.c:(.text+0x1144): undefined reference to `jack_activate'
libjjack.c:(.text+0x11d0): undefined reference to `jack_get_ports'
libjjack.c:(.text+0x1284): undefined reference to `jack_port_name'
libjjack.c:(.text+0x1298): undefined reference to `jack_connect'
libjjack.c:(.text+0x12e8): undefined reference to `jack_port_name'
libjjack.c:(.text+0x130c): undefined reference to `jack_connect'
/tmp/cccgfFid.o: In function `Java_de_gulden_framework_jjack_JJackSystem_nativeDestroy':
libjjack.c:(.text+0x13d4): undefined reference to `jack_client_close'
/tmp/cccgfFid.o: In function `Java_de_gulden_framework_jjack_JJackSystem_getSampleRate':
libjjack.c:(.text+0x1418): undefined reference to `jack_get_sample_rate'
/tmp/cccgfFid.o: In function `Java_de_gulden_framework_jjack_JJackSystem_getBufferSize':
libjjack.c:(.text+0x145c): undefined reference to `jack_get_buffer_size'
collect2: error: ld returned 1 exit status

Now Java still uses pulseaudio, which takes up much cpu.
I hope and guess that this is the cause for bad audio performance and so would like to change it to alsa or jack2.
Are there any ideas on how to do this?
I already changed the sound.properties file in /usr/lib/jvm/java-8-oracle/jre/lib added the lines proposed in Make Java or OpenJDK use ALSA ...
But top shows me, that still pulseaudio is being used.

@Ollie Which audio software connection from Java/Beads to sound interface did you use?

Neil C Smith

unread,
Feb 17, 2017, 9:32:04 AM2/17/17
to beadsp...@googlegroups.com
Hi,

JJack is a dead project. Current Beads downloads have JNAJack
included. This should work on the Pi. Pretty sure I've had Praxis
LIVE running with JACK there - JNAJack is developed as part of Praxis
LIVE, although not tried with the older versions of the library and
JNA in Beads. Let me know if you get stuck and I'll have a look at
the native stuff, although I think Ollie has had this working too?

Best wishes,

Neil
> --
> You received this message because you are subscribed to the Google Groups
> "beadsproject" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to beadsproject...@googlegroups.com.
> To post to this group, send email to beadsp...@googlegroups.com.
> Visit this group at https://groups.google.com/group/beadsproject.
> For more options, visit https://groups.google.com/d/optout.



wellen...@gmail.com

unread,
Feb 18, 2017, 10:58:04 AM2/18/17
to beadsproject
I installed Jack (choose Real time on install) on the Raspberry, added audio group permissions (reboot required) and now can start a jack server:

apt-get install jackd2
sudo adduser pi audio
jackd
-R -d alsa -d hw:ALSA,0 -r 44100 -p 1024 -i 0 -o 2 -S

It will print the following, so I assume it's working:

jackdmp 1.9.10
Copyright 2001-2005 Paul Davis and others.
Copyright 2004-2014 Grame.
jackdmp comes
with ABSOLUTELY NO WARRANTY
This is free software, and you are welcome to redistribute it
under certain conditions
; see the file COPYING for details
JACK server starting
in realtime mode with priority 10
self-connect-mode is "Don't restrict self connect requests"
audio_reservation_init
Acquire audio card Audio0
creating alsa driver
... hw:ALSA,0|hw:ALSA,0|1024|2|44100|0|2|nomon|swmeter|-|16bit
ALSA
: Cannot open PCM device alsa_pcm for capture. Falling back to playback-only mode
configuring
for 44100Hz, period = 1024 frames (23.2 ms), buffer = 2 periods
ALSA
: final selected sample format for playback: 16bit little-endian
ALSA
: use 2 periods for playback

However on the processing side I change my audio context to:
ac = new AudioContext(new AudioServerIO.Jack(), buffer_size, new IOAudioFormat(44100, 16, 0, 2, true, false));

I have to add this import line, which i got from Getting Multiple Audio Inputs in Processing.
import org.jaudiolibs.beads.AudioServerIO;

How is processing actually getting this path in the library folder?
The path is:  ./Processing/libraries/beads/src/beads_io/org/jaudiolibs/beadsAudioServerIO.java

Now, when I export it to ARM and run it on the Raspberry (start the jack server first), I get this error:
Starting Jack implementation of AudioServerIO
Feb 18, 2017 3:51:34 PM org.jaudiolibs.beads.AudioServerIO$1 run
SEVERE
: null
org
.jaudiolibs.jnajack.JackException: Can't find native library
        at org.jaudiolibs.jnajack.Jack.getInstance(Jack.java:428)
        at org.jaudiolibs.audioservers.jack.JackAudioServer.initialise(JackAudioServer.java:102)
        at org.jaudiolibs.audioservers.jack.JackAudioServer.run(JackAudioServer.java:86)
        at org.jaudiolibs.beads.AudioServerIO$1.run(Unknown Source)
        at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.UnsatisfiedLinkError: /tmp/jna/jna5607197974741006973.tmp: /tmp/jna/jna5607197974741006973.tmp: cannot open shared object file: No such file or directory
        at java.lang.ClassLoader$NativeLibrary.load(Native Method)
        at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1938)
        at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1821)
        at java.lang.Runtime.load0(Runtime.java:809)
        at java.lang.System.load(System.java:1086)
        at com.sun.jna.Native.loadNativeLibraryFromJar(Native.java:771)
        at com.sun.jna.Native.loadNativeLibrary(Native.java:697)
        at com.sun.jna.Native.<clinit>(Native.java:127)
        at org.jaudiolibs.jnajack.lowlevel.JackLibraryDirect.<clinit>(JackLibraryDirect.java:19)
        at org.jaudiolibs.jnajack.Jack.getInstance(Jack.java:425)
        ... 4 more

"Can't find native library" means a compiled file is missing?
On Windows it gives the same error. (+ "Unable to load library 'jack'")

In the topic on stackoverflow.com, mentioned above, the solution was using eclipse instead of processing.
So should be possible with processing, too, or are the beads librarys for eclipse and processing different?

Neil C Smith

unread,
Feb 18, 2017, 3:21:45 PM2/18/17
to beadsp...@googlegroups.com
Hi,

That's JNA failing to extract and load its native library. It could be a permissions issue, but best to try updating to a newer JNA jar (inside Beads library folder?) first.

Best wishes,

Neil

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

--
You received this message because you are subscribed to the Google Groups "beadsproject" group.
To unsubscribe from this group and stop receiving emails from it, send an email to beadsproject+unsubscribe@googlegroups.com.

wellen...@gmail.com

unread,
Feb 20, 2017, 4:54:36 PM2/20/17
to beadsproject
@Neil  Excellent! With the newest jna.jar from GitHub I can start the jack audio server and after running the processing sketch,
beads will connect to the jack server.
It works in some way (jackd is running and uses much less cpu than pulseaudio)
but something seems to be weird with the sample rate.
Playback is too slow and choppy. All sample rate (Wav file, jackd, processing) are set to 44100 Hz.

Jack gives me this output:

jackdmp
1.9.10
Copyright 2001-2005 Paul Davis and others.
Copyright 2004-2014 Grame.
jackdmp comes
with ABSOLUTELY NO WARRANTY
This is free software, and you are welcome to redistribute it
under certain conditions
; see the file COPYING for
details
JACK server starting
in non-realtime mode
self-connect-mode is "Don't restrict self connect requests"
audio_reservation_init
Acquire audio card Audio0

creating alsa driver
... hw:ALSA,0|hw:ALSA,0|512|2|44100|0|2|nomon|swmeter|-|32bit

ALSA
: Cannot open PCM device alsa_pcm for capture. Falling back to playback-
only mode
configuring
for 44100Hz, period = 512 frames (11.6 ms), buffer = 2 periods
ALSA
: final selected sample format for playback: 16bit little-endian
ALSA
: use 2 periods for playback
JackAudioDriver::ProcessGraphAsyncMaster: Process error
JackAudioDriver::ProcessGraphAsyncMaster: Process error

... and java/processing:
Sample Rate: 44100.0
Inputs: 0
Outputs: 2
Bit Depth: 16
Big Endian: false
Signed: true

Starting Jack implementation of AudioServerIO

When lowering the buffer to 512 sample it gets really worse,
increasing it to 4069 improves audio quality, but it's still very choppy.
Switching jackd to non-realtime (-r parameter) doesn't have an effect.

However if I choose a buffer size of 8192 it works OK, but if all sounds are muted there is a periodical white-noise (like a steam locomotive).
Could all this be caused by the raspberrys' audio output (which is just two GPIOs acting as a PWM-DAC)?
Should I try one of the available i2s Sound interfaces?

Many Greetings!






wellen...@gmail.com

unread,
Feb 21, 2017, 5:43:05 AM2/21/17
to beadsproject
Got the solution! I used the qjackctl gui to try some settings and found out that I head to increase the Periods/Buffer from 2 to >4.
Before I though the Buffer size is defined through frames/period and never changed the periods/buffer.

Starting the jack server now looks like this. Later I will include it into the startup script of the processing sketch:
DISPLAY=:0 jackd -R -u -d alsa -d hw:ALSA,0 -r48000 -p1024 -n4 -s1 -D0 -i0 -o2 -S1

It works very well with jackd consuming only 2% of the cpu (pulseaudio used 20-30%).
Since a small latency is not important for me I might increase the buffer even more.
Occasionally an error pops up (which should be ignored when turning softmode (-s) on):
JackEngine::XRun: client = Beads was not finished, state = Running
JackAudioDriver::ProcessGraphAsyncMaster: Process error

For Raspberry 3 users I found this:Raspberry Pi DAC improvement
Maybe it has a positive effect, I don't know. The sound quality now is okay for me.
I'm wondering why they don't include the new kernel versions into the raspbian images.
Mine was still 4.4 and now it's 4.9.

I tried the whole procedure on the raspberry pi zero and it also works much better than before!
Playing nine *.WAV files (48kHz, mono, 16 bit) simultaneously will bring java to use ~80% cpu time
and almost no RAM is left but audio is playing glitch- and chop-free.

9Files.JPG

Neil C Smith

unread,
Feb 21, 2017, 6:42:02 AM2/21/17
to beadsp...@googlegroups.com
Hi,

On 20 February 2017 at 21:54, <wellen...@gmail.com> wrote:
> @Neil Excellent! With the newest jna.jar from GitHub I can start the jack
> audio server and after running the processing sketch,
> beads will connect to the jack server.

Great! I have a feeling this is a soft-float / hard-float thing that
has changed in JNA.

> Jack gives me this output:
> ...
> JACK server starting in non-realtime mode

> Switching jackd to non-realtime (-r parameter) doesn't have an effect.

hmmm .. Is that output from when you were deliberately trying to start
without realtime, or is it failing to start with realtime privileges?
Realtime should help!

Yes, you can get better performance by upping the number of periods,
which effectively adds extra buffering / latency. This is also useful
because I wrote the Beads IO as a quick proof of concept - the JACK
buffer size has to directly match the Beads internal buffer size,
which can affect how your project sounds. Praxis LIVE does this
differently by splitting the external buffer into (by default) 64
sample buffers internally. It would be good to get the Beads IO doing
this too.

Best wishes,

Neil

Oliver Bown

unread,
Feb 21, 2017, 6:56:33 PM2/21/17
to beadsp...@googlegroups.com
Good outcome! What audio buffer size are you using in Beads though?

Also, if you’re able to do direct comparison with JavaSound performance that’d be great for the record.

I’ve generally found JavaSound to be more solid on Linux than on OSX, and haven’t had a need for Jack because I’m not trying multichannel stuff. But getting better low-latency with Beads on a Pi, and of course any performance improvements, would be most welcome.

Ollie

--
You received this message because you are subscribed to the Google Groups "beadsproject" group.
To unsubscribe from this group and stop receiving emails from it, send an email to beadsproject...@googlegroups.com.

To post to this group, send email to beadsp...@googlegroups.com.
Visit this group at https://groups.google.com/group/beadsproject.
For more options, visit https://groups.google.com/d/optout.
<9Files.JPG>

wellen...@gmail.com

unread,
Feb 23, 2017, 2:21:20 AM2/23/17
to beadsproject
Hello Ollie,

in Processing/Java I use a buffer size of 1024 for beads:
ac = new AudioContext(new AudioServerIO.Jack(), 1024, new IOAudioFormat(48000, 16, 0, 2, true, false));

JavaSound:
ac = new AudioContext(new JavaSoundAudioIO(1024), 1024, new IOAudioFormat(44100, 16, 0, 2, true, false));

As mentioned above, when using Java Sound pulseaudio is used, which consumes too much cpu time.
I have the suspicion, that something is wrong there.
Searching on the internet, it seems to me, that many people are happy with pulseaudio and it shouldn't be so slow.

A) Could it JavaSound that does not work well with pulseaudio?

B) On the raspberry there has to be some low-level part of the kernel, which enables two PWM GPIOs as a DAC.
I am not sure, but maybe it's this: Raspberrypi/linux/include/sound/pcm.h
Could it be that pulseaudio does not make use of that and instead does all the GPIO shifting on its own?

Neil C Smith

unread,
Feb 23, 2017, 5:21:14 AM2/23/17
to beadsp...@googlegroups.com
Hi,

On 23 February 2017 at 07:21, <wellen...@gmail.com> wrote:
> As mentioned above, when using Java Sound pulseaudio is used, which consumes
> too much cpu time.
> I have the suspicion, that something is wrong there.

Have you tried different sample rates with the JavaSound backend? eg.
48000 PulseAudio tends to open the soundcard at a fixed samplerate,
and does samplerate conversion when required. This samplerate
conversion can slow things down, and might be the cause of glitches /
CPU usage.

Does the JavaSoundAudioIO allow for selecting and alternative
JavaSound mixer? If so, try the direct ALSA one too.

Best wishes,

Neil

---
Reply all
Reply to author
Forward
0 new messages