WAV — efeitos sonoros e ligação dos bancos de som
Fonte: coreprime/kbot @ 0ab97bf · Editar no GitHub
Os efeitos sonoros do Total Annihilation (vozes das unidades, impactos das armas, cliques da interface) são ficheiros WAV PCM normais de 8 ou 16 bits: o contentor não tem nada de específico do TA. A parte interessante é a ligação: a forma como os FBI das unidades, os TDF das armas e a interface global encaminham nomes de ficheiro para o sistema de som, através de três camadas de indireção.
Tip
Experimente por si.
# Play one directly
ls $(kbot ctx path)/sounds/ | head
afplay $(kbot ctx path)/sounds/cmdsel1.wav # macOS
aplay $(kbot ctx path)/sounds/cmdsel1.wav # Linux
# The web UI also previews WAV/MP3 inline
kbot mount $(kbot ctx path) --server
No disco, é só WAV
Os ficheiros WAV estão em sounds/. Seguem o formato RIFF WAVE normal:
tudo o que reproduz WAV reproduz estes. O kbot não os analisa como um
formato próprio; o explorador entrega-os ao elemento <audio> do
navegador.
Codificação típica nos ficheiros distribuídos pela Cavedog:
| Propriedade | Valor |
|---|---|
| Frequência de amostragem | 22050 Hz (a maioria), 11025 Hz (alguns cliques da interface) |
| Profundidade de bits | PCM de 8 bits sem sinal |
| Canais | Mono |
| Duração | 0.1–3 segundos |
| Tamanho do ficheiro | 5 KB – 200 KB |
De vez em quando, há mods que trazem amostras estéreo de 16 bits; o motor aceita-as, mas gastam mais memória.
As três camadas da ligação
Descobrir "o que toca quando o Comandante ARM é selecionado" segue esta cadeia:
FBI gamedata/sound.tdf sounds/
┌─────────────┐ ┌───────────────────────┐ ┌──────────────┐
│ units/ │ │ [ARM_COM] │ │ cmdsel1.wav │
│ armcom.fbi │ │ { │ │ │
│ │ ──▶ │ select1=cmdsel1; │ ──▶│ │
│ Sound │ │ ok1=cmdok1; │ │ │
│ Category= │ │ ... │ │ │
│ ARM_COM; │ │ } │ │ │
└─────────────┘ └───────────────────────┘ └──────────────┘
1. FBI picks 2. sound.tdf maps 3. WAV file
a category event → filename on disk
Camada 1 — SoundCategory no FBI
O FBI de uma unidade indica uma categoria:
[UNITINFO]
{
UnitName=ARMCOM;
SoundCategory=ARM_COM; // ← points at [ARM_COM] in sound.tdf
...
}
As categorias são partilhadas entre unidades: todas as variantes do Comandante ARM, ou todos os Kbots ARM, apontam para a mesma categoria, para que as vozes de seleção se mantenham coerentes dentro de um lado.
Camada 2 — gamedata/sound.tdf
O TDF associa eventos do motor a nomes de ficheiros WAV dentro de uma categoria:
[ARM_COM]
{
select1=cmdsel1; // Selecting the unit
ok1=cmdok1; // Movement order acknowledged
arrived1=cmdarvd1; // Reached destination
cant1=cantdo4; // Order rejected ("I can't do that")
underattack=warning1; // Took damage
count5=count1; // Commander self-destruct countdown (5)
count0=count6; // …countdown (now)
canceldestruct=cancel2;
}
Repare no sufixo 1 na maioria dos nomes de eventos. Cada evento
pode ter uma família de escolhas: a chave simples (select) e as chaves
numeradas select1, select2, select3, …; o motor escolhe uma ao
acaso, para dar variedade. Com apenas select1 definida, toca sempre a
mesma fala.
O TA 3.1c lê, para cada evento, a chave simples, se existir, e depois
KEY1, KEY2, … até ao primeiro número em falta: com
select1=kbarmsel; select3=kbarmse2; só toca o kbarmsel, porque a
falta de select2 termina a lista. (A falta da chave simples não impede
as numeradas.) Um valor vazio é uma escolha silenciosa. As chaves que não
sejam um dos eventos indicados abaixo nunca são reproduzidas.
Camada 3 — sounds/<name>.wav
O valor no TDF é o nome base (sem a extensão .wav). O motor procura
sounds/<stem>.wav no sistema de ficheiros virtual.
Important
O sufixo .wav está implícito. Se escrever select1=cmdsel1.wav
no TDF, o motor tenta encontrar sounds/cmdsel1.wav.wav e, sem aviso,
não toca nada.
Chaves de eventos padrão
O TA 3.1c lê 23 eventos da categoria de som de uma unidade, cada um com a
chave simples mais a família numerada descrita acima (ok, ok1,
ok2, …):
| Evento | Quando é disparado |
|---|---|
select |
Unidade selecionada. |
underattack |
A unidade sofre dano. |
activate / deactivate |
Ligar/desligar (radar, bloqueador, fortificações). |
ok |
Ordem aceite. |
arrived |
A unidade conclui uma deslocação. |
cant |
Ordem rejeitada (terreno, fila de construção, etc.). |
unitcomplete |
A unidade acabou de ser construída. |
build |
O construtor começa a construir. |
repair |
O construtor começa a reparar. |
working |
O construtor está a reciclar/ressuscitar. |
load / unload |
O transporte recolhe / larga uma unidade. |
cloak / uncloak |
A unidade camufla-se / deixa de estar camuflada (os comandantes). |
capture |
O Comandante ou uma unidade capaz de capturar começa a capturar. |
count5 … count0 |
Ticks da contagem decrescente da autodestruição. |
canceldestruct |
Autodestruição cancelada. |
Cada chave pode ter uma entrada KEYtext correspondente (select1text)
com a legenda da fala. As outras chaves da categoria são ignoradas.
O visualizador de unidades e a sandbox do KBot Studio seguem as mesmas
regras: os metadados da unidade (/api/studio/unit/{name}) trazem
exatamente as chaves que o jogo reproduz para estes eventos, e cada
evento toca uma das suas chaves ao acaso.
Sons da interface — allsound.tdf
Os eventos da interface (cliques em botões, transições de menu, vinhetas
de fim de jogo) usam chaves da mesma forma, mas estão em secções ao
estilo de [GLOBAL_*] do gamedata/allsound.tdf:
[BIGBUTTON] { sound=butmain1; }
[SMLBUTTON] { sound=button1; }
[SKIRMISH] { sound=butnskir; }
[BGM] { sound=drone2; } // Background music ID
Estas secções são referidas pelo nome a partir dos ficheiros .gui dos
menus. Para mudar o som do clique do botão "Skirmish", basta editar este
TDF; não é preciso mexer em nenhum .gui.
Sons das armas
Os TDF das armas (TDF) têm diretamente as suas próprias chaves de som, sem camada de indireção:
[LIGHTLASER] {
...
soundstart=lasrmas1; // On fire
soundhit=lasrhit1; // On impact
soundwater=splshbig; // On water hit (overrides soundhit)
soundtrigger=1; // Play soundstart on each burst pulse, not just first
}
Aplica-se a mesma pesquisa em sounds/<stem>.wav. Os sons das armas são
afinados disparo a disparo: se mudar a arma de uma unidade, também vai
ter de reajustar os níveis de som no TDF da arma.
Exemplo comentado — acrescentar uma nova voz de seleção
Coloque um WAV novo em
sounds/(recomenda-se mono, 22050 Hz, 8 bits):mymod/sounds/cmdsel_grunt.wavAcrescente um novo evento em
gamedata/sound.tdf:[ARM_COM] { select1=cmdsel1; // Existing select2=cmdsel_grunt; // Your new line, randomly selected }Não é preciso mudar o FBI: a referência
SoundCategory=ARM_COMque já existe chega.Empacote e teste:
kbot hpi pack ./mymod --target mymod.ufo
O motor passa a alternar entre cmdsel1.wav e cmdsel_grunt.wav quando
o Comandante é selecionado.
Tamanhos típicos
| Recurso | Intervalo observado nos recursos da Cavedog |
|---|---|
| Fala de unidade | 5–60 KB |
| Impacto de arma | 5–30 KB |
| Explosão | 30–120 KB |
| Ciclo de música | 100 KB – 1 MB |
gamedata/sound.tdf |
~20 KB (mais de 300 categorias) |
gamedata/allsound.tdf |
~6 KB |
Armadilhas
Warning
Um WAV em falta fica em silêncio, não dá erro. Escreva
select1=cmsdel1 (com letras trocadas) e o motor simplesmente não toca
nada na seleção: nem mensagem no registo, nem alternativa. Teste sempre
no jogo os sons que alterou.
- A extensão
.wavestá implícita: nunca a escreva no valor do TDF. - A frequência de amostragem importa. Os sons reproduzidos fora de 8 kHz / 11.025 kHz / 22.05 kHz / 44.1 kHz podem engasgar-se nos caminhos de hardware da época do Windows 9x que alguns motores comerciais ainda usam. 22050 Hz mono é a escolha segura por omissão.
- Os WAV estéreo são convertidos para mono pelo motor. Não distribua estéreo, a não ser que tenha uma razão espacial concreta.
- MP3 em
sounds/: aqui, o motor ignora os MP3. O leitor de música tem um caminho de código à parte paramusic/*.mp3. - A Cavedog distribui alguns WAV com PCM de 16 bits e frequências de amostragem bizarras (por exemplo, 7000 Hz): continuam a funcionar, mas, se estiver a criar ferramentas que assumem 22050/8/mono, vai tropeçar neles.
Ver também
- TDF — o formato usado pelo
sound.tdf, peloallsound.tdfe pelos campos de som das armas. - Interface do TA: Kingdoms — os widgets
.guireferem eventos de som da interface. - Glossário — categoria de som.