Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
播放固定频率声音的Python库_Python_Audio_Mp3_Frequency - Fatal编程技术网

播放固定频率声音的Python库

播放固定频率声音的Python库,python,audio,mp3,frequency,Python,Audio,Mp3,Frequency,我的房子里有蚊子的问题。这通常不会涉及程序员社区;然而,我看到一些设备声称通过播放17Khz的音调来阻止这些讨厌的生物。我想用我的笔记本电脑做这个 一种方法是创建一个带有单一固定频率音调()的MP3,并重复播放 第二种是使用电脑内置扬声器播放声音。我正在寻找类似QBasic声音的东西: 是否有用于此目的的python库?是解决此问题的简单跨平台解决方案: >>> import audiere >>> d = audiere.open_device() >

我的房子里有蚊子的问题。这通常不会涉及程序员社区;然而,我看到一些设备声称通过播放17Khz的音调来阻止这些讨厌的生物。我想用我的笔记本电脑做这个

一种方法是创建一个带有单一固定频率音调()的MP3,并重复播放

第二种是使用电脑内置扬声器播放声音。我正在寻找类似QBasic声音的东西:

是否有用于此目的的python库?

是解决此问题的简单跨平台解决方案:

>>> 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机器获得,例如

为了在Linux上同时支持Python 2和Python 3,可以使用Windows和OSX:

#!/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)。

您可以使用SDL()的

该模块包含在Python中,因此没有需要安装的外部库,它应该可以做您想要做的事情(除此之外没有什么)

它非常简单,虽然只适用于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)

我简化了jfs对Python3.6+的回答,并做了一些小的改进:

import math
from pyaudio import PyAudio, paUInt8

def generate_sine_wave(frequency, duration, volume=0.2, sample_rate=22050):
    ''' Generate a tone at the given frequency.

        Limited to unsigned 8-bit samples at a given sample_rate.
        The sample rate should be at least double the frequency.
    '''
    if sample_rate < (frequency * 2):
        print('Warning: sample_rate must be at least double the frequency '
              f'to accurately represent it:\n    sample_rate {sample_rate}'
              f' ≯ {frequency*2} (frequency {frequency}*2)')

    num_samples = int(sample_rate * duration)
    rest_frames = num_samples % sample_rate

    pa = PyAudio()
    stream = pa.open(
        format=paUInt8,
        channels=1,  # mono
        rate=sample_rate,
        output=True,
    )

    # make samples
    s = lambda i: volume * math.sin(2 * math.pi * frequency * i / sample_rate)
    samples = (int(s(i) * 0x7F + 0x80) for i in range(num_samples))

    # write several samples at a time
    for buf in zip( *([samples] * sample_rate) ):
        stream.write(bytes(buf))

    # fill remainder of frameset with silence
    stream.write(b'\x80' * rest_frames)

    stream.stop_stream()
    stream.close()
    pa.terminate()

generate_sine_wave(
    # see http://www.phy.mtu.edu/~suits/notefreqs.html
    frequency=523.25,   # Hz, waves per second C6
    duration=1.2,       # seconds to play sound
    volume=0.25,        # 0..1 how loud it is
    sample_rate=22050,  # number of samples per second: 11025, 22050, 44100
)
导入数学
从pyaudio导入pyaudio,paUInt8
def生成正弦波(频率、持续时间、体积=0.2,采样率=22050):
''以给定频率生成音调。
仅限于给定采样率下的无符号8位采样。
采样率应至少为频率的两倍。
'''
如果采样率<(频率*2):
打印('警告:采样率必须至少是频率的两倍'
为了准确地表示它:\n sample_rate{sample_rate}
f'≯ {frequency*2}(frequency{frequency}*2'))
num_samples=int(采样率*持续时间)
剩余帧=采样数百分比采样率
pa=PyAudio()
流=pa.open(
格式=paUInt8,
通道=1,#单声道
速率=采样速率,
输出=真,
)
#制作样品
s=lambda i:volume*math.sin(2*math.pi*频率*i/采样率)
样本=(范围内i的int(s(i)*0x7F+0x80)(num_样本))
#一次写几个样本
对于zip中的buf(*[样本]*样本率)):
stream.write(字节(buf))
#用静默填充框架集的其余部分
stream.write(b'\x80'*rest\u帧)
stream.stop_stream()
stream.close()
pa.终止()
产生正弦波(
#看http://www.phy.mtu.edu/~suits/notefqs.html
频率=523.25,#Hz,每秒波数C6
持续时间=1.2,#秒播放声音
音量=0.25,#0..1有多大
采样率=22050,每秒采样数:110252205044100
)

使用MP3时要小心,因为它通过去除人类听不到的频率而获得压缩,并且听力阈值通常为20kHz,离17kHz不远。因此,当您的固定频率音调转换为MP3时,可能会播放不同的频率集,或者衰减您所追求的频率集。作为一个人,你可能无法分辨这两者之间的区别。但是蚊子可能…非常感谢。如果我选择这个解决方案,我会使用一个短(~3秒)的WAV文件。那么它对蚊子有效吗???相关:是的,请告诉它是否有效:)我曾经在一只蚊子附近测试过一个手持设备,蚊子在我手臂附近飞。它没有开始叮咬,但也没有任何反应,只是停留在皮肤附近。顺便说一句,虽然这会产生声音,但我真的怀疑它能阻止蚊子,事实上,我怀疑它们甚至能听到。问题是,大多数昆虫不像我们那样用鼓膜来听,而是用感觉毛来听。但感觉毛发只对气流速度敏感,而对压力不敏感。当你远离说话者时,几乎所有的压力都以很小的速度存在。也就是说,除非他们站在你的扬声器上,否则他们听不到。所以扬声器必须非常强大,可能不是普通的PC扬声器。幸运的是,我还是一名科学系的学生——我会问一位昆虫学家,然后把答案贴在这里。“人耳是压力探测器,而蚊子的耳朵则探测声场的粒子速度分量,该分量仅限于声近场声源附近。蚊子的耳朵对远场声压波动不敏感。“如何在Django注册winsound?酷。你能谈谈稳定性问题吗?最小版本是0.2。@ UDI PASMON: PyOdieR是一个简单的包装器,用于对应的C++库。奇特的示例编写代码对于持续时间的样本不起作用。我的一个朋友与我共享这个链接来安装和安装PyoDo:如果你使用这个解决方案,我会收到奇怪的错误消息,发送给STDERR。我怎样才能摆脱它们?详情请参阅!
#!/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)
import math
from pyaudio import PyAudio, paUInt8

def generate_sine_wave(frequency, duration, volume=0.2, sample_rate=22050):
    ''' Generate a tone at the given frequency.

        Limited to unsigned 8-bit samples at a given sample_rate.
        The sample rate should be at least double the frequency.
    '''
    if sample_rate < (frequency * 2):
        print('Warning: sample_rate must be at least double the frequency '
              f'to accurately represent it:\n    sample_rate {sample_rate}'
              f' ≯ {frequency*2} (frequency {frequency}*2)')

    num_samples = int(sample_rate * duration)
    rest_frames = num_samples % sample_rate

    pa = PyAudio()
    stream = pa.open(
        format=paUInt8,
        channels=1,  # mono
        rate=sample_rate,
        output=True,
    )

    # make samples
    s = lambda i: volume * math.sin(2 * math.pi * frequency * i / sample_rate)
    samples = (int(s(i) * 0x7F + 0x80) for i in range(num_samples))

    # write several samples at a time
    for buf in zip( *([samples] * sample_rate) ):
        stream.write(bytes(buf))

    # fill remainder of frameset with silence
    stream.write(b'\x80' * rest_frames)

    stream.stop_stream()
    stream.close()
    pa.terminate()

generate_sine_wave(
    # see http://www.phy.mtu.edu/~suits/notefreqs.html
    frequency=523.25,   # Hz, waves per second C6
    duration=1.2,       # seconds to play sound
    volume=0.25,        # 0..1 how loud it is
    sample_rate=22050,  # number of samples per second: 11025, 22050, 44100
)