O que VST Maker faz?
Skill comunitário não oficial. Não criado ou endossado por nenhum fornecedor de plugin, sintetizador ou framework mencionado aqui.
Como ler as tags de confiança:
- (V: fonte) verificado com a fonte nomeada.
- (R) regra prática ou de gosto. Um valor inicial para testar medindo e ouvindo, nunca uma lei.
Se um fato não tiver tag, é uma prática padrão que você ainda deve verificar antes de confiar nele para um lançamento.
0. Regras básicas
- Pergunte antes de construir: tipo de plugin (sintetizador, efeito, controlador), SO alvo (Linux, macOS, Windows), formatos (VST3 primeiro; CLAP ou LV2 opcionais), paleta de cores (nunca assuma uma; ofereça um padrão neutro se o usuário não tiver nenhuma), licença (veja 1).
- Plugins gratuitos e de código aberto devem funcionar offline: sem conta, sem servidor de licença, sem download na instalação ou execução. Tudo o que o plugin precisa deve estar incluído.
- Nunca afirme que um som é bom de ouvido. Meça-o (veja 12) e deixe os ouvidos do usuário fazerem a avaliação final.
- Cite ou teste cada número. Diga "não verificado" quando um valor for uma regra prática.
- Faça um passo de cada vez quando o usuário não for um programador. Respostas curtas primeiro, detalhes sob demanda.
1. Configuração do projeto e licença
- JUCE tem licenciamento duplo: a licença JUCE e AGPLv3. Sem um plano JUCE pago, você deve usá-lo sob AGPLv3, e AGPLv3 exige mais do que publicar o código-fonte (V: fórum JUCE, resposta da equipe). Leia a licença JUCE atual para a versão que você usa antes de escolher, e informe ao usuário qual se aplica. Não declare preços de tier ou limites de receita de memória.
- Use CMake. Mantenha o código de DSP livre de tipos de GUI do JUCE para que possa ser testado unitariamente sem uma janela.
- Construa VST3 primeiro. CLAP e LV2 são opcionais: verifique os documentos atuais do JUCE e clap-juce-extensions antes de prometer qualquer um.
- Onde os hosts escaneiam VST3 (V: Steinberg VST 3 Developer Portal, Locais de Plugins):
- Linux:
$HOME/.vst3/primeiro, depois/usr/lib64/vst3/,/usr/lib/vst3/,/usr/local/lib64/vst3/,/usr/local/lib/vst3/. - macOS:
~/Library/Audio/Plug-ins/VST3/(usuário),/Library/Audio/Plug-ins/VST3/(global). - Windows:
C:\Program Files\Common Files\VST3\(global),%LOCALAPPDATA%\Programs\Common\VST3\(usuário, principalmente para desenvolvimento). - Os hosts usam o primeiro plugin encontrado para um determinado UID do Processador, escaneando em ordem de prioridade.
- Linux:
2. Segurança em tempo real
processBlock executa em uma thread de áudio de alta prioridade com um prazo rígido. A documentação do JUCE diz que qualquer interação com a UI ali está fora de questão, e o código deve lidar com tamanhos de bloco variáveis (V: documentos JUCE AudioProcessor).
Nunca na thread de áudio:
- alocar ou liberar memória (new, delete, malloc, vetores ou strings em crescimento, construir juce::String)
- obter um bloqueio que outra thread possa segurar (std::mutex, CriticalSection)
- E/S de arquivo, rede ou console
- chamar a UI ou MessageManager
- lançar exceções ou chamar qualquer coisa com comportamento de tempo real desconhecido
Em vez disso:
- Aloque em
prepareToPlay(a taxa de amostragem permanece constante até a reprodução parar; o tamanho do bloco é apenas uma dica e a documentação diz para programar defensivamente caso um host o exceda) (V: documentos JUCE). Libere emreleaseResourcesou no destrutor. - Comunique-se com outras threads usando filas lock-free (
juce::AbstractFifo) ou atômicos. A UI consulta atômicos com um Timer; ou acione AsyncUpdater a partir da thread de áudio. - Coloque
juce::ScopedNoDenormalsno topo deprocessBlock; ele permanece ativo até a função retornar, então ajudantes não o repetem (V: consenso do fórum JUCE, não documentação oficial). Também projete caminhos de realimentação para que não possam decair em denormais. - Leitura recomendada: Ross Bencina, "Real-time audio programming 101: time waits for nothing" (não citado aqui, não pôde ser obtido quando este skill foi escrito).
3. Parâmetros e estado
- Use
AudioProcessorValueTreeState: automação do host, desfazer e salvar estado vêm com ele. - Suavize cada parâmetro que atinge um ganho, frequência, mix ou tempo de atraso (
juce::SmoothedValue), ou você obtém ruído de zíper e cliques. - Leia valores uma vez por bloco em variáveis locais, a menos que o valor seja suavizado por amostra.
- Dê a cada parâmetro um ID de string estável. Nunca renomeie ou reordene IDs após o lançamento: isso quebra projetos salvos e automação. Adicione novos parâmetros com novos IDs e mantenha um número de versão de estado.
- Valide tudo carregado do estado ou presets: limite intervalos, ignore chaves desconhecidas, nunca confie em tamanhos ou contagens.
- Mantenha o processador (DSP e estado) estritamente separado do editor (UI). O processador deve funcionar perfeitamente com a janela do editor fechada. O próprio VST3 divide um plugin em um processador e um controlador (V: tutorial Steinberg VST 3, "Code your first plug-in").
- Fatos VST3 que vale a pena saber mesmo quando JUCE os encapsula (V: mesmo tutorial): parâmetros são sempre normalizados para 0,0 a 1,0; defina o sinalizador automatable para que os hosts possam automatizar; um bloco de processamento pode conter mais de uma alteração para o mesmo parâmetro, então um processador escrito à mão deve lidar corretamente com a fila (o tutorial aplica apenas a última alteração, o que é uma simplificação); se a entrada estiver silenciosa, defina e honre os sinalizadores de silêncio e limpe os buffers de saída; rejeite layouts de barramento não suportados em vez de adivinhar; quando não houver entradas ou amostras, ainda aplique alterações de parâmetro pendentes.
Mais fatos da arquitetura VST3 (V: Steinberg VST 3 Developer Portal, documentação da API):
- O processador deve funcionar sem nenhum controlador carregado, então o estado DSP nunca depende do editor.
process()esetProcessing()podem executar na thread de áudio: sem alocação. Initialize e terminate executam na thread da UI.- Arranjos de barramento e alto-falante podem mudar apenas enquanto o plugin está inativo. Forneça buffers para todos os barramentos, mesmo os inativos. Buffers de entrada e saída podem compartilhar memória, então não limpe saídas cegamente.
- Notas chegam como eventos em
process(). As alterações de parâmetro chegam com precisão de amostra através de filas de parâmetros. Tempo e transporte chegam no contexto do processo. - Edições da GUI para o host usam beginEdit, performEdit, endEdit nessa ordem, apenas na thread da UI.
- Na restauração do estado, o processador é restaurado primeiro; o controlador então recebe o estado do componente e não deve disparar callbacks de manipulador.
- Não envie mensagens privadas processador-para-controlador de
process(); use a thread da UI ou a API de Troca de Dados. - Unidades agrupam parâmetros; a interface de mapeamento MIDI mapeia CCs MIDI para parâmetros.
- Páginas do Portal para ler quando necessário: Parâmetros e Automação, Diagramas de Fluxo de Trabalho, Múltipla E/S Dinâmica (sidechain), Unidades VST 3, Troca de Dados.
4. Performance: CPU, RAM, GPU
- Meça antes de otimizar (veja 12).
- CPU (R): processe em blocos, pré-calcule coeficientes quando um parâmetro mudar, evite ramificações por amostra e chamadas virtuais em loops internos, evite
std::pow,std::exp,std::sinpor amostra onde uma recorrência ou tabela funciona e mede mais rápido. - RAM: pré-aloque uma vez, compartilhe wavetables e tabelas entre vozes, libere buffers grandes em
releaseResources. - GPU e UI: desenhe apenas enquanto o editor estiver visível e na frente. Pause timers, medidores e animação de canvas quando oculto; áudio, automação e MIDI continuam em execução. Limite a taxa de repintura e repinte apenas regiões sujas (R). Use renderização de GPU apenas se claramente necessário e testado no Linux.
- Um editor oculto ou fechado não deve manter trabalho por quadro em execução.
5. Latência
- Reporte a latência real com
setLatencySamples("o número de amostras de atraso que ele introduz", V: documentos JUCE) sempre que o plugin atrasar o áudio: limitadores ou compressores lookahead, filtros de fase linear, filtros de oversampling. Verifique em um host se o relatório é aplicado. - Instrumentos adicionam latência zero de note-on ao som.
- Filtros de oversampling de fase linear adicionam latência; os de fase mínima não, mas mudam a fase. Escolha intencionalmente e documente.
juce::dsp::Oversamplingrelata sua latência; reporte-a. - Mantenha
getTailLengthSecondscorreto para reverbs e delays para que os hosts não cortem as caudas.
6. Qualidade de som
Aliasing
- Ondas dente de serra e quadradas ingênuas têm harmônicos acima de Nyquist que se dobram como ruído inarmônico. Correções: métodos de passo com largura de banda limitada (família BLEP), formas de onda polinomiais diferenciadas, wavetables com largura de banda limitada por oitava, ou oversampling.
- Um método publicado: formas de onda polinomiais diferenciadas; a avaliação do modelo de escuta dos autores encontrou um método de quarta ordem perceptualmente livre de alias em toda a gama de um piano de cauda (V: Välimäki, Nam, Smith, Abel, IEEE TASLP vol. 18 no. 4, 2010).
- Qualquer não linearidade (distorção, saturação, wavefolding, clipagem forte) cria novos harmônicos que alias. Faça oversampling em torno de estágios não lineares, ou use anti-aliasing baseado em antiderivada. Zavalishin cobre antialiasing de waveshaping (V: "The Art of VA Filter Design", seção 6.13).
- Teste aliasing por medição (veja 12), não a olho no código do oscilador.
Filtros
- Para filtros analógicos modelados, use estruturas de realimentação de atraso zero (topology-preserving transform). O livro os aborda no capítulo 3 (seção 3.9, realimentação de atraso zero), o ladder estilo Moog no capítulo 5 e a saturação do loop de realimentação no capítulo 6 (V: Zavalishin, "The Art of VA Filter Design", rev. 2.1.0, índice).
- Para EQ simples e filtros utilitários, use biquads. O Audio EQ Cookbook (R. Bristow-Johnson, W3C Working Group Note 2021) fornece passa-baixa, passa-alta, passa-banda, notch, all-pass, EQ shelving e peaking (V).
- Suavize mudanças de cutoff e ressonância, limite o cutoff abaixo de Nyquist, mantenha a ressonância estável em extremos e compense o nível para que a ressonância alta não aumente o volume.
Suave em vez de áspero (R, da prática de produtores; teste cada)
- Aspereza geralmente vem de aliasing, clipagem forte, picos de ressonância fortes nos médios superiores e muitos agudos não filtrados.
- Um lead com o lowpass totalmente aberto pode soar muito brilhante. Um cutoff inicial em torno de 12 kHz para leads brilhantes é um valor de gosto relatado pelo usuário, não uma regra.
- A saturação dentro do loop de realimentação do filtro é uma razão comum para filtros estilo analógico soarem suaves (V: Zavalishin cobre saturação do loop de realimentação; a afirmação perceptual é R).
- Modulação muito pequena e lenta mantém tons estáticos vivos, por exemplo, uma deriva de pitch de alguns cents. Converta antes de escolher: 0,1% é cerca de 1,7 cents, 1% é cerca de 17 cents, e 17 cents é claramente audível como desafinação. Fique no extremo baixo, a menos que a desafinação seja o objetivo.
- Sons encorpados vêm de camadas, uníssono com espalhamento de desafinação, um suboscilador e largura estéreo. Verifique a compatibilidade mono (some L e R, ouça por sons ocos ou cancelamentos).
Ganho e DC
- Execute a cadeia interna em float com bastante headroom. Nunca clipe dentro da cadeia. Coloque o único clipper ou limitador na saída, intencionalmente.
- Remova DC após não linearidades assimétricas com um passa-alta suave na faixa de unidades a dezenas de Hz (R); verifique com a medição de DC em 12.
- Combine o volume do preset (veja 9) para que a troca de presets não salte o nível.
7. Design de sintetizador
- Vozes: pré-aloque cada voz, nunca aloque em note-on. Torne a polifonia uma constante ou uma configuração do usuário. Roube vozes com um fade curto, nunca um corte abrupto.
- Envelopes: use um attack e release mínimos de alguns milissegundos para evitar cliques; no retrigger, comece do nível atual, não de zero.
- Uníssono: fases iniciais aleatórias ou espalhadas, uma curva de espalhamento de desafinação, espalhamento estéreo e uma compensação de nível que não cresce com o número de vozes.
- Supersaw: o Roland JP-8000 Super Saw é descrito como semelhante a sete osciladores dente de serra desafinados entre si (V: Wikipedia, Roland JP-8000). Análises detalhadas existem: Adam Szabo, "How to Emulate the Super Saw" (KTH, 2010) e Alex Shore (2013), ambos citados naquela página. Leia-os para curvas de desafinação e mixagem em vez de adivinhar números.
- Deriva e sensação analógica: modulação aleatória lenta de pitch e cutoff, por voz, pequena e não correlacionada.
- Ideias vistas em sintetizadores supersaw comerciais, apenas para estudo; escreva seu próprio código e design, nunca copie o código, aparência, nome ou presets de um produto (R, verifique por ouvido e medição):
- Um LFO lento por oscilador, com frequências espaçadas por proporções irracionais, como a proporção áurea, para que o movimento combinado não se repita audivelmente.
- Um macro "deriva" que escala a desafinação e a profundidade da deriva juntas, com controles finos em uma segunda página.
- Um high-pass rastreado por tecla como seu próprio controle (o som supersaw estilo JP-8000 usa um).
- Um filtro com oversampling 2x ou 4x opcional; reporte a latência de oversampling ao host.
- Verifique escalas dB em medidores, espalhamento estéreo por voz e efeitos com capacidade sidechain: lacunas que alguns produtos deixam e que os usuários notam.
- MIDI: use a posição de amostra de cada evento MIDI dentro do bloco para que as notas comecem com precisão de amostra. Lide com pitch bend (intervalo padrão de dois semitons, configurável), pedal sustain, all-notes-off e note-off com release. Ofereça mono, legato e portamento se o instrumento for voltado para lead ou baixo.
- Wavetables: largura de banda limitada por oitava ou faixa de pitch; cross-fade entre quadros para evitar ruído de zíper; interpole (linear é barato, ordem superior custa CPU, meça o aliasing).
8. Design de FX
- Compressor e limitador: detecte no domínio log com attack e release suavizados, aplique suavização de ganho, adicione makeup automático ou manual, reporte latência se você usar lookahead. Um limitador no final de uma cadeia precisa de um teto true-peak ou oversampled se prometer segurança entre amostras.
- Multibanda: divida com crossovers Linkwitz-Riley para que as bandas somem de volta planas; processe cada banda; recombin. Mantenha os crossovers consistentes em fase e reporte qualquer latência adicional.
- Delay: interpolação de atraso fracionário, filtros de amortecimento no caminho de realimentação, sincronização de tempo, ping-pong, ducking e um limite de realimentação para que não possa fugir.
- Reverb: redes de atraso de realimentação ou a topologia de placa Dattorro (J. Dattorro, "Effect Design Part 1", JAES 1997); amorteça os agudos na cauda; module linhas de atraso ligeiramente para evitar toque metálico; exponha pré-atraso, decay, amortecimento, tamanho e mix.
- Prática inicial comum para leads, teste por ouvido (R): mantenha o retorno do reverb fora dos graves com um passa-alta em torno de 200 a 300 Hz, corte os agudos da cauda e use um mix moderado.
- Chorus, ensemble, fase…