Создание фрагментов WAV - PullRequest
0 голосов
/ 28 октября 2011

Я пытаюсь добавить пользовательские чанки в существующий файл 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 ]

1 голос
/ 28 октября 2011

mmioDescend начинает поиск с текущей позиции файла. Так что он не найдет кусок, который вы только что написали. Сначала вы должны сбросить положение файла на начало или на предыдущий фрагмент. Правильно ли вы установили другие поля чанка (ckSize и fccType)? Возможно, вам следует выполнить mmioAscend после создания чанка, чтобы получить правильное заполнение.

0 голосов
/ 22 июля 2014
hmmio_out = mmioOpen(L"test.wav", 0, MMIO_CREATE | MMIO_WRITE);

должно быть

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

! Внимание, это приведет к удалению содержимого файла из-за MMIO_CREATE;

0 голосов
/ 28 октября 2011

См. Внутри спецификации RIFF :

В случае успеха mmioCreateChunk () перемещает текущую позицию файла в начало области данных нового фрагмента (и после типа чанка для чанков RIFF или LIST). Содержимое чанка затем может быть записано с использованием mmioWrite (), или может быть создан подчанк с другим вызовом mmioCreateChunk ().Обратите внимание, что mmioCreateChunk () не может частично вставить чанк в уже существующий файл.Если это сделать, существующие данные в файле будут перезаписаны.

...