SlideShare uma empresa Scribd logo
1 de 50
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
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
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
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
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
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
“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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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...
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
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
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
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
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
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
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
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
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
Resultados cobertura de código
(Testes automatizados)
--------------- coverage: platform linux2, python 2.7.3-final-0 ------------------------------ coverage: platform linux2, python 2.7.3-final-0 ---------------Name
Stmts
Miss Branch BrPart Cover
Missing
Name
Stmts
Miss Branch BrPart Cover
Missing
----------------------------------------------------------------------------------------------------------------------__init__
44
1
18
4
92%
72
Mock
__init__
44
1
18
4
92%
72
lazy_analysis
125
3
60
2
97%
211, 259-260
lazy_analysis
125
3
60
2
97%
211, 259-260
lazy_auditory
60
0
14
0
100%
lazy_auditory
60
0
14
0
100%
lazy_compat
42
5
6
1
88%
43, 67-68, 78-79
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_core
174
7
78
9
94%
124, 136-138, 346, 471, 478
lazy_filters
509
179
245
117
61%
55, 62, 83, 93, [...]
lazy_filters
509
179
245
117
61%
55, 62, 83, 93, [...]
lazy_io
156
43
58
28
67%
89, 141-157, 161, [...]
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_itertools
37
12
20
13
56%
38, 59-60, 69-74, 100-103
lazy_lpc
128
15
42
7
87%
121, 135-136, [...]
lazy_lpc
128
15
42
7
87%
121, 135-136, [...]
lazy_math
61
1
28
0
99%
133
lazy_math
61
1
28
0
99%
133
lazy_midi
54
5
26
3
90%
70, 111, 150, 156, 158
lazy_midi
54
5
26
3
90%
70, 111, 150, 156, 158
lazy_misc
110
9
62
10
89%
156-157, 194, [...]
lazy_misc
110
9
62
10
89%
156-157, 194, [...]
lazy_poly
184
2
124
3
98%
387-388
lazy_poly
184
2
124
3
98%
387-388
lazy_stream
175
2
76
4
98%
59, 738
lazy_stream
175
2
76
4
98%
59, 738
lazy_synth
243
32
118
39
80%
277-299, 428, 430, [...]
lazy_synth
243
32
118
39
80%
277-299, 428, 430, [...]
lazy_text
104
16
70
18
80%
133-148, 207, [...]
lazy_text
104
16
70
18
80%
133-148, 207, [...]
----------------------------------------------------------------------------------------------------------------------TOTAL
2206
332
1045
258
82%
TOTAL
2206
332
1045
258
82%
========================= 5938 passed in 29.00 seconds =========================
========================= 5938 passed in 29.00 seconds =========================
Brasília – DF
8 horas de
treinamento

Síntese em tempo real com a AudioLazy
2013-09-30 – Danilo J. S. Bellini – @danilobellini
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
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
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
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

Mais conteúdo relacionado

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
 
(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-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
 
(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
 
(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
 

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)
 
(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-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...
 
(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
 
(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
 

(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
  • 46. Resultados cobertura de código (Testes automatizados) --------------- coverage: platform linux2, python 2.7.3-final-0 ------------------------------ coverage: platform linux2, python 2.7.3-final-0 ---------------Name Stmts Miss Branch BrPart Cover Missing Name Stmts Miss Branch BrPart Cover Missing ----------------------------------------------------------------------------------------------------------------------__init__ 44 1 18 4 92% 72 Mock __init__ 44 1 18 4 92% 72 lazy_analysis 125 3 60 2 97% 211, 259-260 lazy_analysis 125 3 60 2 97% 211, 259-260 lazy_auditory 60 0 14 0 100% lazy_auditory 60 0 14 0 100% lazy_compat 42 5 6 1 88% 43, 67-68, 78-79 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_core 174 7 78 9 94% 124, 136-138, 346, 471, 478 lazy_filters 509 179 245 117 61% 55, 62, 83, 93, [...] lazy_filters 509 179 245 117 61% 55, 62, 83, 93, [...] lazy_io 156 43 58 28 67% 89, 141-157, 161, [...] 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_itertools 37 12 20 13 56% 38, 59-60, 69-74, 100-103 lazy_lpc 128 15 42 7 87% 121, 135-136, [...] lazy_lpc 128 15 42 7 87% 121, 135-136, [...] lazy_math 61 1 28 0 99% 133 lazy_math 61 1 28 0 99% 133 lazy_midi 54 5 26 3 90% 70, 111, 150, 156, 158 lazy_midi 54 5 26 3 90% 70, 111, 150, 156, 158 lazy_misc 110 9 62 10 89% 156-157, 194, [...] lazy_misc 110 9 62 10 89% 156-157, 194, [...] lazy_poly 184 2 124 3 98% 387-388 lazy_poly 184 2 124 3 98% 387-388 lazy_stream 175 2 76 4 98% 59, 738 lazy_stream 175 2 76 4 98% 59, 738 lazy_synth 243 32 118 39 80% 277-299, 428, 430, [...] lazy_synth 243 32 118 39 80% 277-299, 428, 430, [...] lazy_text 104 16 70 18 80% 133-148, 207, [...] lazy_text 104 16 70 18 80% 133-148, 207, [...] ----------------------------------------------------------------------------------------------------------------------TOTAL 2206 332 1045 258 82% TOTAL 2206 332 1045 258 82% ========================= 5938 passed in 29.00 seconds ========================= ========================= 5938 passed in 29.00 seconds ========================= Brasília – DF 8 horas de treinamento Síntese em tempo real com a AudioLazy 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