语音文件pcm转wav

时间:2021-01-16 19:45:10



/* Save 16 bit PCM 44.1kHz stereo data into a WAV-File, so common media

   players will recognize it.

*/




#include <unistd.h>

#include <stdint.h>

#include <stdbool.h>

#include <stdio.h>

#include <stdint.h>

#include <assert.h>


#include <sys/stat.h>


#include <machine/endian.h>

#ifdef __APPLE__

#include <libkern/OSByteOrder.h>


#define htobe16(x) OSSwapHostToBigInt16(x)

#define htole16(x) OSSwapHostToLittleInt16(x)

#define be16toh(x) OSSwapBigToHostInt16(x)

#define le16toh(x) OSSwapLittleToHostInt16(x)


#define htobe32(x) OSSwapHostToBigInt32(x)

#define htole32(x) OSSwapHostToLittleInt32(x)

#define be32toh(x) OSSwapBigToHostInt32(x)

#define le32toh(x) OSSwapLittleToHostInt32(x)


#define htobe64(x) OSSwapHostToBigInt64(x)

#define htole64(x) OSSwapHostToLittleInt64(x)

#define be64toh(x) OSSwapBigToHostInt64(x)

#define le64toh(x) OSSwapLittleToHostInt64(x)


#endif


char *g_pcm_filename;

char *g_wav_filename;

FILE* g_pcm_fd = NULL;

FILE* g_wav_fd = NULL;


/* important: these values are here for documentation. if they are

   changed, the code must be reviewed */

const int channels = 1;

const int samplerate = 16000;

const int bytespersample = 2;


#define WRITE_OR_DIE(ptr,tp,sz,f) \

  if (fwrite(ptr,tp,sz,f) != sz) return false;


int file_size(char* filename)  

{  

    struct stat statbuf;  

    stat(filename,&statbuf);  

    int size=statbuf.st_size;  

  

    return size;  

}  


int main(int argc, char* argv[])

{

if (argc != 3){

printf("Usage : pcm2wav pcm_filenma wav_filename\n");

return -1;

}

g_pcm_filename = argv[1];

g_wav_filename = argv[2];

int pcmfile_size=file_size(g_pcm_filename);

int sample_count=pcmfile_size/channels/bytespersample;

int period_ms=1000*sample_count/samplerate;

printf("pcm file : %s\n", g_pcm_filename);

printf("wav file : %s\n", g_wav_filename);

printf("period = %dms\n", period_ms);

g_pcm_fd = fopen(g_pcm_filename, "rb");

g_wav_fd = fopen(g_wav_filename, "wb");



//write WAV header

    size_t out;

    int32_t size;

    int16_t nchan;


    WRITE_OR_DIE("RIFF", sizeof(char), 4, g_wav_fd);


    size = (int32_t) htole32 ((uint32_t)(36 + bytespersample

         * channels * sample_count));

    WRITE_OR_DIE(&size, sizeof(int32_t), 1, g_wav_fd);


    WRITE_OR_DIE("WAVEfmt ", sizeof(char), 8, g_wav_fd);


    /* chunk size == 16 */

    size = (int32_t) htole32 ((uint32_t) 16);

    WRITE_OR_DIE(&size, sizeof(int32_t), 1, g_wav_fd);


    /* format = pcm */

    WRITE_OR_DIE("\1\0", sizeof(char), 2, g_wav_fd);


    nchan = (int16_t) htole16 ((uint16_t) channels);

    WRITE_OR_DIE(&nchan, sizeof(int16_t), 1, g_wav_fd);

    size = (int32_t) htole32 ((uint32_t) samplerate);

    WRITE_OR_DIE(&size, sizeof(int32_t), 1, g_wav_fd);

    size = (int32_t)htole32((uint32_t)(samplerate * channels * bytespersample));

    WRITE_OR_DIE(&size, sizeof(int32_t), 1, g_wav_fd);

    nchan = (int16_t) htole16 ((uint16_t) (channels * bytespersample));

    WRITE_OR_DIE(&nchan, sizeof(int16_t), 1, g_wav_fd);

    nchan = (int16_t) htole16 ((uint16_t) (8 * bytespersample));

    WRITE_OR_DIE(&nchan, sizeof(int16_t), 1, g_wav_fd);

    WRITE_OR_DIE("data", sizeof(char), 4, g_wav_fd);

    size = (int32_t) htole32 ((uint32_t) (bytespersample * channels * sample_count));

    WRITE_OR_DIE(&size, sizeof(int32_t), 1, g_wav_fd);

char byte;

int readlen;

//copy pcm

while(1)

{

readlen = fread(&byte, 1, 1, g_pcm_fd);

if (readlen<1)

break;

fwrite(&byte, 1, 1, g_wav_fd);

}

fclose(g_pcm_fd);

fclose(g_wav_fd);

return 0;

}