Подтвердить что ты не робот

Python: каковы ближайшие эквиваленты Linux и OSX от winsound.Beep?

Если вы хотите подать звуковой сигнал о динамике в Windows, Python 2, очевидно, обеспечивает полезную функцию: winsound.Beep(). Оптимальная вещь об этой функции заключается в том, что она принимает аргументы, определяющие точную частоту и продолжительность звукового сигнала. Это именно то, что я хочу сделать, за исключением того, что я не использую Windows. Так что...

Каковы ближайшие эквиваленты winsound.Beep() для Linux и OSX, привнося как можно меньше зависимостей?

Обратите внимание, что я хочу, чтобы вы могли напрямую подавать звуковой сигнал, а не воспроизводить звуковой файл. Кроме того, мне нужно иметь возможность контролировать частоту и продолжительность звукового сигнала, поэтому curses.beep() и print '\a' не будут работать. Наконец, я знаю, что PyGame предоставляет обширные звуковые возможности, но, учитывая, что я не требую каких-либо других функций PyGame, это похоже на использование кувалды, чтобы взломать орех (и в любом случае я пытаюсь избавиться от зависимостей насколько это возможно).

4b9b3361

Ответ 1

Я нашел здесь потенциальное решение: http://bytes.com/topic/python/answers/25217-beeping-under-linux

Он включает в себя запись непосредственно в /dev/audio. Не уверен, насколько он переносится или даже работает вообще - я не на Linux-машине 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()

Ответ 2

winsound только для окон, и я не мог найти кросс-платформенный способ сделать это, кроме print "/a". Однако вы не можете установить частоту и продолжительность с помощью этого.

Однако вы можете попробовать команду os.system сделать то же самое с системной командой beep. Вот фрагмент, который определяет функцию, которая имеет независимый от платформы способ

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)

Для получения дополнительной информации просмотрите этот блог

EDIT: вам нужно будет установить звуковой пакет на linux для запуска команды beep. Вы можете установить, указав команду

sudo apt-get install beep

Ответ 3

Самый легкий кросс-платформенный уровень, который я вижу, - "PortAudio". Это используется R, например, в их пакете, чтобы обернуть вызовы драйвера конкретной платформы в простой режим воспроизведения/записи оцифрованных осциллограмм в виде массива. Хорошие люди в М.И.Т. создайте для этого привязку Python, но вам нужно будет включить скомпилированный .dll/.so для этого. http://people.csail.mit.edu/hubert/pyaudio/

(libao похож на Xiph создателей Ogg/Vorbis, существует оболочка pyao, но это кажется менее широко используемым)

SoX - отличный набор кросс-платформенных инструментов с гораздо большей функциональностью для преобразования формата и чтения файлов и т.д.

Использование ctypes для совершения звонков с Python на драйвер возможно, но очень грязно, даже простейшее унаследованное WinMM.

Ответ 4

Я нашел 3 метода для Linux:

  • Новый метод с использованием API evdev Linux работает с любым пользователем в группе input (пример исходного кода)
  • старый метод с использованием fcntl и /dev/console (требует привилегий root) (пример исходного кода)
  • вызвать команду beep непосредственно с помощью subprocess или os.system (медленнее и должно быть установлено в системе).

См. также моя функция tone() здесь со всеми альтернативами.

Ответ 5

Это работает на 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)