| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- # -*-coding:Latin-1 -*
- """Analyse du micro et stockage des parametres pour le chat vocal"""
- import audioop
- import time
- from math import fabs
- import cPickle as pickle #lecture/ecriture d'objets dans un fichier
- #modules complémentaires
- import pymedia.audio.sound as sound
- class AnaSon():
- """analyse et stocke les parametres d'entree du son (version pymedia)"""
- def __init__(self):
- """initialisation des parametres par defauts"""
- #puissance moyenne du son en silence
- self.pMoy_silence = 1800
- #ecarts liees aux parasites
- self.ecartSilence = 500
- #puissance moyenne du son en parlant
- self.pMoy_parle = 16000
- #coeff de puissance
- self.coeffP = 1.00
- #puissance de reference
- self.pRef = 20000
- #forme d'onde (liste des puissances) en silence et en parlant
- self.formeS = []
- self.formeP = []
- #duree des tests
- self.duree = 5
- #peripheriques par defaut:
- self.IDmicro = 0
- #pour le traitement du son:
- self.compte = 0
- #affiche des infos
- self.affichage = True
-
- #fichier de sauvegarde
- self.fichier = "param_micro"
- self.ecoute = False
- #pour enregistrement de la reception
- #self.enregistrement = open( "ResultatAnalyse.mp3", 'wb' )
- def recup(self):
- """recupere si possible les parametres enregistres"""
- try:
- with open(self.fichier, 'rb') as f:
- tmp = pickle.load(f)
- f.close()
- print("Parametres récupérés")
- except IOError:
- tmp = self
- print("Pas de parametres enregistres, parametres par defaut utilises")
- return tmp
-
- def sauver(self):
- """sauvegarde les parametres analyses"""
- with open(self.fichier, 'wb') as f:
- pickle.dump(self, f, -1)
- f.close()
- print("Parametres sauvegardes.")
- def analyser(self):
- """lance l'analyse du son"""
- print("\n*** Analyse du micro ***\n")
-
- #phase 1: quel micro?
- print(sound.getIDevices())
- self.IDmicro = input("\nMicro par defaut? (id) > ")
- micro = sound.Input( 16000, 1, sound.AFMT_S16_LE, self.IDmicro )
- micro.start()
- sortie = sound.Output( 16000, 1, sound.AFMT_S16_LE )
- enregistrement = open( "ResultatsAnaSon.mp3", 'wb' )
-
- # phase 2 : parasites
- #liste des donnees recues au cours de l'analyse
- frames_test = []
-
- #boucle de reception
- print("Test des parasites: ne parlez pas (env. {} sec)\n".format(self.duree+1))
- pause = raw_input("Appuyez sur Entree pour lancer: \n")
- t0 = time.time()
- while time.time() - t0 < self.duree:
- son = micro.getData()
- if son and len(son):
- frames_test.append(son)
- #audioop.rms renvoie la puissance moyenne du son
- self.formeS.append(audioop.rms(son,2))
- #on enleve la premiere valeur qui n'est generalement pas representative:
- del frames_test[0]
- del self.formeS[0]
- print("{}\n".format(self.formeS))
-
- #donnees utilisees pour l'attenuation du son lors des silences:
- self.pMoy_silence = audioop.rms(b''.join(frames_test),2)
- self.ecartMax = 0
-
- ecart_mesure = 0
- for son in frames_test:
- if fabs(audioop.rms(son,2) - self.pMoy_silence) > ecart_mesure:
- ecart_mesure = fabs(audioop.rms(son,2) - self.pMoy_silence)
- if ecart_mesure > 10:
- self.ecartSilence = ecart_mesure
-
- # phase 3 : parle
- frames_test = []
- print("Test de la voix: parlez normalement (env. {} sec)\n ".format(self.duree+1))
- pause = raw_input("Appuyez sur Entree pour lancer: \n")
- t0 = time.time()
- while time.time() - t0 < self.duree:
- son = micro.getData()
- if son and len(son):
- self.formeP.append(audioop.rms(son,2))
- if audioop.rms(son,2) > (self.pMoy_silence + self.ecartSilence):
- frames_test.append(son)
- #on enleve la premiere valeur qui n'est generalement pas representative:
- del self.formeP[0]
- print("{}\n".format(self.formeP))
-
- if len(frames_test)>0:
- del frames_test[0]
- self.pMoy_parle = audioop.rms(b''.join(frames_test),2)
- #mise a jour du coeff de puissance:
- if self.pMoy_parle != 0:
- self.coeffP = self.pRef / self.pMoy_parle
- if self.coeffP < 0.2:
- self.coeffP = 0.20
- elif self.coeffP > 4:
- self.coeffP = 4.00
- else:
- print("\n (!) Erreur: la puissance de la voix est insuffisante pour etre detectee")
- print("\n*** Fin de l'analyse ***\n")
- micro.stop()
- enregistrement.close()
- self.sauver()
- def traitement(self, data):
- """renvoie la donnee sonore traitee selon les parametres utilises"""
- #est-on dans la 'zone de silence'?
- kS = 1
- retour = None
- seuil_iterations = 3
- if audioop.rms(data,2) <= self.pMoy_silence + self.ecartSilence:
- #on ne diminue la puissance du son qu'apres un certain nombre d'iterations (4 ici)
- self.compte += 1
- if self.compte > seuil_iterations:
- if self.affichage and self.compte == seuil_iterations + 1:
- print("\n-> silence")
- kS = 0.2
- else:
- if self.affichage and self.compte != 0:
- print("\n-> parle")
- self.compte = 0
- #retour = audioop.mul(data, 2, (self.coeffP))
- kS = 1
- retour = audioop.mul(data, 2, (kS * self.coeffP))
- return retour
-
- def ecouterMicro(self):
- """ecouter son micro"""
- micro = sound.Input( 16000, 1, sound.AFMT_S16_LE, self.IDmicro )
- micro.start()
- sortie = sound.Output( 16000, 1, sound.AFMT_S16_LE )
- t0 = time.time()
- #while time.time() - t0 < self.duree:
- while True:
- son = micro.getData()
- if son and len(son):
- son_traite = self.traitement(son)
- #print("{} - {}".format(audioop.rms(son,2), audioop.rms(son_traite,2)))
- sortie.play(son_traite)
-
- micro.stop()
-
- def __repr__(self):
- """affiche les parametres utilises"""
- chaine = "\n*** Parametres utilises ***\n"\
- "\n Puissance moyenne en silence: {} "\
- "\n Amplitude parasites: {} "\
- "\n Puissance moyenne en parlant: {} "\
- "\n Multiplicateur applique: {} "\
- "".format(self.pMoy_silence, self.ecartSilence, self.pMoy_parle, self.coeffP)
- return chaine
- ######### si lancement direct ########
- if __name__ == "__main__":
- a = AnaSon()
- a.analyser()
- #a = None
- #a = AnaSon()
- #a = a.recup()
- print(a)
- #a.ecouterMicro()
- #a.analyser()
- pause = raw_input("appuyez sur entree")
-
|