numpy 将音频数据写入WAV文件的首选方法?

vwkv1x7d  于 2023-01-09  发布在  其他
关注(0)|答案(1)|浏览(271)

我正在尝试用python的wavenumpy写一个音频文件,目前为止我有以下代码,运行良好:

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()),因为没有它我的代码也能正常运行,而且这似乎是额外的开销(特别是当数组变得太大时)。

jhkqcmku

jhkqcmku1#

假设您只打算写入正弦波,则可以只创建一个周期作为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)

相关问题