C++ 创建WAV块
我正在尝试向现有WAV文件添加自定义块。我正在使用mmioCreateChunk函数,但在执行之后,文件没有任何更改。以下是我的程序代码:C++ 创建WAV块,c++,audio,wav,C++,Audio,Wav,我正在尝试向现有WAV文件添加自定义块。我正在使用mmioCreateChunk函数,但在执行之后,文件没有任何更改。以下是我的程序代码: #include <windows.h> #include <mmsystem.h> #include <iostream> #include <fstream> using namespace std; #pragma comment( lib, "winmm" ) int main() {
#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;
}
#包括
#包括
#包括
#包括
使用名称空间std;
#pragma注释(lib,“winmm”)
int main()
{
HMMIO HMMIO;//打开文件的文件句柄
MMCKINFO mmckinfoParent;//父块信息
MMCKINFO mmckinfoFormatChunk;//格式化块信息结构
MMCKINFO mmckinfoDataChunk;//数据块信息结构
MMCKINFO mmckinfoRdibChunk;//Rdib块信息结构
//打开文件以使用缓冲I/O进行读取
//通过使用默认的内部缓冲区
如果(!(hmmio=mmiopen(L“out.wav”),则为空,
MMIO_(读取)))
{
参见:
如果成功,mmioCreateChunk()将当前文件位置移动到
新数据块的数据区的开头(在数据块之后
输入RIFF或LIST chunks)。可以使用另一个创建子块
调用mmioCreateChunk()。请注意,mmioCreateChunk()无法插入
将数据块部分分块到已存在的文件中。如果尝试此操作,
文件中的现有数据将被覆盖
mmioDescend开始在当前文件位置搜索。因此它将找不到您刚刚写入的块。您应该首先将文件位置重置为开始位置,或重置为以前的块。
是否正确设置了其他块字段(ckSize和fccType)?
也许您应该在创建块后执行mmioAscend以获得正确的填充
hmmio_out = mmioOpen(L"test.wav", 0, MMIO_CREATE | MMIO_WRITE);
应该是
hmmio_out = mmioOpen(L"test.wav", 0, MMIO_CREATE | MMIO_READWRITE);
!注意,由于MMIO_CREATE,它将删除文件内容;我还尝试创建一个新文件,并将现有文件中的数据复制到该文件中,但结果相同。它添加了我要写入该文件的信息,但它无法将其识别为块。我正在使用RIFF view应用程序查看RIFF文件结构,但它找不到新块到。但是,如果我用记事本++打开文件,我可以看到插入其中的信息。这是我的问题。您可以在编辑的主题主消息中看到的新代码。您正在将块长度设置为文件长度?块可能不完整(它必须有偶数个字节),这可能是RIFF view无法看到它的原因。