繁体   English   中英

如何在 Python 中将 16 位 WAV 文件编码为 8 位?

[英]How to Encode a 16 Bit WAV file in 8 bit in Python?

我正在尝试从锯齿波中播放声音。 我在 Python 中创建了波形,并且能够将其保存为 WAV 文件,但是当我尝试播放它时,它说文件无法播放,因为文件类型不受支持、文件扩展名不正确或文件已损坏。 我使用了这个人的教程( https://thehackerdiary.wordpress.com/2017/06/09/it-is-ridiculously-easy-to-generate-any-audio-signal-using-python/ ),他们解决了这个问题通过在 Audacity 中将原始波形从 16 位编码为 8 位。 仅使用 Python 怎么能做到这一点?

import soundfile

data, samplerate = soundfile.read('sawtooth_100_hz.wav')
soundfile.write('sawtooth_100_hz_8bit.wav', data, samplerate, subtype='PCM_S8')

^^ 我试过这个并得到以下错误: ValueError: Invalid combination of format, subtype and endian

我认为编写本教程的人走了很长的路。 有一种更简单的方法可以将 NumPy 数组转换为 wav 文件,该文件在下面用于生成与教程中生成的相同的 wav 文件:

import numpy as np
from scipy.io import wavfile

sampling_rate = 44100
freq = 440
samples = 44100

x = np.arange(samples)
y = 100*np.sin(2 * np.pi * freq * x / sampling_rate)

wavfile.write("test.wav", sampling_rate, y)

您可以使用wavfile.read()方法毫无问题地读取此文件

令人惊讶的是,底层libsndfile库不支持带有签名的 8 位样本(仅无符号)的 WAV 文件,请参阅http://www.mega-nerd.com/libsndfile/#Features

您还可以使用soundfile模块进行检查:

>>> import soundfile as sf
>>> sf.available_subtypes('wav')
{'PCM_16': 'Signed 16 bit PCM', 'PCM_24': 'Signed 24 bit PCM', 'PCM_32': 'Signed 32 bit PCM', 'PCM_U8': 'Unsigned 8 bit PCM', 'FLOAT': '32 bit float', 'DOUBLE': '64 bit float', 'ULAW': 'U-Law', 'ALAW': 'A-Law', 'IMA_ADPCM': 'IMA ADPCM', 'MS_ADPCM': 'Microsoft ADPCM', 'GSM610': 'GSM 6.10', 'G721_32': '32kbs G721 ADPCM'}

您可以尝试改用 AIFF 或 FLAC 吗?

或者您可以创建一个 RAW 文件(即一个不包含有关其自身数据格式的信息的无头文件),这就是他们在您提到的教程中所做的(请注意,他们正在使用这些选项: -t raw -e signed -b 8 )。

有关创建和播放信号的更多信息,请参阅:

听起来您只想从 Python 中生成样本和播放?

如果是这样,看起来库“sounddevice”将允许您将样本直接写入您的音频设备:

https://python-sounddevice.readthedocs.io/en/0.3.15/usage.html#playback

我现在不在 python 环境中,所以还没有测试,但是将它与您的示例代码混合只是:

import sounddevice as sd
import numpy as np

sampling_rate = 44100
freq = 440
samples = 44100

x = np.arange(samples)
y = 100*np.sin(2 * np.pi * freq * x / sampling_rate)

sd.play(y, sampling_rate)

Sounddevice 的作者在 SO,请参阅他对类似问题的回复: https://stackoverflow.com/a/34179010/1339735

您可能需要进行一些缩放 - 不确定它是否像大多数浮点播放一样接受 -1 到 1 的值,或者像您的示例中那样接受 +/- 100 的值。

以上所有答案都很有帮助,但最终我从这个线程中找到了解决我的问题的方法: How to generate audio from a numpy array?

这是我的代码:

import numpy as np
from scipy.io.wavfile import write
from scipy import signal as sg

#data = np.random.uniform(-1,1,44100) # 44100 random samples between -1 and 1
sampling_rate = 44100                    ## Sampling Rate
freq = 150                               ## Frequency (in Hz)
duration = 3   # in seconds, may be float

t = np.linspace(0, duration, sampling_rate*duration) # Creating time vector
data = sg.sawtooth(2 * np.pi * freq * t, 0)          # Sawtooth signal

'''
Scaling data to 16 bit. Divide each number by max number in array to get
fraction and multiply data by 32767 because that is the max value a 16 bit
integer can take
'''
scaled = np.int16(data/np.max(np.abs(data)) * 32767) 
write('test.wav', 44100, scaled) # Write to file. Can be overridden

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM