Java合并(连接)多个音频
合并的说法有歧义,为了方便大家搜索到这里,所以用这个标题,实际上是连接(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输出结果
中间生成文件
多个文件合成的文件
Java合并(连接)多个音频的更多相关文章
- Java JDBC连接SQL Server2005错误:通过端口 1433 连接到主机 localhost 的 TCP/IP 连接失败 及sql2008外围服务器
转载:Java JDBC连接SQL Server2005错误:通过端口 1433 连接到主机 localhost 的 TCP/IP 连接失败 错误原因如下: Exception in thread & ...
- SQL连接操作符介绍(循环嵌套, 哈希匹配和合并连接)
今天我将介绍在SQLServer 中的三种连接操作符类型,分别是:循环嵌套.哈希匹配和合并连接.主要对这三种连接的不同.复杂度用范例的形式一一介绍. 本文中使用了示例数据库AdventureWorks ...
- 排序合并连接(sort merge join)的原理
排序合并连接(sort merge join)的原理 排序合并连接(sort merge join)的原理 排序合并连接(sort merge join) 访问次数:两张表都只会访 ...
- Java Mysql连接池配置和案例分析--超时异常和处理
前言: 最近在开发服务的时候, 发现服务只要一段时间不用, 下次首次访问总是失败. 该问题影响虽不大, 但终究影响用户体验. 观察日志后发现, mysql连接因长时间空闲而被关闭, 使用时没有死链检测 ...
- java jdbc 连接mysql数据库 实现增删改查
好久没有写博文了,写个简单的东西热热身,分享给大家. jdbc相信大家都不陌生,只要是个搞java的,最初接触j2ee的时候都是要学习这么个东西的,谁叫程序得和数据库打交道呢!而jdbc就是和数据库打 ...
- JAVA JDBC连接 SQLServer2012 连接失败 端口号错误
SQLServer2012的SQL Sever 网络配置 我有4个 SQLEXPRESS的协议 SQLSERVER2008的协议 MSSQLSERVER的协议 SQLSERVER2012的协议 他们都 ...
- JAVA长连接demo
http://blog.csdn.net/caomiao2006/article/details/38830475 JAVA长连接demo 2014-08-25 23:20 4767人阅读 评论(2) ...
- oracle表连接------>排序合并连接(Merge Sort Join)
排序合并连接 (Sort Merge Join)是一种两个表在做连接时用排序操作(Sort)和合并操作(Merge)来得到连接结果集的连接方法. 对于排序合并连接的优缺点及适用场景例如以下: a,通常 ...
- Java网络连接之HttpURLConnection、HttpsURLConnection
工具类包含两个方法: http请求.https请求 直接看代码: package com.jtools; import java.io.BufferedReader; import java.io.I ...
- mongodb3.0分片及java代码连接操作测试(开启用户验证)
最近抽时间搭建了一下mongodb简单的分片,整个过程还算是蛮顺利,只不过在用户验证这一块遇到了一些问题,好在最后终于搞定. 一.服务器搭建过程: 1.安装四个mongodb:一个作为config.一 ...
随机推荐
- 学习Spring-Data-Jpa(六)---spring-data-commons中的repository
1.spring-data-commons项目 spring-data-commons项目是所有spring-data项目的核心,我们来看一下该项目下的repository包中的接口和注解. 2.Re ...
- 双向认证下rpc-gateway使用(同时提供rpc和http服务)
下载go get -v github.com/grpc-ecosystem/grpc-gateway,然后把这个包下面的third-party下面的google文件夹拷贝到Prod.proto的同级目 ...
- .net大文件分块上传断点续传demo
IE的自带下载功能中没有断点续传功能,要实现断点续传功能,需要用到HTTP协议中鲜为人知的几个响应头和请求头. 一. 两个必要响应头Accept-Ranges.ETag 客户端每次提交下载请求时,服务 ...
- am335x system upgrade rootfs for dhcpcd cross compile(十三)
dhcpcd移植 [目的] 移植dhcpcd的目是在AM335X开发板上使用dhcp功能,获取WAN口设备的IP,并且可以通过参数指定其matric,matric值越小,其优先级越高.如设备可以以太网 ...
- Filebeat在windows下安装使用
一.windows下安装Filebeat 官网下载安装包 解压到指定目录,打开解压后的目录,打开filebeat.yml进行配置. 1.配置为输出到ElasticSearch ①:配置 Filebea ...
- mysqli的方法测试小结
<?php class MysqlController extends ControllerBase { public $config = array(); public $mysql = NU ...
- 洛谷 P5436 【XR-2】缘分 题解
P5436 [XR-2]缘分 题目背景 世间万物都置身于缘分编织的大网中.缘分未到,虽历经千劫,却不能相遇.缘分到了,在草原上都能等到一艘船.--<一禅小和尚> 题目描述 一禅希望知道他和 ...
- 机器学习---用python实现感知机算法和口袋算法(Machine Learning PLA Pocket Algorithm Application)
之前在<机器学习---感知机(Machine Learning Perceptron)>一文中介绍了感知机算法的理论知识,现在让我们来实践一下. 有两个数据文件:data1和data2,分 ...
- orm-配置不启动项目自动查询orm
配置 #!/usr/bin/env python import os import sys if __name__ == "__main__": os.environ.setdef ...
- 【概率论】6-1:大样本介绍(Large Random Samples Introduction)
title: [概率论]6-1:大样本介绍(Large Random Samples Introduction) categories: - Mathematic - Probability keyw ...