WAV: efeitos sonoros e ligação dos bancos de som
Fonte: coreprime/kbot @ 0ab97bf · Editar no GitHub
Os efeitos sonoros do Total Annihilation (amostras de voz das unidades, impactos de armas, cliques da interface) são arquivos WAV PCM comuns de 8 ou 16 bits: o contêiner não tem nada de específico do TA. A parte interessante é a ligação: como os FBIs das unidades, os TDFs das armas e a interface global encaminham nomes de arquivo para o barramento de som por meio de três camadas de indireção.
Tip
Experimente você mesmo.
# 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 arquivos WAV ficam em sounds/. Eles seguem o formato RIFF WAVE padrão:
qualquer coisa que toque WAV toca esses arquivos. O kbot não os analisa como
um formato próprio; o explorador os entrega ao elemento <audio> do
navegador.
Codificação típica dos arquivos lançados pela Cavedog:
| Propriedade | Valor |
|---|---|
| Taxa 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 arquivo | 5 KB – 200 KB |
Alguns mods trazem amostras estéreo de 16 bits; o motor as aceita, mas elas 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 dá o nome de uma categoria:
[UNITINFO]
{
UnitName=ARMCOM;
SoundCategory=ARM_COM; // ← points at [ARM_COM] in sound.tdf
...
}
As categorias são compartilhadas 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 fiquem coerentes dentro de um lado.
Camada 2: gamedata/sound.tdf
O TDF associa eventos do motor a nomes de arquivos 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 evento. Cada evento pode ter
uma família de opções: a chave simples (select) e as chaves numeradas
select1, select2, select3, …; o motor sorteia uma delas para variar.
Se só select1 estiver definida, a mesma fala toca todas as vezes.
Para cada evento, o TA 3.1c lê a chave simples, se existir, e depois KEY1,
KEY2, … até o primeiro número que faltar: com
select1=kbarmsel; select3=kbarmse2; só kbarmsel toca, porque a ausência
de select2 encerra a lista. (A falta da chave simples não impede as
numeradas.) Um valor vazio é uma opção silenciosa. As chaves que não são
nenhum dos eventos abaixo nunca tocam.
Camada 3: sounds/<name>.wav
O valor no TDF é o radical do nome (sem a extensão .wav). O motor
procura sounds/<stem>.wav no sistema de arquivos virtual.
Important
O sufixo .wav fica implícito. Se você escrever select1=cmdsel1.wav
no TDF, o motor vai procurar sounds/cmdsel1.wav.wav e, sem avisar, não
vai tocar nada.
Chaves de evento padrão
O TA 3.1c lê 23 eventos da categoria de som de uma unidade, cada um como a
chave simples mais a família numerada descrita acima (ok, ok1, ok2, …):
| Evento | Quando dispara |
|---|---|
select |
A unidade é selecionada. |
underattack |
A unidade sofre dano. |
activate / deactivate |
Liga/desliga (radar, bloqueador, fortificações). |
ok |
Ordem aceita. |
arrived |
A unidade termina um movimento. |
cant |
Ordem recusada (terreno, fila de construção etc.). |
unitcomplete |
A unidade termina de ser construída. |
build |
O construtor começa a construir. |
repair |
O construtor começa a reparar. |
working |
O construtor está reciclando/ressuscitando. |
load / unload |
O transporte pega / larga uma unidade. |
cloak / uncloak |
A unidade se camufla / deixa a camuflagem (os Comandantes). |
capture |
O Comandante ou uma unidade capaz de capturar começa a capturar. |
count5 … count0 |
Passos da contagem regressiva da autodestruição. |
canceldestruct |
Autodestruição cancelada. |
Cada chave pode ter uma entrada KEYtext correspondente (select1text) com
a legenda da fala. As demais 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 toca para esses eventos, e cada evento toca uma das suas
chaves sorteada.
Sons da interface: allsound.tdf
Os eventos da interface (cliques de botões, transições de menu, vinhetas de
fim de partida) usam chaves do mesmo jeito, mas ficam em seções no estilo
[GLOBAL_*] de gamedata/allsound.tdf:
[BIGBUTTON] { sound=butmain1; }
[SMLBUTTON] { sound=button1; }
[SKIRMISH] { sound=butnskir; }
[BGM] { sound=drone2; } // Background music ID
Essas seções são referenciadas pelo nome nos arquivos .gui dos menus. Para
trocar o som do clique do botão "Skirmish", basta editar este TDF, sem mexer
em nenhum .gui.
Sons das armas
Os TDFs das armas (TDF) trazem suas próprias chaves de som diretamente, 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
}
Vale a mesma busca em sounds/<stem>.wav. Os sons das armas são ajustados
por disparo: se você trocar a arma de uma unidade, vai precisar reajustar
também 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 basta.Empacote e teste:
kbot hpi pack ./mymod --target mymod.ufo
Agora o motor alterna entre cmdsel1.wav e cmdsel_grunt.wav quando o
Comandante é selecionado.
Tamanhos típicos
| Recurso | Faixa observada nos recursos da Cavedog |
|---|---|
| Fala de unidade | 5–60 KB |
| Impacto de arma | 5–30 KB |
| Explosão | 30–120 KB |
| Música em loop | 100 KB – 1 MB |
gamedata/sound.tdf |
~20 KB (mais de 300 categorias) |
gamedata/allsound.tdf |
~6 KB |
Armadilhas
Warning
Um WAV ausente é silêncio, não erro. Escreva errado select1=cmsdel1
(letras trocadas) e o motor simplesmente não toca nada na seleção: nenhuma
mensagem no log, nenhuma alternativa. Teste sempre no jogo os sons que você
mudou.
- A extensão
.wavfica implícita: nunca a escreva no valor do TDF. - A taxa de amostragem importa. Sons tocados fora de 8 kHz / 11,025 kHz / 22,05 kHz / 44,1 kHz podem engasgar nos caminhos de hardware da época do Windows 9x que alguns motores comerciais ainda usam. 22050 Hz mono é o padrão seguro.
- O motor mistura os WAVs estéreo para mono. Não use estéreo, a não ser que haja um motivo espacial específico.
- MP3 em
sounds/: o motor ignora MP3s aqui. O reprodutor de música tem um caminho de código separado paramusic/*.mp3. - A Cavedog lança alguns WAVs em PCM de 16 bits e com taxas de amostragem estranhas (por exemplo, 7000 Hz): eles funcionam, mas se você estiver criando ferramentas que presumem 22050/8/mono, vai tropeçar neles.
Veja também
- TDF: o formato usado por
sound.tdf,allsound.tdfe pelos campos de som das armas. - Interface do TA: Kingdoms: os widgets
.guireferenciam eventos de som da interface. - Glossário: categoria de som.