summaryrefslogtreecommitdiffstats
path: root/src/java/com/jogamp/openal/util/WAVLoader.java
diff options
context:
space:
mode:
authorXerxes Rånby <[email protected]>2013-07-09 13:07:18 +0200
committerXerxes Rånby <[email protected]>2013-07-09 13:07:18 +0200
commit4b16dc0b788c496eac594212eababcc4913b6d2a (patch)
treee49dadecbe091e063c429447e1298508a520fefe /src/java/com/jogamp/openal/util/WAVLoader.java
parent14186120ed0c26a053ca90969ac45d55dda53468 (diff)
parent6292ed9712b17f849f22221aea9d586c3a363c09 (diff)
Merge remote-tracking branch 'gouessej/master'
Diffstat (limited to 'src/java/com/jogamp/openal/util/WAVLoader.java')
-rw-r--r--src/java/com/jogamp/openal/util/WAVLoader.java122
1 files changed, 94 insertions, 28 deletions
diff --git a/src/java/com/jogamp/openal/util/WAVLoader.java b/src/java/com/jogamp/openal/util/WAVLoader.java
index f997eb4..22b4194 100644
--- a/src/java/com/jogamp/openal/util/WAVLoader.java
+++ b/src/java/com/jogamp/openal/util/WAVLoader.java
@@ -34,16 +34,14 @@
package com.jogamp.openal.util;
+import java.io.DataInputStream;
import java.io.File;
+import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteOrder;
-import javax.sound.sampled.AudioFormat;
-import javax.sound.sampled.AudioInputStream;
-import javax.sound.sampled.AudioSystem;
-
-import com.jogamp.openal.UnsupportedAudioFileException;
+import com.jogamp.openal.ALException;
/**
* A Loader utility for (.wav) files. Creates a WAVData object containing the
@@ -66,15 +64,10 @@ public class WAVLoader {
* @throws IOException If the file can no be found or some other IO error
* occurs
*/
- public static WAVData loadFromFile(String filename)
- throws UnsupportedAudioFileException, IOException {
+ public static WAVData loadFromFile(String filename) throws IOException {
File soundFile = new File(filename);
- try {
- AudioInputStream aIn = AudioSystem.getAudioInputStream(soundFile);
- return loadFromStreamImpl(aIn);
- } catch (javax.sound.sampled.UnsupportedAudioFileException e) {
- throw new UnsupportedAudioFileException(e);
- }
+ InputStream is = new FileInputStream(soundFile);
+ return loadFromStreamImpl(is);
}
/**
@@ -89,24 +82,97 @@ public class WAVLoader {
* @throws IOException If the file can no be found or some other IO error
* occurs
*/
- public static WAVData loadFromStream(InputStream stream)
- throws UnsupportedAudioFileException, IOException {
- AudioInputStream aIn;
- try {
- aIn = AudioSystem.getAudioInputStream(stream);
- return loadFromStreamImpl(aIn);
- } catch (javax.sound.sampled.UnsupportedAudioFileException e) {
- throw new UnsupportedAudioFileException(e);
- }
+ public static WAVData loadFromStream(InputStream stream) throws IOException {
+ return loadFromStreamImpl(stream);
}
+
+ private static long readUnsignedIntLittleEndian(DataInputStream is) throws IOException {
+ byte[] buf = new byte[4];
+ is.readFully(buf);
+ return (buf[0] & 0xFF | ((buf[1] & 0xFF) << 8) | ((buf[2] & 0xFF) << 16) | ((buf[3] & 0xFF) << 24));
+ }
+
+ private static short readUnsignedShortLittleEndian(DataInputStream is) throws IOException {
+ byte[] buf = new byte[2];
+ is.readFully(buf);
+ return (short) (buf[0] & 0xFF | ((buf[1] & 0xFF) << 8));
+ }
+
+ private static WAVData loadFromStreamImpl(InputStream aIn) throws IOException {
+ /**
+ * references:
+ * http://www.sonicspot.com/guide/wavefiles.html
+ * https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
+ * http://stackoverflow.com/questions/1111539/is-the-endianness-of-format-params-guaranteed-in-riff-wav-files
+ * http://sharkysoft.com/archive/lava/docs/javadocs/lava/riff/wave/doc-files/riffwave-content.htm
+ */
+ final DataInputStream din;
+ if (aIn instanceof DataInputStream) {
+ din = (DataInputStream) aIn;
+ } else {
+ din = new DataInputStream(aIn);
+ }
+ try {
+ if (din.readInt() != 0x52494646) {// "RIFF", little endian
+ //FIXME "RIFX", big endian, read the data in big endian in this case
+ throw new ALException("Invalid WAV header");
+ }
+ // length of the RIFF, unused
+ readUnsignedIntLittleEndian(din);
+ if (din.readInt() != 0x57415645) {// "WAVE"
+ throw new ALException("Invalid WAV header");
+ }
+ boolean foundFmt = false;
+ boolean foundData = false;
+
+ short sChannels = 0, sSampleSizeInBits = 0;
+ long sampleRate = 0;
+ long chunkLength = 0;
+ while (!foundData) {
+ int chunkId = din.readInt();
+ chunkLength = readUnsignedIntLittleEndian(din);
+ switch (chunkId) {
+ case 0x666D7420: // "fmt "
+ foundFmt = true;
+ // compression code, unused
+ readUnsignedShortLittleEndian(din);
+ sChannels = readUnsignedShortLittleEndian(din);
+ sampleRate = readUnsignedIntLittleEndian(din);
+ // bytes per second, unused
+ readUnsignedIntLittleEndian(din);
+ // block alignment, unused
+ readUnsignedShortLittleEndian(din);
+ sSampleSizeInBits = readUnsignedShortLittleEndian(din);
+ din.skip(chunkLength - 16);
+ break;
+ case 0x66616374: // "fact"
+ // FIXME: compression format dependent data?
+ din.skip(chunkLength);
+ break;
+ case 0x64617461: // "data"
+ if (!foundFmt)
+ throw new ALException(
+ "WAV fmt chunks must be before data chunks");
+ foundData = true;
+ break;
+ default:
+ // unrecognized chunk, skips it
+ din.skip(chunkLength);
+ }
+ }
- private static WAVData loadFromStreamImpl(AudioInputStream aIn)
- throws UnsupportedAudioFileException, IOException {
- final AudioFormat fmt = aIn.getFormat();
- return WAVData.loadFromStream(aIn, -1, fmt.getChannels(), fmt.getSampleSizeInBits(),
- Math.round(fmt.getSampleRate()),
- fmt.isBigEndian() ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN, false);
+ final int channels = (int) sChannels;
+ final int sampleSizeInBits = sSampleSizeInBits;
+ final float fSampleRate = (float) sampleRate;
+ //FIXME big endian not supported yet
+ final boolean isBigEndian = false;
+ return WAVData.loadFromStream(aIn, -1, channels, sampleSizeInBits,
+ Math.round(fSampleRate), isBigEndian ? ByteOrder.BIG_ENDIAN
+ : ByteOrder.LITTLE_ENDIAN, false);
+ } finally {
+ din.close();
+ }
}
}