Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/308.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 获取播放wav音频级别作为输出_Python_Audio_Raspberry Pi - Fatal编程技术网

Python 获取播放wav音频级别作为输出

Python 获取播放wav音频级别作为输出,python,audio,raspberry-pi,Python,Audio,Raspberry Pi,我想做一个说话的嘴,当播放wav文件发出声音时,它会移动或发出光或其他东西。因此,我需要检测wav文件何时在说话,或者何时在字词之间处于静默状态。目前我正在使用我找到的pygame脚本 import pygame pygame.mixer.init() pygame.mixer.music.load("my_sentence.wav") pygame.mixer.music.play() while pygame.mixer.music.get_busy() == True: conti

我想做一个说话的嘴,当播放wav文件发出声音时,它会移动或发出光或其他东西。因此,我需要检测wav文件何时在说话,或者何时在字词之间处于静默状态。目前我正在使用我找到的pygame脚本

import pygame
pygame.mixer.init()
pygame.mixer.music.load("my_sentence.wav")
pygame.mixer.music.play()
while pygame.mixer.music.get_busy() == True:
    continue
我想我可以在while循环中进行一些检查,以查看声音输出级别或类似的内容,然后将其发送到其中一个gpio输出。但我不知道如何做到这一点


任何帮助都将不胜感激

您需要检查WAV文件以确定语音何时出现。最简单的方法是寻找响亮和安静的时段。因为声音与波一起工作,当声音安静时,波文件中的值不会发生很大变化,而当声音很大时,它们会发生很大变化

估计响度的一种方法是声音。正如您在文章中看到的,这可以定义为
E[(X-mu)^2]
,可以写成
average((X-average(X))^2)
。这里,X是给定点处的信号值(存储在WAV文件中的值,在代码中称为
sample
)。如果变化很大,差异会很大

这将允许您计算整个文件的响度。但是,您希望跟踪文件在任何给定时间的音量,这意味着您需要一种形式的音频。一个简单的方法是使用一个

我还没有测试下面的代码,所以它不太可能工作,但应该可以让您开始。它加载WAV文件,使用低通滤波器跟踪均值和方差,并计算出方差何时高于或低于某个阈值。然后,在播放WAV文件时,它会记录开始播放后的时间,并打印出WAV文件是响亮的还是安静的

以下是您可能仍然需要执行的操作:

  • 修正我在代码中故意犯的错误
  • 添加一些有用的内容,以应对喧闹/安静的变化
  • 更改阈值和反应时间以获得良好的音频效果
  • 添加一些(可变阈值)以停止灯光闪烁
我希望这有帮助

import wave
import struct
import time

def get_loud_times(wav_path, threshold=10000, time_constant=0.1):
    '''Work out which parts of a WAV file are loud.
        - threshold: the variance threshold that is considered loud
        - time_constant: the approximate reaction time in seconds'''

    wav = wave.open(wav_path, 'r')
    length = wav.getnframes()
    samplerate = wav.getframerate()

    assert wav.getnchannels() == 1, 'wav must be mono'
    assert wav.getsampwidth() == 2, 'wav must be 16-bit'

    # Our result will be a list of (time, is_loud) giving the times when
    # when the audio switches from loud to quiet and back.
    is_loud = False
    result = [(0., is_loud)]

    # The following values track the mean and variance of the signal.
    # When the variance is large, the audio is loud.
    mean = 0
    variance = 0

    # If alpha is small, mean and variance change slower but are less noisy.
    alpha = 1 / (time_constant * float(sample_rate))

    for i in range(length):
        sample_time = float(i) / samplerate
        sample = struct.unpack('<h', wav.readframes(1))

        # mean is the average value of sample
        mean = (1-alpha) * mean + alpha * sample

        # variance is the average value of (sample - mean) ** 2
        variance = (1-alpha) * variance + alpha * (sample - mean) ** 2

        # check if we're loud, and record the time if this changes
        new_is_loud = variance > threshold
        if is_loud != new_is_loud:
            result.append((sample_time, new_is_loud))
        is_loud = new_is_loud

    return result

def play_sentence(wav_path):
    loud_times = get_loud_times(wav_path)
    pygame.mixer.music.load(wav_path)

    start_time = time.time()
    pygame.mixer.music.play()

    for (t, is_loud) in loud_times:
        # wait until the time described by this entry
        sleep_time = start_time + t - time.time()
        if sleep_time > 0:
            time.sleep(sleep_time)

        # do whatever
        print 'loud' if is_loud else 'quiet'
导入波
导入结构
导入时间
def获取声音次数(波形路径,阈值=10000,时间常数=0.1):
''计算出WAV文件的哪些部分声音很大。
-阈值:被认为是响亮的方差阈值
-时间常数:以秒为单位的近似反应时间“”
wav=波形打开(波形路径'r')
长度=wav.getnframes()
samplerate=wav.getframerate()
断言wav.getnchannels()==1,“wav必须是mono”
断言wav.getsampwidth()==2,“wav必须是16位”
#我们的结果将是一个(时间,是响亮的)列表,给出
#当音频从响亮切换到安静并返回时。
这是错的吗
结果=[(0.,是)]
#以下值跟踪信号的平均值和方差。
#当差异较大时,音频会很大。
平均值=0
方差=0
#如果alpha很小,则均值和方差变化较慢,但噪声较小。
α=1/(时间常数*浮动(采样率))
对于范围内的i(长度):
取样时间=浮子(i)/取样器
示例=结构解包('阈值
如果是大声的!=新的是大声的:
result.append((采样时间,新建时间)
是大声的=新的是大声的
返回结果
def播放句子(波形路径):
响亮次数=获得响亮次数(wav路径)
pygame.mixer.music.load(wav_路径)
开始时间=time.time()
pygame.mixer.music.play()
对于(t,is_loud)在loud_时间:
#等待此条目描述的时间
sleep\u time=start\u time+t-time.time()
如果睡眠时间>0:
时间。睡眠(睡眠时间)
#做任何事
如果是“大声”,则打印“大声”,否则打印“安静”

对我来说,这似乎是树莓派的问题……我不知道它为什么被迁移。如果我理解“music.get_busy()==True”while子句,它将在.wav文件播放时执行。因此,您可以将您的电机命令放入while循环中…对吗…还是我遗漏了什么?谢谢@NULL的回答。
music.get_busy()==真
将一直是真的,因为声音从开始到结束。但我想检测单词之间的沉默,我不想让嘴巴一直在自主移动。我想在句子沉默时停止移动。我明白了。嗯……我会考虑一下。这可以通过电路轻松完成,而不是解析音频。你呢只寻找软件解决方案?你的答案看起来很好,我会在接下来的几天里再次阅读并尝试代码。谢谢!;)我已经创建了社区wiki,希望这意味着你可以使用找到的任何修复程序对其进行编辑。祝你好运样本率未定义,我将样本作为元组获取,不能乘法。有更新的代码吗?