고정 주파수 사운드를 재생하기위한 파이썬 라이브러리
문제
집에 모기 문제가 있습니다. 이것은 일반적으로 프로그래머 커뮤니티와 관련이 없습니다. 그러나 나는 17kHz 톤을 연주함으로써 이러한 불쾌한 생물을 방해한다고 주장하는 일부 장치를 보았습니다. 노트북을 사용 하여이 작업을 수행하고 싶습니다.
한 가지 방법은 AA 단일 고정 주파수 톤으로 MP3를 만드는 것입니다.이것은 Audacity에 의해 쉽게 수행 될 수 있습니다), 파이썬 라이브러리로 열립니다 반복적으로 연주합니다.
두 번째는 컴퓨터 내장 스피커를 사용하여 사운드를 재생하는 것입니다. QBasic과 비슷한 것을 찾고 있습니다 소리:
SOUND 17000, 100
이를위한 파이썬 라이브러리가 있습니까?
해결책
Pyaudiere 문제에 대한 간단한 크로스 플랫폼 솔루션입니다.
>>> import audiere
>>> d = audiere.open_device()
>>> t = d.create_tone(17000) # 17 KHz
>>> t.play() # non-blocking call
>>> import time
>>> time.sleep(5)
>>> t.stop()
pyaudiere.org가 사라졌습니다. 사이트 Python 2 용 바이너리 설치 업체 (Debian, Windows)는 Wayback Machine EG를 통해 제공됩니다. 여기 소스 코드가 있습니다 pyaudiere-0.2.tar.gz
.
Linux, Windows, OSX에서 Python 2와 3을 모두 지원합니다. pyaudio
기준 치수 대신 사용할 수 있습니다.
#!/usr/bin/env python
"""Play a fixed frequency sound."""
from __future__ import division
import math
from pyaudio import PyAudio # sudo apt-get install python{,3}-pyaudio
try:
from itertools import izip
except ImportError: # Python 3
izip = zip
xrange = range
def sine_tone(frequency, duration, volume=1, sample_rate=22050):
n_samples = int(sample_rate * duration)
restframes = n_samples % sample_rate
p = PyAudio()
stream = p.open(format=p.get_format_from_width(1), # 8bit
channels=1, # mono
rate=sample_rate,
output=True)
s = lambda t: volume * math.sin(2 * math.pi * frequency * t / sample_rate)
samples = (int(s(t) * 0x7f + 0x80) for t in xrange(n_samples))
for buf in izip(*[samples]*sample_rate): # write several samples at a time
stream.write(bytes(bytearray(buf)))
# fill remainder of frameset with silence
stream.write(b'\x80' * restframes)
stream.stop_stream()
stream.close()
p.terminate()
예시:
sine_tone(
# see http://www.phy.mtu.edu/~suits/notefreqs.html
frequency=440.00, # Hz, waves per second A4
duration=3.21, # seconds to play sound
volume=.01, # 0..1 how loud it is
# see http://en.wikipedia.org/wiki/Bit_rate#Audio
sample_rate=22050 # number of samples per second
)
수정 된 (Python 3을 지원하기 위해) 버전입니다. 이 askubuntu 답변.
다른 팁
내 코드를 여기에 넣고 있는데 프로그래머가 코드 작동 방식에 대해 명확하게 얻는 데 도움이됩니다.
설명은 코드 자체에 있습니다
#!/usr/bin/env python3
import pyaudio
import struct
import math
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 44100
p = pyaudio.PyAudio()
def data_for_freq(frequency: float, time: float = None):
"""get frames for a fixed frequency for a specified time or
number of frames, if frame_count is specified, the specified
time is ignored"""
frame_count = int(RATE * time)
remainder_frames = frame_count % RATE
wavedata = []
for i in range(frame_count):
a = RATE / frequency # number of frames per wave
b = i / a
# explanation for b
# considering one wave, what part of the wave should this be
# if we graph the sine wave in a
# displacement vs i graph for the particle
# where 0 is the beginning of the sine wave and
# 1 the end of the sine wave
# which part is "i" is denoted by b
# for clarity you might use
# though this is redundant since math.sin is a looping function
# b = b - int(b)
c = b * (2 * math.pi)
# explanation for c
# now we map b to between 0 and 2*math.PI
# since 0 - 2*PI, 2*PI - 4*PI, ...
# are the repeating domains of the sin wave (so the decimal values will
# also be mapped accordingly,
# and the integral values will be multiplied
# by 2*PI and since sin(n*2*PI) is zero where n is an integer)
d = math.sin(c) * 32767
e = int(d)
wavedata.append(e)
for i in range(remainder_frames):
wavedata.append(0)
number_of_bytes = str(len(wavedata))
wavedata = struct.pack(number_of_bytes + 'h', *wavedata)
return wavedata
def play(frequency: float, time: float):
"""
play a frequency for a fixed time!
"""
frames = data_for_freq(frequency, time)
stream = p.open(format=FORMAT, channels=CHANNELS, rate=RATE, output=True)
stream.write(frames)
stream.stop_stream()
stream.close()
if __name__ == "__main__":
play(400, 1)
당신은 사용할 수 있습니다 파이썬 바인딩 SDL의간단한 직접 미디어 라이브러리).