diff --git a/engine/src/core/com/jme3/audio/AudioBuffer.java b/engine/src/core/com/jme3/audio/AudioBuffer.java index ed5dbefcd..697108583 100644 --- a/engine/src/core/com/jme3/audio/AudioBuffer.java +++ b/engine/src/core/com/jme3/audio/AudioBuffer.java @@ -58,7 +58,7 @@ public class AudioBuffer extends AudioData { } /** - * @return The duratiion of the audio in seconds. It is expected + * @return The duration of the audio in seconds. It is expected * that audio is uncompressed. */ public float getDuration(){ diff --git a/engine/src/core/com/jme3/audio/plugins/WAVLoader.java b/engine/src/core/com/jme3/audio/plugins/WAVLoader.java index 3e7a5d8d8..ca237863d 100644 --- a/engine/src/core/com/jme3/audio/plugins/WAVLoader.java +++ b/engine/src/core/com/jme3/audio/plugins/WAVLoader.java @@ -40,9 +40,7 @@ import com.jme3.asset.AssetLoader; import com.jme3.audio.AudioKey; import com.jme3.util.BufferUtils; import com.jme3.util.LittleEndien; -import java.io.DataInput; import java.io.IOException; -import java.io.InputStream; import java.nio.ByteBuffer; import java.util.logging.Level; import java.util.logging.Logger; @@ -57,52 +55,24 @@ public class WAVLoader implements AssetLoader { private static final int i_fmt = 0x20746D66 ; private static final int i_data = 0x61746164; - private static final int[] index_table = - { - -1, -1, -1, -1, 2, 4, 6, 8, - -1, -1, -1, -1, 2, 4, 6, 8 - }; - private static final int[] step_table = - { - 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, - 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, - 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, - 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, - 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, - 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, - 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, - 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, - 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 - }; - private boolean readStream = false; private AudioBuffer audioBuffer; private AudioStream audioStream; private AudioData audioData; private int bytesPerSec; - private int dataLength; private float duration; private LittleEndien in; - private boolean adpcm = false; - private int predictor; - private int step_index; - private int step; - private void readFormatChunk(int size) throws IOException{ // if other compressions are supported, size doesn't have to be 16 // if (size != 16) // logger.warning("Expected size of format chunk to be 16"); int compression = in.readShort(); - if (compression == 1){ - - }else if (compression == 17){ - adpcm = true; - }else{ - throw new IOException("WAV Loader only supports PCM or ADPCM wave files"); + if (compression != 1){ + throw new IOException("WAV Loader only supports PCM wave files"); } int channels = in.readShort(); @@ -118,74 +88,41 @@ public class WAVLoader implements AssetLoader { logger.log(Level.WARNING, "Expected {0} bytes per second, got {1}", new Object[]{expectedBytesPerSec, bytesPerSec}); } - duration = dataLength / bytesPerSec; - if (!adpcm){ - if (bitsPerSample != 8 && bitsPerSample != 16) - throw new IOException("Only 8 and 16 bits per sample are supported!"); - - if ( (bitsPerSample / 8) * channels != bytesPerSample) - throw new IOException("Invalid bytes per sample value"); + if (bitsPerSample != 8 && bitsPerSample != 16) + throw new IOException("Only 8 and 16 bits per sample are supported!"); - if (bytesPerSample * sampleRate != bytesPerSec) - throw new IOException("Invalid bytes per second value"); + if ( (bitsPerSample / 8) * channels != bytesPerSample) + throw new IOException("Invalid bytes per sample value"); - audioData.setupFormat(channels, bitsPerSample, sampleRate); + if (bytesPerSample * sampleRate != bytesPerSec) + throw new IOException("Invalid bytes per second value"); - int remaining = size - 16; - if (remaining > 0) - in.skipBytes(remaining); - }else{ - if (bitsPerSample != 4) - throw new IOException("IMA ADPCM header currupt"); - - predictor = in.readShort(); - step_index = in.readByte(); // ???? - int what = in.readByte(); // skip reserved byte - step = index_table[what]; + audioData.setupFormat(channels, bitsPerSample, sampleRate); - audioData.setupFormat(channels, 16, sampleRate); + int remaining = size - 16; + if (remaining > 0){ + in.skipBytes(remaining); } + } - private int decodeNibble(int nibble){ - step = step_table[step_index]; - step_index += index_table[nibble]; - - if (step_index < 0) - step_index = 0; - else if (step_index > 88) - step_index = 88; - - boolean sign = (nibble & 8) != 0; - int delta = nibble & 7; - - int diff = (2 * delta + 1) * step; - if (sign) predictor -= diff; - else predictor += diff; - - predictor &= 0xFFFF; - - return predictor; - } - -// private ByteBuffer decodeAdpcm(int len){ -// dataLength = len * 4; // 4 bits per sample to 16 bits per sample -// } - - private void readDataChunkForBuffer(int len) throws IOException{ - dataLength = len; - ByteBuffer data = BufferUtils.createByteBuffer(dataLength); + private void readDataChunkForBuffer(int len) throws IOException { + ByteBuffer data = BufferUtils.createByteBuffer(len); byte[] buf = new byte[512]; int read = 0; while ( (read = in.read(buf)) > 0){ - data.put(buf, 0, read); + data.put(buf, 0, Math.min(read, data.remaining()) ); } data.flip(); audioBuffer.updateData(data); in.close(); } + private void readDataChunkForStream(int len) throws IOException { + audioStream.updateData(in, duration); + } + public Object load(AssetInfo info) throws IOException { this.in = new LittleEndien(info.openStream()); @@ -208,26 +145,30 @@ public class WAVLoader implements AssetLoader { audioData = audioBuffer; } - while (true){ + while (true) { int type = in.readInt(); int len = in.readInt(); - switch (type){ + switch (type) { case i_fmt: readFormatChunk(len); break; case i_data: - if (readStream){ - audioStream.updateData(in, duration); - }else{ + // Compute duration based on data chunk size + duration = len / bytesPerSec; + + if (readStream) { + readDataChunkForStream(len); + } else { readDataChunkForBuffer(len); } return audioData; default: int skipped = in.skipBytes(len); - if (skipped <= 0) + if (skipped <= 0) { return null; - + } + break; } }