zoukankan      html  css  js  c++  java
  • Java合并(连接)多个音频

    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("	java AudioConcat -h");
            out("	java 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输出结果

    中间生成文件

     多个文件合成的文件

  • 相关阅读:
    terraform入门操作指南
    linux常用命令
    pssh用法范例
    nginx共享内存使用
    Redis监控指标[转]
    xargs用法笔记
    systemd用法记录一
    esxcli部分常用命令
    lua自定义功能模块table类型转string类型
    curl用法笔记
  • 原文地址:https://www.cnblogs.com/passedbylove/p/11895541.html
Copyright © 2011-2022 走看看