Skip to content
אצלי
Go back

Notação musical no Standard Notes: ABC, ChordPro e alphaTex

Editor Stave dentro do Standard Notes no tema escuro, com o código alphaTex de uma música à esquerda e, à direita, partitura e tablatura de melodia, guitarra base e baixo

Também disponível em inglês: Music notation in Standard Notes: ABC, ChordPro and alphaTex.

O Standard Notes é um app de notas gratuito, open source e com criptografia ponta a ponta, que uso desde abril de 2024. Além do editor padrão, ele aceita editores customizados, e venho escrevendo alguns:

Todos compartilham a mesma base: React 18 e TypeScript, build com Vite, o stylekit do Standard Notes para os temas, Vitest e fast-check nos testes unitários e Playwright nos testes de ponta a ponta.

O quarto é o Stave, um editor de notação musical. Você escreve a música como texto e ele desenha a partitura, a tablatura ou a cifra ao lado, toca e exporta (SVG, PNG, MIDI, PDF, Guitar Pro). A regra é a mesma dos outros plugins: a nota guarda só o texto, então continua legível sem o plugin e é criptografada como o resto dos seus dados.

O Stave entende três formatos de texto: ABC, ChordPro e alphaTex. Eles parecem fazer a mesma coisa, mas cada um nasceu para um tipo de músico, e é disso que trata este post.

Table of contents

Open Table of contents

Instalando o Stave

  1. No Standard Notes (web ou desktop), abra Preferences, depois Plugins.

  2. No fim da página, cole a URL abaixo em Install Custom Plugin:

    https://esli.cafe/StandardNotes-Stave/ext.json
  3. Crie uma nota, abra o menu Editor e escolha Stave.

Não é preciso escolher o formato: o Stave detecta pelo texto. Se a primeira linha começa com X:, é ABC; linhas com tags como \title indicam alphaTex; diretivas como {title:} ou letras com [acordes] indicam ChordPro. Uma nota vazia oferece um modelo de cada, e o menu Help traz uma cola de sintaxe para os três.

ABC

Stave com uma música em ABC. À esquerda, o código com cabeçalho X, T, M, L, Q e K, duas vozes, Melody e Bass, e uma linha de letra. À direita, a partitura em duas pautas, clave de sol e clave de fá, com cifras acima, dinâmicas, trinado, ritornelos com primeira e segunda casa e a letra sob a melodia

Origem

O ABC foi criado por Chris Walshaw no início dos anos 1990 para anotar melodias de música tradicional, principalmente irlandesa e escocesa, de um jeito que coubesse em um e-mail ou em um fórum de Usenet. A ideia era que um músico conseguisse ler o texto mesmo sem software nenhum. Isso deu certo: hoje existem dezenas de milhares de melodias folk publicadas em ABC, e a versão atual do padrão é a 2.1. No Stave, o desenho e a reprodução ficam por conta do abcjs, de Paul Rosen.

Sintaxe

Um arquivo ABC tem um cabeçalho de campos de uma letra seguidos de dois-pontos, e depois o corpo com as notas:

No corpo:

Exemplo

X:1
T:Morning on the Stave
M:4/4
L:1/8
K:G
|: "G"G2 BG dGBG | "C"c2 ec "G"B2 dB | "Am"A2 cA "D"F2 AF | "G"G4 z4 :|

Uma melodia em sol maior, 4/4, quatro compassos com ritornelo e uma cifra por tempo forte. Dá para ler e cantarolar sem renderizar nada, que é justamente a proposta.

A mesma música em ABC no tema escuro. O código à esquerda tem os campos do cabeçalho, as vozes e os ornamentos realçados em cores, e a partitura à direita fica em fundo claro, com melodia, baixo, cifras e letra

ChordPro

Stave com uma música em ChordPro. À esquerda, as diretivas title, subtitle, artist, key, capo, tempo e time, seguidas de estrofes e refrão com acordes entre colchetes no meio da letra. À direita, a folha de música com título, os dados da música e cada acorde em azul acima da sílaba em que entra

Origem

O ChordPro vem do programa chord, escrito por Martin Leclerc e Mario Dorion no início dos anos 1990 para imprimir songbooks a partir de arquivos de texto. O formato se espalhou por apps de cifra e de palco e virou um padrão de fato. Hoje é mantido por Johan Vromans, que reescreveu a ferramenta de referência e publica a especificação em chordpro.org.

O foco é outro: não há notas nem ritmo, só letra e acordes. É o formato de quem toca violão na roda, não de quem lê partitura. Por isso o Stave desenha e transpõe ChordPro, mas não toca: uma cifra não diz a duração de nada.

Sintaxe

São só dois elementos:

As diretivas mais usadas:

Linhas que começam com # são comentários do arquivo e não aparecem.

Exemplo

{title: Morning on the Stave}
{key: G}
{capo: 2}

{start_of_verse: Verse 1}
[G]Morning comes on the [C]stave, [G]light on every [Am]line
{end_of_verse}

{start_of_chorus}
And the [C]tune goes [G]round a-[Am]gain, [D7]
{end_of_chorus}

Sem o plugin, o texto continua sendo uma cifra legível. Com ele, os acordes sobem para cima da letra, e transpor muda todos os acordes e o {key} de uma vez, baixos de acordes como D/F# incluídos.

A mesma música em ChordPro no tema escuro. Diretivas em azul e acordes em amarelo no código à esquerda; à direita, a folha com o título, os dados da música, a Verse 1, o refrão marcado por uma barra à esquerda, a Verse 2 e a ponte com um comentário em itálico

alphaTex

Stave com a mesma música em alphaTex, tema escuro. À esquerda, as tags title, tempo, ts e ks, a faixa Melody com instrumento, pauta e letra, e as notas no formato traste.corda.duração com efeitos entre chaves. À direita, partitura e tablatura de três faixas: melodia, guitarra base com acordes e um baixo de 4 cordas

Origem

O alphaTex é o formato de texto do alphaTab, uma biblioteca open source criada por Daniel Kuschny para desenhar e tocar partitura e tablatura no navegador. O alphaTab nasceu para abrir arquivos do Guitar Pro, e o alphaTex é a forma de escrever a mesma coisa à mão. Por isso ele pensa como um guitarrista: em vez de nomear a nota, você diz em qual traste e em qual corda ela está.

É o mais completo dos três para instrumentos de corda: várias faixas, afinações próprias, técnicas como bend, slide, hammer-on e palm mute. No Stave, ele também importa MusicXML e arquivos do Guitar Pro 3 a 7 e exporta para Guitar Pro 7.

Sintaxe

Os metadados são tags com barra invertida:

As notas seguem o formato traste.corda.duração:

Exemplo

\title "Morning Riff"
\tempo 96
\track "Guitar"
\staff {score tabs}
0.6.8 0.6 3.6 0.6 5.6.4 3.6.8 5.6 | (0.6 2.5 2.4).4{ch "E5"} 7.3{b (0 4)}.4 r.2
\track "Bass"
\tuning (G2 D2 A1 E1)
\staff {tabs}
0.4.4 0.4 3.4 0.4 | 0.4.2 r.2

Duas faixas: uma guitarra com um riff na corda grave, um power chord de mi e um bend de um tom, e um baixo de 4 cordas acompanhando. É menos legível que ABC para quem não toca, mas para quem já lê tablatura a tradução é direta.

A mesma música em alphaTex no tema claro. À direita, a melodia em partitura e tablatura, a guitarra base com acordes batidos e setas indicando a direção da batida, e o baixo em clave de fá com a sua tablatura, seguidos da segunda linha com slide, bend e as casas de primeira e segunda vez

Qual usar

Os três guardam música como texto, mas cada um responde a uma pergunta diferente:

O exemplo completo de cada formato, no menu File do Stave, é a mesma música escrita nos três, o que ajuda bastante a comparar.

Como o Stave foi feito

O Stave é uma página única escrita em TypeScript com React 18, com build pelo Vite. O Standard Notes carrega a página em um iframe, e ela conversa com o app pelo component relay do Standard Notes: recebe a nota, salva o texto de volta (com um pequeno atraso que junta edições rápidas em um único salvamento) e guarda as preferências de layout nos dados do próprio plugin, nunca na nota. A interface reaproveita os padrões do plugin Milkdown, e todas as cores vêm das variáveis de tema do Standard Notes, então todos os temas funcionam sem código específico.

Um editor, três engines

O centro do projeto é uma interface TypeScript, Engine, e a UI só conversa com as notações através dela. Cada engine:

Um registro lista os três engines, e é o único arquivo que sabe que eles existem. Cada renderizador é carregado com um import() dinâmico, então o Vite o coloca em um chunk próprio: abrir o editor carrega o React, a UI e o CodeMirror, e quem só escreve ChordPro nunca baixa o abcjs nem o alphaTab.

O engine de ABC

O ABC é desenhado e tocado pelo abcjs 6, uma biblioteca MIT escrita em JavaScript. O renderAbc desenha SVG, e o seu click listener devolve as posições de caractere de cada nota, e é assim que um clique na partitura seleciona o texto. A reprodução usa o sintetizador do abcjs com TimingCallbacks para mover o cursor, a exportação MIDI usa o getMidiFile e a transposição usa o strTranspose, que reescreve o código e a armadura de clave. O sintetizador do abcjs busca as amostras em uma CDN por padrão, então o Stave leva as amostras de piano do Fluid R3 GM no build e aponta o sintetizador para elas.

O Verovio, um gravador de partituras em WebAssembly com resultado mais bonito, foi medido e ficou de fora: 2,3 MB com gzip contra 146 KB do abcjs, sem suporte a várias vozes no importador de ABC e sem ligação do desenho de volta ao texto.

O engine de alphaTex

O alphaTex roda sobre o alphaTab 1.8, uma biblioteca MPL-2.0 escrita em TypeScript. O AlphaTexImporter lê o texto e devolve os diagnósticos com a posição; o Stave envolve uma etapa do importador para anotar o trecho de código de cada tempo, e é isso que faz o clique e o destaque do cursor funcionarem. A partitura é desenhada em SVG na thread principal, com a fonte musical Bravura. A exportação MIDI passa pelo MidiFileGenerator do alphaTab, a de Guitar Pro 7 pelo Gp7Exporter, e a importação de MusicXML e Guitar Pro passa pelo ScoreLoader e depois pelo AlphaTexExporter, que escreve o alphaTex na nota. A transposição é código do próprio Stave, porque precisa mudar trastes de corda quando eles saem do braço.

A reprodução foi a parte mais difícil. O alphaTab toca por um worker (o sintetizador) e um audio worklet, mas o Standard Notes carrega os plugins em um iframe com origem opaca, onde um worker não consegue iniciar a partir da URL do plugin. O Vite gera o player do alphaTab como um único script clássico, sem imports; no primeiro Play, a página baixa esse script e inicia o worker a partir de um blob com o texto dele, e então carrega o SoundFont Sonivox.

O engine de ChordPro

O ChordPro não usa biblioteca nenhuma. O ChordSheetJS, a biblioteca JavaScript mais comum, é GPL-2.0-only e não pode ser combinado com um plugin AGPL-3.0, então o Stave tem um parser próprio em TypeScript. Ele lê o texto linha a linha e gera uma lista de itens (letras divididas em segmentos de acorde e sílaba, diretivas, seções, comentários, tablatura), cada um com as suas posições no código, e informa diretivas desconhecidas e acordes ou seções não fechados como erros. O renderizador monta a folha em HTML com chamadas ao DOM e coloca o texto da nota via textContent, nunca como markup, então nada em uma nota consegue injetar código. A transposição move todos os acordes, baixos incluídos, e a diretiva {key}.

Segurança, offline e testes

Um plugin do Vite adiciona uma Content Security Policy ao build: scripts só da origem do próprio plugin, sem código inline, sem eval, conexões só para a origem do plugin e workers só a partir de blobs. Fontes, SoundFonts e amostras vão junto com o build, então o editor continua funcionando offline, como o app. Todas as dependências vêm do registro do npm, e o component relay, que tinha uma correção só no GitHub, fica copiado no repositório com a licença dele.

Os testes usam Vitest, Testing Library e fast-check para testes unitários e de propriedades, e Playwright para testes de ponta a ponta que carregam o plugin em uma simulação dos apps web e mobile, tocam música, verificam a CSP e rodam o axe-core contra a WCAG 2.1 AA.

A versão atual é a v1.2.0, licença AGPL-3.0. O código está em github.com/Esl1h/StandardNotes-Stave.


Share this post on:

Next Post
Music notation in Standard Notes: ABC, ChordPro and alphaTex