WAV相关:从PCM16 Little Endian数据转WAV文件
数据格式
[0.0, -0.0, -0.0, 0.0, 0.0, 0.0, 5.960464477539063e-08, 5.960464477539063e-08, 1.1920928955078125e-07, 1.7881393432617188e-07, 2.384185791015625e-07,.....]
转换方法:c#
- using System;
- using System.IO;
- using System.Text;
- namespace deserialfromPCMData
- {
- public static class BinaryWriterExtensions
- {
- private const int HeaderSize = ;
- private const int Hz = ; //frequency or sampling rate
- private const float RescaleFactor = ; //to convert float to Int16
- public static void AppendWaveData<T>(this T stream, float[] buffer)
- where T : Stream
- {
- if (stream.Length > HeaderSize)
- {
- stream.Seek(, SeekOrigin.End);
- }
- else
- {
- stream.SetLength(HeaderSize);
- stream.Position = HeaderSize;
- }
- // rescale
- var floats = Array.ConvertAll(buffer, x => (short)(x * RescaleFactor));
- // Copy to bytes
- var result = new byte[floats.Length * sizeof(short)];
- Buffer.BlockCopy(floats, , result, , result.Length);
- // write to stream
- stream.Write(result, , result.Length);
- // Update Header
- UpdateHeader(stream);
- }
- public static void UpdateHeader(Stream stream)
- {
- var writer = new BinaryWriter(stream);
- writer.Seek(, SeekOrigin.Begin);
- writer.Write(Encoding.ASCII.GetBytes("RIFF")); //RIFF marker. Marks the file as a riff file. Characters are each 1 byte long.
- writer.Write((int)(writer.BaseStream.Length - )); //file-size (equals file-size - 8). Size of the overall file - 8 bytes, in bytes (32-bit integer). Typically, you'd fill this in after creation.
- writer.Write(Encoding.ASCII.GetBytes("WAVE")); //File Type Header. For our purposes, it always equals "WAVE".
- writer.Write(Encoding.ASCII.GetBytes("fmt ")); //Mark the format section. Format chunk marker. Includes trailing null.
- writer.Write(); //Length of format data. Always 16.
- writer.Write((short)); //Type of format (1 is PCM, other number means compression) . 2 byte integer. Wave type PCM
- writer.Write((short)); //Number of Channels - 2 byte integer
- writer.Write(Hz); //Sample Rate - 32 byte integer. Sample Rate = Number of Samples per second, or Hertz.
- writer.Write(Hz * * ); // sampleRate * bytesPerSample * number of channels, here 16000*2*1.
- writer.Write((short)( * )); //channels * bytesPerSample, here 1 * 2 // Bytes Per Sample: 1=8 bit Mono, 2 = 8 bit Stereo or 16 bit Mono, 4 = 16 bit Stereo
- writer.Write((short)); //Bits per sample (BitsPerSample * Channels) ?? should be 8???
- writer.Write(Encoding.ASCII.GetBytes("data")); //"data" chunk header. Marks the beginning of the data section.
- writer.Write((int)(writer.BaseStream.Length - HeaderSize)); //Size of the data section. data-size (equals file-size - 44). or NumSamples * NumChannels * bytesPerSample ??
- }
- } //end of class
- }
- using System;
- using System.IO;
- using System.Text;
- namespace deserialfromPCMData
- {
- class SaveAudioStreamToWav
- {
- static void Main(string[] args)
- {
- Stream instream = File.OpenRead(@"g:\sample.txt");
- BufferedStream bfs = new BufferedStream(instream);
- byte[] array = new byte[bfs.Length];
- instream.Read(array, , array.Length);
- string str = Encoding.Default.GetString(array);
- var StreamSample = str.Substring(, str.Length - ).Split(',');
- var floatsArray = new float[StreamSample.Length];
- floatsArray = Array.ConvertAll(StreamSample, x => (float)Convert.ToDouble(x));
- using (var stream = new FileStream(@"g:\sample2.wav", FileMode.Create, FileAccess.ReadWrite))
- {
- stream.AppendWaveData(floatsArray);
- }
- }
- }
- }
Java方法:
- package com;
- import com.sun.media.sound.WaveFileWriter;
- import org.junit.Test;
- import javax.sound.sampled.AudioFileFormat;
- import javax.sound.sampled.AudioFormat;
- import javax.sound.sampled.AudioInputStream;
- import java.io.*;
- import java.util.Arrays;
- //https://stackoverflow.com/questions/3599378/java-read-wav-file-as-a-float-array
- //
- //https://stackoverflow.com/questions/26824663/how-do-i-use-audio-sample-data-from-java-sound
- //
- //https://stackoverflow.com/questions/4440015/java-pcm-to-wav
- public class TestWavFile {
- //采样率16kHz
- private float SAMPLING_RATE = 16000;
- private float sampleSizeBits = 16;
- //把short(2字节)拆解成字节流byte[2]
- public byte[] get16BitPcm(short[] data) {
- byte[] resultData = new byte[2 * data.length];
- int iter = 0;
- for (short sample : data) {
- resultData[iter++] = (byte)(sample & 0x00ff);
- resultData[iter++] = (byte)((sample & 0xff00) >>> 8);
- }
- return resultData;
- }
- @Test
- public void test() throws IOException{
- BufferedReader bufferedReader = new BufferedReader(
- new InputStreamReader(
- new FileInputStream("g:/sample.txt")));
- StringBuffer buffer = new StringBuffer();
- String line = null;
- while ( (line = bufferedReader.readLine()) != null)
- {
- buffer.append(line);
- }
- int len = buffer.length();
- String raw = buffer.substring(1,len-1);
- Short[] data = Arrays.stream(raw.split(","))
- .map(track->( Float.valueOf(track) * 0x7fff ))
- .map(item->item.shortValue()).toArray(Short[]::new);
- short [] frameData = new short[data.length];
- for (int i = 0; i< data.length; i++) {
- frameData[i] = data[i];
- }
- WaveFileWriter writer = new WaveFileWriter();
- FileOutputStream outStream = new FileOutputStream("g:/sample.wav");
- //(采样率,比特位,通道,是否有符号,大小端)
- //比特位:short 2个字节 2*8 = 16
- //是否有符号:是否有负数
- //
- AudioFormat format = new AudioFormat(SAMPLING_RATE,16,1,true,false);
- AudioInputStream audioInputStream = new AudioInputStream(new ByteArrayInputStream(get16BitPcm(frameData)), format, frameData.length);
- writer.write(audioInputStream, AudioFileFormat.Type.WAVE, outStream);
- }
- }
java封装工具:
- import com.fasterxml.jackson.databind.ObjectMapper;
- import com.sun.media.sound.WaveFileWriter;
- import lombok.Data;
- import lombok.extern.slf4j.Slf4j;
- import org.apache.commons.lang3.ArrayUtils;
- import javax.sound.sampled.AudioFileFormat;
- import javax.sound.sampled.AudioFormat;
- import javax.sound.sampled.AudioInputStream;
- import java.io.ByteArrayInputStream;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.nio.ByteBuffer;
- import java.util.Arrays;
- @Slf4j
- public final class WavFileGenerator {
- //采样率16kHz
- private float SAMPLING_RATE = 16000;
- private float sampleSizeBits = 16;
- private int HeaderSize = 44;
- //frequency or sampling rate
- private int Hz = 16_000;
- private byte[] values;
- public WavFileGenerator(String ctx)
- {
- this(convert(ctx));
- }
- public WavFileGenerator(String []values)
- {
- convert(toPrimitive(Arrays.asList(values).stream().map(Float::valueOf).toArray(size -> new Float[size])));
- }
- public WavFileGenerator(short[] values)
- {
- /*sizeof(short) was 2 bytes in java platform*/
- byte[] result = new byte[values.length * 2];
- // 1short = 2bytes
- int iter = 0;
- for (short sample : values) {
- result[iter++] = (byte)(sample & 0x00ff);
- result[iter++] = (byte)((sample & 0xff00) >>> 8);
- }
- this.values = result;
- }
- public WavFileGenerator(float[] floatValues)
- {
- this(convert(floatValues));
- }
- static float[] toPrimitive(Float[] floats)
- {
- return ArrayUtils.toPrimitive(floats);
- }
- public static final short[] convert(float[] values)
- {
- //PCM 16bit little endian
- short[] shortValues = new short[values.length];
- for (int i = 0; i < values.length; i++) {
- float value = values[i];
- shortValues[i] = (short) (value < 0 ? value* 0x8000 : value*0x7fff);
- }
- return shortValues;
- }
- public static final float[] convert(String ctx)
- {
- ObjectMapper objectMapper = new ObjectMapper();
- try {
- Float[] data = objectMapper.readValue(ctx, Float[].class);
- return toPrimitive(data);
- } catch (IOException e) {
- log.error("转换出错:{}",e);
- }
- return new float[0];
- }
- public byte[] getFmtChunk()
- {
- return null;
- }
- public byte[] getDataChunk()
- {
- return values;
- }
- void builder()
- {
- }
- public ByteBuffer getAudioStream()
- {
- return null;
- }
- public void saveFile(String dest) throws IOException {
- WaveFileWriter writer = new WaveFileWriter();
- FileOutputStream outStream = new FileOutputStream(dest);
- AudioFormat format = new AudioFormat(SAMPLING_RATE,16,1,true,false);
- int frames = values.length / 2;
- AudioInputStream audioInputStream = new AudioInputStream(new ByteArrayInputStream(values), format, frames);
- writer.write(audioInputStream, AudioFileFormat.Type.WAVE, outStream);
- audioInputStream.close();
- outStream.close();
- }
- }
运行以上两个文件,最终会成功wav文件。
WAV相关:从PCM16 Little Endian数据转WAV文件的更多相关文章
- 【应用】:shell crontab定时生成oracle表的数据到txt文件,并上传到ftp
一.本人环境描述 1.oracle服务端装在win7 32位上,oracle版本为10.2.0.1.0 2.Linux为centos6.5 32位,安装在Oracle VM Vir ...
- HTML5操作麦克风获取音频数据(WAV)的一些基础技能
基于HTML5的新特性,操作其实思路很简单. 首先通过navigator获取设备,然后通过设备监听语音数据,进行原始数据采集. 相关的案例比较多,最典型的就是链接:https://developer. ...
- pcm数据生成wav文件
Qt由pcm数据生成wav文件 void AudioGrabber::saveWave(const QString &fileName, const QByteArray &raw, ...
- C#中使用WavHelper保存录音数据为wav文件
C#将录音数据文件保存为wav格式文件,这里使用到的是WavHelper工具类. WavHelper工具类: using System; using System.Collections.Generi ...
- php添加数据到xml文件的例子
php添加数据到xml文件中 时间:2015-12-17 06:30:37来源:网络 导读:php添加数据到xml文件中 xml文件:stu.xml: 复制代码代码如下: <?xml ver ...
- MYSQL数据库导入大数据量sql文件失败的解决方案
1.在讨论这个问题之前首先介绍一下什么是"大数据量sql文件". 导出sql文件.选择数据库-----右击选择"转储SQL文件"-----选择"结构和 ...
- [大数据]-Fscrawler导入文件(txt,html,pdf,worf...)到Elasticsearch5.3.1并配置同义词过滤
fscrawler是ES的一个文件导入插件,只需要简单的配置就可以实现将本地文件系统的文件导入到ES中进行检索,同时支持丰富的文件格式(txt.pdf,html,word...)等等.下面详细介绍下f ...
- Python:将爬取的网页数据写入Excel文件中
Python:将爬取的网页数据写入Excel文件中 通过网络爬虫爬取信息后,我们一般是将内容存入txt文件或者数据库中,也可以写入Excel文件中,这里介绍关于使用Excel文件保存爬取到的网页数据的 ...
- 30G 上亿数据的超大文件,如何快速导入生产环境?
Hello,大家好,我是楼下小黑哥~ 如果给你一个包含一亿行数据的超大文件,让你在一周之内将数据转化导入生产数据库,你会如何操作? 上面的问题其实是小黑哥前段时间接到一个真实的业务需求,将一个老系统历 ...
随机推荐
- 2019-2020-1 20199312 《Linux内核原理与分析》 第九周作业
进程调度 1.中断:起到切出进程指令流的作用.中断处理程序是与进程无关的内核指令流.中断类型: 硬中断:可屏蔽中断和不可屏蔽中断.高电平说明有中断请求. 软中断/异常: 故障:出问题,但可以恢复到当前 ...
- Appium环境搭建(Mac)
为什么选择Mac做自动化测试? 既可以做iOS端的测试也可以进行Android端测试 Mac运行效率相对于Win要高很多,可以真正发挥appium的功能 环境依赖 Node.js Appium App ...
- 关于跨域介绍和djiago解决跨域问题
什么是跨域? 跨域,指的是浏览器不能执行其他网站的脚本.它是由浏览器的同源策略造成的,是浏览器对javascript施加的安全限制. 什么是同源策略? 同源策略又分为以下两种 DOM同源策略:禁止对不 ...
- CocoaPods加载第三方库
http://code4app.com/article/cocoapods-install-usage
- C# 对IOC的理解 依赖的转移
原文:https://blog.csdn.net/huwei2003/article/details/40022011 系统 可方便的替换 日志类 自己的理解: 依赖接口,日志的实例化 不直接写在依赖 ...
- 最长公共子序列 DP
class Solution: def LCS(self,A,B): if not A or not B: #边界处理 return 0 dp = [[0 for _ in range(len(B)+ ...
- mpvue开发小程序
实例生命周期 beforeCreate created beforeMount mounted beforeUpdate updated activated deactivated beforeDes ...
- SDOI2015做题记录
由于我懒,并且这里面除了D2T3恶心以外都不难写,所以很多代码都没写-- 排序 对于某一个合法的操作序列(操作序列定义为每次交换的两组数),可以随意交换顺序,仍然合法.所以对于一个操作集合,答案就加\ ...
- ES6——class类继承(读书笔记)
前言 我一定是一个傻子,昨天这篇文章其实我已经写好了一半了,但是我没有保存 这是学习ES6的过程,我没有系统的看完阮大大的书.零零散散的,很多功能知道,但是没有实际的用过 看了几遍,总是看前面几章,所 ...
- Hadoop(一)—— 启动与基本使用
一.安装&启动 安装 下载hadoop2.7.2 https://archive.apache.org/dist/hadoop/common/hadoop-2.7.2/ 2.7.2-官方文档 ...