Audio

In short

There are no audio files. AudioSynth is a small DSP kit; SoundBank and BallparkOrgan build every clip once at boot. GameAudio listens to GameEvents and plays them, so gameplay code never calls audio. Outside the menu organ, every sound is a reaction to something on the field; the cutscenes and the live hit counter call GameAudio’s static one-liners directly.

How it works

  1. GameRoot adds GameAudio to [Game]. Its Awake builds a SoundBank, the organ loop, the “Charge!” fanfare and five clips of its own (intro impact, firework bang, sad trombone, counter tick, riser), and makes four AudioSources: music (loops, ignores listener pause), ball (the pitch whir), sfx (one-shots) and counter (the hit counter’s ticks, on their own source so changing their pitch never bends a cheer).
  2. The music source plays all the time at volume 0 and fades: on in menus, off in AtBat, CoopWatch, Intro and Outro.
  3. Each GameEvents event maps to sounds (table below).
  4. UI code calls static one-liners: GameAudio.Click, Coin, Shuffle, Buzz, LevelUp, Cheer, Groan, YourTurn. The cutscenes and the hit show have their own (table below).
  5. Pausing sets AudioListener.pause (GameAudio.SetPaused): the field goes silent, the organ keeps playing.

Event to sound

EventSound
StateChangedOrgan fades in (menus) or out (at bat, spectating); the ball whir stops.
PitchThrownSpecial-ball cue at the windup (pitch per effect; on a boss pitch the boss’s ball, PitchData.Primary), then the whir from release to the plate at the pitch’s speed, then a glove pop if nobody hit it.
SwingStartedWhoosh.
SwingResolvedContact: a crack by exit velocity (green crack on a green), a ping on solid contact, a small cheer on a green that grows with the streak. Whiff: an “ooh”.
HitLandedHome run: homer bell, a big or huge cheer, then “Charge!“. Foul: soft ooh. In play: groan.
CountChangedWood block on an out (plus a groan on a strikeout); a lighter, higher wood block on a strike.
RoundFinishedCleared: cheer and “Charge!“. Failed: groan (not for a co-op turn).
RunEndedHuge cheer on a win; a chime on a new best.
ScoreboardHitSmash: crunch, boom and tinkling glass (Scoreboard).

Direct calls (no event)

CallSoundCalled by
CrowdSwellSmall cheer at 0.55Match intro opening (Cutscenes)
WhooshThe whoosh at pitch 1.15Every slash wipe in the intro and outros
ImpactLow thump plus a dark noise burstA name slamming in (intro), outro titles; also under StackHit and CounterSlam
FanfareHuge cheer, then “Charge!” 0.3 s laterMAP BEATEN
FireworkBangFalling 90 to 28 Hz boom plus 26 crackle popsEach firework burst (Fireworks)
SadTromboneD4, C#4, C4, then a long wobbling B3GAME OVER
CounterTick(feet)A 30 ms blip that climbs a major scale, a step every 35 ft (pitch capped at 3), louder per heat tierHitCounter, every 10 ft (Hit Show)
CounterDing(tier)Chime, a little higher per tierDistance milestones
GoneHalf-second riser plus a small cheerThe ball clearing the wall
StackHit(step)Coin, pitch 1 + 0.14 per step, plus a soft impactEach multiplier joining the home-run score
CounterSlamImpact plus six quick coinsThe total landing in the score panel
CounterStampWood blockOUT / FOUL stamp

The clips

SoundBank builds: CrackSoft, CrackMedium, CrackHard, CrackGreen, Ping, HomerBell, PitchWhir, Whoosh, GlovePop, WoodBlock, Tick, Coin, Shuffle, Buzz, Chime, SpecialBall, CheerSmall, CheerBig, CheerHuge, Groan, Ooh, Smash. Crowd sounds are layered voices, not noise. There is no umpire voice: a wood block marks strikes and outs and the HUD shows the call.

GameAudio builds its own five clips in code with AudioSynth: IntroImpact, FireworkBang, SadTrombone, CountTick, Riser.

BallparkOrgan plays the public-domain “Take Me Out to the Ball Game” chorus as a 3/4 waltz from note tables, and builds the “Charge!” fanfare. The melody was transcribed from memory: a wrong note is a one-line fix in its table.

AudioSynth gives oscillators (Tone, Organ, Brass, Sweep, Voices, Noise), filters (LowPass, LowPassSweep, HighPass), envelopes (Envelope, ExpDecay), mixing (Mix, MixInto, Gain, Wobble, MakeLoop, Normalize, Clamp), NoteHz("C5") and ToClip.

Numbers

WhatValueWhere to tune
Sample rate44,100 Hz, monoAudioSynth.Rate
Organ tempo116 BPM, 3 beats per barBallparkOrgan.Bpm
Music fade0.7 sGameAudio.MusicFadeSeconds
Organ loudness at slider 10.5GameAudio.MusicBase
Whir loudness at slider 10.55GameAudio.WhirBase
Whir pitchspeedMph / 85, clamped 0.7 to 1.6ReferencePitchMph
Solid contact (ping)quality >= 0.55SolidContactQuality
Crack choicegreen: CrackGreen; < 78 mph soft; < 96 mph medium; else hardSoundBank.CrackFor
Huge cheerhome run of 450 ft or moreGameAudio.OnHitLanded
”Charge!” delay after the bell0.6 sChargeDelay
Special-ball cue pitch$$$ 1.25, Super Fast 1.1, Anti-Gravity 0.9, Ghost 0.75, Sticky 0.6, Wiffle 1.4, Headwind 0.8, Tailwind 1.2SpecialBallPitch
Counter tick scale step35 ft per scale degree, base pitch 0.55, max 3GameAudio.CounterTick
Default volumesmusic 0.6, sound 1GameSettings

In the code

FileWhat it does
Scripts/Audio/GameAudio.csSources, event handlers, UI, cutscene and counter one-liners, its own five clips, SetPaused.
Scripts/Audio/SoundBank.csBuilds and holds every effect clip; CrackFor.
Scripts/Audio/AudioSynth.csThe DSP kit.
Scripts/Audio/BallparkOrgan.csBuildLoop, BuildCharge.

Gotchas

README drift

The README’s tuning list says to assign a real clip to GreenFeedback.GreenClip. That field no longer exists: GreenFeedback only shakes the camera, and the green sound is CrackGreen plus the small cheer in GameAudio.

  • The whir and glove pop wait on game time (WaitForSeconds), so they follow the ball through hit stop and slow motion. Delayed one-shots use real time.
  • Volumes are read from GameRoot.Instance.Save.settings on every play, so the MUSIC and SOUND sliders apply live.
  • All clips are built in Awake, which adds a little to boot time.
  • The counter source keeps the last pitch it was given; every call through PlayCounter sets it first.