【问题标题】:How do wave files store multiple channels?波形文件如何存储多个通道?
【发布时间】:2011-02-27 23:06:20
【问题描述】:

我使用 Audacity 创建了两个波形文件。两者都有 44100hz 采样率,32 位浮点采样,保存为 WAV(Microsoft)16 位签名并包含 1 秒的静音(根据 Audacity)。不同之处在于一个文件包含一个通道,而另一个文件包含两个(立体声)。读取一个通道文件时,我得到这样的帧:

0x00 0x00  
...  ...  

正如预期的那样,但是在读取第二个文件时我得到了:

0x00 0x00 0x00 0x00  
0x01 0x00 0xff 0xff  
0x00 0x00 0x00 0x00  
0x00 0x00 0x01 0x00  
0xff 0xff 0x01 0x00  
0xfe 0xff 0x03 0x00  

这对我来说似乎是一个随机模式。它与频道在波形文件中的存储方式有关吗?不应该是这样的:

0x00 0x00 0x00 0x00  
...  ...  ...  ...  

?

PS:我已经使用 python 内置模块 'wave' 来读取文件。

【问题讨论】:

  • 我需要答案来编写一个程序,该程序从单声道文件中读取,复制其频道并在一个频道的开头添加 0.2 秒的静音,等等。

标签: python audio wave


【解决方案1】:

已删除代码和上一篇文章。

静音:“真正的”静音必须为零。否则,它通常被称为“房间”静音,如果您不使用噪音门,它会随处可见的非常小的噪音。 (记录) 它只是一个想法:请记住,使用有符号值将导致 1 位用于有符号/无符号标记。也许(我不知道)这是您在使用 audacity 将其转换为签名的波形文件后所看到的。对不起,但我没有时间测试这个。

波形文件: 我不知道您对声音文件了解多少,但是: 如果您只想添加静音,请尝试以下方式: 每个样本的大小为 X 位:因此一个样本需要 X/8 个字节。 您知道采样率 - 因此您可以将原始原始字节数组复制到大小之一 (silence_length_in_samplesbytes_per_frame)+(original)+(silence_length_in_samplesbytes_per_frame) 并使用我希望python工具可以做到这一点。

2 频道: 原始字节按以下方式组织: [sample1(channel1_bytes,channel2bytes)][sample2(channel1_bytes,channel2_bytes).... 我希望我的意思很清楚:)

【讨论】:

  • 我认为这回答了我的问题。该例程非常有帮助。谢谢你。 PS:我仍然对“静音”立体声文件的随机字节模式感到困惑。也许 Audacity 或 wave 模块中确实存在错误。
  • 请注意例程 - 它仅适用于具有 little_endian 和 1 通道的 16 位签名文件的 testet。 (此时采样率不关心)这就是我删除它的原因。原理是正确的,但我想我必须重新处理已签名/未签名的事情。
【解决方案2】:

据我所知,通道应该是交替的,因此 44.1 khz 的 1 秒将是 88,200 k 样本的流,左右交替或规范所说的任何内容。

Audacity 也不应该得到 float -> int 转换错误,反之亦然。尝试从整数样本而不是浮点数开始。或者让一个通道为已知值(即 Ox8f8f)而另一个为 0,这可能更容易弄清楚。

【讨论】:

  • 现在我知道这是个好主意。我只是想做同样的事情。 :P 谢谢。
【解决方案3】:

您可以使用此代码查看这些数字:

import struct
struct.unpack("f", struct.pack("I", 0xfeff0300))
(-1.6948435790786458e+38,)

它们看起来都非常小,可以说是无声的数字。我生成了静音并将其保存为 32 位浮点 WAV,并且没有得到小数字。我的文件包含零,不包括标题。

0.2 秒静默,2 通道浮点数据可以像这样生成:

import array
silence = array.array("f", [0] * int(44100 * 2 * 0.2))

【讨论】:

  • 其实 -1.6948435790786458e+38 是一个非常大的负数,不是沉默的一部分。您不应该将数据视为 4byte 浮点数,它是 2 个通道 x 2 个字节(小端序)
【解决方案4】:

预期静音的极低电平信号可能是由在从 32 位到 16 位的转换中使用的dither 引起的。

【讨论】:

  • 这是有道理的。我忘记了抖动。
【解决方案5】:

数据不是随机的

看着它,我似乎每行看到 2 个 int 值,每行 2 个字节为 little-endian:

0x00 0x00 0x00 0x00  
0x01 0x00 0xff 0xff  
0x00 0x00 0x00 0x00  
0x00 0x00 0x01 0x00  
0xff 0xff 0x01 0x00  
0xfe 0xff 0x03 0x00  

解码为:

 0  0
 1 -1
 0  0
 0  1
-1  1
-2  3

所以你看到那些非常接近 0 的数字(几乎是沉默),就像其他人所建议的那样抖动。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-06
    • 2023-03-10
    相关资源
    最近更新 更多