sounds WAV -> OPUS
This commit is contained in:
parent
103e4d35f5
commit
93f98f9984
11 changed files with 367 additions and 554 deletions
|
@ -4,6 +4,11 @@ import java.io.BufferedInputStream;
|
|||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ShortBuffer;
|
||||
|
||||
import org.lwjgl.BufferUtils;
|
||||
import org.lwjgl.util.opus.OpusFile;
|
||||
|
||||
import game.log.Log;
|
||||
import game.rng.Random;
|
||||
|
@ -124,10 +129,6 @@ public enum SoundEvent {
|
|||
SLIME_SMALL("slime_small1", "slime_small2", "slime_small3", "slime_small4", "slime_small5");
|
||||
|
||||
private static final Random RANDOM = new Random();
|
||||
private static final byte[] WAV_HDR = "RIFF".getBytes();
|
||||
private static final byte[] WAV_HDR_FMT = "fmt ".getBytes();
|
||||
private static final byte[] WAV_HDR_DATA = "data".getBytes();
|
||||
private static final byte[] WAV_FORMAT = "WAVE".getBytes();
|
||||
|
||||
private final String[] sounds;
|
||||
private final short[][] buffers;
|
||||
|
@ -138,130 +139,68 @@ public enum SoundEvent {
|
|||
for(int z = 0; z < entry.sounds.length; z++) {
|
||||
String sound = entry.sounds[z];
|
||||
Log.SOUND.trace("Lade Sound %s", sound);
|
||||
entry.buffers[z] = readWav("sounds/" + sound + ".wav", 48000, (short)1);
|
||||
entry.buffers[z] = readOpus("sounds/" + sound + ".opus");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static int read32(byte[] data, int off) {
|
||||
int value = 0;
|
||||
for(int h = 0; h < 4; h++) {
|
||||
value |= (int)((data[h + off]) & 0xff) << (8*h);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private static short read16(byte[] data, int off) {
|
||||
short value = 0;
|
||||
for(int h = 0; h < 2; h++) {
|
||||
value |= (short)((data[h + off]) & 0xff) << (8*h);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private static boolean memcmp(byte[] d1, int off, byte[] d2, int size) {
|
||||
for(int z = 0; z < size; z++) {
|
||||
if(d1[z + off] != d2[z])
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static int readWavHeader(byte[] data, int samplerate, short channels, short bytes) {
|
||||
if(memcmp(data, 0, WAV_HDR, 4)) {
|
||||
Log.IO.debug("base header");
|
||||
return 0;
|
||||
}
|
||||
int len = read32(data, 4);
|
||||
if(memcmp(data, 8, WAV_FORMAT, 4)) {
|
||||
Log.IO.debug("wave header");
|
||||
return 0;
|
||||
}
|
||||
if(memcmp(data, 12, WAV_HDR_FMT, 4)) {
|
||||
Log.IO.debug("fmt header");
|
||||
return 0;
|
||||
}
|
||||
if(read32(data, 16) != 16) {
|
||||
Log.IO.debug("header size");
|
||||
return 0;
|
||||
}
|
||||
if(read16(data, 20) != 1) {
|
||||
Log.IO.debug("pcm");
|
||||
return 0;
|
||||
}
|
||||
if(read16(data, 22) != channels) {
|
||||
Log.IO.debug("channels");
|
||||
return 0;
|
||||
}
|
||||
if(read32(data, 24) != samplerate) {
|
||||
Log.IO.debug("sample rate");
|
||||
return 0;
|
||||
}
|
||||
if(read32(data, 28) != (samplerate * ((int)channels) * ((int)bytes))) {
|
||||
Log.IO.debug("bitrate");
|
||||
return 0;
|
||||
}
|
||||
if(read16(data, 32) != (channels * bytes)) {
|
||||
Log.IO.debug("sample align");
|
||||
return 0;
|
||||
}
|
||||
if(read16(data, 34) != (8 * bytes)) {
|
||||
Log.IO.debug("sample size");
|
||||
return 0;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
private static short[] readWav(String filename, int samplerate, short channels) {
|
||||
private static short[] readOpus(String filename) {
|
||||
InputStream in = null;
|
||||
byte[] data;
|
||||
try {
|
||||
InputStream fd = new BufferedInputStream(FileUtils.getResource(filename));
|
||||
byte[] hdr = new byte[36];
|
||||
if(fd.read(hdr, 0, 36) != 36) {
|
||||
Log.IO.error("Fehler beim Lesen von WAV-Datei '%s': E/A-Fehler", filename);
|
||||
fd.close();
|
||||
return null;
|
||||
}
|
||||
if(readWavHeader(hdr, samplerate, channels, (short)2) == 0) {
|
||||
Log.IO.error("Fehler beim Lesen von WAV-Datei '%s': Falsches oder fehlerhaftes Format", filename);
|
||||
fd.close();
|
||||
return null;
|
||||
}
|
||||
int len = 0;
|
||||
do {
|
||||
if(len != 0 && fd.skip(len) != len) {
|
||||
Log.IO.error("Fehler beim Lesen von WAV-Datei '%s': E/A-Fehler", filename);
|
||||
fd.close();
|
||||
return null;
|
||||
}
|
||||
if(fd.read(hdr, 0, 8) != 8) {
|
||||
Log.IO.error("Fehler beim Lesen von WAV-Datei '%s': E/A-Fehler", filename);
|
||||
fd.close();
|
||||
return null;
|
||||
}
|
||||
len = read32(hdr, 4);
|
||||
}
|
||||
while(memcmp(hdr, 0, WAV_HDR_DATA, 4));
|
||||
int samples = len / ((int)channels * 2);
|
||||
byte[] buf = new byte[samples * channels * 2];
|
||||
if(fd.read(buf, 0, samples * channels * 2) != samples * channels * 2) {
|
||||
Log.IO.error("Fehler beim Lesen von WAV-Datei '%s': E/A-Fehler", filename);
|
||||
fd.close();
|
||||
return null;
|
||||
}
|
||||
fd.close();
|
||||
short[] sbuf = new short[samples * channels];
|
||||
for(int z = 0; z < samples * channels; z++) {
|
||||
sbuf[z] = read16(buf, z << 1);
|
||||
}
|
||||
return sbuf;
|
||||
in = new BufferedInputStream(FileUtils.getResource(filename));
|
||||
data = FileUtils.readBytes(in);
|
||||
}
|
||||
catch(FileNotFoundException e) {
|
||||
Log.IO.error("Fehler beim Öffnen von WAV-Datei '%s': Datei nicht gefunden", filename);
|
||||
Log.IO.error("Fehler beim Lesen von OPUS-Datei '%s': Datei nicht gefunden", filename);
|
||||
return null;
|
||||
}
|
||||
catch(IOException e) {
|
||||
Log.IO.error("Fehler beim Öffnen von WAV-Datei '%s': %s", filename, e.getMessage());
|
||||
Log.IO.error("Fehler beim Lesen von OPUS-Datei '%s': %s", filename, e.getMessage());
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
finally {
|
||||
try {
|
||||
if(in != null)
|
||||
in.close();
|
||||
}
|
||||
catch(IOException e) {
|
||||
}
|
||||
}
|
||||
ByteBuffer buf = BufferUtils.createByteBuffer(data.length);
|
||||
buf.put(data);
|
||||
buf.flip();
|
||||
long fd = OpusFile.op_open_memory(buf, null);
|
||||
if(fd == 0L) {
|
||||
Log.IO.error("Fehler beim Lesen von OPUS-Datei '%s': Falsches oder fehlerhaftes Format", filename);
|
||||
return null;
|
||||
}
|
||||
if(OpusFile.op_channel_count(fd, -1) != 1) {
|
||||
Log.IO.error("Fehler beim Lesen von OPUS-Datei '%s': Falsches Anzahl von Kanälen (!= 1)", filename);
|
||||
OpusFile.op_free(fd);
|
||||
return null;
|
||||
}
|
||||
long samples = OpusFile.op_pcm_total(fd, -1);
|
||||
if(samples < 0L) {
|
||||
Log.IO.error("Fehler beim Lesen von OPUS-Datei '%s': E/A-Fehler", filename);
|
||||
OpusFile.op_free(fd);
|
||||
return null;
|
||||
}
|
||||
ShortBuffer pcm = BufferUtils.createShortBuffer((int)samples);
|
||||
int state;
|
||||
while((state = OpusFile.op_read(fd, pcm, null)) > 0L) {
|
||||
pcm.position(pcm.position() + state);
|
||||
}
|
||||
if(state < 0L) {
|
||||
Log.IO.error("Fehler beim Lesen von OPUS-Datei '%s': E/A-Fehler", filename);
|
||||
OpusFile.op_free(fd);
|
||||
return null;
|
||||
}
|
||||
OpusFile.op_free(fd);
|
||||
short[] decoded = new short[(int)samples];
|
||||
pcm.rewind();
|
||||
pcm.get(decoded);
|
||||
return decoded;
|
||||
}
|
||||
|
||||
private SoundEvent(String ... sounds) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue