Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (499)
Games in Android Showcase (118)
games submitted by our members
Games in WIP (568)
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 ... 6
  ignore  |  Print  
  Need a really simple library for playing sounds and music? Try TinySound.  (Read 58214 times)
0 Members and 1 Guest are viewing this topic.
Offline kuusisto

Senior Member


Medals: 13



« Posted 2012-03-10 05:06:56 »

https://github.com/finnkuusisto/TinySound

I made TinySound for fun and potentially for use in my own projects.  Have a look if you're interested.  If you find any bugs, please submit them to the issue tracker on the Github.
Offline ReBirth
« Reply #1 - Posted 2012-03-10 05:24:31 »

I read the example, and it's really simple!

Offline kuusisto

Senior Member


Medals: 13



« Reply #2 - Posted 2012-03-11 14:26:40 »

I'm glad you think so.  That was the goal after all.  That is, unless you only mean that the example isn't sufficient for understanding how to use the library.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline ra4king

JGO Kernel


Medals: 347
Projects: 3
Exp: 5 years


I'm the King!


« Reply #3 - Posted 2012-03-11 15:42:40 »

Really nice and simple library, I like it Smiley

Instead of an init() method, you could simply put that in a static block:
1  
2  
3  
static {
    //this stuff is called when this class is loaded into memory
}

Offline davedes
« Reply #4 - Posted 2012-03-11 15:48:08 »

Really nice and simple library, I like it Smiley

Instead of an init() method, you could simply put that in a static block:
1  
2  
3  
static {
    //this stuff is called when this class is loaded into memory
}

But then you can't shutdown() and re-init() ... Tongue

Offline ra4king

JGO Kernel


Medals: 347
Projects: 3
Exp: 5 years


I'm the King!


« Reply #5 - Posted 2012-03-11 15:57:41 »

O__o why would you shutdown then re-init?

Offline kuusisto

Senior Member


Medals: 13



« Reply #6 - Posted 2012-03-11 16:33:06 »

Really nice and simple library, I like it Smiley

Instead of an init() method, you could simply put that in a static block:
1  
2  
3  
static {
    //this stuff is called when this class is loaded into memory
}

That's a reasonable idea, but I like the symmetry of having to initialize and shutdown.
Offline sproingie

JGO Kernel


Medals: 202



« Reply #7 - Posted 2012-03-11 19:10:02 »

The init method does a lot of side-effectful things including starting up the mixer.  It's probably not a good idea to put things like that into a static initializer.  Also, like kuusisto says, you're also able to shut it down and presumably even start it back up, something I could reasonably see doing if you did something like switch the output device.
Offline ra4king

JGO Kernel


Medals: 347
Projects: 3
Exp: 5 years


I'm the King!


« Reply #8 - Posted 2012-03-11 19:58:58 »

Ah OK Smiley

Offline gouessej
« Reply #9 - Posted 2012-03-11 22:07:06 »

Hi

The intention is noble but there are already a lot of "tiny" libraries wrapping only JavaSound. I don't want to discourage you, such a project has a pedagogical interest as it helps you to learn lots of things about JavaSound but I don't really see how it could be useful outside this scope. You wrap only JavaSound, therefore your library inherits its limitations. Your library just has less features than Paul Lamb Sound Library which is quite modular (it's subdivided into several plugins, you can take only the useful parts, it is not heavy), you have no support of OpenAL. I have looked at your source code and I've found some typical "beginner" mistakes. For example, the internal format used by TinySound is hardcoded, what do you do if this one is not supported on a given platform? All your helpers won't work. You seem to use the default mixer, you don't even try to get the "best" one, the one with the best support of mixing. Good luck. Thanks for sharing your source code.

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline kuusisto

Senior Member


Medals: 13



« Reply #10 - Posted 2012-03-11 22:32:49 »

Hi

The intention is noble but there are already a lot of "tiny" libraries wrapping only JavaSound. I don't want to discourage you, such a project has a pedagogical interest as it helps you to learn lots of things about JavaSound but I don't really see how it could be useful outside this scope. You wrap only JavaSound, therefore your library inherits its limitations. Your library just has less features than Paul Lamb Sound Library which is quite modular (it's subdivided into several plugins, you can take only the useful parts, it is not heavy), you have no support of OpenAL. I have looked at your source code and I've found some typical "beginner" mistakes. For example, the internal format used by TinySound is hardcoded, what do you do if this one is not supported on a given platform? All your helpers won't work. You seem to use the default mixer, you don't even try to get the "best" one, the one with the best support of mixing. Good luck. Thanks for sharing your source code.
Like I said, I did this mostly for fun and I'm not trying to compete with Paul's library.  Also, I don't see having fewer features as an inherent flaw unless you need those features, in which case you would use something that has those features.  By no means is TinySound supposed to be feature-rich.  It's just supposed to be really simple.

Edit:
I should also mention for others who may be reading this that TinySound doesn't support only one format as was suggested, but it does store all audio data in memory in a single format.  There is at least some attempt to convert other formats to the internal format.  For those interested, the internal format is 44.1kHz, 16-bit stereo.
Offline davedes
« Reply #11 - Posted 2012-03-12 05:32:44 »

Don't be discouraged by gouessej -- that's an impressive little library you've got. At the very least, the source code provides an excellent starting point for those wanting to write a software mixer but don't have a clue where to begin. Smiley And since this library is basically just sending PCM data, I don't see why it couldn't be extended to support OpenAL.

Paul's library is excellent but it's by no means the holy grail of java sound. Have you looked at the source code? It's pretty brutal; tons of repetition and lots of unnecessary bloat.

It's a great library if you plan to support a wide variety of systems because (a) it's thread-safe and (b) it can use Java Sound as a fallback. But say you are programming a simple OpenGL game using a single thread -- these bonuses are not really necessary, and SoundSystem just becomes a rather bulky wrapper around OpenAL. Because of the compatibility with Java Sound, we lose some nice features of OpenAL like synchronized playback and EFX. And because the actual AL commands are queued and processed in another thread, you can run into issues like this:
1  
2  
SoundSystem.play(source);
boolean b = SoundSystem.playing(source); <-- returns false


On the other hand, Paul's decoders are awesome -- I might use them alongside my own thin OpenAL wrapper for my game.

Online nsigma
« Reply #12 - Posted 2012-03-12 09:53:30 »

Don't be discouraged by gouessej -- that's an impressive little library you've got.

+1  You've got the start of a nice, simple API there.  There's a definite need for a robust but simple software mixing JavaSound solution around here (not sure if Paul Lamb's library finally has this yet?).  I did make a promise a short time ago to fork out the software mixing code from Praxis, but paid work kind of got in the way, and it's never going to be as simple a solution as this anyway.

I particularly like the look of the code for your UpdateRunner (caveat - not tried it yet!) - seems you're writing to the audio line without blocking on write()?  This is the way to get decent performance out of JavaSound.

It's a great library if you plan to support a wide variety of systems because (a) it's thread-safe ...

You say that like it's a good thing!  Wink  Naive synchronization is one of the main causes of bad performance in audio libraries.  Worth reading this article - http://www.rossbencina.com/code/real-time-audio-programming-101-time-waits-for-nothing

In particular with regards to the TinySound library I'd suggest getting rid of all the synchronized methods in Mixer and instead passing events into your audio thread by way of a ConcurrentLinkedQueue.  Just pass in a Runnable to manipulate the lists if you're not in the audio thread, draining  the queue on each read().

Best wishes, Neil

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

Senior Member


Medals: 13



« Reply #13 - Posted 2012-03-12 16:24:06 »

Thanks for the feedback, everyone.

I was reluctant at first to introduce synchronization in the mixer and I would certainly consider some amount of redesign if there were enough complaints about latency, but at this point I'm not sure there is a need.  I didn't really consider OpenAL support as users would then need to distribute native libraries with their projects, making TinySound more complex.  Beside that, TinySound was never meant to be a 3D sound library, so OpenAL support seemed like overkill.  There may be other reasons for support, however, in which case I may eventually consider it.

Ultimately, my thought was that TinySound might be used in projects at the scale of Ludum Dare entries or similar.

Edit:
Of course, I don't want to make it sound like TinySound couldn't be used for more complicated projects than those of Ludum Dare scale.  It could be used anywhere that more advanced audio features are unnecessary and/or where you just want to get sounds working quickly.
Offline gouessej
« Reply #14 - Posted 2012-03-12 21:02:54 »

Don't be discouraged by gouessej -- that's an impressive little library you've got. At the very least, the source code provides an excellent starting point for those wanting to write a software mixer but don't have a clue where to begin. Smiley And since this library is basically just sending PCM data, I don't see why it couldn't be extended to support OpenAL.
I have never tried to discourage him and I wrote his library has a pedagogical interest. Please avoid such false accusations.

Paul's library is excellent but it's by no means the holy grail of java sound. Have you looked at the source code? It's pretty brutal; tons of repetition and lots of unnecessary bloat.
JavaSound is by no means the holy grail of sound in Java. If you really think Paul's source code contains tons of repetition, why haven't you suggested him some improvements?

Offline davedes
« Reply #15 - Posted 2012-03-12 22:14:04 »

Quote
If you really think Paul's source code contains tons of repetition, why haven't you suggested him some improvements?
Because my suggestion would be "rewrite the library with better coding standards." Tongue Truth is, it doesn't really matter since most of the users seem happy enough with the rather limiting SoundSystem singleton.

Offline dimension17

Junior Newbie


Medals: 1



« Reply #16 - Posted 2012-03-14 15:20:08 »

Thanks for sharing this. I love the simplicity.

Just a quick nooby question if I may. I'm just working on sound for my first game, and decided to use your library to make things easier. However I keep getting the following exception when I attempt to load a new sound. Here's the callstack:

1  
2  
3  
4  
5  
6  
7  
8  
Exception in thread "Thread-4" java.lang.NegativeArraySizeException
   at kuusisto.tinysound.TinySound.readAllBytesTwoChannel(TinySound.java:412)
   at kuusisto.tinysound.TinySound.readAllBytes(TinySound.java:365)
   at kuusisto.tinysound.TinySound.loadSound(TinySound.java:335)
   at kuusisto.tinysound.TinySound.loadSound(TinySound.java:310)
   at brickout6.Game.LoadContent(Game.java:95)
   at brickout6.Game.access$100(Game.java:28)
   at brickout6.Game$1.run(Game.java:61)


and the code fragment it fails at:

1  
2  
3  
4  
5  
private static byte[][] readAllBytesTwoChannel(AudioInputStream stream) {
      //read all the bytes (assuming 16-bit, 2-channel)
     int numBytesPerChannel = (int)stream.getFrameLength() *
         (stream.getFormat().getFrameSize() / 2);
      byte[] left = new byte[numBytesPerChannel];


Now, I get that a NegativeArraySizeException is telling me that numBytesPerChannel is returning an invalid array index. but I'm not quite sure why I should be getting it in this case? Checking the code, it performs multiple data validity/null checks on the loaded file prior to reaching this line so if there was something wrong with say, the path to the file, or the integrity of the file, surely this would be flagged sooner by the built-in error handling?

Sorry for the nooby question as I'm very much a beginner at all this. Any idea what's going on here?
Offline kuusisto

Senior Member


Medals: 13



« Reply #17 - Posted 2012-03-14 16:20:00 »

Thanks for sharing this. I love the simplicity.

Just a quick nooby question if I may. I'm just working on sound for my first game, and decided to use your library to make things easier. However I keep getting the following exception when I attempt to load a new sound. Here's the callstack:

1  
2  
3  
4  
5  
6  
7  
8  
Exception in thread "Thread-4" java.lang.NegativeArraySizeException
   at kuusisto.tinysound.TinySound.readAllBytesTwoChannel(TinySound.java:412)
   at kuusisto.tinysound.TinySound.readAllBytes(TinySound.java:365)
   at kuusisto.tinysound.TinySound.loadSound(TinySound.java:335)
   at kuusisto.tinysound.TinySound.loadSound(TinySound.java:310)
   at brickout6.Game.LoadContent(Game.java:95)
   at brickout6.Game.access$100(Game.java:28)
   at brickout6.Game$1.run(Game.java:61)


and the code fragment it fails at:

1  
2  
3  
4  
5  
private static byte[][] readAllBytesTwoChannel(AudioInputStream stream) {
      //read all the bytes (assuming 16-bit, 2-channel)
     int numBytesPerChannel = (int)stream.getFrameLength() *
         (stream.getFormat().getFrameSize() / 2);
      byte[] left = new byte[numBytesPerChannel];


Now, I get that a NegativeArraySizeException is telling me that numBytesPerChannel is returning an invalid array index. but I'm not quite sure why I should be getting it in this case? Checking the code, it performs multiple data validity/null checks on the loaded file prior to reaching this line so if there was something wrong with say, the path to the file, or the integrity of the file, surely this would be flagged sooner by the built-in error handling?

Sorry for the nooby question as I'm very much a beginner at all this. Any idea what's going on here?

This isn't a nooby question; I think you've just encountered a bug in my code.  Either the frame length is negative or the frame size is.  I would bet that the frame size is -1, meaning that your audio file has no specified frame size.  I'm not sure how I should handle that in the code, but I guess if it's linear PCM, which it should be if it reaches this point in the code, then the frame size is just the number of bytes per sample multiplied by the number of channels.  I'll open an issue on the TinySound Github page to take care of this ASAP.  It would also help a lot if I could get a copy of your audio file for testing, but since it's an asset I understand if that isn't possible.
Offline ra4king

JGO Kernel


Medals: 347
Projects: 3
Exp: 5 years


I'm the King!


« Reply #18 - Posted 2012-03-14 17:27:44 »

You're casting stream.getFrameLength() to an int, meaning that if the value of the long was greater than 2147483647 ((2^31)-1), the value will become a negative number.

Offline kuusisto

Senior Member


Medals: 13



« Reply #19 - Posted 2012-03-14 17:34:27 »

You're casting stream.getFrameLength() to an int, meaning that if the value of the long was greater than 2147483647 ((2^31)-1), the value will become a negative number.

True.  I should check for that too (I'll open an issue).  Still, that would mean that the audio file being loaded is over 13 hours long, so I feel like that's a less likely explanation for this specific scenario.
Offline dimension17

Junior Newbie


Medals: 1



« Reply #20 - Posted 2012-03-14 19:54:30 »

  It would also help a lot if I could get a copy of your audio file for testing, but since it's an asset I understand if that isn't possible.

No probs at all. It was just a random .wav file that I downloaded to test drive the library. Grab it here http://dnfw.org/hl/sound/kart/coin.wav

Hope it helps Smiley
Offline kuusisto

Senior Member


Medals: 13



« Reply #21 - Posted 2012-03-14 20:36:17 »

  It would also help a lot if I could get a copy of your audio file for testing, but since it's an asset I understand if that isn't possible.

No probs at all. It was just a random .wav file that I downloaded to test drive the library. Grab it here http://dnfw.org/hl/sound/kart/coin.wav

Hope it helps Smiley


Thanks.  It would appear that, after conversion to the internal format using Java's AudioSystem class, the getFrameLength() function is returning -1.  I can read all the bytes into a list instead of precomputing, but perhaps someone else knows why this is the case.  It doesn't appear to be documented.  I'm at work right now, but I'll try to fix this sometime tonight.
Offline kuusisto

Senior Member


Medals: 13



« Reply #22 - Posted 2012-03-15 04:55:05 »

I
  It would also help a lot if I could get a copy of your audio file for testing, but since it's an asset I understand if that isn't possible.

No probs at all. It was just a random .wav file that I downloaded to test drive the library. Grab it here http://dnfw.org/hl/sound/kart/coin.wav

Hope it helps Smiley


Thanks.  It would appear that, after conversion to the internal format using Java's AudioSystem class, the getFrameLength() function is returning -1.  I can read all the bytes into a list instead of precomputing, but perhaps someone else knows why this is the case.  It doesn't appear to be documented.  I'm at work right now, but I'll try to fix this sometime tonight.

It looks like this conversion is supported since Java 7 and the file simply won't load in 6.  Since I'm not entirely convinced yet that this isn't a bug, I've just pushed changes that check for negative frame length and don't load the sound if so.  Unfortunately, that means you'll need to use a different audio file to play around.

For generating nice, simple sound effects I highly recommend as3sfxr (http://www.superflashbros.net/as3sfxr/), which is a Flash port of Dr. Petter's sfxr (http://www.drpetter.se/project_sfxr.html).
Offline dimension17

Junior Newbie


Medals: 1



« Reply #23 - Posted 2012-03-15 10:38:02 »

Wow, that's a really useful tool. Thanks!  Cool
Offline philfrei
« Reply #24 - Posted 2012-03-15 22:17:23 »

Anyone with half a brain can take a sound file and load it into Audacity (free) and convert it to the format required by the sound service. I see no reason why conversion has to be a requirement, as long as the game can play the sound correctly.

I spent some time looking at Paul Lamb's sound system and was overwhelmed. Modular or not, it is like a couple phone books is size. I was hoping to learn a thing or two but mostly got lost. So I can sympathize with the desire to make a small sound system.

Based on things I've heard from folks here, though, and on my own experiences, a web game pretty much can't use .wav files other than a few short sf/x, because of the download time. Some sort of compression is needed and Ogg/Vorbis is preferred. I think if you can figure out a way to support Ogg/Vorbis, you will have solved a big obstacle. Paul's system does so, and is to be recommended for that.

I couldn't figure out how to do some "fancy" things I wanted to do, like looping (via alternating two playbacks) longer Ogg/Vorbis files without getting memory leaks. Also, the very act of playing a compressed sound is significantly more costly than playing a PCM format file. (Was looking at decompressing and storing as .wav on the client, but that gets into a lot of hoohah about Signing.)

Hopefully you will have better luck if you decide to tackle this. For myself, I've decided to ditch Ogg/Vorbis and to generate my sounds on the fly. I can do this because I have a lot of background with FM and it is pretty efficient for sound synthesis.

Best of luck with your project!

"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 davedes
« Reply #25 - Posted 2012-03-15 22:35:09 »

philfrei - Decoding an OGG to PCM data can be done relatively painlessly with libraries like JOrbis. Alternatively, you could use Slick-Util's OGGInputStream, or Paul's OGG decoders on their own. Then you don't need to worry about how to play the compressed data, or having to sign anything, or storing WAV files on the user's machine, or whatever you were trying to do before.

Offline philfrei
« Reply #26 - Posted 2012-03-15 23:23:55 »

Thanks. JOrbis didn't work 100% for me. Maybe it reflects more on my competence than the library. I was having memory leak problems, using code based on this tutorial: http://www.jcraft.com/jorbis/tutorial/Tutorial.html Perhaps there is a better example to use for implementing. Or I didn't modify the code in a good way for the degree of replays I was trying to build into the app in question.

For sure, others have had good results with JOrbis. And I have a very appealing FM workaround, so I haven't looked back to figure out where I went wrong.

But to stay on topic, a big plus for TinySound would be to allow use of JOrbis, and the above link has both a program that works and lots of references & useful links, if the OP doesn't already know about them and is interested.  Smiley

"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 kuusisto

Senior Member


Medals: 13



« Reply #27 - Posted 2012-03-16 16:34:07 »

But to stay on topic, a big plus for TinySound would be to allow use of JOrbis, and the above link has both a program that works and lots of references & useful links, if the OP doesn't already know about them and is interested.  Smiley

This isn't a bad idea.  I like that JOrbis is pure java (no native libraries to distribute) and wouldn't require me to change my license.  I'll look into this.  On the other hand, it might be kind of interesting/fun to write my own Vorbis decoder, but that would perhaps take a different level of motivation.
Offline ra4king

JGO Kernel


Medals: 347
Projects: 3
Exp: 5 years


I'm the King!


« Reply #28 - Posted 2012-03-16 18:13:37 »

This code is all you need to get JOrbis working with Java Sound. Then you just need to include this JAR that includes JOrbis and the necessary metadata to tell Java Sound to use it for OGG files Smiley

Offline kuusisto

Senior Member


Medals: 13



« Reply #29 - Posted 2012-03-18 16:59:08 »

I've updated TinySound for better format conversion and lag prevention (frame-skipping).  I'm working on Vorbis support using Javazoom's VorbisSPI library.  It should work right out of the box, but something is off.  I hope to have that working by the end of today.
Pages: [1] 2 3 ... 6
  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.

Pippogeek (41 views)
2014-09-24 16:13:29

Pippogeek (32 views)
2014-09-24 16:12:22

Pippogeek (22 views)
2014-09-24 16:12:06

Grunnt (47 views)
2014-09-23 14:38:19

radar3301 (30 views)
2014-09-21 23:33:17

BurntPizza (65 views)
2014-09-21 02:42:18

BurntPizza (37 views)
2014-09-21 01:30:30

moogie (44 views)
2014-09-21 00:26:15

UprightPath (53 views)
2014-09-20 20:14:06

BurntPizza (55 views)
2014-09-19 03:14:18
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!