// 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.util.DynamicArray;
/**
* Decodes ACM encoded audio data in WAVC format into uncompressed PCM WAV audio data.
*/
public class WavcBuffer extends AcmBuffer
{
public WavcBuffer(ResourceEntry entry) throws Exception
{
super(entry);
}
public WavcBuffer(ResourceEntry entry, AudioOverride override) throws Exception
{
super(entry, override);
}
public WavcBuffer(byte[] buffer, int offset) throws Exception
{
super(buffer, offset);
}
public WavcBuffer(byte[] buffer, int offset, AudioOverride override) throws Exception
{
super(buffer, offset, override);
}
//--------------------- Begin Class AudioBuffer ---------------------
@Override
protected void convert(byte[] buffer, int offset, AudioOverride override) throws Exception
{
// parsing WAVC buffer
if (!new String(buffer, 0, 4).equals("WAVC"))
throw new Exception("Invalid WAVC header");
if (!new String(buffer, 4, 4).equals("V1.0"))
throw new Exception("Unsupported WAVC version");
// int dsize = DynamicArray.getInt(buffer, 8);
int csize = DynamicArray.getInt(buffer, 12);
int acmOfs = DynamicArray.getInt(buffer, 16);
if (acmOfs < 0x1c || acmOfs + csize > buffer.length - offset)
throw new Exception("Invalid WAVC header data");
int numChannels = DynamicArray.getUnsignedShort(buffer, offset + 20);
if (numChannels < 1 || numChannels > 2)
throw new Exception("Unsupported number of audio channels: " + numChannels);
int bitsPerSample = DynamicArray.getUnsignedShort(buffer, offset + 22);
if (bitsPerSample < 8 || bitsPerSample > 32)
throw new Exception("Unsupported bits/sample: " + bitsPerSample);
int sampleRate = DynamicArray.getUnsignedShort(buffer, offset + 24);
if (sampleRate < 4096 || sampleRate > 192000)
throw new Exception("Unsupported sample rate: " + sampleRate);
if (override != null) {
if (override.numChannels < 0)
override.numChannels = numChannels;
if (override.sampleRate < 0)
override.sampleRate = sampleRate;
if (override.bitsPerSample < 0)
override.bitsPerSample = bitsPerSample;
}
// let AcmBuffer handle the remaining data
super.convert(buffer, offset + acmOfs, override);
}
//--------------------- Begin Class AudioBuffer ---------------------
}