Hallo.
Ich versuche im Moment WAVE Dateien in Java zu dekodieren, welche im Format: 17 (DIALOGIC OKI ADPCM) komprimiert sind einzulesen, da das Java-Sound nicht von sich aus kann. Ich habe nun einen eigenen Decoder geschrieben... Leider klappt der nicht. Das wird wohl daran liegen, dass das anderes ADPCM ist als ich dachte.
Im Internet konnte ich nichts dazu finden, außer fertige Codecs für zum Beispiel. Windows Media-Player...
Gibt es vielleicht eine fertige Java-Library (nicht native), welche das Format unterstützt? Oder hat jemand eine Beschreibung zu diesem Format?
Mein nicht funktionierender Decoder sieht so aus:
Danke!
Ich versuche im Moment WAVE Dateien in Java zu dekodieren, welche im Format: 17 (DIALOGIC OKI ADPCM) komprimiert sind einzulesen, da das Java-Sound nicht von sich aus kann. Ich habe nun einen eigenen Decoder geschrieben... Leider klappt der nicht. Das wird wohl daran liegen, dass das anderes ADPCM ist als ich dachte.
Im Internet konnte ich nichts dazu finden, außer fertige Codecs für zum Beispiel. Windows Media-Player...
Gibt es vielleicht eine fertige Java-Library (nicht native), welche das Format unterstützt? Oder hat jemand eine Beschreibung zu diesem Format?
Mein nicht funktionierender Decoder sieht so aus:
Java:
public class ADPCMInputStream extends FilterInputStream {
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 static final int index_table[] = {
-1, -1, -1, -1, 2, 4, 6, 8,
-1, -1, -1, -1, 2, 4, 6, 8
};
private byte buf = 0;
private int buf_off = 0;
public ADPCMInputStream(InputStream in) {
super(in);
}
private int getBit() throws IOException {
if (buf_off >= 8) {
int r = super.read();
if (r == -1) {
throw new EOFException();
}
buf = (byte) r;
buf_off = 0;
}
boolean b = (buf & 1 << buf_off) != 0;
buf_off++;
return b ? 1 : 0;
}
private int clip(int i, int min, int max) {
if (i < min) {
return min;
}
if (i > max) {
return max;
}
return i;
}
private int bits = 1 << 3; // 4 bits per sample
private int j = bits - 1;
private int k = bits >> 1;
private int index = 0;
private int predicted = 0;
@Override
public int read() {
throw new UnsupportedOperationException("Can't read a single byte from this stream!");
}
@Override
public int read(byte[] buf) throws IOException {
return read(buf, 0, buf.length);
}
@Override
public int read(byte[] buf, int off, int len) throws IOException {
int avail = in.available();
if (avail <= 1) {
return -1;
}
int cnt = Math.min(avail * 2, len);
cnt -= cnt % 2;
for (int i = off; i < off + cnt;) {
int nib = 0;
for (int b = 0; b < 4; b++) {
nib |= (getBit() << b);
}
int to = step_table[index];
int i1 = 0;
for (int i2 = k; i2 > 0; i2 >>= 1) {
if ((nib & i2) != 0) {
i1 += to;
}
to >>= 1;
}
i1 += to;
predicted += ((nib & bits) != 0 ? -i1 : i1);
short sample = (short) clip(predicted, Short.MIN_VALUE, Short.MAX_VALUE);
buf[i++] = (byte) (sample & 0xFF);
buf[i++] = (byte) ((sample >> 8) & 0xFF);
index += index_table[(nib & j)];
index = clip(index, 0, 88);
}
return cnt;
}
}
Danke!