# Zeitangabe zu Audio-Bytestrom



## Dopser (16. Jan 2011)

Hallo zusammen,

derzeit bin ich dabei ein Spiel zu programmieren, welches mir aus einer .wav Datei eine Welle zeichnet, auf dem ein kleiner Surfer dann surfen kann.

Hierfür habe ich die Klasse, welches mir eine .wav Datei schon mal abspielt:

```
import java.io.File; 
import java.io.IOException; 
import javax.sound.sampled.AudioFormat; 
import javax.sound.sampled.AudioInputStream; 
import javax.sound.sampled.AudioSystem; 
import javax.sound.sampled.DataLine; 
import javax.sound.sampled.FloatControl; 
import javax.sound.sampled.LineUnavailableException; 
import javax.sound.sampled.SourceDataLine; 
import javax.sound.sampled.UnsupportedAudioFileException; 
 
public class AePlayWave extends Thread { 
 
    private String filename;
 
    private Position curPosition;
 
    private final int EXTERNAL_BUFFER_SIZE = 524288; // 128Kb 
 
    enum Position { 
        LEFT, RIGHT, NORMAL
    };
 
    public AePlayWave(String wavfile) { 
        filename = wavfile;
        curPosition = Position.NORMAL;
    } 
 
    public AePlayWave(String wavfile, Position p) { 
        filename = wavfile;
        curPosition = p;
    } 
 
    public void run() { 
 
        File soundFile = new File(filename);
        if (!soundFile.exists()) { 
            System.err.println("Wave file not found: " + filename);
            return;
        } 
 
        AudioInputStream audioInputStream = null;
        try { 
            audioInputStream = AudioSystem.getAudioInputStream(soundFile);
        } catch (UnsupportedAudioFileException e1) { 
            e1.printStackTrace();
            return;
        } catch (IOException e1) { 
            e1.printStackTrace();
            return;
        } 
 
        AudioFormat format = audioInputStream.getFormat();
        SourceDataLine auline = null;
        DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
 
        try { 
            auline = (SourceDataLine) AudioSystem.getLine(info);
            auline.open(format);
        } catch (LineUnavailableException e) { 
            e.printStackTrace();
            return;
        } catch (Exception e) { 
            e.printStackTrace();
            return;
        } 
 
        if (auline.isControlSupported(FloatControl.Type.PAN)) { 
            FloatControl pan = (FloatControl) auline
                    .getControl(FloatControl.Type.PAN);
            if (curPosition == Position.RIGHT) 
                pan.setValue(1.0f);
            else if (curPosition == Position.LEFT) 
                pan.setValue(-1.0f);
        } 
 
        auline.start();
        int nBytesRead = 0;
        byte[] abData = new byte[EXTERNAL_BUFFER_SIZE];
 
        try { 
            while (nBytesRead != -1) { 
                nBytesRead = audioInputStream.read(abData, 0, abData.length);
                if (nBytesRead >= 0) 
                    auline.write(abData, 0, nBytesRead);
            } 
        } catch (IOException e) { 
            e.printStackTrace();
            return;
        } finally { 
            auline.drain();
            auline.close();
        } 
 
    } 
}
```
Zu meiner Frage:
Der Bytecode bzw. das Lied wird ja in den Zeilen 

```
try { 
            while (nBytesRead != -1) { 
                nBytesRead = audioInputStream.read(abData, 0, abData.length);
                if (nBytesRead >= 0) 
                    auline.write(abData, 0, nBytesRead);
            }
```

abgespielt. 
Ist es möglich genau herauszufinden, welches Byte zu welcher Zeit(sek oder ms) gerade meine Boxen verlässt?
Oder anders gefragt: Wie weiß ich, wann welches Byte in die DataSourceLine geschrieben wird?
Danke im Voraus !


----------



## SlaterB (16. Jan 2011)

schreiben tust du ja selber, da kannst du den Zeitpunkt abfragen,
aber diese Objekt wird sicherlich die Daten buffern, deswegen ist nicht ganz klar, ob die aktuellen Bytes oder nicht eher paar tausend davor gerade gespielt werden,

ich kenne mich dazu gar nicht aus, habe in der API aber


> long 	getLongFramePosition()
> Obtains the current position in the audio data, in sample frames.
> long 	getMicrosecondPosition()
> Obtains the current position in the audio data, in microseconds.


gesehen, diese Methoden schon ausprobiert?
wann und wo du das aufrufst ist ne andere Frage

denkbar ist zunächst die  while (nBytesRead != -1)-Schleife, oder ein separater Thread, oder nach der Schleife noch,
wenn wie gesagt der Buffer groß ist, dann läuft das Lied vielleicht noch paar Sekunden/ Minuten, nachdem die letzten Bytes von deiner Schleife übergeben wurden,
vielleicht blockiert auch Zeile 91 solange, bis die Daten abgespielt sind


----------



## Dopser (19. Jan 2011)

Super!
getMicrosecondPosition() war genau das, was ich gebraucht hab um weiterzuprogrammieren
Vielen Dank!
Gruß
Dopser


----------

