Search code examples
pythonpython-3.xaudiopyaudio

Generating a sine wave sound in python


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)

Solution

  • 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
    

    above python executes just fine on my Ubuntu laptop across various release including ubuntu 20.04 ... however below is output to terminal when I run above code ... just ignore below messages sadly those are normal

    python generate_sin_wave_sound.py 
    
    ALSA lib pcm.c:2642:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear
    ALSA lib pcm.c:2642:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe
    ALSA lib pcm.c:2642:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side
    ALSA lib pcm_route.c:869:(find_matching_chmap) Found no matching channel map
    ALSA lib pcm_route.c:869:(find_matching_chmap) Found no matching channel map
    ALSA lib pcm_route.c:869:(find_matching_chmap) Found no matching channel map
    ALSA lib pcm_route.c:869:(find_matching_chmap) Found no matching channel map
    Cannot connect to server socket err = No such file or directory
    Cannot connect to server request channel
    jack server is not running or cannot be started
    JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
    JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
    Cannot connect to server socket err = No such file or directory
    Cannot connect to server request channel
    jack server is not running or cannot be started
    JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
    JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
    ALSA lib pcm_oss.c:377:(_snd_pcm_oss_open) Unknown field port
    ALSA lib pcm_oss.c:377:(_snd_pcm_oss_open) Unknown field port
    ALSA lib pcm_usb_stream.c:486:(_snd_pcm_usb_stream_open) Invalid type for card
    ALSA lib pcm_usb_stream.c:486:(_snd_pcm_usb_stream_open) Invalid type for card
    Cannot connect to server socket err = No such file or directory
    Cannot connect to server request channel
    jack server is not running or cannot be started
    JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
    JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock