⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fssoundconstructor.java

📁 利用opensource的开源jar实现生成flash文件
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 *  FSSoundConstructor.java
 *  Transform Utilities
 *
 * Copyright (c) 2001-2006 Flagstone Software Ltd. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, 
 * are permitted provided that the following conditions are met:
 *
 *  * Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright notice, 
 *    this list of conditions and the following disclaimer in the documentation 
 *    and/or other materials provided with the distribution.
 *  * Neither the name of Flagstone Software Ltd. nor the names of its contributors 
 *    may be used to endorse or promote products derived from this software 
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
 * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package com.flagstone.transform.util;

import java.io.*;
import java.util.zip.*;
import com.flagstone.transform.*;

/** 
 * The FSSoundConstructor class is used to generate the objects used to define and 
 * control the sounds that are played in a Flash movie. The FSSoundConstructor can 
 * be used to generate definitions for:
 *
 * <ul>
 * <li>Event sounds that are played in response to a particular event such as a button 
 * being clicked.</li>
 * <li>Streaming sound that is played as movie is being displayed.</li>
 * </ul>
 *
 * The FSSoundConstructor contains constructors and methods that allow sound data to 
 * be loaded from an external file simplifying the process of adding sound to a movie. 
 * The FSSoundConstructor currently supports uncompressed PCM format (with either 
 * big-endian or little-endian byte ordering) and MP3 format files.
 *
 * Once loaded, the PCM sound data should be compressed to ADPCM format as the relatively 
 * large sizes make PCM coded sounds generally unsuitable for inclusion in a Flash movie. 
 * ADPCM is a compressed format and Flash supports a modified ADPCM algorithm with 
 * compressed samples taking 2, 3, 4 or 5 bits. This results in much smaller file sizes 
 * when a movie is encoded. Code, developed at Centre for Mathematics and Computer Science,
 * Amsterdam, The Netherlands, is available on Flagstone's web site to perform the 
 * ADPCM compression.
 * 
 * For sounds containing more than one channel, the sound levels for each channel are 
 * interleaved for each sample. For example a stereo sound the order of the samples and 
 * channels levels are:
 *
 *<pre>
 * Sample       0          1          2
 *          +---+---+  +---+---+  +---+---+
 *          | 1 | 2 |  | 1 | 2 |  | 1 | 2 | ....
 *          +---+---+  +---+---+  +---+---+
 *</pre>
 *
 * NOTE: The byte order for the PCM data in WAVE sound files may vary according to the 
 * platform on which the sound file was created. The FSSoundConstructor currently only
 * supports WAVE files with little-endian byte order.
 *
 * <b>Examples</b>
 *
 * The following code samples illustrate how to use the FSSoundConstructor class to add 
 * sounds to a Flash file.
 *
 * 1. Playing an uncompressed WAVE file.\n
 *
 *<pre>
 * int soundId = movie.newIdentifier();
 *
 * // Generate an FSDefineSound object using the attributes defined in the wave file.
 * // An FSSound object is used to instruct the Flash Player to start playing a sound.
 *
 * FSSoundConstructor soundGenerator = new FSSoundGenerator("sound.wav");
 *
 * movie.add(soundGenerator.defineSound(soundId));
 * movie.add(new FSSound(soundId, FSSound.Start));
 *</pre>
 *
 * 2. Streaming Sounds.\n
 *
 * Larger sound files may be streamed to the Flash Player - splitting the sound data into a 
 * sequence of blocks which is synchronised with the frames as they are displayed. Typically 
 * block of sound data is generated for each frame displayed.
 *
 *<pre>
 * int framesPerSecond = 12;
 *
 * FSSoundConstructor soundGenerator = new FSSoundGenerator("soundTrack.wav");
 *   
 * // Calculate the number of decoded sound samples played for each frame
 *
 * int samplesPerBlock = soundGenerator.getSampleRate() / framesPerSecond;
 * int numberOfBlocks = soundGenerator.getSamplesPerChannel() / samplesPerBlock;
 *
 * // An FSSoundStreamHeader2 object defines the attributes of the streaming sound.
 * 
 * movie.add(soundGenerator.streamHeader(samplesPerBlock));
 *
 * // Add a streaming block for each frame so the sound is played as each frame is displayed.
 *
 * for (int i=0; i&lt;numberOfBlocks; i++)
 * {
 *     movie.add(soundGenerator.streamBlock(i, samplesPerBlock));
 *     movie.add(new FSShowFrame());
 * }
 * </pre>
 *
 */
public class FSSoundConstructor
{
    private static final int[] riffSignature = { 82, 73, 70, 70 };
    private static final int[] wavSignature = { 87, 65, 86, 69 };

    private static final int FMT = 0x20746d66;
    private static final int DATA = 0x61746164;

    private static final int MPEG1 = 3;
    
    private static final int frameSizeMP3[] = { 576, 576, 576, 1152 };
    private static final int channelCount[] = { 2, 2, 2, 1 };

    private static final int bitRates[][] =
    {
        { -1,  8, 16, 24, 32, 40, 48, 56,  64,  80,  96, 112, 128, 144, 160, -1 }, // MPEG 2.5
        { -1, -1, -1, -1, -1, -1, -1, -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, -1 }, // Reserved
        { -1,  8, 16, 24, 32, 40, 48, 56,  64,  80,  96, 112, 128, 144, 160, -1 }, // MPEG 2.0
        { -1, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, -1 }, // MPEG 1.0
    };

    private static final int samplingRates[][] =
    {
        { 11025, -1, -1, -1 },
        {    -1, -1, -1, -1 },
        { 22050, -1, -1, -1 },
        { 44100, -1, -1, -1 }
    };
    
    private int format = FSSound.PCM;
    private int numberOfChannels = 0;
    private int samplesPerChannel = 0;
    private int sampleRate = 0;
    private int sampleSize = 0;

    private byte[] sound = null;
    
    private int[][] frameTable = null;
    private int samplesPerFrame = 0;

    /**
     * Creates a new uninitialized FSSoundConstructor object.  Use setSound to 
     * provide the content.
     */
    public FSSoundConstructor() 
    {
    }
    /** 
     * Creates a new FSSoundConstructor object initialised with the contents of 
     * the specified sound file.
     *
     * @param fileName the name of the file containing the sound.
     * 
     * @throws FileNotFoundException - if the file does not exist, is a 
     * directory rather than a regular file, or for some other reason cannot be 
     * opened for reading.
     * 
     * @throws IOException - if an I/O error occurs while reading the file.
     * 
     * @throws DataFormatException if the file contains a sound format not 
     * supported by the FSSoundConstructor.
     */
    public FSSoundConstructor(String fileName) throws IOException, DataFormatException
    {
        setSound(fileName);
    }
    /** 
     * Accessor method returning the format for the encoded sound data.
     *
     * @return the format of the encoded sound, either FSSound.NATIVE_PCM (platform
     * dependent byte-order), FSSound.PCM (PCM little-endian byte-order), FSSound.ADPCM or
     * FSSound.MP3.
     */
    public int getFormat()
    {
        return format;
    }

    /** 
     * Accessor method returning the number of channels in the sound.
     * 
     * @return the number of sound channels, typically this will be 1 (mono) or 2 (stereo).
     */
    public int getNumberOfChannels()
    {
        return numberOfChannels;
    }

    /** 
     * Accessor method returning the number of samples in each channel.
     *
     * @return the number of samples in each channel.
     */
    public int getSamplesPerChannel()
    {
        return samplesPerChannel;
    }

    /** 
     * Accessor method returning the rate at which the sound will be played. The playback 
     * rate should be a value supported by the Flash Player 5512, 11025, 22050 or 44100 
     * Hertz. Although the sound rate may be changed using the changeSampleRate method 
     * the FSSoundConstructor class does not support the filtering required to change 
     * the sample rate from an arbitrary value to one of the rates supported by the Flash 
     * Player.
     *
     * MP3 formatted sounds have playback rates of 11025, 22050 or 44100.
     *
     * @return the playback rate for the sound, either 5512, 11025, 22050 or 44100 Hertz.
     */
    public int getSampleRate()
    {
        return sampleRate;
    }

    /** 
     * Accessor method returning the number of bytes for each decoded sound sample.
     * 
     * @return the number of bytes in each sample.
     */
    public int getSampleSize()
    {
        return sampleSize;
    }

    /** 
     * Accessor method returning a copy of the encoded sound data.
     * 
     * @return encoded sound data.
     */
    public byte[] getSound()
    {
        byte[] bytes = new byte[sound.length];
        
        System.arraycopy(sound, 0, bytes, 0, sound.length);

        return bytes;
    }

    /** 
     * Initialises the FSSoundConstructor with the contents of the specified file.
     * 
     * @param filename the name of a file containing encoded sound data.
     * 
     * @throws FileNotFoundException - if the file does not exist, is a directory 
     * rather than a regular file, or for some other reason cannot be opened for 
     * reading.
     * 
     * @throws IOException - if an I/O error occurs while reading the file.
     * 
     * @throws DataFormatException if the file contains a sound format not 
     * supported by the FSSoundConstructor.
     */
    public void setSound(String filename) throws IOException, DataFormatException
    {
        if (filename.toLowerCase().endsWith(".mp3"))
            decodeMP3(dataFromFile(filename));
        else if (filename.toLowerCase().endsWith(".wav"))
            decodeWAV(filename);
    }
    /** 
     * Initialises the FSSoundConstructor with the sound data and set of 
     * parameters. This method can be used to update the sound following 
     * processing for example to convert a stereo sound to mono to reduce the 
     * size of the encoded data.
     * 
     * @param format the format of the encoded sound either FSSound.PCM, 
     * FSSound.ADPCM or FSSound.MP3.
     * 
     * @param channelCount the number of sound channels, 1 = mono, 2 = stereo.
     * @param sampleCount the number of samples in each channel.
     * 
     * @param sampleRate the rate at which the sound is played in kiloHertz. 
     * Flash supports 5512, 11025, 22050 or 44100.
     * 
     * @param sampleSize the number of bytes for each uncompressed sound sample, 
     * either 1 or 2.
     * 
     * @param bytes an array of sound samples encoding in the specified format.
     */
    public void setSound(int format, int channelCount, int sampleCount, int sampleRate, int sampleSize, byte[] bytes)
    {
        this.format = format;
        this.numberOfChannels = channelCount;
        this.samplesPerChannel = sampleCount;
        this.sampleRate = sampleRate;
        this.sampleSize = sampleSize;

        sound = new byte[bytes.length];
        System.arraycopy(bytes, 0, sound, 0, bytes.length);
        
        if (format == FSSound.MP3)
            initFrameTable(bytes);
    }

    /** 
     * Generates an FSDefineSound object from the sound data. The FSDefineSound object is 
     * created using the encoded sound data so if the sound was decoded in order to change 
     * the number of channels, sample rate or sample size it must be re-encoded.
     * 
     * @param anIdentifier a unique identifier for the FSDefineSound object.
     * 
     * @return an FSDefineSound object initialised with the encoded sound data.
     */
    public FSDefineSound defineSound(int anIdentifier)
    {
        byte[] bytes = null;
        
        switch (format)
        {
            case FSSound.PCM:
            case FSSound.ADPCM:
                bytes = new byte[sound.length];
                System.arraycopy(sound, 0, bytes, 0, sound.length);
                break;
            case FSSound.MP3:
                bytes = new byte[2+sound.length];
                bytes[0] = 0;
                bytes[1] = 0;
                System.arraycopy(sound, 0, bytes, 2, sound.length);
                break;
        }
        return new FSDefineSound(anIdentifier, format, sampleRate, numberOfChannels, sampleSize, samplesPerChannel, bytes);
    }

    /** 
     * Generates an FSSoundStreamHead2 object to stream the sound data to the Flash Player.
     * 
     * @param samplesPerBlock the number of samples in each subsequent FSSoundStreamBlock 
     * object.
     * 
     * @return an FSDefineSound object initialised with the encoded sound data.
     */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -