I tried different ways to play sine waves in sounddevice, and they worked fine, until I tried to overlay multiple frequencies at once. I also get loud scratching noises in my speaker whenever there are no frequencies to play. I've simplified my code to this:
import sounddevice
import numpy
SAMPLE_RATE = 44100
frequencies = {440: 0, 550: 0, 660: 0}
# hz: start_index
def callback(outdata: numpy.ndarray, frames: int, time, status) -> None:
"""writes sound output to 'outdata' from sound_queue."""
# params may need annotations... :/
result = None
for frequency, start_index in frequencies.items():
t = (start_index + numpy.arange(frames)) / SAMPLE_RATE
t = t.reshape(-1, 1)
wave = numpy.sin(2 * numpy.pi * frequency * t)
if result is None:
result = wave
else:
result += wave
frequencies[frequency] += frames
if result is None:
result = numpy.arange(frames) / SAMPLE_RATE
result = result.reshape(-1, 1)
outdata[:] = result
stream = sounddevice.OutputStream(channels=1, samplerate=SAMPLE_RATE, callback=callback)
stream.start()
while True:
pass