linux下将pcm文件转换成wav文件——c语言

前言:我尝试在Linux下将 16k/16b/单通道 的pcm音频转换成wav文件,网上找了很多例子都无法达到效果。于是参考网上的一些资料,写了一个pcm to wav程序,分享给大家。


pcm2wav.c文件

/*
 * @Description:  
 * @version:  V1.0
 * @Company: 
 * @Author: Lipingping
 * @Date: 2019-09-19 11:30:20
 * @LastEditors: Lipingping
 * @LastEditTime: 2019-09-19 11:35:36
 */

#include "wavHeader.h"

long getFileSize(const char *filename)
{
    FILE *fp = fopen(filename, "r");
    if (!fp)
        return -1;
    fseek(fp, 0, SEEK_END);
    long size = ftell(fp);
    fclose(fp);
    return size;
}

void WriteWaveHeader(FILE *fptr, unsigned int num)
{
    WAVE_HEADER WaveHeader;
    FORMAT WaveFormat;
    DATA WaveData;
    /**************RIFF chunk 参数定义*********************/
    WaveHeader.riffid[0] = 'R'; //ChunkID
    WaveHeader.riffid[1] = 'I';
    WaveHeader.riffid[2] = 'F';
    WaveHeader.riffid[3] = 'F';
    WaveHeader.dwSize = num * BYTES_EACH_SAMPLE + 36; //ChunkSize

    WaveHeader.riffType[0] = 'W'; //Format
    WaveHeader.riffType[1] = 'A';
    WaveHeader.riffType[2] = 'V';
    WaveHeader.riffType[3] = 'E';

    /**************fmt chunk 参数定义**********************/
    WaveFormat.fccid[0] = 'f'; //SubChunkID
    WaveFormat.fccid[1] = 'm';
    WaveFormat.fccid[2] = 't';
    WaveFormat.fccid[3] = ' ';

    WaveFormat.dwSize = 16;                                                     //SubChunkSize
    WaveFormat.wFormatTag = 1;                                                  //AudioFormat
    WaveFormat.wChannels = CHANNEL_NUN;                                         //NumChannels
    WaveFormat.dwSamplesPerSec = SAMPLE_RATE;                                   //SampleRate
    WaveFormat.dwAvgBytePerSec = BYTES_EACH_SAMPLE * SAMPLE_RATE * CHANNEL_NUN; //ByteRate
    WaveFormat.wBlockAlign = BYTES_EACH_SAMPLE;                                 //BlockAlign
    WaveFormat.uiBitsPerSample = QUANTIZATION;                                  //BitsPerSample

    /**************Data chunk 参数定义**********************/
    WaveData.fccid[0] = 'd'; //BlockID
    WaveData.fccid[1] = 'a';
    WaveData.fccid[2] = 't';
    WaveData.fccid[3] = 'a';
    WaveData.dwSize = num * BYTES_EACH_SAMPLE; //BlockSize

    fwrite(&WaveHeader, sizeof(WAVE_HEADER), 1, fptr);
    fwrite(&WaveFormat, sizeof(FORMAT), 1, fptr);
    fwrite(&WaveData, sizeof(DATA), 1, fptr);
}

void convertPcm2Wav(const char *inputFile, const char *wavFile)
{
    char buffer[4 * 1024 * 1024] = {};

    FILE *frpcm, *fwwav;
    frpcm = fopen(inputFile, "rb");
    fwwav = fopen(wavFile, "wb");
    if (!frpcm || !fwwav)
    {
        printf("ERROR: failed to fopen.\n");
        exit(1);
    }

    int file_sizes = getFileSize(inputFile);
    int numOfword = fread(buffer, 1, file_sizes, frpcm);

    WriteWaveHeader(fwwav, numOfword);               //向fptr指向的wav文件写入wav标准头文件
    fwrite(buffer, sizeof(short), numOfword, fwwav); //向fptr指向的wav文件写入buffer指向的fcm源文件

    if (frpcm)
    {
        fclose(frpcm);
        frpcm = NULL;
    }

    if (fwwav)
    {
        fclose(fwwav);
        fwwav = NULL;
    }
}

int main(int argc, char const *argv[])
{
    if (argc != 3)
    {
        printf("ERROR: the number of parameters is short.\n  Usage: %s input.pcm output.wav\n", argv[0]);
        exit(1);
    }

    convertPcm2Wav(argv[1], argv[2]);
    return 0;
}

wavHeader.h文件:

/*
 * @Description:  
 * @version:  V1.0
 * @Company: 
 * @Author: Lipingping
 * @Date: 2019-09-19 11:29:07
 * @LastEditors: Lipingping
 * @LastEditTime: 2019-09-19 11:35:24
 */
#ifndef _WAV_H
#define _WAV_H

#include <stdio.h>
#include <stdlib.h>

#define SAMPLE_RATE 16000
#define QUANTIZATION 16
#define BYTES_EACH_SAMPLE 2
#define CHANNEL_NUN 1
#define FORMAT_TAG 1

struct RIFF_CHUNK
{
    char riffid[4];
    unsigned int dwSize;
    char riffType[4];
};
typedef struct RIFF_CHUNK WAVE_HEADER;

struct FORMAT_CHUNK
{
    char fccid[4];
    unsigned int dwSize;
    short wFormatTag;
    short wChannels;
    unsigned int dwSamplesPerSec;
    unsigned int dwAvgBytePerSec;
    short wBlockAlign;
    short uiBitsPerSample;
};
typedef struct FORMAT_CHUNK FORMAT;

struct DATA_CHUNK
{
    char fccid[4];
    unsigned int dwSize;
};

typedef struct DATA_CHUNK DATA;

#endif

 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、Java实现wav音频文件转换pcm音频文件(AudioUtils.java) 2、Java实现播放pcm音频文件PCMPlay.java) WAVwav是一种无损的音频文件格式,WAV符合 PIFF(Resource Interchange File Format)规范。所有的WAV都有一个文件头,这个文件头音频流的编码参数。WAV对音频流的编码没有硬性规定,除了PCM之外,还有几乎所有支持ACM规范的编码都可以为WAV的音频流进行编码。 PCM:PCM(Pulse Code Modulation----脉码调制录音)。所谓PCM录音就是将声音等模拟信号变符号化的脉冲列,再予以记录。PCM信号是由[1]、[0]等符号构的数字信号,而未经过任何编码和压缩处理。与模拟信号比,它不易受传送系统的杂波及失真的影响。动态范围宽,可得到音质相当好的影响效果。 简单来说:wav是一种无损的音频文件格式,pcm是没有压缩的编码方式。 WAVPCM的关系 WAV可以使用多种音频编码来压缩其音频流,不过我们常见的都是音频流被PCM编码处理的WAV,但这不表示WAV只能使用PCM编码,MP3编码同样也可以运用在WAV中,和AVI一样,只要安装好了相应的Decode,就可以欣赏这些WAV了。在Windows平台下,基于PCM编码的WAV是被支持得最好的音频格式,所有音频软件都能完美支持,由于本身可以达到较高的音质的要求,因此,WAV也是音乐编辑创作的首选格式,适合保存音乐素材。因此,基于PCM编码的WAV被作为了一种中介的格式,常常使用在其他编码的相互转换之中,例如MP3转换WMA。 简单来说:pcm是无损wav文件中音频数据的一种编码方式,但wav还可以用其它方式编码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值