2017-02-14 49 views
1

我可以成功创建一个16位的wav文件,但是当创建一个24位文件时,我听到的只是白噪声。我正在设置24位有符号整数数据块。我是否必须在wav文件头的字节20中设置一些特殊的音频格式?我目前使用的格式1.有什么特别的我可以创建一个24位WAV文件?

编辑#1

wBitsPerSample字段设置为24。wAvgBytesPerSec(字节速率)字段设置为

// 44100 * (2 * 3) 
sampleRate * blockAlign 

wBlockAlign设置到

// 2 * 3 
numChannels * bytesPerSampe 

假设你人准备好了,数据本身需要是24位对接(需要位移和掩码,除非数据已经来自24位字节源)。或换句话说:每个样本需要3个字节。和16位字节顺序一样重要。

虽然我不知道我是否有这部分权利。

我的数据来自Float32,从-1到1(AudioBuffer.getChannelData())。我然后将其转换为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 
} 

,这个流程是否尊重规范(它好像我DOIT位移位和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); 
} 

的伎俩。我假设字节顺序不正确?我很困惑,为什么把最后一个字节放在前两个字节之前是正确的顺序。

我还建议这个问题重新开放,因为它已经足够窄而不再被视为“广泛”。

+1

你可以发布一些代码来帮助我们找出你错误的地方吗? – bejado

+0

请看我编辑的相关代码。 – maximedupre

回答

0

从在后的有限上下文 -

字段wBitsPerSample()内fmt->fmt-ck格式特定块,使用1-(PCM为wFormatTag是细)必须反映每个样品,即比特数。 24在这种情况下。假设你已经做了,数据本身需要是24位对接(需要位移和掩码,除非数据已经来自24位字节源)。或换句话说:每个样本需要3个字节。和16位字节顺序一样重要。

wAvgBytesPerSecwBlockAlign的计算方法与刚才的新比特大小一样。

+0

请查看我的编辑以获取更多与您的答案相关的信息。 – maximedupre

+0

我认为你指出了我的好方向,就像16位字节顺序一样。“如果您有时间添加说明,请查看我的编辑。谢谢! – maximedupre

+1

@ maximedupre是的,这是一个字节顺序问题。在旧版本中,字节更加“混洗”,而它们需要按顺序排列。 little-endian会颠倒顺序(16位写入),然后在错误的末尾添加MSB(此处为最高有效字节)或LSB。在新的变体中,顺序应该是这样。 – K3N

相关问题