← Voltar ao Blog

A transcrição funcionou. O acompanhamento, não: tentei gerar playback de karaokê com OSS e travei três vezes

Um amigo me contou que produz sozinho, tirando de ouvido, os playbacks que usa para gravar covers. Fiquei com aquilo na cabeça desde então. Resolvi ver até onde a máquina chega fazendo a mesma coisa, testei com uma música e não cheguei lá.

O que eu queria era um acompanhamento para treinar. Se desse certo, queria passar para outras pessoas que ensaiam a mesma música. Poder distribuir era o ponto de partida.

Só que, na hora de passar para alguém, uma das opções some. Mesmo tirando só o vocal de uma faixa comercial, a matéria-prima continua sendo a gravação que outra pessoa fez. Para uso doméstico tudo bem; para distribuir, muda tudo.

Foi aí que uma ideia minha caiu. Eu achava que o áudio dos serviços de karaokê fosse o disco original com o vocal removido. Na verdade é outra gravação, feita tocando a música de novo do zero.

Então pensei: se a máquina tocar de novo, a gravação que sai é minha.

Montei com OSS e não saiu nada que dê para ouvir.

Mas o interessante não é o fracasso em si. É que meu diagnóstico de onde eu estava travando mudou três vezes, e nas três eu estava confiante o bastante para começar a construir em cima do diagnóstico errado antes que alguma coisa me avisasse. Vou na ordem.

O que dá para distribuir e o que não dá

São duas camadas de direito. A obra musical em si e a gravação, que no Brasil chamam de direitos conexos do fonograma. Quando você processa a faixa comercial, o direito sobre aquele fonograma continua com a gravadora.

✕  tirar o vocal do disco original  → o fonograma continua sendo da gravadora → não distribuo
◯  transcrever e tocar de novo      → gravação gerada por mim                 → há margem para distribuir

O direito sobre a obra não some por tocar de novo. O trâmite com ECAD e editora continua existindo. Não sou advogado e não vou cravar onde fica o limite. O que eu queria medir era se o caminho de “refazer a gravação” se sustenta tecnicamente.

O alvo foi uma música só: “Koi Darou”, da banda japonesa wacci, com 4 minutos e 50 segundos. Todos os números que aparecem daqui em diante saíram da análise dessa faixa. É uma gravação de banda com sintetizador e coro por cima, ou seja, nada fácil para transcrever.

A montagem

São três etapas. Separar, transcrever, tocar.

EtapaFerramentaLicença
SeparaçãoDemucs htdemucsMIT
TranscriçãoBasic Pitch (Spotify)Apache-2.0
SínteseFluidSynth 2.2.5 + FluidR3_GM.sf2conforme cada distribuição

Preenchi a coluna de licença antes de qualquer outra coisa porque o objetivo era distribuir. Basta uma peça não redistribuível no meio do caminho para travar tudo lá na saída.

Recurso computacional exigiu menos do que eu esperava. O Demucs roda na CPU a 2,2 vezes o tempo real, então a faixa de 4min50 virou 4 stems em 2min12 numa máquina que eu já tinha.

Perdi um dos meus motivos para comprar GPU.

Para transcrição multi-instrumento também existem MT3 e Omnizart, mas eu não testei nenhum dos dois. O Basic Pitch deu resultado antes e a comparação perdeu a razão de ser. O MT3 aparece adiante, porém como texto de README, não como medição minha.

Travamento 1: “a transcrição não dá conta de pop” estava errado

Minha primeira suspeita foi a transcrição. Uma linha monofônica até vai, mas pop com sintetizador, guitarra e coro empilhados eu não acreditava que virasse partitura.

O que resolveu foi a separação. O README do MT3 avisa que o modelo não foi treinado com voz cantada, então entregar áudio com vocal produz resultado estranho. Ou seja, separando antes, essa restrição nem chega a existir.

Para conferir se a separação estava mesmo funcionando, passei três entradas por um detector de pitch e comparei a distribuição de confiança.

EntradaMediana da confiançaFaixa predominante
Original0,865A1–E2 (baixo)
Acompanhamento0,893A1–E2 (baixo)
Stem de vocal0,976região da voz

Original e acompanhamento estão os dois agarrados nos graves do baixo, sem seguir a melodia. No stem de vocal esses graves não sobram, e a sobreposição entre os histogramas de vocal e não-vocal caiu para 0,09.

A separação funciona.

Aí rodei o Basic Pitch nos três stems. A proporção que cai dentro de uma tessitura plausível está definida assim:

#: 楽器として妥当な音域 (MIDI)
EXPECTED = {
    "bass": (28, 55),      # E1 〜 G3
    "other": (48, 84),     # C3 〜 C6
    "vocals": (45, 79),    # A2 〜 G5
}

low, high = EXPECTED[stem]
in_range = float(np.mean((pitches >= low) & (pitches <= high)))

Resultado:

stemnotaspor segundodentro da tessituranotas mais frequentes
bass7942,888%B, A, E, C#, G#
other322811,279%E, B, A, G#, C#
vocals8943,195%E, B, F#, G#

A coluna que mais pesou foi a da direita. Os três stems foram transcritos de forma independente e todos os nomes de nota que saíram cabem na escala de Mi maior (E F# G# A B C# D#). Três cadeias que não consultam o resultado uma da outra pousaram na mesma tonalidade, então não é coincidência. O resultado do vocal também bate com uma partitura que eu já tinha gerado por outro caminho (SwiftF0).

Os três stems chegaram à mesma tonalidade de forma independente

A transcrição estava funcionando.

Quem eu suspeitei primeiro era inocente o tempo todo.

Travamento 2: “é a qualidade da síntese” também estava errado

Com a transcrição de pé, passei a achar que a barreira era a síntese. MIDI tocado em onda senoidal soa horrível, é claro. Com um timbre decente deveria dar para ouvir, era o raciocínio.

Subi o timbre por etapas e pedi para escutarem a cada uma.

VersãoComo foi sintetizadoVeredito
resynthonda senoidal (bass + other)não serve
pianopiano do FluidSynth (bass + other)não serve
guidepiano do FluidSynth (só a melodia)hmm
musicboxcaixinha de música do FluidSynth (só a melodia)fraco

Subi quatro degraus de timbre e a avaliação quase não se mexeu. Se trocar onda senoidal por um piano de SoundFont não muda nada, o problema não é o timbre.

Desconfiei da sujeira e escrevi um filtro para ralear as notas. O stem other tem 11,2 notas por segundo. Achei que fossem acordes densos, mas era nota curta em sequência: a cauda de pad e de reverb entrando como nota.

#: これより短い音は捨てる (秒)
MIN_DURATION = 0.2
#: これより弱い音は捨てる。弱い誤検出を落とす
MIN_VELOCITY = 50
#: 同時に鳴らす上限。伴奏なので土台の和音が要る
MAX_SIMULTANEOUS = 5

notes = [
    n
    for n in instrument.notes
    if n.end - n.start >= MIN_DURATION and n.velocity >= MIN_VELOCITY
]

As 3228 notas caíram para 1770 e melhorou um pouco. Continuou impossível de ouvir.

A versão mais bem avaliada ter sido a caixinha de música também diz alguma coisa. Ela toca só a melodia. Se a que tem menos notas ficou na frente, o que faltava não era qualidade sonora.

Travamento 3: o que faltava era o arranjo

Fui então atrás de como o playback de karaokê e os arranjos de caixinha de música são realmente produzidos. Nos dois casos existe alguém arranjando e programando.

Shigeshi Miki, presidente da C-Music, produtora de áudio para karaokê, descreve assim a rotina:

A entrada de dados é toda feita de ouvido. Por isso não recebemos MIDI da gravadora, embora seja comum receber a música antes do lançamento para adiantar o trabalho. — Shigeshi Miki (C-Music) / DTM Station (Ken Fujimoto)

Ninguém entrega dado nenhum. Alguém senta com o disco e vai tirando nota por nota, e no Japão existe uma certificação de MIDI que serve diretamente para essa vaga, o que já diz bastante sobre o grau de especialização do trabalho.

Com caixinha de música é igual. A maioria dos “arranjos de caixinha de música” do YouTube é som eletrônico com timbre de caixinha, arranjado livremente. Gravação de caixinha real, girando de verdade, quase não se acha.

Lado a lado fica assim:

Etapas
Playback de karaokêpessoa tira de ouvido → pessoa arranja → programa
Arranjo de caixinhapessoa arranja (tira notas, ajusta o movimento, transpõe) → programa
Este experimentomáquina transcreve → toca do jeito que saiu

O que faltava era o arranjo

A coluna do meio estava inteira vazia.

Copiar o original e refazer aquilo em formato que funcione no instrumento são trabalhos diferentes, e arranjo de caixinha de música só se sustenta porque alguém já fez o segundo. Trocar só o timbre da transcrição não chega lá.

O que meu amigo fazia era justamente essa coluna do meio. Tirar as notas de ouvido a máquina assume. Remontar aquilo em formato que funcione no instrumento ele fazia na mão. Quando ele me contou, eu não contei aquilo como uma etapa. “Tirar de ouvido” é uma expressão só para dois trabalhos distintos.

Como reproduzir

# 1. separar em 4 stems
python -m demucs -n htdemucs -d cpu -o <destino> <áudio>

# 2. criar um venv isolado para a transcrição
uv venv --python 3.10 amt-venv
VIRTUAL_ENV=$PWD/amt-venv uv pip install basic-pitch 'numpy<2' 'setuptools<81' scipy

# 3. passar os caminhos e rodar
export SONGFIT_STEMS=<destino do Demucs>/htdemucs/<música>
export SONGFIT_WORK=<diretório de trabalho>
./amt-venv/bin/python amt_check.py bass other vocals   # transcrever e avaliar
./amt-venv/bin/python render_fluid.py all              # sintetizar

O tropeço foi no passo 2. O basic-pitch exige numpy<2, então colocá-lo no mesmo venv de um projeto que usa numpy 2 quebra tudo. Separe o venv da transcrição.

Passei os caminhos por variável de ambiente em vez de argumento para não deixar o material gerado cair dentro do repositório sem querer. Derivado de obra protegida fica fora do alcance de um git add ..

Onde eu travei, resumido

MomentoO que eu achava que era a causaNa prática
No começotranscrição não dá conta de poperrado. separando, dá 88 / 79 / 95%
Depois que a transcrição funcionoua barreira é a sínteseerrado. quatro degraus de timbre não mudam a avaliação
Timbre não muda nadafalta a etapa de arranjoaqui acertei

As duas primeiras linhas, ou seja, os dois primeiros suspeitos, eram inocentes. Eu suspeitei na ordem do que é mais fácil de mexer, o que parecia depuração e era quase o contrário disso. Precisão de transcrição e timbre de síntese têm parâmetro: você mexe e o número anda. É confortável suspeitar de onde existe número que anda.

O que estava vazio de verdade era um lugar sem nenhum parâmetro. Onde a etapa em si não existe, não nasce margem de ajuste.

Vale registrar a validade: isto vale para o OSS em agosto de 2026.

O que precisa mudarEfeito
escrever eu mesmo a etapa de arranjoo cerne. remontar as notas copiadas em formato que funcione no instrumento
síntese de MIDI para áudio ficar natural sem intervençãoderruba a barreira do timbre, o arranjo continua
precisão de transcrição multi-instrumento subirnão adianta. a transcrição já está suficiente

O próximo passo é estimar os acordes do stem other. Se der para tirar o acorde de cada compasso das 3228 notas, tenho base para remontar o acompanhamento. Se você travou no mesmo ponto, me conte por onde começou a atacar.