【问题标题】:Scipy Write Audio IssueScipy 写音频问题
【发布时间】:2017-02-03 08:56:37
【问题描述】:

我正在做一个 ICA 应用程序,我的目标是从混合信号观察中分离信号。它似乎在理论上有效,当我从 numpy ndarray 中查看 ICA 恢复的信号时,信号清晰可见。但是,当我尝试将此 ndarray 写入 .wav 进行播放时,信号完全消失了。从下图中可以很容易地看出这一点:

第一张图显示了 ICA 恢复信号的 numpy ndarray 信号。第二张图显示了我只是加载了应该由 scipy .wav write 写入的文件,你可以看到它是无声的。

这种行为令人费解,因为之前我使用了完全相同的程序来使用混合矩阵生成混合信号观测值(也采用相同的格式,numpy ndarrays)。在下图中,您会注意到每件事都完全相同,但是,无论出于何种原因,scipy write .wav 工作——第二张图确实验证了信号是从 .wav 加载的。从第一个图(numpy nd 数组)写入的 wav。

我想知道有条件成功的背后是什么。我知道浮点数和整数需要小心处理,但我很确定我没有忽略任何事情。

图片很好地解释了它,我唯一想澄清的是play_wav函数在做什么,它基本上只是编写.wav并创建一个音频对象:

def play_wav(file, fs, data):
    wavfile.write(file, fs, data.astype(np.dtype('i2')))
    display(Audio(filename=file))

进口:

import numpy as np
from scipy.io import wavfile
from IPython.display import display, Audio
from sklearn.decomposition import FastICA

【问题讨论】:

  • 你还没有显示函数load_wav。如果您能提供一个MVCE,我们可以复制并运行它以重新创建问题,这将有所帮助。
  • 公平点,这是一个包含我整个 jupyter 笔记本的存储库。目前上传速度很低,我在这个链接上只使用了 1 个 .wav。我会尽快更新它以包含所有 3 个 .wav。如果需要,您可以使用自己的 .wav。当然,如果你只是想看看事物的内部运作,你可以查看 notebook ipynb 文件。这是:github.com/diggetybo/ICA-Attachments
  • 好的,现在所有 3 个 .wav 都在那里。如果有人想 100% 重新创建我的程序,那现在是可能的。将 .wavs 放在 jupyter notebook 目录中。

标签: python audio scipy scikit-learn signal-processing


【解决方案1】:

看起来您尝试写入的数组包含 [-0.02, 0.02] 范围内的值。在将数组写入 WAV 文件之前将数组转换为 16 位整数时,所有这些值都将被截断为零!

wavfile.write 支持 float32 数组,因此您可以完全跳过转换步骤。或者,在将数组转换为 int16 之前,将数组重新缩放到介于 215 和 -215 之间,例如:

((data + data.min()) * (2 ** 15) / data.ptp()).astype(np.int16)

【讨论】:

  • 伟大的工作 ali_m,你找到了问题!我可能永远不会注意到这一点。只是出于好奇,你为什么选择2^15?是因为这样会插入它们以接近其原始水平吗?所以你从笔记本开头的.wavs中查看“真实信号”就知道了它们的原始水平,我猜?我问是因为我想为一般情况写那行,在这种情况下,我可能需要一个公式来确定要使用的基数和幅度。还是 2^15 是某种标准?
  • 16 位有符号整数可以表示 2^15(实际上是 2^15 - 1)和 -2^15 之间的值。有 15 位来编码每个整数的大小,然后用 1 位来编码它的符号。当您从浮点数转换为整数时,数组中的每个值都将向下舍入到最接近的整数。通过缩放值以填充可表示整数的范围,您可以最大限度地减少由于这种舍入造成的精度损失。
  • 现在说得通了,如果没有你,这一切都做不成!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-08
  • 2018-07-19
相关资源
最近更新 更多