web-dev-qa-db-fra.com

Comment obtenir le son du microphone en python et le traiter à la volée?

Salutations,

J'essaie d'écrire un programme en Python qui imprimerait une chaîne à chaque fois qu'il obtiendrait un tap dans le microphone. Quand je dis "tap", je veux dire un bruit soudain fort ou quelque chose de similaire .

J'ai cherché dans SO et j'ai trouvé ce message: Reconnaître le ton de l'audio

Je pense que la bibliothèque PyAudio répondrait à mes besoins, mais je ne sais pas trop comment faire pour que mon programme attende un signal audio (surveillance du microphone en temps réel), et quand j'en ai un comment le traiter (dois-je utiliser Fourier Transform comme il a été instruit dans le post ci-dessus)?

Merci d'avance pour toute aide que vous pourriez me donner.

49
Alex

Si vous utilisez LINUX, vous pouvez utiliser pyALSAAUDIO . Pour les fenêtres, nous avons PyAudio et il y a aussi une bibliothèque appelée SoundAnalyse .

J'ai trouvé un exemple pour Linux ici :

#!/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)
40
jbochi

... et quand j'en ai un comment le traiter (dois-je utiliser Fourier Transform comme il a été indiqué dans le post ci-dessus)?

Si vous voulez un "tap" alors je pense que vous êtes intéressé par l'amplitude plus que par la fréquence. Les transformées de Fourier ne sont donc probablement pas utiles pour votre objectif particulier. Vous voulez probablement faire une mesure courante de l'amplitude à court terme (disons 10 ms) de l'entrée, et détecter quand elle augmente soudainement d'un certain delta. Vous devez régler les paramètres de:

  • quelle est la mesure d'amplitude "à court terme"
  • quelle est l'augmentation delta que vous recherchez
  • la rapidité avec laquelle le changement de delta doit se produire

Bien que je dise que la fréquence ne vous intéresse pas, vous voudrez peut-être d'abord effectuer un filtrage, pour filtrer les composants à basse et haute fréquence en particulier. Cela pourrait vous aider à éviter certains "faux positifs". Vous pouvez le faire avec un filtre numérique FIR ou IIR; Fourier n'est pas nécessaire.

6
Craig McQueen