8

I have tried a number of ways of playing a fixed frequency sound (e.g. 1000Hz) and nothing works.

I have downloaded "beep" and that makes no noise.

I tried interfacing to pyao, and that had no effect.

I tried interfacing to audiere, and get a runtime error indicating the library could not be found, despite installing it from the software centre.

Any guidance for installation of appropriate libraries and relevant code would be most appreciated.

I cannot generate .mp3/ .wav files for this, but need to generate the tones at run time.

Many thanks for you

  • You need to make WAVE a float. Why not call it FREQ? Also the equation is not right. Try this: math.sin((x*2*math.pi*FREQ)/RATE)*127)+128 – user216759 Nov 17 '13 at 20:46
  • Better implementations can be found here: stackoverflow.com/questions/974071/… – Gringo Suave Feb 12 at 20:47
10
import math
#sudo apt-get install python-pyaudio
from pyaudio import PyAudio

#See http://en.wikipedia.org/wiki/Bit_rate#Audio
BITRATE = 16000 #number of frames per second/frameset.      

#See http://www.phy.mtu.edu/~suits/notefreqs.html
FREQUENCY = 261.63 #Hz, waves per second, 261.63=C4-note.
LENGTH = 1.2232 #seconds to play sound

NUMBEROFFRAMES = int(BITRATE * LENGTH)
RESTFRAMES = NUMBEROFFRAMES % BITRATE
WAVEDATA = ''    

for x in xrange(NUMBEROFFRAMES):
   WAVEDATA += chr(int(math.sin(x / ((BITRATE / FREQUENCY) / math.pi)) * 127 + 128))    

#fill remainder of frameset with silence
for x in xrange(RESTFRAMES): 
    WAVEDATA += chr(128)

p = PyAudio()
stream = p.open(
    format=p.get_format_from_width(1),
    channels=1,
    rate=BITRATE,
    output=True,
    )
stream.write(WAVEDATA)
stream.stop_stream()
stream.close()
p.terminate()
| improve this answer | |
  • 2
    it should be (2*math.pi) – jfs Oct 28 '14 at 15:29
  • I had to had future division and 2*math*pi to make it work correctly. Python 2.8 32 bit – chwi Nov 10 '15 at 10:26
  • Python 2.7 plays this as a "smooth" sound whereas Python 3.4 produces a much "buzzier" sound. Why? I tried adding the ____future____ division, but it made no difference. – Ubuntourist Dec 19 '15 at 20:29
  • @Ubuntourist I am not sure, but i think your python 2.7 use a 8-Bit encoding and your Python 3.4 use UTF8, so the char() use 2 Bytes for some Values on Python 3.4 which is not what we want here. – 12431234123412341234123 Jun 3 '17 at 9:52
  • If you use bytestrings instead of python3's charstrings you should get the desired effect – pizzapants184 Jul 20 '17 at 20:35
4

You can do that with python-pyaudio (available at least in 12.04):

from __future__ import division #Avoid division problems in Python 2
import math
import pyaudio
import sys

PyAudio = pyaudio.PyAudio
RATE = 16000
WAVE = 1000
data = ''.join([chr(int(math.sin(x/((RATE/WAVE)/math.pi))*127+128)) for x in xrange(RATE)])
p = PyAudio()

stream = p.open(format =
                p.get_format_from_width(1),
                channels = 1,
                rate = RATE,
                output = True)
for DISCARD in xrange(5):
    stream.write(data)
stream.stop_stream()
stream.close()
p.terminate()
| improve this answer | |
  • Thank you for your help. Unfortunately, I get loads of errors when running, and making any changes to RATE or WAVE results in no sound. The errors are not listed due to a lack of space but refer to "ALSA lib". How would I change a) to eliminate errors and b) to change duration and frequency? Many thanks, – user98415 Oct 22 '12 at 10:52
  • I also get a bunch of error messages, but it plays just fine. Also, changing WAVE gives me different pitch. Are you using jack? Or just pulseaudio? – taneli Oct 23 '12 at 17:33
  • 2
    @user98415: add at the top from __future__ import division to avoid unnecessary truncation on Python 2. – jfs Oct 28 '14 at 15:05
  • @J.F.Sebastian That solved everything for me, thank you – chwi Nov 10 '15 at 10:02

Not the answer you're looking for? Browse other questions tagged or ask your own question.