PCM文件转WAV文件

来源:互联网 发布:兄弟连java 怎么样 编辑:程序博客网 时间:2024/05/24 03:20

PCM文件转成WAV文件,只要加一个表头就够了。

这里假设采样率22050,采样精度16比特,双通道。Intel数端方式存放数据。

因为PCM源文件是四字节对齐,所以以四字节为单位Copy数据。

 

下面的源代码片段,示例库函数如何调用

[cpp] view plaincopy
  1.         FILE *fpS;  
  2.         FILE *fpD;  
  3.         fpS = fopen(ws2s(wsPCMFileName).c_str(),"rb");  
  4.         fpD = fopen(ws2s(wsWAVEFileName).c_str(),"wb+");  
  5.         if(fpS==NULL||fpD==NULL)  
  6.         {  
  7.             ::OutputDebugString(L"[CIrrReplay::createScene]PCM转WAVE失败!/n");  
  8.             return;  
  9.         }  
  10.         fseek(fpS, 0, SEEK_END);  
  11.         long filelength = ftell(fpS);  
  12.         writeWaveHead(fpD);  
  13.         writeWaveBody(fpD,filelength);  
  14.   
  15.         fseek(fpS,44,SEEK_SET);  
  16. #define UNIT 4  
  17.         char buf[UNIT];  
  18.         while(UNIT==fread(buf,1,UNIT,fpS))  
  19.         {  
  20.             fwrite(buf,1,UNIT,fpD);  
  21.         }  
  22.         fclose(fpS);  
  23.         fclose(fpD);  

 

 

下面是待调用库的头文件

[cpp] view plaincopy
  1. #pragma once  
  2.   
  3. #include <stdio.h>  
  4. #include <Windows.h>  
  5. #include <string>  
  6.   
  7. struct RIFF_HEADER  
  8. {  
  9.     char szRiffID[4];  // 'R','I','F','F'  
  10.     DWORD dwRiffSize;  
  11.     char szRiffFormat[4]; // 'W','A','V','E'  
  12. };  
  13.   
  14. struct WAVE_FORMAT  
  15. {  
  16.     WORD wFormatTag;  
  17.     WORD wChannels;  
  18.     DWORD dwSamplesPerSec;  
  19.     DWORD dwAvgBytesPerSec;  
  20.     WORD wBlockAlign;  
  21.     WORD wBitsPerSample;  
  22. };  
  23.   
  24. struct FMT_BLOCK  
  25. {  
  26.     char  szFmtID[4]; // 'f','m','t',' '  
  27.     DWORD  dwFmtSize;  
  28.     WAVE_FORMAT wavFormat;  
  29. };  
  30.   
  31. struct DATA_BLOCK  
  32. {  
  33.     char szDataID[4]; // 'd','a','t','a'  
  34.     DWORD dwDataSize;  
  35. };  
  36.   
  37. union DWORD_CHAR  
  38. {  
  39.     int  nValue;  
  40.     char charBuf[4];  
  41. };  
  42.   
  43. void writeWaveHead(FILE *fp);  
  44. void writeWaveBody(FILE *fp,long filelength);  

下面是待调用库的源文件

[cpp] view plaincopy
  1. #include "PCM2WAVE.h"  
  2. #include <memory.h>  
  3. #include <string.h>  
  4. /* 
  5. Name: 
  6.      writeFile2Int 
  7. Description: 
  8.      在已知文件的指定位置,写一个整数 
  9.      这里假设,int类型占四个字节 
  10. Parameter:sFN    文件名 
  11.      nWhere 准备写的位置(以零开始计数) 
  12.      nValue 具体值。      
  13. Remark: 
  14.      若文件长度小于nWhere,数据写到文件位置0开始的地方 
  15. TestEnv: 
  16.      VS2008+SP1  32位程序 
  17. */  
  18. bool writeFile2Int(FILE *fp,int nWhere,int nValue)  
  19. {  
  20.     if(fp==NULL)  
  21.     {  
  22.         return false;  
  23.     }  
  24.   
  25.     fseek(fp,nWhere,SEEK_SET);  
  26.     DWORD_CHAR dc;  
  27.     dc.nValue=nValue;  
  28.     fwrite(dc.charBuf,1,4,fp);        
  29.     return true;  
  30. }  
  31.   
  32. void writeWaveHead(FILE *fp)  
  33. {  
  34.     if (fp)  
  35.     {  
  36.         //写WAV文件头  
  37.         RIFF_HEADER rh;  
  38.         memset(&rh,0,sizeof(rh));  
  39.         strncpy(rh.szRiffFormat,"WAVE",4);  
  40.         strncpy(rh.szRiffID,"RIFF",4);  
  41.         //rh.dwRiffSize = dataSize + 4 + sizeof(FMT_BLOCK) + sizeof(rh) - 8;//文件大小减去8  
  42.   
  43.         fwrite(&rh,1,sizeof(rh),fp);  
  44.   
  45.         FMT_BLOCK fb;  
  46.         strncpy(fb.szFmtID,"fmt ",4);  
  47.         fb.dwFmtSize = 16;  
  48.         fb.wavFormat.wFormatTag = 0x0001;  
  49.         fb.wavFormat.wChannels = 2;  
  50.         fb.wavFormat.wBitsPerSample = 16;         
  51.         fb.wavFormat.dwSamplesPerSec = 22050;         
  52.         fb.wavFormat.wBlockAlign = fb.wavFormat.wChannels*fb.wavFormat.wBitsPerSample/8;   //4;  
  53.         fb.wavFormat.dwAvgBytesPerSec = fb.wavFormat.dwSamplesPerSec * fb.wavFormat.wBlockAlign;  
  54.           
  55.   
  56.         fwrite(&fb,1,sizeof(fb),fp);  
  57.   
  58.         char buf[]={"data0000"};  
  59.         fwrite(buf,1,sizeof(buf),fp);  
  60.     }  
  61. }  
  62.   
  63. void writeWaveBody(FILE *fp,long filelength)  
  64. {  
  65.     //更新WAV文件dwRiffSize字段中的值  
  66.     int nWhere = 4;  
  67.     writeFile2Int(fp,nWhere, filelength - 8);  
  68.   
  69.     //更新WAV文件DataChunk中Size字段的值  
  70.     nWhere=sizeof(RIFF_HEADER)+sizeof(FMT_BLOCK)+4;  
  71.     writeFile2Int(fp,nWhere,filelength - (sizeof(RIFF_HEADER)+sizeof(FMT_BLOCK)+8) );  
  72. }  


原创粉丝点击