- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的任务是录制 wave 文件,将其转换为 ogg 并将其打包到 riff 容器中。前两部分已经完成,但我对第三部分有疑问。我找到了可以解决我的问题的源代码,但它不能正常工作。
#include <windows.h>
#include <windowsx.h>
#include <mmsystem.h>
#include <memory.h>
#include <stdlib.h>
#include <mmreg.h>
#include <msacm.h>
#include <assert.h>
#include <math.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#define INPUT "record.wav"
#define OUTPUT "output_ogg.wav"
/* The following taken from the vorbis.acm sources */
/* Defines modes for encoding. Set this in 'fmt ' */
#define WAVE_FORMAT_VORBIS1 ((WORD)'O'+((WORD)'g'<<8)) // 0x674f("Og") ... Original stream compatible
#define WAVE_FORMAT_VORBIS2 ((WORD)'P'+((WORD)'g'<<8)) // 0x6750("Pg") ... Have independent header
#define WAVE_FORMAT_VORBIS3 ((WORD)'Q'+((WORD)'g'<<8)) // 0x6751("Qg") ... Have no codebook header
#define WAVE_FORMAT_VORBIS1P ((WORD)'o'+((WORD)'g'<<8)) // 0x676f("og") ... Original stream compatible
#define WAVE_FORMAT_VORBIS2P ((WORD)'p'+((WORD)'g'<<8)) // 0x6770("pg") ... Have independent header
#define WAVE_FORMAT_VORBIS3P ((WORD)'q'+((WORD)'g'<<8)) // 0x6771("qg") ... Have no codebook header
/* The 'fact' chunk required for compressed WAV files */
struct FACT {
unsigned long dwID;
unsigned long dwSize;
unsigned long dwSamples;
};
int main()
{
/* Open source file */
HMMIO hSrcWaveFile=mmioOpen(INPUT,NULL,MMIO_READ);
assert(hSrcWaveFile);
MMCKINFO SrcWaveFile;
mmioDescend(hSrcWaveFile,&SrcWaveFile,NULL,0);
assert(SrcWaveFile.ckid==mmioStringToFOURCC("RIFF",MMIO_TOUPPER));
assert(SrcWaveFile.fccType==mmioStringToFOURCC("WAVE",MMIO_TOUPPER));
MMCKINFO SrcWaveFmt;
/* Go to RIFF-WAVE*/
mmioDescend(hSrcWaveFile,&SrcWaveFmt,&SrcWaveFile,0);
assert(SrcWaveFmt.ckid==mmioStringToFOURCC("fmt ",0));
int SrcHeaderSize=SrcWaveFmt.cksize;
if(SrcHeaderSize<sizeof(WAVEFORMATEX))
SrcHeaderSize=sizeof(WAVEFORMATEX);
WAVEFORMATEX *SrcHeader=(WAVEFORMATEX *)new char[SrcHeaderSize];
ZeroMemory(SrcHeader,SrcHeaderSize);
/* Read fmt */
mmioRead(hSrcWaveFile,(char*)SrcHeader,SrcWaveFmt.cksize);
/* Leave the chunk */
mmioAscend(hSrcWaveFile,&SrcWaveFmt,0);
MMCKINFO SrcWaveData;
while(1){
MMRESULT Result=mmioDescend(hSrcWaveFile,&SrcWaveData,&SrcWaveFile,0);
assert(Result==0);
if(SrcWaveData.ckid==mmioStringToFOURCC("data",0))
break;
Result=mmioAscend(hSrcWaveFile,&SrcWaveData, 0);
assert(Result==0);
}
/* Destination header */
WAVEFORMATEX *DstHeader=(WAVEFORMATEX *)malloc(1024);
ZeroMemory(DstHeader,1024);
printf ("Going ACM!\n");
/* Suggest a format for us */
/* Try to coose the nmber 3 mode (whatever that is) */
DstHeader->wFormatTag = WAVE_FORMAT_VORBIS3;
DstHeader->nChannels = 2;
DstHeader->wBitsPerSample = 16;
DstHeader->nSamplesPerSec = 44100;
printf ("->acmFormatSuggest()\n");
if (acmFormatSuggest(NULL,SrcHeader,DstHeader,1024,ACM_FORMATSUGGESTF_WFORMATTAG))
printf ("ERROR: acmFormatSuggest()\n");
/* We shoudl have the DstHeader filled with data byt the ACM now */
/* Open destination */
HMMIO hDstWaveFile;
/* open the destination file */
hDstWaveFile=mmioOpen(OUTPUT,NULL,MMIO_CREATE|MMIO_WRITE);
assert(hDstWaveFile);
printf ("->mmioOpen() output.wav\n");
/* Create chunks */
MMCKINFO DstWaveFile;
DstWaveFile.fccType=mmioStringToFOURCC("WAVE",MMIO_TOUPPER);
mmioCreateChunk(hDstWaveFile,&DstWaveFile,MMIO_CREATERIFF);
printf ("->mmioCreateChunk() WAVE\n");
/* Create format chunk */
MMCKINFO DstWaveFmt;
DstWaveFmt.ckid=mmioStringToFOURCC("fmt ",0);
/* Create chunk write data and Ascend out of it */
mmioCreateChunk(hDstWaveFile,&DstWaveFmt,0);
printf ("->mmioCreateChunk() fmt\n");
mmioWrite(hDstWaveFile,(char*)DstHeader,sizeof(WAVEFORMATEX)+DstHeader->cbSize);
printf ("->mmioWrite() fmt header\n");
mmioAscend(hDstWaveFile,&DstWaveFmt,0);
printf ("->mmioAscend()\n");
/* fact chunk */
/* this is only my idea of what it should look like */
/* i found that some WAV files had more data than i write */
/* but that seems enough for most of apps i tested */
FACT DstFactChunk;
MMCKINFO FactChunk;
DstFactChunk.dwID = mmioStringToFOURCC ("fact", 0);
DstFactChunk.dwSamples = SrcWaveData.cksize / 4;
DstFactChunk.dwSize = sizeof (DstFactChunk) - sizeof (DstFactChunk.dwID) - sizeof (DstFactChunk.dwSize);
FactChunk.ckid = mmioStringToFOURCC ("fact", 0);
FactChunk.cksize = DstFactChunk.dwSize;
/* Calculate the time */
float TIME;
if (SrcHeader->nSamplesPerSec == 44100)
TIME = DstFactChunk.dwSamples / 44100.f;
mmioWrite (hDstWaveFile, (char *)&DstFactChunk, sizeof (DstFactChunk));
/* This ascend produced an error when i added this whole code */
/* to my Dialog based MFC full feature super duper app */
/* Don't know why really but i think that Write already moves the pointer */
/* past the chun sok this is unnecessery */
/* mmioAscend (hDstWaveFile, &FactChunk, 0); */
/* Create Data chunk */
MMCKINFO DstWaveData;
DstWaveData.ckid=mmioStringToFOURCC("data",0);
mmioCreateChunk(hDstWaveFile,&DstWaveData,0);
mmioAscend (hDstWaveFile, &DstWaveData, 0);
printf ("->mmioCreateChunk() data\n");
/* Print the data we have gathered so far */
printf ("------------Source-----------\n");
printf ("Format: \t\t%X\n", SrcHeader->wFormatTag);
printf ("Channels: \t\t%d\n", SrcHeader->nChannels);
printf ("Samples/Sec: \t\t%d\n", SrcHeader->nSamplesPerSec);
printf ("AverageBytes/Sec: \t%d\n", SrcHeader->nAvgBytesPerSec);
printf ("Bits/Sample: \t\t%d\n", SrcHeader->wBitsPerSample);
printf ("BlockAlign: \t\t%d\n", SrcHeader->nBlockAlign);
printf ("DataSize: \t\t%d\n", SrcWaveData.cksize);
printf ("Time: \t\t\t%.3f\n", TIME);
printf ("Samples: \t\t%d\n", DstFactChunk.dwSamples);
printf ("Extra: \t\t\t%d\n", SrcHeader->cbSize);
printf ("------------------------------\n");
printf ("\n------------Destination------\n");
printf ("Format: \t\t%X\n", DstHeader->wFormatTag);
printf ("Channels: \t\t%d\n", DstHeader->nChannels);
printf ("Samples/Sec: \t\t%d\n", DstHeader->nSamplesPerSec);
printf ("AverageBytes/Sec: \t%d\n", DstHeader->nAvgBytesPerSec);
printf ("Bits/Sample: \t\t%d\n", DstHeader->wBitsPerSample);
printf ("BlockAlign: \t\t%d\n", DstHeader->nBlockAlign);
printf ("Extra: \t\t\t%d\n", DstHeader->cbSize);
printf ("------------------------------\n");
DWORD maxFormatSize = 0;
MMRESULT ACMres;
/* Get the max possbile size from the system this really no necessery */
/* but i was experimenting a bit and so I left it here */
ACMres = acmMetrics( NULL, ACM_METRIC_MAX_SIZE_FORMAT, &maxFormatSize );
if (ACMres != MMSYSERR_NOERROR){
printf ("ERROR: acmMetrics()\n");
}
/* Open ACM stream */
HACMSTREAM acm = NULL;
MMRESULT Result=acmStreamOpen(&acm,NULL,SrcHeader,DstHeader,NULL,0,0,0);
printf ("->acmStreamOpen()\n");
if (Result != MMSYSERR_NOERROR){
printf ("ERROR: acmStreamOpen()\n");
exit (-1);
}
/* This is where the problem's begin, first the buffers */
/* Size of the dest/src is based on the size of src/dest */
DWORD DefaultWriteSize;
DWORD DefaultReadSize = SrcHeader->nBlockAlign * 1024;
/* If we know the dest */
/* Result=acmStreamSize(acm, DefaultWriteSize, &DefaultReadSize, ACM_STREAMSIZEF_DESTINATION); */
printf ("->acmStreamSize()\n");
/* If we know the source, well stay with the source PCM is less problematic */
Result = acmStreamSize (acm, DefaultReadSize, &DefaultWriteSize, ACM_STREAMSIZEF_SOURCE);
printf ("->acmStreamSize() gave us buffer size [%d]\n", DefaultWriteSize);
if (Result != MMSYSERR_NOERROR){
printf ("ERROR: acmStreamSize()\n");
exit (-1);
}
/* Allocate memory */
ACMSTREAMHEADER stream;
ZeroMemory(&stream,sizeof(stream));
stream.cbStruct=sizeof(stream);
stream.pbSrc=(BYTE*)GlobalAlloc(GMEM_FIXED,DefaultReadSize);
stream.cbSrcLength=DefaultReadSize;
stream.pbDst=(BYTE*)GlobalAlloc(GMEM_FIXED,DefaultWriteSize);
stream.cbDstLength=DefaultWriteSize;
/* Prepare header */
printf ("->acmStreamPrepareHeader()\n");
Result=acmStreamPrepareHeader(acm, &stream,0);
if (Result != MMSYSERR_NOERROR){
printf ("ERROR: acmStreamPrepareHeader()\n");
exit (-1);
}
/* The main encoding loop */
/* I'm pretty sure that before the actual reading of samples from the source */
/* I should feed the ACM some junk so that it would write the necessery headers */
/* that Ogg Vorbis requires */
/* but i dont know how much of that 'junk' i would have to write there */
/* i don't know if it can be junk */
/* well i'm pretty clueless here */
for(int RemainSize=SrcWaveData.cksize;RemainSize>0;){
// ????
int ReadSize=DefaultReadSize;
if(ReadSize>RemainSize)
ReadSize=RemainSize;
RemainSize-=ReadSize;
ReadSize=mmioRead(hSrcWaveFile,(char*)stream.pbSrc,ReadSize);
if (ReadSize == -1){
printf ("Can't read\n");
break;
}
stream.cbSrcLength=ReadSize;
/* Convert */
Result=acmStreamConvert(acm,&stream,0);
if (Result)
printf ("ERROR: acmStreamConvert()\n");
int WriteSize=stream.cbDstLengthUsed;
/* Wrtie data */
Result=mmioWrite(hDstWaveFile,(char*)stream.pbDst,WriteSize);
if (Result == -1){
printf ("Can't Write");
break;
}
/* Uncomment this if you want to see the buffer sizes */
/* printf ("READ[%d] :: WRITE[%d]\n", stream.cbSrcLengthUsed, stream.cbDstLengthUsed); */
}
/* Cleaup on Isle 5 !!! */
GlobalFree(stream.pbSrc);
GlobalFree(stream.pbDst);
acmStreamUnprepareHeader(acm,&stream,0);
acmStreamClose(acm,0);
mmioAscend(hSrcWaveFile,&SrcWaveData,0);
mmioAscend(hSrcWaveFile,&SrcWaveFile,0);
mmioAscend(hDstWaveFile,&DstWaveData,0);
mmioAscend(hDstWaveFile,&DstWaveFile,0);
free(DstHeader);
mmioClose(hSrcWaveFile,0);
mmioClose(hDstWaveFile,0);
delete[] SrcHeader;
return 0;
}
当我试图执行这个程序时,它告诉我 acmFormatSuggest() 和 acmStreamOpen() 失败了。请帮我找出错误。
最佳答案
如果安装了支持此格式的 ACM 音频编解码器,acmFormatSuggest(顺便说一下,错误代码是什么?)可能会成功。默认情况下没有可用的,您实际上安装了一个吗?
关于c++ - 使用 acm 将 Ogg 转为 Riff/Wave 编码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7609427/
RIFF WAV文件中的格式参数的字节序是否得到保证?我对此有heard conflicting answers,包括对RIFX文件格式的引用。 最佳答案 是的。 如果文件以RIFF开头,则为小端。
所以我以前从未真正使用过二进制文件,而且我是 C++ 新手。我想读取一个 wav 文件并将其数据部分输出到一个 txt 中(用逗号分隔每个样本的值)。我还设法阅读了标题部分,但这段代码在这里并不重要,
根据WAV / RIFF文件规范:http://www.topherlee.com/software/pcm-tut-wavformat.html header 中的5-8个字节是整个文件的大小减去8
我正在编写一个简单的录音实用程序,我还希望能够使用元数据标记生成的文件。很容易找到用 ID3 标签标记 MP3 文件的库,但我对 WAV 和可能的 FLAC 等无损编解码器更感兴趣。 据我所知,WAV
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我正在用 C# 编写一个应用程序,它将录制音频文件 (*.wav) 并自动标记和命名它们。波形文件是 RIFF 文件(如 AVI),除了波形数据 block 之外,它还可以包含元数据 block 。所
我正在尝试将原始音频数据从一种格式转换为另一种格式,以便进行语音识别。 音频是从 Discord 接收的服务器以20ms block 的格式:48Khz,16位立体声签名BigEndian PCM。
我有一个 ogg 音频文件和一些保存为字节序列的信息。我需要将这些音频和信息打包到一个容器中,例如 RIFF 或其他容器。我正在寻找可以在 .NET 下编写的解决方案。 最佳答案 Ogg 是一种容器格
我正在尝试在 perl 中解码和播放 WAV 文件以进行进一步的操作,我找到了一些关于格式的引用资料,以及一些有趣的 q+a What does a audio frame contain? erro
friend 们 我刚刚从该位置开始使用WaveContainer.as文件来使用actionscript和Im https://code.google.com/p/wami-recorder/sou
所以,我正在编写一个语音识别程序。为此,我从 TIMIT 下载了 400MB 的数据。当我打算阅读 wav 文件时(我尝试了两个库),如下所示: import scipy.io.wavfile as
更多关于我想做什么的信息; http://www.studiodust.com/riffmp3.html 我想要一种方法,使我的控制面板(用 Perl 和 Webmin 制作)可以自动执行此操作。现在
我正在尝试在 python 2.6 中将 16khz wav 文件下采样到 8khz。该文件具有 RIFF header 并且采用 mulaw 格式,并且必须保留该格式。 我浏览了 this big
如何生成包含 WAV/RIFF 声音文件频谱的文件? 我想使用 Linux 命令行。 我知道很酷SoX生成 PNG 频谱图的函数: sox sound.wav -n spectrogram 但我不需要
我的文件使用其哈希名称保存,没有扩展名。但我确定它是 RIFF 文件,如 WAV、MP3。我如何添加 MIME 取决于它使用 nginx 的 RIFF header ? 编辑:大多数文件是 mp3 格
我只想拥有 .wav 文件的数据 block 并排除所有其他 block ,即 riff header 。 let voiceData = try? Data(contentsOf:
我有一个包含 3 个 block 的 RIFF 容器文件; RIFF block 具有“WAVE”标识符。第一个 block 是“fmt”,第二个是“数据”,最后一个是“eink”(我自己的 bloc
我的任务是录制 wave 文件,将其转换为 ogg 并将其打包到 riff 容器中。前两部分已经完成,但我对第三部分有疑问。我找到了可以解决我的问题的源代码,但它不能正常工作。 #include #
如何将 RIFF block 数据写入 WAV 文件的结尾?是的,没错,写入 WAV 文件的结尾。为什么?因为我要替换的旧程序就是这样做的,集成程序就是这样准备的,它们不能被修改。 最佳答案 我个人会
尝试在 Python 中打开 RIFF 文件(据我所知,它是一种 WAV)时出现此错误。 Failed to open file file.wav as a WAV due to: file does
我是一名优秀的程序员,十分优秀!