Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (481)
Games in Android Showcase (110)
games submitted by our members
Games in WIP (548)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1] 2 3
  ignore  |  Print  
  JavaSound on Linux  (Read 20999 times)
0 Members and 1 Guest are viewing this topic.
Offline Socob

Senior Newbie





« Posted 2011-08-24 21:24:46 »

Hello everyone,

I'm trying to get a game working on Linux (Link: http://www.ludumdare.com/compo/ludum-dare-21/?uid=398 [yes, that's Notch's Ludum Dare entry]) - that is, I want to fix the sound, because the rest seems fine. The sound implementation in the game is very basic, but while trying to tinker with it, I've had trouble getting JavaSound to work with Linux at all (using Linux Mint 11).

So, the sound effects are used like this (taken from the source files):
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
package com.mojang.escape;

import javax.sound.sampled.*;

public class Sound {

   public static Sound altar = loadSound("/snd/altar.wav");
   // load a bunch more sounds...

   public static Sound loadSound(String fileName) {
      Sound sound = new Sound();
      try {
         AudioInputStream ais = AudioSystem.getAudioInputStream(Sound.class.getResource(fileName));
         Clip clip = AudioSystem.getClip();
         clip.open(ais);
         sound.clip = clip;
      } catch (Exception e) {
         System.out.println(e);
      }
      return sound;
   }

   private Clip clip;

   public void play() {
      try {
         if (clip != null) {
            new Thread() {
               public void run() {
                  synchronized (clip) {
                     clip.stop();
                     clip.setFramePosition(0);
                     clip.start();
                  }
               }
            }.start();
         }
      } catch (Exception e) {
         System.out.println(e);
      }
   }

}

The input files are very short .wav files of the type "PCM_SIGNED 44100.0 Hz, 16 bit, mono, 2 bytes/frame, little-endian" (according to "ais.getFormat().toString()").

While this works fine on Windows, it fails on my Linux machine using OpenJDK 1.6 at the line "clip.open(ais);":
1  
2  
3  
4  
5  
6  
7  
8  
java.lang.IllegalArgumentException: Invalid format
        at org.classpath.icedtea.pulseaudio.PulseAudioDataLine.createStream(PulseAudioDataLine.java:143)
        at org.classpath.icedtea.pulseaudio.PulseAudioDataLine.open(PulseAudioDataLine.java:100)
        at org.classpath.icedtea.pulseaudio.PulseAudioDataLine.open(PulseAudioDataLine.java:289)
        at org.classpath.icedtea.pulseaudio.PulseAudioClip.open(PulseAudioClip.java:402)
        at org.classpath.icedtea.pulseaudio.PulseAudioClip.open(PulseAudioClip.java:453)
        at com.mojang.escape.Sound.loadSound(Sound.java:33)
        at com.mojang.escape.Sound.<clinit>(Sound.java:6)

So, I changed the "loadSound()" method to the following:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
   public static Sound loadSound(String fileName) {
      Sound sound = new Sound();
      try {
         AudioInputStream ais = AudioSystem.getAudioInputStream(Sound.class.getResource(fileName));
         Clip clip = (Clip) AudioSystem.getLine(new DataLine.Info(Clip.class, ais.getFormat()));
         clip.open(ais);
         sound.clip = clip;
      } catch (Exception e) {
         e.printStackTrace();
      }
      return sound;
   }

This actually works, but if you try to play the same sound many times, there's a pretty large delay (about 1 second) between each play. I've noticed that the "Clip.stop()" method takes a very long time on my machine, which it doesn't on Windows. So, because playing the sound is synchronized in the "play()" method (see above), any attempts to play the sound again have to be queued up and wait until that's finished. In the game, if you play the same sound again very quickly, that obviously doesn't work because the action that triggered the sound is long over.

Because I don't know very much about JavaSound, I decided to switch to the Sun JDK 1.6 and see if that works better. No matter if I use the first or second version of the "loadSound()" method, I get this at "clip.open(ais)":
1  
2  
3  
4  
5  
6  
7  
8  
javax.sound.sampled.LineUnavailableException: line with format PCM_SIGNED 44100.0 Hz, 16 bit, mono, 2 bytes/frame, little-endian not supported.
        at com.sun.media.sound.DirectAudioDevice$DirectDL.implOpen(DirectAudioDevice.java:494)
        at com.sun.media.sound.DirectAudioDevice$DirectClip.implOpen(DirectAudioDevice.java:1280)
        at com.sun.media.sound.AbstractDataLine.open(AbstractDataLine.java:107)
        at com.sun.media.sound.DirectAudioDevice$DirectClip.open(DirectAudioDevice.java:1061)
        at com.sun.media.sound.DirectAudioDevice$DirectClip.open(DirectAudioDevice.java:1151)
        at com.mojang.escape.Sound.loadSound(Sound.java:33)
        at com.mojang.escape.Sound.<clinit>(Sound.java:7)

So, I thought, maybe the format actually isn't supported. So I tried with a .wav file of the following format: "PCM_SIGNED 44100.0 Hz, 16 bit, stereo, 4 bytes/frame, little-endian". I didn't get any exceptions this time, but there's a problem: I can't hear anything. As I tried out various things from the forums, I looped through all the mixers on my system via "AudioSystem.getMixerInfo()". With the Sun JDK, this gave me:
1  
2  
3  
4  
5  
6  
NVidia [plughw:0,0], version 1.0.23
NVidia [plughw:0,1], version 1.0.23
NVidia [plughw:0,2], version 1.0.23
Generic [plughw:1,3], version 1.0.23
Port NVidia [hw:0], version 1.0.23
Port Generic [hw:1], version 1.0.23

while with OpenJDK, I got:
1  
2  
3  
4  
5  
6  
7  
8  
PulseAudio Mixer, version 0.02
default [default], version 1.0.23
NVidia [plughw:0,0], version 1.0.23
NVidia [plughw:0,1], version 1.0.23
NVidia [plughw:0,2], version 1.0.23
Generic [plughw:1,3], version 1.0.23
Port NVidia [hw:0], version 1.0.23
Port Generic [hw:1], version 1.0.23

Now, because sound on Linux is generally a big pile of chaos, I don't really know too much about it and I also don't know what all those mixers are referring to. I do know, however, that I have PulseAudio, so perhaps the missing entries in the Sun JDK list explain why I got no exception, but still couldn't hear any sound.

So, at this point, I'm stuck. To recap, I can't play sound with the Sun JDK at all and with OpenJDK, I don't know how to play the same sound multiple times, quickly. Is there any way I could get this running? I'd really like to stay with JavaSound and avoid any external libraries - the application is extremely simple. I mean, basically, I just want to play some sounds!
Offline Riven
« League of Dukes »

JGO Overlord


Medals: 781
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #1 - Posted 2011-08-24 21:39:27 »

JavaSound typically being such an unstable can of worms, I advice you to do the following:

Open a 16 bit, stereo audio channel at 44100Hz, and do all mixing yourself.

Yes, it's a lot of work, but at least it works and keeps working throughout your game.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline philfrei
« Reply #2 - Posted 2011-08-24 23:33:53 »

I haven't worked with sound specifically on Linux, but I haven't had any Linux users complain about the various Applets I've posted.

Sometimes things that are "slightly incorrect" work on one OS but not on others. Also, there are dozens of ways to slip up and forget a step. I know I've found myself pulling out my hair because I forget something dumb like an open() step or my sound editor decides to export a blank wav and I don't confirm there is actually the expected sound in it before I try to run it in Java.  Tongue  (Not saying you have made such mistakes, just that, in general, a lot of double checking has to be done.)

I'm curious, how long (in frames) are these short sounds?

I suspect that the mixer issue is a red herring.

Not sure I understand your usage, with the static methods and invocation of synchronize on the clip. Do you have code that demonstrates usage that can be run as a test case? I don't see how you select which clip is going to play if the Sound method loads "a bunch more sounds". It looks like each load overwrites clip.

"Greetings my friends! We are all interested in the future, for that is where you and I are going to spend the rest of our lives!" -- The Amazing Criswell
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Socob

Senior Newbie





« Reply #3 - Posted 2011-08-25 00:29:41 »

@Riven:
I guess I'll try that, however I'm not sure how one would actually do that. Do you have any pointers/tips on how to start? Anyway, I'm going to take a closer look at it tomorrow.

@philfrei:
If you've successfully used sound with applets before, could you perhaps demonstrate a working example? I suppose you've used "AudioClip" when working with applets; I don't know in how far that's related to the rest of the JavaSound API, but maybe I can take a look at that as well.

Also, note that the example posted here isn't actually my code - I'm tinkering with an open source game from the Ludum Dare competition (link in the first post) to learn some things and to get it working properly on Linux. By the way, on Windows, there are no problems with the game, and on Linux, everything is fine except for the Sound (which is basically implemented using that single class I posted).

I'd have to check to see how long the sounds are exactly, but they're all shorter than a second. They can also be downloaded (link in the first post) if you need more information.

Concerning the mixer issue, that's just a difference I found between OpenJDK and the Sun JDK. Since I've heard about JavaSound using the wrong mixer before, and because I can get sound with OpenJDK, but not the Sun JDK (with the exact same code), I thought that might be one of the causes (still not sure).

About the code: As I said, the whole game source code is available (it's not huge, the game was made in 2 days) and is not written by me. However, I can explain how it works. An object of the "Sound" class, as it was posted, is supposed to represent a single sound effect that can be played with its only method, "play()" (very simplistic). The "loadSound()" static method loads a sound from a resource, creating a "Sound" object. This could instead be replaced with a constructor, but the author chose to do it like this for some reason. Where I put "load a bunch more sounds...", I just cut out how all the sounds were loaded in the original code, all in the same way:
1  
public static Sound someSound = loadSound("/snd/someSound.wav");

Whenever a sound is needed, it can be played frome elsewhere in the code with (for example)
1  
Sound.someSound.play()
"clip" is not overwritten because each load creates a new sound object, each with its own "clip" field.
Regarding "synchronize", this is needed to prevent multiple threads (a new thread is launched each time a sound is played) from accessing the same clip at the same time, which would cause problems. On Windows, this use of synchronization isn't a problem for the game because the sounds are very short and the threads terminate very quickly. WIth OpenJDK, though, the call to "clip.stop()" takes ages for some reason, so if you play the same sound several times in quick succession (e.g. gunshots), it takes far too long to play all the sounds because the threads can't quit quickly enough, and you still hear the queued-up shots with long pauses in between (during which the thread is busy doing "clip.close()") even if the guns have long stopped shooting.

EDIT: I just found this: Java Theremin. Without having looked at any error messages, I'll just quickly say I'm not getting any sound there, either.
Offline philfrei
« Reply #4 - Posted 2011-08-25 02:14:12 »

I was never tempted by AudioClip. I've always wanted to have some control over volume.

The Theremin isn't working? Interesting. When you drag the mouse upwards, the volume should rise. Are you able to get other sounds via other Java programs? You may have uncovered something that I have not dealt with yet!

My other Applets with sound are http://hexara.com/game.html (warning, slow load) and http://hexara.com/VSL/VSL2.htm

Princec generously posted his code listing, which includes his sound handling, if you want to poke around there for ideas.
http://www.java-gaming.org/topics/using-jorbis-jar-from-jcraft/24367/msg/204698/view.html#msg204698

Re: synchronize, there are perhaps alternative strategies to consider, such as thread isolation. If the clip is synchronized, how does one get access to stop() it? Maybe try using the getLine() method from one of your Mixers rather than from AudioSystem?

But I guess the first thing to establish (is that your volume knob is on -- just kidding), for my being able to help or not, is whether it can play my Applets. If it can't then I clearly have the same problem as you to solve. I'll take a look at the download link you provided as soon as I get a chance.

"Greetings my friends! We are all interested in the future, for that is where you and I are going to spend the rest of our lives!" -- The Amazing Criswell
Offline pjt33
« Reply #5 - Posted 2011-08-25 06:26:09 »

I don't hear anything from the Theremin on my Linux box, either. Socob is spot on with "sound on Linux is generally a big pile of chaos", but I'm pretty sure I don't have anything locking my soundcard at the moment.
Offline philfrei
« Reply #6 - Posted 2011-08-25 07:23:59 »

Thx ptjt33, and Socob, too. I am glad to find this out.
I left a query over at a linux forum--but no responses yes.
The Notch Ludum Dare entry makes sound on my Windows system, but that was expected. (Now, if I could only figure out how to get out of the starting cell, in that game.)

EDIT: found this thread on similar question
http://lists.linuxaudio.org/pipermail/linux-audio-dev/2008-August/021547.html
But I'm not sure what to do with it. If I understand it correctly, it is suggesting that Java isn't selecting the correct output card for whatever reason. But I don't see how we can anticipate that and figure out which Mixer is the best one for a random client.

Another thread recommends prompting the User to select a Mixer.
https://forums.oracle.com/forums/thread.jspa?threadID=2230378&tstart=0&messageID=9627670#9627670
which points to this article, which looks like one of the better sound articles I've come across:
http://www.developerfusion.com/article/84314/wired-for-sound/

"Greetings my friends! We are all interested in the future, for that is where you and I are going to spend the rest of our lives!" -- The Amazing Criswell
Offline nsigma
« Reply #7 - Posted 2011-08-25 08:10:23 »

JavaSound typically being such an unstable can of worms, I advice you to do the following:

Open a 16 bit, stereo audio channel at 44100Hz, and do all mixing yourself.

Yes, it's a lot of work, but at least it works and keeps working throughout your game.

Generally, I'd agree with Riven - do your own software mixing.  I'd stay well clear of Clip - they seem highly problematic (and also used to have difficulties playing sounds under 1 sec.)  I don't entirely agree that JavaSound is an unstable can of worms though - the direct audio devices generally work well if you use the API as intended.  You need to be aware that the direct audio devices are just that though, direct access to the underlying soundcard driver, and can behave quite differently on different systems.  eg. there is no hardware mixing on most Linux drivers, unlike Windows, so playing multiple sounds by opening multiple lines / clips will generally fail.  A lot of Java games (and Pulpcore) suffer from this issue.  The simplest way is to use the direct lines as they were intended - open a single line, keep it open, and mix your sounds into it yourself.

I'd recommend looking at http://www.jsresources.org/ - it's an old site but a lot of the information is still relevant.

I posted the AudioServers code from my Praxis project up recently - info here http://www.java-gaming.org/topics/jaudiolibs/24574/view.html  This abstracts out the actual audio setup code - you just have to implement a callback to fill float buffers as required.  The audio routing / mixing stuff from Praxis will be up under a similar license in the near future, but is currently undergoing some API changes.  I can point you at a few classes in the repo that will do the mixing bit for you though, if you want.

Incidentally, I get sound fine with philfrei's Theremin applet - Linux Mint LTS, Oracle JDK. (it's very crackly mind you, but that might be the synthesis algorithm!  Smiley )

Best wishes, Neil

Praxis LIVE - open-source intermedia toolkit and live interactive visual editor
Digital Prisoners - interactive spaces and projections
Offline philfrei
« Reply #8 - Posted 2011-08-25 08:47:49 »

Crackly?! What does that mean? I am aware of something that I assumed was kind of like anti-aliasing in the high registers, especially the square wave. Is that what you mean? Crackly as a descriptor sounds much worse than that. Does the sine wave crackle, too? That is clear as a bell, over here.

Sorry, Socob, I don't mean to hijack your thread.

As far as mixing, I am kind of disappointed. Windows and Mac systems seem fine with running multiple SourceDataLines at the same time. Are you saying Linux can't handle this, even if we write something that allows the User to pick their preferred sound card?  Tongue

Writing a live mixing routine seems like it should be doable, but a pain. The main thing, I assume is work out the relative volumes of all the source data, then add the audios, frame by frame. Yes? It's basically just an addition operation with provisions made to keep everything aligned in time and to prevent the sums going out of bounds? I guess there is no reason the inner loop can't have 5 different wav files all being read a buffer at a time.

"Greetings my friends! We are all interested in the future, for that is where you and I are going to spend the rest of our lives!" -- The Amazing Criswell
Offline gouessej
« Reply #9 - Posted 2011-08-25 08:53:23 »

Hi

As far as I know, since Java 1.5, JavaSound tries to use the best direct audio mixer. However, on some Linux machines, when some webcams are plugged, it tries to use the webcam as sound output  Angry I wrote a bug report about it. On the other hand, some direct audio mixers are buggy. Some programmers try to use "Java Sound Audio Engine" to get the same behavior everywhere.

As far as I know, there is no "Java Sound Audio Engine" on OpenJDK which means that in this case, you have to use another mixer.

That's why OpenAL (with OpenALSoft) through JOAL (JogAmp) or LWJGL is a better solution in my humble opinion, Riven's suggestion is interesting too. These 2 options are the most viable cross-platform solutions to play sounds in Java.

As far as mixing, I am kind of disappointed. Windows and Mac systems seem fine with running multiple SourceDataLines at the same time. Are you saying Linux can't handle this, even if we write something that allows the User to pick their preferred sound card?  Tongue
Java Sound is quite badly maintained on Linux, it has nothing to do with Linux itself.

Writing a live mixing routine seems like it should be doable, but a pain. The main thing, I assume is work out the relative volumes of all the source data, then add the audios, frame by frame. Yes? It's basically just an addition operation with provisions made to keep everything aligned in time and to prevent the sums going out of bounds? I guess there is no reason the inner loop can't have 5 different wav files all being read a buffer at a time.
Paul Lamb is already working on its own software mixer, I hope he will succeed.

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline nsigma
« Reply #10 - Posted 2011-08-25 11:46:32 »

That's why OpenAL (with OpenALSoft) through JOAL (JogAmp) or LWJGL is a better solution in my humble opinion, Riven's suggestion is interesting too. These 2 options are the most viable cross-platform solutions to play sounds in Java.

If you want to do the actual processing in Java, then Riven's way is the only way.

As far as mixing, I am kind of disappointed. Windows and Mac systems seem fine with running multiple SourceDataLines at the same time. Are you saying Linux can't handle this, even if we write something that allows the User to pick their preferred sound card?  Tongue
Java Sound is quite badly maintained on Linux, it has nothing to do with Linux itself.

Actually, no, it has as much to do with Linux (well ALSA) as Java.  Notwithstanding that Java uses deprecated bits of the Alsa API, JavaSound only supports multiple lines on Linux when ALSA and the soundcard supports hardware mixing, which is not very often.  On Windows, this is emulated in the soundcard drivers, but Java doesn't use this feature of ALSA at the moment.  IMO this is a good thing - the direct mixers do what they're meant to, and give you direct access to the capabilities of the underlying hardware.  That's one reason why Linux has the best JavaSound performance (in terms of latency).  The problem is people not using the API properly.

Writing a live mixing routine seems like it should be doable, but a pain. The main thing, I assume is work out the relative volumes of all the source data, then add the audios, frame by frame. Yes? It's basically just an addition operation with provisions made to keep everything aligned in time and to prevent the sums going out of bounds? I guess there is no reason the inner loop can't have 5 different wav files all being read a buffer at a time.
Paul Lamb is already working on its own software mixer, I hope he will succeed.

And there are many other options - Beads, Rasmus, JASS, Toot, RAPL (when I finish extracting it from Praxis), and even Gervill if you hacked it out.  Software mixing is not exactly hard, particularly if you use float buffers (which any decent audio API does).  As Phil says, it's basically just a summation buffer (possibly with some -1:1 limiting or an auto gain control).

Crackly?! What does that mean? I am aware of something that I assumed was kind of like anti-aliasing in the high registers, especially the square wave. Is that what you mean? Crackly as a descriptor sounds much worse than that. Does the sine wave crackle, too? That is clear as a bell, over here.

The sine wave is actually the worst of the lot.  Quite harsh discontinuities in the audio.  Any chance you've got some out-of-range numbers in there somewhere?  ALSA can be rather unforgiving with that.

Sorry, Socob, I don't mean to hijack your thread.

Well, I kind of initiated the hijack.   persecutioncomplex  I'll post any further things in your thread.

Praxis LIVE - open-source intermedia toolkit and live interactive visual editor
Digital Prisoners - interactive spaces and projections
Offline gouessej
« Reply #11 - Posted 2011-08-25 13:44:07 »

If you want to do the actual processing in Java, then Riven's way is the only way.
As far as I know, Socob just wants to play some sounds, OpenAL is fine to do this.

Actually, no, it has as much to do with Linux (well ALSA) as Java.  Notwithstanding that Java uses deprecated bits of the Alsa API, JavaSound only supports multiple lines on Linux when ALSA and the soundcard supports hardware mixing, which is not very often.  On Windows, this is emulated in the soundcard drivers, but Java doesn't use this feature of ALSA at the moment.  IMO this is a good thing - the direct mixers do what they're meant to, and give you direct access to the capabilities of the underlying hardware.  That's one reason why Linux has the best JavaSound performance (in terms of latency).  The problem is people not using the API properly.
Therefore, it is not a problem in ALSA. Non-Java applications and APIs using it work fine, better than OSS. I don't see what you mean because ALSA supports multiple lines only if the underlying hardware supports hardware mixing.

And there are many other options - Beads, Rasmus, JASS, Toot, RAPL (when I finish extracting it from Praxis), and even Gervill if you hacked it out.  Software mixing is not exactly hard, particularly if you use float buffers (which any decent audio API does).  As Phil says, it's basically just a summation buffer (possibly with some -1:1 limiting or an auto gain control).
Socob only wants to play some sounds like me. Software mixing is not hard for you but it is not the case for me. Paul Lamb has written a nice and easy-to-use API with several plug-ins for JOAL, LWJGL and Java Sound, it supports Ogg Vorbis too. The projects you quote are interesting but in my case, I need an out-of-the box solution, I have no time to hack anything about sound, I cannot spend some time in building all my tools, I have to focus on some things. With Paul Lamb Sound Library, you almost only have to know whether you want to stream your sound or not and which plug-ins you have to use depending on which file formats you need, you can learn how to use it in less than an hour, it is an excellent solution if you do not have any time to tinker existing solutions. Paul Lamb knows the limitations of each APIs he uses, he tries to work around them when possible. Therefore, I think that someone who is not a specialist of sound will have less problems and will waste less time by using it instead of using directly Java Sound or by using the APIs you suggest. I know only some of them, maybe I'm wrong.

Offline Socob

Senior Newbie





« Reply #12 - Posted 2011-08-25 14:07:37 »

The Theremin isn't working? Interesting. When you drag the mouse upwards, the volume should rise. Are you able to get other sounds via other Java programs? You may have uncovered something that I have not dealt with yet!

My other Applets with sound are http://hexara.com/game.html (warning, slow load) and http://hexara.com/VSL/VSL2.htm
Unfortunately, I can't seem to get any sound out of any of your applets. I have no idea why it works for nsigma, considering we're both using very similar Linux versions (maybe it's related to the Java plugin - Sun/Oracle vs. OpenJDK - but that shouldn't matter, right?). Regarding the sound approach in the game again (synchronization), you can't really stop the sound once it's playing, that's correct. Keep in mind that the game had to be created within 48 hours, though, and that the sound is extremely simplistic. As I intend to take part in that competition eventually, as well, (with the somewhat self-imposed limit of using "pure" Java), I doubt I'll have time or energy to deal with annoying sound issues or to implement some complex sound system.


@nsigma:
So, basically, I seem to have approached the JavaSound API in the wrong way. What I was basically looking for was the way it was used in my first post - you load a file, get a sound clip, let it play when it's needed, and it gets done without much trouble. I don't need any special features or anything (heck, for this, I don't even need volume control). I haven't had time to look at your links/suggestions yet, but I'll see what I can get done. Still, isn't there an easier way to do something relatively simple like this? So far, JavaSound seems terribly non-portable and completely opposite to Java's cross-platform goals.


@gouessej:
You've desribed my problem pretty exactly - I don't want/need sophisticated audio due to the circumstances. OpenAL would be a solution, but as I've said, I'd like to avoid native libraries. That doesn't mean it doesn't work, though - in fact, the Slick2D library (which uses LWJGL/OpenAL) does pretty much exactly what I want: you create a "Sound" object, call a "play" method, and you're done. The problem is that I want that, but without native dependencies. I'll have a look at Paul's library, it seems to be pretty popular.
Offline nsigma
« Reply #13 - Posted 2011-08-25 15:15:18 »

If you want to do the actual processing in Java, then Riven's way is the only way.
As far as I know, Socob just wants to play some sounds, OpenAL is fine to do this.
Not in pure Java it's not!

Therefore, it is not a problem in ALSA. Non-Java applications and APIs using it work fine, better than OSS. I don't see what you mean because ALSA supports multiple lines only if the underlying hardware supports hardware mixing.
I didn't say it was a problem with ALSA.  Non-Java applications work fine, and so do Java applications when they do what the majority of native applications do, which is software mix to a single line!   ALSA (leaving aside dmix for a minute) only supports multiple lines where the soundcard itself provides them.  ALSA through dmix, and also PulseAudio, provide software mixing on top of the basic ALSA drivers.  However, this is to allow multiple software to play at the same time, not usually to allow any individual software to open multiple lines.

See also - http://www.jsresources.org/faq_audio.html#alsa_mixing

And there are many other options - Beads, Rasmus, JASS, Toot, RAPL (when I finish extracting it from Praxis), and even Gervill if you hacked it out.  Software mixing is not exactly hard, particularly if you use float buffers (which any decent audio API does).  As Phil says, it's basically just a summation buffer (possibly with some -1:1 limiting or an auto gain control).
Socob only wants to play some sounds like me. Software mixing is not hard for you but it is not the case for me. Paul Lamb has written a nice and easy-to-use API with several plug-ins for JOAL, LWJGL and Java Sound, it supports Ogg Vorbis too. The projects you quote are interesting but in my case, I need an out-of-the box solution, I have no time to hack anything about sound, I cannot spend some time in building all my tools, I have to focus on some things. With Paul Lamb Sound Library, you almost only have to know whether you want to stream your sound or not and which plug-ins you have to use depending on which file formats you need, you can learn how to use it in less than an hour, it is an excellent solution if you do not have any time to tinker existing solutions. Paul Lamb knows the limitations of each APIs he uses, he tries to work around them when possible. Therefore, I think that someone who is not a specialist of sound will have less problems and will waste less time by using it instead of using directly Java Sound or by using the APIs you suggest. I know only some of them, maybe I'm wrong.

I understand all that, and I'm not trying to suggest everyone become an audio specialist (although I don't believe for a minute you'd really find software mixing hard considering what else you've done - it's basically summing arrays of data).  Both Beads and JASS could probably work out of the box pretty much for this, though licences would be an issue for some - that's why my intention with RAPL is to be GPL+CPE.  There is a definite need for a nice audio library built on top of JavaSound that makes this simple to work with, and I gave some examples of some I already know about.  Paul's library has a nice API, but I don't agree with you that he's working around the limitation of the APIs, at least for JavaSound - all the mixers tell you how many simultaneous lines they can support, which on Linux will generally be 1!

@nsigma:
So, basically, I seem to have approached the JavaSound API in the wrong way. What I was basically looking for was the way it was used in my first post - you load a file, get a sound clip, let it play when it's needed, and it gets done without much trouble.  I don't need any special features or anything (heck, for this, I don't even need volume control). I haven't had time to look at your links/suggestions yet, but I'll see what I can get done. Still, isn't there an easier way to do something relatively simple like this?

Yeah, that's the bit of JavaSound that doesn't work very well!  Smiley  Personally, I'd look for a simple 3rd-party replacement.  From my list I'd look at Beads or JASS first, or maybe some of the audio libraries written for Processing.

So far, JavaSound seems terribly non-portable and completely opposite to Java's cross-platform goals.

Not really.  The API allows you to query the underlying system for capabilities.  You just can't expect the same capabilities on every platform, but I'd rather Java echoed the underlying system than tried to paper over the cracks!  Lots of things in Java work differently on different platforms - as long as the API allows you to query the difference, I don't see the problem with that.

Praxis LIVE - open-source intermedia toolkit and live interactive visual editor
Digital Prisoners - interactive spaces and projections
Offline gouessej
« Reply #14 - Posted 2011-08-25 15:34:21 »

@gouessej:
You've desribed my problem pretty exactly - I don't want/need sophisticated audio due to the circumstances. OpenAL would be a solution, but as I've said, I'd like to avoid native libraries. That doesn't mean it doesn't work, though - in fact, the Slick2D library (which uses LWJGL/OpenAL) does pretty much exactly what I want: you create a "Sound" object, call a "play" method, and you're done. The problem is that I want that, but without native dependencies. I'll have a look at Paul's library, it seems to be pretty popular.
Ok, you're right. If you want to avoid native dependencies, OpenAL is not the way to go. Paul Lamb Sound Library is even used by Minecraft Smiley It would allow you to go on using Java Sound without needing any extra effort to switch to JOAL (except for deployment).

Offline krasse
« Reply #15 - Posted 2011-08-25 20:15:16 »

The only tricky part of doing the mixing yourself is that you have to convert to and from different formats.

Here is a piece of source code that will take care of a lot of convertions. It is part of the Gervill midi synthesizer.

Offline gouessej
« Reply #16 - Posted 2011-08-26 08:28:35 »

The only tricky part of doing the mixing yourself is that you have to convert to and from different formats.

Here is a piece of source code that will take care of a lot of convertions. It is part of the Gervill midi synthesizer.
Thank you very much for this example  Grin

Offline nsigma
« Reply #17 - Posted 2011-08-26 11:37:30 »

The only tricky part of doing the mixing yourself is that you have to convert to and from different formats.

Here is a piece of source code that will take care of a lot of convertions. It is part of the Gervill midi synthesizer.
Thank you very much for this example  Grin

That is the same class used in the AudioServers code you were asking me about a month ago!  If you'd bothered to follow up on my long reply to your question you'd have found it.  Tongue

The other 'conversion' code potentially of use is interpolation to handle pitch changes - not so much to handle dynamic pitch changes but for sample rate conversion.  I say potentially because it makes more sense to convert all your samples to the same sample rate beforehand, but I know not everyone does.  There is some good code for this in Gervill too, though from recollection the API is not as simple to use externally as it could be.

Praxis LIVE - open-source intermedia toolkit and live interactive visual editor
Digital Prisoners - interactive spaces and projections
Offline gouessej
« Reply #18 - Posted 2011-08-26 11:46:49 »

That is the same class used in the AudioServers code you were asking me about a month ago!  If you'd bothered to follow up on my long reply to your question you'd have found it.  Tongue
Sorry. I remind you that I'm a former participant to a silly reality TV show, it has caused me a lot of troubles and it is sometimes difficult for me to stay focused. I put this link into my bookmarks. Anyway, I still think writing a software mixer is not trivial, at least for me.

Offline nsigma
« Reply #19 - Posted 2011-08-26 11:50:39 »

Socob, just went to check out Phil's theremin and got no sound this time.  I know the reason though - I'd just watched a Flash video.  Restarting Firefox fixed this, but I've noticed this before - Flash can have a tendency to not release the soundcard so Java can't get an output line.  It probably doesn't cover your issue, but it's another one to be aware of.

Praxis LIVE - open-source intermedia toolkit and live interactive visual editor
Digital Prisoners - interactive spaces and projections
Offline Socob

Senior Newbie





« Reply #20 - Posted 2011-08-27 01:41:45 »

@nsigma:
Well, that's cool beans, because I come into contact with Flash all the time. Also, having to tell users to avoid Flash if they want sound doesn't sound fun.


As a general update, I've tried out Paul's library. As expected, using it with OpenAL works perfectly without trouble. However, if I use the JavaSound part of Paul's library, I get the exact same problems as before: No sound whatsoever with the Sun/Oracle JDK, and slow/error-prone sound with OpenJDK. I guess I can try some of the other suggested libraries later, but at this point, I don't see how that would change things. To be honest, I'm getting extremely annoyed with this. I mean, what's the point of trying to do something like software mixing or using another library if I can't get a single sound out of the Sun/Oracle JDK at all? I'm not trying to do anything fancy, like opening multiple lines or anything. I tested each of the available mixers by getting a single line from the mixer and trying to play one .wav file with that. Half of them crashed with an exception with even the most basic .wav file (unsupported format - well, what format is supported, then?), while the other half just didn't do anything. The fact that I do get sound with OpenJDK seems to be related to the missing mixers after all - Google found me this link: http://mail.openjdk.java.net/pipermail/sound-dev/2011-May/000115.html, which indicates that with the Sun/Oracle JDK, JavaSound does not seem to provide any mixers on Linux that work reliably. The "Java Sound Audio Engine" mixer, which I've also seen mentioned sometimes, doesn't even seem to exist on my machine.

Really, it's going to take a lot to convince me that JavaSound on Linux is not completely worthless. Actually, it would help if anyone could post a tiny bit of example code that plays a sound on Linux with the Oracle/Sun JDK, because I haven't seen that yet. In particular, it would help because I'm still not sure if I'm using the API the "right" way, since one apparently has to follow a bunch of obscure, undocumented rules to do anything with JavaSound/Linux.
Offline nsigma
« Reply #21 - Posted 2011-08-27 08:46:38 »

"they call me dava ja vu they do they call me dave ja vu"  Cheesy

Well, you could try out the audio examples in Praxis (link in sig - also see JAudioLibs thread linked above), but I don't think this would class as a lightweight example!  I'd still be interested to know if it has the same issue mind you ...  Smiley

The best bet is probably to try the JSInfo applet / application at http://www.jsresources.org/apps/jsinfo.html.  The applet should be fine for testing output, though doesn't give you access to all of JavaSound (eg. input needs security permissions).  Not only does this allow you to query all the mixers, it gives you a GUI for running through all the various line open permutations with test sound output and will tell you of any errors.  Source code for it is available, and there are some other simple audio examples on that site.

The message you linked to highlights the issue that Java (Oracle one) always wants to open the soundcard exclusively - Flash used to be (sometimes still is?) the same.  It is highly likely that you've got another application accessing the soundcard (try switching off any sound theme for the desktop, checking for any audio apps in system tray, and possibly killing pulseaudio too and see if that helps at all).  This is the reason a PulseAudio mixer was added to OpenJDK - not sure if that made its way into Java 7?!  Personally, I find PulseAudio to be more trouble than it's worth most of the time though.

Praxis LIVE - open-source intermedia toolkit and live interactive visual editor
Digital Prisoners - interactive spaces and projections
Offline Socob

Senior Newbie





« Reply #22 - Posted 2011-08-27 15:21:38 »

@nsigma:
At first, I was like "what the heck are you talking about?", then I looked at my post and went "how did THAT happen?".

Anyway, I'm kind of shocked. The Audio example in Praxis seems to work without any trouble at all, even while playing Flash videos at the same time. How did you do that? Does it use anything else other than JavaSound for audio output? If not, I think I'll take a very close look at Praxis/JAudioLibs after all.

As for the JSInfo applet, that is indeed useful, especially if you have no idea what the mixers are actually supposed to do (input or output) (like me). I couldn't get sound output to work with that, but the GUI confused me a little, so I might've been doing it wrong.

Regarding the PulseAudio mixer, I already seem to have that with OpenJDK 6 (-> first post). OpenJDK also has the "default" ALSA mixer mentioned in the link I posted, which doesn't seem to lock the soundcard exclusively and which apparently does work (even on my machine), so even if you don't like PulseAudio, I don't see why this shouldn't be included in both JDKs, as it seems to be (almost?) the only reliable way. Now, of course I could try to close everything I have running, kill PulseAudio and so on and perhaps eventually get sound output with one of the mixers even with the Sun/Oracle JDK, but I can't expect my users to do the same thing. There really needs to be a way to output sound without having to impose any kind of ridiculous, strict set of rules on the users, otherwise they're just not going to bother, even if it's not really the developer's fault.
Offline nsigma
« Reply #23 - Posted 2011-08-28 22:43:50 »

Anyway, I'm kind of shocked. The Audio example in Praxis seems to work without any trouble at all, even while playing Flash videos at the same time. How did you do that? Does it use anything else other than JavaSound for audio output? If not, I think I'll take a very close look at Praxis/JAudioLibs after all.

Well, that's good to know, though also intriguing!  If you're not using the JACK output (and it's not set up to by default) then Praxis is just using JavaSound.  You can see how the lines are set up in the initialise() and runImpl() methods here - http://code.google.com/p/praxis/source/browse/audio.servers.javasound/src/org/jaudiolibs/audioservers/javasound/JavasoundAudioServer.java

Couple of other things that Praxis might be doing differently -

* Praxis is currently set up to always open input lines as well (I doubt this is your issue).
* Praxis always iterates through the mixers to find one that supports output lines.  See the find...Mixer() methods in the above class.  I wonder if it's possible that you're experiencing the same issue that gouessej has with JavaSound picking a soundcard (webcam) that is input only.  Although I think you said you'd tried all mixers?

As for the JSInfo applet, that is indeed useful, especially if you have no idea what the mixers are actually supposed to do (input or output) (like me). I couldn't get sound output to work with that, but the GUI confused me a little, so I might've been doing it wrong.

It's not easy to find your way around, that's for sure!  Use the "Line Lifecycle" tab, and click Line [create -> open -> start] and then Data [start].  There doesn't seem to be a way to select a particular mixer for this though.

Regarding the PulseAudio mixer, I already seem to have that with OpenJDK 6 (-> first post). OpenJDK also has the "default" ALSA mixer mentioned in the link I posted, which doesn't seem to lock the soundcard exclusively and which apparently does work (even on my machine), so even if you don't like PulseAudio, I don't see why this shouldn't be included in both JDKs, as it seems to be (almost?) the only reliable way. Now, of course I could try to close everything I have running, kill PulseAudio and so on and perhaps eventually get sound output with one of the mixers even with the Sun/Oracle JDK, but I can't expect my users to do the same thing. There really needs to be a way to output sound without having to impose any kind of ridiculous, strict set of rules on the users, otherwise they're just not going to bother, even if it's not really the developer's fault.

Don't get me wrong, I'd like to see the PulseAudio mixer and an up-to-date ALSA mixer in the standard Oracle JDK, and I wonder whether it's made it in to 7 (not looked yet).  It's just that I've had issues with PulseAudio in the past, and quite frankly don't have much interest in multiple applications playing audio at the same time - I've only one set of ears!  Smiley  I'm all for having the choice though.

I should point out also that on my setup I don't have to jump through any hoops (ie. kill PulseAudio) to get Java sound - I think PulseAudio should auto-suspend when nothing is playing through it.

I'm probably going to be offline for the next week, so good luck with it!

Best wishes, Neil

Praxis LIVE - open-source intermedia toolkit and live interactive visual editor
Digital Prisoners - interactive spaces and projections
Offline gouessej
« Reply #24 - Posted 2011-08-29 08:08:23 »

Socob, you can get better results with JavaSound (and Paul Lamb Sound Library) by converting your files to another format or change the rate (or the sample size; if it is 32, set it to 16 bits). I did it for my game and now, it is ... less bad, it works reliably on Oracle JVM but not completely on OpenJDK.

Offline Socob

Senior Newbie





« Reply #25 - Posted 2011-08-29 14:20:23 »

@nsigma (even if you're offline ;-) ):
I have the suspicion that Praxis might perhaps be started with OpenJDK instead of the Sun/Oracle JVM for some reason on my computer. I started it with the launch script in the "bin" directory, so I don't really know what it's doing, and I haven't found another way to launch it. Still looking into the code, regardless. Also, PulseAudio does auto-suspend if nothing is playing - it's been enough for me to just get rid of every application that's even remotely related to sound, mainly Firefox/Flash, and then JavaSound actually manages to work even with the Oracle JVM (which doesn't help much, of course).

@gouessej:
So, you mean you can play sounds with the Oracle JVM on Linux even if you have, say, a Flash video playing at the same time? That would be strange, because OpenJDK seems to work a lot better for me, and as I said, I can't get sound with the Oracle JVM at all if something else is using sound at the same time. As for the file format, I'm basically already using the most simple file sound format there is. As I wrote in the first post, I'm trying to play uncompressed 44100 Hz, 16bit signed, mono/stereo .wav files, so I don't really know what I should change it to that would work better.
Offline gouessej
« Reply #26 - Posted 2011-08-29 15:19:55 »

It depends on the mixer you use but relying on the availability of such a mixer is not a good idea.

Maybe Praxis is started with OpenJDK because your Linux is configured to use it by default like mine. You can try to use Praxis with Oracle JVM by modifying the script to use this JVM instead of OpenJDK.

Offline paulscode

Senior Member


Medals: 12


Staff Sergeant


« Reply #27 - Posted 2011-08-29 19:47:36 »

I haven't been on the forum in a while .. I seem to have missed a really good conversation here.

I understand all that, and I'm not trying to suggest everyone become an audio specialist (although I don't believe for a minute you'd really find software mixing hard considering what else you've done - it's basically summing arrays of data).
The best solution is to do software mixing on a single line, as you've pointed out.  Unfortunately, there is a little more to it than your characterization if you need to support pitch changes, panning, and mixing multiple formats.  Sure, all those can be done as well, but then you also have to get it to run at an acceptable speed to avoid latency.  Doing the mixing in native rather than pure java is really the way this should be done.. OpenJDK really should ship with its own native software mixer, like the Java Sound Audio Engine.

Paul's library has a nice API, but I don't agree with you that he's working around the limitation of the APIs, at least for JavaSound - all the mixers tell you how many simultaneous lines they can support, which on Linux will generally be 1!
Personally I wouldn't characterize my library as working around the limitation of the API (thats kind of an oxymoron if you think about it), but rather providing a common API to access various other lower-level APIs.

We love death.  The US loves life.  That is the difference between us.  -Osama bin Laden, mass murderer
Offline Riven
« League of Dukes »

JGO Overlord


Medals: 781
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #28 - Posted 2011-08-29 19:52:49 »

The best solution is to do software mixing on a single line, as you've pointed out.  Unfortunately, there is a little more to it than your characterization if you need to support pitch changes, panning, and mixing multiple formats.  Sure, all those can be done as well, but then you also have to get it to run at an acceptable speed to avoid latency.
I think most people here would love to simply play audio reliably. Mixing different formats in plain Java is 'fast enough', if you keep it at that. After we have something that works, it might be time to add features like pitch changes and panning, although I doubt many of us are even remotely interested in such features Smiley => K.I.S.S.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline paulscode

Senior Member


Medals: 12


Staff Sergeant


« Reply #29 - Posted 2011-08-29 21:34:51 »

True.  I guess my perspective has always been 3D sound, which of course requires per-line changes of at least gain and pan, and preferably pitch as well.

We love death.  The US loves life.  That is the difference between us.  -Osama bin Laden, mass murderer
Pages: [1] 2 3
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

atombrot (26 views)
2014-08-19 09:29:53

Tekkerue (24 views)
2014-08-16 06:45:27

Tekkerue (23 views)
2014-08-16 06:22:17

Tekkerue (14 views)
2014-08-16 06:20:21

Tekkerue (22 views)
2014-08-16 06:12:11

Rayexar (60 views)
2014-08-11 02:49:23

BurntPizza (38 views)
2014-08-09 21:09:32

BurntPizza (30 views)
2014-08-08 02:01:56

Norakomi (37 views)
2014-08-06 19:49:38

BurntPizza (67 views)
2014-08-03 02:57:17
List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!