简体   繁体   中英

Python: what are the nearest Linux and OSX equivalents of winsound.Beep?

If one wishes to beep the speaker on Windows, Python 2 apparently provides a useful function: winsound.Beep() . The neat thing about this function is that it takes arguments specifying the exact frequency and duration of the beep. This is exactly what I want to do, except that I don't use Windows. So...

What are the nearest equivalents of winsound.Beep() for Linux and OSX , bringing in as few dependencies as possible?

Please note that I want to be able to beep the speaker directly, not to play a sound file. Also, I need to be able to control the frequency and duration of the beep, so curses.beep() and print '\\a' won't do. Lastly, I am aware that PyGame provides extensive sound capabilities, but given that I don't require any of PyGame's other functionality, that would seem like using a sledgehammer to crack a nut (and anyway, I'm trying to do away with dependencies as far as possible).

I found a potential solution here:http://bytes.com/topic/python/answers/25217-beeping-under-linux

It involves writing directly to /dev/audio. Not sure how portable it is or if it even works at all - i'm not on a linux machine atm.

def beep(frequency, amplitude, duration):
    sample = 8000
    half_period = int(sample/frequency/2)
    beep = chr(amplitude)*half_period+chr(0)*half_period
    beep *= int(duration*frequency)
    audio = file('/dev/audio', 'wb')
    audio.write(beep)
    audio.close()

winsound is only for windows and I could not find any cross platform way to do this, other than print "/a". However, you cannot set the frequency and duration with this.

However, you can try the os.system command to do the same with the system command beep . Here is a snippet, which defines the function playsound in a platform independent way

try:
    import winsound
except ImportError:
    import os
    def playsound(frequency,duration):
        #apt-get install beep
        os.system('beep -f %s -l %s' % (frequency,duration))
else:
    def playsound(frequency,duration):
        winsound.Beep(frequency,duration)

For more info, look at this blog

EDIT: You will need to install the beep package on linux to run the beep command. You can install by giving the command

sudo apt-get install beep

This works on mac:

import numpy as np
import simpleaudio as sa

def sound(x,z):
 frequency = x # Our played note will be 440 Hz
 fs = 44100  # 44100 samples per second
 seconds = z  # Note duration of 3 seconds

 # Generate array with seconds*sample_rate steps, ranging between 0 and seconds
 t = np.linspace(0, seconds, seconds * fs, False)

 # Generate a 440 Hz sine wave
 note = np.sin(frequency * t * 2 * np.pi)

 # Ensure that highest value is in 16-bit range
 audio = note * (2**15 - 1) / np.max(np.abs(note))
 # Convert to 16-bit data
 audio = audio.astype(np.int16)

 # Start playback
 play_obj = sa.play_buffer(audio, 1, 2, fs)

 # Wait for playback to finish before exiting
 play_obj.wait_done()

sound(300,2)

sound(200,1)

The most light-weight cross-platform layer I can see is "PortAudio". This is used by R for instance in their package to wrap platform-specific driver calls into simple play/record of digitized waveforms as an array. The good folk at MIT produce a Python binding for this, but you will need to include the compiled .dll/.so for this to work. http://people.csail.mit.edu/hubert/pyaudio/

( libao is similar by Xiph the makers of Ogg/Vorbis , a wrapper pyao exists but this seems less widely used )

SoX is an excellent set of cross-platform tools with much more functionality for format conversion and reading files etc..

Using ctypes to make calls from Python to a driver is feasible but very messy, even the simplest legacy WinMM.

I've found 3 methods for Linux:

  • new method using the Linux evdev API, works with any user in the input group ( example source code )
  • old method using fcntl and /dev/console (requires root priviledges) ( example source code )
  • invoke the beep command directly with subprocess or os.system (slower and must be installed in the system).

See also my tone() function here with all the alternatives .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM