我有一个基于上述问题的任务。每个样本的采样频率和大小在问题中是已知的。我只需要了解为此所需的编码类型。
问问题
658 次
3 回答
3
使用文件格式规范(例如这个)来查看如何读取文件头、确定采样率、比特率等。
The canonical WAVE format starts with the RIFF header:
0 4 ChunkID Contains the letters "RIFF" in ASCII form
(0x52494646 big-endian form).
4 4 ChunkSize 36 + SubChunk2Size, or more precisely:
4 + (8 + SubChunk1Size) + (8 + SubChunk2Size)
This is the size of the rest of the chunk
following this number. This is the size of the
entire file in bytes minus 8 bytes for the
two fields not included in this count:
ChunkID and ChunkSize.
8 4 Format Contains the letters "WAVE"
(0x57415645 big-endian form).
The "WAVE" format consists of two subchunks: "fmt " and "data":
The "fmt " subchunk describes the sound data's format:
12 4 Subchunk1ID Contains the letters "fmt "
(0x666d7420 big-endian form).
16 4 Subchunk1Size 16 for PCM. This is the size of the
rest of the Subchunk which follows this number.
20 2 AudioFormat PCM = 1 (i.e. Linear quantization)
Values other than 1 indicate some
form of compression.
22 2 NumChannels Mono = 1, Stereo = 2, etc.
24 4 SampleRate 8000, 44100, etc.
28 4 ByteRate == SampleRate * NumChannels * BitsPerSample/8
32 2 BlockAlign == NumChannels * BitsPerSample/8
The number of bytes for one sample including
all channels. I wonder what happens when
this number isn't an integer?
34 2 BitsPerSample 8 bits = 8, 16 bits = 16, etc.
2 ExtraParamSize if PCM, then doesn't exist
X ExtraParams space for extra parameters
The "data" subchunk contains the size of the data and the actual sound:
36 4 Subchunk2ID Contains the letters "data"
(0x64617461 big-endian form).
40 4 Subchunk2Size == NumSamples * NumChannels * BitsPerSample/8
This is the number of bytes in the data.
You can also think of this as the size
of the read of the subchunk following this
number.
44 * Data The actual sound data.
在那之后,你会发现原始 pcm 数据,像交错一样
[sample 1 ][sample 2 ]
[s1,ch1][s1,ch2][s2,ch1][s2,ch2]
您可以以写入二进制模式打开每个样本的文本文件,然后循环遍历音频数据,读取单个样本/通道的字节,然后使用fprintf
或fwrite
将它们写入正确的文件。
于 2013-02-07T10:01:10.137 回答
1
采样频率与此无关,但每个样本的大小(通常每个样本每个通道 8 或 16 位)决定了您需要使用的指针大小,因此这里是每个通道 8 位的示例:
char* reader = begin; // interleaved
char* left = malloc(numsamples); // de-interleaved
char* right = malloc(numsamples);
while(reader<end) {
*left = *reader;
++left;
++reader;
*right = *reader;
++right;
++reader;
}
要对 2 通道 16 位交错音频执行相同操作,只需将所有 3 个缓冲区声明short*
为malloc(numsamples*2)
于 2013-02-07T10:03:48.560 回答
0
假设您已将 WAV 数据加载到内存中,您需要做的就是:
- 打开两个输出文件(使用
fopen()
)。 - 循环遍历样本数据,并为每个样本:
- 将左声道的值放在第一个文件中
- 将正确通道的值放在第二个文件中
- 关闭文件。
于 2013-02-07T10:00:59.033 回答