• Nenhum resultado encontrado

4.2 Detalhamento da arquitetura de software

4.2.2 Instrumentos

Disponibilizamos na m´aquina deste TCC 8 instrumentos: um Kick (bumbo), dois Hats (pratos), sendo um para o Hat aberto, (i.e. com o pedal dos pratos pressionado) e outro para o Hat fechado(i.e. com o pedal pressionado), um Snare (caixa), uma Clap (palmas) e 3 FM (sintetizador que usa n˜ao o modelo subtrativo mas o modelo de modula¸c˜ao de frequˆencia, discutidos com mais detalhes nas pr´oximas subse¸c˜oes). Tal escolha foi baseada tanto nos instrumentos presentes nas m´aquinas comerciais quanto na experiˆencia pessoal do aluno.

Nas subse¸c˜oes seguintes descrevemos como cada um dos instrumentos se relaciona com os parˆametros control´aveis pela interface. Para todos os instrumentos, disponibilizamos um parˆametro sample ou s´ıntese, que indica se a m´aquina deve usar o modelo de gera¸c˜ao de som (s´ıntese) ou reproduzir um arquivo de ´audio pr´e-gravado (sample).

Kick

• O tempo de decaimento exponencial do envelope.

• O tom (frequˆencia) da senoide sendo modulada pelo envelope.

• Cutoff LPF: um filtro LPF ´e aplicado antes da sa´ıda do bloco, o que permite controlar sua frequˆencia de corte.

• Ataque: tempo que o envelope demora para ir de 0 a 1 (frequˆencia m´ınima a frequˆencia m´axima).

• SNR: o Kick ´e uma mistura de um seno modulado e ruido branco, e este parˆametro controla a propor¸c˜ao entre ambos na composi¸c˜ao da onda gerada.

• Concavidade do envelope: o envelope exponencial ´e dado por trˆes pontos: (0, 1), (T/2, midPoint) e (T, 0.001). Este parˆametro ´e o midPoint.

Hats

• Tom: 6 ondas quadradas s˜ao somadas para gerar o conte´udo harmˆonico. As pro- por¸c˜oes de frequˆencias s˜ao fixas mas a frequˆencia da mais grave ´e determinada por esse parˆametro.

• Dura¸c˜ao: o tempo de decaimento exponencial do envelope.

• Hpf: Um filtro HPF ´e aplicado antes da sa´ıda deste instrumento. Este parˆametro controla a frequˆencia de corte do filtro.

• Bpf: Um filtro BPF, onde sua frequˆencia de corte ´e controlada pelo usu´ario ´e apli- cado antes do HPF, tambem com frequˆencia de corte controlada pelo usu´ario.

• SNR: Propor¸c˜ao de sinal ru´ıdo (idem ao Kick).

• Ataque: Tempo que o envelope demora para ir de 0 a 1 (idem ao Kick). Snare

• Tom: o snare ´e uma senoide modulada, este parˆametro corresponde a a frequˆencia da senoide.

• Dura¸c˜ao: tempo de decaimento exponencial do envelope. • Ataque (idem ao Kick).

Claps

• Tom: a Clap ´e formada por 3 Snares seguidos, com um atraso em cada um. Este parˆametro indica a fequencia base do Snare.

• Dura¸c˜ao • Ataque

• Intervalo: o intervalo entre os 3 snares FM

Os parˆametros do FM ser˜ao discutidos em uma se¸c˜ao separada no apˆendice, pois a complexidade da gera¸c˜ao da onda FM n˜ao ser´a coberta deste TCC.

4.2.3

Mixer e efeitos

O mixer simplesmente soma os sinais vindos dos 8 instrumentos digitalmente, sem limitar o sinal, podendo causar distor¸c˜ao do sinal caso a soma seja maior do que 1.

Os efeitos disponibilizados s˜ao somente uma distor¸c˜ao do tipo waveshaper e um filtro HPF.

4.2.4

Sa´ıda

O m´odulo de sa´ıda separa o sinal proveniente do m´odulo de efeitos entre as portas de sa´ıda digitais: ´audio anal´ogico e ´audio por USB. N˜ao h´a transforma¸c˜ao alguma no sinal prevista para este m´odulo, mas ele ´e considerado importante pois realiza a comunica¸c˜ao apropriada usando as bibliotecas de suporte da placa.

4.2.5

M´odulos de Software

4.2.5.1 HAL

A Harware Abstraction Layer (HAL) foi implementada atrav´es de um m´odulo que encapsula todas as fun¸c˜oes de acesso ao harware f´ısico. Nele s˜ao configuradas cada uma das portas digitais ou anal´ogicas do microcontrolador, s˜ao definidos os m´etodos e parˆametros de comunica¸c˜ao serial, os m´etodos de comunica¸c˜ao MIDI e as macros para se referir a cada uma das portas no restante do c´odigo. Esta modulariza¸c˜ao foi pensada para que, se o hardware for substitu´ıdo no futuro ou outras formas de comunica¸c˜ao forem adicionadas, basta substituir este m´odulo por um compat´ıvel com o novo hardware.

4.2.5.2 Encoder

O encoder ´e um dos dispositivos de hardware usado como interface com o usu´ario. Este m´odulo foi implementado atrav´es de uma classe que abstrai a intera¸c˜ao com os

encoders f´ısicos em funcionalidades que ser˜ao utilizadas no restante do projeto. Cada encoder [26] f´ısico possui 3 pinos: A, B e C. os pinos A e B disparam pulsos quadrados quando o encoder ´e girado pelo usu´ario, e a diferen¸ca de fase dos pulsos indica qual a dire¸c˜ao de rota¸c˜ao do encoder. A classe desenvolvida abstrai esta caracter´ıstica atrav´es de m´etodos que s˜ao chamados quando o encoder gira no sentido hor´ario ou anti-hor´ario. O pino C ´e um interruptor bin´ario de contato, ativo alto quando o encoder est´a pressionado.

Para muitas aplica¸c˜oes, ´e interessante manter um registro na forma de um inteiro com sinal, que conta quantos passos de rota¸c˜ao o encoder realizou. Essa informa¸c˜ao tamb´em ´e guardada na classe Encoder desenvolvida, mas na forma de uma vari´avel de objeto (na instˆancia). Para outras aplica¸c˜oes espec´ıficas, ´e desej´avel que o encoder controle um parˆametro externo, implementado por uma classe pr´opria. A classe Encoder foi preparada para controlar o parˆametro externo atrav´es da ValueInterface, implementada pela classe externa (do parˆametro). A classe do encoder recebe um ponteiro para um parˆametro (objeto) e invoca os m´etodos decrement e increment dessa interface quando o encoder decrementa ou incrementa seu valor, respectivamente. H´a um m´etodo para configurar o ponteiro para o objeto do parˆametro controlado, que pode ser nulo se a funcionalidade n˜ao for necess´aria para o encoder representado pela instˆancia.

4.2.5.3 Unidade de controle

A unidade de controle est´a descrita no arquivo beta.ino, o arquivo principal do projeto. Nesse arquivo, todos os outros m´odulos s˜ao importados e configurados, criando instancias de todas as classes necess´arias para o projeto e passando-as como referencia para criar as interconex˜oes. As callbacks de fun¸c˜oes dos outros m´odulos tamb´em s˜ao configuradas neste m´odulo.

Um atraso ´e aplicado no fim da fase de configura¸c˜ao para garantir que todos os blocos ass´ıncronos foram iniciados. J´a o la¸co principal executa sempre na velocidade m´axima poss´ıvel. ´E importante que esse la¸co seja eficiente computacionalmente e o mais curto poss´ıvel, j´a que a atualiza¸c˜ao das interfaces e a reflex˜ao de mudan¸cas tanto no display como na infraestrutura de ´audio s˜ao afetadas pela latˆencia de execu¸c˜ao deste la¸co, afetando assim a usabilidade do produto.

A fase de setup ent˜ao ´e composta por: iniciar a comunica¸c˜ao serial, iniciar a infraes- trutura de ´audio e configurar seus callbacks, instanciar os instrumentos, normalizar seus respectivos volumes, configurar o roteamento de ´audio, configurar a HAL e os encoders, iniciar o display (assincronamente), iniciar a comunica¸c˜ao I2C com a interface A do AT-

Figura 18: Unidade de controle

Mega328p e finalmente configurar os callbacks para as mensagens MIDI.

O la¸co principal, por sua vez, ´e composto por: transferir arquivos pendentes pela interface serial com o computador, propagar as mensagens MIDI recebidas da interface A na ultima itera¸c˜ao do la¸co para a serial e para os respectivos instrumentos, ler as novas mensagens MIDI provenientes da interface A, ler o estado de todos os encoders e atualizar os menus do display.

4.2.5.4 Infraestrutura de ´Audio

A infraestrutura de ´audio encapsula a comunica¸c˜ao com o DAC, a administra¸c˜ao da mem´oria de ´audio, as conex˜oes de ´audio internas, os efeitos comuns a todos os instru- mentos e administra a comunica¸c˜ao com o cart˜ao SD para armazenamento de arquivos de ´audio em formato RAW.

4.2.5.5 Instrument Interface

Para que possamos tratar todos os instrumentos em um ´unico la¸co na unidade de con- trole, todos devem possuir uma interface comum, que chamamos deInstrument Interface. Essa interface conta com um m´etodo para trocar mensagens MIDI com o instrumento

(noteOn), outro para configurar os parˆametros internos do instrumento (mantidos em uma lista dentro do objeto) e dois m´etodos, getNextValue e getCurrentValue, que re- tornam o pr´oximo e o atual parˆametro da lista interna do instrumento, respectivamente. A interface tamb´em exp˜oe um parˆametro chamado de Amplificador, que representa a sa´ıda de ´audio do instrumento, permitindo que ele possa ser roteado para um somador de sinais.

4.2.5.6 Value Interface

A Value Interface ´e a representa¸c˜ao de um parˆametro de ´audio. Os parˆametros s˜ao n´umeros reais (ponto flutuante), com um m´ınimo e um m´aximo. Como os parˆametros s˜ao controlados por encoders discretos, a varia¸c˜ao entre o m´ınimo e o m´aximo do parˆametro tamb´em deve ser discreta, portanto na sua inicializa¸c˜ao determinamos quantos passos levam o valor do seu m´ınimo para o seu m´aximo. Muitos parˆametros de ´audio, como frequˆencia, volume e tempos de decaimento dos envelopes, devem ser exponenciais, assim a interface permite que o parˆametro seja controlado exponencialmente. Finalmente, s˜ao expostos dois m´etodos al´em do construtor, o increment e o decrement, que respectiva- mente incrementam ou decrementam o valor exponencialmente ou linearmente. Tamb´em ´e necess´ario que a interface guarde uma string com o nome do parˆametro para que ele seja mostrado no display.

4.2.5.7 Display

O display talvez seja um dos m´odulos mais complexos do projeto, uma vez que ele controla um display [27] f´ısico de 128 por 64 pixels, o que representa uma quantidade de informa¸c˜ao gr´afica consider´avel para um microcontrolador. Tanto sua escrita como o armazenamento dessas informa¸c˜oes s˜ao problemas que foram resolvidos na implementa¸c˜ao dessa classe. Na primeira vers˜ao, o microcontrolador escrevia a tela inteira sempre que houvesse alguma mudan¸ca no conte´udo (enviado atrav´es da interface serial I2C), por´em isso levava em torno de 14ms, o que introduzia uma latˆencia inaceit´avel na leitura da interface, fazendo ela se tornar irresponsiva a altera¸c˜oes pequenas nos encoders. Assim a implementa¸c˜ao final que mostramos neste trabalho tem funcionamento ass´ıncrono para n˜ao bloquear a CPU quando houver escrita no display.

Para que a implementa¸c˜ao ass´ıncrona fosse poss´ıvel, a comunica¸c˜ao com display por I2C foi alterada para ser baseada em DMA, onde os dados s˜ao transmitidos por I2C diretamente da mem´oria, sem travar a CPU, e oposi¸c˜ao `a transmiss˜ao direta. Na co-

munica¸c˜ao DMA, o processador escreve os dados a serem transmitidos em uma por¸c˜ao especifica da mem´oria e dispara o inicio da transmiss˜ao. Um m´odulo separado lˆe cada peda¸co da informa¸c˜ao armazenada pela CPU na mem´oria e o transmite pelo canal I2C especificado. Durante a transmiss˜ao dos dados pelo m´odulo DMA, a CPU est´a livre para executar qualquer outra a¸c˜ao que seja necess´aria, inclusive reescrever no display. Quando a transmiss˜ao finaliza, o m´odulo de DMA emite uma interrup¸c˜ao, que ´e utilizada para trocar do estrado ”Inicia transmiss˜ao”para ”Transmiss˜ao terminada”no diagrama acima.

A escrita no display se inicia com a chamada do m´etodo putScreen, que aceita duas strings ou uma string e um float como parˆametros. Esses m´etodos colocam as strings em um buffer e invoca o m´etodo triggerTransmission. Esse m´etodo verifica se h´a algo no buffer a ser transmitido e, caso positivo, invoca o m´etodo transmitScreen, que ´e responsavel por calcular cada pixel da tela usando como base uma matriz constante contendo a representa¸c˜ao em pixeis de todas as letras mai´usculas, n´umeros e ponto. Esta matriz foi criada e guardada na mem´oria de programa, desta maneira o m´etodo calcula a partir da string o espa¸co que cada caractere deve ocupar na tela, preenchendo os espa¸cos em branco at´e o fim da linha e intercalando cada linha escrita com duas linhas em branco. Finalmente o m´etodo inicia a tranmiss˜ao com os pixeis calculados.

No m´etodo Init foi definido uma fun¸c˜ao de callback para a interrup¸c˜ao de comu- nica¸c˜ao terminada apontando para a pr´opria fun¸c˜ao triggerTransmission. Desta ma- neira, se algo foi colocado no buffer enquanto o display estava transmitindo algo, esse dado ser´a transmitido imediatamente. Foram implementadas tamb´em regras para os ca- sos em que a comunica¸c˜ao falha ou o barramento serial trava (as regras envolvem abortar a tranmiss˜ao, reiniciar os controladores envolvidos e retomar o ciclo do in´ıcio).

4.2.5.8 Menu

O menu ´e uma representado por uma classe que cont´em uma lista de telas, cada uma com sua funcionalidade. A tela ´e uma classe em si que tem uma fun¸c˜ao de callback que atende o evento de clique, uma fun¸c˜ao que renderiza a tela no display e strings e parˆametros adicionais.

As telas foram pensadas para serem intuitivas para o usu´ario. Disponibilizamos as seguintes telas no projeto do TCC: Distor¸c˜ao, que controla o efeito de distor¸c˜ao aplicado no sinal de sa´ıda; Filtro que controla a frequˆencia de corte, ressonˆancia e tipo (LFP, HPF ou BPF) de um filtro aplicado tamb´em ao sinal de sa´ıda; clock, que escolhe se o usu´ario quer usar o clock proveniente da entrada serial MIDI ou gerar um clock interno (neste caso

´e poss´ıvel controlar a sua frequˆencia); e Sess˜ao, que salva ou recupera todos os parˆametros da m´aquina usando a EEPROM do microcontrolador como armazenamento permanente.

4.2.5.9 Serial Transfer

Al´em da possibilidade de usar os modelos de s´ıntese, o usu´ario pode, tamb´em, re- produzir um arquivo de ´audio representando cada instrumento. Esses arquivos devem ficar guardados na mem´oria flash serial interna, que n˜ao ´e acess´ıvel para o usu´ario. A solu¸c˜ao proposta e implementada foi transferir arquivos pela comunica¸c˜ao serial com o computador para a mem´oria interna. Uma aplica¸c˜ao de CLI (i.e. aplica¸c˜ao que n˜ao tem interface gr´afica, apenas interface textual para desenvolvedor) simples foi desenvolvida para ler um arquivo, converte-lo para um fluxo de bytes em um formato RAW e iniciar a comunica¸c˜ao com a placa. J´a na placa, a cada itera¸c˜ao do la¸co verifica-se se a CLI est´a tentando iniciar uma comunica¸c˜ao e, caso seja detectada, o m´odulo SerialTransfer ´e acionado para administrar a comunica¸c˜ao e salvar o arquivo recebido na mem´oria serial. Este m´odulo tamb´em retorna o resultado para o usu´ario por meio do display. No in´ıcio da transmiss˜ao a aplica¸c˜ao envia o tamanho do nome do arquivo, seguido do o nome do arquivo, o tamanho dos dados que ser˜ao transmitidos e finalmente os dados em si. Para cada bloco transmitido pela CLI, o m´odulo valida o pacote e devolve um sinal de reconhe- cimento da transferˆencia (ACK simples). Quando forem recebidos tantos pacotes como a aplica¸c˜ao especificou no preˆambulo da transmiss˜ao, a comunica¸c˜ao ´e fechada e o controle ´e devolvido para o la¸co principal do firmware da m´aquina.

4.2.6

EEPROM

Quando o sistema perde a energia todos os parˆametros s˜ao perdidos e ele volta a seu estado inicial. Isso pode frustar os usu´arios, ent˜ao implementamos um m´odulo de software para armazenar todos os parˆametros na EEPROM local e outro para recuperar todos os parˆametros da EEPROM. Todo o estado pode ser representado em apenas 176 bytes (42 floats dos instrumentos e um byte por instrumento para indiciar quantos parˆametros devem ser recuperados).

No documento GABRIEL YSHAY DRUM MACHINE DIGITAL (páginas 33-41)

Documentos relacionados