我正在尝试实施Karplus-Strong算法。
当我玩(通过Jupyter Notebook使用音频(y,rate = Fs))收集的numpy数组(代表吉他音乐)时,一切正常。
不幸的是,使用WAVE模块将numpy数组: y 写入wav文件是不正确的(使用下一个python代码):
noise_output = wave.open('k-s.wav', 'w')
noise_output.setparams((1, 4, Fs, 0, 'NONE', 'not compressed'))
for i in range(0, len(y)):
value = y[i]
packed_value = struct.pack('f', value)
noise_output.writeframes(packed_value)
noise_output.close()
y 的每个元素都是
<type 'numpy.float64'>
为了正确写入WAV文件,我应该如何修改写循环?
有关此问题的更多信息。在写入WAV之前,y数组的第一个元素是:
[ 0.33659756 0.33659756 -0.43915295 -0.87036152 1.40708988 0.32123558
-0.6889402 1.9739982 -1.29587159 -0.12299964 2.18381762 0.82228042
0.24593503 -1.28067426 -0.67568838 -0.01843234 -1.830472 1.2729578
-0.56575346 0.55410736]
将元素写入WAV文件后,关闭WAV文件并再次读取,我得到了收集数组的前20个元素:
[ 1051481732 1051481732 -1092560728 -1084305405 1068768133 1050966269
-1087349149 1073523705 -1079648481 -1107564740 1074512811 1062371576
1048303204 -1079775966 -1087571478 -1130954901 -1075163928 1067642952
-1089415880 1057872379]
答案 0 :(得分:2)
import scipy.io.wavfile
scipy.io.wavfile.write("karplus.wav", Fs, y)
多田! AFAIK适用于float64和float32,可能还有其他。对于立体声,形状必须是(nb_samples,2)。请参阅scipy.io.wavfile.write。
答案 1 :(得分:0)
以下是使用wave
标准库编写(立体声)波形文件的代码示例。
我提供了两个示例:一个使用numpy
,另一个不需要任何依赖项。
请注意,如果您的数据位于numpy数组中,则不需要struct
库。
import wave
import numpy as np
samplerate = 44100
# A note on the left channel for 1 second.
t = np.linspace(0, 1, samplerate)
left_channel = 0.5 * np.sin(2 * np.pi * 440.0 * t)
# Noise on the right channel.
right_channel = np.random.random(size=samplerate)
# Put the channels together with shape (2, 44100).
audio = np.array([left_channel, right_channel]).T
# Convert to (little-endian) 16 bit integers.
audio = (audio * (2 ** 15 - 1)).astype("<h")
with wave.open("sound1.wav", "w") as f:
# 2 Channels.
f.setnchannels(2)
# 2 bytes per sample.
f.setsampwidth(2)
f.setframerate(samplerate)
f.writeframes(audio.tobytes())
(几乎)这是相同的代码,但是没有使用numpy
。不需要外部依赖项。
import math
import random
import struct
import wave
samplerate = 44100
left_channel = [
0.5 * math.sin(2 * math.pi * 440.0 * i / samplerate) for i in range(samplerate)
]
right_channel = [random.random() for _ in range(samplerate)]
with wave.open("sound2.wav", "w") as f:
f.setnchannels(2)
f.setsampwidth(2)
f.setframerate(samplerate)
for samples in zip(left_channel, right_channel):
for sample in samples:
sample = int(sample * (2 ** 15 - 1))
f.writeframes(struct.pack("<h", sample))