
Um PLAYER em C++ sem dependências para toques Yamaha SMAF (.mmf): o formato polifônico de toques dos chips telefônicos MA-3 / MA-5 dos anos 2000, reconstruído com seu próprio mecanismo FM livre de ROM. O player aberto que ninguém terminou. Comprovado no FXChainPlayer.
por Akustikrausch (Andreas Wendorf)
um pequeno reprodutor de ringtones Yamaha SMAF (.mmf) em c++, sem dependências.
Você entrega um daqueles arquivos que faziam o seu Samsung, Sharp ou Panasonic tocarem
deedle-deedle-dee em 2004, e ele devolve áudio estéreo limpo. Sem telefone, sem
firmware, sem ROM de sample. Apenas o chip FM, reconstruído em software.
Este é o som de uma década inteira que quase ninguém se preocupou em preservar em código aberto. Existem milhões desses arquivos ainda circulando, e ninguém nunca finalizou um reprodutor aberto para eles: as tentativas pararam em 2004 ou contornam o sintetizador por completo. Então aqui está um em c++, escrito a partir do formato, com seu próprio núcleo de sintetizador FM.
🎧 este código é enviado em um produto real: FXChainPlayer. um reprodutor de áudio nativo para Windows que toca seus velhos ringtones ao lado de seus FLACs, SIDs e módulos do Amiga. É onde este motor roda todos os dias, contra um corpus de centenas de tons reais de aparelhos. Baixe o reprodutor para apenas ouvir, ou continue lendo para saber como o chip funciona.
a série Yamaha MA (YMU762 = MA-3, YMU765 = MA-5) foi o chip de som dentro
de uma enorme fatia dos telefones do início dos anos 2000. É um sintetizador FM legítimo,
primo próximo dos chips OPL/OPN da era Adlib e Sega Genesis, miniaturizado para um
aparelho. Os arquivos que ele tocava, SMAF (.mmf), carregam uma partitura FM mais
samples ADPCM opcionais. O toque polifônico nasceu aqui.
Então chegaram os smartphones, os ringtones em mp3 tomaram conta e todo o formato morreu silenciosamente. A Yamaha tirou seu SDK do ar. E diferente das cenas Amiga ou C64, quase ninguém escreveu um emulador. O que existe:
umjammer/vavi-sound (java) analisa e toca SMAF, e é uma referência comportamental
brilhante, mas não faz síntese FM: ele reembrulha os tons como General MIDI
e deixa o sintetizador Java aproximá-los. E é Java.Portanto, um reprodutor nativo, com licença permissiva, livre de ROM do chip FM real não existia. Este é esse. Cada byte do analisador e cada operador do sintetizador foi escrito a partir da descrição pública do formato SMAF mais muita observação de arquivos reais em um editor hexadecimal, nunca copiando de outro reprodutor.
o motor é composto por cinco pequenas peças, cada uma testável individualmente:
src/
smaf_file o contêiner MMMD: chunks TLV big-endian (CNTI/OPDA/MTR/ATR),
duas gerações de partitura (HandyPhone para MA-1/2, Mobile para MA-3/5)
ma_player os dois decodificadores de eventos (+ Huffman Okumura para a variante
compactada), um escalonador que roda em milissegundos como o chip
fazia, e o laço de renderização que aciona um pool de vozes FM
ma_fm_core o DSP FM: operadores de 2 e 4 operandos, envelopes ADSR exponenciais,
os algoritmos de conexão estilo OPL e seu próprio banco de patches
de aproximação General MIDI
smaf_voice decodifica os blobs de sysex de voz da Yamaha (VM35 para MA-3/5, VMA para
MA-1/2) em patches FM, incluindo a forma compactada em bits do MA-3
yamaha_adpcm o codec ADPCM de 4 bits da família YM2608, para as vozes sampleadas
O modelo de temporização é a surpresa agradável: SMAF não tem eventos de andamento, o tempo é puramente métrico (tempo do evento = soma das durações vezes uma base de tempo, em milissegundos), então um tick mapeia diretamente para um milissegundo e depois para amostras. O núcleo FM roda diretamente na sua taxa de saída, então não há reamostragem no caminho do sintetizador.
os chips MA também carregavam uma pequena ROM de samples General MIDI para que um toque pudesse dizer "toque o programa 5" e obter um piano predefinido. Essa ROM é da Yamaha, nunca foi divulgada publicamente, e este projeto não a distribui, não a deseja e nunca a incorporará. Essa é uma linha dura.
Em vez disso, ma_fm_core carrega seu próprio banco de patches FM construído manualmente que substitui
a ROM: um arquivo que pede "programa 5" recebe uma voz FM plausível da família correta.
Não será bit a bit idêntico a um aparelho de 2003, e essa é a troca honesta. O que você obtém é a partitura FM real,
o tempo real das notas, o ADSR real, tocados por um sintetizador próprio. Reconhecido, e toca.
Arquivos que carregam suas próprias vozes personalizadas (muitos fazem isso) soam exatamente como foram criados, porque essas vozes estão no arquivo, não na ROM.
cmake -B build && cmake --build build
./build/smaf-render seu_ringtone.mmf out.wav 30
ou conecte a biblioteca ao seu próprio código:
#include "smaf_file.h"
#include "ma_player.h"
using namespace fxchain::smaf;
SmafFile file;
file.parse(bytes.data(), bytes.size()); // contêiner MMMD
MaPlayer player;
player.init(file, 44100); // constrói vozes + decodifica a partitura
float buf[1024 * 2]; // estéreo intercalado
int frames = player.render(buf, 1024); // bombeia o sintetizador
43 79 06 7F 03) que alguns arquivos de kit de bateria puro
carregam suas amostras; e as formas de onda mais altas específicas do SD-1. Veja
ROADMAP.md..mld) (um primo; veja
ROADMAP.md m3).este analisador foi feito para consumir arquivos não confiáveis, então foi escrito de forma defensiva: cada comprimento de chunk é limitado ao buffer real, o inflate Huffman tem proteções de nó + profundidade e um teto de saída, e os decodificadores de eventos carregam limites de iteração + total de eventos. Ele degrada para "não é um arquivo SMAF válido" em vez de travar. Detalhes e relatórios em SECURITY.md.
src/ o motor (quatro pequenas unidades de tradução mais um codec cabeçalho, sem
dependências). example/smaf-render.cpp o CLI wav em menos de 100 linhas. CMakeLists.txt
constrói uma biblioteca estática smaf mais o exemplo. Isso é tudo.
Apache License 2.0 (veja LICENSE). O analisador e o sintetizador são trabalho original; nenhum código de terceiros é fornecido, e nenhum material de ROM ou SDK da Yamaha está incluído. O conhecimento do formato veio da especificação pública SMAF e da observação.
não afiliado, autorizado ou endossado pela Yamaha. "SMAF" e os nomes dos chips MA são da Yamaha. Este é um trabalho de interoperabilidade: um reprodutor independente de um formato de arquivo aberto, construído sem qualquer código Yamaha ou a ROM de amostra protegida.
saudações a todos que ainda se lembram de como era o som do seu toque.