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(); } } }
相关推荐
电信坐席系统的外呼录音格式是v3格式,大多的播放器都不能播放该录音,该文档是将该录音转换成wav格式,以便于播放。
Java音频视频编码器,本文实例将任何音频格式转换为MP3格式 您还可以调整视频大小,更改其大小和比例等 本文实例实用于任何Windows,MacOS,Linux系统 附:完整jar项目,完善的demo,详细的注释,简单易操作
在录音格式转换前,我们需要将录音文件的后缀名从 .v3 改成 .vox。这一步骤非常重要,因为 Cool Edit Pro 2.0 只能识别 .vox 格式的录音文件。我们可以使用小工具 refilesname 文件重命名 .zip 来批量改录音文件后缀...
在这个场景下,我们经常会遇到不同音频格式之间的转换问题,比如将微信小程序中使用的silk格式转换为PCM或MP3格式。本文将详细介绍这个过程及其相关知识点。 一、silk格式 silk是Skype开发的一种高效音频编码格式,...
Java微信支付V3实现退款功能,等操作
微信提现到零钱V3接口的对接Java实现主要涉及到微信支付平台的相关开发,这是一个关键的金融功能,允许用户将资金从微信支付账户转移到他们的微信零钱。以下是对这个实现过程的详细说明: 1. **微信支付接口对接**...
综上所述,Java实现Web在线预览Office文档和PDF文档主要涉及文件读取、内容转换、文档预览和服务器端的文件操作。通过合理选择和使用相应的库和工具,可以构建出稳定且高效的在线预览系统。在Linux环境下,结合开源...
微信小程序语音识别,转成一般各大接口所用的wav格式,有的语音接口可以使用pcm,不过听别人所建议转成wav的更好识别,这里面的是不需要安装操作的ffmpeg.exe和silk_v3_decoder.exe文件,所以应该都可以使用,比如...
V3转wav wav转MP3 wav生成波形图工具类
java实现的简单网络管理协议!附件是整个工程,下载下来配置ip就可以运行,附有mib库,支持snmpV1,V2,V3版本协议!绝对是好资源,为了兼容移动的网络设备控制,研究了一段时间,现分享出来。不懂得可以找我
Java小程序V3支付APIv3后端代码实现与工具是一个重要的技术主题,涉及到现代电子商务和移动支付的关键技术。本文将深入探讨如何在Java环境中构建支持微信小程序V3支付的后端系统,以及相关的开发工具和最佳实践。 1...
微信小程序录音解码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中可以使用`java.security.MessageDigest`和`javax.crypto.Mac`类来实现。 3. **构建请求参数**:根据微信支付接口文档,创建支付请求所需的参数,如商户订单号(out_trade_no)、金额(amount)、接收者OpenID...
在IT领域,音频格式转换是一项常见的任务,尤其在微信等社交平台中,音频文件的兼容性和格式转换至关重要。本文将详细讲解如何将MP3格式的音频文件与silk_v3格式进行互转,以及微信未base64编码的语音转换过程。 ...
自己整理的微信支付V3版本javaDemo,放上自己的参数就可以调试,10分值不值自己看,能解决你当前遇到的大问题。
这个名为"javareport打印报表.rar"的压缩包包含的是JavaReport V3企业版的发布版本,根据描述,这个版本是经过验证可以正常使用的,相较于网络上其他可能存在问题的大体积版本,这个版本更加可靠。 JavaReport的...
本代码使使用python中jpype加载java的jar包实现v3转wav的,linux和windows下都可以使用。 配置需要: windows或者linux需要配置java环境 需要安装 jpype pip install jpype 使用方式: 命令 :python jar包路径 v3...
在开发Java微信支付(小程序)退款功能时,我们需要熟悉微信支付V3版本的API接口以及相关的业务流程。本文将深入探讨这一主题,帮助开发者理解如何实现这个功能。 首先,微信支付V3是微信官方推出的新一代支付接口...