<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Estatísticas de Timbre
Objetivo
Ao fim desta unidade, o aluno será capaz de utilizar estatísticas de descritores de timbre como um indicador do conteúdo de um arquivo de áudio
Pré-requisitos
Antes de iniciar esta unidade, o aluno deve sentir-se confortável com a seguinte afirmação
Step1:  Estatística e vetores
Podemos utilizar vetores para registrar uma série de medições de um mesmo fenômeno. Um sinal digitalizado, por exemplo, pode ser considerado um vetor. Assim, é possível tomar um certo conjunto de amostras de dois sinais e calcular sua distância Euclidiana, por exemplo. Na notação que aplicamos para sinais, teríamos
Step2:  Normalizando vetores
Uma operação matemática interessante que podemos fazer é a de normalizar vetores. Esta operação resulta em um vetor com média zero e variância unitária. O vetor $\boldsymbol x_{\mbox{normalizado}}$ pode ser calculado por
Step3:  Análise estatística de descritores de áudio
Nesta análise, vamos verificar como as estatísticas de descritores de áudio podem ser utilizadas para identificar, de forma objetiva, o conteúdo de descritores.
No código que segue, calcularemos o flatness espectral ao longo de quadros de curta duração de três trechos de áudio, contendo, respectivamente uma percussão, uma guitarra e um coral. Após, mostraremos os valores calculados em um histograma.
Step4:  Podemos, neste momento, detectar alguns comportamentos interessantes
Step5:  É importante perceber que este procedimento permite relacionar arquivos de áudio a um vetor, de tantas dimensões quanto se queira (poderíamos expandir este procedimento para incluir outros descritores, por exemplo).
Esses vetores podem ser mostrados numa figura
Step6:  Generalização
Até o momento, mostramos como relacionar arquivos de áudio a vetores, mas não há nenhuma prova de que esses vetores são representativos quanto ao conteúdo acústico que utilizamos como base. Vamos começar esse processo de forma anedotal, utilizando o arquivo de áudio que foi usado como exercício na unidade anterior. Calcularemos a média e a variância de seu flatness espectral ao longo do tempo, e então mostraremos como o vetor resultante se relaciona com os anteriores.
Step7:  Podemos visualizar que o ponto de teste parece mais próximo do vetor da Tabla que dos demais. Podemos calcular essa distância
<ASSISTANT_TASK:>
Python Code:
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
# Demonstrando propriedades de vetores
# Ideia: coloque mais dimensoes nos vetores e veja o que acontece!
x = np.array([4, 3])
y = np.array([3, 4])
print x
print y
print x + y # Soma de vetores
print 10 * x # Multiplicacao por escalar
print np.linalg.norm(y), np.linalg.norm(x) # Modulo de vetores
print np.linalg.norm(y-x), np.linalg.norm(x-y) # Distancia euclidiana
Explanation: Estatísticas de Timbre
Objetivo
Ao fim desta unidade, o aluno será capaz de utilizar estatísticas de descritores de timbre como um indicador do conteúdo de um arquivo de áudio
Pré-requisitos
Antes de iniciar esta unidade, o aluno deve sentir-se confortável com a seguinte afirmação:
É possível calcular características objetivas de um espectrograma de forma a caracterizar aspectos de seu conteúdo acústico.
Vetores
Um vetor é um conjunto ordenado de medidas escalares. Por exemplo, podemos indicar um ponto na superfície terrestre através de um par ordenado $(a, b)$, onde $a$ é a longitude e $b$ é a latitude de um ponto. O mesmo vale para o plano Euclidiano: nele, qualquer ponto pode ser definido por um par $(x, y)$.
Um vetor é, usualmente, denotado por uma letra minúscula em negrito, tal qual $\boldsymbol x$. O $n$-ésmio elemento de um vetor é denotado $x_n$ (sem negrito). Para vetores, valem as seguintes propriedades:
Soma de vetores
A soma de dois vetores é um vetor composto pela soma de seus elementos correspondentes. Assim, se $\boldsymbol z = \boldsymbol y + \boldsymbol x$, então $z_n = y_n + x_n$.
Multiplicação por escalar
A multiplicação de um vetor por um número escalar resulta num vetor no qual cada um dos elementos do vetor original foi multiplicado por esse número escalar. Assim, se $\boldsymbol y = a \boldsymbol x$, então $y_n = a x_n$.
Módulo
O módulo de um vetor é igual ao comprimento da reta que o liga à origem. Para vetores de dimensão arbitrária $N$, a norma $||\boldsymbol x ||$ é dada por:
$$|| \boldsymbol x || = \sqrt{\sum_{n=1}^N x_n^2}.$$
Distância Euclidiana
A distância Euclidiana entre dois vetores é igual ao módulo de sua diferença, isto é:
$$d(\boldsymbol x, \boldsymbol y) = || \boldsymbol y - \boldsymbol x || = || \boldsymbol x - \boldsymbol y || = \sqrt{\sum_{n=1}^N (x_n-y_n)^2}.$$
End of explanation
# Demonstrando propriedades de vetores
# Ideia: coloque mais dimensoes nos vetores e veja o que acontece!
x = np.array([-40, -30, 30, 40])
y = np.array([3, 4, -3, -4])
z = np.array([0, 1, -6, -7])
print np.mean(x), np.mean(y), np.mean(z) # Medias
print np.var(x), np.var(y), np.var(z) # Variancias
Explanation: Estatística e vetores
Podemos utilizar vetores para registrar uma série de medições de um mesmo fenômeno. Um sinal digitalizado, por exemplo, pode ser considerado um vetor. Assim, é possível tomar um certo conjunto de amostras de dois sinais e calcular sua distância Euclidiana, por exemplo. Na notação que aplicamos para sinais, teríamos:
$$d(\boldsymbol x, \boldsymbol y) = \sqrt{\sum_{n=0}^{N-1} (x[n]-y[n])^2}.$$
Assim, verificamos que vetores e sinais podem ser representados da mesma maneira, e, portanto, podemos aplicar propriedades de sinais em vetores e propriedades de vetores em sinais.
Em vetores, tanto quanto em sinais ou em um conjunto qualquer de números, podemos calcular medidas estatísticas. Elas descrevem como um sinal se comporta ao longo de várias medições, sob um ponto de vista estatístico.
Média e Variância
A média de um conjunto de amostras é dada por:
$$\mu_x = \frac{\sum_{n=0}^{N-1} x[n]}{N}.$$
A média é o valor $a$ que minimiza a soma dos quadrados das distâncias $(a-x[n])^2$ ao longo de todas as amostras, isto é:
$$\mu_x = \arg \min_a \sum_{n=0}^{N-1} (a-x[n])^2.$$
Ainda assim, sempre que houver qualquer tipo de variação em um sinal $x[n]$, é impossível escolher um valor que leva a soma de todas as distâncias a zero. A medida que indica qual é a dispersão residual é a variância, dada por:
$$\sigma^2_x = \sum_{n=0} ^{N-1} (\mu_x - x[n])^2.$$
A media $\sigma_x = \sqrt{\sigma_x^2}$ é chamada de desvio padrão.
End of explanation
x = np.array([4, 3, 2, 4, 3.2, 1, 2, 90, 1, 2, 3, 4])
x_norm = (x - np.mean(x))/np.sqrt(np.var(x))
print np.mean(x), np.mean(x_norm)
print np.var(x), np.var(x_norm)
Explanation: Normalizando vetores
Uma operação matemática interessante que podemos fazer é a de normalizar vetores. Esta operação resulta em um vetor com média zero e variância unitária. O vetor $\boldsymbol x_{\mbox{normalizado}}$ pode ser calculado por:
$$\boldsymbol x_{\mbox{normalizado}} = \frac{\boldsymbol x-\mu_x}{\sigma_x}.$$
End of explanation
import mir3.modules.tool.wav2spectrogram as spectrogram
import mir3.modules.features.flatness as flatness
fnames = ['audio/tabla.wav', 'audio/bbking.wav', 'audio/chorus.wav']
flat_samples = []
for fname in fnames:
    wav2spec = spectrogram.Wav2Spectrogram() # Objeto que converte arquivos wav para espectrogramas
    s = wav2spec.convert(open(fname, 'rb'), window_length=1024, window_step=512, spectrum_type='magnitude')
    fness = flatness.Flatness()
    f = fness.calc_track(s)
    flat_samples.append(f.data)
    
plt.figure();
plt.hist(flat_samples, 15, normed=1, histtype='bar',
                            color=['red', 'blue', 'green'],
                            label=['Tabla', 'Guitarra', 'Coral']);
plt.xlabel('Flatness');
plt.ylabel('Quantidade de quadros');
plt.legend(loc=1);
Explanation: Análise estatística de descritores de áudio
Nesta análise, vamos verificar como as estatísticas de descritores de áudio podem ser utilizadas para identificar, de forma objetiva, o conteúdo de descritores.
No código que segue, calcularemos o flatness espectral ao longo de quadros de curta duração de três trechos de áudio, contendo, respectivamente uma percussão, uma guitarra e um coral. Após, mostraremos os valores calculados em um histograma.
End of explanation
m = []
s =[]
for a in xrange(3):
    m.append(np.mean(flat_samples[a]))
    s.append(np.var(flat_samples[a]))
    
    print fnames[a], np.mean(flat_samples[a]), np.var(flat_samples[a])
Explanation: Podemos, neste momento, detectar alguns comportamentos interessantes:
* O flatness do coral permanece o tempo todo abaixo de 0.1
* Embora o flatness da guitarra seja, em geral, baixo, também pode subir para valores mais altos
* O flatness da tabla tem uma dispersão muito grande entre 0 e 0.45.
Veja que essas observações indicam que a média (a tendência geral) e a variância (dispersão) podem ser boas formas de descrever esses histogramas em uma forma mais compacta
End of explanation
color=['red', 'blue', 'green']
label=['Tabla', 'Guitarra', 'Coral']
plt.figure();
for a in xrange(len(m)):
    plt.scatter(m[a], s[a], color=color[a], label=label[a])
plt.xlabel('Media de flatness')
plt.ylabel('Variancia de flatness')
plt.legend(label, loc=4);
plt.show()
Explanation: É importante perceber que este procedimento permite relacionar arquivos de áudio a um vetor, de tantas dimensões quanto se queira (poderíamos expandir este procedimento para incluir outros descritores, por exemplo).
Esses vetores podem ser mostrados numa figura:
End of explanation
wav2spec = spectrogram.Wav2Spectrogram() # Objeto que converte arquivos wav para espectrogramas
spec = wav2spec.convert(open('audio/testing.wav', 'rb'), window_length=1024, window_step=512, spectrum_type='magnitude')
fness = flatness.Flatness()
f = fness.calc_track(spec)
m.append(np.mean(f.data))
s.append(np.var(f.data))
color=['red', 'blue', 'green', 'black']
label=['Tabla', 'Guitarra', 'Coral', 'Teste']
plt.figure();
for a in xrange(len(m)):
    plt.scatter(m[a], s[a], color=color[a], label=label[a])
plt.xlabel('Media de flatness')
plt.ylabel('Variancia de flatness')
plt.legend(label, loc=4);
plt.show()
Explanation: Generalização
Até o momento, mostramos como relacionar arquivos de áudio a vetores, mas não há nenhuma prova de que esses vetores são representativos quanto ao conteúdo acústico que utilizamos como base. Vamos começar esse processo de forma anedotal, utilizando o arquivo de áudio que foi usado como exercício na unidade anterior. Calcularemos a média e a variância de seu flatness espectral ao longo do tempo, e então mostraremos como o vetor resultante se relaciona com os anteriores.
End of explanation
for i in xrange(3):
    print label[i], np.linalg.norm( np.array([s[-1]-s[i], m[-1]-m[i]]))
Explanation: Podemos visualizar que o ponto de teste parece mais próximo do vetor da Tabla que dos demais. Podemos calcular essa distância:
End of explanation
<END_TASK>