关于wav的文件结构网上能抓到一大把,这里只是简单的提一下。
wav文件分4个块,RIFF chunk ,Format chunk ,Data chunk是必须的。Fact chunk 可选。
其中RIFFSIZE DataSize 字段需要根据文件字节数计算: RIFFSize=DataSize+36-8; 因为三个chunk大小是36bytes,除去ID字节。
其他参数按照自己需求设置,formattag 如果是采用pcm则为1。
有一点要注意的是写入文件时候要考虑little—Endian和big_endian的区别。wav文件默认的little—endian方式。所以写入数据时要将顺序调整后在写入。
一下是我写的一个例子的代码:
虽然javasound可以直接保存为wav,但是我的实际需求是从需要更底层的控制,所以就自己写了一个demo。从microphone采集音频,并保存为文件。
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.TargetDataLine;
public class SpeechStore {
private static byte[] RIFF="RIFF".getBytes();
private static byte[] RIFF_SIZE=new byte[4];
private static byte[] RIFF_TYPE="WAVE".getBytes();
private static byte[] FORMAT="fmt ".getBytes();
private static byte[] FORMAT_SIZE=new byte[4];
private static byte[] FORMATTAG=new byte[2];
private static byte[] CHANNELS=new byte[2];
private static byte[] SamplesPerSec =new byte[4];
private static byte[] AvgBytesPerSec=new byte[4];
private static byte[] BlockAlign =new byte[2];
private static byte[] BitsPerSample =new byte[2];
private static byte[] DataChunkID="data".getBytes();
private static byte[] DataSize=new byte[4];
public static boolean isrecording=false;
public void writeToWave(){
}
public static void init(){
//这里主要就是设置参数,要注意revers函数在这里的作用
FORMAT_SIZE=new byte[]{(byte)16,(byte)0,(byte)0,(byte)0};
byte[] tmp=revers(intToBytes(1));
FORMATTAG=new byte[]{tmp[0],tmp[1]};
CHANNELS=new byte[]{tmp[0],tmp[1]};
SamplesPerSec=revers(intToBytes(16000));
AvgBytesPerSec=revers(intToBytes(32000));
tmp=revers(intToBytes(2));
BlockAlign=new byte[]{tmp[0],tmp[1]};
tmp=revers(intToBytes(16));
BitsPerSample=new byte[]{tmp[0],tmp[1]};
}
public static byte[] revers(byte[] tmp){
byte[] reversed=new byte[tmp.length];
for(int i=0;i<tmp.length;i++){
reversed[i]=tmp[tmp.length-i-1];
}
return reversed;
}
public static byte[] intToBytes(int num){
byte[] bytes=new byte[4];
bytes[0]=(byte)(num>>24);
bytes[1]=(byte)((num>>16)& 0x000000FF);
bytes[2]=(byte)((num>>8)& 0x000000FF);
bytes[3]=(byte)(num & 0x000000FF);
return bytes;
}
public static void main(String[] args){
InputStream input=capAudio();
int toaldatasize=0;
int audiolen;
byte[] audiochunk=new byte[1024];
//因为文件需要顺序读写,并且只能在最后才能确定riffsize和datasize参数,所以对前面的data要缓存。
ByteArrayOutputStream bytebuff=new ByteArrayOutputStream(9600000);
Timer tm=new Timer(20000);
tm.start();
try {
while(isrecording){
audiolen=input.read(audiochunk);
toaldatasize+=audiolen;
bytebuff.write(audiochunk, 0, audiolen);
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
DataSize=revers(intToBytes(toaldatasize));
RIFF_SIZE=revers(intToBytes(toaldatasize+36-8));
File wavfile= new File("F:\\writedformdata.wav");
FileOutputStream file=null;
try {
file=new FileOutputStream(wavfile);
BufferedOutputStream fw=new BufferedOutputStream(file);
init();
fw.write(RIFF);
fw.write(RIFF_SIZE);
fw.write(RIFF_TYPE);
fw.write(FORMAT);
fw.write(FORMAT_SIZE);
fw.write(FORMATTAG);
fw.write(CHANNELS);
fw.write(SamplesPerSec);
fw.write(AvgBytesPerSec);
fw.write(BlockAlign);
fw.write(BitsPerSample);
fw.write(DataChunkID);
fw.write(DataSize);
fw.write(bytebuff.toByteArray());
fw.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//这是音频采集的部分。
public static InputStream capAudio(){
float fFrameRate = 16000.0F;
TargetDataLine target_line = null;
AudioFormat format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
fFrameRate, 16, 1, 2, fFrameRate, false);
DataLine.Info lineInfo = new DataLine.Info(TargetDataLine.class,
format, 65536);
try {
target_line = (TargetDataLine) AudioSystem.getLine(lineInfo);
target_line.open(format, 655360);
} catch (LineUnavailableException e) {
System.err
.println("ERROR: LineUnavailableException at AudioSender()");
e.printStackTrace();
}
AudioInputStream audio_input = new AudioInputStream(target_line);
target_line.start();
isrecording=true;
return audio_input;
}
public void stopRecord(){
}
}
//Timer 是一个定时线程,到指定时间后将isrecording设置为false从而停止采集音频。
public class Timer extends Thread{
private int len;
public Timer(int len_){
this.len=len_;
}
public void run(){
try {
Thread.sleep(len);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
SpeechStore.isrecording=false;
}
}
分享到:
相关推荐
Java实现将WAV文件转换为MP3文件是一个常见的音频处理任务,主要涉及到音频编码和解码的知识。在本文中,我们将深入探讨这个过程,并提供一些关键的编程概念和技术。 首先,WAV和MP3是两种不同的音频文件格式。WAV...
Java实现多个wav文件合成一个的方法示例 本文介绍了Java实现多个wav文件合成一个的方法,涉及java文件流读写、编码转换、解析等相关操作技巧。 知识点1:Java中的文件流读写 在Java中,文件流读写是通过使用`...
java对wav音频文件头分析代码,解析wav音频文件的组成部分以及每个部分的相应的值和类型
总的来说,将WAV文件转换为MP3格式在Java中可以通过调用像LAME这样的外部工具实现,这使得我们能够在不直接依赖于特定平台的API的情况下,实现音频格式的转换。同时,为了获得更好的用户体验和健壮性,需要对错误...
总之,"JAVA 音频文件PCM转WAV Utils类"是Java音频处理领域的一个实用工具,它简化了音频格式转换的过程,使得开发人员可以更方便地在不同音频格式之间进行转换,特别是在需要从基本的PCM数据创建WAV文件的场合。
wav 格式文件用于 java 程序转换mp3 使用
标题中的“wav文件播放”指的是在计算机上使用编程语言(如VB,Visual Basic)实现对.wav音频文件的播放功能。.wav是微软公司开发的一种无损音频格式,它保留了原始音频的所有细节,但文件体积相对较大。在编程中...
1、Java实现wav音频文件转换为pcm音频文件(AudioUtils.java) 2、Java实现播放pcm音频文件(PCMPlay.java) ...简单来说:pcm是无损wav文件中音频数据的一种编码方式,但wav还可以用其它方式编码。
`JAVA调用exe可执行文件.txt`这个文件名暗示了可能有额外的处理步骤,比如Java程序可能通过`Runtime.getRuntime().exec()`方法调用外部的音频处理工具,例如转换WAV文件或提取特定信息。这通常发生在Java自身的处理...
一个挺简单的Java音乐播放器,主要是播放wav格式的音频文件,其它格式暂不支持,代码比较早,确实是比较简单的例子,Java新手参考吧。源代码如下所示: public MusicDemo() { textbox=new TextBox("title",...
纯Java ,从输入流中截去音频的前44个字节。 适用WAV转PCM
这是一个完整的myeclipse项目,主要实现的功能有: 1.用java获取wave类型的音频文件头信息; 2.根据传入参数截取指定时间段内的音频片段 改资源为本人原创,下载后导入myeclipse可以直接运行
本文将深入探讨如何在Java和C++(VC++)环境中读取、处理和保存WAV文件,以及与PCM数据的关系。 首先,WAV文件是微软开发的一种音频容器格式,它包含了未经压缩的音频数据。这种格式的优点是数据质量高,但缺点是...
单纯用vb实现的wav文件合并,两个文件要有相同的码率,采样位数,声道等等,总之就是两个正常大小的文件合并是可以的,只要两个文件的总大小小于2GB,那就可以了.这个纯vb6实现,像一般的几十兆的wav文件合并,还是很快的,...
WAV文件格式是一种无损音频编码格式,由微软与IBM共同开发,主要用于存储数字音频数据。它是基于RIFF(Resource Interchange File Format)文件结构的,这种格式在Windows操作系统环境中非常常见。WAV文件能够忠实...
- 读取WAV文件头信息:通过`java.io.RandomAccessFile`类读取文件,并解析出关键参数。 - 解码WAV数据:使用`java.nio`包中的缓冲区进行高效的数据读取和转换。 - 转换格式:实现音频数据的位深度和声道数转换。 - ...
在本文中,我们将深入探讨如何使用 Java 来拆分 WAV 音频文件。标题中的“wav-splitter”项目提供了一个示例,展示了如何将一个大的 WAV 文件分割成多个500毫秒的小片段。这个过程在音频处理和分析中非常有用,例如...
Java播放wav音频功能的实现代码,播放wav音频,压缩包中带有测试音频,是否能播放 MP3,未知。 boolean looping = false; //是否循环播放 String[] choics = { "chimes.wav", "start.wav" }; //声音文件名数组...
对于`WavCutUtils.java`,这个类通常会包含对WAV文件进行剪辑的方法。WAV是一种无损音频格式,存储的数据是原始的PCM(脉冲编码调制)数据,因此剪辑操作相对简单。关键步骤可能包括: 1. **读取WAV文件**:使用`...
在Java编程环境中,开发人员经常需要处理多媒体文件,如音频文件。这个名为"AudioDemo"的项目就是一个关于如何使用Java来获取音频文件播放时长的示例代码。在这个项目中,开发者可以学习到如何利用Java的内置库来...