/* * JSwiff is an open source Java API for Macromedia Flash file generation * and manipulation * * Copyright (C) 2004-2005 Ralf Terdic (contact@jswiff.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package com.jswiff.swfrecords.tags; import com.jswiff.io.InputBitStream; import com.jswiff.io.OutputBitStream; import java.io.IOException; /** * <p> * This tag defines an event sound. * </p> * * <p> * Warning: you are responsible for obtaining technology licenses needed for * encoding and decoding sound data (see e.g. <a * href="http://mp3licensing.com">mp3licensing.com</a> for details on mp3 * licensing). * </p> * * @since SWF 1 */ public final class DefineSound extends DefinitionTag { /** * Uncompressed sound format. For 16-bit samples, native byte ordering * (little-endian or big-endian) is used. Warning: this introduces * platform dependency! */ public static final byte FORMAT_UNCOMPRESSED = 0; /** * ADPCM compressed sound format (simple compression algorithm without * licensing issues). */ public static final byte FORMAT_ADPCM = 1; /** * mp3 compressed sound format (for high-quality sound encoding) (since SWF * 4). */ public static final byte FORMAT_MP3 = 2; /** * Uncompressed little-endian sound format, i.e. 16-bit samples are decoded * using little-endian byte ordering (platform-independent format) (since * SWF 4). */ public static final byte FORMAT_UNCOMPRESSED_LITTLE_ENDIAN = 3; /** * Nellymoser Asao compressed sound format (optimized for low-bitrate mono * speech transmission) (since SWF 6). */ public static final byte FORMAT_NELLYMOSER = 6; /** 5.5 kHz sampling rate */ public static final byte RATE_5500_HZ = 0; /** 11 kHz sampling rate */ public static final byte RATE_11000_HZ = 1; /** 22 kHz sampling rate */ public static final byte RATE_22000_HZ = 2; /** 44 kHz sampling rate */ public static final byte RATE_44000_HZ = 3; private byte format; private byte rate; private boolean is16BitSample; private boolean isStereo; private long sampleCount; private byte[] soundData; /** * Creates a new DefineSound instance. Supply the character ID of the * sound, the encoding format (one of the provided <code>FORMAT_...</code> * constants), the sampling rate (use <code>RATE_...</code> constants), * specify whether 8-bit or 16-bit samples are used (8-bit samples are * allowed only for uncompressed formats) and whether the sound is mono or * stereo (Nellymoser merely supports mono). Provide the number of samples * (for stereo sound: sample pairs) and, finally, the actual sound data as * raw data. * * @param characterId character ID of sound * @param format encoding format (use provided constants) * @param rate sampling rate (use provided constants) * @param is16BitSample if <code>true</code>, 16-bit samples are used * (otherwise 8-bit, for uncompressed formats only) * @param isStereo if <code>true</code>, sound is stereo, otherwise mono * @param sampleCount number of samples (stereo: sample pairs) * @param soundData raw sound data */ public DefineSound( int characterId, byte format, byte rate, boolean is16BitSample, boolean isStereo, long sampleCount, byte[] soundData) { code = TagConstants.DEFINE_SOUND; this.characterId = characterId; this.format = format; this.rate = rate; this.is16BitSample = is16BitSample; this.isStereo = isStereo; this.sampleCount = sampleCount; this.soundData = soundData; } DefineSound() { // empty } /** * Sets the encoding format of the sound (one of the * <code>FORMAT_...</code> constants). * * @param format sound encoding format */ public void setFormat(byte format) { this.format = format; } /** * Returns the encoding format of the sound (one of the * <code>FORMAT_...</code> constants). * * @return sound encoding format */ public byte getFormat() { return format; } /** * Returns the sampling rate of the sound (one of the <code>RATE_...</code> * constants). * * @return sampling rate */ public byte getRate() { return rate; } /** * Sets the sound's number of samples (for stereo sound: sample pairs). * * @param sampleCount sample count */ public void setSampleCount(long sampleCount) { this.sampleCount = sampleCount; } /** * Returns the sound's number of samples (for stereo sound: sample pairs). * * @return sample count */ public long getSampleCount() { return sampleCount; } /** * Sets the sound data. * * @param soundData raw sound data (as byte array) */ public void setSoundData(byte[] soundData) { this.soundData = soundData; } /** * Returns the sound data. * * @return raw sound data (as byte array) */ public byte[] getSoundData() { return soundData; } /** * Specifies whether the sound is stereo or not. * * @param isStereo <code>true</code> if stereo, otherwise * <code>false</code> */ public void setStereo(boolean isStereo) { this.isStereo = isStereo; } /** * Checks whether the sound is stereo or not. * * @return <code>true</code> if stereo, otherwise <code>false</code> */ public boolean isStereo() { return isStereo; } /** * Checks whether the sample size is 16 bit or 8 bit. * * @return <code>true</code> if 16-bit sample size, <code>false</code> if * 8-bit */ public boolean is16BitSample() { return is16BitSample; } /** * Specifies whether the sample size is 16 bit or 8 bit. * * @param is16BitSample <code>true</code> if 16-bit sample size, * <code>false</code> if 8-bit */ public void set16BitSample(boolean is16BitSample) { this.is16BitSample = is16BitSample; } protected void writeData(OutputBitStream outStream) throws IOException { outStream.writeUI16(characterId); outStream.writeUnsignedBits(format, 4); outStream.writeUnsignedBits(rate, 2); outStream.writeBooleanBit(is16BitSample); outStream.writeBooleanBit(isStereo); outStream.writeUI32(sampleCount); outStream.writeBytes(soundData); } void setData(byte[] data) throws IOException { InputBitStream inStream = new InputBitStream(data); characterId = inStream.readUI16(); format = (byte) inStream.readUnsignedBits(4); rate = (byte) inStream.readUnsignedBits(2); is16BitSample = inStream.readBooleanBit(); isStereo = inStream.readBooleanBit(); sampleCount = inStream.readUI32(); // that's 7 bytes soundData = new byte[data.length - 7]; System.arraycopy(data, 7, soundData, 0, data.length - 7); } }