Android Open Source - SoundBox Wave File






From Project

Back to project page SoundBox.

License

The source code is released under:

GNU General Public License

If you think the Android project SoundBox listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

// Copyright (c) 2011 Szymon Jakubczak. All rights reserved.
// Use of this source code is governed by a license that can be found in
// the LICENSE file.
package net.szym.soundbox;
/*from   www .  ja v  a 2s .  c  o  m*/
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;

/**
 * Utility to read little-endian integers from an InputStream. (DataInputStream
 * can only do big-endian.)
 */
class LittleEndianInputStream {
  private DataInputStream dis;
  private byte[] buf = new byte[8];

  LittleEndianInputStream(InputStream is) {
    dis = new DataInputStream(is);
  }

  void readFully(byte[] dst) throws IOException {
    dis.readFully(dst);
  }

  void readFully(byte[] dst, int offset, int byteCount) throws IOException {
    dis.readFully(dst, offset, byteCount);
  }

  int readByte() throws IOException {
    // these 0xff are necessary to convert from signed to unsigned (stupid Java
    // quirk)
    return dis.readByte() & 0xff;
  }

  int readShort() throws IOException {
    dis.readFully(buf, 0, 2);
    return (short) ((buf[0] & 0xff) | ((buf[1] & 0xff) << 8));
  }

  int readInt() throws IOException {
    dis.readFully(buf, 0, 4);
    return (buf[0] & 0xff) | ((buf[1] & 0xff) << 8) |
        ((buf[2] & 0xff) << 16) | ((buf[3] & 0xff) << 24);
  }
}

/**
 * Parser for WAVE file in PCM format.
 */
public class WaveFile {
  // magic chunk ids
  static final byte[] ID_RIFF = "RIFF".getBytes();
  static final byte[] ID_WAVE = "WAVE".getBytes();
  static final byte[] ID_FMT = "fmt ".getBytes();
  static final byte[] ID_DATA = "data".getBytes();

  /**
   * Parser for one chunk of the WAVE format.
   */
  class Chunk {
    byte[] id = new byte[4];
    int size;
    byte[] data;

    void read(InputStream is) throws IOException {
      LittleEndianInputStream lis = new LittleEndianInputStream(is);
      lis.readFully(id);
      size = lis.readInt();
      data = new byte[size];
      lis.readFully(data);
    }

    InputStream blob() {
      return new ByteArrayInputStream(data);
    }
  }

  public final int numChannels;
  public final int sampleRate;
  public final int bitsPerSample;
  public final byte[] data;

  public WaveFile(InputStream is) throws IOException {
    Chunk riff = new Chunk();
    riff.read(is);
    check(Arrays.equals(ID_RIFF, riff.id), "Bad header");
    is = riff.blob();
    byte[] format = new byte[4];
    int nr = is.read(format);
    check(nr == 4, "Missing format");
    check(Arrays.equals(ID_WAVE, format), "Bad format");
    Chunk fmt = new Chunk();
    fmt.read(is);
    check(Arrays.equals(ID_FMT, fmt.id), "Missing fmt");
    Chunk datachunk = new Chunk();
    datachunk.read(is);
    check(Arrays.equals(ID_DATA, datachunk.id), "Missing data");

    LittleEndianInputStream lis = new LittleEndianInputStream(fmt.blob());
    int audioFormat = lis.readShort();
    check(audioFormat == 1, "Only PCM files supported");
    numChannels = lis.readShort();
    sampleRate = lis.readInt();
    int byteRate = lis.readInt();
    int blockAlign = lis.readShort();
    bitsPerSample = lis.readShort();
    check(byteRate == sampleRate * numChannels * bitsPerSample / 8,
        "Byte rate mismatch");
    check(blockAlign == numChannels * bitsPerSample / 8, "Block align mismatch");

    data = datachunk.data;
  }

  private static void check(boolean val, String msg) throws IOException {
    if (!val) {
      throw new IOException(msg);
    }
  }

  /**
   * @return file length in samples
   */
  public int getLength() {
    return data.length * 8 / (numChannels * bitsPerSample);
  }

  /**
   * @return approx. file length in milliseconds
   */
  public int getTimeLength() {
    return (getLength() * 1000) / sampleRate;
  }
}




Java Source Code List

net.szym.soundbox.SoundBoxActivity.java
net.szym.soundbox.SoundBox.java
net.szym.soundbox.WaveFile.java