O documento descreve a instalação e uso básico da biblioteca Python AudioLazy para síntese de áudio em tempo real. As principais informações são:
1) AudioLazy pode ser instalada via pip ou clonando o repositório GitHub. Dependências incluem PyAudio, NumPy, SciPy entre outras.
2) A biblioteca permite gerar formas de onda como senóides e ruídos. Exemplos incluem tocar uma nota simples e somar múltiplas senóides.
3) Streams representam dados de áudio de forma lazy, permit
(2013-07-05) [fisl] Compatibilidade entre Python 2 e 3
(2013-09-30) [PythonBrasil] Síntese em tempo real com a AudioLazy
1. Síntese em tempo real com a
AudioLazy
http://pypi.python.org/pypi/audiolazy
Copyright (C) 2012-2013
Danilo de Jesus da Silva Bellini
danilo.bellini@gmail.com
@danilobellini
Brasília – DF
8 horas de
treinamento
Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini
2. Parte 0
Instalação
Brasília – DF
8 horas de
treinamento
Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini
3. Instalando
AudioL
a
pip install audiolazy
pip install audiolazy
# ou
# ou
easy_install audiolazy
easy_install audiolazy
# ou (em um diretório apropriado)
# ou (em um diretório apropriado)
wget -c https://pypi.python.org/packages/source/a/audiolazy/audiolazy-0.05.tar.gz
wget -c https://pypi.python.org/packages/source/a/audiolazy/audiolazy-0.05.tar.gz
tar xvzf audiolazy-0.05.tar.gz
tar xvzf audiolazy-0.05.tar.gz
python audiolazy-0.05/setup.py install
python audiolazy-0.05/setup.py install
# ou
# ou
git clone https://github.com/danilobellini/audiolazy
git clone https://github.com/danilobellini/audiolazy
cd audiolazy
cd audiolazy
pip install .
pip install .
# ou
# ou
pip install git+https://github.com/danilobellini/audiolazy
pip install git+https://github.com/danilobellini/audiolazy
●
PyAudio, NumPy, MatPlotLib, SciPy, wxPython
(python-wxgtk2.8)
–
–
●
“Dependencias”
Pode instalar pelo apt-get, pacman, ...
Music21
Brasília – DF
8 horas de
treinamento
Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini
zy
4. Parte 1
Senóides
Go go go!
Não, é Python!
Brasília – DF
8 horas de
treinamento
Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini
5. Antes da tecnologia digital...
●
1807 – Thomas Young – Vibroscópio
●
1860 – Leon Scott – Fonoautógrafo
●
●
–
1877 – Charles Cros / Thomas Edison – Parleofone
(modelo) / Fonógrafo (implementação e patente)
●
1888 – Emil Berliner – Gramofone
●
1939 – John Cage – Imaginary Landscape No. 1
1948 – Musique concrète
–
https://www.youtube.com/watch?v=CVN_mxVntXk
–
2 vitrolas (velocidade variável) c/ a gravação de uma
frequência, piano abafado e prato
–
Pierre Schaeffer – Etude aux Chemin
de Fer
●
●
1951 – Elektronische Musik
Uma das primeiras músicas eletroacústicas da história
–
Estúdio em Colônia – Alemanha
(NWDR – Nordwestdeutscher
Rundfunk)
●
●
–
Brasília – DF
8 horas de
treinamento
https://www.youtube.com/watch?v=N9pOq8
Equipamento para geração e
processamento de sons. Permite
“compor diretamente na fita magnética”.
Herbert Eimert
Cursos de verão em Darmstadt
Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini
6. Década de 1950
Síntese aditiva analógica
●
Música eletrônica
●
Karlheinz Stockhausen – Opus 3
–
Para síntese aditiva [analógica]
–
1953 – Estudo I
●
–
http://www.youtube.com/watch?v=5_NWwUB6Dis
1954 – Estudo II
●
Número 5:
–
–
●
Intervalo entre fundamental e quinto harmônico dividido em 25 alturas
Proporção de frequências: √ 5
25
http://www.youtube.com/watch?v=hXqvBvOXV3U
Brasília – DF
8 horas de
treinamento
Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini
7. “Hello world” em áudio
●
Tocar uma senóide
–
Console interativo
from audiolazy import *
from audiolazy import *
Multith
re
rate = 44100
rate = 44100
s, Hz = sHz(rate)
s, Hz = sHz(rate)
ad!
player = AudioIO()
player = AudioIO()
snd = sinusoid(440 * Hz).limit(2 * s)
snd = sinusoid(440 * Hz).limit(2 * s)
th = player.play(snd, rate=rate) # an AudioThread
th = player.play(snd, rate=rate) # an AudioThread
player.close() # Kill th (AudioIO arg isn't true)
player.close() # Kill th (AudioIO arg isn't true)
–
Scripts podem usar gerenciadores de contexto
with AudioIO(True) as player: # Wait threads
with AudioIO(True) as player: # Wait threads
player.play(snd, rate=rate)
player.play(snd, rate=rate)
Brasília – DF
8 horas de
treinamento
Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini
8. Notas/Alturas e MIDI Pitch
●
Notas/alturas
–
D = Ré
–
E = Mi
–
F = Fá
–
A = Lá
–
B = Si
–
–
●
MIDI Pitch
–
str2freq
–
“Cb4” (dó bemol) é a mesma nota que B3
freq2str
–
Ignoram a alteração
str2midi
–
Iniciam em dó
midi2str
–
Oitavas
–
●
Todas as combinações
G = Sol
–
●
C = Dó
–
●
midi2freq
–
freq2midi
Define 69 como A4 (lá central), deslocamento em
semitons
Brasília – DF
8 horas de
treinamento
Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini
9. Exercícios #1 – #4
1
Sintetizar mais de uma senóide em
simultâneo
–
2
Dica: multiplicar cada senóide por um
número
4
stop
–
pause
Brasília – DF
8 horas de
treinamento
Sintetizar além das senóides
gauss_noise
–
●
saw_table
–
play
–
Algo muda?
–
Usar métodos do objeto AudioThread
ao invés do método limit “das
senóides” (objetos Stream)
–
Usar keyword arg “phase”, em
radianos
–
Soma de senóides ou diferentes
instâncias de AudioThread
–
Mudar a fase da senóide
–
Frequências iguais e diferentes
–
3
white_noise
[Extra #1] Tocar algo na escala
do Estudo II de Stockhausen
Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini
10. Parte 2
Stream!
Brasília – DF
8 horas de
treinamento
Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini
11. 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 (endless)
–
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
Laziness!
Brasília – DF
8 horas de
treinamento
Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini
12. Classe Stream
In [1]: from audiolazy import Stream
In [1]: from audiolazy import Stream
●
Iterável
In [2]: dados = Stream(5, 7, 1, 2, 5, 3, 2) # Periódico
In [2]: dados = Stream(5, 7, 1, 2, 5, 3, 2) # Periódico
●
Heterogêneo
In [3]: dados2 = Stream(0, 1) # Idem
In [3]: dados2 = Stream(0, 1) # Idem
●
Avaliação tardia
In [4]: (dados + dados2).take(15)
In [4]: (dados + dados2).take(15)
Out[4]: [5, 8, 1, 3, 5, 4, 2, 6, 7, 2, 2, 6, 3, 3, 5]
Out[4]: [5, 8, 1, 3, 5, 4, 2, 6, 7, 2, 2, 6, 3, 3, 5]
–
●
Lembra geradores
Operadores
–
Elementwise/broadcast como no NumPy
●
Já estávamos usando (sinusoid)!
●
Ausência de índices
–
Limite de representação inteira (32 bits estouraria em 27:03:12)
Brasília – DF
8 horas de
treinamento
Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini
13. 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]:
In [5]:
Out[5]:
Out[5]:
Stream([2, 3, 4]).take(5) # Lista de entrada
Stream([2, 3, 4]).take(5) # Lista de entrada
[2, 3, 4]
[2, 3, 4]
In [6]: Stream(2, 3, 4).take(5) # Números de entrada
In [6]: Stream(2, 3, 4).take(5) # Números de entrada
Out[6]: [2, 3, 4, 2, 3]
Out[6]: [2, 3, 4, 2, 3]
In [7]: Stream(*[2, 3, 4]).take(5) # Lista com "*"
In [7]: Stream(*[2, 3, 4]).take(5) # Lista com "*"
Out[7]: [2, 3, 4, 2, 3]
Out[7]: [2, 3, 4, 2, 3]
In [8]: (2 * Stream([1 + 2j, -3j, 7]).real).take(inf)
In [8]: (2 * Stream([1 + 2j, -3j, 7]).real).take(inf)
Out[8]: [2.0, 0.0, 14]
Out[8]: [2.0, 0.0, 14]
Brasília – DF
8 horas de
treinamento
Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini
14. Decorador tostream:
Geradores convertidos em Stream
●
Já foi aplicado a TODOS os itertools (e.g. count)!!!
In [1]: from audiolazy import tostream
In [1]: from audiolazy import tostream
In [2]: @tostream
In [2]: @tostream
...: def impulse():
...: def impulse():
...:
yield 1
...:
yield 1
...:
while True:
...:
while True:
...:
yield 0
...:
yield 0
...:
...:
In [3]:
In [3]:
Out[3]:
Out[3]:
impulse #
impulse #
<function
<function
De fato, uma função
De fato, uma função
__main__.impulse>
__main__.impulse>
Síntese
personalizada!
(Acesso direto
às amostras)
In [4]: impulse() # Devolve um objeto Stream
In [4]: impulse() # Devolve um objeto Stream
Out[4]: <audiolazy.lazy_stream.Stream at 0x30824d0>
Out[4]: <audiolazy.lazy_stream.Stream at 0x30824d0>
In [5]: impulse().take(5)
In [5]: impulse().take(5)
Out[5]: [1, 0, 0, 0, 0]
Out[5]: [1, 0, 0, 0, 0]
In [6]: (impulse() + 1).take(5) # Outro objeto instanciado
In [6]: (impulse() + 1).take(5) # Outro objeto instanciado
Out[6]: [2, 1, 1, 1, 1]
Out[6]: [2, 1, 1, 1, 1]
Brasília – DF
8 horas de
treinamento
Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini
15. Music III – Segregação de fluxos:
Controle e dados
●
Taxa de dados e taxa de controle
–
Processamento em blocos
●
●
–
●
Music 3 (origem), PureData, CSound, LADSPA
Contraste: funcionalidade “strongly timed”
–
●
Síncrono
Tamanho de bloco constante
ChunK
ControlStream (AudioLazy)
–
Property “value”
–
Permite interatividade
●
Tempo real
–
In [2]: data.take(5)
In [2]: data.take(5)
Out[2]: [42, 42, 42, 42, 42]
Out[2]: [42, 42, 42, 42, 42]
In [3]: data.value = -1
In [3]: data.value = -1
In [4]:
In [4]:
Out[4]:
Out[4]:
data.take(5)
data.take(5)
[-1, -1, -1, -1, -1]
[-1, -1, -1, -1, -1]
Por amostra
–
In [1]: data = ControlStream(42)
In [1]: data = ControlStream(42)
Alteração do valor não é síncrona
Brasília – DF
8 horas de
treinamento
Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini
16. Exercícios #5 – #6
5
Controlar a senóide (ou outra forma de onda) no shell em uma única thread
6
Utilizar o teclado do computador como interface com o usuário
–
●
Usar o “getch” do link http://code.activestate.com/recipes/134892/ (getch do C, readkey do
Pascal) ou alguma biblioteca (curses, Tkinter, ...)
[Extra] Associar o teclado QWERTY às alturas e simular a interface de um piano:
–
“asdfghjkl” para “C3 D3 E3 F3 G3 A3 B3 C4 D4” (teclas brancas)
–
“wetyuop” para “C#3 D#3 F#3 G#3 A#3 C#4 D#4” (teclas pretas)
Brasília – DF
8 horas de
treinamento
Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini
17. 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 [1]: data = Stream([1, 2, 3, 4, 5])
In [2]: blks = data.blocks(size=2, hop=1)
In [2]: blks = data.blocks(size=2, hop=1)
In [3]: [list(blk) for blk in blks]
In [3]: [list(blk) for blk in blks]
Out[3]: [[1, 2], [2, 3], [3, 4], [4, 5]]
Out[3]: [[1, 2], [2, 3], [3, 4], [4, 5]]
Brasília – DF
8 horas de
treinamento
Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini
18. Parte 3
Síntese aditiva
Brasília – DF
8 horas de
treinamento
Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini
19. Síntese digital
●
1951 – CSIRAC (Australia)
–
●
http://news.bbc.co.uk/2/hi/technology/7458479.stm
Década de 1960
–
Max Mattews (EUA)
●
–
●
MUSIC
“Compilar” música, lento
Década de 1970
–
Viabilidade de realizar síntese digital em tempo real
Brasília – DF
8 horas de
treinamento
Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini
20. Síntese aditiva
●
Série e Transformada de Fourier
–
●
●
Uma função contínua [por partes] pode ser
decomposta em uma soma de senóides
Custa caro (número de osciladores)
Som harmônico: relação inteira entre as
frequências componentes
Brasília – DF
8 horas de
treinamento
Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini
21. Envoltória/Envelope ADSR
●
Attack
–
●
Duração
Sustain
–
●
Duração
Decay
–
●
from audiolazy import adsr, inf
from audiolazy import adsr, inf
import pylab
import pylab
env = adsr(100, a=5, d=3, s=.8, r=10).take(inf)
env = adsr(100, a=5, d=3, s=.8, r=10).take(inf)
pylab.plot(env)
pylab.plot(env)
pylab.show()
pylab.show()
Intensidade
Release
–
Duração
Brasília – DF
8 horas de
treinamento
Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini
22. Polinômios
●
Necessário para os filtros lineares
●
Baseados em dicionário
In [8]:
In [8]:
Out[8]:
Out[8]:
(x + x ** 2 + x ** -.5)(4)
(x + x ** 2 + x ** -.5)(4)
20.5
20.5
–
–
Expoente negativo (Laurent)
–
●
Memória
Expoente fracionário (soma de potências)
Coeficientes podem ser objetos Stream, símbolos
do SymPy, etc.
In [9]: lagrange.poly([(1, 3), (3, 14), (45, 0)])
In [9]: lagrange.poly([(1, 3), (3, 14), (45, 0)])
Out[9]: -2.89773 + 6.0303 * x - 0.132576 * x^2
Out[9]: -2.89773 + 6.0303 * x - 0.132576 * x^2
●
Objeto “x”
●
Interpolação (polinômios de Lagrange)
Brasília – DF
8 horas de
treinamento
Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini
23. Exercícios #7 – #8
7
8
●
Sintetizar um som harmônico somando senóides.
A frequência fundamental precisa estar presente?
Utilizar a envoltória ADSR ao invés do método
Stream.limit
[Extra] Usar “ADS” separado do “R” em uma
interface com o usuário (e.g. eventos de mouse
up/down).
Brasília – DF
8 horas de
treinamento
Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini
24. Music IV – Table Lookup
●
Sons periódicos: armazenar um período do som
–
Instâncias de TableLookup
●
●
sin_table
saw_table
–
–
Método normalize
–
●
Método harmonize
Operadores
Consulta à tabela, com índices fracionários
Brasília – DF
8 horas de
treinamento
Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini
25. Exercício #9
●
Abrir o exemplo play_bach_choral.py e alterar o
sintetizador para que seja utilizada onda quadrada
–
Necessita do Music21
–
Substituir ks_synth(freq) por uma função que realize a
síntese proposta
–
Originalmente esse exemplo utilizou o modelo “digitar”
de Karplus-Strong, e trata-se de uma síntese
subtrativa.
Brasília – DF
8 horas de
treinamento
Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini
26. Parte 4
Síntese por modulação
Brasília – DF
8 horas de
treinamento
Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini
27. Década de 1980
●
Ampliação da área de síntese digital
●
Necessidade de reduzir os custos
–
–
●
Síntese por modulação (AM, FM, RM)
Síntese por filtragem (Subtrativa)
1985 – Surgimento da especificação MIDI
–
Professor Guido Stolfi (Poli-USP) havia construído um
sintetizador com um protocolo de comunicação antes
do MIDI existir
Brasília – DF
8 horas de
treinamento
Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini
28. Modulação em amplitude e em anel
●
Produto de sinais
●
Ring Modulation
–
–
●
Simetria entre ondas portadora e modulada
“Senóide multiplica senóide”
AM (Amplitude Modulation)
–
“Senóide * (1 + Senóide)”
–
Ring Modulation com “portadora” somada
●
●
●
Assimetria entre ondas
Faz diferença na percepção de frequência
Exercício #10 – AM e RM modulando ruído branco
Brasília – DF
8 horas de
treinamento
Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini
Imagem da
Wikipedia
29. Modulação em frequência
●
FM (Frequency Modulation)
–
Composição “Senóide(Senóide)”
●
–
A frequência é uma senóide
Equivalente à modulação em fase
●
Derivadas
●
Yamaha DX7
●
Sega Genesis / Mega Drive
Brasília – DF
8 horas de
treinamento
Imagem da
Wikipedia
Ex
em
mc
plo
fm
.py
Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini
30. Parte 5
Filtros e síntese subtrativa
Brasília – DF
8 horas de
treinamento
Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini
31. Filtros LTI
(Lineares e invariantes no tempo)
“Digital signal processing is mainly
based on linear time-invariant
systems.”
systems.”
(Dutilleux, Dempwolf, Holters e Zölzer
DAFx, segunda edição, capítulo 4, p. 103)
Brasília – DF
8 horas de
treinamento
Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini
32. Transformada Z
●
Definição:
●
Interpretação:
– Atraso em k amostras!
●
Muitos “infinitos”
–
Teoremas
●
Possibilitam o uso prático
(eliminam os “infinitos”)
Brasília – DF
8 horas de
treinamento
Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini
33. Exemplo de transformada Z
●
Acumulador
●
Média móvel
Saída / Entrada, ou
H(z) = Y(z) / X(z)
Brasília – DF
8 horas de
treinamento
Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini
34. Objeto “z”
In [1]: from audiolazy import z, Stream, maverage
In [1]: from audiolazy import z, Stream, maverage
In [2]: M = 5
In [2]: M = 5
In [3]: media_movel_5 = (1 - z ** -M) / (M * (1 - z ** -1))
In [3]: media_movel_5 = (1 - z ** -M) / (M * (1 - z ** -1))
In [4]: acumulador = 1 / (1 - z ** -1)
In [4]: acumulador = 1 / (1 - z ** -1)
In [5]:
In [5]:
Out[5]:
Out[5]:
media_movel_5(Stream(5)).take(10)
media_movel_5(Stream(5)).take(10)
[1.0, 2.0, 3.0, 4.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0]
[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)
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]
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)
In [7]: maverage.recursive(4)
Out[7]:
Out[7]:
0.25 - 0.25 * z^-4
0.25 - 0.25 * z^-4
----------------------------------1 - z^-1
1 - z^-1
Filtros LTI, em geral:
Brasília – DF
8 horas de
treinamento
Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini
35. Filtros prontos!
Filtr
Coe os va
ficie
rian
pod ntes “a tes no
em
se r ” e m d e t e m p o !
o b je
tos S a * z **
-k
trea
m)
●
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)
Brasília – DF
8 horas de
treinamento
Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini
36. Plot (AudioLazy + MatPlotLib)!
●
DTFT - Caso particular da transformada Z
–
●
Método plot dos filtros
–
●
O valor de z está na circunferência complexa unitária
Resposta em frequência
Método zplot
–
Estabilidade do filtro
–
X
Pólos: “X”
●
–
Raízes do denominador
Zeros: “O”
●
X
Raízes do numerador
Brasília – DF
8 horas de
treinamento
Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini
MatPlotLib
faz melhor
que isto...
37. 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
Brasília – DF
8 horas de
treinamento
Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini
38. Exercícios
11
12
Implementar a sequência de Fibonacci como
resposta ao impulso de um filtro digital
Utilizando filtros ressonadores, criar um sintetizador
de “vozes subliminares” com vogais.
–
Utilizar a tabela do Wikipedia em inglês (artigo sobre
“formants”)
–
Valores recomendados para largura de banda:
●
●
400Hz (menor formante)
2kHz (maior formante)
Brasília – DF
8 horas de
treinamento
Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini
39. Parte 6
Análise
Brasília – DF
8 horas de
treinamento
Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini
40. Quantização em ponto flutuante
freq = 100 * Hz
freq = 100 * Hz
bw = erb(freq, Hz) * gammatone_erb_constants(4)[0]
bw = erb(freq, Hz) * gammatone_erb_constants(4)[0]
filt = gammatone.slaney(freq, bw)
filt = gammatone.slaney(freq, bw)
filt.plot(rate=rate, freq_scale="log", samples=8192).show()
filt.plot(rate=rate, freq_scale="log", samples=8192).show()
Sem CascadeFilter
Brasília – DF
8 horas de
treinamento
Com CascadeFilter
Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini
41. 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 →
Brasília – DF
8 horas de
treinamento
Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini
42. Série harmônica
●
F0, 2F0, 3F0, 4F0 …
–
100 Hz, 200 Hz, 300 Hz...
Inteiros?
Racionais?
Primos?
2+
oitava
Comb!
freqs = [str2freq(note) for note in "E2 G#2 B2".split()] # Mi maior
freqs = [str2freq(note) for note in "E2 G#2 B2".split()] # Mi maior
filt = ParallelFilter(comb.tau(freq_to_lag(freq * Hz), .1 * s)
filt = ParallelFilter(comb.tau(freq_to_lag(freq * Hz), .1 * s)
Brasília – DF
for freq in freqs)
for freq in freqs)
Síntese em tempo real com a AudioLazy
8 horas de
filt.plot(samples=8192, rate=rate, min_freq=220*Hz, max_freq=880*Hz).show()
filt.plot(samples=8192, rate=rate, min_freq=220*Hz, max_freq=880*Hz).show()
treinamento
2013-09-30 – Danilo J. S. Bellini – @danilobellini
43. Envoltória espectral
LPC - Predição Linear
Formantes
Pode ser
utilizado para
classificação
de vogais
from audiolazy import *
from audiolazy import *
rate = 22050
rate = 22050
s, Hz = sHz(rate)
s, Hz = sHz(rate)
size = 512
size = 512
table = sin_table.harmonize({1: 1, 2: 5, 3: 3, 4: 2, 6: 9, 8: 1}).normalize()
table = sin_table.harmonize({1: 1, 2: 5, 3: 3, 4: 2, 6: 9, 8: 1}).normalize()
data = table(str2freq("Bb3")
data = table(str2freq("Bb3")
filt = lpc(data, order=14) #
filt = lpc(data, order=14) #
G = 1e-2 # Ganho apenas para
G = 1e-2 # Ganho apenas para
* Hz).take(size) # Nota si bemol da 3a oitava
* Hz).take(size) # Nota si bemol da 3a oitava
Filtro de análise
Filtro de análise
alinhamento na visualização com a DFT
alinhamento na visualização com a DFT
Brasília – DF
# Filtro de síntese
# Filtro de síntese
Síntese em tempo real com a AudioLazy
8 horas de
(G / filt).plot(blk=data, rate=rate, samples=1024, unwrap=False).show()
(G / filt).plot(blk=data, rate=rate, samples=1024, unwrap=False).show()
treinamento
2013-09-30 – Danilo J. S. Bellini – @danilobellini
44. Parte 7
Finalização
Brasília – DF
8 horas de
treinamento
Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini
45. AudioLazy
●
DSP (Digital Signal Processing) para áudio
–
Análise
●
MIR (Music Information Retrieval)
–
–
●
Síntese
Processamento
Expressividade de código
–
●
Tempo real (latência de 35ms é possível)
–
●
Facilita prototipação, simulação
Possibilita uso em aplicações finais
100% Python
–
Multiplataforma
Brasília – DF
8 horas de
treinamento
Suporta Python 2 e 3 com o
mesmo
Síntese em tempo real com a AudioLazycódigo!
2013-09-30 – Danilo J. S. Bellini – @danilobellini
47. 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
import pytest
p = pytest.mark.parametrize
p = pytest.mark.parametrize
from scipy.signal import lfilter
from scipy.signal import lfilter
from audiolazy import ZFilter, almost_eq
from audiolazy import ZFilter, almost_eq
class TestZFilterScipy(object):
class TestZFilterScipy(object):
@p("a", [[1.], [3.], [1., 3.], [15., -17.2], [-18., 9.8, 0., 14.3]])
@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("b", [[1.], [-1.], [1., 0., -1.], [1., 3.]])
@p("data", [range(5), range(5, 0, -1), [7, 22, -5], [8., 3., 15.]])
@p("data", [range(5), range(5, 0, -1), [7, 22, -5], [8., 3., 15.]])
def test_lfilter(self, a, b, data):
def test_lfilter(self, a, b, data):
filt = ZFilter(b, a) # Cria um filtro com a AudioLazy
filt = ZFilter(b, a) # Cria um filtro com a AudioLazy
Brasília – DF
expected = de
expected = lfilter(b, a, data).tolist()comAplica o filtro com o SciPy
Síntese em tempo real # a AudioLazy
8 horas lfilter(b, a, data).tolist() # Aplica o filtro com o SciPy
assert almost_eq(filt(data), expected)Bellini – @danilobellini
assert almost_eq(filt(data), expected) # Compara os resultados
2013-09-30 – Danilo J. S. # Compara os resultados
treinamento
48. Situação atual da AudioLazy
●
Versão 0.05, última “zero-zero”
–
Próxima versão (0.1) deve incluir
●
●
●
●
●
Python 2 e 3!
–
●
●
Filtros com expoentes inteiros variantes no tempo
Sync para I/O (evita caching no Linux)
Personalização do AudioIO (dispositivo não padrão)
Otimização para filtros comb
Embora o MatPlotLib e o py.test sejam mais lento no Python 3, não é o caso com a
AudioLazy
664 downloads realizados no último mês (PyPI, valor coletado dia 2013-0930)
Sintetizador, pedaleira e jogos em desenvolvimento utilizando ou planejando
utilizar a AudioLazy
Brasília – DF
8 horas de
treinamento
Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini
49. Possíveis continuações para o
desenvolvimento da AudioLazy
●
Análise
●
Testes
–
–
Chegar aos 100%
–
●
Heurísticas, MIR features
Plugins (Vamp)
–
Mock MatPlotLib
●
Modelagem audição
–
Filtros
–
Outros modelos (Lyon, Seneff, gamma chirp, etc.)
Atrasos/expoentes variantes no tempo
●
–
●
Conversão entre x-dB e ERB
Síntese e processamento
–
–
Escrita no tempo
–
SymPy
–
Host de plugins LADSPA
Frações parciais
–
Wah, phaser, eco, compressor, noise gate, …
–
Implementações alternativas
Integrar com PureData, CSound, etc.
I/O
Flanger
Karplus-Strong variante no tempo
–
Exemplos de uso da AudioLazy
●
●
●
●
●
●
Treliça
Forma direta II
Outros
–
MIDI
–
Logo
–
Evitar caching
–
Melhorar a documentação (Sphinx)
–
Integrar com PyGame
–
Otimização
Brasília – DF
8 horas de
treinamento
Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini
50. Obrigado!
O treinamento acabou, mas ainda há conteúdo
a ser visto.
Dúvidas?
Depoimentos?
Comentários?
Fork me on GitHub
https://github.com/danilobellini/audiolazy
Brasília – DF
8 horas de
treinamento
Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini