-
Notifications
You must be signed in to change notification settings - Fork 1
/
decode_versaoAlunos.py
132 lines (93 loc) · 5.39 KB
/
decode_versaoAlunos.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#Importe todas as bibliotecas
from suaBibSignal import *
import peakutils #alternativas #from detect_peaks import * #import pickle
import numpy as np
import sounddevice as sd
import matplotlib.pyplot as plt
import time
#funcao para transformas intensidade acustica em dB, caso queira usar
def todB(s):
sdB = 10*np.log10(s)
return(sdB)
def main():
#*****************************instruções********************************
#declare um objeto da classe da sua biblioteca de apoio (cedida)
# algo como:
signal = signalMeu()
frequencias = {'1': (697, 1209),
'2': (697, 1336),
'3': (697, 1477),
'4': (770, 1209),
'5': (770, 1336),
'6': (770, 1477),
'7': (852, 1209),
'8': (852, 1336),
'9': (852, 1477),
'*': (941, 1209),
'0': (941, 1336),
'#': (941, 1477)
}
#voce importou a bilioteca sounddevice como, por exemplo, sd. entao
# os seguintes parametros devem ser setados:
sd.default.samplerate = 44100 #taxa de amostragem
fs = 44100
sd.default.channels = 1 #numCanais # o numero de canais, tipicamente são 2. Placas com dois canais. Se ocorrer problemas pode tentar com 1. No caso de 2 canais, ao gravar um audio, terá duas listas
duration = 5 # #tempo em segundos que ira aquisitar o sinal acustico captado pelo mic
#calcule o numero de amostras "numAmostras" que serao feitas (numero de aquisicoes) durante a gracação. Para esse cálculo você deverá utilizar a taxa de amostragem e o tempo de gravação
numAmostras = int(fs * duration)
#faca um print na tela dizendo que a captacao comecará em n segundos. e entao
#use um time.sleep para a espera
for i in range(3):
print(f"gravando em {(3-i)} segundos")
time.sleep(1)
#Ao seguir, faca um print informando que a gravacao foi inicializada
print("gravacao iniciada")
#para gravar, utilize
audio = sd.rec(int(numAmostras), fs, channels=1)
sd.wait()
print("gravacao finalizada")
#analise sua variavel "audio". pode ser um vetor com 1 ou 2 colunas, lista, isso dependerá so seu sistema, drivers etc...
#extraia a parte que interessa da gravação (as amostras) gravando em uma variável "dados". Isso porque a variável audio pode conter dois canais e outas informações).
dados = audio[:, 0]
# use a funcao linspace e crie o vetor tempo. Um instante correspondente a cada amostra!
t = np.linspace(0, duration, numAmostras, endpoint=False)
# plot do áudio gravado (dados) vs tempo! Não plote todos os pontos, pois verá apenas uma mancha (freq altas) .
plt.plot(t, dados)
plt.xlabel('Tempo (s)')
plt.ylabel('Amplitude')
plt.show()
## Calcule e plote o Fourier do sinal audio. como saida tem-se a amplitude e as frequencias
xf, yf = signal.calcFFT(dados, fs)
signal.plotFFT(dados, fs)
#agora, voce tem os picos da transformada, que te informam quais sao as frequencias mais presentes no sinal. Alguns dos picos devem ser correspondentes às frequencias do DTMF!
#Para descobrir a tecla pressionada, voce deve extrair os picos e compara-los à tabela DTMF
#Provavelmente, se tudo deu certo, 2 picos serao PRÓXIMOS aos valores da tabela. Os demais serão picos de ruídos.
# para extrair os picos, voce deve utilizar a funcao peakutils.indexes(,,)
# Essa funcao possui como argumentos dois parâmetros importantes: "thres" e "min_dist".
# "thres" determina a sensibilidade da funcao, ou seja, quao elevado tem que ser o valor do pico para de fato ser considerado um pico
#"min_dist" é relatico tolerancia. Ele determina quao próximos 2 picos identificados podem estar, ou seja, se a funcao indentificar um pico na posicao 200, por exemplo, só identificara outro a partir do 200+min_dis. Isso evita que varios picos sejam identificados em torno do 200, uma vez que todos sejam provavelmente resultado de pequenas variações de uma unica frequencia a ser identificada.
# Comece com os valores:
index = peakutils.indexes(yf, thres=0.4, min_dist=50)
print("index de picos {}" .format(index)) #yf é o resultado da transformada de fourier
#printe os picos encontrados!
# Aqui você deverá tomar o seguinte cuidado: A funcao peakutils.indexes retorna as POSICOES dos picos. Não os valores das frequências onde ocorrem! Pense a respeito
#encontre na tabela duas frequencias proximas às frequencias de pico encontradas e descubra qual foi a tecla
#print o valor tecla!!!
#Se acertou, parabens! Voce construiu um sistema DTMF
tecla = None
for freq in frequencias.values():
if np.isclose(xf[index[0]], freq[0], rtol=0.1) and np.isclose(xf[index[1]], freq[1], rtol=0.1):
tecla = frequencias[freq]
break
if tecla is not None:
print("Tecla pressionada: {}".format(tecla))
else:
print("Nenhuma tecla pressionada foi detectada.")
#Você pode tentar também identificar a tecla de um telefone real! Basta gravar o som emitido pelo seu celular ao pressionar uma tecla.
## Exiba gráficos do fourier do som gravados
plt.plot(xf[:len(xf)//2], yf[:len(yf)//2])
plt.xlabel('Frequência (Hz)')
plt.ylabel('Amplitude')
plt.show()
if __name__ == "__main__":
main()