创建WAV块

时间:2011-10-28 12:15:07

标签: c++ audio wav

我正在尝试将自定义块添加到现有的WAV文件中。我正在使用mmioCreateChunk函数,但在执行后没有任何更改文件。这是我的程序代码:

#include <windows.h> 
#include <mmsystem.h> 
#include <iostream>
#include <fstream>

using namespace std;

#pragma comment( lib, "winmm" )

int main() 
{
  HMMIO       hmmio;                 // file handle for open file 
  MMCKINFO    mmckinfoParent;        // parent chunk information 
  MMCKINFO    mmckinfoFormatChunk;   // Format chunk information structure 
  MMCKINFO    mmckinfoDataChunk;     // Data chunk information structure
  MMCKINFO    mmckinfoRdibChunk;     // Rdib chunk information structure

  // Open the file for reading with buffered I/O 
  // by using the default internal buffer   
  if(!(hmmio = mmioOpen(L"out.wav", NULL, 
    MMIO_READ))) 
  { 
    cout << "Error opening file." << endl;
    return 0; 
  }

  // Locate a "RIFF" chunk with a "WAVE" form type to make 
  // sure the file is a waveform-audio file. 
  mmckinfoParent.fccType = mmioFOURCC('W', 'A', 'V', 'E'); 
  if (mmioDescend(hmmio, (LPMMCKINFO) &mmckinfoParent, NULL, 
    MMIO_FINDRIFF)) 
  { 
    cout << "This is not a waveform-audio file." << endl; 
    mmioClose(hmmio, 0); 
    return 0; 
  }

  // Find the "FMT" chunk (form type "FMT"); it must be 
  // a subchunk of the "RIFF" chunk. 
  mmckinfoFormatChunk.ckid = mmioFOURCC('f', 'm', 't', ' '); 
  if (mmioDescend(hmmio, &mmckinfoFormatChunk, &mmckinfoParent, 
    MMIO_FINDCHUNK)) 
  { 
    cout << "Waveform-audio file has no \"FMT\" chunk." << endl; 
    mmioClose(hmmio, 0); 
    return 0; 
  }

  unsigned int fmtSize = mmckinfoFormatChunk.cksize;
  char * waveFmt = new char[fmtSize];
  mmioRead(hmmio, waveFmt, mmckinfoFormatChunk.cksize);

  mmioAscend(hmmio, &mmckinfoFormatChunk, 0); 

  // Find the data subchunk. The current file position should be at 
  // the beginning of the data chunk; however, you should not make 
  // this assumption. Use mmioDescend to locate the data chunk. 
  mmckinfoDataChunk.ckid = mmioFOURCC('d', 'a', 't', 'a'); 
  if (mmioDescend(hmmio, &mmckinfoDataChunk, &mmckinfoParent, 
    MMIO_FINDCHUNK)) 
  { 
    cout << "Waveform-audio file has no data chunk." << endl; 
    mmioClose(hmmio, 0); 
    return 0;
  }

  unsigned int size = mmckinfoDataChunk.cksize;
  char* data = new char[size];
  mmioRead(hmmio, data, size);
  mmioClose(hmmio, 0);

  ifstream fs;
  fs.open("out.txt");

  // get length of file:
  fs.seekg (0, ios::end);
  int length = fs.tellg();
  fs.seekg (0, ios::beg);

  // allocate memory:
  char* buffer = new char [length];

  // read data as a block:
  fs.read (buffer,length);
  fs.close();

  HMMIO hmmio_out;

  //Creating new wav file.
  hmmio_out = mmioOpen(L"test.wav", 0, MMIO_CREATE | MMIO_WRITE);

  //Creating RIFF chunk
  mmioCreateChunk(hmmio_out, &mmckinfoParent, MMIO_CREATERIFF);

  //Creating format chunk and inserting information from source file
  mmioCreateChunk(hmmio_out, &mmckinfoFormatChunk, 0);
  mmioWrite(hmmio_out, waveFmt, mmckinfoFormatChunk.cksize);

  mmioAscend(hmmio_out, &mmckinfoFormatChunk, 0);

  //Creating data chunk and inserting information from source file
  mmioCreateChunk(hmmio_out, &mmckinfoDataChunk, 0);
  mmioWrite(hmmio_out, data, mmckinfoDataChunk.cksize);

  mmioAscend(hmmio_out, &mmckinfoDataChunk, 0);

  //Creating new rdib chunk and inserting information from out.txt
  mmckinfoRdibChunk.ckid = mmioFOURCC('r', 'd', 'i', 'b');
  mmckinfoRdibChunk.cksize = sizeof(char) * length;
  mmioCreateChunk(hmmio_out, &mmckinfoRdibChunk, 0);

  mmioWrite(hmmio_out, buffer, sizeof(char) * length);

  mmioAscend(hmmio_out, &mmckinfoRdibChunk, 0);

  // Close the file. 
  mmioClose(hmmio_out, 0); 

  return 0; 
}

创建新块需要做些什么?

3 个答案:

答案 0 :(得分:1)

mmioDescend开始在当前文件位置搜索。所以它找不到你刚才写的那块。您应该首先将文件位置重置为开头或前一个块。 您是否正确设置了其他块字段(ckSize和fccType)? 也许你应该在创建块之后执行mmioAscend来获得正确的填充。

答案 1 :(得分:0)

请参阅Inside the RIFF Specification

  

如果成功, mmioCreateChunk()会将当前文件位置移动到   新块的数据区域的开头(以及块之后)   输入RIFF或LIST块)。 然后可以是块的内容   使用mmioWrite()编写,或可以使用另一个创建子块   调用mmioCreateChunk()。请注意,mmioCreateChunk()无法插入   中途进入已存在的文件。如果这样做,   文件中的现有数据将被覆盖。

答案 2 :(得分:0)

hmmio_out = mmioOpen(L"test.wav", 0, MMIO_CREATE | MMIO_WRITE);

应该是

hmmio_out = mmioOpen(L"test.wav", 0, MMIO_CREATE | MMIO_READWRITE);

!注意它会因MMIO_CREATE而删除文件内容;