社区首页 >问答首页 >java pcm转wav

java pcm转wav
EN

Stack Overflow用户
提问于 2010-12-14 14:09:53
回答 5查看 10.3K关注 0票数 4

我有一个pcm文件,我想把它转换成wav文件。

有没有合适的api或代码来做这件事?

EN

回答 5

Stack Overflow用户

发布于 2013-08-28 14:03:17

这是我的代码

代码语言:javascript
代码运行次数:0
复制
/**
 * Write PCM data as WAV file
 * @param os  Stream to save file to
 * @param pcmdata  8 bit PCMData
 * @param srate  Sample rate - 8000, 16000, etc.
 * @param channel Number of channels - Mono = 1, Stereo = 2, etc..
 * @param format Number of bits per sample (16 here)
 * @throws IOException
 */
public void PCMtoFile(OutputStream os, short[] pcmdata, int srate, int channel, int format) throws IOException {
    byte[] header = new byte[44];
    byte[] data = get16BitPcm(pcmdata);

    long totalDataLen = data.length + 36;
    long bitrate = srate * channel * format;

    header[0] = 'R'; 
    header[1] = 'I';
    header[2] = 'F';
    header[3] = 'F';
    header[4] = (byte) (totalDataLen & 0xff);
    header[5] = (byte) ((totalDataLen >> 8) & 0xff);
    header[6] = (byte) ((totalDataLen >> 16) & 0xff);
    header[7] = (byte) ((totalDataLen >> 24) & 0xff);
    header[8] = 'W';
    header[9] = 'A';
    header[10] = 'V';
    header[11] = 'E';
    header[12] = 'f'; 
    header[13] = 'm';
    header[14] = 't';
    header[15] = ' ';
    header[16] = (byte) format; 
    header[17] = 0;
    header[18] = 0;
    header[19] = 0;
    header[20] = 1; 
    header[21] = 0;
    header[22] = (byte) channel; 
    header[23] = 0;
    header[24] = (byte) (srate & 0xff);
    header[25] = (byte) ((srate >> 8) & 0xff);
    header[26] = (byte) ((srate >> 16) & 0xff);
    header[27] = (byte) ((srate >> 24) & 0xff);
    header[28] = (byte) ((bitrate / 8) & 0xff);
    header[29] = (byte) (((bitrate / 8) >> 8) & 0xff);
    header[30] = (byte) (((bitrate / 8) >> 16) & 0xff);
    header[31] = (byte) (((bitrate / 8) >> 24) & 0xff);
    header[32] = (byte) ((channel * format) / 8); 
    header[33] = 0;
    header[34] = 16; 
    header[35] = 0;
    header[36] = 'd';
    header[37] = 'a';
    header[38] = 't';
    header[39] = 'a';
    header[40] = (byte) (data.length  & 0xff);
    header[41] = (byte) ((data.length >> 8) & 0xff);
    header[42] = (byte) ((data.length >> 16) & 0xff);
    header[43] = (byte) ((data.length >> 24) & 0xff);

    os.write(header, 0, 44);
    os.write(data);
    os.close();
}

编辑: 2016-01-11

代码语言:javascript
代码运行次数:0
复制
public byte[] get16BitPcm(short[] data) {
    byte[] resultData = new byte[2 * data.length];
    int iter = 0;
    for (double sample : data) {
        short maxSample = (short)((sample * Short.MAX_VALUE));
        resultData[iter++] = (byte)(maxSample & 0x00ff);
        resultData[iter++] = (byte)((maxSample & 0xff00) >>> 8);
    }
    return resultData;
}
票数 7
EN

Stack Overflow用户

发布于 2016-07-29 05:33:11

这应该很容易做到,因为WAV = Metadata + PCM (按照这个顺序)。这应该是可行的:

代码语言:javascript
代码运行次数:0
复制
private void rawToWave(final File rawFile, final File waveFile) throws IOException {

byte[] rawData = new byte[(int) rawFile.length()];
DataInputStream input = null;
try {
    input = new DataInputStream(new FileInputStream(rawFile));
    input.read(rawData);
} finally {
    if (input != null) {
        input.close();
    }
}

DataOutputStream output = null;
try {
    output = new DataOutputStream(new FileOutputStream(waveFile));
    // WAVE header
    // see http://ccrma.stanford.edu/courses/422/projects/WaveFormat/
    writeString(output, "RIFF"); // chunk id
    writeInt(output, 36 + rawData.length); // chunk size
    writeString(output, "WAVE"); // format
    writeString(output, "fmt "); // subchunk 1 id
    writeInt(output, 16); // subchunk 1 size
    writeShort(output, (short) 1); // audio format (1 = PCM)
    writeShort(output, (short) 1); // number of channels
    writeInt(output, 44100); // sample rate
    writeInt(output, RECORDER_SAMPLERATE * 2); // byte rate
    writeShort(output, (short) 2); // block align
    writeShort(output, (short) 16); // bits per sample
    writeString(output, "data"); // subchunk 2 id
    writeInt(output, rawData.length); // subchunk 2 size
    // Audio data (conversion big endian -> little endian)
    short[] shorts = new short[rawData.length / 2];
    ByteBuffer.wrap(rawData).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(shorts);
    ByteBuffer bytes = ByteBuffer.allocate(shorts.length * 2);
    for (short s : shorts) {
        bytes.putShort(s);
    }

    output.write(fullyReadFileToBytes(rawFile));
} finally {
    if (output != null) {
        output.close();
    }
}
}
byte[] fullyReadFileToBytes(File f) throws IOException {
int size = (int) f.length();
byte bytes[] = new byte[size];
byte tmpBuff[] = new byte[size];
FileInputStream fis= new FileInputStream(f);
try { 

    int read = fis.read(bytes, 0, size);
    if (read < size) {
        int remain = size - read;
        while (remain > 0) {
            read = fis.read(tmpBuff, 0, remain);
            System.arraycopy(tmpBuff, 0, bytes, size - remain, read);
            remain -= read;
        } 
    } 
}  catch (IOException e){
    throw e;
} finally { 
    fis.close();
} 

return bytes;
} 
private void writeInt(final DataOutputStream output, final int value) throws IOException {
output.write(value >> 0);
output.write(value >> 8);
output.write(value >> 16);
output.write(value >> 24);
}

private void writeShort(final DataOutputStream output, final short value) throws IOException {
output.write(value >> 0);
output.write(value >> 8);
}

private void writeString(final DataOutputStream output, final String value) throws IOException {
for (int i = 0; i < value.length(); i++) {
    output.write(value.charAt(i));
    }
}

如何使用

它使用起来非常简单。就像这样叫它:

代码语言:javascript
代码运行次数:0
复制
File f1 = new File("/sdcard/44100Sampling-16bit-mono-mic.pcm"); // The location of your PCM file
File f2 = new File("/sdcard/44100Sampling-16bit-mono-mic.wav"); // The location where you want your WAV file
try {
rawToWave(f1, f2);
} catch (IOException e) {
e.printStackTrace();
}

这一切是如何工作的

如您所见,WAV报头是WAV和PCM文件格式之间的唯一区别。假设您正在录制16位PCM单声道音频(根据您的代码,您是)。rawToWave函数只是巧妙地向WAV文件添加了头文件,以便音乐播放器知道在打开文件时会发生什么,然后在头文件之后,它只是从最后一位开始写入PCM数据。

Cool Tip

如果你想改变你声音的音调,或者制作一个变音应用,你所要做的就是增加/减少代码中writeInt(output, 44100); // sample rate的值。减少它将告诉玩家以不同的速率播放它,从而改变输出音高。只是一点额外的“很高兴知道”的事情。:)

票数 4
EN

Stack Overflow用户

发布于 2018-03-23 21:22:19

我还不能发表评论,但请注意,devflow答案中的get16BitPcm方法正在奇怪地缩放输入数据。如果您已经有16位pcm数据要写入wav文件,则该方法应如下所示:

代码语言:javascript
代码运行次数:0
复制
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;
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4440015

复制
相关文章
Linux是否能在8位MCU上运行?
我们经常可以看到初学者在单片机论坛中询问他们是否可以在他们微不足道的小的8位微机中运行Linux。这些问题的结果通常是带来笑声。我们也经常看到,在Linux论坛中,询问Linux运行的最低要求是什么。常见的答案是Linux需要一个32位架构和一个MMU(存储器管理单元),并至少1MB的RAM来满足内核的需求。
刘盼
2020/04/01
1.8K0
idea配置tomcat服务器运行项目_idea添加tomcat服务器
从Eclipse转IDEA后面对的第一个问题,就是要为IDEA配置tomcat服务,否则不可用。那么,
全栈程序员站长
2022/11/02
3.5K0
安卓应用将能在苹果/windows设备上运行?
前 言 / 2022.8.29 昨日,谷歌宣称正在推出新的跨设备 SDK ,其中包含开发者需要的工具,以使他们的应用能在安卓设备上运行良好。好家伙,这是新时代要来了? 01 谷歌即将推出跨设备 SDK  什么是 SDK ? 简单介绍一下,又称软件开发工具包,一般都是一些软件工程师为特定的软件包、软件框架、硬件平台、操作系统等建立应用软件时的开发工具的集合。 通俗点也可以理解为由第三方服务商提供的实现软件产品某项功能的工具包。 而这次推出的跨设备 SDK ,主要目的就是让开发者们的应用能在安卓设备上良好运
老九君
2022/08/31
1.4K0
安卓应用将能在苹果/windows设备上运行?
腾讯云服务器上tomcat配置文件参数详解
<Connector port="8080" protocol="HTTP/1.1"
用户8639654
2021/08/04
5.8K0
ubuntu服务器上配置tomcat
嗯,最近想在自己的腾讯云服务器上跑个项目玩玩,由于服务器是重装的系统,所以,只能自己手动装tomcat。 不过,tomcat是基于java的,必须又java环境tomcat才能够使用,因此首先要做的是安装jdk。
roobtyan
2019/02/21
2.3K0
tomcat学习 | DefaultServlet | tomcat做文件服务器
小刀这几天在追斗罗大陆,看到唐门,也突然有一种想组建类似的想法,我们有内门,有外门,有长老等等,让学习变成游戏,有想法的,或者想和小刀聊一聊的,加小刀微信吧: best396975802
微笑的小小刀
2019/09/03
1.4K0
tomcat学习 | DefaultServlet | tomcat做文件服务器
Nginx 部署与集群
前面已经将 Nginx 的大部分内容进行了讲解,我们都知道了 Nginx 在高并发场景和处理静态资源是非常高性能的,但是在实际项目中除了静态资源还有就是后台业务代码模块,一般后台业务都会被部署在 Tomcat、weblogic 或者是 websphere 等 Web 服务器上。那么如何使用 Nginx 接收用户的请求并把请求转发到后台 Web 服务器?
用户9615083
2022/12/25
9850
Nginx 部署与集群
一个服务器上运行多个tomcat,显示总启动某一个特定tomcat
今天想在公司的一个服务器上加一个 tomcat运行自己的工程做测试,因为此服务器上之前有一个tomcat,为了不冲突,又重新下载了一个。然后就直接./startup.sh启动了,一直启动失败,也看不到具体报错信息。于是,找到tomcat/bin/catalina,sh这个文件,直接./catalina.sh run 运行这个脚本,这样就能看到具体的报错信息了。
全栈程序员站长
2022/06/30
1K0
一个服务器上运行多个tomcat,显示总启动某一个特定tomcat
docker构建自定义镜像
要构建一个镜像,第一步准备所需要的文件,第二步编写Dockerfile文件,比如我现在构建一个java web镜像
用户2409797
2019/02/25
1.2K0
Tomcat搭建文件服务器
①. 进入tomcat下的conf目录,找到server.xml文件,在Host标签下加入如下标签     path:表示对外映射的路径,     docBase:物理磁盘路径,可以是绝对路径,也可以是相对路径,甚至是共享磁盘目录     debug参数不用管     reloadable表示是否重新加载 <Context path="/files" docBase="D://files" debug="0" reloadable="true"/> 访问http://localhost/files/a.t
用户1215919
2018/02/27
3.1K0
堡垒机远程不上服务器的原因 连接不上怎么办?
堡垒机对于企业的运维系统的安全审计,和管理控制功能是显而易见的,堡垒机也成了许多的大中小型企业必备的网络服务项目之一,但是在使用堡垒机的过程当中,总是会出现一些操作上的问题以及使用中的问题。出现这些问题要及时解决,否则会给堡垒机的作用带来不好的影响,堡垒机远程不上服务器是怎么回事呢?
用户8715145
2021/12/11
14.2K0
Docker运行Tomcat
一. 首先在我们的服务器上安装Docker。 安装教程-任意门 我就罗列一下主要的几步:
jwangkun
2021/12/23
8900
在服务器上运行Python项目
Anaconda是一个开源Python发行版本,包括Python 和很多常用库如Numpy、Matplotlib等,对小白很方便
Minerva
2020/05/25
4.1K0
云游戏连接不上服务器是什么原因?云游戏连接不上服务器怎么处理?
现在的年轻人对于网络游戏都是非常热衷的,在学习或者工作休闲之余玩上两把游戏可以充分放松自己的心情以及压力,也是因此现在网络游戏越来越盛行,游戏虽然有很多弊端但是也是有很多好处的,不然国家也不会放任游戏产业不管了。想要玩游戏就需要拥有设备,比如常用的手机或者电脑都可以玩各种游戏,现在还推出了云游戏平台,不需要高配置的设备就可以轻松玩转大型游戏,那么云游戏连接不上服务器是什么原因?云游戏连接不上服务器怎么处理?
用户8715145
2021/10/22
9.9K0
Jenkins+Ansible 实现自动化运维 DevOps
鄙人刚开始选的war包 结果折腾了好久 要么拿不到PATH命令 要么拿到命令没有授权 很脑袋疼 直接选对应包 一键轻松
Parker
2020/07/21
3K2
docker 下安装 nginx / apache / tomcat 常用服务器
安装 nginx 服务器 访问 nginx Tags | Docker Hub 可查看详情 https://hub.docker.com/_/nginx?tab=tags 这里我们拉取官方最新镜像:
acc8226
2022/05/17
5200
docker 下安装 nginx / apache / tomcat 常用服务器
谁说程序不能在指定地址运行?
我们知道程序在每次运行的时候地址都是不一样的,linux之所以有这样的设计也许是为了安全性考虑,不利于黑客的攻击。
刘盼
2020/06/30
7410
Nginx---动静分离
我们都知道了Nginx在高并发场景和处理静态资源是非常高性能的,但是在实际项目中除了静态资源还有就是后台业务代码模块,一般后台业务都会被部署在Tomcat,weblogic或者是websphere等web服务器上。那么如何使用Nginx接收用户的请求并把请求转发到后台web服务器?
大忽悠爱学习
2021/12/07
5520
Nginx---动静分离
springboot在tomcat运行
使用外部tomcat部署时,为排除springboot内置的tomcat,修改pom.xml文件,增加
似水的流年
2019/12/06
9790
点击加载更多

相似问题

Excel VBA - AdvancedFilter

28

vba应复制整个列

12

excel VBA复制粘贴仅行A列?

12

Excel VBA复制特定列

30

Excel VBA:复制大量列

11
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文