Java-Gaming.org    
Featured games (91)
games approved by the League of Dukes
Games in Showcase (579)
games submitted by our members
Games in WIP (500)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  My way of playing wav files as sound effects (in simple Java2D)  (Read 8902 times)
0 Members and 1 Guest are viewing this topic.
Offline Cyclonis

Senior Newbie





« Posted 2006-05-07 00:12:47 »

Hi, quite analogous to the static class that is being widely used to accelerate images in your gfx card, I also made a static class which plays sampled media sounds, like .wav files

All you have to do is put this class in your project tree, initialize all the sounds by calling this once anywhere: SoundHandler.get().loadSoundFx();

and whenever you need to play a sound just call: SoundHandler.get().play("boom1");


I am also pretty much a beginner, so I hope other beginners can make good use of this class too. If you have any questions or comments, reply to this thread, or email me at k.verbist@student.tudelft.nl

I am also interested in what the advanced programmers have to say about this class.

/*
 * SoundHandler.java
 *
 * Created on May 6, 2006, 1:39 AM
 *
 * To change this template, choose Tools | Options and locate the template under
 * the Source Creation and Management node. Right-click the template and choose
 * Open. You can then make changes to the template in the Source Editor.
 */

package tankpwnage;

import java.util.HashMap;

import java.io.File;
import java.io.IOException;

import javax.sound.sampled.*;

/**
 *
 * @author Cyclonis Delta
 */
public class SoundHandler implements LineListener {
   
    private static final int BUFFER = 128000;
   
    private static SoundHandler instance = new SoundHandler();
   
    private HashMap soundFiles;
       
    public static SoundHandler get() {
        return instance;
    }
   
    public void loadSoundFx() {
        soundFiles = new HashMap();
        File directory = new File("./sound/fx");
        File[] files = directory.listFiles();
        for (int i=0;i<files.length;i++) {
            if (files.isFile()) {
                // This is a sound effect
                String filename = files.getName();
                String path = "./sound/fx/"+filename;
                File theFile = new File(path);
                int dot = filename.indexOf(".wav");
               
                String ref = filename.substring(0, dot);
               
                AudioInputStream audioInputStream = null;
                Clip clip = null;
               
               
                try {
                    audioInputStream = AudioSystem.getAudioInputStream(theFile);
                    if (audioInputStream != null) {
         AudioFormat   format = audioInputStream.getFormat();
         DataLine.Info   info = new DataLine.Info(Clip.class, format);
         try
         {
            clip = (Clip) AudioSystem.getLine(info);
            //clip.addLineListener(this);
            clip.open(audioInputStream);
                                soundFiles.put(ref, clip);
         }
         catch (LineUnavailableException e)
         {
            e.printStackTrace();
         }
         catch (IOException e)
         {
            e.printStackTrace();
         }
         
                    }
                }
                catch (Exception e) {
                    e.printStackTrace();
                }
               
                               
            }
        }
    }
   
    public void update(LineEvent event)
   {
      if (event.getType().equals(LineEvent.Type.STOP))
      {
                        Clip clip = (Clip)event.getLine();
                        clip.setFramePosition(1);
      }
      else if (event.getType().equals(LineEvent.Type.CLOSE))
      {
         /*
          *   There is a bug in the jdk1.3/1.4.
          *   It prevents correct termination of the VM.
          *   So we have to exit ourselves.
          */
         System.exit(0);
      }
   }
   
    public void play(String ref) {
               
        Clip clip = (Clip) soundFiles.get(ref);
        if (clip.isRunning()) {
            clip.stop();
            clip.setFramePosition(1);
        }
        clip.addLineListener(this);
        //while (!clip.isRunning()) {
        clip.start();
        //}
       
       
    }
   
}
Offline fantasyer

Innocent Bystander





« Reply #1 - Posted 2006-05-07 08:59:51 »

Hi, i am a newbie and i am also interesting in your code. I think it is very easy to use.
However, i have two questions about the code.
1> When u have many wav files, does it need too much memory?
2> While playing many files together, does it work well?

Thanks!
Offline SluX

Junior Member





« Reply #2 - Posted 2006-05-07 10:04:17 »

Hmm i ve noticed that when u call the loadSoundFx() u always do soundFiles = new HashMap();
So if it gets called more than once it will spend unnecessary time loading again...It would be better to initialize it in singleton's constructor.....

"Intelligence is the most beautiful gift and the greatest temptation which one life can receive from the gods."Me Cheesy
Play strategic football
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Cyclonis

Senior Newbie





« Reply #3 - Posted 2006-05-07 12:43:37 »

Hi,

Yes, you could load it with the singleton, as long as you load it only once. I load it once when the game starts, I think that is ok too.

I didn't notice a significant drop in frame rate, so I guess it does not take a lot of memory. my game plays around 400 fps, with or without the sounds

I did notice that with a lot of sounds, sometimes a particular sound gets skipped or played a little too late.  If someone manages to fix that in this class, I'd be happy to see it
Offline SluX

Junior Member





« Reply #4 - Posted 2006-05-08 23:02:28 »

400 fps? Are u sure about that....sounds a bit too much Wink

"Intelligence is the most beautiful gift and the greatest temptation which one life can receive from the gods."Me Cheesy
Play strategic football
Offline Cyclonis

Senior Newbie





« Reply #5 - Posted 2006-05-10 15:01:50 »

hi,

Yeah I get around 400 fps when I only let the thread sleep for 1 ms        I used to get only a maximum of 60 but I changed my code according to that hardware acceleration tutorial for Java and it boosted all my game's FPS up to around 400.
Offline Kova

Senior Member





« Reply #6 - Posted 2006-05-11 10:45:39 »

what hardware accelation tutorial for Java? Tnx.
Offline SluX

Junior Member





« Reply #7 - Posted 2006-05-20 10:49:31 »

U see...i m really not sure that your results are correct. Especially if u r using Thread.sleep() which is very innacurate....well...mayb u r testing on linux tho....more accurate there than on win...

"Intelligence is the most beautiful gift and the greatest temptation which one life can receive from the gods."Me Cheesy
Play strategic football
Offline CommanderKeith
« Reply #8 - Posted 2006-05-20 17:15:24 »

hi,

Yeah I get around 400 fps when I only let the thread sleep for 1 ms        I used to get only a maximum of 60 but I changed my code according to that hardware acceleration tutorial for Java and it boosted all my game's FPS up to around 400.

400 FPS with a sleep of 1 ms means you take only 1ms (plus a tiny bit) to paint the screen.  I can't see how that's possible whatever acceleration (OGL or direct draw) you're using, unless you don't paint the whole screen & just re-render the parts that changed.

U see...i m really not sure that your results are correct. Especially if u r using Thread.sleep() which is very innacurate....well...mayb u r testing on linux tho....more accurate there than on win...

I think sleep gaurantees a minimum that is accurate, but the maximum is innaccurate.  Regardless, 400fps does seem too high.

This is how you calculate FPS:

float avMillisBetweenUpdates = (float)((cumulativeNanosBetweenUpdates)/(counter*1000000f));
// where cumulativeNanosBetweenUpdates is nanos over which we're measuring framerate.  (nanosecond time from System.nanoTime() )
// counter is number of frame draws over the above time.

float fps = (float)(1000/avMillisBetweenUpdates);

If 400 FPS is possible & you repaint the whole screen, I'd like to know how too  Smiley
Keith



Offline Kova

Senior Member





« Reply #9 - Posted 2006-05-22 00:40:14 »

if you sleep 1ms every tick and you have 400 fps, that would mean you sleep 400ms in one second and on the rest 600 ms you manage to render 400 fps... not likely Wink
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Cyclonis

Senior Newbie





« Reply #10 - Posted 2007-05-29 01:27:58 »

Hi,

I was gone for a long time, and I am back into making some games in Java   Grin

Yes, I did manage to get 400 fps.

I used the following code to accomplish this:

http://www.cokeandcode.com/info/showsrc/showsrc.php?src=../spaceinvaders/org/newdawn/spaceinvaders/SpriteStore.java

What it does to my understanding is that it stores your sprite into your graphics accelerator hardware. I don't know the rest, but with the same calculation for my FPS, I saw it increase from 50-60 fps to around 400, with a geforce 6800
Offline erikd

JGO Ninja


Medals: 15
Projects: 4
Exp: 14 years


Maximumisness


« Reply #11 - Posted 2007-05-29 15:16:04 »

Quote
I think sleep gaurantees a minimum that is accurate, but the maximum is innaccurate.  Regardless, 400fps does seem too high.

Well, if there's just a little rendering going on, 400fps doesn't seem too high to me, even with a sleep of 1ms.

Having said that, my experience is that on some versions of windows, a sleep of less than a certain number of ms seemed to do nothing (iirc the threshold was 5 but I'm not sure). This was in the early java 1.4 days, so maybe this isn't the case anymore (haven't tested this in a long time)...

Offline broumbroum

Junior Member





« Reply #12 - Posted 2007-05-29 19:35:12 »

I noticed that your SndHr is instanced statically, but when you instance the class you will have an infinite loopback on your static instance, because of this recursivity. I suppose it doesn't affect much the heap memory, but this might be noticeable with multithreading.
Plus I'd recommend you to use some kind of WeakHashMap impl or SoftReferences in your HashMap, and that is the question if you intend to load larger amount of SFX. Personnally I will use no HashMaps but WeakHashMap<Integer, SoftReference> with the int keys stored in some LIFO-HIFO (that is, last-recently-used and most-recently-used) as a soft-cache would behave.
Nevertheless this class is quite correct. Smiley
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  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
/*
 * SoundHandler.java
 *
 * Created on May 6, 2006, 1:39 AM
 *
 * To change this template, choose Tools | Options and locate the template under
 * the Source Creation and Management node. Right-click the template and choose
 * Open. You can then make changes to the template in the Source Editor.
 */


package tankpwnage;

import java.util.HashMap;

import java.io.File;
import java.io.IOException;

import javax.sound.sampled.*;

/**
 *
 * @author Cyclonis Delta
 */

public class SoundHandler implements LineListener {
   
    private static final int BUFFER = 128000;
   
    private static SoundHandler instance = new SoundHandler();
   
    private HashMap soundFiles;
       
    public static SoundHandler get() {
        return instance;
    }
   
    public void loadSoundFx() {
        soundFiles = new HashMap();
        File directory = new File("./sound/fx");
        File[] files = directory.listFiles();
        for (int i=0;i<files.length;i++) {
            if (files[i].isFile()) {
                // This is a sound effect
               String filename = files[i].getName();
                String path = "./sound/fx/"+filename;
                File theFile = new File(path);
                int dot = filename.indexOf(".wav");
               
                String ref = filename.substring(0, dot);
               
                AudioInputStream audioInputStream = null;
                Clip clip = null;
               
               
                try {
                    audioInputStream = AudioSystem.getAudioInputStream(theFile);
                    if (audioInputStream != null) {
         AudioFormat   format = audioInputStream.getFormat();
         DataLine.Info   info = new DataLine.Info(Clip.class, format);
         try
         {
            clip = (Clip) AudioSystem.getLine(info);
            //clip.addLineListener(this);
           clip.open(audioInputStream);
                                soundFiles.put(ref, clip);
         }
         catch (LineUnavailableException e)
         {
            e.printStackTrace();
         }
         catch (IOException e)
         {
            e.printStackTrace();
         }
         
                    }
                }
                catch (Exception e) {
                    e.printStackTrace();
                }
               
                               
            }
        }
    }
   
    public void update(LineEvent event)
   {
      if (event.getType().equals(LineEvent.Type.STOP))
      {
                        Clip clip = (Clip)event.getLine();
                        clip.setFramePosition(1);
      }
      else if (event.getType().equals(LineEvent.Type.CLOSE))
      {
         /*
          *   There is a bug in the jdk1.3/1.4.
          *   It prevents correct termination of the VM.
          *   So we have to exit ourselves.
          */

         System.exit(0);
      }
   }
   
    public void play(String ref) {
               
        Clip clip = (Clip) soundFiles.get(ref);
        if (clip.isRunning()) {
            clip.stop();
            clip.setFramePosition(1);
        }
        clip.addLineListener(this);
        //while (!clip.isRunning()) {
       clip.start();
        //}
       
       
    }
   
}


::::... :..... :::::: ;;;:::™ b23:production 2006 GNU/GPL @ http://b23prodtm.webhop.info
on sf.net: /projects/sf3jswing
Java (1.6u10 plz) Web Start pool
dev' VODcast[/ur
Offline Cyclonis

Senior Newbie





« Reply #13 - Posted 2007-06-01 02:09:36 »

I noticed that your SndHr is instanced statically, but when you instance the class you will have an infinite loopback on your static instance, because of this recursivity. I suppose it doesn't affect much the heap memory, but this might be noticeable with multithreading.
Plus I'd recommend you to use some kind of WeakHashMap impl or SoftReferences in your HashMap, and that is the question if you intend to load larger amount of SFX. Personnally I will use no HashMaps but WeakHashMap<Integer, SoftReference> with the int keys stored in some LIFO-HIFO (that is, last-recently-used and most-recently-used) as a soft-cache would behave.
Nevertheless this class is quite correct. Smiley

thankx for the tips. I will see if I can improve my class. I made it on base of that graphic accelerator class and converted it for sound fx  Smiley
Offline Abuse

JGO Coder


Medals: 10


falling into the abyss of reality


« Reply #14 - Posted 2007-09-28 22:25:49 »

I think sleep gaurantees a minimum that is accurate, but the maximum is innaccurate.

I thought so too, but apparently this is not the case.

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6313903

Quote
Note as per 5068368 there is no explicit requirement that a sleep last for at least the amount of time requested, so an early return is valid according to the JLS third edition.

Make Elite IV:Dangerous happen! Pledge your backing at KICKSTARTER here! https://dl.dropbox.com/u/54785909/EliteIVsmaller.png
Offline Tryllion

Senior Newbie





« Reply #15 - Posted 2007-11-14 15:14:56 »

Hi
I am new to Java and i have 1 question . Why this class have static instance  ?
Why it cant be just simple created somewhere in for example my mainGame class ?

class mainGame {
static SoundHandler sh = new Soundhandler();

//...
}

And second question : where should I keep all wav s ? In jar or rather in simple folder ?  Huh
I think loading from JAR will take long time, but then when it is loaded it doesn't matter because the class keep all wav s in RAM , right ?
Sorry for poor English  Tongue Grin
Offline cylab

JGO Knight


Medals: 34



« Reply #16 - Posted 2007-11-15 19:23:39 »

Hi
I am new to Java and i have 1 question . Why this class have static instance  ?
Why it cant be just simple created somewhere in for example my mainGame class ?

class mainGame {
static SoundHandler sh = new Soundhandler();

//...
}

Singleton Pattern: http://en.wikipedia.org/wiki/Singleton_pattern

And second question : where should I keep all wav s ? In jar or rather in simple folder ?  Huh
I think loading from JAR will take long time, but then when it is loaded it doesn't matter because the class keep all wav s in RAM , right ?

Loading from JAR or folder shouldn't make much of a difference.

Mathias - I Know What [you] Did Last Summer!
Pages: [1]
  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.

xsi3rr4x (42 views)
2014-04-15 18:08:23

BurntPizza (38 views)
2014-04-15 03:46:01

UprightPath (54 views)
2014-04-14 17:39:50

UprightPath (36 views)
2014-04-14 17:35:47

Porlus (53 views)
2014-04-14 15:48:38

tom_mai78101 (75 views)
2014-04-10 04:04:31

BurntPizza (134 views)
2014-04-08 23:06:04

tom_mai78101 (234 views)
2014-04-05 13:34:39

trollwarrior1 (195 views)
2014-04-04 12:06:45

CJLetsGame (203 views)
2014-04-01 02:16:10
List of Learning Resources
by SHC
2014-04-18 03:17:39

List of Learning Resources
by Longarmx
2014-04-08 03:14:44

Good Examples
by matheus23
2014-04-05 13:51:37

Good Examples
by Grunnt
2014-04-03 15:48:46

Good Examples
by Grunnt
2014-04-03 15:48:37

Good Examples
by matheus23
2014-04-01 18:40:51

Good Examples
by matheus23
2014-04-01 18:40:34

Anonymous/Local/Inner class gotchas
by Roquen
2014-03-11 15:22:30
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!