2009-12-20 27 views
43

Chúc mừng,Làm thế nào để có được đầu vào âm thanh từ microphone trong python, và xử lý nó trên bay?

Tôi đang cố viết một chương trình bằng Python sẽ in chuỗi mỗi khi có một lần nhấn vào micrô. Khi tôi nói 'tap', tôi có nghĩa là một tiếng động đột ngột lớn hoặc một cái gì đó tương tự.

tôi đã tìm kiếm trong SO và thấy bài này: Recognising tone of the audio

Tôi nghĩ rằng thư viện PyAudio sẽ phù hợp với nhu cầu của tôi, nhưng tôi không hoàn toàn chắc chắn làm thế nào để làm cho chương trình của tôi chờ đợi một tín hiệu âm thanh (theo dõi thời gian thực micro), và khi tôi có một cách để xử lý nó (tôi có cần sử dụng Fourier Transform như nó đã được hướng dẫn trong bài viết trên) không?

Cảm ơn bạn trước vì bất kỳ trợ giúp nào bạn có thể cho tôi.

+1

Cũng được thảo luận tại đây: http://stackoverflow.com/questions/193789/microphone-access-in-python –

Trả lời

33

Nếu bạn đang sử dụng LINUX, bạn có thể sử dụng pyALSAAUDIO. Đối với các cửa sổ, chúng tôi có PyAudio và cũng có một thư viện có tên là SoundAnalyse.

Tôi tìm thấy một ví dụ cho Linux here:

#!/usr/bin/python 
## This is an example of a simple sound capture script. 
## 
## The script opens an ALSA pcm for sound capture. Set 
## various attributes of the capture, and reads in a loop, 
## Then prints the volume. 
## 
## To test it out, run it and shout at your microphone: 

import alsaaudio, time, audioop 

# Open the device in nonblocking capture mode. The last argument could 
# just as well have been zero for blocking mode. Then we could have 
# left out the sleep call in the bottom of the loop 
inp = alsaaudio.PCM(alsaaudio.PCM_CAPTURE,alsaaudio.PCM_NONBLOCK) 

# Set attributes: Mono, 8000 Hz, 16 bit little endian samples 
inp.setchannels(1) 
inp.setrate(8000) 
inp.setformat(alsaaudio.PCM_FORMAT_S16_LE) 

# The period size controls the internal number of frames per period. 
# The significance of this parameter is documented in the ALSA api. 
# For our purposes, it is suficcient to know that reads from the device 
# will return this many frames. Each frame being 2 bytes long. 
# This means that the reads below will return either 320 bytes of data 
# or 0 bytes of data. The latter is possible because we are in nonblocking 
# mode. 
inp.setperiodsize(160) 

while True: 
    # Read data from device 
    l,data = inp.read() 
    if l: 
     # Return the maximum of the absolute value of all samples in a fragment. 
     print audioop.max(data, 2) 
    time.sleep(.001) 
+0

Vì vậy, hãy xem PyAudio (http://people.csail.mit.edu/hubert/pyaudio/) ;-) – jbochi

5

... và khi tôi có một cách xử lý nó (tôi cần phải sử dụng Fourier Transform như nó đã được hướng dẫn trong bài viết ở trên) ?

Nếu bạn muốn "nhấn" thì tôi nghĩ bạn quan tâm đến biên độ nhiều hơn tần suất. Vì vậy, biến đổi Fourier có thể không hữu ích cho mục tiêu cụ thể của bạn. Bạn có thể muốn thực hiện một phép đo hoạt động ngắn hạn (nói 10 ms) biên độ của đầu vào, và phát hiện khi nó đột nhiên tăng bởi một đồng bằng nhất định. Bạn sẽ cần phải điều chỉnh các thông số của:

  • "ngắn hạn" đo biên độ là những gì
  • gì là vùng đồng bằng tăng bạn tìm kiếm
  • một cách nhanh chóng như thế nào sự thay đổi đồng bằng phải xảy ra

Mặc dù tôi đã nói rằng bạn không quan tâm đến tần suất, trước tiên bạn có thể muốn thực hiện một số bộ lọc để lọc ra các thành phần tần số thấp và tần số cao. Điều đó có thể giúp bạn tránh được một số "sai tích cực". Bạn có thể làm điều đó với bộ lọc kỹ thuật số FIR hoặc IIR; Fourier là không cần thiết.

+1

Có, những gì tôi đã làm là lấy audioop.max (dữ liệu, 2) và thay đổi giá trị của nó với giá trị trước đó (từ lần lặp trước). Bằng cách này tôi có thể phát hiện nếu có sự gia tăng đột ngột. Và nó hoạt động tốt! Cảm ơn tất cả các bạn! :-) – Alex

Các vấn đề liên quan