使用GStreamer(或其他库)检测麦克风上的吹气

时间:2011-04-16 12:21:53

标签: python gtk audio pygtk gstreamer

我可以使用GStreamer(或其他兼容Linux的声音库)检测麦克风上的吹气吗?

我可以获得有关声音的一些信息:

import gtk, gst

def playerbinMessage(bus, message):
    if message.type == gst.MESSAGE_ELEMENT:
        struct = message.structure

        if struct.get_name() == 'level':
            # printing peak, decay, rms
            print struct['peak'][0], struct['decay'][0], struct['rms'][0]

pipeline = gst.parse_launch('pulsesrc ! level ! filesink location=/dev/null')

bus = pipeline.get_bus()
bus.add_signal_watch()
bus.connect('message', playerbinMessage)

pipeline.set_state(gst.STATE_PLAYING)

gtk.main()

我用它来检测鼓掌,但我不知道我是否可以使用这些信息来检测吹气,而不会让我的电脑混淆吹嘘和说话。另外,我不知道是否有另一种方法可以使用GStreamer或其他兼容Linux的声音库来分析声音。

3 个答案:

答案 0 :(得分:3)

您需要查看超过音频级别以区分吹奏和语音。首先,考虑到大多数语音都包含高于约80Hz的音频,而吹麦克风会产生大量的低频隆隆声。

所以:如果你想坚持使用gstreamer,也许可以尝试使用“audiocheblimit”过滤器在测量其水平之前低通声音。 (类似于audiocheblimit mode=low-pass cutoff=40 poles=4

就个人而言,我的方法更像是:

  1. 使用类似python-alsaaudio
  2. 的内容录制原始音频
  3. 使用numpy
  4. 计算声音块的傅里叶变换
  5. 总结低频(可能是20-40Hz)的幅度,并在该值足够大时触发。
  6. 如果这不起作用,那么我会寻找更聪明的检测算法。这种方法(alsa + numpy)非常灵活,但比gstreamer方法复杂一点。

    编辑:我刚注意到gstreamer还有一个“频谱”元素,它将返回傅里叶变换。

答案 1 :(得分:0)

只是答案和操作码的混合(sample pipe

#!/usr/bin/env python

import pygtk
pygtk.require('2.0')
import gtk, gst, time

class HelloWorld:

  def delete_event(self, widget, event, data=None):
      print "delete event occurred"
      return False

  def destroy(self, widget, data=None):
      print "destroy signal occurred"
      gtk.main_quit()

  def __init__(self):
      self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
      self.window.connect("delete_event", self.delete_event)
      self.window.connect("destroy", self.destroy)
      self.window.set_border_width(2)
      #self.window.set_size_request(600, 483)

      """ Play """
      self.vbox = gtk.VBox(False, 2)
      self.vbox.set_border_width(0)

      self.hbox = gtk.HBox()
      self.hlpass = gtk.Entry()
      self.hlpass.set_text("low-pass")
      self.hbox.pack_start( gtk.Label("High/Low-pass: "), False, False, 0 )
      self.hbox.pack_start( self.hlpass, False, False, 0 )
      self.vbox.add(self.hbox)

      self.hbox = gtk.HBox()
      self.cutoff = gtk.Entry()
      self.cutoff.set_text("40")
      self.hbox.pack_start( gtk.Label("Cutoff: "), False, False, 0 )
      self.hbox.pack_start( self.cutoff, False, False, 0 )
      self.vbox.add(self.hbox)

      self.hbox = gtk.HBox()
      self.poles = gtk.Entry()
      self.poles.set_text("4")
      self.hbox.pack_start( gtk.Label("Poles: "), False, False, 0 )
      self.hbox.pack_start( self.poles, False, False, 0 )
      self.vbox.add(self.hbox)

      self.hbox = gtk.HBox()
      self.button = gtk.Button("High-Pass")
      self.button.connect("clicked", self.change, None)
      self.hbox.pack_start(self.button, False, False, 0 )
      self.vbox.add(self.hbox)

      self.window.add(self.vbox)
      self.window.show_all()

  def main(self):
      self.gst()
      gtk.main()

  def gst(self):
      test = """
      alsasrc device=hw:0 ! audioconvert ! audioresample ! audiocheblimit mode=low-pass cutoff=40 poles=4 name=tuneit ! level ! autoaudiosink
      """
      self.pipeline = gst.parse_launch(test)
      self.bus = self.pipeline.get_bus()
      self.bus.add_signal_watch()
      self.bus.connect('message', self.playerbinMessage)
      self.pipeline.set_state(gst.STATE_PLAYING)

  def playerbinMessage(self,bus, message):
    if message.type == gst.MESSAGE_ELEMENT:
      struct = message.structure
      if struct.get_name() == 'level':
        print struct['peak'][0], struct['decay'][0], struct['rms'][0]
        #time.sleep(1)

  def change(self, widget, data=None):
    data = [self.hlpass.get_text(), self.cutoff.get_text(), self.poles.get_text()]
    print data[0], data[1], data[2]
    self.audiocheblimit = self.pipeline.get_by_name('tuneit')
    self.audiocheblimit.props.mode = data[0]
    self.audiocheblimit.props.cutoff = int( data[1] )
    self.audiocheblimit.props.poles = int ( data[2] )

if __name__ == "__main__":
    hello = HelloWorld()
    hello.main()

输出低通:

-20.9227157774 -20.9227157774 -20.953279177
-20.9366239523 -20.9227157774 -20.9591815321
-20.9290995367 -20.9227157774 -20.9601319723

输出高通:

-51.2328030138 -42.8335117509 -62.2730163502
-51.3932079772 -43.3559607159 -62.2080540769
-52.1412276733 -43.8784096809 -62.9151309943

修改

high-pass = speech and taking all audio
low-pass  = some audio like when you are talking near the microphone

答案 2 :(得分:0)

CMU Sphinx项目http://cmusphinx.sourceforge.net/是用于语音识别的工具包,它可以使用gstreamer来提供麦克风流。你可以看看。