java sound resource

合并的说法有歧义,为了方便大家搜索到这里,所以用这个标题,实际上是连接(concat),可以理解为字符串concat方法所指定的含义。

AudioConcat.java源码
*    AudioConcat.java
 *
 *    This file is part of jsresources.org
 */

/*
 * Copyright (c) 1999 - 2001 by Matthias Pfisterer
 * 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.
 *
 * 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.
 */

/*
|<---            this code is formatted to fit into 80 columns             --->|
*/

import gnu.getopt.Getopt;

import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/*    If the compilation fails because this class is not available,
    get gnu.getopt from the URL given in the comment below.
*/


// TODO: the name AudioConcat is no longer appropriate. There should be a name that is neutral to concat/mix.

/**    <titleabbrev>AudioConcat</titleabbrev>
    <title>Concatenating or mixing audio files</title>

    <formalpara><title>Purpose</title>
    <para>This program reads multiple audio files and
    writes a single one either
    containing the data of all the other
    files in order (concatenation mode, option <option>-c</option>)
    or containing a mixdown of all the other files
    (mixing mode, option <option>-m</option>).
    For concatenation, the input files must have the same audio
    format. They need not have the same file type.</para>
    </formalpara>

    <formalpara><title>Usage</title>
    <para>
    <cmdsynopsis>
    <command>java AudioConcat</command>
    <arg choice="plain"><option>-h</option></arg>
    </cmdsynopsis>
    <cmdsynopsis>
    <command>java AudioConcat</command>
    <arg choice="opt"><option>-D</option></arg>
    <group choice="plain">
    <arg><option>-c</option></arg>
    <arg><option>-m</option></arg>
    </group>
    <arg choice="plain"><option>-o <replaceable>outputfile</replaceable></option></arg>
    <arg choice="plain" rep="repeat"><replaceable>inputfile</replaceable></arg>
    </cmdsynopsis>
    </para>
    </formalpara>

    <formalpara><title>Parameters</title>
    <variablelist>
    <varlistentry>
    <term><option>-c</option></term>
    <listitem><para>selects concatenation mode</para></listitem>
    </varlistentry>
    <varlistentry>
    <term><option>-m</option></term>
    <listitem><para>selects mixing mode</para></listitem>
    </varlistentry>
    <varlistentry>
    <term><option>-o <replaceable>outputfile</replaceable></option></term>
    <listitem><para>The filename of the output file</para></listitem>
    </varlistentry>
    <varlistentry>
    <term><replaceable>inputfile</replaceable></term>
    <listitem><para>the name(s) of input file(s)</para></listitem>
    </varlistentry>
    </variablelist>
    </formalpara>

    <formalpara><title>Bugs, limitations</title>
    <para>
    This program is not well-tested. Output is always a WAV
    file. Future versions should be able to convert
    different audio formats to a dedicated target format.
    </para></formalpara>

    <formalpara><title>Source code</title>
    <para>
    <ulink url="AudioConcat.java.html">AudioConcat.java</ulink>,
    <ulink url="SequenceAudioInputStream.java.html">SequenceAudioInputStream.java</ulink>,
    <ulink url="MixingAudioInputStream.java.html">MixingAudioInputStream.java</ulink>,
    <ulink url="http://www.urbanophile.com/arenn/hacking/download.html">gnu.getopt.Getopt</ulink>
    </para>
    </formalpara>

*/
public class AudioConcat
{
    private static final int    MODE_NONE = 0;
    private static final int    MODE_MIXING = 1;
    private static final int    MODE_CONCATENATION = 2;

    /**    Flag for debugging messages.
     *    If true, some messages are dumped to the console
     *    during operation.    
     */
    private static boolean    DEBUG = false;



    public static void main(String[] args)
    {
        /**    Mode of operation.
            Determines what to do with the input files:
            either mixing or concatenation.
         */
        int        nMode = MODE_NONE;
        String        strOutputFilename = null;
        AudioFormat    audioFormat = null;
        List        audioInputStreamList = new ArrayList();

        // int    nExternalBufferSize = DEFAULT_EXTERNAL_BUFFER_SIZE;
        // int    nInternalBufferSize = AudioSystem.NOT_SPECIFIED;


        /*
         *    Parsing of command-line options takes place...
         */
        Getopt    g = new Getopt("AudioConcat", args, "hDcmo:");
        int    c;
        while ((c = g.getopt()) != -1)
        {
            switch (c)
            {
            case 'h':
                printUsageAndExit();

            case 'o':
                strOutputFilename = g.getOptarg();
                if (DEBUG) { out("AudioConcat.main(): output filename: " + strOutputFilename); }
                break;

            case 'c':
                nMode = MODE_CONCATENATION;
                break;

            case 'm':
                nMode = MODE_MIXING;
                break;

            case 'D':
                DEBUG = true;
                break;

            case '?':
                printUsageAndExit();

            default:
                out("AudioConcat.main(): getopt() returned " + c);
                break;
            }
        }

        /*
         *    All remaining arguments are assumed to be filenames of
         *    soundfiles we want to play.
         */
        String    strFilename = null;
        for (int i = g.getOptind(); i < args.length; i++)
        {
            strFilename = args[i];
            File    soundFile = new File(strFilename);

            /*
             *    We have to read in the sound file.
             */
            AudioInputStream    audioInputStream = null;
            try
            {
                audioInputStream = AudioSystem.getAudioInputStream(soundFile);
            }
            catch (Exception e)
            {
                /*
                 *    In case of an exception, we dump the exception
                 *    including the stack trace to the console output.
                 *    Then, we exit the program.
                 */
                e.printStackTrace();
                System.exit(1);
            }
            AudioFormat    format = audioInputStream.getFormat();
            /*
              The first input file determines the audio format. This stream's
              AudioFormat is stored. All other streams are checked against
              this format.
             */
            if (audioFormat == null)
            {
                audioFormat = format;
                if (DEBUG) { out("AudioConcat.main(): format: " + audioFormat); }
            }
            else if ( ! audioFormat.matches(format))
            {
                // TODO: try to convert
                out("AudioConcat.main(): WARNING: AudioFormats don't match");
                out("AudioConcat.main(): master format: " + audioFormat);
                out("AudioConcat.main(): this format: " + format);
            }
            audioInputStreamList.add(audioInputStream);
        }

        if (audioFormat == null)
        {
            out("No input filenames!");
            printUsageAndExit();
        }
        AudioInputStream    audioInputStream = null;
        switch (nMode)
        {
        case MODE_CONCATENATION:
            audioInputStream = new SequenceAudioInputStream(audioFormat, audioInputStreamList);
            break;

        case MODE_MIXING:
            audioInputStream = new MixingAudioInputStream(audioFormat, audioInputStreamList);
            break;

        default:
            out("you have to specify a mode (either -m or -c).");
            printUsageAndExit();
        }

        if (strOutputFilename == null)
        {
            out("you have to specify an output filename (using -o <filename>).");
            printUsageAndExit();
        }
        File    outputFile = new File(strOutputFilename);
        try
        {
            AudioSystem.write(audioInputStream, AudioFileFormat.Type.WAVE, outputFile);
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }

        if (DEBUG) { out("AudioConcat.main(): before exit"); }
        System.exit(0);
    }



    private static void printUsageAndExit()
    {
        out("AudioConcat: usage:");
        out("\tjava AudioConcat -h");
        out("\tjava AudioConcat [-D] -c|-m -o <outputfile> <inputfile> ...");
        System.exit(1);
    }



    private static void out(String strMessage)
    {
        System.out.println(strMessage);
    }
}



/*** AudioConcat.java ***/

食用方法(从main方法中拷贝出代码来测试):

import org.junit.Test;

import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.UnsupportedAudioFileException;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.TreeSet;

public class TestConcatAudioStream {

    private static final int    MODE_MIXING = 1;
    private static final int    MODE_CONCATENATION = 2;
    /**    Flag for debugging messages.
     *    If true, some messages are dumped to the console
     *    during operation.
     */
    private static boolean        DEBUG = true;

    private static void out(String strMessage)
    {
        System.out.println(strMessage);
    }

    @Test
    public void testMultiReSampling2() throws IOException, UnsupportedAudioFileException {
        TreeSet<String> orderedFileNames = getOrderedSeqFileNames();
        Iterator<String> it = orderedFileNames.iterator();

        ByteOutputStream out = new ByteOutputStream();

        while (it.hasNext())
        {
            String fileName = it.next();

            String _16kFileName = fileName.substring(0, fileName.lastIndexOf(".")).concat("_16k.wav");
            convert(fileName,_16kFileName);
            RandomAccessFile raf = new RandomAccessFile(_16kFileName, "r");
            raf.skipBytes(44);
            byte buff[] = new byte[(int) (raf.length()-44)];
            raf.read(buff);
            out.write(buff);
        }
        WavFileGenerator generator = new WavFileGenerator(16000,16);
        //AudioStreamHelper.saveToFile("e:/asset/sampleRateConverter_16k.wav",out.getBytes());
        generator.saveFile("e:/asset/sampleRateConverter_16k.wav",out.getBytes());
    }

    @Test
    public void testMultiReSampling() throws IOException {
        TreeSet<String> orderedFileNames = getOrderedSeqFileNames();
        Iterator<String> it = orderedFileNames.iterator();

        ByteOutputStream out = new ByteOutputStream();

        while (it.hasNext())
        {
            String fileName = it.next();
            byte[] bytes = Files.readAllBytes(Paths.get(fileName));
            byte[] resampled = AudioStreamHelper.reSampling2PCM(bytes);
            out.write(resampled);
        }
        StdAudio.play(out.toByteArray());
    }


    void convert(String srcFile,String trgtFile) throws IOException, UnsupportedAudioFileException {
        float    fTargetSampleRate =16000.0f;
        if (DEBUG) { out("target sample rate: " + fTargetSampleRate); }
        File    sourceFile = new File(srcFile);
        File    targetFile = new File(trgtFile);

        /* We try to use the same audio file type for the target
           file as the source file. So we first have to find
           out about the source file's properties.
        */
        AudioFileFormat        sourceFileFormat = AudioSystem.getAudioFileFormat(sourceFile);
        AudioFileFormat.Type    targetFileType = sourceFileFormat.getType();

        /* Here, we are reading the source file.
         */
        AudioInputStream    sourceStream = null;
        sourceStream = AudioSystem.getAudioInputStream(sourceFile);
        if (sourceStream == null)
        {
            out("cannot open source audio file: " + sourceFile);
            System.exit(1);
        }
        AudioFormat    sourceFormat = sourceStream.getFormat();
        if (DEBUG)  { out("source format: " + sourceFormat); }

        /* Currently, the only known and working sample rate
           converter for Java Sound requires that the encoding
           of the source stream is PCM (signed or unsigned).
           So as a measure of convenience, we check if this
           holds here.
        */
        AudioFormat.Encoding    encoding = sourceFormat.getEncoding();
        if (! AudioCommon.isPcm(encoding))
        {
            out("encoding of source audio data is not PCM; conversion not possible");
            System.exit(1);
        }

        /* Since we now know that we are dealing with PCM, we know
           that the frame rate is the same as the sample rate.
        */
        float        fTargetFrameRate = fTargetSampleRate;

        /* Here, we are constructing the desired format of the
           audio data (as the result of the conversion should be).
           We take over all values besides the sample/frame rate.
        */

        AudioFormat    targetFormat = new AudioFormat(
                sourceFormat.getEncoding(),
                fTargetSampleRate,
                sourceFormat.getSampleSizeInBits(),
                sourceFormat.getChannels(),
                sourceFormat.getFrameSize(),
                fTargetFrameRate,
                sourceFormat.isBigEndian());

        if (DEBUG)  { out("desired target format: " + targetFormat); }

        /* Now, the conversion takes place.
         */
        AudioInputStream    targetStream = AudioSystem.getAudioInputStream(targetFormat, sourceStream);
        if (DEBUG) { out("targetStream: " + targetStream); }

        /* And finally, we are trying to write the converted audio
           data to a new file.
        */
        int    nWrittenBytes = 0;
        nWrittenBytes = AudioSystem.write(targetStream, targetFileType, targetFile);
        if (DEBUG) { out("Written bytes: " + nWrittenBytes); }
    }

    @Test
    public void testMultiReSamplingUsingStreamConvert() throws IOException {
        TreeSet<String> orderedFileNames = getOrderedSeqFileNames();
        Iterator<String> it = orderedFileNames.iterator();

        ByteOutputStream out = new ByteOutputStream();

        while (it.hasNext())
        {
            String fileName = it.next();
            byte[] bytes = Files.readAllBytes(Paths.get(fileName));

            byte[] resampled = AudioStreamHelper.reSampling2PCM(bytes);
            out.write(resampled);
        }
        StdAudio.play(out.toByteArray());
    }

    @Test
    public void test()
    {

        /**    Mode of operation.
         Determines what to do with the input files:
         either mixing or concatenation.
         */
        int        nMode = MODE_CONCATENATION;
        String        strOutputFilename = "e:\\asset\\48k_concatStream.wav";
        AudioFormat    audioFormat = null;
        List audioInputStreamList = new ArrayList();

        /*
         *    All remaining arguments are assumed to be filenames of
         *    soundfiles we want to play.
         */

        String    strFilename = null;

        int size = getOrderedSeqFileNames().size();

        Iterator<String> it = getOrderedSeqFileNames().iterator();
        while (it.hasNext()){
        //for (int i = 0; i < size; i++)
        //{
            strFilename = it.next();
            File soundFile = new File(strFilename);

            /*
             *    We have to read in the sound file.
             */
            AudioInputStream audioInputStream = null;
            try
            {
                audioInputStream = AudioSystem.getAudioInputStream(soundFile);
            }
            catch (Exception e)
            {
                /*
                 *    In case of an exception, we dump the exception
                 *    including the stack trace to the console output.
                 *    Then, we exit the program.
                 */
                e.printStackTrace();
                System.exit(1);
            }
            AudioFormat format = audioInputStream.getFormat();
            /*
              The first input file determines the audio format. This stream's
              AudioFormat is stored. All other streams are checked against
              this format.
             */
            if (audioFormat == null)
            {
                audioFormat = format;
                System.out.println("AudioConcat.main(): format: " + audioFormat);
            }
            else if ( ! audioFormat.matches(format))
            {
                // TODO: try to convert
                System.out.println("AudioConcat.main(): WARNING: AudioFormats don't match");
                System.out.println("AudioConcat.main(): master format: " + audioFormat);
                System.out.println("AudioConcat.main(): this format: " + format);
            }
            audioInputStreamList.add(audioInputStream);
        }

        if (audioFormat == null)
        {
            System.out.println("No input filenames!");

        }
        AudioInputStream    audioInputStream = null;
        switch (nMode)
        {
            case MODE_CONCATENATION:
                audioInputStream = new SequenceAudioInputStream(audioFormat, audioInputStreamList);
                break;

            case MODE_MIXING:
                audioInputStream = new MixingAudioInputStream(audioFormat, audioInputStreamList);
                break;

            default:
                System.out.println("you have to specify a mode (either -m or -c).");
        }

        if (strOutputFilename == null)
        {
            System.out.println("you have to specify an output filename (using -o <filename>).");

        }
        File    outputFile = new File(strOutputFilename);
        try
        {
            AudioSystem.write(audioInputStream, AudioFileFormat.Type.WAVE, outputFile);
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }


    public TreeSet<String> getOrderedSeqFileNames()
    {
        try (DirectoryStream<Path> stream = Files.newDirectoryStream(Paths.get("E:\\asset"), "*.wav")) {

            TreeSet<String> treeSet = new TreeSet<>();
            Iterator<Path> it = stream.iterator();


            while (it.hasNext()) {
                Path path = it.next();
                String filename = path.getFileName().toString();
                if (filename.matches("\\d{13}\\.wav") && Files.size(path) > 0) {
                    treeSet.add(path.toString());
                }
            }
            return treeSet;
        }catch (Exception e)
        {}
        return null;
    }
}

 

本地文件如下:

 

 

 

testMultiReSampling2输出结果

中间生成文件

 

 

 

 

 多个文件合成的文件

 

 

 

 

posted on 2019-11-20 09:04  你不知道的浪漫  阅读(5201)  评论(0编辑  收藏  举报