`
mox_sir
  • 浏览: 35654 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

java实现V3格式音频文件向wav文件的转换

    博客分类:
  • Java
 
阅读更多
package com.loveLife.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class V3ToWav {
	private static V3ToWav v3ToWav;
	private V3ToWav(){
		
	}
	
	public static V3ToWav getInstance(){
		if(v3ToWav == null){
			v3ToWav = new V3ToWav();
		}
		return v3ToWav;
	}

	private static final int WAV_HEAD = 36;// wav文件头长度

	private static final int VF_ADPCM = 1;// 编码格式

	private static final int BIT_RATE_VB_8 = 1;// 每个样本位数

	private static final int BIT_RATE_VB_16 = 2;// 每个样本位数

	private static final int RESET_VALUE = 48;

	private static byte out_val;

	/**
	 * 
	 * @param inFile
	 * @param outFile
	 * @param voxFormat
	 *            格式 取值范围:VF_ADPCM = 1, VF_MULAW = 2, VF_ALAW = 3
	 * @param voxRate
	 *            采样率 取值范围:VR_6K = 6000, VR_8K = 8000
	 * @param bit_rate
	 *            位数 取值范围:VB_8 = 1, VB_16 = 2
	 * @return
	 */

	public static void voxConvert(String inFile, String outFile, int voxFormat,
			int voxRate, int bit_rate) throws Exception {

		if (outFile == null) {
			outFile = inFile.substring(0, inFile.length() - 2);
			outFile = outFile + "wav";
		}

		File outF = new File(outFile);
		File inF = new File(inFile);

		long inFileSize = inF.length();
		if (voxFormat == VF_ADPCM) { // if using ADPCM input format...
			inFileSize = inFileSize * 2;
		}// change from bytes to samples

		FileOutputStream filewriter = new FileOutputStream(outF, false);
		String wavBegin = "RIFF";
		filewriter.write(wavBegin.getBytes());// WAV 文件头

		long wavLength = inFileSize * bit_rate + WAV_HEAD;
		byte[] tmpArr = new byte[4];
		longToIntBinary(wavLength, tmpArr, 0);
		filewriter.write(tmpArr);// 文件总长度

		String wavTag = "WAVEfmt ";
		filewriter.write(wavTag.getBytes());// WAV 文件标识

		int headLength = 16;
		tmpArr = new byte[4];
		longToIntBinary(headLength, tmpArr, 0);
		filewriter.write(tmpArr);// size of .WAV file header

		int wFormatTag = 1; // format tag (01 = Windows PCM)
		tmpArr = new byte[2];
		toShortBinary(wFormatTag, tmpArr, 0);
		filewriter.write(tmpArr);// format tag (01 = Windows PCM)

		int nChannels = 1; // channels (1=mono, 2=stereo)
		tmpArr = new byte[2];
		toShortBinary(nChannels, tmpArr, 0);
		filewriter.write(tmpArr);// channels (1=mono, 2=stereo)

		int nSamplesPerSec = voxRate; // samples per second
		tmpArr = new byte[4];
		longToIntBinary(nSamplesPerSec, tmpArr, 0);
		filewriter.write(tmpArr);

		int nAvgBytesPerSec = voxRate * bit_rate; // bytes per second
		// during play
		tmpArr = new byte[4];
		longToIntBinary(nAvgBytesPerSec, tmpArr, 0);
		filewriter.write(tmpArr);

		int nBlockAlign = bit_rate; // bytes per sample
		tmpArr = new byte[2];
		toShortBinary(nBlockAlign, tmpArr, 0);
		filewriter.write(tmpArr);// bytes per sample

		int wBitsPerSample = 8 * bit_rate; // bits per sample
		tmpArr = new byte[2];
		toShortBinary(wBitsPerSample, tmpArr, 0);
		filewriter.write(tmpArr);// bits per sample

		/** ******以下是数据头********* */
		String dataTag = "data";
		filewriter.write(dataTag.getBytes());// data tag

		long Datalen = inFileSize * bit_rate; // write size of .WAV data
		// portion
		tmpArr = new byte[4];
		longToIntBinary(Datalen, tmpArr, 0);
		filewriter.write(tmpArr);// 数据总长度

		FileInputStream fileReader = new FileInputStream(inF);
		byte[] outbytebuffer = new byte[20000];
		int[] outintbuffer = new int[20000];
		switch (voxFormat) {
		case VF_ADPCM:// VF_ADPCM
		{
			short Sn = 0; // initialize the ADPCM variables
			int SS = 16; // initialize the Step
			int SSindex = 1;
			int i = 0;
			byte[] b = new byte[10000];

			int outindex;
			byte sample;// 一个采样样本

			int allBytes = fileReader.available();
			while (allBytes > 0) {
				int thisRead = allBytes > 10000 ? 10000 : allBytes;
				int bytes = fileReader.read(b, 0, thisRead);

				allBytes -= thisRead;// 剩余可读的字节数
				outindex = 0;
				for (int index = 0; index < bytes; index++) {
					sample = b[index];
					byte highByte = (byte) (sample >>> 4 & 0xff);
					byte lowByte = (byte) (sample & 0x0f);

					/** *****开始高字节处理******** */
					if ((highByte == 0) || (highByte == 8)) {
						i++;
					}
					Object[] retVal = decode((byte) (sample >>> 4), Sn, SS,
							SSindex);
					Sn = ((Short) retVal[0]).shortValue();
					SS = ((Integer) retVal[1]).intValue();
					SSindex = ((Integer) retVal[2]).intValue();

					int out_int;
					if (bit_rate == BIT_RATE_VB_8) {// if 8 bits per sample...
						out_int = Sn / 16;
						if (out_int > 127) { // clip if above or below WAV
							// bounds
							out_int = 127;
						}
						if (out_int < -128) {
							out_int = -128;
						}
						out_val = (byte) ((out_int - 128) & 0xff); // convert

						// to
						// .WAV format
						outbytebuffer[outindex] = out_val; // write the output
						// byte
					} else {// else 16 bits per sample
						out_int = Sn * 16; // rescale to 16 bits
						outintbuffer[outindex] = out_int; // write the output
						// int
					}
					outindex++;

					if (i == RESET_VALUE) { // Reset ADPCM variables 48位时重置各个值
						Sn = 0; // initialize the ADPCM variables
						SS = 16; // initialize the Step
						i = 0;
					}

					/** *******低字节处理********* */
					if (lowByte == 0 || lowByte == 8) {
						i++;
					}
					retVal = decode((byte) (sample & 0x0f), Sn, SS, SSindex);
					Sn = ((Short) retVal[0]).shortValue();
					SS = ((Integer) retVal[1]).intValue();
					SSindex = ((Integer) retVal[2]).intValue();

					if (bit_rate == BIT_RATE_VB_8) {// if 8 bits per sample...
						out_int = Sn / 16;
						if (out_int > 127) { // clip if above or below WAV
							// bounds
							out_int = 127;
						}
						if (out_int < -128) {
							out_int = -128;
						}
						out_val = (byte) ((out_int - 128) & 0xff); // convert

						// to
						// .WAV format
						outbytebuffer[outindex] = out_val; // write the output
						// byte
					} else {// else 16 bits per sample
						out_int = Sn * 16; // rescale to 16 bits
						outintbuffer[outindex] = out_int; // write the output
						// int
					}
					outindex++;

					if (i == RESET_VALUE) { // Reset ADPCM variables 48位时重置各个值
						Sn = 0; // initialize the ADPCM variables
						SS = 16; // initialize the Step
						i = 0;
					}
				}
				if (bit_rate == BIT_RATE_VB_8) {
					filewriter.write(outbytebuffer);

				} else {
					for (int j = 0; j < outintbuffer.length; j++) {
						byte[] arr = new byte[4];
						longToIntBinary(outintbuffer[j], arr, 0);
						filewriter.write(arr);

					}
				}
			}
			break;

		}
		default:
			break;
		}

		fileReader.close();
		filewriter.close();

	}

	/**
	 * 
	 * @param sample
	 * @param Sn
	 * @param ss
	 *            引用变量
	 * @param SSindex
	 *            引用变量
	 * @return
	 */
	private static Object[] decode(byte sample, short Sn, int SS, int SSindex) {
		Object[] retArr = new Object[3];
		int[] SSadjust = new int[] { -1, -1, -1, -1, 2, 4, 6, 8 };
		// Calculated stepsizes per Dialogic Application Note 1366
		int[] SStable = new int[] { 0, 16, 17, 19, 21, 23, 25, 28, 31, 34, 37,
				41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143,
				157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449,
				494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, 1411,
				1552 };
		int Mn = 0; // calculate the linear adjustment
		if ((sample & 0x4) != 0) {
			Mn = SS;
		}
		if ((sample & 0x2) != 0) {
			Mn = Mn + (SS >>> 1);
		}// div 2
		if ((sample & 0x1) != 0) {
			Mn = Mn + (SS >>> 2);
		}// div 4

		Mn = Mn + (SS >>> 3); // div 8
		// 取Sample的符号位,即最高位
		if ((sample & 0x8) != 0) { // 最高位为1,则符号位为负
			Sn = (short) (((int) Sn - Mn) & 0xffff); // ...subtract the
			// adjustment
		} else { // 符号位为正
			Sn = (short) (((int) Sn + Mn) & 0xffff); // ...add the adjustment
		}

		if (Sn > 2047) { // adjust if sample too large...
			Sn = 2047;
		}
		if (Sn < -2048) { // ...or too small
			Sn = -2048;
		}

		// use as index into step size adjustment, adjust step size index
		SSindex = SSindex + SSadjust[sample & 0x07];

		if (SSindex < 1) { // keep SSindex within bounds...
			SSindex = 1;
		}
		if (SSindex > 49) {
			SSindex = 49;
		}

		SS = SStable[SSindex]; // get new step size from table

		retArr[0] = Sn;
		retArr[1] = SS;
		retArr[2] = SSindex;
		return retArr;
	}

	/**
	 * 整型转数组
	 * 
	 * @param val
	 * @param array
	 * @param offset
	 */
	private static void longToIntBinary(long val, byte[] array, int offset) {
		array[offset] = (byte) (val & 0xff);
		array[offset + 1] = (byte) (val >>> 8 & 0xff);
		array[offset + 2] = (byte) (val >>> 16 & 0xff);
		array[offset + 3] = (byte) (val >>> 24 & 0xff);
	}

	private void byteToShortBinary(byte val, byte[] array, int offset) {
		array[offset] = (byte) (val & 0xff);
		array[offset + 1] = 0x0;
	}

	/**
	 * java中没有有符号类型,所以将超过0x7FFF的short类型保存为int类型。本方法提供了将有符号short类型
	 * 转换保存在字节数组中,占据两个字节
	 * 
	 * @param val
	 *            int
	 * @param array
	 *            byte[]
	 * @param offset
	 *            int
	 */
	private static void toShortBinary(int val, byte[] array, int offset) {
		array[offset] = (byte) (val & 0xff);
		array[offset + 1] = (byte) (val >>> 8 & 0xff);
	}

	public static void main(String[] args) {

		String inFile  = "D:\\file\\v3File\\0717262.V3";
		String outFile = "D:\\file\\wavFile\\0717262.wav";

		try {
			voxConvert(inFile, outFile, 1, 6000, 1);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

 

1
0
分享到:
评论
2 楼 happerlan 2016-12-01  
不对,是WAV怎么转换VOX?
1 楼 happerlan 2016-12-01  
请问怎么把WAV转为MP3.

相关推荐

    v3后缀名录音文件转换成wav格式录音

    电信坐席系统的外呼录音格式是v3格式,大多的播放器都不能播放该录音,该文档是将该录音转换成wav格式,以便于播放。

    java任意音频文件格式转mp3

    Java音频视频编码器,本文实例将任何音频格式转换为MP3格式 您还可以调整视频大小,更改其大小和比例等 本文实例实用于任何Windows,MacOS,Linux系统 附:完整jar项目,完善的demo,详细的注释,简单易操作

    工具使用方法V3录音格式转换.pdf

    在录音格式转换前,我们需要将录音文件的后缀名从 .v3 改成 .vox。这一步骤非常重要,因为 Cool Edit Pro 2.0 只能识别 .vox 格式的录音文件。我们可以使用小工具 refilesname 文件重命名 .zip 来批量改录音文件后缀...

    微信小程序语音silk格式转换pcm、MP3格式

    在这个场景下,我们经常会遇到不同音频格式之间的转换问题,比如将微信小程序中使用的silk格式转换为PCM或MP3格式。本文将详细介绍这个过程及其相关知识点。 一、silk格式 silk是Skype开发的一种高效音频编码格式,...

    Java微信支付V3实现退款功能,等操作.rar

    Java微信支付V3实现退款功能,等操作

    微信提现到零钱V3接口的对接java实现demo.rar

    微信提现到零钱V3接口的对接Java实现主要涉及到微信支付平台的相关开发,这是一个关键的金融功能,允许用户将资金从微信支付账户转移到他们的微信零钱。以下是对这个实现过程的详细说明: 1. **微信支付接口对接**...

    Java实现web在线预览office文档

    综上所述,Java实现Web在线预览Office文档和PDF文档主要涉及文件读取、内容转换、文档预览和服务器端的文件操作。通过合理选择和使用相应的库和工具,可以构建出稳定且高效的在线预览系统。在Linux环境下,结合开源...

    微信小程序语音silk转换pcm,wav格式

    微信小程序语音识别,转成一般各大接口所用的wav格式,有的语音接口可以使用pcm,不过听别人所建议转成wav的更好识别,这里面的是不需要安装操作的ffmpeg.exe和silk_v3_decoder.exe文件,所以应该都可以使用,比如...

    V3转wav wav转MP3 wav生成波形图工具类

    V3转wav wav转MP3 wav生成波形图工具类

    snmpv3 java实现

    java实现的简单网络管理协议!附件是整个工程,下载下来配置ip就可以运行,附有mib库,支持snmpV1,V2,V3版本协议!绝对是好资源,为了兼容移动的网络设备控制,研究了一段时间,现分享出来。不懂得可以找我

    Java 小程序V3支付 apiv3 后端代码实现与工具

    Java小程序V3支付APIv3后端代码实现与工具是一个重要的技术主题,涉及到现代电子商务和移动支付的关键技术。本文将深入探讨如何在Java环境中构建支持微信小程序V3支付的后端系统,以及相关的开发工具和最佳实践。 1...

    微信小程序录音解码silk v3音频文件 类似微信的amr和aud文件silk-v3-decoder.zip

    微信小程序录音解码silk v3音频文件 类似微信的amr和aud文件silk-v3-decoder.zip,[Skype Silk codec sdk]解码Silk v3音频文件(如微信AMR、AUD文件、QQ SLK文件)并转换为其他格式(如MP3)。批量转换支持。

    Java音频格式转换,支持amr、aud、slk、silk转成mp3-附件资源

    Java音频格式转换,支持amr、aud、slk、silk转成mp3-附件资源

    V3ToWavUtil.java

    很牛逼的算法,网上很难找到。我找了好久才找到的,希望大家支持~~很牛逼的算法,网上很难找到。我找了好久才找到的,希望大家支持~~

    Java实现微信企业付款到个人零钱简易demo.rar

    Java中可以使用`java.security.MessageDigest`和`javax.crypto.Mac`类来实现。 3. **构建请求参数**:根据微信支付接口文档,创建支付请求所需的参数,如商户订单号(out_trade_no)、金额(amount)、接收者OpenID...

    mp3和silk_v3格式互转.zip

    在IT领域,音频格式转换是一项常见的任务,尤其在微信等社交平台中,音频文件的兼容性和格式转换至关重要。本文将详细讲解如何将MP3格式的音频文件与silk_v3格式进行互转,以及微信未base64编码的语音转换过程。 ...

    微信支付V3版本JAVA服务端

    自己整理的微信支付V3版本javaDemo,放上自己的参数就可以调试,10分值不值自己看,能解决你当前遇到的大问题。

    javareport打印报表.rar(JavaReport-V3-Enterprise-Released)

    这个名为"javareport打印报表.rar"的压缩包包含的是JavaReport V3企业版的发布版本,根据描述,这个版本是经过验证可以正常使用的,相较于网络上其他可能存在问题的大体积版本,这个版本更加可靠。 JavaReport的...

    v3_to_wav_python.zip

    本代码使使用python中jpype加载java的jar包实现v3转wav的,linux和windows下都可以使用。 配置需要: windows或者linux需要配置java环境 需要安装 jpype pip install jpype 使用方式: 命令 :python jar包路径 v3...

    java微信支付(小程序),退款(V3版本)

    在开发Java微信支付(小程序)退款功能时,我们需要熟悉微信支付V3版本的API接口以及相关的业务流程。本文将深入探讨这一主题,帮助开发者理解如何实现这个功能。 首先,微信支付V3是微信官方推出的新一代支付接口...

Global site tag (gtag.js) - Google Analytics