Generating sine wave sound in Python

后端 未结 6 1124
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-01 05:31

I need to generate a sine wave sound in Python, and I need to be able to control frequency, duration, and relative volume. By \'generate\' I mean that I want it to play thou

相关标签:
6条回答
  • 2020-12-01 05:50
    import pyaudio
    import numpy as np
    
    p = pyaudio.PyAudio()
    
    volume = 0.5     # range [0.0, 1.0]
    fs = 44100       # sampling rate, Hz, must be integer
    duration = 1.0   # in seconds, may be float
    f = 440.0        # sine frequency, Hz, may be float
    
    # generate samples, note conversion to float32 array
    samples = (np.sin(2*np.pi*np.arange(fs*duration)*f/fs)).astype(np.float32)
    
    # for paFloat32 sample values must be in range [-1.0, 1.0]
    stream = p.open(format=pyaudio.paFloat32,
                    channels=1,
                    rate=fs,
                    output=True)
    
    # play. May repeat with different volume values (if done interactively) 
    stream.write(volume*samples)
    
    stream.stop_stream()
    stream.close()
    
    p.terminate()
    
    0 讨论(0)
  • 2020-12-01 05:50

    ivan-onys gave an excellent answer, but there is a little addition to it: this script will produce 4 times shorter sound than expected because Pyaudio write method needs string data of float32, but when you pass numpy array to this method, it converts whole array as entity to a string, therefore you have to convert data in numpy array to the byte sequence yourself like this:

    samples = (np.sin(2*np.pi*np.arange(fs*duration)*f/fs)).astype(np.float32).tobytes()
    

    and you have to change this line as well:

    stream.write(samples)
    
    0 讨论(0)
  • 2020-12-01 05:59

    The script from ivan_onys produces a signal that is four times shorter than intended. If a TypeError is returned when volume is a float, try adding .tobytes() to the following line instead.

    stream.write((volume*samples).tobytes())
    

    @mm_ float32 = 32 bits, and 8 bits = 1 byte, so float32 = 4 bytes. When samples are passed to stream.write as float32, byte count (duration) is divided by 4. Writing samples back .tobytes() corrects for quartering the sample count when writing to float32.

    0 讨论(0)
  • 2020-12-01 06:04

    I the bregman lab toolbox you have a set of functions that does exactly what you want. This python module is a little bit buggy but you can adapt this code to get your own functions

    0 讨论(0)
  • 2020-12-01 06:06

    One of the more consistent andeasy to install ways to deal with sound in Python is the Pygame multimedia libraries.

    I'd recomend using it - there is the pygame.sndarray submodule that allows you to manipulate numbers in a data vector that become a high-level sound object that can be playerd in the pygame.mixer module.

    The documentation in the pygame.org site should be enough for using the sndarray module.

    0 讨论(0)
  • 2020-12-01 06:06

    Today for Python 3.5+ the best way is to install the packages recommended by the developer.

    http://people.csail.mit.edu/hubert/pyaudio/

    For Debian do

    sudo apt-get install python3-all-dev portaudio19-dev
    

    before trying to install pyaudio

    0 讨论(0)
提交回复
热议问题