/*
Реализация спецификаций CLDC версии 1.1 (JSR-139), MIDP версии 2.1 (JSR-118)
и других спецификаций для функционирования компактных приложений на языке
Java (мидлетов) в среде программного обеспечения Малик Эмулятор.
Copyright © 2016–2017, 2019–2023, 2025 Малик Разработчик
Это свободная программа: вы можете перераспространять ее и/или изменять
ее на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
в каком она была опубликована Фондом свободного программного обеспечения;
либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.
Эта программа распространяется в надежде, что она будет полезной,
но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
общественной лицензии GNU.
Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
вместе с этой программой. Если это не так, см.
<https://www.gnu.org/licenses/>.
*/
package malik.emulator.fileformats.sound.sampled.wave;
import java.io.*;
import malik.emulator.fileformats.*;
import malik.emulator.fileformats.sound.sampled.*;
public final class WaveEncoder extends Object implements SampledSoundEncoder
{
public static final long SIGNATURE = 0x52494646L; /* RIFF */
private static final int WAVE = 0x57415645; /* WAVE */
private static final int FMT = 0x666d7420; /* fmt */
private static final int DATA = 0x64617461; /* data */
private int channels;
private int frequency;
private short[] samples;
public WaveEncoder() {
}
public void saveToOutputStream(OutputStream stream) throws IOException {
saveToDataStream(new ExtendedDataOutputStream(stream));
}
public void saveToDataStream(ExtendedDataOutputStream stream) throws IOException {
int len;
int soundChannels = channels;
int soundFrequency = frequency;
byte[] soundData;
short[] soundSamples = samples;
if(soundSamples == null)
{
throw new EmptyAdapterException("WaveEncoder.saveToOutputStream: кодер не содержит данные.");
}
soundData = new byte[(len = soundSamples.length) << 1];
for(int pos = 0, i = 0; i < len; i++)
{
int sample = soundSamples[i];
soundData[pos++] = (byte) sample;
soundData[pos++] = (byte) (sample >> 8);
}
stream.writeInt((int) SIGNATURE);
stream.writeIntLE((len <<= 1) + 0x24);
stream.writeInt(WAVE);
stream.writeInt(FMT);
stream.writeIntLE(0x10);
stream.writeShortLE(1);
stream.writeShortLE(soundChannels);
stream.writeIntLE(soundFrequency);
stream.writeIntLE((soundFrequency * soundChannels) << 1);
stream.writeShortLE(soundChannels << 1);
stream.writeShortLE(16);
stream.writeInt(DATA);
stream.writeIntLE(len);
stream.write(soundData);
}
public void clear() {
channels = 0;
frequency = 0;
samples = null;
}
public void setSamples(int channels, int samplesPerSecond, short[] samples) throws InvalidDataFormatException, UnsupportedDataException {
int len;
if(samples == null)
{
throw new NullPointerException("WaveEncoder.setSamples: аргумент samples равен нулевой ссылке.");
}
if(channels < 1 || channels > 2 || samplesPerSecond <= 0 || samplesPerSecond > 0xffff)
{
throw new UnsupportedDataException("WaveEncoder.setSamples: неподдерживаемые данные.");
}
if((len = samples.length) % channels != 0)
{
throw new InvalidDataFormatException("WaveEncoder.setSamples: неправильный формат данных.");
}
Array.copy(samples, 0, samples = new short[len], 0, len);
this.channels = channels;
this.frequency = samplesPerSecond;
this.samples = samples;
}
public boolean isEmpty() {
return (channels | frequency) == 0 && samples == null;
}
}