For anyone who finds this in the future, I've opened up this thread on stackoverflow, which will hopefully be more informative: https://stackoverflow.com/questions/66129025/generated-sine-wave-sounds-buzzy-or-square-instead-of-sine

I am working on a toolkit to visualize sound, and also to write custom synthesizers. I wrote the following program, which generates a 100Hz sine wave, plays it back to me through python's simpleaudio package, and plots the signal that was played.

import numpy as np
import simpleaudio as sa
import matplotlib.pyplot as plt

def generate_sine_tone(numsamples, sample_time, frequency):
    t = np.arange(numsamples) * sample_time # Time vector
    signal = 8388605*np.sin(2*np.pi * frequency*t)
    return signal

if __name__ == "__main__":
    duration = 1
    samprate = 44100 # Sampling rate
    numsamples = samprate*duration# Sample count
    st = 1.0 / samprate # Sample time
    t = np.arange(numsamples) * st # Time vecto

    nchannels = 2
    sampwidth = 3

    signal = generate_sine_tone(numsamples, st, 100)
    signal2 = np.asarray([ int(x) for x in signal ])

    play_obj = sa.play_buffer(signal2, nchannels, sampwidth, samprate)

However, despite looking correct, the signal that is played back sounds buzzy, like a square wave, instead of a sine wave. At first I thought this was a code problem, but I've spent a lot of time trying to debug, and it seems to be working as anticipated.

enter image description here enter image description here

So my question is this: Does this signal look correct to produce a smooth sine wave? Is there some kind of configuration error? Do I need to further process the signal to get something like this?

Thank you for any contribution.

  • I cannot install simpleaudio, but still I've some doubts. That wave doesn't seem a sine, more like a sawtooth (but could be related to the antialiasing of matplotlib). Also, a sample width of 3 means 24 bits, which is not odd, but still uncommon, and might even not be completely compatible with your audio system (resulting in dithering). Then, I don't know how simpleaudio deals with inconsistent channel counts, but it seems to me that you're feeding a monodimensional array while trying to play it on two channels (which would result in strange results depending on the frequency of the signal). – musicamante Feb 9 at 22:18
  • 2
    This would probably be better answered on stackoverflow. I can't spot any logical errors here, but you could possibly print your audio to a wav file and see if the problem persists, and if it does, maybe share the audio here. "Square wave" suggests clipping to me but your values seem to be within the range of 24 bit audio as you specified, so I don't see why it would clip. – Edward Feb 9 at 22:20
  • 1
    In order to debug it you can try to display the waveform that is actually played back by your computer, e.g. by recording it with in another application. Also, while I'm unfamiliar with the library, I don't understand why you specify 2 channels, while providing 1-dimensional array... or could there be another requirement for the input data – user1079505 Feb 9 at 23:02
  • 1
    aha ok. maybe @piiperiReinstateMonica can expand on his concerns about what is passed to play_buffer... – topo Reinstate Monica Feb 10 at 0:04
  • 2
    The OP has raised this on StackOverflow as it is a programming question, not actually a Music question - so I'll close here. – Doktor Mayhem Feb 10 at 10:22