创建24位WAV文件有什么特别的事情吗? [英] Is there anything special I have to do to create a 24-bit WAV file?
问题描述
我可以成功创建一个16位的wav文件,但是当创建一个24位的文件时,我听到的只是白噪声.我正在设置24位带符号整数数据块.我必须在wav文件头的字节20处设置一些特殊的音频格式吗?我当前正在使用格式1.
I can successfully create a 16-bit wav file, but when creating a 24-bit file, all I hear is white noise. I'm setting 24-bit signed integer data chunks. Do I have to set some special audio format at byte 20 in the wav file header? I'm currently using format 1.
编辑#1
wBitsPerSample
字段设置为24.wAvgBytesPerSec
(字节速率)字段设置为
The wBitsPerSample
field is set to 24. The wAvgBytesPerSec
(byte rate) field is set to
// 44100 * (2 * 3)
sampleRate * blockAlign
和wBlockAlign
设置为
// 2 * 3
numChannels * bytesPerSampe
假设您已经做过,则数据本身需要24位对接(需要移位和屏蔽,除非数据已经来自24位字节源).或换种说法:每个样本将占用3个字节.与16位一样,字节顺序也很重要.
Assuming you already did, the data itself needs to be 24-bit butt-to-butt (requires bit-shifting and masking unless the data already is from a 24-bit byte source). Or put differently: each sample will take 3 bytes. And as with 16-bit the byte-order matters.
不过,我不知道这部分是否正确.
I don't know if I got this part right, though.
我的数据以Float32的形式出现,从-1到1(AudioBuffer.getChannelData()
).然后将其转换为Int24:
My data comes in the form of Float32 that goes from -1 to 1 (AudioBuffer.getChannelData()
). I then convert it to Int24:
function floatTo24BitPCM(output, offset, input) {
for (var i = 0; i < input.length; i++, offset += 3) {
var s = Math.floor(input[i] * 8388608 + 0.5)
output.setInt24(offset, s, true)
}
}
和
DataView.prototype.setInt24 = function(pos, val, littleEndian) {
this.setInt16(pos, val >> 8, littleEndian);
this.setInt8(pos+2, val & ~4294967040, littleEndian); // this "magic number" masks off the first 16 bits
}
此过程是否符合规范(似乎我在setInt24
中进行位移位和屏蔽)?
Does this process respect the specification (it seems like I'm doit bit shifting and masking in setInt24
)?
编辑#2
修改
DataView.prototype.setInt24 = function(pos, val, littleEndian) {
this.setInt16(pos, val >> 8, littleEndian);
this.setInt8(pos+2, val & ~4294967040, littleEndian); // this "magic number" masks off the first 16 bits
}
到
DataView.prototype.setUint24 = function(pos, val, littleEndian) {
this.setUint8(pos, val & ~4294967040, littleEndian); // this "magic number" masks off the first 16 bits
this.setUint16(pos + 1, val >> 8, littleEndian);
}
成功了.我认为字节顺序不正确?我对为什么采用最后一个字节并将其放在前两个字节之前是正确的顺序感到困惑.
did the trick. I assume that the byte-order was incorrect? I'm confused as to why taking the last byte and putting it before the first two bytes is the correct order.
我还建议重新提出这个问题,因为它的范围非常狭窄,不再被认为是广泛的".
I also suggest that this question is re-opened as it is narrow enough to not be considered as "broad" anymore.
推荐答案
从帖子的有限上下文中-
From the limited context in the post -
字段wBitsPerSample
(在fmt->fmt-ck
格式特定的块内,对于wFormatTag
使用1(PCM)很好)必须反映每个样本的位数,即.在这种情况下为24.
The field wBitsPerSample
(inside fmt->fmt-ck
format specific chunk, using 1 (PCM) for wFormatTag
is fine) must reflect number of bits per sample, ie. 24 in this case.
假设您已经做过,则数据本身需要24位对接(需要移位和屏蔽,除非数据已经来自24位字节源).或换种说法:每个样本将占用3个字节.与16位一样,字节顺序也很重要.
Assuming you already did, the data itself needs to be 24-bit butt-to-butt (requires bit-shifting and masking unless the data already is from a 24-bit byte source). Or put differently: each sample will take 3 bytes. And as with 16-bit the byte-order matters.
wAvgBytesPerSec
和wBlockAlign
的计算与以前一样,只是具有新的位大小.
wAvgBytesPerSec
and wBlockAlign
are calculated as before just with the new bit size.
这篇关于创建24位WAV文件有什么特别的事情吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!