3

I've recieved a byte array from the server and I know that connects and sends perfectly. It's when I try and play the sound from the byte array.

Here's what I have to play the sound.

SourceDataLine speaker = null;
try {
    DataLine.Info speakerInfo = new DataLine.Info(SourceDataLine.class, getAudioFormat(samplerate));
    speaker = (SourceDataLine) AudioSystem.getLine(speakerInfo);
} catch (LineUnavailableException e) {
    e.printStackTrace();
}
int nBytesRead = 0;
    while (nBytesRead != -1) {
    if (nBytesRead >= 0) {
         speaker.write(bytes, 0, nBytesRead);
    }
}

getAudioFormat:

private AudioFormat getAudioFormat(float sample) {
    int sampleSizeBits = 16;
    int channels = 1;
    boolean signed = true;
    boolean bigEndian = false;
    return new AudioFormat(sample, sampleSizeBits, channels, signed, bigEndian);
}

How can I play music from a byte[]?

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
KeirDavis
  • 665
  • 2
  • 10
  • 32

3 Answers3

2

I don't see where you are reading from your sound byte array in your while loop. They way you are set up, there should probably be something along these lines:

while (nBytesRead = soundDataArray.read(bytes) != 1)

...assuming you have the read method set up so that the buffer called 'bytes' receives the data from the read command. Then the write() method will have 'bytes' repeatedly populated to send.

Of course, 'bytes' is just a buffer only used in the while loop, NOT the byte array with the source sound.

Sometimes the read method has two inputs, as in: .read(bufferArray, bytesToRead); where values in the range of a k or several k are common. (bufferArray.length == bytesToRead)

Phil Freihofner
  • 7,645
  • 1
  • 20
  • 41
  • What class would 'soundDataArray' be? Plus, if it is meant to be 'AudioInputStream', I can't because it's received bytes from a server (as stated in the first line) – KeirDavis Feb 19 '13 at 22:20
  • Hmmm. Maybe my answer was not so clear. The main point is that you need to progressively grab chunks of your input array and give them to the write() method, yes? So, perhaps you write a method for reading the bytes (usually done with the help of a cursor or index to keep track of progress between calls to the read() method). Maybe the whole thing is a wrapper for your bytes. That way, the index could be an instance variable outside of the read() method. In this scenario, SoundDataArray would be the new Object definition (wrapping the byte file you received). – Phil Freihofner Feb 20 '13 at 02:02
  • Right... So the soundDataArray is a cast Object? So (Object) bytes.read(bytes, 0, bytes.length);? – KeirDavis Feb 20 '13 at 08:47
  • I am terrible with terminology, I apologize. The last sentence should read "In this scenario, SoundDataArray would be the new class definition". No 'Object' involved, no casting needed. You might also take a look at TargetDataLine for an example of progressive reads. If you could create a TDL to handle your incoming (from the server) sound, you could use it in your while loop. – Phil Freihofner Feb 20 '13 at 13:23
0

Some time ago I wrote a small server to stream music over http: Stream music in loop over http using java

Go over there, and the way it plays, you just go to the specified link, i.e : www.localhost:8080/test in my case and the browser streams the music.

Maybe you could find the solution in combining some of my results with the yours' ones.

Actually, whatever link returns the bytearray, would be streamed by browser depending on the datatype, etc.

Community
  • 1
  • 1
user
  • 3,058
  • 23
  • 45
0

This way you can play sound from Byte[].

hope it helps others.

import javax.sound.sampled.*;
import java.io.*;

public class PlaySoundFromByteArr {

  public static void main(String[] args) throws IOException, UnsupportedAudioFileException {
    String FILE_PATH = "resources/wav-1.wav";

    byte[] byteArr = getByte(FILE_PATH);
    AudioFormat format = getFormat(FILE_PATH);
    playAudioUsingByteArray(byteArr, format);
  }

  private static byte[] getByte(String FILE_PATH) {
    byte[] byteArr = new byte[0];

    try {
      ByteArrayOutputStream out = new ByteArrayOutputStream();
      AudioInputStream in =  AudioSystem.getAudioInputStream(new File(FILE_PATH));

      int numOfBytes;
      byte[] buffer = new byte[1024];

      while( (numOfBytes = in.read(buffer)) > 0 ){
        out.write(buffer, 0,numOfBytes);
      }
      out.flush();
      byteArr = out.toByteArray();
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    } catch (UnsupportedAudioFileException e) {
      e.printStackTrace();
    }

    return byteArr;
  }

  private static AudioFormat getFormat(String FILE_PATH) throws IOException, UnsupportedAudioFileException {
    AudioInputStream in =  AudioSystem.getAudioInputStream(new File(FILE_PATH));
    return in.getFormat();
  }

  private static void playAudioUsingByteArray(byte[] byteArr, AudioFormat format) {
    try (Clip clip = AudioSystem.getClip()) {
      clip.open(format, byteArr, 0, byteArr.length);
      clip.start();
      clip.drain();
      Thread.sleep(clip.getMicrosecondLength());
    }
    catch (LineUnavailableException | InterruptedException e) {
      e.printStackTrace();
    }
  }

}
Jin Lim
  • 1,759
  • 20
  • 24