Java-Gaming.org    
Featured games (79)
games approved by the League of Dukes
Games in Showcase (476)
Games in Android Showcase (106)
games submitted by our members
Games in WIP (533)
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  
  Playing the same sound many times  (Read 3896 times)
0 Members and 1 Guest are viewing this topic.
Offline Max Pesce

Junior Member




Nil tam arduum quod non ingenio vincas


« Posted 2003-07-26 06:54:05 »

My problem is that I don't know how to play play the same clip many times simultaneously...

If an event in the game happens two times I must play the same clip two times.

This is the code I use now:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
if(!soundOn) return true;
           
            Clip snd=getSound(name);
           
            if(snd==null){
                  Debug.err("! SoundBank.playSound() Sound '"+name+"' not present!");
                  return false;
            }
           
            if(snd.isRunning()){
                  snd.stop();
            }
            snd.setMicrosecondPosition(0);
            snd.start();


Infact I should not stop the sound, but run another
"instance"...

Any idea?

Offline aikarele

Senior Newbie





« Reply #1 - Posted 2003-07-26 08:40:33 »

I would suggest that you load your clip to a byte array and then use AudioSystem.getLine to get a new line for each clip. Here is a short example how to play audio.wav 32 times simultaneously (i.e. 32 polyphony):

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
import javax.sound.sampled.*;
import java.io.*;

public class MultiClip {
   public static void main(String[] args) {
      try {
         AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(new File("audio.wav"));
         AudioFormat af                    = audioInputStream.getFormat();
         int size                          = (int) (af.getFrameSize() * audioInputStream.getFrameLength());
         byte[] audio                      = new byte[size];
         DataLine.Info info                = new DataLine.Info(Clip.class, af, size);
         audioInputStream.read(audio, 0, size);

         for(int i=0; i < 32; i++) {
            Clip clip = (Clip) AudioSystem.getLine(info);
            clip.open(af, audio, 0, size);
            clip.start();
         }
      }
      catch(Exception e) {
         e.printStackTrace();
      }
   }
}
Archimedes
Guest
« Reply #2 - Posted 2003-07-26 09:46:47 »

This works fine.
However when do I clip.stop() any of the 32 samples?
(Because so they run forver, even silently...)
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Max Pesce

Junior Member




Nil tam arduum quod non ingenio vincas


« Reply #3 - Posted 2003-07-26 10:50:29 »

Good solution.
Thanks.

To Archimedes:
The sounds stops when it finish, so there's no problem
if you don't stop them...

The only problem is with the GarbageCollector: every
time you play a sound you create a new object that
remains in "suspension" until the GC comes...

Archimedes
Guest
« Reply #4 - Posted 2003-07-26 12:40:13 »

Quote
Good solution.
To Archimedes:
The sounds stops when it finish, so there's no problem
if you don't stop them...

The only problem is with the GarbageCollector: every
time you play a sound you create a new object that
remains in "suspension" until the GC comes...

Ah I see. Thanks for the info.
The thing with the GC is a kind of problem I think when you play various wav samples repeated times in your game. Very soon your Java application takes more and more memory... and then... it stops when the GC comes? :-)
"Funny."
;-)
Offline Max Pesce

Junior Member




Nil tam arduum quod non ingenio vincas


« Reply #5 - Posted 2003-07-26 13:47:05 »

Bad news...

This is the class that I use to encapsulate a WAV.
The only propetary function is "Debug(String,int)", it
simply prints out a string 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  
class Sample{
     
      /* Number of unstopped sounds */
      static int numberOfActiveClips=0;
     
      /* Number of clips requested */
      static int numberOfRequestedClips=0;
     
      /* Binary data */
      byte[]      wav;
      /* Size of binary data */
      int            size;
     
      DataLine.Info      info;
      AudioFormat            af;
     
      Vector                  clipList=new Vector();
     
      /* Constructor */
      public Sample(AudioInputStream audioInputStream){
            af          = audioInputStream.getFormat();
          size      = (int) (af.getFrameSize() * audioInputStream.getFrameLength());
          wav            = new byte[size];
          info      = new DataLine.Info(Clip.class, af, size);
         
            try{
                audioInputStream.read(wav, 0, size);
             } catch(Exception e){ e.printStackTrace(); }
      }
     
      /* Retrivies a Clip from the stored binary data */
      public Clip getClip(){
            Clip clip,c;
           
            /* Stop and remove finished clips */
            Iterator iter=clipList.iterator();            
            while(iter.hasNext()){
                  c=(Clip)iter.next();
                  if(!c.isRunning()){
                        c.stop();
                        c.flush();
                        iter.remove();
                        numberOfActiveClips--;
                  }
            }
           
            try{
                  clip = (Clip) AudioSystem.getLine(info);
                    clip.open(af, wav, 0, size);
              } catch(Exception e){ e.printStackTrace(); return null; }
             
              /* Add this clip to the list of unstopped clips */
              clipList.add(clip);
              numberOfActiveClips++;
             
              numberOfRequestedClips++;
             
              return clip;
      }
     
      public static void debug(){
            Debug.print("-- Number of active clips: "+numberOfActiveClips,0);
            Debug.print("-- Number of requested clips: "+numberOfRequestedClips,0);
      }
}


To resolve the problem that clips may live forever, I check
every time a clip is required, what old clips aren't running
and I stop them.

If I use ONLY one or two Sample, I can request as many
clips as I want and all goes right.

If I use 5/6 Samples after some requests (exactly 64 sample!) Java VM gives me the
following error:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
javax.sound.sampled.LineUnavailableException: No Free Voices
        at com.sun.media.sound.MixerClip.nSetup(Native Method)
        at com.sun.media.sound.MixerClip.getValidVoiceId(MixerClip.java:608)
        at com.sun.media.sound.MixerClip.implOpen(MixerClip.java:590)
        at com.sun.media.sound.MixerClip.open(MixerClip.java:159)
        at fishbros.pyro.Sample.getClip(SoundBank.java:77)
        at fishbros.pyro.SoundBank.getSound(SoundBank.java:201)
        at fishbros.pyro.SoundBank.playSound(SoundBank.java:249)
        at fishbros._teranoid.Ball.controlCollision(Ball.java:421)
        at fishbros._teranoid.Ball.live(Ball.java:489)
        at fishbros.pyro.EntityRoster.makeEmLive(EntityRoster.java:157)
        at fishbros._teranoid.Game.nextFrame(Game.java:290)
        at fishbros.pyro.App.run(App.java:299)
        at java.lang.Thread.run(Thread.java:536)


It seems like there are no more Line avaible!
What can I do more than simply stop() clips to release lines?Huh

And why if I use only two samples all is OK?

PS: When the GC collectors comes it only slow down
your App for few milleseconds.


Offline Max Pesce

Junior Member




Nil tam arduum quod non ingenio vincas


« Reply #6 - Posted 2003-07-26 14:11:36 »


I've discovered that the problem was not related with
the number of samples...

The game that generates a "No voices" error is using
sample PAN (to position audio left or right)

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
      public void setPan(String name,float pan) {
            Clip clip=getSound(name);
           
            if(clip==null) return;            
            try {
                  FloatControl panControl =
                        (FloatControl) clip.getControl(FloatControl.Type.PAN);
                  panControl.setValue(pan);
            } catch (Exception ex) {
                  ex.printStackTrace();
            }
      }


It seems there's no way to release a Clip after you have
set a PAN value on it...

In the other cases the Class is PERFECT!

Offline aikarele

Senior Newbie





« Reply #7 - Posted 2003-07-26 20:14:03 »

1  
javax.sound.sampled.LineUnavailableException: No Free Voices 


simply means you don't have any more free lines left. Seems that your soundcard supports 64 polyphony (mine only supports 32!). I think your problem is that you never close the lines (sorry about my bad example). Stop method does not release the line, it simply stops the playback. As the Java documentation says:
Quote
"public void stop() Stops the line. A stopped line should cease I/O activity. If the line is open and running, however, it should retain the resources required to resume activity. A stopped line should retain any audio data in its buffer instead of discarding it, so that upon resumption the I/O can continue where it left off, if possible.


So... instead of stop() method, try close()
Offline swpalmer

JGO Coder




Where's the Kaboom?


« Reply #8 - Posted 2003-07-27 03:47:55 »

It might make sense to create a sound server class that picks a line that isn't active and writes the wave data to it... but basically keeps all the lines around to be reused by they next sound it gets.  You would set a fixed limit for the number of simultaneous sounds, if you the class is asked to play a sound and all the lines are busy that sound would just get skipped.

Offline aikarele

Senior Newbie





« Reply #9 - Posted 2003-07-27 10:44:18 »

1  
DataLine.Info info = new DataLine.Info(Clip.class, af, size);


One potential problem with re-using the DataLines is the code above. DataLine.Info requires that you state the used audio format and buffer size, so if you want to re-use the same line, you have to make sure it supports ALL the needed formats and the buffer size is big enough. Once again, the Java documentation will come to rescue. You can create a DataLine.Info with multiple audio formats:
1  
DataLine.Info(Class lineClass, AudioFormat[] formats, int minBufferSize, int maxBufferSize) 

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

Junior Member




Nil tam arduum quod non ingenio vincas


« Reply #10 - Posted 2003-07-27 14:11:29 »


I perfectly understand what you say...

But simply using stop() instead of close() never
generate a "all lines busy" situation.
Infact the new version of my code breaks the 64
poliphony limit, this means that in an unknown way
lines are really released.

I'll try using close()...

Offline Max Pesce

Junior Member




Nil tam arduum quod non ingenio vincas


« Reply #11 - Posted 2003-07-27 14:26:48 »


Using close() instead of stop() fixes the problem with
panned sounds but...

close() is slower than stop() and so using it to
release lines creates choppy sounds...

I think I'll continue to use stop() and eliminate panned
sounds Smiley


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.

pw (18 views)
2014-07-24 01:59:36

Riven (17 views)
2014-07-23 21:16:32

Riven (14 views)
2014-07-23 21:07:15

Riven (17 views)
2014-07-23 20:56:16

ctomni231 (45 views)
2014-07-18 06:55:21

Zero Volt (40 views)
2014-07-17 23:47:54

danieldean (32 views)
2014-07-17 23:41:23

MustardPeter (36 views)
2014-07-16 23:30:00

Cero (51 views)
2014-07-16 00:42:17

Riven (50 views)
2014-07-14 18:02:53
HotSpot Options
by dleskov
2014-07-08 03:59:08

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:58:24

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:47:22

How do I start Java Game Development?
by ra4king
2014-05-17 11:13:37

HotSpot Options
by Roquen
2014-05-15 09:59:54

HotSpot Options
by Roquen
2014-05-06 15:03:10

Escape Analysis
by Roquen
2014-04-29 22:16:43

Experimental Toys
by Roquen
2014-04-28 13:24:22
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!