diff game/SoundElement.java @ 22:afde253ec705

More work.
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 31 Jan 2011 21:28:59 +0200
parents
children 0741dc117808
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/game/SoundElement.java	Mon Jan 31 21:28:59 2011 +0200
@@ -0,0 +1,189 @@
+/*
+ * Ristipolku Game Engine
+ * (C) Copyright 2011 Matti 'ccr' Hämäläinen <ccr@tnsp.org>
+ */
+package game;
+
+import java.util.*;
+import java.io.*;
+import game.*;
+import javax.sound.sampled.*;
+
+
+class SoundElement implements Runnable
+{
+    private final String name;
+
+    private AudioInputStream stream;
+    private AudioFormat format;
+    private SourceDataLine line;
+    private Thread playThread;
+    private int loopCount;
+    private boolean playing, streaming;
+    private int volume = 100;
+
+    byte[] buffer;
+    int length;
+    
+    
+    SoundElement(String filename, boolean streaming) throws IOException
+    {
+        this.name = filename;
+        this.streaming = streaming;
+
+        ResourceLoader res = new ResourceLoader(name);
+        if (res == null || res.getStream() == null)
+        {
+            throw new IOException("Could not load audio resource '"+name+"'.\n");
+        }
+
+
+        try {
+            stream = AudioSystem.getAudioInputStream(res.getStream());
+            format = stream.getFormat();
+        }
+        catch (UnsupportedAudioFileException e) {
+            throw new IOException("Unsupported audio file format for '"+name+"'.\n");
+        }
+        catch (IOException e)
+        {
+            throw new IOException("Could not load audio resource '"+name+"'.\n");
+        }
+
+
+        if (streaming) {
+            System.out.print("Loading '"+name+"' as a clip\n");
+            try {
+                clip = AudioSystem.getClip();
+                clip.open(stream);
+            }
+            catch (LineUnavailableException e)
+            {
+                throw new IOException("Line unavailable for '"+name+"'.\n");
+            }
+            finally {
+                stream.close();
+            }
+        }
+        else
+        {
+            clip = null;
+            System.out.print("Loading '"+name+"' as stream\n");
+            
+            try {
+                SourceDataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
+                System.out.print("info: "+stream.getFrameLength() + ", " + format.getFrameSize() + "\n");
+                line = (SourceDataLine) AudioSystem.getLine(info);
+                line.open(format);
+            }
+            catch (LineUnavailableException e) {
+                throw new IOException("Line unavailable for '"+name+"'.\n");
+            }
+        }
+    }
+
+    public void play()
+    {
+        System.out.print("Sound("+name+").play()\n");
+        if (streaming)
+        {
+            clip.setFramePosition(0);
+            clip.start();
+        }
+        else
+        {
+            if (playThread == null)
+            {
+                doPlay = true;
+                loopCount = 1;
+                playThread = new Thread(this);
+                playThread.start();
+            }
+        }
+    }
+    
+    public void loop(int n)
+    {
+        System.out.print("Sound("+name+").loop("+n+")\n");
+        if (isClip())
+        {
+            clip.setFramePosition(0);
+            if (n < 0)
+                clip.loop(Clip.LOOP_CONTINUOUSLY);
+            else
+                clip.loop(n);
+        }
+        else
+        {
+            if (playThread == null)
+            {
+                doPlay = true;
+                loopCount = n;
+                playThread = new Thread(this);
+                playThread.start();
+            }
+        }
+    }
+    
+    public void stop()
+    {
+        if (isClip())
+        {
+            if (clip.isRunning())
+                clip.stop();
+        }
+        else
+        {
+            if (playThread != null)
+            {
+                playThread.interrupt();
+                doPlay = false;
+                playThread = null;
+            }
+        }
+    }
+    
+    public boolean isPlaying()
+    {
+        if (isClip())
+            return clip.isRunning();
+        else
+            return (playThread != null && line.isRunning());
+    }
+
+    public void run()
+    {
+        line.start();
+        byte[] buf = new byte[line.getBufferSize()];
+
+        while (doPlay && (loopCount > 0 || loopCount == -1))
+        {
+            try {
+                int numRead = 0;
+                while ((numRead = stream.read(buf, 0, buf.length)) >= 0 && doPlay)
+                {
+                    int offset = 0;
+                    while (offset < numRead)
+                    {
+                        System.out.print("audioThread: offs="+offset+", numread="+numRead+"\n");
+                        offset += line.write(buf, offset, numRead - offset);
+                    }
+                }
+                line.drain();
+
+                System.out.print("audioThread: stream.reset()\n");
+                stream.reset();
+            }
+            catch (IOException e) {
+            }
+
+            if (loopCount > 0)
+                loopCount--;
+        }
+        
+        line.stop();
+        doPlay = false;
+    }
+}
+
+