[英]Preferred way to write audio data to a WAV file?
我正在尝试使用 python 的wave
和numpy
编写音频文件。 到目前为止,我有以下内容并且效果很好:
import wave
import numpy as np
# set up WAV file parameters
num_channels = 1 # mono audio
sample_width = 1 # 8 bits(1 byte)/sample
sample_rate = 44.1e3 # 44.1k samples/second
frequency = 440 # 440 Hz
duration = 20 # play for this many seconds
num_samples = int(sample_rate * duration) # samples/seconds * seconds
# open WAV file and write data
with wave.open('sine8bit_2.wav', 'w') as wavfile:
wavfile.setnchannels(num_channels)
wavfile.setsampwidth(sample_width)
wavfile.setframerate(sample_rate)
t = np.linspace(0, duration, num_samples)
data = (127*np.sin(2*np.pi*frequency*t)).astype(np.int8)
wavfile.writeframes(data) # or data.tobytes() ??
我的问题是,由于我使用的是高采样率, num_samples
变量可能会很快变得太大(比如 3 分 30 秒的轨道有 9261000 个样本)。 使用这么大的 numpy 数组是否可取? 有没有更好的方法来解决这个问题? 在这种情况下还需要使用writeframes(.tobytes())
,因为我的代码在没有它的情况下运行良好,而且看起来像是额外的开销(特别是如果 arrays 变得太大)。
假设您只打算写入一个正弦波,您可以只创建一个周期作为data
数组并将其多次写入.wav
文件。
使用您提供的参数,您的data
数组使用该方法缩小了 8800 倍。 它的大小也不再取决于文件的持续时间!
import wave
import numpy as np
# set up WAV file parameters
num_channels = 1 # mono audio
sample_width = 1 # 8 bits(1 byte)/sample
sample_rate = 44.1e3 # 44.1k samples/second
frequency = 440 # 440 Hz
duration = 20 # play for this many seconds
# Create a single period of sine wave.
n = round(sample_rate/frequency)
t = np.linspace(0, 1/frequency, n)
data = (127*np.sin(2*np.pi*frequency*t)).astype(np.int8)
periods = round(frequency*duration)
# open WAV file and write data
with wave.open('sine8bit_2.wav', 'w') as wavfile:
wavfile.setnchannels(num_channels)
wavfile.setsampwidth(sample_width)
wavfile.setframerate(sample_rate)
for _ in range(periods):
wavfile.writeframes(data)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.