// Near Infinity - An Infinity Engine Browser and Editor
// Copyright (C) 2001 - 2005 Jon Olav Hauglid
// See LICENSE.txt for license information
package org.infinity.resource.sound;
import org.infinity.resource.key.ResourceEntry;
import org.infinity.resource.sound.AudioBuffer.AudioOverride;
import org.infinity.util.DynamicArray;
import org.infinity.util.io.StreamUtils;
public class AudioFactory
{
// supported audio formats
private static enum AudioFormat {
FMT_UNKNOWN, FMT_WAV, FMT_ACM, FMT_WAVC, FMT_OGG
}
/**
* Attempts to detect the resource format of the specified resource and returns a
* matching AudioBuffer object.
* @param entry The audio resource to decode.
* @return An AudioBuffer object, or null if resource format could not be determined.
*/
public static AudioBuffer getAudioBuffer(ResourceEntry entry)
{
return getAudioBuffer(entry, null);
}
/**
* Attempts to detect the resource format of the specified resource and returns a
* matching AudioBuffer object.
* @param entry The audio resource to decode.
* @param override An optional AudioOverride object containing audio properties to override.
* @return An AudioBuffer object, or null if resource format could not be determined.
*/
public static AudioBuffer getAudioBuffer(ResourceEntry entry, AudioOverride override)
{
if (entry != null) {
try {
return getAudioBuffer(StreamUtils.toArray(entry.getResourceBuffer()), 0, override);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
return null;
}
/**
* Attempts to detect the resource format of the specified data and returns a
* matching AudioBuffer object.
* @param buffer A buffer containing unprocessed audio data.
* @param offset Start offset of the audio data.
* @return An AudioBuffer object, or null on error or if audio format could not be determined.
*/
public static AudioBuffer getAudioBuffer(byte[] buffer, int offset)
{
return getAudioBuffer(buffer, offset, null);
}
/**
* Attempts to detect the resource format of the specified data and returns a
* matching AudioBuffer object.
* @param buffer A buffer containing unprocessed audio data.
* @param offset Start offset of the audio data.
* @param override An optional AudioOverride object containing audio properties to override.
* @return An AudioBuffer object, or null on error or if audio format could not be determined.
*/
public static AudioBuffer getAudioBuffer(byte[] buffer, int offset, AudioOverride override)
{
try {
switch (detectFormat(buffer, offset)) {
case FMT_WAV:
return new WavBuffer(buffer, offset, override);
case FMT_ACM:
return new AcmBuffer(buffer, offset, override);
case FMT_WAVC:
return new WavcBuffer(buffer, offset, override);
case FMT_OGG:
return new OggBuffer(buffer, offset, override);
default:
return null;
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* Convenience method: Returns a buffer containing decoded audio data including WAV header.
* @param entry The audio resource to decode.
* @return A buffer containing decoded audio data including WAV header or null on error.
*/
public static byte[] convertAudio(ResourceEntry entry)
{
return convertAudio(entry, null);
}
/**
* Convenience method: Returns a buffer containing decoded audio data including WAV header.
* @param entry The audio resource to decode.
* @param override An optional AudioOverride object containing audio properties to override.
* @return A buffer containing decoded audio data including WAV header or null on error.
*/
public static byte[] convertAudio(ResourceEntry entry, AudioOverride override)
{
if (entry != null) {
try {
return convertAudio(StreamUtils.toArray(entry.getResourceBuffer()), 0, override);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
return null;
}
/**
* Convenience method: Returns a buffer containing decoded audio data including WAV header.
* @param buffer A buffer containing unprocessed audio data.
* @param offset Start offset of the audio data.
* @return A buffer containing decoded audio data including WAV header or null on error.
*/
public static byte[] convertAudio(byte[] buffer, int offset)
{
return convertAudio(buffer, offset, null);
}
/**
* Convenience method: Returns a buffer containing decoded audio data including WAV header.
* @param buffer A buffer containing unprocessed audio data.
* @param offset Start offset of the audio data.
* @param override An optional AudioOverride object containing audio properties to override.
* @return A buffer containing decoded audio data including WAV header or null on error.
*/
public static byte[] convertAudio(byte[] buffer, int offset, AudioOverride override)
{
try {
AudioBuffer ab = getAudioBuffer(buffer, offset, override);
if (ab != null)
return ab.getAudioData();
} catch (Exception e) {
e.printStackTrace();
return null;
}
return null;
}
// Detects supported audio formats
private static AudioFormat detectFormat(byte[] buffer, int offset)
{
AudioFormat af = AudioFormat.FMT_UNKNOWN;
try {
if (buffer != null && offset >= 0 && offset + 4 < buffer.length) {
String s = new String(buffer, offset, 4);
if (s.equals("RIFF")) {
if (offset + 44 < buffer.length && new String(buffer, offset + 8, 4).equals("WAVE")) {
af = AudioFormat.FMT_WAV;
}
} else if (s.equals("WAVC")) {
if (offset + 32 < buffer.length && new String(buffer, offset + 4, 4).equals("V1.0")) {
af = AudioFormat.FMT_WAVC;
}
} else if (s.equals("OggS")) {
af = AudioFormat.FMT_OGG;
} else if (DynamicArray.getInt(buffer, offset) == 0x01032897) {
af = AudioFormat.FMT_ACM;
}
}
} catch (Throwable t) {
}
return af;
}
}