* Got rid of ADPCM stuff that didn't even work
* Fixed bug in WAVLoader causing it to fail if the file had extra bytes at the end git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7201 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
a724165a33
commit
6c776e7bb3
@ -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(){
|
||||
|
@ -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 && 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) * channels != bytesPerSample)
|
||||
throw new IOException("Invalid bytes per sample value");
|
||||
|
||||
if (bytesPerSample * sampleRate != bytesPerSec)
|
||||
throw new IOException("Invalid bytes per second value");
|
||||
if (bytesPerSample * sampleRate != bytesPerSec)
|
||||
throw new IOException("Invalid bytes per second value");
|
||||
|
||||
audioData.setupFormat(channels, bitsPerSample, sampleRate);
|
||||
audioData.setupFormat(channels, bitsPerSample, sampleRate);
|
||||
|
||||
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, 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;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user