魔兽世界自动钓鱼系统的设计与实现 - 鱼上钩声音事件的提取(1)
(2013-04-17 16:10:33)
标签:
魔兽世界系统设计与实现python |
分类: 编程实战 |
前面已经提到过在鱼漂下沉,也就是鱼上钩,这一事件发生的时间点用图像识别比较耗费资源,进而想用在钓鱼时上鱼上钩时会有声音这一点来获取事件发生的时间点(其实是图像识别我也不会,借口而已)。简单说来就是在系统输出的音频流中识别鱼上钩的声音事件发生的时间点。这一时间点就是是下一步提杆操作的基础。首先列出所要解决的所有问题:
-
获取系统音频流输出
-
声音事件的描述,也就量声音事件的表达,即特征
-
声音事件在录音中的识别与在音频流中的识别
获取系统音频流输出
录制系统音频输出方法很简单,我开始想通过选择录音设备(立体声混音),这样就可以不干扰麦克风录音的功能。最终还是放弃了,直接将“立体声混音”这个设备设为默认录音设备,这样随便用一个录音软件都可以录下系统的声音输出了。联想到win7、win8还可以调节单个应用程序的输出,我最开始的最高计划是选择某一应用程序的音频输出,当然,这样就降低了后续处理的难度,没必要。
总之,在这一部分上浪费了大量时间,主要是看见了一篇中文的用python加DirectSound做语言处理的论文,然后就想办法借用Win32API来调用DirectSound,最终能够实现录制特定长度的音频文件(wav)但是却不知道怎么分段录制,而一段一段录制对后面的音频流的实时处理非常重要。造成困难的主要原因还是python的DirectSound的例子太少,文档过于简单,WinPython给出的文档简直没法看!既然都是做系统调用,任意语言的代码应该是类似的,直接参考C#的例子又发现对应起来还是有困难的……另外,SourceForge上面其实是有一个DirectPython的开源项目,但是打不开……没办法,折腾到最后只好放弃DirectSound方案。下面是调用DirectSound的录制wav文件的一段代码,我从py2.6的代码上修改为了py3k的:
"""
Created on Thu Apr 11 18:00:43 2013
@author: du00
"""
import
import
import
import
def
d
sdesc
sdesc.dwBufferBytes
sdesc.lpwfxFormat
sdesc.lpwfxFormat.wFormatTag
sdesc.lpwfxFormat.nChannels
sdesc.lpwfxFormat.nSamplesPerSec
sdesc.lpwfxFormat.nAvgBytesPerSec
sdesc.lpwfxFormat.nBlockAlign
sdesc.lpwfxFormat.wBitsPerSample
buffer
event
notify
notify.SetNotificationPositions
buffer.Start(0)
win32event.WaitForSingleObject(event,
# in real life, more, smaller buffers should be retrieved
f
f.write(wav_header_pack(sdesc.lpwfxFormat,
data
f.write(data)
f.close
后来才发现python有封装PortAudio的pyAudio包,真心简单好用,而且还是跨平台的,免除了学习Win32AP的痛苦,网站上提供的例子简单明了,一看就会!录制音频的代码如下:
"""
Created on Fri Apr 12 05:14:56 2013
@author: du00
"""
"""PyAudio example: Record a few seconds of audio and save to a WAVE file."""
import
import
CHUNK
FORMAT
CHANNELS
RATE
RECORD_SECONDS
WAVE_OUTPUT_FILENAME
p
stream
print("* recording")
frames
for
print("* done recording")
stream.stop_stream()
stream.close()
p.terminate()
wf
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(b''.join(frames))
wf.close
简单了不少吧!不觉得?http://www/uc/myshow/blog/misc/gif/E___7393ZH00SIGG.gif-
虽然终极目的是在音频播放(音频流)中实时地识别,但是做这些录制工作还是非常有必要的,录制的音频可以从宏观地把握声音事件与背景、其它声音事件的区别,有助于理解声音事件。下一部分的所有工作都是在存在录制的音频文件基础上展开的。