问题
I've been trying to generate a sine wave using the following code and playing it thought my speakers, but it sounds horrible. Anyone knows why? It does not sound like a sine wave.
dur = int(FS * float(duration) / 1000)
for i in range(dur):
a = frequency * i * 2 * math.pi / FS
y = math.sin(a)
outbuf[i] = y * 0.2
p = pyaudio.PyAudio()
stream = p.open(format=pyaudio.paFloat32, channels=1, rate=44100, output=True)
stream.write(outbuf)
stream.stop_stream()
stream.close()
p.terminate()
play_sound("sine", 1000, 1, 1000)
回答1:
the audio buffer must be packed into binary, for python3 use b''.join(struct.pack
also simplified the sin curve synthesis by moving the angle theta increment constant to outside of the loop
import pyaudio
import numpy as np
import math
import struct
FS = 44100 # frames per second, samples per second or sample rate
def play_sound(type, frequency, volume, duration):
generate_sound(type, frequency, volume, duration)
def generate_sound(type, frequency, volume, duration):
outbuf = np.random.normal(loc=0, scale=1, size=int(float(duration / 1000.0)*FS))
if type == "sine":
dur = int(FS * float(duration / 1000.0))
theta = 0.0
incr_theta = frequency * 2 * math.pi / FS # frequency increment normalized for sample rate
for i in range(dur):
outbuf[i] = volume * math.sin(theta)
theta += incr_theta
p = pyaudio.PyAudio()
stream = p.open(format=pyaudio.paFloat32, channels=1, rate=FS, output=True)
data = b''.join(struct.pack('f', samp) for samp in outbuf) # must pack the binary data
stream.write(data)
stream.stop_stream()
stream.close()
p.terminate()
play_sound("sine", 220, 0.8, 1000) # duration in milliseconds
来源:https://stackoverflow.com/questions/61576953/generating-a-sine-wave-sound-in-python