/** * Copyright 2012 Jason Sorensen (sorensenj@smert.net) * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. */ package net.smert.frameworkgl.openal.codecs.wav; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.ByteBuffer; import java.nio.ByteOrder; import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.UnsupportedAudioFileException; import net.smert.frameworkgl.Files; import net.smert.frameworkgl.Fw; import net.smert.frameworkgl.openal.codecs.Codec; import net.smert.frameworkgl.openal.codecs.Conversion; import org.lwjgl.openal.AL10; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * * @author Jason Sorensen <sorensenj@smert.net> */ public class WAVCodec implements Codec { private final static Logger log = LoggerFactory.getLogger(WAVCodec.class); private Data create(AudioInputStream ais) throws IOException { // Get the audio format AudioFormat audioFormat = ais.getFormat(); // Determine format based on the number of channels and sample size int channels = audioFormat.getChannels(); int format = 0; int sampleSizeInBits = audioFormat.getSampleSizeInBits(); if (channels == 1) { if (sampleSizeInBits == 8) { format = AL10.AL_FORMAT_MONO8; } else if (sampleSizeInBits == 16) { format = AL10.AL_FORMAT_MONO16; } else { throw new RuntimeException("Sample size in bits must be 8 or 16: " + sampleSizeInBits); } } else if (audioFormat.getChannels() == 2) { if (sampleSizeInBits == 8) { format = AL10.AL_FORMAT_STEREO8; } else if (sampleSizeInBits == 16) { format = AL10.AL_FORMAT_STEREO16; } else { throw new RuntimeException("Sample size in bits must be 8 or 16: " + sampleSizeInBits); } } else { throw new RuntimeException("Channels must be 1 or 2: " + channels); } // Read data int available = ais.available(); assert (available > 0); byte[] byteArray = new byte[available]; int read; int total = 0; while (((read = ais.read(byteArray, total, byteArray.length - total)) != -1) && (total < byteArray.length)) { total += read; } // Convert data ByteBuffer buffer = Conversion.ConvertEndianness(byteArray, sampleSizeInBits / 8, ByteOrder.nativeOrder(), audioFormat.isBigEndian() ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN); // Create codec data Data data = new Data(); data.buffer = buffer; data.channels = channels; data.format = format; data.sampleRate = (int) audioFormat.getSampleRate(); return data; } @Override public Data load(String audioFile) throws IOException { log.info("Loading WAV audio file: {}", audioFile); Files.FileAsset fileAsset = Fw.files.getAudio(audioFile); // Open file stream and read data try (InputStream is = fileAsset.openStream(); BufferedInputStream bis = new BufferedInputStream(is); AudioInputStream ais = AudioSystem.getAudioInputStream(bis)) { return create(ais); } catch (UnsupportedAudioFileException ex) { throw new IOException(ex); } } }