SlideShare uma empresa Scribd logo
1 de 47
Baixar para ler offline
AudioLazy - DSP expressivo e em
tempo real para o Python
http://pypi.python.org/pypi/audiolazyhttp://pypi.python.org/pypi/audiolazy
Copyright (C) 2012-2013Copyright (C) 2012-2013
Danilo de Jesus da Silva Bellini <danilo.bellini@gmail.com>Danilo de Jesus da Silva Bellini <danilo.bellini@gmail.com>
Parte 1
Síntese! Show me the code!
Go go go!Go go go!
Não, Python!Não, Python!
“Hello world” em áudio
● Tocar uma senóide
– Console interativo
– Script
from audiolazy import *
rate = 44100
s, Hz = sHz(rate)
th = AudioIO().play(sinusoid(440 * Hz), rate=rate)
from audiolazy import *
rate = 44100
s, Hz = sHz(rate)
th = AudioIO().play(sinusoid(440 * Hz), rate=rate)
from audiolazy import *
rate = 44100
s, Hz = sHz(rate)
with AudioIO(True) as player:
player.play(sinusoid(440 * Hz), rate=rate)
from audiolazy import *
rate = 44100
s, Hz = sHz(rate)
with AudioIO(True) as player:
player.play(sinusoid(440 * Hz), rate=rate)
Multithread!
Síntese
● ControlStream
– Property “value”
– Permite interatividade
● Tempo real
● Síntese
– Ring Modulation - Senóide * Senóide
– AM - Senóide * (1 + Senóide)
– FM - Senóide(Senóide)
– Subtrativa (e.g. Karplus-Strong)
– Aditiva (e.g. TableLookup) Imagem da
Wikipedia
Exemplos!!!wxPython,
Music21
Parte 2
Queremos mais itertools!!!
repeat chain count imap ifilter izip ...repeat chain count imap ifilter izip ...
Stream !Stream !
Container para áudio
● Tempo real
– Amostras (dados/elementos) inexistentes...
● ...em tempo de compilação (dados a serem coletados)
● ...em tempo de execução (dados criados no futuro)
– Duração possivelmente indefinida
– Não deve ser necessário computar tudo para começar
a apresentar o resultado
● Resultados parciais
● Para cada amostra de entrada, deve haver uma de saída
– Minimizar lag (atraso) entre entrada e saída
Avaliação tardia!
Classe Stream
● Iterável
● Heterogêneo
● Operadores
– Elementwise/broadcast
como no NumPy
● Avaliação tardia
– Lembra geradores
● Já estávamos usando!
– sinusoid,
karplus_strong,
ControlStream, ...
● Ausência de índices
– Limite de representação
inteira (32 bits
estouraria em 27:03:12)
In [1]: from audiolazy import Stream
In [2]: dados = Stream(5, 7, 1, 2, 5, 3, 2) # Periódico
In [3]: dados2 = Stream(0, 1) # Idem
In [4]: (dados + dados2).take(15)
Out[4]: [5, 8, 1, 3, 5, 4, 2, 6, 7, 2, 2, 6, 3, 3, 5]
In [1]: from audiolazy import Stream
In [2]: dados = Stream(5, 7, 1, 2, 5, 3, 2) # Periódico
In [3]: dados2 = Stream(0, 1) # Idem
In [4]: (dados + dados2).take(15)
Out[4]: [5, 8, 1, 3, 5, 4, 2, 6, 7, 2, 2, 6, 3, 3, 5]
Classe Stream
● Métodos, atributos e propriedades são aplicados
elemento a elemento
– Exceto quando existe na classe Stream (“take”,
“blocks”, “peek”, “skip”, “limit”, ...)
● Finito ou de finalização indeterminada
In [5]: Stream([2, 3, 4]).take(5) # Lista de entrada
Out[5]: [2, 3, 4]
In [6]: Stream(2, 3, 4).take(5) # Números de entrada
Out[6]: [2, 3, 4, 2, 3]
In [7]: Stream(*[2, 3, 4]).take(5) # Lista com "*"
Out[7]: [2, 3, 4, 2, 3]
In [8]: (2 * Stream([1 + 2j, -3j, 7]).real).take(inf)
Out[8]: [2.0, 0.0, 14]
In [5]: Stream([2, 3, 4]).take(5) # Lista de entrada
Out[5]: [2, 3, 4]
In [6]: Stream(2, 3, 4).take(5) # Números de entrada
Out[6]: [2, 3, 4, 2, 3]
In [7]: Stream(*[2, 3, 4]).take(5) # Lista com "*"
Out[7]: [2, 3, 4, 2, 3]
In [8]: (2 * Stream([1 + 2j, -3j, 7]).real).take(inf)
Out[8]: [2.0, 0.0, 14]
Decorador tostream:
Geradores convertidos em Stream
● Já foi aplicado a TODOS os itertools (e.g. count)!!!
In [1]: from audiolazy import tostream
In [2]: @tostream
...: def impulse():
...: yield 1
...: while True:
...: yield 0
...:
In [3]: impulse # De fato, uma função
Out[3]: <function __main__.impulse>
In [4]: impulse() # Devolve um objeto Stream
Out[4]: <audiolazy.lazy_stream.Stream at 0x30824d0>
In [5]: impulse().take(5)
Out[5]: [1, 0, 0, 0, 0]
In [6]: (impulse() + 1).take(5) # Outro objeto instanciado
Out[6]: [2, 1, 1, 1, 1]
In [1]: from audiolazy import tostream
In [2]: @tostream
...: def impulse():
...: yield 1
...: while True:
...: yield 0
...:
In [3]: impulse # De fato, uma função
Out[3]: <function __main__.impulse>
In [4]: impulse() # Devolve um objeto Stream
Out[4]: <audiolazy.lazy_stream.Stream at 0x30824d0>
In [5]: impulse().take(5)
Out[5]: [1, 0, 0, 0, 0]
In [6]: (impulse() + 1).take(5) # Outro objeto instanciado
Out[6]: [2, 1, 1, 1, 1]
Síntese
personalizada!
(Acesso direto
às amostras)
Processamento em bloco
● Stream.blocks(size, hop)
– Qualquer salto (hop) positivo
– Se mudar a saída, a mudança persistirá na próxima
saída quando hop < size
● Saídas são a mesma fila circular implementada como
collections.deque
In [1]: data = Stream([1, 2, 3, 4, 5])
In [2]: blks = data.blocks(size=2, hop=1)
In [3]: [list(blk) for blk in blks]
Out[3]: [[1, 2], [2, 3], [3, 4], [4, 5]]
In [1]: data = Stream([1, 2, 3, 4, 5])
In [2]: blks = data.blocks(size=2, hop=1)
In [3]: [list(blk) for blk in blks]
Out[3]: [[1, 2], [2, 3], [3, 4], [4, 5]]
Parte 3
FiltrosFiltros
Filtros LTI
(Lineares e invariantes no tempo)
““Digital signal processing is mainlyDigital signal processing is mainly
based on linear time-invariantbased on linear time-invariant
systems.systems.””
(Dutilleux, Dempwolf, Holters e Zölzer(Dutilleux, Dempwolf, Holters e Zölzer
DAFx, segunda edição, capítulo 4, p. 103)DAFx, segunda edição, capítulo 4, p. 103)
Transformada Z
● Definição:
● Interpretação:
–Atrasoem k
amostras!
● Muitos “infinitos”
– Teoremas
● Possibilitam o uso prático
(eliminam os “infinitos”)
Exemplo de transformada Z
● Acumulador ● Média móvel
Tá legal...mas, na prática, cadê o tal código?!
Saída / Entrada, ou
H(z) = Y(z) / X(z)
Objeto “z”
In [1]: from audiolazy import z, Stream, maverage
In [2]: M = 5
In [3]: media_movel_5 = (1 - z ** -M) / (M * (1 - z ** -1))
In [4]: acumulador = 1 / (1 - z ** -1)
In [5]: media_movel_5(Stream(5)).take(10)
Out[5]: [1.0, 2.0, 3.0, 4.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0]
In [6]: acumulador(Stream(5)).take(10)
Out[6]: [5.0, 10.0, 15.0, 20.0, 25.0, 30.0, 35.0, 40.0, 45.0, 50.0]
In [7]: maverage.recursive(4)
Out[7]:
0.25 - 0.25 * z^-4
------------------
1 - z^-1
In [1]: from audiolazy import z, Stream, maverage
In [2]: M = 5
In [3]: media_movel_5 = (1 - z ** -M) / (M * (1 - z ** -1))
In [4]: acumulador = 1 / (1 - z ** -1)
In [5]: media_movel_5(Stream(5)).take(10)
Out[5]: [1.0, 2.0, 3.0, 4.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0]
In [6]: acumulador(Stream(5)).take(10)
Out[6]: [5.0, 10.0, 15.0, 20.0, 25.0, 30.0, 35.0, 40.0, 45.0, 50.0]
In [7]: maverage.recursive(4)
Out[7]:
0.25 - 0.25 * z^-4
------------------
1 - z^-1
Filtros LTI, em geral:
Filtros prontos!
● Média móvel
● Ressonadores
● Comb
● Passa-baixas e passa-altas
● Gammatone (Patterson-Holdsworth, audição)
– Slaney
– Klapuri
● 4 ressonadores em cascata
– Implementação genérica (qualquer ordem)
● Teoremas (parte de meu mestrado)
Filtros variantes no tempo!
Coeficientes “a” em de a * z ** -k
podem ser objetos Stream)
Plot (AudioLazy + MatPlotLib)!
● DTFT - Caso particular da transformada Z
– O valor de z está na circunferência complexa unitária
● Método plot dos filtros
– Resposta em frequência
● Método zplot
– Estabilidade do filtro
– Pólos: “X”
● Raízes do denominador
– Zeros: “O”
● Raízes do numerador
X
X
MatPlotLib
faz melhor
que isto...
Considerações finais sobre filtros
● Implementação direta I
– Evita multiplicação por 1
– Não cria os termos com coeficiente nulo
● JIT (Just in Time)
– Cada filtro é criado e compilado em tempo de
execução
– Permite filtros variantes no tempo gerais e (até certo
ponto) eficientes
Parte 4 - Cálculo numérico (e um
pouco de simbólico também)
Heeeeeey, não era sobre áudio?Heeeeeey, não era sobre áudio?
Exemplos
● Pi (exemplo no repositório da AudioLazy)
– Série de Madhava-Gregory-Leibniz
● Fibonacci
atan(v)=v−
v3
3
+
v5
5
−
v7
7
+
v9
9
...
atan(1)= π
4
In [2]: (z ** -1 / (1 - z ** -1 - z ** -2))(impulse()).take(10)
Out[2]: [0.0, 1.0, 1.0, 2.0, 3.0, 5.0, 8.0, 13.0, 21.0, 34.0]
In [2]: (z ** -1 / (1 - z ** -1 - z ** -2))(impulse()).take(10)
Out[2]: [0.0, 1.0, 1.0, 2.0, 3.0, 5.0, 8.0, 13.0, 21.0, 34.0]
h[n]=h[n−1]+h[ n−2]+δ[ n−1]
Polinômios
● Necessário para os filtros lineares
● Baseados em dicionário
– Memória
– Expoente negativo (Laurent)
– Expoente fracionário (soma de potências)
● Coeficientes podem ser objetos Stream, símbolos
do SymPy, etc.
● Objeto “x”
● Interpolação (polinômios de Lagrange)
In [9]: lagrange.poly([(1, 3), (3, 14), (45, 0)])
Out[9]: -2.89773 + 6.0303 * x - 0.132576 * x^2
In [9]: lagrange.poly([(1, 3), (3, 14), (45, 0)])
Out[9]: -2.89773 + 6.0303 * x - 0.132576 * x^2
In [8]: (x + x ** 2 + x ** -.5)(4)
Out[8]: 20.5
In [8]: (x + x ** 2 + x ** -.5)(4)
Out[8]: 20.5
SymPy
Stream de símbolos
Comparação de números em ponto
flutuante (IEEE 754)
● Valor absoluto (limiar “l”)
● Comparação pelo número de bits de mantissa (“t”
bits de tolerância para “s” bits de mantissa)
● Implementado em um dicionário de estratégias:
– almost_eq.diff
– almost_eq ou almost_eq.bits
∣a−b∣≤l
∣a−b∣≤2(t − s−1)∣a+b∣
Quantização em ponto flutuante
Com CascadeFilter
Warning:
Há textos que nem sempre são claros quanto aos aspectos
necessários à implementação para garantir a estabilidade numérica
freq = 100 * Hz
bw = erb(freq, Hz) * gammatone_erb_constants(4)[0]
filt = gammatone.slaney(freq, bw)
filt.plot(rate=rate, freq_scale="log", samples=8192).show()
freq = 100 * Hz
bw = erb(freq, Hz) * gammatone_erb_constants(4)[0]
filt = gammatone.slaney(freq, bw)
filt.plot(rate=rate, freq_scale="log", samples=8192).show()
Sem CascadeFilter
Parte 5
MIRMIR
((Music Information RetrievalMusic Information Retrieval))
Pitch – Shepard
● Som de Shepard
– Subir “sem parar”
– Exemplo no GitHub
● Duas dimensões:
– Altura (pitch height)
● Dimensão “linear”
– Croma (pitch chroma)
● Dimensão “circular”
● Lembra Escher →
Série harmônica
● F0, 2F0, 3F0, 4F0 …
– 100 Hz, 200 Hz, 300 Hz... Comb!
freqs = [str2freq(note) for note in "E2 G#2 B2".split()] # Mi maior
filt = ParallelFilter(comb.tau(freq_to_lag(freq * Hz), .1 * s)
for freq in freqs)
filt.plot(samples=8192, rate=rate, min_freq=220*Hz, max_freq=880*Hz).show()
freqs = [str2freq(note) for note in "E2 G#2 B2".split()] # Mi maior
filt = ParallelFilter(comb.tau(freq_to_lag(freq * Hz), .1 * s)
for freq in freqs)
filt.plot(samples=8192, rate=rate, min_freq=220*Hz, max_freq=880*Hz).show()
Inteiros?
Racionais?
Primos?
2+ oitava
ZCR
Taxa de cruzamentos no zero
In [15]: pitch1.take(10) # Resultado em Hz
Out[15]:
[872.0947265625001,
882.861328125,
872.0947265625001,
882.861328125,
882.861328125,
882.861328125,
882.861328125,
872.0947265625001,
882.861328125,
872.0947265625001]
In [16]: freq2str(pitch1).take(10) # Resultado em nomes de notas
Out[16]:
['A5+5.62%',
'A5+5.62%',
'A5+5.62%',
'A5+5.62%',
'A5+5.62%',
'A5-15.62%',
'A5+5.62%',
'A5-15.62%',
'A5+5.62%',
'A5+5.62%']
In [15]: pitch1.take(10) # Resultado em Hz
Out[15]:
[872.0947265625001,
882.861328125,
872.0947265625001,
882.861328125,
882.861328125,
882.861328125,
882.861328125,
872.0947265625001,
882.861328125,
872.0947265625001]
In [16]: freq2str(pitch1).take(10) # Resultado em nomes de notas
Out[16]:
['A5+5.62%',
'A5+5.62%',
'A5+5.62%',
'A5+5.62%',
'A5+5.62%',
'A5-15.62%',
'A5+5.62%',
'A5-15.62%',
'A5+5.62%',
'A5+5.62%']
pitch1 = zcross_pitch(data1) / Hzpitch1 = zcross_pitch(data1) / Hz
@tostream
def zcross_pitch(sig, size=2048):
"Devolve a altura em cada bloco com o dado tamanho"
for blk in zcross(sig, hysteresis=.2).blocks(size):
yield lag_to_freq(2. * size / sum(blk))
@tostream
def zcross_pitch(sig, size=2048):
"Devolve a altura em cada bloco com o dado tamanho"
for blk in zcross(sig, hysteresis=.2).blocks(size):
yield lag_to_freq(2. * size / sum(blk))
data1 = .5 * sinusoid(880 * Hz)
data1 += .5 * saw_table(880*3 * Hz)
data1 *= .9 + .1 * white_noise()
data1 = .5 * sinusoid(880 * Hz)
data1 += .5 * saw_table(880*3 * Hz)
data1 *= .9 + .1 * white_noise()
Por quenão DFT?
AMDF (Average Magnitude Difference
Function)
Autocorrelação
Transcrição por envoltória dinâmica
Decomposição cromática
● Filtros gammatone
– Paralelo
● Oitavas
In [1]: from audiolazy import octaves
In [2]: octaves(440)
Out[2]: [27.5, 55.0, 110.0, 220.0, 440, 880, 1760, 3520, 7040, 14080]
In [1]: from audiolazy import octaves
In [2]: octaves(440)
Out[2]: [27.5, 55.0, 110.0, 220.0, 440, 880, 1760, 3520, 7040, 14080]
from __future__ import division
from audiolazy import *
def cromafb(classes=12, rate):
s, Hz = sHz(rate)
cg = gammatone_erb_constants(4)[0]
fb = 440
return [
ParallelFilter(
gammatone.sampled(f*Hz, cg*erb(f))
for f in octaves(fb * 2**(n/classes))
) for n in xrange(classes)
]
rate = 44100
bank = cromafb(rate=rate)
bank[0].plot(freq_scale="log", rate=rate)
from __future__ import division
from audiolazy import *
def cromafb(classes=12, rate):
s, Hz = sHz(rate)
cg = gammatone_erb_constants(4)[0]
fb = 440
return [
ParallelFilter(
gammatone.sampled(f*Hz, cg*erb(f))
for f in octaves(fb * 2**(n/classes))
) for n in xrange(classes)
]
rate = 44100
bank = cromafb(rate=rate)
bank[0].plot(freq_scale="log", rate=rate)
Cromagrama
from audiolazy import *
rate = 22050
s, Hz = sHz(rate)
size = 512
table = sin_table.harmonize({1: 1, 2: 5, 3: 3, 4: 2, 6: 9, 8: 1}).normalize()
data = table(str2freq("Bb3") * Hz).take(size) # Nota si bemol da 3a oitava
filt = lpc(data, order=14) # Filtro de análise
G = 1e-2 # Ganho apenas para alinhamento na visualização com a DFT
# Filtro de síntese
(G / filt).plot(blk=data, rate=rate, samples=1024, unwrap=False).show()
from audiolazy import *
rate = 22050
s, Hz = sHz(rate)
size = 512
table = sin_table.harmonize({1: 1, 2: 5, 3: 3, 4: 2, 6: 9, 8: 1}).normalize()
data = table(str2freq("Bb3") * Hz).take(size) # Nota si bemol da 3a oitava
filt = lpc(data, order=14) # Filtro de análise
G = 1e-2 # Ganho apenas para alinhamento na visualização com a DFT
# Filtro de síntese
(G / filt).plot(blk=data, rate=rate, samples=1024, unwrap=False).show()
Envoltória espectral
LPC - Predição Linear
Formantes
Pode ser
utilizado para
classificação
de vogais
Parte 6
NúcleoNúcleo
(Não, não vai explodir...)(Não, não vai explodir...)
AbstractOperatorOverloaderMeta
● Metaclasse
– Classe cujas instâncias são classes
● Abstrata
– Classe com recursos especificados porém sem
implementação
● Sobrecarga massiva de operadores:
– Binários
– Binários reversos
– Unários
● Utiliza-se da classe OpMethod
– Organiza todos os 33 possíveis dunders de operadores
Há, entretanto, 35 no Python 2.
AbstractOperatorOverloaderMeta
insere __div__ e __rdiv__
automaticamente a partir de
__truediv__ e __rtruediv__
(quando aplicável)
Objeto window
Um dicionário de estratégias
In [1]: from audiolazy import window
In [2]: window # Vejamos as estratégias disponíveis
Out[2]:
{('bartlett',): <function audiolazy.lazy_analysis.bartlett>,
('blackman',): <function audiolazy.lazy_analysis.blackman>,
('hamming',): <function audiolazy.lazy_analysis.hamming>,
('hann', 'hanning'): <function audiolazy.lazy_analysis.hann>,
('rectangular', 'rect'): <function audiolazy.lazy_analysis.rectangular>,
('triangular', 'triangle'): <function audiolazy.lazy_analysis.triangular>}
In [3]: window["rect"](3) # Obtém a estratégia, chamando com 1 argumento
Out[3]: [1.0, 1.0, 1.0]
In [4]: window.triangle(3) # Idem, mas feito com outra sintaxe (dicionário)
Out[4]: [0.5, 1.0, 0.5]
In [5]: hm_wnd = window.hamming # Referenciando fora do dicionário
In [6]: hm_wnd # Esta estratégia é uma função comum
Out[6]: <function audiolazy.lazy_analysis.hamming>
In [1]: from audiolazy import window
In [2]: window # Vejamos as estratégias disponíveis
Out[2]:
{('bartlett',): <function audiolazy.lazy_analysis.bartlett>,
('blackman',): <function audiolazy.lazy_analysis.blackman>,
('hamming',): <function audiolazy.lazy_analysis.hamming>,
('hann', 'hanning'): <function audiolazy.lazy_analysis.hann>,
('rectangular', 'rect'): <function audiolazy.lazy_analysis.rectangular>,
('triangular', 'triangle'): <function audiolazy.lazy_analysis.triangular>}
In [3]: window["rect"](3) # Obtém a estratégia, chamando com 1 argumento
Out[3]: [1.0, 1.0, 1.0]
In [4]: window.triangle(3) # Idem, mas feito com outra sintaxe (dicionário)
Out[4]: [0.5, 1.0, 0.5]
In [5]: hm_wnd = window.hamming # Referenciando fora do dicionário
In [6]: hm_wnd # Esta estratégia é uma função comum
Out[6]: <function audiolazy.lazy_analysis.hamming>
Também é um iterável por
suas estratégias
(ver windows_plot.py)
Documentação
● Docstrings: documentação no código
– Uso em ambientes interativos
– reStructuredText
– Organização em seções
● Visualização no Spyder (Rich Text), IPython
● Sphinx
– Conversão automática do sistema de seções para o formato do
Sphinx
– Muitos formatos: LaTeX (PDF, DVI, PS), ePUB, HTML, TexInfo, etc.
● Apresentação, instruções de instalação e exemplos básicos
– Integração com MatPlotLib, Music21, wxPython, Tkinter, etc.
http://pythonhosted.org/audiolazy
https://github.com/danilobellini/audiolazy/tree/master/audiolazy/examples
Parte 7
FinalizaçãoFinalização
AudioLazy
● DSP (Digital Signal Processing) para áudio
– Análise
● MIR (Music Information Retrieval)
– Síntese
– Processamento
● Expressividade de código
– Facilita prototipação, simulação
● Tempo real (latência de 35ms é possível)
– Possibilita uso em aplicações finais
● 100% Python
– Multiplataforma
Suporta Python 2 e 3 com o
mesmo código!
Motivações e justificativas
No papel...
● Demanda e insatisfação com código existente
– Por mim
● Vetores (NumPy, Octave/MatLab)...tempo real?
● Índices...=(
– Por outros
● Sustainable Software for Audio and Music Research
– ISMIR 2012 (Tutorial)
– DAFx 2012 (Tutorial)
● Software Carpentry
● Ausência de código fonte disponível
– Algoritmo de Klapuri (2008)!!! Bad guy...código?
● Base para trabalhos futuros
Resumidamente:
The Litmus Test
If you have to refer to theIf you have to refer to the
documentation every timedocumentation every time
you use a module, find (oryou use a module, find (or
build) a new module.build) a new module.
Até tentei evitar...mas...
Resultados cobertura de código
(Testes automatizados)
--------------- coverage: platform linux2, python 2.7.3-final-0 ----------------
Name Stmts Miss Branch BrPart Cover Missing
------------------------------------------------------------
__init__ 44 1 18 4 92% 72
lazy_analysis 125 3 60 2 97% 211, 259-260
lazy_auditory 60 0 14 0 100%
lazy_compat 42 5 6 1 88% 43, 67-68, 78-79
lazy_core 174 7 78 9 94% 124, 136-138, 346, 471, 478
lazy_filters 509 179 245 117 61% 55, 62, 83, 93, [...]
lazy_io 156 43 58 28 67% 89, 141-157, 161, [...]
lazy_itertools 37 12 20 13 56% 38, 59-60, 69-74, 100-103
lazy_lpc 128 15 42 7 87% 121, 135-136, [...]
lazy_math 61 1 28 0 99% 133
lazy_midi 54 5 26 3 90% 70, 111, 150, 156, 158
lazy_misc 110 9 62 10 89% 156-157, 194, [...]
lazy_poly 184 2 124 3 98% 387-388
lazy_stream 175 2 76 4 98% 59, 738
lazy_synth 243 32 118 39 80% 277-299, 428, 430, [...]
lazy_text 104 16 70 18 80% 133-148, 207, [...]
------------------------------------------------------------
TOTAL 2206 332 1045 258 82%
========================= 5938 passed in 29.00 seconds =========================
--------------- coverage: platform linux2, python 2.7.3-final-0 ----------------
Name Stmts Miss Branch BrPart Cover Missing
------------------------------------------------------------
__init__ 44 1 18 4 92% 72
lazy_analysis 125 3 60 2 97% 211, 259-260
lazy_auditory 60 0 14 0 100%
lazy_compat 42 5 6 1 88% 43, 67-68, 78-79
lazy_core 174 7 78 9 94% 124, 136-138, 346, 471, 478
lazy_filters 509 179 245 117 61% 55, 62, 83, 93, [...]
lazy_io 156 43 58 28 67% 89, 141-157, 161, [...]
lazy_itertools 37 12 20 13 56% 38, 59-60, 69-74, 100-103
lazy_lpc 128 15 42 7 87% 121, 135-136, [...]
lazy_math 61 1 28 0 99% 133
lazy_midi 54 5 26 3 90% 70, 111, 150, 156, 158
lazy_misc 110 9 62 10 89% 156-157, 194, [...]
lazy_poly 184 2 124 3 98% 387-388
lazy_stream 175 2 76 4 98% 59, 738
lazy_synth 243 32 118 39 80% 277-299, 428, 430, [...]
lazy_text 104 16 70 18 80% 133-148, 207, [...]
------------------------------------------------------------
TOTAL 2206 332 1045 258 82%
========================= 5938 passed in 29.00 seconds =========================
Mock
Testes com oráculos
● 80 c/ o scipy.signal.lfilter
● 64 c/ o subpacote de otimização do SciPy
● 2 c/ o NumPy
import pytest
p = pytest.mark.parametrize
from scipy.signal import lfilter
from audiolazy import ZFilter, almost_eq
class TestZFilterScipy(object):
@p("a", [[1.], [3.], [1., 3.], [15., -17.2], [-18., 9.8, 0., 14.3]])
@p("b", [[1.], [-1.], [1., 0., -1.], [1., 3.]])
@p("data", [range(5), range(5, 0, -1), [7, 22, -5], [8., 3., 15.]])
def test_lfilter(self, a, b, data):
filt = ZFilter(b, a) # Cria um filtro com a AudioLazy
expected = lfilter(b, a, data).tolist() # Aplica o filtro com o SciPy
assert almost_eq(filt(data), expected) # Compara os resultados
import pytest
p = pytest.mark.parametrize
from scipy.signal import lfilter
from audiolazy import ZFilter, almost_eq
class TestZFilterScipy(object):
@p("a", [[1.], [3.], [1., 3.], [15., -17.2], [-18., 9.8, 0., 14.3]])
@p("b", [[1.], [-1.], [1., 0., -1.], [1., 3.]])
@p("data", [range(5), range(5, 0, -1), [7, 22, -5], [8., 3., 15.]])
def test_lfilter(self, a, b, data):
filt = ZFilter(b, a) # Cria um filtro com a AudioLazy
expected = lfilter(b, a, data).tolist() # Aplica o filtro com o SciPy
assert almost_eq(filt(data), expected) # Compara os resultados
Conclusões
● Tempo real em Python
● Expressividade + avaliação tardia
– Modularidade
● Multiparadigma
– Funcional
– Reflexivo
– Objetos
● Filtros digitais a partir de filtros analógicos
● Orientação a testes
● Padrão IEEE 754
Últimas novidades!
● Python 3!
● Contas com polinômios variantes no tempo
● Métodos das classes Stream e StreamTeeHub
– Peek
– Skip
– Limit
● Polinômios de Lagrange (interpolação)
● Reamostragem (taxa de amostragem variante no
tempo)
– Isso é útil? (variante no tempo)
Possíveis continuações para o
desenvolvimento da AudioLazy
● Análise
– FFT
– Heurísticas para transcrição
– Outras transformadas
● Modelagem audição
– Outros modelos (Lyon, Seneff,
gamma chirp, etc.)
– Conversão entre x-dB e ERB
● Síntese e processamento
– Wah, phaser, flanger, chorus, eco,
compressor, noise gate, limiter, …
● Testes
– 100%
– Mock MatPlotLib
●
Filtros
– Atrasos/expoentes variantes no
tempo
– Interpolação por splines
– Frações parciais
– Otimização
– Escrita no tempo
– SymPy
– Treliça
●
Outros
– Integrar com PureData
– I/O MIDI
– Plugins (e.g. Vamp)
– Tutorial
– Logo
Obrigado!
Perguntas?Perguntas?
Fork me on GitHubFork me on GitHub
https://github.com/danilobellini/audiolazyhttps://github.com/danilobellini/audiolazy

Mais conteúdo relacionado

Mais procurados

Hands On TensorFlow and Keras
Hands On TensorFlow and KerasHands On TensorFlow and Keras
Hands On TensorFlow and KerasSandro Moreira
 
Threads 06: Coleções concorrentes
Threads 06: Coleções concorrentesThreads 06: Coleções concorrentes
Threads 06: Coleções concorrentesHelder da Rocha
 
Introdução a linguagem Go
Introdução a linguagem GoIntrodução a linguagem Go
Introdução a linguagem GoAllisson Azevedo
 
Curso de Java: Introdução a lambda e Streams
Curso de Java: Introdução a lambda e StreamsCurso de Java: Introdução a lambda e Streams
Curso de Java: Introdução a lambda e StreamsHelder da Rocha
 
Python: a primeira mordida
Python: a primeira mordidaPython: a primeira mordida
Python: a primeira mordidaLuciano Ramalho
 
Orientação a Objetos em Python
Orientação a Objetos em PythonOrientação a Objetos em Python
Orientação a Objetos em PythonLuciano Ramalho
 
Introdução às Redes Neurais com PHP
Introdução às Redes Neurais com PHPIntrodução às Redes Neurais com PHP
Introdução às Redes Neurais com PHPOtávio Calaça Xavier
 
(2013-09-30) [PythonBrasil] Síntese em tempo real com a AudioLazy
(2013-09-30) [PythonBrasil] Síntese em tempo real com a AudioLazy(2013-09-30) [PythonBrasil] Síntese em tempo real com a AudioLazy
(2013-09-30) [PythonBrasil] Síntese em tempo real com a AudioLazyDanilo J. S. Bellini
 
Apresentação recursividade rev2
Apresentação recursividade rev2Apresentação recursividade rev2
Apresentação recursividade rev2Rogerio Oliveira
 
Ruby e Erlang de mãos dadas
Ruby e Erlang de mãos dadasRuby e Erlang de mãos dadas
Ruby e Erlang de mãos dadasÉverton Ribeiro
 
Sobrecarga e invocação de métodos - Preparatório Certificação - OCAJP7 - Aula...
Sobrecarga e invocação de métodos - Preparatório Certificação - OCAJP7 - Aula...Sobrecarga e invocação de métodos - Preparatório Certificação - OCAJP7 - Aula...
Sobrecarga e invocação de métodos - Preparatório Certificação - OCAJP7 - Aula...Paulo Henrique Lerbach Rodrigues
 
Vetorização e Otimização de Código - Intel Software Conference 2013
Vetorização e Otimização de Código - Intel Software Conference 2013Vetorização e Otimização de Código - Intel Software Conference 2013
Vetorização e Otimização de Código - Intel Software Conference 2013Intel Software Brasil
 
Recursividade em C
Recursividade em CRecursividade em C
Recursividade em CCaique Silva
 
O que é que o Java não tem?
O que é que o Java não tem?O que é que o Java não tem?
O que é que o Java não tem?Denis Costa
 

Mais procurados (20)

(2013-05-03) AudioLazy - Slides
(2013-05-03) AudioLazy - Slides(2013-05-03) AudioLazy - Slides
(2013-05-03) AudioLazy - Slides
 
Hands On TensorFlow and Keras
Hands On TensorFlow and KerasHands On TensorFlow and Keras
Hands On TensorFlow and Keras
 
Recursividade
RecursividadeRecursividade
Recursividade
 
M2ti - Python Brasil
M2ti - Python BrasilM2ti - Python Brasil
M2ti - Python Brasil
 
Threads 06: Coleções concorrentes
Threads 06: Coleções concorrentesThreads 06: Coleções concorrentes
Threads 06: Coleções concorrentes
 
Introdução a linguagem Go
Introdução a linguagem GoIntrodução a linguagem Go
Introdução a linguagem Go
 
Curso de Java: Introdução a lambda e Streams
Curso de Java: Introdução a lambda e StreamsCurso de Java: Introdução a lambda e Streams
Curso de Java: Introdução a lambda e Streams
 
Python: a primeira mordida
Python: a primeira mordidaPython: a primeira mordida
Python: a primeira mordida
 
Orientação a Objetos em Python
Orientação a Objetos em PythonOrientação a Objetos em Python
Orientação a Objetos em Python
 
Linguagem Go
Linguagem GoLinguagem Go
Linguagem Go
 
Redes Neurais com PHP
Redes Neurais com PHPRedes Neurais com PHP
Redes Neurais com PHP
 
Introdução às Redes Neurais com PHP
Introdução às Redes Neurais com PHPIntrodução às Redes Neurais com PHP
Introdução às Redes Neurais com PHP
 
(2013-09-30) [PythonBrasil] Síntese em tempo real com a AudioLazy
(2013-09-30) [PythonBrasil] Síntese em tempo real com a AudioLazy(2013-09-30) [PythonBrasil] Síntese em tempo real com a AudioLazy
(2013-09-30) [PythonBrasil] Síntese em tempo real com a AudioLazy
 
Apresentação recursividade rev2
Apresentação recursividade rev2Apresentação recursividade rev2
Apresentação recursividade rev2
 
Python
PythonPython
Python
 
Ruby e Erlang de mãos dadas
Ruby e Erlang de mãos dadasRuby e Erlang de mãos dadas
Ruby e Erlang de mãos dadas
 
Sobrecarga e invocação de métodos - Preparatório Certificação - OCAJP7 - Aula...
Sobrecarga e invocação de métodos - Preparatório Certificação - OCAJP7 - Aula...Sobrecarga e invocação de métodos - Preparatório Certificação - OCAJP7 - Aula...
Sobrecarga e invocação de métodos - Preparatório Certificação - OCAJP7 - Aula...
 
Vetorização e Otimização de Código - Intel Software Conference 2013
Vetorização e Otimização de Código - Intel Software Conference 2013Vetorização e Otimização de Código - Intel Software Conference 2013
Vetorização e Otimização de Código - Intel Software Conference 2013
 
Recursividade em C
Recursividade em CRecursividade em C
Recursividade em C
 
O que é que o Java não tem?
O que é que o Java não tem?O que é que o Java não tem?
O que é que o Java não tem?
 

Destaque

บทที่ 2 html introduction
บทที่ 2 html introductionบทที่ 2 html introduction
บทที่ 2 html introductionNattipong Siangyen
 
SKF圆锥滚子轴承参数-Taper Roller Bearings Parameter
SKF圆锥滚子轴承参数-Taper Roller Bearings ParameterSKF圆锥滚子轴承参数-Taper Roller Bearings Parameter
SKF圆锥滚子轴承参数-Taper Roller Bearings ParameterCHIK BEARING
 
News May 18-24
News May 18-24News May 18-24
News May 18-24nuthorn
 
ADVTS DESIGNED BY MR SINHA
ADVTS DESIGNED BY MR SINHAADVTS DESIGNED BY MR SINHA
ADVTS DESIGNED BY MR SINHASunil Sinha
 
Il mangiare pp
Il mangiare ppIl mangiare pp
Il mangiare ppLevMar
 
News May 31 - Jun 6
News May 31 -  Jun 6News May 31 -  Jun 6
News May 31 - Jun 6nuthorn
 
ADV 493 Final Presentation, A Presentation for C3 Events
ADV 493 Final Presentation, A Presentation for C3 EventsADV 493 Final Presentation, A Presentation for C3 Events
ADV 493 Final Presentation, A Presentation for C3 EventsAngela Wright
 
A definitive guide to the brexit negotiations, By Sadaf Alidad
A definitive guide to the brexit negotiations, By Sadaf AlidadA definitive guide to the brexit negotiations, By Sadaf Alidad
A definitive guide to the brexit negotiations, By Sadaf AlidadSadaf Alidad
 
Women and ncds
Women and ncdsWomen and ncds
Women and ncdshansens55
 
Guidelines for international students studying in nz
Guidelines for international students studying in nzGuidelines for international students studying in nz
Guidelines for international students studying in nzzamelianz
 
Meclab 夏遊 美食部2
Meclab 夏遊 美食部2Meclab 夏遊 美食部2
Meclab 夏遊 美食部2Badoyau
 
8 acre property in North Bangalore available for joint development
8 acre property in North Bangalore available for joint development8 acre property in North Bangalore available for joint development
8 acre property in North Bangalore available for joint developmentflatpundits
 
Advecto brochure may 2012
Advecto brochure may 2012Advecto brochure may 2012
Advecto brochure may 2012Advecto Ltd
 
บทที่ 6 การใช้สร้างรายการด้วย list
บทที่ 6 การใช้สร้างรายการด้วย listบทที่ 6 การใช้สร้างรายการด้วย list
บทที่ 6 การใช้สร้างรายการด้วย listNattipong Siangyen
 

Destaque (17)

บทที่ 2 html introduction
บทที่ 2 html introductionบทที่ 2 html introduction
บทที่ 2 html introduction
 
SKF圆锥滚子轴承参数-Taper Roller Bearings Parameter
SKF圆锥滚子轴承参数-Taper Roller Bearings ParameterSKF圆锥滚子轴承参数-Taper Roller Bearings Parameter
SKF圆锥滚子轴承参数-Taper Roller Bearings Parameter
 
News May 18-24
News May 18-24News May 18-24
News May 18-24
 
Hitachi Solutions Ecommerce Store Front Designer Guide
Hitachi Solutions Ecommerce Store Front Designer GuideHitachi Solutions Ecommerce Store Front Designer Guide
Hitachi Solutions Ecommerce Store Front Designer Guide
 
ADVTS DESIGNED BY MR SINHA
ADVTS DESIGNED BY MR SINHAADVTS DESIGNED BY MR SINHA
ADVTS DESIGNED BY MR SINHA
 
Il mangiare pp
Il mangiare ppIl mangiare pp
Il mangiare pp
 
News May 31 - Jun 6
News May 31 -  Jun 6News May 31 -  Jun 6
News May 31 - Jun 6
 
ADV 493 Final Presentation, A Presentation for C3 Events
ADV 493 Final Presentation, A Presentation for C3 EventsADV 493 Final Presentation, A Presentation for C3 Events
ADV 493 Final Presentation, A Presentation for C3 Events
 
A definitive guide to the brexit negotiations, By Sadaf Alidad
A definitive guide to the brexit negotiations, By Sadaf AlidadA definitive guide to the brexit negotiations, By Sadaf Alidad
A definitive guide to the brexit negotiations, By Sadaf Alidad
 
Ha nam
Ha namHa nam
Ha nam
 
Bar Stock Threaded End Thermowell
Bar Stock Threaded End ThermowellBar Stock Threaded End Thermowell
Bar Stock Threaded End Thermowell
 
Women and ncds
Women and ncdsWomen and ncds
Women and ncds
 
Guidelines for international students studying in nz
Guidelines for international students studying in nzGuidelines for international students studying in nz
Guidelines for international students studying in nz
 
Meclab 夏遊 美食部2
Meclab 夏遊 美食部2Meclab 夏遊 美食部2
Meclab 夏遊 美食部2
 
8 acre property in North Bangalore available for joint development
8 acre property in North Bangalore available for joint development8 acre property in North Bangalore available for joint development
8 acre property in North Bangalore available for joint development
 
Advecto brochure may 2012
Advecto brochure may 2012Advecto brochure may 2012
Advecto brochure may 2012
 
บทที่ 6 การใช้สร้างรายการด้วย list
บทที่ 6 การใช้สร้างรายการด้วย listบทที่ 6 การใช้สร้างรายการด้วย list
บทที่ 6 การใช้สร้างรายการด้วย list
 

Semelhante a AudioLazy DSP Python

(2013-10-16) [LatinoWare] Processamento de sinais em Python
(2013-10-16) [LatinoWare] Processamento de sinais em Python(2013-10-16) [LatinoWare] Processamento de sinais em Python
(2013-10-16) [LatinoWare] Processamento de sinais em PythonDanilo J. S. Bellini
 
(2013-10-03) [PythonBrasil] AudioLazy, processamento de sinais para música, j...
(2013-10-03) [PythonBrasil] AudioLazy, processamento de sinais para música, j...(2013-10-03) [PythonBrasil] AudioLazy, processamento de sinais para música, j...
(2013-10-03) [PythonBrasil] AudioLazy, processamento de sinais para música, j...Danilo J. S. Bellini
 
Introdução à Programação em Python
Introdução à Programação em PythonIntrodução à Programação em Python
Introdução à Programação em PythonRodrigo Hübner
 
EDA_Aula_09_Complexidade_2021.1.pdf
EDA_Aula_09_Complexidade_2021.1.pdfEDA_Aula_09_Complexidade_2021.1.pdf
EDA_Aula_09_Complexidade_2021.1.pdfSimoneSantos16595
 
Aula5 introducao c
Aula5 introducao cAula5 introducao c
Aula5 introducao cprofwtelles
 
InterCon 2016 - Software as a service usando Go como principal linguagem: os ...
InterCon 2016 - Software as a service usando Go como principal linguagem: os ...InterCon 2016 - Software as a service usando Go como principal linguagem: os ...
InterCon 2016 - Software as a service usando Go como principal linguagem: os ...iMasters
 
Py sintaxe
Py sintaxePy sintaxe
Py sintaxeFlapenta
 
Estruturas de dados em Python
Estruturas de dados em PythonEstruturas de dados em Python
Estruturas de dados em PythonRicardo Paiva
 
IEEEweek 2017 @ DETI Univ. Aveiro - Workshop Python
IEEEweek 2017 @ DETI Univ. Aveiro - Workshop PythonIEEEweek 2017 @ DETI Univ. Aveiro - Workshop Python
IEEEweek 2017 @ DETI Univ. Aveiro - Workshop PythonDiogo Gomes
 
(2013-07-05) [fisl] Compatibilidade entre Python 2 e 3
(2013-07-05) [fisl] Compatibilidade entre Python 2 e 3(2013-07-05) [fisl] Compatibilidade entre Python 2 e 3
(2013-07-05) [fisl] Compatibilidade entre Python 2 e 3Danilo J. S. Bellini
 
Por que Python? Vamos Conhecer? Vamos Aprender?
Por que Python? Vamos Conhecer? Vamos Aprender?Por que Python? Vamos Conhecer? Vamos Aprender?
Por que Python? Vamos Conhecer? Vamos Aprender?Juliano Atanazio
 
Introdução a linguagem Python
Introdução a linguagem PythonIntrodução a linguagem Python
Introdução a linguagem PythonLuciano Ramalho
 
Desenvolvendo jogos com pygame
Desenvolvendo jogos com pygameDesenvolvendo jogos com pygame
Desenvolvendo jogos com pygameTchelinux
 
Desenvolvendo Jogos com pygame - Rafael Guterres Jeffman - Tchelinux Caxias d...
Desenvolvendo Jogos com pygame - Rafael Guterres Jeffman - Tchelinux Caxias d...Desenvolvendo Jogos com pygame - Rafael Guterres Jeffman - Tchelinux Caxias d...
Desenvolvendo Jogos com pygame - Rafael Guterres Jeffman - Tchelinux Caxias d...Tchelinux
 
Iniciando em Python
Iniciando em PythonIniciando em Python
Iniciando em PythonRober Guerra
 
Arduino e Python: Do It Yourself
Arduino e Python: Do It YourselfArduino e Python: Do It Yourself
Arduino e Python: Do It YourselfBruno Nascimento
 

Semelhante a AudioLazy DSP Python (20)

(2013-10-16) [LatinoWare] Processamento de sinais em Python
(2013-10-16) [LatinoWare] Processamento de sinais em Python(2013-10-16) [LatinoWare] Processamento de sinais em Python
(2013-10-16) [LatinoWare] Processamento de sinais em Python
 
(2013-10-03) [PythonBrasil] AudioLazy, processamento de sinais para música, j...
(2013-10-03) [PythonBrasil] AudioLazy, processamento de sinais para música, j...(2013-10-03) [PythonBrasil] AudioLazy, processamento de sinais para música, j...
(2013-10-03) [PythonBrasil] AudioLazy, processamento de sinais para música, j...
 
Introdução à Programação em Python
Introdução à Programação em PythonIntrodução à Programação em Python
Introdução à Programação em Python
 
Python
PythonPython
Python
 
EDA_Aula_09_Complexidade_2021.1.pdf
EDA_Aula_09_Complexidade_2021.1.pdfEDA_Aula_09_Complexidade_2021.1.pdf
EDA_Aula_09_Complexidade_2021.1.pdf
 
Aula5 introducao c
Aula5 introducao cAula5 introducao c
Aula5 introducao c
 
Aula5 introducao c
Aula5 introducao cAula5 introducao c
Aula5 introducao c
 
InterCon 2016 - Software as a service usando Go como principal linguagem: os ...
InterCon 2016 - Software as a service usando Go como principal linguagem: os ...InterCon 2016 - Software as a service usando Go como principal linguagem: os ...
InterCon 2016 - Software as a service usando Go como principal linguagem: os ...
 
Py sintaxe
Py sintaxePy sintaxe
Py sintaxe
 
Curso de Python e Django
Curso de Python e DjangoCurso de Python e Django
Curso de Python e Django
 
Estruturas de dados em Python
Estruturas de dados em PythonEstruturas de dados em Python
Estruturas de dados em Python
 
IEEEweek 2017 @ DETI Univ. Aveiro - Workshop Python
IEEEweek 2017 @ DETI Univ. Aveiro - Workshop PythonIEEEweek 2017 @ DETI Univ. Aveiro - Workshop Python
IEEEweek 2017 @ DETI Univ. Aveiro - Workshop Python
 
(2013-07-05) [fisl] Compatibilidade entre Python 2 e 3
(2013-07-05) [fisl] Compatibilidade entre Python 2 e 3(2013-07-05) [fisl] Compatibilidade entre Python 2 e 3
(2013-07-05) [fisl] Compatibilidade entre Python 2 e 3
 
Por que Python? Vamos Conhecer? Vamos Aprender?
Por que Python? Vamos Conhecer? Vamos Aprender?Por que Python? Vamos Conhecer? Vamos Aprender?
Por que Python? Vamos Conhecer? Vamos Aprender?
 
Introdução a linguagem Python
Introdução a linguagem PythonIntrodução a linguagem Python
Introdução a linguagem Python
 
Desenvolvendo jogos com pygame
Desenvolvendo jogos com pygameDesenvolvendo jogos com pygame
Desenvolvendo jogos com pygame
 
Desenvolvendo Jogos com pygame - Rafael Guterres Jeffman - Tchelinux Caxias d...
Desenvolvendo Jogos com pygame - Rafael Guterres Jeffman - Tchelinux Caxias d...Desenvolvendo Jogos com pygame - Rafael Guterres Jeffman - Tchelinux Caxias d...
Desenvolvendo Jogos com pygame - Rafael Guterres Jeffman - Tchelinux Caxias d...
 
Iniciando em Python
Iniciando em PythonIniciando em Python
Iniciando em Python
 
Workshop Python
Workshop PythonWorkshop Python
Workshop Python
 
Arduino e Python: Do It Yourself
Arduino e Python: Do It YourselfArduino e Python: Do It Yourself
Arduino e Python: Do It Yourself
 

Mais de Danilo J. S. Bellini

(2018-10-18) [ETEC Uirapuru] Segurança da Informação
(2018-10-18) [ETEC Uirapuru] Segurança da Informação(2018-10-18) [ETEC Uirapuru] Segurança da Informação
(2018-10-18) [ETEC Uirapuru] Segurança da InformaçãoDanilo J. S. Bellini
 
(2018-08-25) [Flask Conf] Introdução ao Sanic - O Flask Assíncrono
(2018-08-25) [Flask Conf] Introdução ao Sanic - O Flask Assíncrono(2018-08-25) [Flask Conf] Introdução ao Sanic - O Flask Assíncrono
(2018-08-25) [Flask Conf] Introdução ao Sanic - O Flask AssíncronoDanilo J. S. Bellini
 
(2018-07-14) [Just Python] Números no Python!
(2018-07-14) [Just Python] Números no Python!(2018-07-14) [Just Python] Números no Python!
(2018-07-14) [Just Python] Números no Python!Danilo J. S. Bellini
 
(2017-08-12) [GruPy-SP] AudioLazy no GruPy! (+LV2)
(2017-08-12) [GruPy-SP] AudioLazy no GruPy! (+LV2)(2017-08-12) [GruPy-SP] AudioLazy no GruPy! (+LV2)
(2017-08-12) [GruPy-SP] AudioLazy no GruPy! (+LV2)Danilo J. S. Bellini
 
(2017-07-22) [TDC] Audiolazy em 2017!
(2017-07-22) [TDC] Audiolazy em 2017!(2017-07-22) [TDC] Audiolazy em 2017!
(2017-07-22) [TDC] Audiolazy em 2017!Danilo J. S. Bellini
 
(2017-05-27) [Grupy-SP] Polígonos, pontos e outras geometrias no Shapely (GIS)
(2017-05-27) [Grupy-SP] Polígonos, pontos e outras geometrias no Shapely (GIS)(2017-05-27) [Grupy-SP] Polígonos, pontos e outras geometrias no Shapely (GIS)
(2017-05-27) [Grupy-SP] Polígonos, pontos e outras geometrias no Shapely (GIS)Danilo J. S. Bellini
 
(2016-08-13) [Grupy-SP] Plugin pytest-doctest-custom v1.0.0
(2016-08-13) [Grupy-SP] Plugin pytest-doctest-custom v1.0.0(2016-08-13) [Grupy-SP] Plugin pytest-doctest-custom v1.0.0
(2016-08-13) [Grupy-SP] Plugin pytest-doctest-custom v1.0.0Danilo J. S. Bellini
 
(2015-03-14) [Grupy-SP] Projetos Open Source, como colaborar?
(2015-03-14) [Grupy-SP] Projetos Open Source, como colaborar?(2015-03-14) [Grupy-SP] Projetos Open Source, como colaborar?
(2015-03-14) [Grupy-SP] Projetos Open Source, como colaborar?Danilo J. S. Bellini
 
(2015-01-29/30) [WTA2015] Adaptatividade em Python (Tutorial)
(2015-01-29/30) [WTA2015] Adaptatividade em Python (Tutorial)(2015-01-29/30) [WTA2015] Adaptatividade em Python (Tutorial)
(2015-01-29/30) [WTA2015] Adaptatividade em Python (Tutorial)Danilo J. S. Bellini
 
(2014-11-05) [PythonBrasil] Testando com py.test e tox
(2014-11-05) [PythonBrasil] Testando com py.test e tox(2014-11-05) [PythonBrasil] Testando com py.test e tox
(2014-11-05) [PythonBrasil] Testando com py.test e toxDanilo J. S. Bellini
 
(2014-10-27) [SETI-UFLA-MG] AudioLazy
(2014-10-27) [SETI-UFLA-MG] AudioLazy(2014-10-27) [SETI-UFLA-MG] AudioLazy
(2014-10-27) [SETI-UFLA-MG] AudioLazyDanilo J. S. Bellini
 
(2014-08-09) [TDC] AudioLazy 0.6 will robotize you!
(2014-08-09) [TDC] AudioLazy 0.6 will robotize you!(2014-08-09) [TDC] AudioLazy 0.6 will robotize you!
(2014-08-09) [TDC] AudioLazy 0.6 will robotize you!Danilo J. S. Bellini
 
(2014-05-24) [Taubaté Perl Mongers] AudioLazy Python DSP (Digital Signal Proc...
(2014-05-24) [Taubaté Perl Mongers] AudioLazy Python DSP (Digital Signal Proc...(2014-05-24) [Taubaté Perl Mongers] AudioLazy Python DSP (Digital Signal Proc...
(2014-05-24) [Taubaté Perl Mongers] AudioLazy Python DSP (Digital Signal Proc...Danilo J. S. Bellini
 
(2013-11-29) [RuPy] AudioLazy Python DSP (Digital Signal Processing)
(2013-11-29) [RuPy] AudioLazy Python DSP (Digital Signal Processing)(2013-11-29) [RuPy] AudioLazy Python DSP (Digital Signal Processing)
(2013-11-29) [RuPy] AudioLazy Python DSP (Digital Signal Processing)Danilo J. S. Bellini
 
(2013-10-17) [LatinoWare] Automatizando o GIMP com Python
(2013-10-17) [LatinoWare] Automatizando o GIMP com Python(2013-10-17) [LatinoWare] Automatizando o GIMP com Python
(2013-10-17) [LatinoWare] Automatizando o GIMP com PythonDanilo J. S. Bellini
 
(2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3
(2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3(2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3
(2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3Danilo J. S. Bellini
 
(2013-07-05) [fisl] Semáforo Gráfico dose para TDD em dojos
(2013-07-05) [fisl] Semáforo Gráfico dose para TDD em dojos(2013-07-05) [fisl] Semáforo Gráfico dose para TDD em dojos
(2013-07-05) [fisl] Semáforo Gráfico dose para TDD em dojosDanilo J. S. Bellini
 

Mais de Danilo J. S. Bellini (20)

(2018-10-18) [ETEC Uirapuru] Segurança da Informação
(2018-10-18) [ETEC Uirapuru] Segurança da Informação(2018-10-18) [ETEC Uirapuru] Segurança da Informação
(2018-10-18) [ETEC Uirapuru] Segurança da Informação
 
(2018-08-25) [Flask Conf] Introdução ao Sanic - O Flask Assíncrono
(2018-08-25) [Flask Conf] Introdução ao Sanic - O Flask Assíncrono(2018-08-25) [Flask Conf] Introdução ao Sanic - O Flask Assíncrono
(2018-08-25) [Flask Conf] Introdução ao Sanic - O Flask Assíncrono
 
(2018-07-14) [Just Python] Números no Python!
(2018-07-14) [Just Python] Números no Python!(2018-07-14) [Just Python] Números no Python!
(2018-07-14) [Just Python] Números no Python!
 
(2017-08-12) [GruPy-SP] AudioLazy no GruPy! (+LV2)
(2017-08-12) [GruPy-SP] AudioLazy no GruPy! (+LV2)(2017-08-12) [GruPy-SP] AudioLazy no GruPy! (+LV2)
(2017-08-12) [GruPy-SP] AudioLazy no GruPy! (+LV2)
 
(2017-07-22) [TDC] Audiolazy em 2017!
(2017-07-22) [TDC] Audiolazy em 2017!(2017-07-22) [TDC] Audiolazy em 2017!
(2017-07-22) [TDC] Audiolazy em 2017!
 
(2017-05-27) [Grupy-SP] Polígonos, pontos e outras geometrias no Shapely (GIS)
(2017-05-27) [Grupy-SP] Polígonos, pontos e outras geometrias no Shapely (GIS)(2017-05-27) [Grupy-SP] Polígonos, pontos e outras geometrias no Shapely (GIS)
(2017-05-27) [Grupy-SP] Polígonos, pontos e outras geometrias no Shapely (GIS)
 
(2016-08-13) [Grupy-SP] Plugin pytest-doctest-custom v1.0.0
(2016-08-13) [Grupy-SP] Plugin pytest-doctest-custom v1.0.0(2016-08-13) [Grupy-SP] Plugin pytest-doctest-custom v1.0.0
(2016-08-13) [Grupy-SP] Plugin pytest-doctest-custom v1.0.0
 
(2015-03-14) [Grupy-SP] Projetos Open Source, como colaborar?
(2015-03-14) [Grupy-SP] Projetos Open Source, como colaborar?(2015-03-14) [Grupy-SP] Projetos Open Source, como colaborar?
(2015-03-14) [Grupy-SP] Projetos Open Source, como colaborar?
 
(2015-01-29/30) [WTA2015] Adaptatividade em Python (Tutorial)
(2015-01-29/30) [WTA2015] Adaptatividade em Python (Tutorial)(2015-01-29/30) [WTA2015] Adaptatividade em Python (Tutorial)
(2015-01-29/30) [WTA2015] Adaptatividade em Python (Tutorial)
 
(2014-11-05) [PythonBrasil] Testando com py.test e tox
(2014-11-05) [PythonBrasil] Testando com py.test e tox(2014-11-05) [PythonBrasil] Testando com py.test e tox
(2014-11-05) [PythonBrasil] Testando com py.test e tox
 
(2014-10-27) [SETI-UFLA-MG] AudioLazy
(2014-10-27) [SETI-UFLA-MG] AudioLazy(2014-10-27) [SETI-UFLA-MG] AudioLazy
(2014-10-27) [SETI-UFLA-MG] AudioLazy
 
(2014-08-09) [TDC] AudioLazy 0.6 will robotize you!
(2014-08-09) [TDC] AudioLazy 0.6 will robotize you!(2014-08-09) [TDC] AudioLazy 0.6 will robotize you!
(2014-08-09) [TDC] AudioLazy 0.6 will robotize you!
 
(2014-05-24) [Taubaté Perl Mongers] AudioLazy Python DSP (Digital Signal Proc...
(2014-05-24) [Taubaté Perl Mongers] AudioLazy Python DSP (Digital Signal Proc...(2014-05-24) [Taubaté Perl Mongers] AudioLazy Python DSP (Digital Signal Proc...
(2014-05-24) [Taubaté Perl Mongers] AudioLazy Python DSP (Digital Signal Proc...
 
(2014-04-16) [Garoa HC] Strategy
(2014-04-16) [Garoa HC] Strategy(2014-04-16) [Garoa HC] Strategy
(2014-04-16) [Garoa HC] Strategy
 
(2013-12-18) [Garoa HC] AudioLazy
(2013-12-18) [Garoa HC] AudioLazy(2013-12-18) [Garoa HC] AudioLazy
(2013-12-18) [Garoa HC] AudioLazy
 
(2014-03-26) [7masters] AudioLazy
(2014-03-26) [7masters] AudioLazy(2014-03-26) [7masters] AudioLazy
(2014-03-26) [7masters] AudioLazy
 
(2013-11-29) [RuPy] AudioLazy Python DSP (Digital Signal Processing)
(2013-11-29) [RuPy] AudioLazy Python DSP (Digital Signal Processing)(2013-11-29) [RuPy] AudioLazy Python DSP (Digital Signal Processing)
(2013-11-29) [RuPy] AudioLazy Python DSP (Digital Signal Processing)
 
(2013-10-17) [LatinoWare] Automatizando o GIMP com Python
(2013-10-17) [LatinoWare] Automatizando o GIMP com Python(2013-10-17) [LatinoWare] Automatizando o GIMP com Python
(2013-10-17) [LatinoWare] Automatizando o GIMP com Python
 
(2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3
(2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3(2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3
(2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3
 
(2013-07-05) [fisl] Semáforo Gráfico dose para TDD em dojos
(2013-07-05) [fisl] Semáforo Gráfico dose para TDD em dojos(2013-07-05) [fisl] Semáforo Gráfico dose para TDD em dojos
(2013-07-05) [fisl] Semáforo Gráfico dose para TDD em dojos
 

AudioLazy DSP Python

  • 1. AudioLazy - DSP expressivo e em tempo real para o Python http://pypi.python.org/pypi/audiolazyhttp://pypi.python.org/pypi/audiolazy Copyright (C) 2012-2013Copyright (C) 2012-2013 Danilo de Jesus da Silva Bellini <danilo.bellini@gmail.com>Danilo de Jesus da Silva Bellini <danilo.bellini@gmail.com>
  • 2. Parte 1 Síntese! Show me the code! Go go go!Go go go! Não, Python!Não, Python!
  • 3. “Hello world” em áudio ● Tocar uma senóide – Console interativo – Script from audiolazy import * rate = 44100 s, Hz = sHz(rate) th = AudioIO().play(sinusoid(440 * Hz), rate=rate) from audiolazy import * rate = 44100 s, Hz = sHz(rate) th = AudioIO().play(sinusoid(440 * Hz), rate=rate) from audiolazy import * rate = 44100 s, Hz = sHz(rate) with AudioIO(True) as player: player.play(sinusoid(440 * Hz), rate=rate) from audiolazy import * rate = 44100 s, Hz = sHz(rate) with AudioIO(True) as player: player.play(sinusoid(440 * Hz), rate=rate) Multithread!
  • 4. Síntese ● ControlStream – Property “value” – Permite interatividade ● Tempo real ● Síntese – Ring Modulation - Senóide * Senóide – AM - Senóide * (1 + Senóide) – FM - Senóide(Senóide) – Subtrativa (e.g. Karplus-Strong) – Aditiva (e.g. TableLookup) Imagem da Wikipedia Exemplos!!!wxPython, Music21
  • 5. Parte 2 Queremos mais itertools!!! repeat chain count imap ifilter izip ...repeat chain count imap ifilter izip ... Stream !Stream !
  • 6. Container para áudio ● Tempo real – Amostras (dados/elementos) inexistentes... ● ...em tempo de compilação (dados a serem coletados) ● ...em tempo de execução (dados criados no futuro) – Duração possivelmente indefinida – Não deve ser necessário computar tudo para começar a apresentar o resultado ● Resultados parciais ● Para cada amostra de entrada, deve haver uma de saída – Minimizar lag (atraso) entre entrada e saída Avaliação tardia!
  • 7. Classe Stream ● Iterável ● Heterogêneo ● Operadores – Elementwise/broadcast como no NumPy ● Avaliação tardia – Lembra geradores ● Já estávamos usando! – sinusoid, karplus_strong, ControlStream, ... ● Ausência de índices – Limite de representação inteira (32 bits estouraria em 27:03:12) In [1]: from audiolazy import Stream In [2]: dados = Stream(5, 7, 1, 2, 5, 3, 2) # Periódico In [3]: dados2 = Stream(0, 1) # Idem In [4]: (dados + dados2).take(15) Out[4]: [5, 8, 1, 3, 5, 4, 2, 6, 7, 2, 2, 6, 3, 3, 5] In [1]: from audiolazy import Stream In [2]: dados = Stream(5, 7, 1, 2, 5, 3, 2) # Periódico In [3]: dados2 = Stream(0, 1) # Idem In [4]: (dados + dados2).take(15) Out[4]: [5, 8, 1, 3, 5, 4, 2, 6, 7, 2, 2, 6, 3, 3, 5]
  • 8. Classe Stream ● Métodos, atributos e propriedades são aplicados elemento a elemento – Exceto quando existe na classe Stream (“take”, “blocks”, “peek”, “skip”, “limit”, ...) ● Finito ou de finalização indeterminada In [5]: Stream([2, 3, 4]).take(5) # Lista de entrada Out[5]: [2, 3, 4] In [6]: Stream(2, 3, 4).take(5) # Números de entrada Out[6]: [2, 3, 4, 2, 3] In [7]: Stream(*[2, 3, 4]).take(5) # Lista com "*" Out[7]: [2, 3, 4, 2, 3] In [8]: (2 * Stream([1 + 2j, -3j, 7]).real).take(inf) Out[8]: [2.0, 0.0, 14] In [5]: Stream([2, 3, 4]).take(5) # Lista de entrada Out[5]: [2, 3, 4] In [6]: Stream(2, 3, 4).take(5) # Números de entrada Out[6]: [2, 3, 4, 2, 3] In [7]: Stream(*[2, 3, 4]).take(5) # Lista com "*" Out[7]: [2, 3, 4, 2, 3] In [8]: (2 * Stream([1 + 2j, -3j, 7]).real).take(inf) Out[8]: [2.0, 0.0, 14]
  • 9. Decorador tostream: Geradores convertidos em Stream ● Já foi aplicado a TODOS os itertools (e.g. count)!!! In [1]: from audiolazy import tostream In [2]: @tostream ...: def impulse(): ...: yield 1 ...: while True: ...: yield 0 ...: In [3]: impulse # De fato, uma função Out[3]: <function __main__.impulse> In [4]: impulse() # Devolve um objeto Stream Out[4]: <audiolazy.lazy_stream.Stream at 0x30824d0> In [5]: impulse().take(5) Out[5]: [1, 0, 0, 0, 0] In [6]: (impulse() + 1).take(5) # Outro objeto instanciado Out[6]: [2, 1, 1, 1, 1] In [1]: from audiolazy import tostream In [2]: @tostream ...: def impulse(): ...: yield 1 ...: while True: ...: yield 0 ...: In [3]: impulse # De fato, uma função Out[3]: <function __main__.impulse> In [4]: impulse() # Devolve um objeto Stream Out[4]: <audiolazy.lazy_stream.Stream at 0x30824d0> In [5]: impulse().take(5) Out[5]: [1, 0, 0, 0, 0] In [6]: (impulse() + 1).take(5) # Outro objeto instanciado Out[6]: [2, 1, 1, 1, 1] Síntese personalizada! (Acesso direto às amostras)
  • 10. Processamento em bloco ● Stream.blocks(size, hop) – Qualquer salto (hop) positivo – Se mudar a saída, a mudança persistirá na próxima saída quando hop < size ● Saídas são a mesma fila circular implementada como collections.deque In [1]: data = Stream([1, 2, 3, 4, 5]) In [2]: blks = data.blocks(size=2, hop=1) In [3]: [list(blk) for blk in blks] Out[3]: [[1, 2], [2, 3], [3, 4], [4, 5]] In [1]: data = Stream([1, 2, 3, 4, 5]) In [2]: blks = data.blocks(size=2, hop=1) In [3]: [list(blk) for blk in blks] Out[3]: [[1, 2], [2, 3], [3, 4], [4, 5]]
  • 12. Filtros LTI (Lineares e invariantes no tempo) ““Digital signal processing is mainlyDigital signal processing is mainly based on linear time-invariantbased on linear time-invariant systems.systems.”” (Dutilleux, Dempwolf, Holters e Zölzer(Dutilleux, Dempwolf, Holters e Zölzer DAFx, segunda edição, capítulo 4, p. 103)DAFx, segunda edição, capítulo 4, p. 103)
  • 13. Transformada Z ● Definição: ● Interpretação: –Atrasoem k amostras! ● Muitos “infinitos” – Teoremas ● Possibilitam o uso prático (eliminam os “infinitos”)
  • 14. Exemplo de transformada Z ● Acumulador ● Média móvel Tá legal...mas, na prática, cadê o tal código?! Saída / Entrada, ou H(z) = Y(z) / X(z)
  • 15. Objeto “z” In [1]: from audiolazy import z, Stream, maverage In [2]: M = 5 In [3]: media_movel_5 = (1 - z ** -M) / (M * (1 - z ** -1)) In [4]: acumulador = 1 / (1 - z ** -1) In [5]: media_movel_5(Stream(5)).take(10) Out[5]: [1.0, 2.0, 3.0, 4.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0] In [6]: acumulador(Stream(5)).take(10) Out[6]: [5.0, 10.0, 15.0, 20.0, 25.0, 30.0, 35.0, 40.0, 45.0, 50.0] In [7]: maverage.recursive(4) Out[7]: 0.25 - 0.25 * z^-4 ------------------ 1 - z^-1 In [1]: from audiolazy import z, Stream, maverage In [2]: M = 5 In [3]: media_movel_5 = (1 - z ** -M) / (M * (1 - z ** -1)) In [4]: acumulador = 1 / (1 - z ** -1) In [5]: media_movel_5(Stream(5)).take(10) Out[5]: [1.0, 2.0, 3.0, 4.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0] In [6]: acumulador(Stream(5)).take(10) Out[6]: [5.0, 10.0, 15.0, 20.0, 25.0, 30.0, 35.0, 40.0, 45.0, 50.0] In [7]: maverage.recursive(4) Out[7]: 0.25 - 0.25 * z^-4 ------------------ 1 - z^-1 Filtros LTI, em geral:
  • 16. Filtros prontos! ● Média móvel ● Ressonadores ● Comb ● Passa-baixas e passa-altas ● Gammatone (Patterson-Holdsworth, audição) – Slaney – Klapuri ● 4 ressonadores em cascata – Implementação genérica (qualquer ordem) ● Teoremas (parte de meu mestrado) Filtros variantes no tempo! Coeficientes “a” em de a * z ** -k podem ser objetos Stream)
  • 17. Plot (AudioLazy + MatPlotLib)! ● DTFT - Caso particular da transformada Z – O valor de z está na circunferência complexa unitária ● Método plot dos filtros – Resposta em frequência ● Método zplot – Estabilidade do filtro – Pólos: “X” ● Raízes do denominador – Zeros: “O” ● Raízes do numerador X X MatPlotLib faz melhor que isto...
  • 18. Considerações finais sobre filtros ● Implementação direta I – Evita multiplicação por 1 – Não cria os termos com coeficiente nulo ● JIT (Just in Time) – Cada filtro é criado e compilado em tempo de execução – Permite filtros variantes no tempo gerais e (até certo ponto) eficientes
  • 19. Parte 4 - Cálculo numérico (e um pouco de simbólico também) Heeeeeey, não era sobre áudio?Heeeeeey, não era sobre áudio?
  • 20. Exemplos ● Pi (exemplo no repositório da AudioLazy) – Série de Madhava-Gregory-Leibniz ● Fibonacci atan(v)=v− v3 3 + v5 5 − v7 7 + v9 9 ... atan(1)= π 4 In [2]: (z ** -1 / (1 - z ** -1 - z ** -2))(impulse()).take(10) Out[2]: [0.0, 1.0, 1.0, 2.0, 3.0, 5.0, 8.0, 13.0, 21.0, 34.0] In [2]: (z ** -1 / (1 - z ** -1 - z ** -2))(impulse()).take(10) Out[2]: [0.0, 1.0, 1.0, 2.0, 3.0, 5.0, 8.0, 13.0, 21.0, 34.0] h[n]=h[n−1]+h[ n−2]+δ[ n−1]
  • 21. Polinômios ● Necessário para os filtros lineares ● Baseados em dicionário – Memória – Expoente negativo (Laurent) – Expoente fracionário (soma de potências) ● Coeficientes podem ser objetos Stream, símbolos do SymPy, etc. ● Objeto “x” ● Interpolação (polinômios de Lagrange) In [9]: lagrange.poly([(1, 3), (3, 14), (45, 0)]) Out[9]: -2.89773 + 6.0303 * x - 0.132576 * x^2 In [9]: lagrange.poly([(1, 3), (3, 14), (45, 0)]) Out[9]: -2.89773 + 6.0303 * x - 0.132576 * x^2 In [8]: (x + x ** 2 + x ** -.5)(4) Out[8]: 20.5 In [8]: (x + x ** 2 + x ** -.5)(4) Out[8]: 20.5
  • 23. Comparação de números em ponto flutuante (IEEE 754) ● Valor absoluto (limiar “l”) ● Comparação pelo número de bits de mantissa (“t” bits de tolerância para “s” bits de mantissa) ● Implementado em um dicionário de estratégias: – almost_eq.diff – almost_eq ou almost_eq.bits ∣a−b∣≤l ∣a−b∣≤2(t − s−1)∣a+b∣
  • 24. Quantização em ponto flutuante Com CascadeFilter Warning: Há textos que nem sempre são claros quanto aos aspectos necessários à implementação para garantir a estabilidade numérica freq = 100 * Hz bw = erb(freq, Hz) * gammatone_erb_constants(4)[0] filt = gammatone.slaney(freq, bw) filt.plot(rate=rate, freq_scale="log", samples=8192).show() freq = 100 * Hz bw = erb(freq, Hz) * gammatone_erb_constants(4)[0] filt = gammatone.slaney(freq, bw) filt.plot(rate=rate, freq_scale="log", samples=8192).show() Sem CascadeFilter
  • 25. Parte 5 MIRMIR ((Music Information RetrievalMusic Information Retrieval))
  • 26. Pitch – Shepard ● Som de Shepard – Subir “sem parar” – Exemplo no GitHub ● Duas dimensões: – Altura (pitch height) ● Dimensão “linear” – Croma (pitch chroma) ● Dimensão “circular” ● Lembra Escher →
  • 27. Série harmônica ● F0, 2F0, 3F0, 4F0 … – 100 Hz, 200 Hz, 300 Hz... Comb! freqs = [str2freq(note) for note in "E2 G#2 B2".split()] # Mi maior filt = ParallelFilter(comb.tau(freq_to_lag(freq * Hz), .1 * s) for freq in freqs) filt.plot(samples=8192, rate=rate, min_freq=220*Hz, max_freq=880*Hz).show() freqs = [str2freq(note) for note in "E2 G#2 B2".split()] # Mi maior filt = ParallelFilter(comb.tau(freq_to_lag(freq * Hz), .1 * s) for freq in freqs) filt.plot(samples=8192, rate=rate, min_freq=220*Hz, max_freq=880*Hz).show() Inteiros? Racionais? Primos? 2+ oitava
  • 28. ZCR Taxa de cruzamentos no zero In [15]: pitch1.take(10) # Resultado em Hz Out[15]: [872.0947265625001, 882.861328125, 872.0947265625001, 882.861328125, 882.861328125, 882.861328125, 882.861328125, 872.0947265625001, 882.861328125, 872.0947265625001] In [16]: freq2str(pitch1).take(10) # Resultado em nomes de notas Out[16]: ['A5+5.62%', 'A5+5.62%', 'A5+5.62%', 'A5+5.62%', 'A5+5.62%', 'A5-15.62%', 'A5+5.62%', 'A5-15.62%', 'A5+5.62%', 'A5+5.62%'] In [15]: pitch1.take(10) # Resultado em Hz Out[15]: [872.0947265625001, 882.861328125, 872.0947265625001, 882.861328125, 882.861328125, 882.861328125, 882.861328125, 872.0947265625001, 882.861328125, 872.0947265625001] In [16]: freq2str(pitch1).take(10) # Resultado em nomes de notas Out[16]: ['A5+5.62%', 'A5+5.62%', 'A5+5.62%', 'A5+5.62%', 'A5+5.62%', 'A5-15.62%', 'A5+5.62%', 'A5-15.62%', 'A5+5.62%', 'A5+5.62%'] pitch1 = zcross_pitch(data1) / Hzpitch1 = zcross_pitch(data1) / Hz @tostream def zcross_pitch(sig, size=2048): "Devolve a altura em cada bloco com o dado tamanho" for blk in zcross(sig, hysteresis=.2).blocks(size): yield lag_to_freq(2. * size / sum(blk)) @tostream def zcross_pitch(sig, size=2048): "Devolve a altura em cada bloco com o dado tamanho" for blk in zcross(sig, hysteresis=.2).blocks(size): yield lag_to_freq(2. * size / sum(blk)) data1 = .5 * sinusoid(880 * Hz) data1 += .5 * saw_table(880*3 * Hz) data1 *= .9 + .1 * white_noise() data1 = .5 * sinusoid(880 * Hz) data1 += .5 * saw_table(880*3 * Hz) data1 *= .9 + .1 * white_noise() Por quenão DFT?
  • 29. AMDF (Average Magnitude Difference Function)
  • 31. Decomposição cromática ● Filtros gammatone – Paralelo ● Oitavas In [1]: from audiolazy import octaves In [2]: octaves(440) Out[2]: [27.5, 55.0, 110.0, 220.0, 440, 880, 1760, 3520, 7040, 14080] In [1]: from audiolazy import octaves In [2]: octaves(440) Out[2]: [27.5, 55.0, 110.0, 220.0, 440, 880, 1760, 3520, 7040, 14080] from __future__ import division from audiolazy import * def cromafb(classes=12, rate): s, Hz = sHz(rate) cg = gammatone_erb_constants(4)[0] fb = 440 return [ ParallelFilter( gammatone.sampled(f*Hz, cg*erb(f)) for f in octaves(fb * 2**(n/classes)) ) for n in xrange(classes) ] rate = 44100 bank = cromafb(rate=rate) bank[0].plot(freq_scale="log", rate=rate) from __future__ import division from audiolazy import * def cromafb(classes=12, rate): s, Hz = sHz(rate) cg = gammatone_erb_constants(4)[0] fb = 440 return [ ParallelFilter( gammatone.sampled(f*Hz, cg*erb(f)) for f in octaves(fb * 2**(n/classes)) ) for n in xrange(classes) ] rate = 44100 bank = cromafb(rate=rate) bank[0].plot(freq_scale="log", rate=rate)
  • 33. from audiolazy import * rate = 22050 s, Hz = sHz(rate) size = 512 table = sin_table.harmonize({1: 1, 2: 5, 3: 3, 4: 2, 6: 9, 8: 1}).normalize() data = table(str2freq("Bb3") * Hz).take(size) # Nota si bemol da 3a oitava filt = lpc(data, order=14) # Filtro de análise G = 1e-2 # Ganho apenas para alinhamento na visualização com a DFT # Filtro de síntese (G / filt).plot(blk=data, rate=rate, samples=1024, unwrap=False).show() from audiolazy import * rate = 22050 s, Hz = sHz(rate) size = 512 table = sin_table.harmonize({1: 1, 2: 5, 3: 3, 4: 2, 6: 9, 8: 1}).normalize() data = table(str2freq("Bb3") * Hz).take(size) # Nota si bemol da 3a oitava filt = lpc(data, order=14) # Filtro de análise G = 1e-2 # Ganho apenas para alinhamento na visualização com a DFT # Filtro de síntese (G / filt).plot(blk=data, rate=rate, samples=1024, unwrap=False).show() Envoltória espectral LPC - Predição Linear Formantes Pode ser utilizado para classificação de vogais
  • 34. Parte 6 NúcleoNúcleo (Não, não vai explodir...)(Não, não vai explodir...)
  • 35. AbstractOperatorOverloaderMeta ● Metaclasse – Classe cujas instâncias são classes ● Abstrata – Classe com recursos especificados porém sem implementação ● Sobrecarga massiva de operadores: – Binários – Binários reversos – Unários ● Utiliza-se da classe OpMethod – Organiza todos os 33 possíveis dunders de operadores Há, entretanto, 35 no Python 2. AbstractOperatorOverloaderMeta insere __div__ e __rdiv__ automaticamente a partir de __truediv__ e __rtruediv__ (quando aplicável)
  • 36. Objeto window Um dicionário de estratégias In [1]: from audiolazy import window In [2]: window # Vejamos as estratégias disponíveis Out[2]: {('bartlett',): <function audiolazy.lazy_analysis.bartlett>, ('blackman',): <function audiolazy.lazy_analysis.blackman>, ('hamming',): <function audiolazy.lazy_analysis.hamming>, ('hann', 'hanning'): <function audiolazy.lazy_analysis.hann>, ('rectangular', 'rect'): <function audiolazy.lazy_analysis.rectangular>, ('triangular', 'triangle'): <function audiolazy.lazy_analysis.triangular>} In [3]: window["rect"](3) # Obtém a estratégia, chamando com 1 argumento Out[3]: [1.0, 1.0, 1.0] In [4]: window.triangle(3) # Idem, mas feito com outra sintaxe (dicionário) Out[4]: [0.5, 1.0, 0.5] In [5]: hm_wnd = window.hamming # Referenciando fora do dicionário In [6]: hm_wnd # Esta estratégia é uma função comum Out[6]: <function audiolazy.lazy_analysis.hamming> In [1]: from audiolazy import window In [2]: window # Vejamos as estratégias disponíveis Out[2]: {('bartlett',): <function audiolazy.lazy_analysis.bartlett>, ('blackman',): <function audiolazy.lazy_analysis.blackman>, ('hamming',): <function audiolazy.lazy_analysis.hamming>, ('hann', 'hanning'): <function audiolazy.lazy_analysis.hann>, ('rectangular', 'rect'): <function audiolazy.lazy_analysis.rectangular>, ('triangular', 'triangle'): <function audiolazy.lazy_analysis.triangular>} In [3]: window["rect"](3) # Obtém a estratégia, chamando com 1 argumento Out[3]: [1.0, 1.0, 1.0] In [4]: window.triangle(3) # Idem, mas feito com outra sintaxe (dicionário) Out[4]: [0.5, 1.0, 0.5] In [5]: hm_wnd = window.hamming # Referenciando fora do dicionário In [6]: hm_wnd # Esta estratégia é uma função comum Out[6]: <function audiolazy.lazy_analysis.hamming> Também é um iterável por suas estratégias (ver windows_plot.py)
  • 37. Documentação ● Docstrings: documentação no código – Uso em ambientes interativos – reStructuredText – Organização em seções ● Visualização no Spyder (Rich Text), IPython ● Sphinx – Conversão automática do sistema de seções para o formato do Sphinx – Muitos formatos: LaTeX (PDF, DVI, PS), ePUB, HTML, TexInfo, etc. ● Apresentação, instruções de instalação e exemplos básicos – Integração com MatPlotLib, Music21, wxPython, Tkinter, etc. http://pythonhosted.org/audiolazy https://github.com/danilobellini/audiolazy/tree/master/audiolazy/examples
  • 39. AudioLazy ● DSP (Digital Signal Processing) para áudio – Análise ● MIR (Music Information Retrieval) – Síntese – Processamento ● Expressividade de código – Facilita prototipação, simulação ● Tempo real (latência de 35ms é possível) – Possibilita uso em aplicações finais ● 100% Python – Multiplataforma Suporta Python 2 e 3 com o mesmo código!
  • 40. Motivações e justificativas No papel... ● Demanda e insatisfação com código existente – Por mim ● Vetores (NumPy, Octave/MatLab)...tempo real? ● Índices...=( – Por outros ● Sustainable Software for Audio and Music Research – ISMIR 2012 (Tutorial) – DAFx 2012 (Tutorial) ● Software Carpentry ● Ausência de código fonte disponível – Algoritmo de Klapuri (2008)!!! Bad guy...código? ● Base para trabalhos futuros
  • 41. Resumidamente: The Litmus Test If you have to refer to theIf you have to refer to the documentation every timedocumentation every time you use a module, find (oryou use a module, find (or build) a new module.build) a new module. Até tentei evitar...mas...
  • 42. Resultados cobertura de código (Testes automatizados) --------------- coverage: platform linux2, python 2.7.3-final-0 ---------------- Name Stmts Miss Branch BrPart Cover Missing ------------------------------------------------------------ __init__ 44 1 18 4 92% 72 lazy_analysis 125 3 60 2 97% 211, 259-260 lazy_auditory 60 0 14 0 100% lazy_compat 42 5 6 1 88% 43, 67-68, 78-79 lazy_core 174 7 78 9 94% 124, 136-138, 346, 471, 478 lazy_filters 509 179 245 117 61% 55, 62, 83, 93, [...] lazy_io 156 43 58 28 67% 89, 141-157, 161, [...] lazy_itertools 37 12 20 13 56% 38, 59-60, 69-74, 100-103 lazy_lpc 128 15 42 7 87% 121, 135-136, [...] lazy_math 61 1 28 0 99% 133 lazy_midi 54 5 26 3 90% 70, 111, 150, 156, 158 lazy_misc 110 9 62 10 89% 156-157, 194, [...] lazy_poly 184 2 124 3 98% 387-388 lazy_stream 175 2 76 4 98% 59, 738 lazy_synth 243 32 118 39 80% 277-299, 428, 430, [...] lazy_text 104 16 70 18 80% 133-148, 207, [...] ------------------------------------------------------------ TOTAL 2206 332 1045 258 82% ========================= 5938 passed in 29.00 seconds ========================= --------------- coverage: platform linux2, python 2.7.3-final-0 ---------------- Name Stmts Miss Branch BrPart Cover Missing ------------------------------------------------------------ __init__ 44 1 18 4 92% 72 lazy_analysis 125 3 60 2 97% 211, 259-260 lazy_auditory 60 0 14 0 100% lazy_compat 42 5 6 1 88% 43, 67-68, 78-79 lazy_core 174 7 78 9 94% 124, 136-138, 346, 471, 478 lazy_filters 509 179 245 117 61% 55, 62, 83, 93, [...] lazy_io 156 43 58 28 67% 89, 141-157, 161, [...] lazy_itertools 37 12 20 13 56% 38, 59-60, 69-74, 100-103 lazy_lpc 128 15 42 7 87% 121, 135-136, [...] lazy_math 61 1 28 0 99% 133 lazy_midi 54 5 26 3 90% 70, 111, 150, 156, 158 lazy_misc 110 9 62 10 89% 156-157, 194, [...] lazy_poly 184 2 124 3 98% 387-388 lazy_stream 175 2 76 4 98% 59, 738 lazy_synth 243 32 118 39 80% 277-299, 428, 430, [...] lazy_text 104 16 70 18 80% 133-148, 207, [...] ------------------------------------------------------------ TOTAL 2206 332 1045 258 82% ========================= 5938 passed in 29.00 seconds ========================= Mock
  • 43. Testes com oráculos ● 80 c/ o scipy.signal.lfilter ● 64 c/ o subpacote de otimização do SciPy ● 2 c/ o NumPy import pytest p = pytest.mark.parametrize from scipy.signal import lfilter from audiolazy import ZFilter, almost_eq class TestZFilterScipy(object): @p("a", [[1.], [3.], [1., 3.], [15., -17.2], [-18., 9.8, 0., 14.3]]) @p("b", [[1.], [-1.], [1., 0., -1.], [1., 3.]]) @p("data", [range(5), range(5, 0, -1), [7, 22, -5], [8., 3., 15.]]) def test_lfilter(self, a, b, data): filt = ZFilter(b, a) # Cria um filtro com a AudioLazy expected = lfilter(b, a, data).tolist() # Aplica o filtro com o SciPy assert almost_eq(filt(data), expected) # Compara os resultados import pytest p = pytest.mark.parametrize from scipy.signal import lfilter from audiolazy import ZFilter, almost_eq class TestZFilterScipy(object): @p("a", [[1.], [3.], [1., 3.], [15., -17.2], [-18., 9.8, 0., 14.3]]) @p("b", [[1.], [-1.], [1., 0., -1.], [1., 3.]]) @p("data", [range(5), range(5, 0, -1), [7, 22, -5], [8., 3., 15.]]) def test_lfilter(self, a, b, data): filt = ZFilter(b, a) # Cria um filtro com a AudioLazy expected = lfilter(b, a, data).tolist() # Aplica o filtro com o SciPy assert almost_eq(filt(data), expected) # Compara os resultados
  • 44. Conclusões ● Tempo real em Python ● Expressividade + avaliação tardia – Modularidade ● Multiparadigma – Funcional – Reflexivo – Objetos ● Filtros digitais a partir de filtros analógicos ● Orientação a testes ● Padrão IEEE 754
  • 45. Últimas novidades! ● Python 3! ● Contas com polinômios variantes no tempo ● Métodos das classes Stream e StreamTeeHub – Peek – Skip – Limit ● Polinômios de Lagrange (interpolação) ● Reamostragem (taxa de amostragem variante no tempo) – Isso é útil? (variante no tempo)
  • 46. Possíveis continuações para o desenvolvimento da AudioLazy ● Análise – FFT – Heurísticas para transcrição – Outras transformadas ● Modelagem audição – Outros modelos (Lyon, Seneff, gamma chirp, etc.) – Conversão entre x-dB e ERB ● Síntese e processamento – Wah, phaser, flanger, chorus, eco, compressor, noise gate, limiter, … ● Testes – 100% – Mock MatPlotLib ● Filtros – Atrasos/expoentes variantes no tempo – Interpolação por splines – Frações parciais – Otimização – Escrita no tempo – SymPy – Treliça ● Outros – Integrar com PureData – I/O MIDI – Plugins (e.g. Vamp) – Tutorial – Logo
  • 47. Obrigado! Perguntas?Perguntas? Fork me on GitHubFork me on GitHub https://github.com/danilobellini/audiolazyhttps://github.com/danilobellini/audiolazy