# Sampled sound

Apache has no CD audio tracks on the discs in this collection. Its music and briefing speech are headerless, unsigned eight-bit PCM files. The six music recordings use interleaved stereo at **22,000 Hz**. The 327 briefing and campaign recordings use mono at the same rate. This is the literal rate passed by `start_music_`, `play_speech_` and the debriefing callers, not 22,050 Hz.

The main theme loops. Its first pass starts at the beginning; subsequent passes seek to byte `0x75600`, about 10.927 seconds into the stereo recording. The stream reader uses a 1 MiB circular buffer and 2,048-byte reads. Speech temporarily replaces the music stream, with routines to save and restore the music position.

## Sound banks

`SOUND/MAXIMAL.BLK` packs all 189 effects. Its first 32-bit word gives their combined payload size. Records then contain a signed 32-bit effect ID, an unsigned 32-bit byte length, and the PCM bytes. ID -1 ends the bank. `MINIMAL.BLK` has the same records without the total-size header; it contains 18 samples, byte-identical to their counterparts in the full bank.

The executable's `_effect` table has 189 entries of 40 bytes. Each holds the original source filename, playback rate, repeat flag, runtime buffer information and the minimal-effects flag. The samples are unsigned eight-bit mono. Rates include 6,000 Hz for radio chatter, 6,302 Hz for radio effects, 12,604 Hz for rotors and weapons, and 22,050 Hz for many cockpit voice calls. A `.RAW` filename alone does not reveal any of this.

The native check executes `initialise_sound_data_` and `load_minimal_sound_effects_`, replacing file access and the DirectSound allocation boundary. Every loaded PCM buffer and rate agrees with the independent bank decoder. Separate checks run `internal_create_sound_buffer_` through all four PCM format modes and inspect its actual WAVEFORMAT fields at the DirectSound call.

## Speech and movies

`build_speech_filename_` chooses the briefing and outcome recordings from the game mode, warzone, campaign level and mission slot. Campaign mission numbers are translated through `_campaign_mission_number`; they are not simply the mission IDs written into filenames. Training uses `ET` recordings. The briefing selection routine calls speech kind 10 for training, 6 for single missions and 3 for campaigns.

Campaign movies are selected by warzone and campaign level. Each warzone has eight movies. `load_campaign_mission_` plays the appropriate movie before opening the briefing screen and starting its speech. The movies themselves contain no audio.

The [usage map](usage.json) records filenames returned by the unchanged selection routine, their contexts and the campaign movie table. Kinds 7, 8 and 9 generate the EO, EP and EF outcome filename families; their entries are marked as selector results because callers for these three kinds have not been found. Contexts without a corresponding file are listed separately. The sound browser links campaign and training briefings to their missions.

## Extraction checks

The local browser uses maximum-compression FLAC copies. Each file is encoded with verification enabled, then decoded independently with FFmpeg and compared byte for byte with the source PCM. No resampling or normalisation is applied. See [the sample verification report](native-audio-check.json), [resource list](index.json) and `tools/audio.py`.

## Stream execution

The [stream check](native-stream-check.json) runs the original music-reader thread against an in-memory sample device. It honours the thread's requested sleep intervals and advances sample positions at their original PCM rates. A 270-second run matches 11,880,000 bytes of the theme, including its loop. Interrupting after 4.32 seconds with training speech preserves byte position 190,080 and resumes from exactly that byte. A standalone speech recording drains and stops without starting music.

The reader leaves roughly 128 KiB free after its initial fill. When a non-repeating file ends, it replaces the final incomplete 2 KiB block with five zero-filled blocks and drains the buffer. For `ET10____.RAW`, this discards the final 1,454 source bytes. This behaviour is in the reader itself. The FLAC extractions retain the complete source recording.

`music_fader_routine_` applies 64 volume steps with two-millisecond sleeps before ending the current sample. The stream test observes the fade commands; host mixing and resampling are separate device concerns.

## Effect channels and volume

The Windows backend has sixteen effect channels. `play_sound_effect_` takes the first free or finished channel and duplicates the source sample buffer. When all sixteen are playing, the request returns −1. Reusing a channel clears matching cockpit/radio ownership. The actual sample receives its original table rate, repeat flag and `master × requested_volume / 63`.

DirectSound volume is `clamp(1000 − 64000 / volume, −10000, 0)` in hundredths of a decibel, with zero mapped to −10000. This is a nonlinear gain curve. Although effect callers supply a pan argument, the Windows `play_sound_effect_sample_` does not call the pan setter; these mono samples therefore remain centred.

The [channel check](native-channels-check.json) covers 756 starts across all 189 effects, channel saturation and reuse, stopping all effects, 128 gain values and nine pan conversions through the actual backend routines.
