我们正在使用一个非常老的程序来驱动一些设备testing。 这些testing可以运行几天,我想知道什么时候testing已经完成。 testing完成后,可执行文件会以每秒1次蜂鸣声的速度连续发出蜂鸣声,直到操作员介入。
有没有办法让我“听”这个哔哔声,并在MB发出哔哔声时发出通知? 我希望有一个sys
或os
库,我可以用来表明这一点。
我们在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)
扬声器是否通过2针插头连接到主板?
如果是这样,拦截它并监视信号应该是微不足道的。 从示波器开始验证信号,然后连接某种USB数字I / O监视器 – 您应该能够计数脉冲并确定频率。 (有现成的解决方案,或简单的Arduino程序将工作)。
或者,如果您想进入真正的低级编程,请查看驱动扬声器的“可编程间隔定时器”芯片。 具体看“ 读回状态字节 ”中的“输出引脚状态”。
你可能需要写一个C扩展名到python来访问这些端口: 在这里查看一些C代码来访问芯片。
好的,这里是我使用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
和UPPERBOUND
之间。 如果频率在这两个界限之间,则会创建一个文件来说明何时发生。 此代码将继续,直至到达SEARCHTIME
并且至少发现一声蜂鸣。 由于有一些重叠,所有的处理都是在线程中完成的。
请注意,这可能会产生误报,这就是为什么它在第一次发现后不会终止。 另外,如果它从来没有发现,它会继续运行。 永远。
最后一点:正如我刚才所说,我还没有能够测试,所以它可能不会在你的拳头去跑。 我提前道歉,但至少应该给你一个很好的开局。 请让我知道什么是休息,所以我可以在这里修复它!
参考文献:
祝你好运
我不熟悉在Windows上编程,所以在这个答案很多的猜测。
假定程序调用一些Windows API函数来嘟嘟说话者,这可能是由某个DLL提供的。 在一个POSIX平台上,我将使用LD_PRELOAD
来加载一个共享库,用我自己的版本来覆盖这个API函数,然后这个函数可以通知我。 Windows上可能有类似的技术。 也许DLL注入帮助。