3

How can i read an AudioInputStream upto a particular number of bytes/microsecond position ? For example :

AudioInputStream ais = AudioSystem.getAudioInputStream( new File("file.wav") );
// let the file.wav be of y bytes

Now i want to obtain an AudioInputStream that has data upto some x bytes where x < y bytes.

How can i do that ?

I have been thinking hard but haven't got any method to do that ?

Suhail Gupta
  • 22,386
  • 64
  • 200
  • 328

2 Answers2

12

The code below shows you how to copy a part of an audio stream, reading from one file and writing to another.

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

class AudioFileProcessor {

  public static void main(String[] args) {
    copyAudio("/tmp/uke.wav", "/tmp/uke-shortened.wav", 2, 1);
  }

  public static void copyAudio(String sourceFileName, String destinationFileName, int startSecond, int secondsToCopy) {
    AudioInputStream inputStream = null;
    AudioInputStream shortenedStream = null;
    try {
      File file = new File(sourceFileName);
      AudioFileFormat fileFormat = AudioSystem.getAudioFileFormat(file);
      AudioFormat format = fileFormat.getFormat();
      inputStream = AudioSystem.getAudioInputStream(file);
      int bytesPerSecond = format.getFrameSize() * (int)format.getFrameRate();
      inputStream.skip(startSecond * bytesPerSecond);
      long framesOfAudioToCopy = secondsToCopy * (int)format.getFrameRate();
      shortenedStream = new AudioInputStream(inputStream, format, framesOfAudioToCopy);
      File destinationFile = new File(destinationFileName);
      AudioSystem.write(shortenedStream, fileFormat.getType(), destinationFile);
    } catch (Exception e) {
      println(e);
    } finally {
      if (inputStream != null) try { inputStream.close(); } catch (Exception e) { println(e); }
      if (shortenedStream != null) try { shortenedStream.close(); } catch (Exception e) { println(e); }
    }
  }

  public static void println(Object o) {
    System.out.println(o);
  }

  public static void print(Object o) {
    System.out.print(o);
  }

}
Martin Dow
  • 5,273
  • 4
  • 30
  • 43
  • why the size of byte array is taken to be `bPS/500` ? Can you explain what are you doing as you write `inputStream.skip(bytesPerSecond)` and then reading to the byte array ? Please elaborate and include it in your answer – Suhail Gupta Sep 25 '11 at 18:07
  • The JavaDocs explain what those methods do: http://download.oracle.com/javase/6/docs/api/javax/sound/sampled/AudioInputStream.html#read(byte[], int, int) "Reads up to a specified maximum number of bytes of data from the audio stream, putting them into the given byte array." http://download.oracle.com/javase/6/docs/api/javax/sound/sampled/AudioInputStream.html#skip(long) "Skips over and discards a specified number of bytes from this audio input stream." `byte[] bytes = new byte[bytesPerSecond / 500]` gives me 2 milliseconds worth of bytes, as shown in the comment a couple of lines below. – Martin Dow Sep 25 '11 at 19:34
  • @ Martin Dow Thank you for coming back to the question. But it has not solved my problem.I want to cut the audio file but not skip some portion of it.That is what the question is : Obtaining an `ais` that has data less than the original. In the above program we've not obtained any stream that has data less than that of stream. I know a particular position _it may be in bytes,frame pos.,in millisec._ and i want to obtain a stream that has data upto that pos. _i.e cut the audio file_ – Suhail Gupta Sep 27 '11 at 06:21
  • That wasn't clear from your question. I've updated my answer. You should be able to figure it out from there. – Martin Dow Sep 27 '11 at 07:19
  • @ Martin Dow it does not cut the file. Let me verify,`secondsToCopy` in the above program is the `currentPosInSec` ? – Suhail Gupta Sep 28 '11 at 14:21
  • `secondsToCopy` is how many second you want to copy. `startSecond` is the second at which you want to start copying. I can't really think of clearer variable names! If there's anything you don't understand, then the JavaDocs are detailed: http://download.oracle.com/javase/6/docs/api/. You also need to follow this tutorial: http://download.oracle.com/javase/tutorial/sound/sampled-overview.html. – Martin Dow Sep 28 '11 at 15:59
  • I was overlooking one statement in my version of program . I was multiplying microseconds with `pow(10,6)` instead of dividing to convert it into seconds. So the program never cut the sound ! – Suhail Gupta Sep 28 '11 at 16:49
  • Good. I'm glad you got it working. I would still recommend you take the time to read the tutorial and carefully read the API documentation - it will save you a lot of time and confusion. – Martin Dow Sep 28 '11 at 16:53
0

Now that you have the stream you can read one byte at a time up to the maximum number ob bytes you want using read(), or read a fixed number of bytes with read(byte[] b).

DarkByte
  • 192
  • 5