【问题标题】:Creating WAV chunks创建 WAV 块
【发布时间】:2011-10-28 12:15:06
【问题描述】:

我正在尝试将自定义块添加到现有 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; 
}

我必须做什么来创建新的块?

【问题讨论】:

    标签: c++ audio wav


    【解决方案1】:

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

    【讨论】:

    • 我正在使用 RIFF 视图应用程序来查看 riff 文件结构,但它没有找到新的块。但是,如果我在记事本++ 中打开我的文件,我可以看到插入其中的信息。那是我的问题。您可以在编辑的主题主消息中看到的新代码。
    • 您将块长度设置为文件长度?块可能不完整(它必须有偶数字节),这可能是 RIFF 视图看不到它的原因。
    【解决方案2】:

    Inside the RIFF Specification:

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

    【讨论】:

    • 我也尝试创建一个新文件并将现有文件中的数据复制到其中,但结果是一样的。
    • 它将我想要写入此文件的信息添加到此文件中,但它不会将其识别为块。
    【解决方案3】:
    hmmio_out = mmioOpen(L"test.wav", 0, MMIO_CREATE | MMIO_WRITE);
    

    应该是

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

    !注意,由于 MMIO_CREATE,它会删除文件的内容;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-07
      • 2017-01-07
      • 2015-10-31
      • 1970-01-01
      • 2023-03-13
      • 1970-01-01
      • 1970-01-01
      • 2019-07-04
      相关资源
      最近更新 更多