O objetivo desta atividade é exercitar o uso de operações com bits, controle de fluxo, e acesso a vetores utilizando o conjunto de instruções da arquitetura RISC-V.
MIDI (Interface Digital de Instrumentos Musicais, do inglês Musical Instrument Digital Interface) é um padrão de armazenamento e comunicação entre instrumentos musicais, computadores e ferramentas de áudio. Sua estrutura consiste em representar notas musicais através de uma sequência de comandos simples e de fácil reprodução. Um arquivo MIDI possui até 16 canais. A cada canal, um instrumento musical pode ser associado. A melodia é, então, representada como uma lista de notas musicais para cada canal. Cada nota possui ainda sua velocidade, frequência e tempo.
Neste laboratório, você deve implementar um tocador de músicas no formato MIDI utilizando a linguagem de montagem do RISC-V. O programa é dividido em duas partes: Parser e Player. O pseudo-código delas pode ser visto no documento mc404_lab07.pdf. Para facilitar o problema, nós fornecemos o arquivo base lab7.s, que já declara as estruturas de dados e implementa a parte Player. Assim, somente a parte Parser precisa ser implementada e será considerada na avaliação do laboratório.
Nesta primeira parte, você deverá ler e interpretar os dados da música. Você receberá a entrada no formato Midigram, uma representação simplificada (e mais compreensível) do formato MIDI. Sua estrutura é ilustrada abaixo.
Header 1 15 Program 8 71 8040 8148 4 8 58 76 8160 8376 4 8 58 76 8400 8616 4 8 59 76 8640 8964 4 8 58 76 12000 12216 4 8 58 76 12240 12456 4 8 59 76 12480 12804 4 8 58 76 15720 15828 4 8 58 76 ... 82440 82488 15 10 20 20 82440 82488 15 10 33 13 82500 82548 15 10 20 18 82500 82548 15 10 33 12 88320
Seu código deverá ler uma linha por vez e identificar seu tipo. No nosso exemplo:
| Arquivo | BPM | Ticks |
|---|---|---|
| 1 | 105 | 240 |
| 2 | 124 | 384 |
| 3 | 78 | 192 |
| 4 | 67 | 480 |
| 5 | 170 | 96 |
| 6 | 114 | 384 |
| 7 | 100 | 96 |
| 8 | 67 | 384 |
A entrada será o valor dos parâmetros BPM e ticks (na mesma linha separados por um espaço), seguido pelos dados do arquivo Midigram. Para testar seu código, disponibilizamos 8 arquivos Midigram (music.zip), mas você pode gerar novos a partir de músicas no formato MIDI (veja como na última seção deste documento).
Exemplo:
105 240 Header 1 15 Program 8 71 8040 8148 4 8 58 76 8160 8376 4 8 58 76 8400 8616 4 8 59 76 8640 8964 4 8 58 76 12000 12216 4 8 58 76 12240 12456 4 8 59 76 12480 12804 4 8 58 76 15720 15828 4 8 58 76 ... 82440 82488 15 10 20 20 82440 82488 15 10 33 13 82500 82548 15 10 20 18 82500 82548 15 10 33 12 88320
Seu código do "parser" deve ser implementado no arquivo lab7.s. Além disso:
Execute a compilação e ligação de seu código como de costume. Agora, basta executar o programa lab7 no simulador para testá-lo. Veja a seção Entrada (acima) para entender o formato de entrada.
Embora a implementação dessa etapa já esteja feita no arquivo de template, a leitura dessa seção é importante para o entendimento da infraestrutura a ser utilizada. Além disso, a compreensão do algoritmo pode vir a ser necessária para o trabalho final da disciplina. Uma vez preenchidos a matriz M e o vetor C, você pode reproduzir a música seguindo o Algoritmo 2 do PDF. Para isso, o código implementa a função "play" dentro do arquivo lab7.s da seguinte forma:
O tempo pode ser obtido através da chamada de sistema gettimeofday. No exemplo a seguir, o tempo em milissegundos é carregado em a0.
la a0, buffer_timeval la a1, buffer_timerzone li a7, 169 # chamada de sistema gettimeofday ecall la a0, buffer_timeval lw t1, 0(a0) # tempo em segundos lw t2, 8(a0) # fração do tempo em microssegundos li t3, 1000 mul t1, t1, t3 div t2, t2, t3 add a0, t2, t1
Um sintetizador de áudio é um componente capaz de imitar o som de instrumentos musicais convencionais. Em nosso simulador RISC-V, nós simulamos o uso de um sintetizador implementado em um circuito integrado e conectado ao microcontrolador pelo barramento. Para simplificar seu uso no laboratório, a syscall SynthPlay foi implementada para tratar da comunicação com o CI. Para conectar o sintetizador ao simulador, é necessário ir à aba "External Devices", seção "Sound Synthesizer", e clicar em "Load Device".
Exemplo de uso da syscall:
li a0, 25 # instrumento (25: guitarra acústica de nylon) li a1, 0x1800 # tempo para tocar a nota (d = 0x1800) ori a1, 0x100000 # velocidade da nota (v = 0x10) ori a1, 0x52000000 # frequencia da nota (f = 0x52) li a2, 1 # canal 1 li a7, 2048 # chamada de sistema ecall
Note que é importante representar a tripla (f, v, d) como indicado na Parte 1 para que o código do Player funcione corretamente.
Agora, basta executar o programa lab7 no simulador para testá-lo.
Você deve submeter o arquivo lab7.s no SuSy.
Endereço para a entrega da atividade no prazo original no sistema SuSy: https://susy.ic.unicamp.br:9999/mc404ab/07a ou https://susy.ic.unicamp.br:9999/mc404ab/07b
Endereço para a entrega da atividade fora do prazo (até dia 16/10): https://susy.ic.unicamp.br:9999/mc404ab/07aa ou https://susy.ic.unicamp.br:9999/mc404ab/07bb