如何“监听”内部主板sp上的声音

2024-05-19 02:55:32 发布

您现在位置:Python中文网/ 问答频道 /正文

我们正在使用一个非常旧的程序来驱动一些设备测试。这些测试可以运行几天,我想知道测试何时完成。当测试完成时,可执行文件会以每秒约1声蜂鸣音的速度持续向主板扬声器发出哔哔声,直到操作员介入为止。在

有没有一种方法可以让我“监听”这个哔哔声,并在MB开始哔哔声时发出通知?我希望有一个sys或{}库来表示这一点。在

我们运行的是Windows XP x86。我还没有在机器上安装Python。在

伪代码:

already_beeping = True

while True:
  speaker_beeping = check_speaker() # returns True or False
  if speaker_beeping == True:
    if already_beeping == False:
      send_notification()
      already_beeping = True
    else:
      pass
  else:
    already_beeping = False
  time.sleep(10)

Tags: 方法程序falsetrue可执行文件ifelse速度
3条回答

好的,这是我试图用PyAudio来解决这个问题,告诉我你的想法。不幸的是,我目前没有办法进行测试。在

这是改编自PyAudio页面上的“Record”示例。在

import threading
import PyAudio
import wave
import struct
import numpy as np
import os
import datetime

CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 44100
RECORD_SECONDS = 5

SEARCHTIME = 5
LOWERBOUND = 0.9
UPPERBOUND = 1.1

class RecorderThread(threading.Thread):
    def __init__(self, name):
        threading.Thread.__init__(self)
        self.name = name
        self.stream = p.open(format=FORMAT,
                             channels=CHANNELS,
                             rate=RATE,
                             input=True,
                             frames_per_buffer=CHUNK)
        self.start()

    def run(self):
        p = pyaudio.PyAudio()
        print("* recording")

        frames = []

        for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
            data = self.stream.read(CHUNK)
            frames.append(data)

        print("* done recording")

        self.stream.stop_stream()
        self.stream.close()
        p.terminate()

        wf = wave.open(self.name, 'wb')
        wf.setnchannels(CHANNELS)
        wf.setsampwidth(p.get_sample_size(FORMAT))
        wf.setframerate(RATE)
        wf.writeframes(b''.join(frames))
        wf.close()

        frate = RATE
        wav_file = wave.open(self.name,'r')
        data = wav_file.readframes(wav_file.getnframes())
        wav_file.close()
        os.remove(self.file)
        data =s truct.unpack('{n}h'.format(n=data_size), data)
        data = np.array(data)

        w = np.fft.fft(data)
        freqs = np.fft.fftfreq(len(w))

        idx=np.argmax(np.abs(w)**2)
        freq=freqs[idx]
        freq_in_hertz=abs(freq*frate)

        if freq_in_herts > LOWERBOUND and freq_in_herts < UPPERBOUND:
            curName = "found0.txt"

            while os.path.exists(curName):
                num = int(curName.split('.')[0][6:])
                curName = "found{}.txt".format(str(num+1))

            f = open(curName, 'r')
            f.write("Found it at {}".format(datetime.datetime.now()))
            f.close()

def main():
    recordingThreads = []

    totalTime = 0

    while totalTime < SEARCHTIME*(24*3600) and not os.path.exists("found.txt"):
        start = datetime.datetime(year=2012, month=2, day=25, hour=9)

        curName = "record0.wav"

        while os.path.exists(curName):
            num = int(curName.split('.')[0][6:])
            curName = "record{}.wav".format(str(num+1))

        recorder = RecorderThread(curName)
        time.sleep(4.5)
        end = datetime.datetime(year=2012, month=2, day=25, hour=18)
        totalTime += end - start

if __name__ == "__main__": main()

好吧,结果比我预想的要大一点。这将在SEARCHTIME指定的天数内运行。每隔4.5秒,它将录制5秒(以确保我们不会错过任何内容),此录制将以动态名称保存(以防止覆盖)。然后我们对.wav文件执行FFT,看看频率是否在LOWERBOUND和{}之间。如果频率介于这两个界限之间,则会创建一个文件,说明发生这种情况的时间。此代码一直持续到到达SEARCHTIME,并且至少找到一个蜂鸣音。因为有一点重叠,所以所有的处理都是在线程中完成的。在

请注意,这可能会产生假阳性,这就是为什么它在第一次发现之后不会终止。另外,如果它找不到东西,它会继续运行。永远。在

最后一点:正如我之前所说,我还没能测试它,所以它很可能不会在你的第一个动作中运行。我提前道歉,但至少,这会给你一个很好的开端。请告诉我什么地方坏了,这样我就可以把它修好了!在

参考文献:

  • 录音声音:来自PyAudio页面的“录制”示例
  • FFT与频率发现:This post

祝你好运

我不熟悉Windows编程,所以这个答案有很多猜测。在

程序可能会调用一些windowsapi函数来向扬声器发出哔声,这可能是由某个DLL提供的。在POSIX平台上,我将使用LD_PRELOAD来加载一个共享库,该库将用我自己的版本覆盖该API函数,然后它将能够通知我。在Windows上可能有类似的技术;也许DLL injection有帮助。在

扬声器是否通过2针头连接到主板?在

如果是这样的话,那么拦截它并监视信号应该很简单。从示波器开始验证信号,然后连接某种USB数字I/O监视器-你应该能够计数脉冲和确定频率。(有现成的解决方案,或者一个简单的Arduino程序就可以了)。在

或者,如果您想进入真正的低级编程,可以查询"Programmable Interval Timer"芯片,该芯片drives the speakers。具体看一下Read Back Status Byte中的“输出引脚状态”。在

您可能需要编写一个到python的C扩展来访问这些端口:请参见here以获取访问芯片的一些示例C代码。在

相关问题 更多 >

    热门问题