`
hustlong
  • 浏览: 124057 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

Java 写wav文件

阅读更多
关于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文件

    Java实现将WAV文件转换为MP3文件是一个常见的音频处理任务,主要涉及到音频编码和解码的知识。在本文中,我们将深入探讨这个过程,并提供一些关键的编程概念和技术。 首先,WAV和MP3是两种不同的音频文件格式。WAV...

    Java实现多个wav文件合成一个的方法示例

    Java实现多个wav文件合成一个的方法示例 本文介绍了Java实现多个wav文件合成一个的方法,涉及java文件流读写、编码转换、解析等相关操作技巧。 知识点1:Java中的文件流读写 在Java中,文件流读写是通过使用`...

    java对wav音频文件头分析代码

    java对wav音频文件头分析代码,解析wav音频文件的组成部分以及每个部分的相应的值和类型

    在java程序中实现wav文件转MP3

    总的来说,将WAV文件转换为MP3格式在Java中可以通过调用像LAME这样的外部工具实现,这使得我们能够在不直接依赖于特定平台的API的情况下,实现音频格式的转换。同时,为了获得更好的用户体验和健壮性,需要对错误...

    JAVA 音频文件PCM转WAV Utils类

    总之,"JAVA 音频文件PCM转WAV Utils类"是Java音频处理领域的一个实用工具,它简化了音频格式转换的过程,使得开发人员可以更方便地在不同音频格式之间进行转换,特别是在需要从基本的PCM数据创建WAV文件的场合。

    wav 格式文件用于 java 程序转换mp3 使用

    wav 格式文件用于 java 程序转换mp3 使用

    wav文件播放

    标题中的“wav文件播放”指的是在计算机上使用编程语言(如VB,Visual Basic)实现对.wav音频文件的播放功能。.wav是微软公司开发的一种无损音频格式,它保留了原始音频的所有细节,但文件体积相对较大。在编程中...

    音频转换(WAV转换为PCM)

    1、Java实现wav音频文件转换为pcm音频文件(AudioUtils.java) 2、Java实现播放pcm音频文件(PCMPlay.java) ...简单来说:pcm是无损wav文件中音频数据的一种编码方式,但wav还可以用其它方式编码。

    JAVA画出wav音频波形图

    `JAVA调用exe可执行文件.txt`这个文件名暗示了可能有额外的处理步骤,比如Java程序可能通过`Runtime.getRuntime().exec()`方法调用外部的音频处理工具,例如转换WAV文件或提取特定信息。这通常发生在Java自身的处理...

    Java简单音乐播放器播放wav文件示例.rar

    一个挺简单的Java音乐播放器,主要是播放wav格式的音频文件,其它格式暂不支持,代码比较早,确实是比较简单的例子,Java新手参考吧。源代码如下所示:  public MusicDemo() {  textbox=new TextBox("title",...

    java wav转为pcm

    纯Java ,从输入流中截去音频的前44个字节。 适用WAV转PCM

    java截取wave文件,java获取wave文件头信息

    这是一个完整的myeclipse项目,主要实现的功能有: 1.用java获取wave类型的音频文件头信息; 2.根据传入参数截取指定时间段内的音频片段 改资源为本人原创,下载后导入myeclipse可以直接运行

    Wav.rar_wav 读 vc 数据_wav java_wav文件读取_保存wav_读取pcm数据

    本文将深入探讨如何在Java和C++(VC++)环境中读取、处理和保存WAV文件,以及与PCM数据的关系。 首先,WAV文件是微软开发的一种音频容器格式,它包含了未经压缩的音频数据。这种格式的优点是数据质量高,但缺点是...

    多个wav文件合并成一个文件

    单纯用vb实现的wav文件合并,两个文件要有相同的码率,采样位数,声道等等,总之就是两个正常大小的文件合并是可以的,只要两个文件的总大小小于2GB,那就可以了.这个纯vb6实现,像一般的几十兆的wav文件合并,还是很快的,...

    WAV文件格式(用于解析WAV文件)

    WAV文件格式是一种无损音频编码格式,由微软与IBM共同开发,主要用于存储数字音频数据。它是基于RIFF(Resource Interchange File Format)文件结构的,这种格式在Windows操作系统环境中非常常见。WAV文件能够忠实...

    JAVA wav转PCM Utils代码工具类

    - 读取WAV文件头信息:通过`java.io.RandomAccessFile`类读取文件,并解析出关键参数。 - 解码WAV数据:使用`java.nio`包中的缓冲区进行高效的数据读取和转换。 - 转换格式:实现音频数据的位深度和声道数转换。 - ...

    wav-splitter:使用 Java 将 WAV 文件分成多个部分

    在本文中,我们将深入探讨如何使用 Java 来拆分 WAV 音频文件。标题中的“wav-splitter”项目提供了一个示例,展示了如何将一个大的 WAV 文件分割成多个500毫秒的小片段。这个过程在音频处理和分析中非常有用,例如...

    Java播放wav音频功能的实现代码.rar

    Java播放wav音频功能的实现代码,播放wav音频,压缩包中带有测试音频,是否能播放 MP3,未知。  boolean looping = false; //是否循环播放  String[] choics = { "chimes.wav", "start.wav" }; //声音文件名数组...

    java音频剪辑支持MP3wav 根据时间剪辑

    对于`WavCutUtils.java`,这个类通常会包含对WAV文件进行剪辑的方法。WAV是一种无损音频格式,存储的数据是原始的PCM(脉冲编码调制)数据,因此剪辑操作相对简单。关键步骤可能包括: 1. **读取WAV文件**:使用`...

    java源码 java获取音频文件 播放时长AudioDemo 2018127

    在Java编程环境中,开发人员经常需要处理多媒体文件,如音频文件。这个名为"AudioDemo"的项目就是一个关于如何使用Java来获取音频文件播放时长的示例代码。在这个项目中,开发者可以学习到如何利用Java的内置库来...

Global site tag (gtag.js) - Google Analytics