문제

집에 모기 문제가 있습니다. 이것은 일반적으로 프로그래머 커뮤니티와 관련이 없습니다. 그러나 나는 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 답변.

다른 팁

모듈 Winsound Python에 포함되어 있으므로 설치할 외부 라이브러리가 없으므로 원하는대로 수행해야합니다.

 import winsound
 winsound.Beep(17000, 100)

매우 간단하고 쉽지만 Windows에서만 사용할 수 있습니다.

하지만:
이 질문에 대한 완전한 답변은이 방법이 소리를 내는데도 그것은 모기를 방해하지 않을 것입니다. 이미 테스트되었습니다 : 참조 여기 그리고 여기

내 코드를 여기에 넣고 있는데 프로그래머가 코드 작동 방식에 대해 명확하게 얻는 데 도움이됩니다.

설명은 코드 자체에 있습니다

#!/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의간단한 직접 미디어 라이브러리).

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top