NeuralDisc v0 — especificação experimental
Data: 28/09/2026. Código, especificação e documentação próprios sob MIT.
Implementação de referência: scripts/ndisc_format.py. A versão é experimental;
alterações incompatíveis exigem outra versão ou outro perfil explícito.
Objetivo e perfil
Um arquivo .ndisc reúne um álbum, créditos e faixas comprimidas. Não contém
pesos neurais, executáveis, chaves ou DRM. O player já precisa possuir o decoder
identificado pelo disco. A v0 envolve os bitstreams ECDC existentes; não introduz
uma rede treinada do zero nem altera o som do perfil A escolhido.
Perfil único: encodec_48khz_3kbps_fp32_v0, estéreo, 48.000 Hz, taxa nominal
de 3 kbps, duas tabelas de quantização de 1.024 entradas, FP32, sem modelo de
entropia. A origem MIT do modelo está em models/encodec-48khz.json.
Disposição binária
Todos os inteiros do cabeçalho externo usam little-endian, sem alinhamento extra.
| Posição | Bytes | Campo |
|---|---|---|
| 0 | 8 | Identificador literal NDISC\x00\r\n |
| 8 | 2 | Versão sem sinal: 0 |
| 10 | 2 | Flags sem sinal: 0; outros valores são rejeitados |
| 12 | 4 | Comprimento do manifesto JSON em bytes |
| 16 | 4 | CRC32 do manifesto, compatível com zlib.crc32 |
| 20 | variável | Manifesto UTF-8, sem BOM |
| 20 + comprimento | variável | Faixas ECDC consecutivas |
O CRC usa o valor sem sinal de 32 bits. O arquivo termina imediatamente depois da última faixa. Não há preenchimento, arquivo auxiliar obrigatório ou índice externo. O empacotador emite JSON compacto, com chaves ordenadas; o leitor aceita outra ordenação ou espaços. Chaves duplicadas, NaN e Infinity são rejeitados.
Manifesto
Campos obrigatórios do álbum:
title,artist: textos não vazios, até 2.048 caracteres cada.profile: identificador do perfil acima.sample_rate: 48000;channels: 2.decoder_state_sha256: 64 caracteres hexadecimais minúsculos. Nesta edição:fa9578d66e734892d114596a6acc57d3d8631ad1bae76c34f9e19da1f45f8ced.tracks: lista ordenada de 1 a 99 faixas.
Campos obrigatórios de cada faixa:
title,artist,license: textos não vazios, até 2.048 caracteres cada.offset: inteiro, relativo ao início da área de faixas. A primeira começa em zero; cada faixa começa exatamente depois da anterior.length: comprimento positivo em bytes, incluindo todo o cabeçalho ECDC.samples: quantidade inteira de amostras por canal, igual à declarada pelo ECDC. A duração ésamples / 48000.crc32: CRC32 dos bytes ECDC da faixa, como oito dígitos hexadecimais minúsculos.gain: número finito maior que zero e menor ou igual a um, aplicado depois da reconstrução. O player de referência limita a saída ao intervalo [-1, 1].
Campos informativos opcionais: description no álbum e composer, genre,
credits, source_url, source_sha256 nas faixas. Campos adicionais podem ser
ignorados; nunca são instruções, caminhos a executar ou autorização de uso.
Declarar uma licença no manifesto não comprova a titularidade da música.
Conteúdo de cada faixa
ECDC versão 0: identificador ECDC, versão uint8, tamanho de JSON uint32
big-endian, JSON e segmentos. O JSON deve declarar m=encodec_48khz, nc=2,
lm=false e al=samples. Seu tamanho é limitado a 4.096 bytes.
Os segmentos começam nas posições 0, 47.520, 95.040… até o fim da faixa.
Cada um contém até 48.000 amostras por canal. Cada segmento armazena uma escala
float32 big-endian, positiva e finita, seguida pelos códigos de 10 bits, na
ordem temporal e depois por quantizador. O empacotamento segue o BitPacker
do EnCodec da revisão fixada, com os bits menos significativos primeiro;
o último byte do segmento é completado com zeros.
Para n amostras no segmento, existem ceil(n / 320) posições temporais e
duas palavras de 10 bits por posição. Seu comprimento total é
4 + ceil(20 × ceil(n / 320) / 8) bytes. A reconstrução respeita a normalização
e a sobreposição do modelo de referência. Não se pode simplesmente concatenar
os segmentos PCM sem combinar as sobreposições.
Validação e limites
O leitor atual limita o arquivo a 16 MiB, o manifesto a 64 KiB e cada faixa a uma hora. Verifica versão, perfil, limites, CRCs, contiguidade, amostras, escalas, duração e ausência de dados excedentes antes de reproduzir. O servidor também exige correspondência com o hash do decoder instalado.
CRC detecta corrupção acidental; não autentica autoria, não é DRM e não recupera setores danificados. O SHA-256 do arquivo inteiro serve como identificador. Não há correção de erros da mídia nesta versão.
Capacidade e reprodução
O orçamento padrão é 1.457.664 bytes: FAT12 de 2.880 setores de 512 bytes, reservando um setor de boot, duas FATs de nove setores e 14 setores de diretório raiz. É o espaço de dados de um disquete vazio nesse layout. A ocupação física do arquivo é arredondada para clusters de 512 bytes; arquivos preexistentes, outros layouts e setores defeituosos diminuem o espaço disponível.
O player local mantém o .ndisc comprimido em RAM e decodifica em blocos de até
990 ms; não exige reconstruir o álbum inteiro antes de iniciar. O transporte
para o navegador é PCM float32 little-endian intercalado L/R, 48 kHz. A fila de
áudio controlada pelo aplicativo antecipa aproximadamente três segundos, além
dos buffers de transporte e do navegador. Isso não estabelece o consumo de RAM
total nem o orçamento de um aparelho embarcado.
Não há busca temporal, reprodução sem intervalo entre faixas, capa, letras, correção de erros ou gravação física de disquetes nesta primeira versão.