diff options
| author | claude-bot <[email protected]> | 2026-07-13 12:27:07 +0000 |
|---|---|---|
| committer | claude-bot <[email protected]> | 2026-07-13 12:27:07 +0000 |
| commit | 9f61c9e6ac6b1ac5692cf6352d2ebbd47a31a686 (patch) | |
| tree | a84756b82513739a2672db3a1f0ec579db6d18ff /src/audio | |
| download | re3-9f61c9e6ac6b1ac5692cf6352d2ebbd47a31a686.tar.gz re3-9f61c9e6ac6b1ac5692cf6352d2ebbd47a31a686.zip | |
Snapshot import (no upstream history) into git.ancap.in.ua/claude, per @lzcnt.
Source: https://github.com/Cai1Hsu/re3 branch miami.
Diffstat (limited to 'src/audio')
31 files changed, 28409 insertions, 0 deletions
diff --git a/src/audio/AudioCollision.cpp b/src/audio/AudioCollision.cpp new file mode 100644 index 0000000..250cd18 --- /dev/null +++ b/src/audio/AudioCollision.cpp @@ -0,0 +1,429 @@ +#include "common.h" + +#include "DMAudio.h" +#include "Entity.h" +#include "AudioCollision.h" +#include "AudioManager.h" +#include "AudioSamples.h" +#include "SurfaceTable.h" +#include "sampman.h" + +const int CollisionSoundIntensity = 60; + +cAudioCollisionManager::cAudioCollisionManager() +{ + m_sQueue.m_pEntity1 = nil; + m_sQueue.m_pEntity2 = nil; + m_sQueue.m_bSurface1 = SURFACE_DEFAULT; + m_sQueue.m_bSurface2 = SURFACE_DEFAULT; + m_sQueue.m_fIntensity2 = 0.0f; + m_sQueue.m_fIntensity1 = 0.0f; + m_sQueue.m_vecPosition = CVector(0.0f, 0.0f, 0.0f); + + for (int i = 0; i < NUMAUDIOCOLLISIONS; i++) + m_bIndicesTable[i] = NUMAUDIOCOLLISIONS; + + m_bCollisionsInQueue = 0; +} + +void +cAudioCollisionManager::AddCollisionToRequestedQueue() +{ + int32 collisionsIndex; + int32 i; + + + if (m_bCollisionsInQueue < NUMAUDIOCOLLISIONS) + collisionsIndex = m_bCollisionsInQueue++; + else { + collisionsIndex = m_bIndicesTable[NUMAUDIOCOLLISIONS - 1]; + if (m_sQueue.m_fDistance >= m_asCollisions1[collisionsIndex].m_fDistance) return; + } + + m_asCollisions1[collisionsIndex] = m_sQueue; + + i = 0; + if(collisionsIndex) { + while(m_asCollisions1[m_bIndicesTable[i]].m_fDistance <= m_asCollisions1[collisionsIndex].m_fDistance) { + if(++i >= collisionsIndex) { + m_bIndicesTable[i] = collisionsIndex; + return; + } + } + memmove(&m_bIndicesTable[i + 1], &m_bIndicesTable[i], NUMAUDIOCOLLISIONS - 1 - i); + } + m_bIndicesTable[i] = collisionsIndex; +} + +float +cAudioManager::GetCollisionLoopingRatio(uint32 a, uint32 b, float c) const +{ + return GetCollisionRatio(c, 0.0f, 0.02f, 0.02f); +} + +float +cAudioManager::GetCollisionOneShotRatio(int32 a, float b) const +{ + float result; + + switch(a) { + case SURFACE_DEFAULT: + case SURFACE_TARMAC: + case SURFACE_PAVEMENT: + case SURFACE_STEEP_CLIFF: + case SURFACE_TRANSPARENT_STONE: + case SURFACE_CONCRETE_BEACH: result = GetCollisionRatio(b, 10.f, 60.f, 50.f); break; + case SURFACE_GRASS: + case SURFACE_GRAVEL: + case SURFACE_MUD_DRY: + case SURFACE_CARDBOARDBOX: result = GetCollisionRatio(b, 0.f, 2.f, 2.f); break; + case SURFACE_CAR: result = GetCollisionRatio(b, 6.f, 50.f, 44.f); break; + case SURFACE_GLASS: + case SURFACE_METAL_CHAIN_FENCE: result = GetCollisionRatio(b, 0.1f, 10.f, 9.9f); break; + case SURFACE_TRANSPARENT_CLOTH: + case SURFACE_THICK_METAL_PLATE: result = GetCollisionRatio(b, 30.f, 130.f, 100.f); break; + case SURFACE_GARAGE_DOOR: result = GetCollisionRatio(b, 20.f, 100.f, 80.f); break; + case SURFACE_CAR_PANEL: result = GetCollisionRatio(b, 0.f, 4.f, 4.f); break; + case SURFACE_SCAFFOLD_POLE: + case SURFACE_METAL_GATE: + case SURFACE_LAMP_POST: result = GetCollisionRatio(b, 1.f, 10.f, 9.f); break; + case SURFACE_FIRE_HYDRANT: result = GetCollisionRatio(b, 1.f, 15.f, 14.f); break; + case SURFACE_GIRDER: result = GetCollisionRatio(b, 8.f, 50.f, 42.f); break; + case SURFACE_PED: result = GetCollisionRatio(b, 0.f, 20.f, 20.f); break; + case SURFACE_SAND: + case SURFACE_WATER: + case SURFACE_RUBBER: + case SURFACE_WHEELBASE: + case SURFACE_SAND_BEACH: result = GetCollisionRatio(b, 0.f, 10.f, 10.f); break; + case SURFACE_WOOD_CRATES: result = GetCollisionRatio(b, 1.f, 4.f, 3.f); break; + case SURFACE_WOOD_BENCH: result = GetCollisionRatio(b, 0.1f, 5.f, 4.9f); break; + case SURFACE_WOOD_SOLID: result = GetCollisionRatio(b, 0.1f, 40.f, 39.9f); break; + case SURFACE_PLASTIC: result = GetCollisionRatio(b, 0.1f, 4.f, 3.9f); break; + case SURFACE_HEDGE: result = GetCollisionRatio(b, 0.f, 0.5f, 0.5f); break; + case SURFACE_CONTAINER: result = GetCollisionRatio(b, 4.f, 40.f, 36.f); break; + case SURFACE_NEWS_VENDOR: result = GetCollisionRatio(b, 0.f, 5.f, 5.f); break; + default: result = 0.f; break; + } + + return result; +} + +float +cAudioManager::GetCollisionRatio(float a, float b, float c, float d) const +{ + float e; + e = a; + if(a <= b) return 0.0f; + if(c <= a) e = c; + return (e - b) / d; +} + +uint32 +cAudioManager::SetLoopingCollisionRequestedSfxFreqAndGetVol(const cAudioCollision &audioCollision) +{ + uint8 surface1 = audioCollision.m_bSurface1; + uint8 surface2 = audioCollision.m_bSurface2; + int32 vol; + float ratio; + + if(surface1 == SURFACE_GRASS || surface2 == SURFACE_GRASS || surface1 == SURFACE_HEDGE || + surface2 == SURFACE_HEDGE) { + ratio = GetCollisionRatio(audioCollision.m_fIntensity2, 0.0001f, 0.09f, 0.0899f); + m_sQueueSample.m_nSampleIndex = SFX_RAIN; + m_sQueueSample.m_nFrequency = 13000.f * ratio + 35000; + vol = 50.f * ratio; + } else if(surface1 == SURFACE_WATER || surface2 == SURFACE_WATER) { + ratio = GetCollisionRatio(audioCollision.m_fIntensity2, 0.0001f, 0.09f, 0.0899f); + m_sQueueSample.m_nSampleIndex = SFX_BOAT_WATER_LOOP; + m_sQueueSample.m_nFrequency = 6050.f * ratio + 16000; + vol = 30.f * ratio; + } else if(surface1 == SURFACE_GRAVEL || surface2 == SURFACE_GRAVEL || surface1 == SURFACE_MUD_DRY || surface2 == SURFACE_MUD_DRY || + surface1 == SURFACE_SAND || surface2 == SURFACE_SAND || surface1 == SURFACE_SAND_BEACH || surface2 == SURFACE_SAND_BEACH) { + ratio = GetCollisionRatio(audioCollision.m_fIntensity2, 0.0001f, 0.09f, 0.0899f); + m_sQueueSample.m_nSampleIndex = SFX_GRAVEL_SKID; + m_sQueueSample.m_nFrequency = 6000.f * ratio + 10000; + vol = 50.f * ratio; + } else if(surface1 == SURFACE_PED || surface2 == SURFACE_PED) { + return 0; + } else { + ratio = GetCollisionRatio(audioCollision.m_fIntensity2, 0.0001f, 0.09f, 0.0899f); + m_sQueueSample.m_nSampleIndex = SFX_SCRAPE_CAR_1; + m_sQueueSample.m_nFrequency = 10000.f * ratio + 10000; + vol = 40.f * ratio; + } + if(audioCollision.m_nBaseVolume < 2) vol = audioCollision.m_nBaseVolume * vol / 2; + return vol; +} + +void +cAudioManager::SetUpLoopingCollisionSound(const cAudioCollision &col, uint8 counter) +{ + bool distCalculated = false; + if(col.m_fIntensity2 > 0.0016f) { + uint8 emittingVol = SetLoopingCollisionRequestedSfxFreqAndGetVol(col); + if(emittingVol) { + CalculateDistance(distCalculated, m_sQueueSample.m_fDistance); + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, CollisionSoundIntensity, m_sQueueSample.m_fDistance); + if(m_sQueueSample.m_nVolume) { + m_sQueueSample.m_nCounter = counter; + m_sQueueSample.m_vecPos = col.m_vecPosition; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 7; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_nLoopStart = + SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = + SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 4.0f; + m_sQueueSample.m_fSoundIntensity = CollisionSoundIntensity; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 5; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + } +} +static const int32 gOneShotCol[] = {SFX_COL_TARMAC_1, + SFX_COL_TARMAC_1, + SFX_COL_GRASS_1, + SFX_COL_GRAVEL_1, + SFX_COL_MUD_1, + SFX_COL_TARMAC_1, + SFX_COL_CAR_1, + SFX_COL_GRASS_1, + SFX_COL_SCAFFOLD_POLE_1, + SFX_COL_GARAGE_DOOR_1, + SFX_COL_CAR_PANEL_1, + SFX_COL_THICK_METAL_PLATE_1, + SFX_COL_SCAFFOLD_POLE_1, + SFX_COL_LAMP_POST_1, + SFX_COL_HYDRANT_1, + SFX_COL_HYDRANT_1, + SFX_COL_METAL_CHAIN_FENCE_1, + SFX_COL_PED_1, + SFX_COL_SAND_1, + SFX_SPLASH_1, + SFX_COL_WOOD_CRATES_1, + SFX_COL_WOOD_BENCH_1, + SFX_COL_WOOD_SOLID_1, + SFX_COL_GRASS_1, + SFX_COL_GRASS_1, + SFX_COL_VEG_1, + SFX_COL_TARMAC_1, + SFX_COL_CONTAINER_1, + SFX_COL_NEWS_VENDOR_1, + SFX_TYRE_BUMP, + SFX_COL_CARDBOARD_1, + SFX_COL_TARMAC_1, + SFX_COL_GATE, + SFX_COL_SAND_1, + SFX_COL_TARMAC_1 }; + +void +cAudioManager::SetUpOneShotCollisionSound(const cAudioCollision &col) +{ + + int16 s1; + int16 s2; + + int32 emittingVol; + float ratio; + + static uint16 counter = 28; + + for(int32 i = 0; i < 2; i++) { + if(i) { + s1 = col.m_bSurface2; + s2 = col.m_bSurface1; + } else { + s1 = col.m_bSurface1; + s2 = col.m_bSurface2; + } + ratio = GetCollisionOneShotRatio(s1, col.m_fIntensity1); + if(s1 == SURFACE_CAR && s2 == SURFACE_PED) ratio /= 4.0f; + if(s1 == SURFACE_CAR && ratio < 0.6f) { + s1 = SURFACE_CAR_PANEL; + ratio = Min(1.f, 2.f * ratio); + } + emittingVol = 40.f * ratio; + if(emittingVol) { + m_sQueueSample.m_fDistance = Sqrt(col.m_fDistance); + m_sQueueSample.m_nVolume = + ComputeVolume(emittingVol, CollisionSoundIntensity, m_sQueueSample.m_fDistance); + if(m_sQueueSample.m_nVolume) { + m_sQueueSample.m_nSampleIndex = gOneShotCol[s1]; + switch(m_sQueueSample.m_nSampleIndex) { + case SFX_COL_TARMAC_1: + m_sQueueSample.m_nSampleIndex += m_anRandomTable[3] % 5; + break; + case SFX_COL_CAR_PANEL_1: + m_sQueueSample.m_nSampleIndex += m_anRandomTable[0] % 6; + break; + case SFX_COL_LAMP_POST_1: + m_sQueueSample.m_nSampleIndex += m_anRandomTable[1] % 2; + break; + case SFX_COL_METAL_CHAIN_FENCE_1: + m_sQueueSample.m_nSampleIndex += m_anRandomTable[3] % 4; + break; + case SFX_COL_PED_1: + m_sQueueSample.m_nSampleIndex += m_anRandomTable[4] % 2; + break; + case SFX_COL_WOOD_CRATES_1: + m_sQueueSample.m_nSampleIndex += m_anRandomTable[4] % 4; + break; + case SFX_COL_WOOD_BENCH_1: + m_sQueueSample.m_nSampleIndex += m_anRandomTable[1] % 4; + break; + case SFX_COL_VEG_1: + m_sQueueSample.m_nSampleIndex += m_anRandomTable[2] % 5; + break; + case SFX_COL_NEWS_VENDOR_1: + m_sQueueSample.m_nSampleIndex += m_anRandomTable[2] % 3; + break; + case SFX_COL_CAR_1: + m_sQueueSample.m_nSampleIndex += m_anRandomTable[1] % 5; + break; + case SFX_COL_CARDBOARD_1: + m_sQueueSample.m_nSampleIndex += m_anRandomTable[3] % 2; + break; + default: break; + } + switch(s1) { + case SURFACE_GLASS: m_sQueueSample.m_nFrequency = 13500; break; + case SURFACE_GIRDER: m_sQueueSample.m_nFrequency = 8819; break; + case SURFACE_WATER: + m_sQueueSample.m_nFrequency = + 2 * SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + break; + case SURFACE_RUBBER: m_sQueueSample.m_nFrequency = 6000; break; + case SURFACE_PLASTIC: m_sQueueSample.m_nFrequency = 8000; break; + default: + m_sQueueSample.m_nFrequency = + SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + break; + } + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16); + m_sQueueSample.m_nCounter = counter++; + if(counter >= 255) counter = 28; + m_sQueueSample.m_vecPos = col.m_vecPosition; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 11; + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_fSpeedMultiplier = 4.0f; + m_sQueueSample.m_fSoundIntensity = CollisionSoundIntensity; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + } +} + +void +cAudioManager::ServiceCollisions() +{ + int i, j; + bool abRepeatedCollision1[NUMAUDIOCOLLISIONS]; + bool abRepeatedCollision2[NUMAUDIOCOLLISIONS]; + + m_sQueueSample.m_nEntityIndex = m_nCollisionEntity; + + for (int i = 0; i < NUMAUDIOCOLLISIONS; i++) + abRepeatedCollision1[i] = abRepeatedCollision2[i] = false; + + for (i = 0; i < m_sCollisionManager.m_bCollisionsInQueue; i++) { + for (j = 0; j < NUMAUDIOCOLLISIONS; j++) { + int index = m_sCollisionManager.m_bIndicesTable[i]; + if ((m_sCollisionManager.m_asCollisions1[index].m_pEntity1 == m_sCollisionManager.m_asCollisions2[j].m_pEntity1) + && (m_sCollisionManager.m_asCollisions1[index].m_pEntity2 == m_sCollisionManager.m_asCollisions2[j].m_pEntity2) + && (m_sCollisionManager.m_asCollisions1[index].m_bSurface1 == m_sCollisionManager.m_asCollisions2[j].m_bSurface1) + && (m_sCollisionManager.m_asCollisions1[index].m_bSurface2 == m_sCollisionManager.m_asCollisions2[j].m_bSurface2) + ) { + abRepeatedCollision1[index] = true; + abRepeatedCollision2[j] = true; + m_sCollisionManager.m_asCollisions1[index].m_nBaseVolume = ++m_sCollisionManager.m_asCollisions2[j].m_nBaseVolume; + SetUpLoopingCollisionSound(m_sCollisionManager.m_asCollisions1[index], j); + break; + } + } + } + + for (i = 0; i < NUMAUDIOCOLLISIONS; i++) { + if (!abRepeatedCollision2[i]) { + m_sCollisionManager.m_asCollisions2[i].m_pEntity1 = nil; + m_sCollisionManager.m_asCollisions2[i].m_pEntity2 = nil; + m_sCollisionManager.m_asCollisions2[i].m_bSurface1 = SURFACE_DEFAULT; + m_sCollisionManager.m_asCollisions2[i].m_bSurface2 = SURFACE_DEFAULT; + m_sCollisionManager.m_asCollisions2[i].m_fIntensity2 = 0.0f; + m_sCollisionManager.m_asCollisions2[i].m_fIntensity1 = 0.0f; + m_sCollisionManager.m_asCollisions2[i].m_vecPosition = CVector(0.0f, 0.0f, 0.0f); + m_sCollisionManager.m_asCollisions2[i].m_fDistance = 0.0f; + } + } + + for (i = 0; i < m_sCollisionManager.m_bCollisionsInQueue; i++) { + int index = m_sCollisionManager.m_bIndicesTable[i]; + if (!abRepeatedCollision1[index]) { + for (j = 0; j < NUMAUDIOCOLLISIONS; j++) { + if (!abRepeatedCollision2[j]) { + m_sCollisionManager.m_asCollisions2[j].m_nBaseVolume = 1; + m_sCollisionManager.m_asCollisions2[j].m_pEntity1 = m_sCollisionManager.m_asCollisions1[index].m_pEntity1; + m_sCollisionManager.m_asCollisions2[j].m_pEntity2 = m_sCollisionManager.m_asCollisions1[index].m_pEntity2; + m_sCollisionManager.m_asCollisions2[j].m_bSurface1 = m_sCollisionManager.m_asCollisions1[index].m_bSurface1; + m_sCollisionManager.m_asCollisions2[j].m_bSurface2 = m_sCollisionManager.m_asCollisions1[index].m_bSurface2; + break; + } + } + SetUpOneShotCollisionSound(m_sCollisionManager.m_asCollisions1[index]); + SetUpLoopingCollisionSound(m_sCollisionManager.m_asCollisions1[index], j); + } + } + + for (int i = 0; i < NUMAUDIOCOLLISIONS; i++) + m_sCollisionManager.m_bIndicesTable[i] = NUMAUDIOCOLLISIONS; + m_sCollisionManager.m_bCollisionsInQueue = 0; +} + +void +cAudioManager::ReportCollision(CEntity *entity1, CEntity *entity2, uint8 surface1, uint8 surface2, float collisionPower, + float velocity) +{ + float distSquared; + CVector v1; + CVector v2; + + if(!m_bIsInitialised || m_nCollisionEntity < 0 || m_nUserPause || + (velocity < 0.0016f && collisionPower < 0.01f)) + return; + + if(entity1->IsBuilding()) { + v1 = v2 = entity2->GetPosition(); + } else if(entity2->IsBuilding()) { + v1 = v2 = entity1->GetPosition(); + } else { + v1 = entity1->GetPosition(); + v2 = entity2->GetPosition(); + } + CVector pos = (v1 + v2) * 0.5f; + distSquared = GetDistanceSquared(pos); + if(distSquared < SQR(CollisionSoundIntensity)) { + m_sCollisionManager.m_sQueue.m_pEntity1 = entity1; + m_sCollisionManager.m_sQueue.m_pEntity2 = entity2; + m_sCollisionManager.m_sQueue.m_bSurface1 = surface1; + m_sCollisionManager.m_sQueue.m_bSurface2 = surface2; + m_sCollisionManager.m_sQueue.m_fIntensity1 = collisionPower; + m_sCollisionManager.m_sQueue.m_fIntensity2 = velocity; + m_sCollisionManager.m_sQueue.m_vecPosition = pos; + m_sCollisionManager.m_sQueue.m_fDistance = distSquared; + m_sCollisionManager.AddCollisionToRequestedQueue(); + } +} diff --git a/src/audio/AudioCollision.h b/src/audio/AudioCollision.h new file mode 100644 index 0000000..a00b16d --- /dev/null +++ b/src/audio/AudioCollision.h @@ -0,0 +1,38 @@ +#pragma once + +#define NUMAUDIOCOLLISIONS 10 + +class CEntity; + +class cAudioCollision +{ +public: + CEntity *m_pEntity1; + CEntity *m_pEntity2; + uint8 m_bSurface1; + uint8 m_bSurface2; + float m_fIntensity1; + float m_fIntensity2; + CVector m_vecPosition; + float m_fDistance; + int32 m_nBaseVolume; + + // no methods +}; + +VALIDATE_SIZE(cAudioCollision, 40); + +class cAudioCollisionManager +{ +public: + cAudioCollision m_asCollisions1[NUMAUDIOCOLLISIONS]; + cAudioCollision m_asCollisions2[NUMAUDIOCOLLISIONS]; + uint8 m_bIndicesTable[NUMAUDIOCOLLISIONS]; + uint8 m_bCollisionsInQueue; + cAudioCollision m_sQueue; + + cAudioCollisionManager(); + void AddCollisionToRequestedQueue(); +}; + +VALIDATE_SIZE(cAudioCollisionManager, 0x354); diff --git a/src/audio/AudioLogic.cpp b/src/audio/AudioLogic.cpp new file mode 100644 index 0000000..7469f57 --- /dev/null +++ b/src/audio/AudioLogic.cpp @@ -0,0 +1,10070 @@ +#include "common.h" + +#include "AudioManager.h" +#include "audio_enums.h" + +#include "Automobile.h" +#include "Boat.h" +#include "Bridge.h" +#include "Camera.h" +#include "Cranes.h" +#include "DMAudio.h" +#include "Entity.h" +#include "Explosion.h" +#include "Fire.h" +#include "Garages.h" +#include "General.h" +#include "HandlingMgr.h" +#include "Heli.h" +#include "ModelIndices.h" +#include "MusicManager.h" +#include "Pad.h" +#include "Ped.h" +#include "Physical.h" +#include "Placeable.h" +#include "Plane.h" +#include "PlayerPed.h" +#include "Pools.h" +#include "Projectile.h" +#include "ProjectileInfo.h" +#include "Replay.h" +#include "Stats.h" +#include "SurfaceTable.h" +#include "Train.h" +#include "Transmission.h" +#include "Vehicle.h" +#include "WaterCannon.h" +#include "Weather.h" +#include "ZoneCull.h" +#include "sampman.h" +#include "Bike.h" +#include "WindModifiers.h" +#include "Fluff.h" +#include "Script.h" +#include "Wanted.h" + +const int channels = ARRAY_SIZE(AudioManager.m_asActiveSamples); +const int policeChannel = channels + 1; +const int allChannels = channels + 2; + +enum PLAY_STATUS { PLAY_STATUS_STOPPED = 0, PLAY_STATUS_PLAYING, PLAY_STATUS_FINISHED }; +enum LOADING_STATUS { LOADING_STATUS_NOT_LOADED = 0, LOADING_STATUS_LOADED, LOADING_STATUS_FAILED }; + +void +cAudioManager::PreInitialiseGameSpecificSetup() const +{ + BankStartOffset[SFX_BANK_0] = SAMPLEBANK_START; +#ifdef GTA_PS2 + BankStartOffset[SAMPLEBANK_CAR_PACARD] = SFX_CAR_ACCEL_1; + BankStartOffset[SAMPLEBANK_CAR_PATHFINDER] = SFX_CAR_ACCEL_2; + BankStartOffset[SAMPLEBANK_CAR_PORSCHE] = SFX_CAR_ACCEL_3; + BankStartOffset[SAMPLEBANK_CAR_SPIDER] = SFX_CAR_ACCEL_4; + BankStartOffset[SAMPLEBANK_CAR_MERC] = SFX_CAR_ACCEL_5; + BankStartOffset[SAMPLEBANK_CAR_MACKTRUCK] = SFX_CAR_ACCEL_6; + BankStartOffset[SAMPLEBANK_CAR_HOTROD] = SFX_CAR_ACCEL_7; + BankStartOffset[SAMPLEBANK_CAR_COBRA] = SFX_CAR_ACCEL_8; + BankStartOffset[SAMPLEBANK_CAR_NONE] = SFX_CAR_ACCEL_9; + BankStartOffset[SAMPLEBANK_FRONTEND] = SFX_PAGE_CHANGE_AND_BACK_LEFT; + BankStartOffset[SAMPLEBANK_TRAIN] = SFX_TRAIN_STATION_AMBIENCE_LOOP; + BankStartOffset[SAMPLEBANK_BUILDING_CLUB_1] = SFX_CLUB_1; + BankStartOffset[SAMPLEBANK_BUILDING_CLUB_2] = SFX_CLUB_2; + BankStartOffset[SAMPLEBANK_BUILDING_CLUB_3] = SFX_CLUB_3; + BankStartOffset[SAMPLEBANK_BUILDING_CLUB_4] = SFX_CLUB_4; + BankStartOffset[SAMPLEBANK_BUILDING_CLUB_5] = SFX_CLUB_5; + BankStartOffset[SAMPLEBANK_BUILDING_CLUB_6] = SFX_CLUB_6; + BankStartOffset[SAMPLEBANK_BUILDING_CLUB_7] = SFX_CLUB_7; + BankStartOffset[SAMPLEBANK_BUILDING_CLUB_8] = SFX_CLUB_8; + BankStartOffset[SAMPLEBANK_BUILDING_CLUB_9] = SFX_CLUB_9; + BankStartOffset[SAMPLEBANK_BUILDING_CLUB_10] = SFX_CLUB_10; + BankStartOffset[SAMPLEBANK_BUILDING_CLUB_11] = SFX_CLUB_11; + BankStartOffset[SAMPLEBANK_BUILDING_CLUB_12] = SFX_CLUB_12; + BankStartOffset[SAMPLEBANK_BUILDING_CLUB_RAGGA] = SFX_CLUB_RAGGA; + BankStartOffset[SAMPLEBANK_BUILDING_STRIP_CLUB_1] = SFX_STRIP_CLUB_1; + BankStartOffset[SAMPLEBANK_BUILDING_STRIP_CLUB_2] = SFX_STRIP_CLUB_2; + BankStartOffset[SAMPLEBANK_BUILDING_WORKSHOP] = SFX_WORKSHOP_1; + BankStartOffset[SAMPLEBANK_BUILDING_PIANO_BAR] = SFX_PIANO_BAR_1; + BankStartOffset[SAMPLEBANK_BUILDING_SAWMILL] = SFX_SAWMILL_LOOP; + BankStartOffset[SAMPLEBANK_BUILDING_DOG_FOOD_FACTORY] = SFX_DOG_FOOD_FACTORY; + BankStartOffset[SAMPLEBANK_BUILDING_LAUNDERETTE] = SFX_LAUNDERETTE_LOOP; + BankStartOffset[SAMPLEBANK_BUILDING_RESTAURANT_CHINATOWN] = SFX_RESTAURANT_CHINATOWN; + BankStartOffset[SAMPLEBANK_BUILDING_RESTAURANT_ITALY] = SFX_RESTAURANT_ITALY; + BankStartOffset[SAMPLEBANK_BUILDING_RESTAURANT_GENERIC_1] = SFX_RESTAURANT_GENERIC_1; + BankStartOffset[SAMPLEBANK_BUILDING_RESTAURANT_GENERIC_2] = SFX_RESTAURANT_GENERIC_2; + BankStartOffset[SAMPLEBANK_BUILDING_AIRPORT] = SFX_AIRPORT_ANNOUNCEMENT_1; + BankStartOffset[SAMPLEBANK_BUILDING_SHOP] = SFX_SHOP_LOOP; + BankStartOffset[SAMPLEBANK_BUILDING_CINEMA] = SFX_CINEMA_BASS_1; + BankStartOffset[SAMPLEBANK_BUILDING_DOCKS] = SFX_DOCKS_FOGHORN; + BankStartOffset[SAMPLEBANK_BUILDING_HOME] = SFX_HOME_1; + BankStartOffset[SAMPLEBANK_BUILDING_PORN_1] = SFX_PORN_1_LOOP; + BankStartOffset[SAMPLEBANK_BUILDING_PORN_2] = SFX_PORN_2_LOOP; + BankStartOffset[SAMPLEBANK_BUILDING_PORN_3] = SFX_PORN_3_LOOP; + BankStartOffset[SAMPLEBANK_BUILDING_POLICE_BALL] = SFX_POLICE_BALL_1; + BankStartOffset[SAMPLEBANK_BUILDING_BANK_ALARM] = SFX_BANK_ALARM_1; + BankStartOffset[SAMPLEBANK_BUILDING_RAVE_INDUSTRIAL] = SFX_RAVE_INDUSTRIAL; + BankStartOffset[SAMPLEBANK_BUILDING_RAVE_COMMERCIAL] = SFX_RAVE_COMMERCIAL; + BankStartOffset[SAMPLEBANK_BUILDING_RAVE_SUBURBAN] = SFX_RAVE_SUBURBAN; + BankStartOffset[SAMPLEBANK_BUILDING_RAVE_COMMERCIAL_2] = SFX_RAVE_COMMERCIAL_2; + BankStartOffset[SAMPLEBANK_BUILDING_39] = SFX_CLUB_1_1; + BankStartOffset[SAMPLEBANK_BUILDING_40] = SFX_CLUB_1_2; + BankStartOffset[SAMPLEBANK_BUILDING_41] = SFX_CLUB_1_3; + BankStartOffset[SAMPLEBANK_BUILDING_42] = SFX_CLUB_1_4; + BankStartOffset[SAMPLEBANK_BUILDING_43] = SFX_CLUB_1_5; + BankStartOffset[SAMPLEBANK_BUILDING_44] = SFX_CLUB_1_6; + BankStartOffset[SAMPLEBANK_BUILDING_45] = SFX_CLUB_1_7; + BankStartOffset[SAMPLEBANK_BUILDING_46] = SFX_CLUB_1_8; + BankStartOffset[SAMPLEBANK_BUILDING_47] = SFX_CLUB_1_9; + BankStartOffset[SAMPLEBANK_EXTRAS] = SFX_EXPLOSION_1; +#endif // GTA_PS2 + BankStartOffset[SFX_BANK_PED_COMMENTS] = SAMPLEBANK_PED_START; +} + +void +cAudioManager::PostInitialiseGameSpecificSetup() +{ + m_nFireAudioEntity = CreateEntity(AUDIOTYPE_FIRE, &gFireManager); + if (m_nFireAudioEntity >= 0) + SetEntityStatus(m_nFireAudioEntity, true); + + m_nCollisionEntity = CreateEntity(AUDIOTYPE_COLLISION, (void *)1); + if (m_nCollisionEntity >= 0) + SetEntityStatus(m_nCollisionEntity, true); + + m_nFrontEndEntity = CreateEntity(AUDIOTYPE_FRONTEND, (void *)1); + if (m_nFrontEndEntity >= 0) + SetEntityStatus(m_nFrontEndEntity, true); + + m_nProjectileEntity = CreateEntity(AUDIOTYPE_PROJECTILE, (void *)1); + if (m_nProjectileEntity >= 0) + SetEntityStatus(m_nProjectileEntity, true); + + m_nWaterCannonEntity = CreateEntity(AUDIOTYPE_WATERCANNON, (void *)1); + if (m_nWaterCannonEntity >= 0) + SetEntityStatus(m_nWaterCannonEntity, true); + + m_nPoliceChannelEntity = CreateEntity(AUDIOTYPE_POLICERADIO, (void *)1); + if (m_nPoliceChannelEntity >= 0) + SetEntityStatus(m_nPoliceChannelEntity, true); +#ifdef GTA_BRIDGE + m_nBridgeEntity = CreateEntity(AUDIOTYPE_BRIDGE, (void*)1); + if (m_nBridgeEntity >= 0) + SetEntityStatus(m_nBridgeEntity, true); +#endif // GTA_BRIDGE + m_nEscalatorEntity = CreateEntity(AUDIOTYPE_ESCALATOR, (void*)1); + if (m_nEscalatorEntity >= 0) + SetEntityStatus(m_nEscalatorEntity, true); + + m_nExtraSoundsEntity = CreateEntity(AUDIOTYPE_EXTRA_SOUNDS, (void*)1); + if (m_nExtraSoundsEntity >= 0) + SetEntityStatus(m_nExtraSoundsEntity, true); + + + m_sMissionAudio.m_nSampleIndex[0] = NO_SAMPLE; + m_sMissionAudio.m_nLoadingStatus[0] = LOADING_STATUS_NOT_LOADED; + m_sMissionAudio.m_nPlayStatus[0] = PLAY_STATUS_STOPPED; + m_sMissionAudio.m_bIsPlaying[0] = false; + m_sMissionAudio.m_bIsPlayed[0] = false; + m_sMissionAudio.m_bPredefinedProperties[0] = true; + m_sMissionAudio.m_nMissionAudioCounter[0] = 0; + m_sMissionAudio.m_bIsMobile[0] = false; + field_5538 = 127; + m_sMissionAudio.m_nSampleIndex[1] = NO_SAMPLE; + m_sMissionAudio.m_nLoadingStatus[1] = LOADING_STATUS_NOT_LOADED; + m_sMissionAudio.m_nPlayStatus[1] = PLAY_STATUS_STOPPED; + m_sMissionAudio.m_bIsPlaying[1] = false; + m_sMissionAudio.m_bIsPlayed[1] = false; + m_sMissionAudio.m_bPredefinedProperties[1] = true; + m_sMissionAudio.m_nMissionAudioCounter[1] = 0; + m_sMissionAudio.m_bIsMobile[1] = false; + field_5538 = 127; + + ResetAudioLogicTimers(CTimer::GetTimeInMilliseconds()); + m_bIsPlayerShutUp = false; + m_nPlayerMood = PLAYER_MOOD_CALM; + m_nPlayerMoodTimer = 0; +} + +void +cAudioManager::PreTerminateGameSpecificShutdown() +{ +#ifdef GTA_BRIDGE + if (m_nBridgeEntity >= 0) { + DestroyEntity(m_nBridgeEntity); + m_nBridgeEntity = AEHANDLE_NONE; + } +#endif + if (m_nEscalatorEntity >= 0) { + DestroyEntity(m_nEscalatorEntity); + m_nEscalatorEntity = AEHANDLE_NONE; + } + if (m_nExtraSoundsEntity >= 0) { + DestroyEntity(m_nExtraSoundsEntity); + m_nExtraSoundsEntity = AEHANDLE_NONE; + } + if (m_nPoliceChannelEntity >= 0) { + DestroyEntity(m_nPoliceChannelEntity); + m_nPoliceChannelEntity = AEHANDLE_NONE; + } + if (m_nWaterCannonEntity >= 0) { + DestroyEntity(m_nWaterCannonEntity); + m_nWaterCannonEntity = AEHANDLE_NONE; + } + if (m_nFireAudioEntity >= 0) { + DestroyEntity(m_nFireAudioEntity); + m_nFireAudioEntity = AEHANDLE_NONE; + } + if (m_nCollisionEntity >= 0) { + DestroyEntity(m_nCollisionEntity); + m_nCollisionEntity = AEHANDLE_NONE; + } + if (m_nFrontEndEntity >= 0) { + DestroyEntity(m_nFrontEndEntity); + m_nFrontEndEntity = AEHANDLE_NONE; + } + if (m_nProjectileEntity >= 0) { + DestroyEntity(m_nProjectileEntity); + m_nProjectileEntity = AEHANDLE_NONE; + } +} + +void +cAudioManager::PostTerminateGameSpecificShutdown() +{ + ; +} + +void +cAudioManager::ResetAudioLogicTimers(uint32 timer) +{ + for (int32 i = 0; i < m_nAudioEntitiesTotal; i++) { + if (m_asAudioEntities[m_anAudioEntityIndices[i]].m_nType == AUDIOTYPE_PHYSICAL) { + CPed *ped = (CPed *)m_asAudioEntities[m_anAudioEntityIndices[i]].m_pEntity; + if (ped->IsPed()) { + ped->m_lastSoundStart = timer; + ped->m_soundStart = timer + m_anRandomTable[0] % 3000; + } + } + } + ClearMissionAudio(0); + ClearMissionAudio(1); + SampleManager.StopChannel(policeChannel); +} + +void +cAudioManager::ProcessReverb() const +{ +#ifdef FIX_BUGS + const uint32 numChannels = channels; +#else + const uint32 numChannels = 28; +#endif + + if (SampleManager.UpdateReverb() && m_bDynamicAcousticModelingStatus) { + for (uint32 i = 0; i < numChannels; i++) { + if (m_asActiveSamples[i].m_bReverbFlag) + SampleManager.SetChannelReverbFlag(i, true); + } + } +} + +float +cAudioManager::GetDistanceSquared(const CVector &v) const +{ + const CVector &c = TheCamera.GetPosition(); + return sq(v.x - c.x) + sq(v.y - c.y) + sq((v.z - c.z) * 0.2f); +} + +void +cAudioManager::CalculateDistance(bool &distCalculated, float dist) +{ + if (!distCalculated) { + m_sQueueSample.m_fDistance = Sqrt(dist); + distCalculated = true; + } +} + +CVehicle *cAudioManager::FindVehicleOfPlayer() +{ + CVehicle* vehicle = FindPlayerVehicle(); + CPlayerPed* ped = FindPlayerPed(); + if (vehicle == nil && ped != nil) { + CEntity *attachedTo = ped->m_attachedTo; + if (attachedTo && attachedTo->IsVehicle()) + vehicle = (CVehicle*)attachedTo; + } + return vehicle; +} + +void +cAudioManager::ProcessPlayerMood() +{ + CPlayerPed *playerPed; + uint32& lastMissionPassedTime = CTheScripts::GetLastMissionPassedTime(); + uint32 curTime = CTimer::GetTimeInMilliseconds(); + + if (m_nPlayerMoodTimer <= curTime) { + playerPed = FindPlayerPed(); + if (playerPed != nil) { + + if (playerPed->m_pWanted->GetWantedLevel() > 3) { + m_nPlayerMood = PLAYER_MOOD_ANGRY; + return; + } + if (playerPed->m_pWanted->GetWantedLevel() > 1) { + m_nPlayerMood = PLAYER_MOOD_PISSED_OFF; + return; + } + + if (lastMissionPassedTime != -1) { + if (curTime < lastMissionPassedTime) { + lastMissionPassedTime = curTime; + return; + } + if (curTime < lastMissionPassedTime + 180000) { + m_nPlayerMood = PLAYER_MOOD_WISECRACKING; + return; + } + } + m_nPlayerMood = PLAYER_MOOD_CALM; + } + } +} + +void +cAudioManager::ProcessSpecial() +{ + CPlayerPed *playerPed; + + if (m_nUserPause) { + if (!m_nPreviousUserPause) { + SampleManager.SetEffectsFadeVolume(MAX_VOLUME); + SampleManager.SetMusicFadeVolume(MAX_VOLUME); + } + } else { + if (!CReplay::IsPlayingBack()) + ProcessPlayerMood(); + playerPed = FindPlayerPed(); + if (playerPed != nil) { + if (playerPed->m_audioEntityId >= 0 && m_asAudioEntities[playerPed->m_audioEntityId].m_bIsUsed) { + if (playerPed->EnteringCar()) { + if(!playerPed->bInVehicle && CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle == nil) + SampleManager.StopChannel(m_nActiveSamples); + } + } + } + } +} + +void +cAudioManager::ProcessEntity(int32 id) +{ + if (m_asAudioEntities[id].m_bStatus) { + m_sQueueSample.m_nEntityIndex = id; + switch (m_asAudioEntities[id].m_nType) { + case AUDIOTYPE_PHYSICAL: + if (!m_nUserPause) { + m_sQueueSample.m_bReverbFlag = true; + ProcessPhysical(id); + } + break; + case AUDIOTYPE_EXPLOSION: + if (!m_nUserPause) { + m_sQueueSample.m_bReverbFlag = true; + ProcessExplosions(id); + } + break; + case AUDIOTYPE_FIRE: + if (!m_nUserPause) { + m_sQueueSample.m_bReverbFlag = true; + ProcessFires(id); + } + break; + case AUDIOTYPE_WEATHER: + if (!m_nUserPause) { + m_sQueueSample.m_bReverbFlag = true; + if(CGame::currArea == AREA_MAIN_MAP || CGame::currArea == AREA_EVERYWHERE) + ProcessWeather(id); + } + break; +/* case AUDIOTYPE_CRANE: + if (!m_nUserPause) { + m_sQueueSample.m_bReverbFlag = true; + ProcessCrane(); + } + break;*/ + case AUDIOTYPE_SCRIPTOBJECT: + if (!m_nUserPause) { + m_sQueueSample.m_bReverbFlag = true; + ProcessScriptObject(id); + } + break; +#ifdef GTA_BRIDGE + case AUDIOTYPE_BRIDGE: + if (!m_nUserPause) { + m_sQueueSample.m_bReverbFlag = true; + ProcessBridge(); + } + break; +#endif + case AUDIOTYPE_FRONTEND: + m_sQueueSample.m_bReverbFlag = false; + ProcessFrontEnd(); + break; + case AUDIOTYPE_PROJECTILE: + if (!m_nUserPause) { + m_sQueueSample.m_bReverbFlag = true; + ProcessProjectiles(); + } + break; + case AUDIOTYPE_GARAGE: + if (!m_nUserPause) + ProcessGarages(); + break; + case AUDIOTYPE_FIREHYDRANT: + if (!m_nUserPause) { + m_sQueueSample.m_bReverbFlag = true; + ProcessFireHydrant(); + } + break; + case AUDIOTYPE_WATERCANNON: + if (!m_nUserPause) { + m_sQueueSample.m_bReverbFlag = true; + ProcessWaterCannon(id); + } + break; + case AUDIOTYPE_ESCALATOR: + if (!m_nUserPause) { + m_sQueueSample.m_bReverbFlag = true; + ProcessEscalators(); + } + break; + case AUDIOTYPE_EXTRA_SOUNDS: + if (!m_nUserPause) { + m_sQueueSample.m_bReverbFlag = true; + ProcessExtraSounds(); + } + break; + default: + return; + } + } +} + +void +cAudioManager::ProcessPhysical(int32 id) +{ + CPhysical *entity = (CPhysical *)m_asAudioEntities[id].m_pEntity; + if (entity) { + switch (entity->GetType()) { + case ENTITY_TYPE_VEHICLE: + ProcessVehicle((CVehicle *)m_asAudioEntities[id].m_pEntity); + break; + case ENTITY_TYPE_PED: + ProcessPed((CPhysical *)m_asAudioEntities[id].m_pEntity); + break; + default: + return; + } + } +} + +#pragma region VEHICLE AUDIO +enum eVehicleModel { + LANDSTAL, + IDAHO, + STINGER, + LINERUN, + PEREN, + SENTINEL, + RIO, + FIRETRUK, + TRASH, + STRETCH, + MANANA, + INFERNUS, + VOODOO, + PONY, + MULE, + CHEETAH, + AMBULAN, + FBICAR, + MOONBEAM, + ESPERANT, + TAXI, + WASHING, + BOBCAT, + MRWHOOP, + BFINJECT, + HUNTER, + POLICE, + ENFORCER, + SECURICA, + BANSHEE, + PREDATOR, + BUS, + RHINO, + BARRACKS, + CUBAN, + CHOPPER, + ANGEL, + COACH, + CABBIE, + STALLION, + RUMPO, + RCBANDIT, + ROMERO, + PACKER, + SENTXS, + ADMIRAL, + SQUALO, + SEASPAR, + PIZZABOY, + GANGBUR, + AIRTRAIN, + DEADDODO, + SPEEDER, + REEFER, + TROPIC, + FLATBED, + YANKEE, + CADDY, + ZEBRA, + TOPFUN, + SKIMMER, + PCJ600, + FAGGIO, + FREEWAY, + RCBARON, + RCRAIDER, + GLENDALE, + OCEANIC, + SANCHEZ, + SPARROW, + PATRIOT, + LOVEFIST, + COASTG, + DINGHY, + HERMES, + SABRE, + SABRETUR, + PHEONIX, + WALTON, + REGINA, + COMET, + DELUXO, + BURRITO, + SPAND, + MARQUIS, + BAGGAGE, + KAUFMAN, + MAVERICK, + VCNMAV, + RANCHER, + FBIRANCH, + VIRGO, + GREENWOO, + JETMAX, + HOTRING, + SANDKING, + BLISTAC, + POLMAV, + BOXVILLE, + BENSON, + MESA, + RCGOBLIN, + HOTRINA, + HOTRINB, + BLOODRA, + BLOODRB, + VICECHEE, + CAR237, + CAR238, + CAR239, + MAX_CARS, + + // HACK so this compiles + // TODO(MIAMI): check it out + DODO = -1 +}; + +enum +{ + OLD_DOOR = 0, + NEW_DOOR, + TRUCK_DOOR, + BUS_DOOR, +}; + + +struct tVehicleSampleData { + eSfxSample m_nAccelerationSampleIndex; + uint8 m_nBank; + eSfxSample m_nHornSample; + int32 m_nHornFrequency; + uint8 m_nSirenOrAlarmSample; + int32 m_nSirenOrAlarmFrequency; + uint8 m_bDoorType; +}; + +const tVehicleSampleData aVehicleSettings[MAX_CARS] = { + {SFX_CAR_REV_10, SFX_BANK_PATHFINDER, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9935, OLD_DOOR}, + {SFX_CAR_REV_11, SFX_BANK_PACARD, SFX_CAR_HORN_56CHEV, 11487, SFX_CAR_HORN_JEEP, 9900, OLD_DOOR}, + {SFX_CAR_REV_2, SFX_BANK_PORSCHE, SFX_CAR_HORN_PORSCHE, 11025, SFX_CAR_HORN_JEEP, 9890, NEW_DOOR}, + {SFX_CAR_REV_5, SFX_BANK_TRUCK, SFX_CAR_HORN_TRUCK, 29711, SFX_CAR_HORN_JEEP, 9960, TRUCK_DOOR}, + {SFX_CAR_REV_11, SFX_BANK_PACARD, SFX_CAR_HORN_56CHEV, 12893, SFX_CAR_HORN_JEEP, 9500, OLD_DOOR}, + {SFX_CAR_REV_4, SFX_BANK_MERC, SFX_CAR_HORN_BMW328, 10706, SFX_CAR_HORN_JEEP, 9600, NEW_DOOR}, + {SFX_CAR_REV_1, SFX_BANK_0, SFX_CAR_HORN_TRUCK, 29711, SFX_CAR_HORN_JEEP, 9700, NEW_DOOR}, + {SFX_CAR_REV_5, SFX_BANK_TRUCK, SFX_CAR_HORN_TRUCK, 29711, SFX_POLICE_SIREN_SLOW, 10588, TRUCK_DOOR}, + {SFX_CAR_REV_5, SFX_BANK_TRUCK, SFX_CAR_HORN_TRUCK, 31478, SFX_CAR_HORN_JEEP, 9800, TRUCK_DOOR}, + {SFX_CAR_REV_11, SFX_BANK_PACARD, SFX_CAR_HORN_BMW328, 9538, SFX_CAR_HORN_JEEP, 9900, NEW_DOOR}, + {SFX_CAR_REV_11, SFX_BANK_PACARD, SFX_CAR_HORN_56CHEV, 10842, SFX_CAR_HORN_JEEP, 10000, OLD_DOOR}, + {SFX_CAR_REV_7, SFX_BANK_COBRA, SFX_CAR_HORN_BMW328, 12017, SFX_CAR_HORN_JEEP, 9900, NEW_DOOR}, + {SFX_CAR_REV_9, SFX_BANK_CADILLAC, SFX_CAR_HORN_JEEP, 22293, SFX_CAR_HORN_JEEP, 9800, NEW_DOOR}, + {SFX_CAR_REV_3, SFX_BANK_SPIDER, SFX_CAR_HORN_BUS2, 18000, SFX_CAR_HORN_JEEP, 9700, OLD_DOOR}, + {SFX_CAR_REV_3, SFX_BANK_SPIDER, SFX_CAR_HORN_BUS, 18286, SFX_CAR_HORN_JEEP, 9600, OLD_DOOR}, + {SFX_CAR_REV_2, SFX_BANK_PORSCHE, SFX_CAR_HORN_PORSCHE, 11025, SFX_CAR_HORN_JEEP, 9500, NEW_DOOR}, + {SFX_CAR_REV_3, SFX_BANK_SPIDER, SFX_CAR_HORN_JEEP, 22295, SFX_AMBULANCE_SIREN_SLOW, 12688, OLD_DOOR}, + {SFX_CAR_REV_4, SFX_BANK_MERC, SFX_CAR_HORN_PORSCHE, 9271, SFX_POLICE_SIREN_SLOW, 11471, NEW_DOOR}, + {SFX_CAR_REV_11, SFX_BANK_PACARD, SFX_CAR_HORN_56CHEV, 12170, SFX_CAR_HORN_JEEP, 9400, OLD_DOOR}, + {SFX_CAR_REV_11, SFX_BANK_PACARD, SFX_CAR_HORN_BMW328, 11000, SFX_CAR_HORN_JEEP, 9300, OLD_DOOR}, + {SFX_CAR_REV_10, SFX_BANK_PATHFINDER, SFX_CAR_HORN_BMW328, 10796, SFX_CAR_HORN_JEEP, 9200, NEW_DOOR}, + {SFX_CAR_REV_4, SFX_BANK_MERC, SFX_CAR_HORN_BMW328, 10500, SFX_CAR_HORN_JEEP, 9100, NEW_DOOR}, + {SFX_CAR_REV_10, SFX_BANK_PATHFINDER, SFX_CAR_HORN_PICKUP, 10924, SFX_CAR_HORN_JEEP, 9000, OLD_DOOR}, + {SFX_CAR_REV_3, SFX_BANK_SPIDER, SFX_CAR_HORN_PICKUP, 11025, SFX_ICE_CREAM_TUNE, 11025, OLD_DOOR}, + {SFX_CAR_REV_6, SFX_BANK_HOTROD, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9100, OLD_DOOR}, + {SFX_HELI_APACHE_1, SFX_BANK_HELI_APACHE, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9200, NEW_DOOR}, + {SFX_CAR_REV_4, SFX_BANK_MERC, SFX_CAR_HORN_BMW328, 10706, SFX_POLICE_SIREN_SLOW, 10511, NEW_DOOR}, + {SFX_CAR_REV_3, SFX_BANK_SPIDER, SFX_CAR_HORN_BUS, 17260, SFX_POLICE_SIREN_SLOW, 11029, OLD_DOOR}, + {SFX_CAR_REV_3, SFX_BANK_SPIDER, SFX_CAR_HORN_PICKUP, 8670, SFX_CAR_HORN_JEEP, 9300, OLD_DOOR}, + {SFX_CAR_REV_7, SFX_BANK_COBRA, SFX_CAR_HORN_PORSCHE, 10400, SFX_CAR_HORN_JEEP, 9400, NEW_DOOR}, + {SFX_CAR_REV_1, SFX_BANK_0, SFX_CAR_HORN_JEEP, 26513, SFX_POLICE_SIREN_SLOW, 11912, NEW_DOOR}, + {SFX_CAR_REV_5, SFX_BANK_TRUCK, SFX_CAR_HORN_BUS2, 11652, SFX_CAR_HORN_JEEP, 9500, BUS_DOOR}, + {SFX_CAR_REV_5, SFX_BANK_TRUCK, SFX_CAR_HORN_TRUCK, 29711, SFX_CAR_HORN_JEEP, 9600, TRUCK_DOOR}, + {SFX_CAR_REV_5, SFX_BANK_TRUCK, SFX_CAR_HORN_TRUCK, 28043, SFX_CAR_HORN_JEEP, 9700, TRUCK_DOOR}, + {SFX_CAR_REV_6, SFX_BANK_HOTROD, SFX_CAR_HORN_JEEP, 25400, SFX_CAR_HORN_JEEP, 9800, OLD_DOOR}, + {SFX_CAR_REV_1, SFX_BANK_0, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9900, NEW_DOOR}, + {SFX_CAR_REV_17, SFX_BANK_VTWIN, SFX_CAR_HORN_JEEP, 26313, SFX_CAR_HORN_JEEP, 10000, NEW_DOOR}, + {SFX_CAR_REV_5, SFX_BANK_TRUCK, SFX_CAR_HORN_BUS, 16291, SFX_CAR_HORN_JEEP, 10100, BUS_DOOR}, + {SFX_CAR_REV_11, SFX_BANK_PACARD, SFX_CAR_HORN_56CHEV, 10842, SFX_CAR_HORN_JEEP, 9900, OLD_DOOR}, + {SFX_CAR_REV_11, SFX_BANK_PACARD, SFX_CAR_HORN_56CHEV, 10233, SFX_CAR_HORN_JEEP, 9800, NEW_DOOR}, + {SFX_CAR_REV_3, SFX_BANK_SPIDER, SFX_CAR_HORN_PICKUP, 8670, SFX_CAR_HORN_JEEP, 9700, OLD_DOOR}, + {SFX_RC_REV, SFX_BANK_RC, SFX_CAR_HORN_PICKUP, 20000, SFX_CAR_HORN_JEEP, 9600, NEW_DOOR}, + {SFX_CAR_REV_11, SFX_BANK_PACARD, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9500, NEW_DOOR}, + {SFX_CAR_REV_5, SFX_BANK_TRUCK, SFX_CAR_HORN_TRUCK, 29000, SFX_CAR_HORN_JEEP, 9400, TRUCK_DOOR}, + {SFX_CAR_REV_1, CAR_SFX_BANKS_OFFSET, SFX_CAR_HORN_BMW328, 9003, SFX_CAR_HORN_JEEP, 9300, NEW_DOOR}, + {SFX_CAR_REV_4, SFX_BANK_MERC, SFX_CAR_HORN_PORSCHE, 12375, SFX_CAR_HORN_JEEP, 9200, NEW_DOOR}, + {SFX_CAR_REV_1, SFX_BANK_0, SFX_CAR_HORN_BUS2, 15554, SFX_CAR_HORN_JEEP, 9100, NEW_DOOR}, + {SFX_CAR_REV_1, SFX_BANK_0, SFX_CAR_HORN_BUS2, 13857, SFX_CAR_HORN_JEEP, 9000, TRUCK_DOOR}, + {SFX_MOPED_REV, SFX_BANK_MOPED, SFX_CAR_HORN_JEEP, 30000, SFX_CAR_HORN_JEEP, 9100, NEW_DOOR}, + {SFX_CAR_REV_7, SFX_BANK_COBRA, SFX_CAR_HORN_JEEP, 22043, SFX_CAR_HORN_JEEP, 9200, OLD_DOOR}, + {SFX_CAR_REV_1, SFX_BANK_0, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9300, NEW_DOOR}, + {SFX_CAR_REV_1, SFX_BANK_0, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9400, NEW_DOOR}, + {SFX_CAR_REV_1, SFX_BANK_0, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9500, NEW_DOOR}, + {SFX_CAR_REV_1, SFX_BANK_0, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9600, NEW_DOOR}, + {SFX_CAR_REV_1, SFX_BANK_0, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9700, NEW_DOOR}, + {SFX_CAR_REV_5, SFX_BANK_TRUCK, SFX_CAR_HORN_TRUCK, 28043, SFX_CAR_HORN_JEEP, 9800, TRUCK_DOOR}, + {SFX_CAR_REV_3, SFX_BANK_SPIDER, SFX_CAR_HORN_BUS, 18286, SFX_CAR_HORN_JEEP, 9900, OLD_DOOR}, + {SFX_CAR_REV_12, SFX_BANK_GOLF_CART, SFX_CAR_HORN_JEEP, 28500, SFX_CAR_HORN_JEEP, 9800, NEW_DOOR}, + {SFX_CAR_REV_1, CAR_SFX_BANKS_OFFSET, SFX_CAR_HORN_56CHEV, 10842, SFX_CAR_HORN_JEEP, 9700, OLD_DOOR}, + {SFX_CAR_REV_8, SFX_BANK_PONTIAC_SLOW, SFX_CAR_HORN_BUS2, 18000, SFX_CAR_HORN_JEEP, 9700, OLD_DOOR}, + {SFX_SEAPLANE_PRO1, SFX_BANK_PLANE_SEAPLANE, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9700, NEW_DOOR}, + {SFX_CAR_REV_20, SFX_BANK_SPORTS_BIKE, SFX_CAR_HORN_JEEP, 27000, SFX_CAR_HORN_JEEP, 9600, NEW_DOOR}, + {SFX_MOPED_REV, SFX_BANK_MOPED, SFX_CAR_HORN_JEEP, 31000, SFX_CAR_HORN_JEEP, 9500, NEW_DOOR}, + {SFX_CAR_REV_17, SFX_BANK_VTWIN, SFX_CAR_HORN_PICKUP, 11000, SFX_CAR_HORN_JEEP, 9400, NEW_DOOR}, + {SFX_RC_REV, SFX_BANK_RC, SFX_CAR_HORN_JEEP, 30000, SFX_CAR_HORN_JEEP, 15000, NEW_DOOR}, + {SFX_CAR_RC_HELI, SFX_BANK_RC_HELI, SFX_CAR_HORN_JEEP, 30000, SFX_CAR_HORN_JEEP, 15000, NEW_DOOR}, + {SFX_CAR_REV_9, SFX_BANK_CADILLAC, SFX_CAR_HORN_56CHEV, 10300, SFX_CAR_HORN_JEEP, 9100, OLD_DOOR}, + {SFX_CAR_REV_9, SFX_BANK_CADILLAC, SFX_CAR_HORN_56CHEV, 10500, SFX_CAR_HORN_JEEP, 9000, OLD_DOOR}, + {SFX_CAR_REV_19, SFX_BANK_HONDA250, SFX_CAR_HORN_JEEP, 30000, SFX_CAR_HORN_JEEP, 9000, NEW_DOOR}, + {SFX_CAR_REV_1, SFX_BANK_0, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9100, TRUCK_DOOR}, + {SFX_CAR_REV_3, SFX_BANK_SPIDER, SFX_CAR_HORN_TRUCK, 28000, SFX_CAR_HORN_JEEP, 9200, TRUCK_DOOR}, + {SFX_CAR_REV_7, SFX_BANK_COBRA, SFX_CAR_HORN_PICKUP, 11200, SFX_CAR_HORN_JEEP, 9300, NEW_DOOR}, + {SFX_CAR_REV_1, SFX_BANK_0, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9400, NEW_DOOR}, + {SFX_CAR_REV_1, SFX_BANK_0, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9500, NEW_DOOR}, + {SFX_CAR_REV_9, SFX_BANK_CADILLAC, SFX_CAR_HORN_56CHEV, 10700, SFX_CAR_HORN_JEEP, 9600, OLD_DOOR}, + {SFX_CAR_REV_1, CAR_SFX_BANKS_OFFSET, SFX_CAR_HORN_BMW328, 9000, SFX_CAR_HORN_JEEP, 9700, OLD_DOOR}, + {SFX_CAR_REV_6, SFX_BANK_HOTROD, SFX_CAR_HORN_BMW328, 9200, SFX_CAR_HORN_JEEP, 9800, OLD_DOOR}, + {SFX_CAR_REV_7, SFX_BANK_COBRA, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9900, NEW_DOOR}, + {SFX_CAR_REV_11, SFX_BANK_PACARD, SFX_CAR_HORN_56CHEV, 10540, SFX_CAR_HORN_JEEP, 9935, TRUCK_DOOR}, + {SFX_CAR_REV_8, SFX_BANK_PONTIAC_SLOW, SFX_CAR_HORN_PICKUP, 11000, SFX_CAR_HORN_JEEP, 9700, NEW_DOOR}, + {SFX_CAR_REV_2, SFX_BANK_PORSCHE, SFX_CAR_HORN_BMW328, 9500, SFX_CAR_HORN_JEEP, 9800, NEW_DOOR}, + {SFX_CAR_REV_7, SFX_BANK_COBRA, SFX_CAR_HORN_BMW328, 9700, SFX_CAR_HORN_JEEP, 9700, NEW_DOOR}, + {SFX_CAR_REV_8, SFX_BANK_PONTIAC_SLOW, SFX_CAR_HORN_BUS2, 18000, SFX_CAR_HORN_JEEP, 9600, OLD_DOOR}, + {SFX_CAR_REV_3, SFX_BANK_SPIDER, SFX_CAR_HORN_BUS, 18000, SFX_CAR_HORN_JEEP, 9500, TRUCK_DOOR}, + {SFX_CAR_REV_1, SFX_BANK_0, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9400, NEW_DOOR}, + {SFX_CAR_REV_8, SFX_BANK_PONTIAC_SLOW, SFX_CAR_HORN_JEEP, 27513, SFX_CAR_HORN_JEEP, 9300, NEW_DOOR}, + {SFX_CAR_REV_8, SFX_BANK_PONTIAC_SLOW, SFX_CAR_HORN_56CHEV, 10700, SFX_CAR_HORN_JEEP, 9200, OLD_DOOR}, + {SFX_CAR_REV_1, SFX_BANK_0, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9100, TRUCK_DOOR}, + {SFX_CAR_REV_1, SFX_BANK_0, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9000, TRUCK_DOOR}, + {SFX_CAR_REV_10, SFX_BANK_PATHFINDER, SFX_CAR_HORN_BUS2, 18000, SFX_CAR_HORN_JEEP, 9100, TRUCK_DOOR}, + {SFX_CAR_REV_1, CAR_SFX_BANKS_OFFSET, SFX_CAR_HORN_BUS2, 17900, SFX_POLICE_SIREN_SLOW, 10511, TRUCK_DOOR}, + {SFX_CAR_REV_4, SFX_BANK_MERC, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9200, NEW_DOOR}, + {SFX_CAR_REV_8, SFX_BANK_PONTIAC_SLOW, SFX_CAR_HORN_BMW328, 9600, SFX_CAR_HORN_JEEP, 9300, NEW_DOOR}, + {SFX_CAR_REV_4, SFX_BANK_0, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9400, NEW_DOOR}, + {SFX_CAR_REV_7, SFX_BANK_COBRA, SFX_CAR_HORN_PORSCHE, 10000, SFX_CAR_HORN_JEEP, 9500, OLD_DOOR}, + {SFX_CAR_REV_6, SFX_BANK_HOTROD, SFX_CAR_HORN_PORSCHE, 10500, SFX_CAR_HORN_JEEP, 9600, OLD_DOOR}, + {SFX_CAR_REV_10, SFX_BANK_PATHFINDER, SFX_CAR_HORN_JEEP, 25513, SFX_CAR_HORN_JEEP, 9700, NEW_DOOR}, + {SFX_CAR_REV_1, SFX_BANK_0, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9800, NEW_DOOR}, + {SFX_CAR_REV_3, SFX_BANK_SPIDER, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9900, NEW_DOOR}, + {SFX_CAR_REV_10, SFX_BANK_PATHFINDER, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9800, NEW_DOOR}, + {SFX_CAR_REV_1, CAR_SFX_BANKS_OFFSET, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9700, NEW_DOOR}, + {SFX_CAR_RC_HELI, SFX_BANK_RC_HELI, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9600, NEW_DOOR}, + {SFX_CAR_REV_6, SFX_BANK_HOTROD, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9700, NEW_DOOR}, + {SFX_CAR_REV_7, SFX_BANK_COBRA, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9600, NEW_DOOR}, + {SFX_CAR_REV_1, CAR_SFX_BANKS_OFFSET, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9500, NEW_DOOR}, + {SFX_CAR_REV_9, SFX_BANK_CADILLAC, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9400, NEW_DOOR}, + {SFX_CAR_REV_2, SFX_BANK_PORSCHE, SFX_CAR_HORN_PORSCHE, 11025, SFX_POLICE_SIREN_SLOW, 11000, NEW_DOOR}, + {SFX_CAR_REV_1, CAR_SFX_BANKS_OFFSET, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9200, NEW_DOOR}, + {SFX_CAR_REV_1, CAR_SFX_BANKS_OFFSET, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9300, NEW_DOOR}, + {SFX_CAR_REV_1, CAR_SFX_BANKS_OFFSET, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9400, NEW_DOOR} }; + + + +bool bPlayerJustEnteredCar; + +const bool hornPatternsArray[8][44] = { + {false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, false, + false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false}, + {false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false}, + {false, false, true, true, true, true, true, true, true, true, true, true, false, false, false, false, true, true, true, true, true, false, + false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false}, + {false, false, true, true, true, true, true, false, false, true, true, true, true, true, false, false, false, true, true, true, true, true, + true, true, true, true, true, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, false}, + {false, false, true, true, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false}, + {false, false, true, true, true, false, false, false, true, true, true, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false}, + {false, false, true, true, true, true, false, false, false, false, true, true, true, false, false, true, true, true, false, false, true, true, + true, true, true, true, false, false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, false, false}, + {false, false, true, true, true, true, false, false, true, true, true, true, true, false, false, false, true, true, true, true, true, true, + false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, false}, +}; + +void cAudioManager::ProcessVehicle(CVehicle* veh) +{ + CVehicle* playerVeh; + cVehicleParams params; + CBike* bike; + CAutomobile* automobile; + + playerVeh = FindVehicleOfPlayer(); + if (playerVeh == veh + || CGame::currArea == AREA_OVALRING + || CGame::currArea == AREA_BLOOD + || CGame::currArea == AREA_DIRT + || CGame::currArea == AREA_EVERYWHERE + || CGame::currArea == AREA_MALL + || CGame::currArea == AREA_MAIN_MAP) { + m_sQueueSample.m_vecPos = veh->GetPosition(); + params.m_bDistanceCalculated = false; + params.m_pVehicle = veh; + params.m_fDistance = GetDistanceSquared(m_sQueueSample.m_vecPos); + params.m_pTransmission = veh->pHandling != nil ? &veh->pHandling->Transmission : nil; + params.m_nIndex = veh->m_modelIndex - MI_FIRST_VEHICLE; + if (veh->GetStatus() == STATUS_SIMPLE) + params.m_fVelocityChange = veh->AutoPilot.m_fMaxTrafficSpeed * 0.02f; + else + params.m_fVelocityChange = DotProduct(veh->m_vecMoveSpeed, veh->GetForward()); + params.m_VehicleType = veh->m_vehType; + + if (CGame::currArea == AREA_MALL && playerVeh != veh) { + ProcessVehicleOneShots(params); + ProcessVehicleSirenOrAlarm(params); + ProcessEngineDamage(params); + return; + } + switch (params.m_VehicleType) { + case VEHICLE_TYPE_CAR: + automobile = (CAutomobile*)veh; + UpdateGasPedalAudio(veh, params.m_VehicleType); + if (veh->m_modelIndex == MI_RCBANDIT || veh->m_modelIndex == MI_RCBARON) { + ProcessModelVehicle(params); + ProcessEngineDamage(params); + } else if (veh->m_modelIndex == MI_RCRAIDER || veh->m_modelIndex == MI_RCGOBLIN) { + ProcessModelHeliVehicle(params); + ProcessEngineDamage(params); + } else { + switch (veh->GetVehicleAppearance()) { + case VEHICLE_APPEARANCE_HELI: + ProcessCarHeli(params); + ProcessVehicleFlatTyre(params); + ProcessEngineDamage(params); + break; + case VEHICLE_APPEARANCE_BOAT: + case VEHICLE_APPEARANCE_PLANE: + break; + default: + if (ProcessVehicleRoadNoise(params)) { + ProcessReverseGear(params); + if (CWeather::WetRoads > 0.0f) + ProcessWetRoadNoise(params); + ProcessVehicleSkidding(params); + ProcessVehicleFlatTyre(params); + ProcessVehicleHorn(params); + ProcessVehicleSirenOrAlarm(params); + if (UsesReverseWarning(params.m_nIndex)) + ProcessVehicleReverseWarning(params); + if(HasAirBrakes(params.m_nIndex)) + ProcessAirBrakes(params); + ProcessCarBombTick(params); + ProcessVehicleEngine(params); + ProcessEngineDamage(params); + ProcessVehicleDoors(params); + } + break; + } + } + ProcessVehicleOneShots(params); + automobile->m_fVelocityChangeForAudio = params.m_fVelocityChange; + break; + case VEHICLE_TYPE_BOAT: + if (veh->m_modelIndex == MI_SKIMMER) + ProcessCarHeli(params); + else + ProcessBoatEngine(params); + ProcessBoatMovingOverWater(params); + ProcessVehicleOneShots(params); + break; + case VEHICLE_TYPE_HELI: + ProcessCarHeli(params); + ProcessVehicleOneShots(params); + break; + case VEHICLE_TYPE_PLANE: + ProcessPlane(params); + ProcessVehicleOneShots(params); + ProcessVehicleFlatTyre(params); + break; + case VEHICLE_TYPE_BIKE: + bike = (CBike*)veh; + UpdateGasPedalAudio(veh, params.m_VehicleType); + if (ProcessVehicleRoadNoise(params)) { + if (CWeather::WetRoads > 0.0f) + ProcessWetRoadNoise(params); + ProcessVehicleSkidding(params); + ProcessVehicleHorn(params); + ProcessVehicleSirenOrAlarm(params); + ProcessCarBombTick(params); + ProcessEngineDamage(params); + ProcessVehicleEngine(params); + ProcessVehicleFlatTyre(params); + } + ProcessVehicleOneShots(params); + bike->m_fVelocityChangeForAudio = params.m_fVelocityChange; + break; + default: + break; + } + ProcessRainOnVehicle(params); + } +} + +void +cAudioManager::ProcessRainOnVehicle(cVehicleParams& params) +{ + const int SOUND_INTENSITY = 22.0f; + + CVehicle *veh; + uint8 emittingVol; + + if (params.m_fDistance >= SQR(SOUND_INTENSITY) || CWeather::Rain <= 0.01f || CCullZones::CamNoRain() && CCullZones::PlayerNoRain()) + return; + + veh = params.m_pVehicle; + veh->m_bRainAudioCounter++; + if (veh->m_bRainAudioCounter >= 2) { + veh->m_bRainAudioCounter = 0; + CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance); + emittingVol = 30.0f * CWeather::Rain; + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = veh->m_bRainSamplesCounter++; + if (veh->m_bRainSamplesCounter > 4) + veh->m_bRainSamplesCounter = 68; + m_sQueueSample.m_nSampleIndex = (m_anRandomTable[1] & 3) + SFX_CAR_RAIN_1; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 9; + m_sQueueSample.m_nFrequency = m_anRandomTable[1] % 4000 + 28000; + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bReverbFlag = false; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } +} + +bool +cAudioManager::ProcessReverseGear(cVehicleParams& params) +{ + const int reverseGearIntensity = 30; + + CAutomobile* automobile; + float modificator; + uint8 emittingVolume; + + if (params.m_fDistance >= SQR(reverseGearIntensity)) + return false; + automobile = (CAutomobile*)params.m_pVehicle; + if (automobile->m_modelIndex == MI_CADDY) + return true; + if (automobile->bEngineOn && (automobile->m_fGasPedal < 0.0f || automobile->m_nCurrentGear == 0)) { + CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance); + if (automobile->m_nDriveWheelsOnGround != 0) { + modificator = params.m_fVelocityChange / params.m_pTransmission->fMaxReverseVelocity; + } else { + if (automobile->m_nDriveWheelsOnGroundPrev != 0) + automobile->m_fGasPedalAudio *= 0.4f; + modificator = automobile->m_fGasPedalAudio; + } + modificator = Abs(modificator); + emittingVolume = modificator * 24.0f; + m_sQueueSample.m_nVolume = ComputeVolume(emittingVolume, reverseGearIntensity, m_sQueueSample.m_fDistance); + + if (m_sQueueSample.m_nVolume != 0) { + if (params.m_pVehicle->m_fGasPedal >= 0.0f) { + m_sQueueSample.m_nCounter = 62; + m_sQueueSample.m_nSampleIndex = SFX_REVERSE_GEAR_2; + } else { + m_sQueueSample.m_nCounter = 61; + m_sQueueSample.m_nSampleIndex = SFX_REVERSE_GEAR; + } + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nFrequency = (6000.0f * modificator) + 7000; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = emittingVolume; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 3.0f; + m_sQueueSample.m_fSoundIntensity = reverseGearIntensity; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 5; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + return true; +} + +void +cAudioManager::ProcessModelVehicle(cVehicleParams& params) +{ + const float SOUND_INTENSITY = 35.0f; + + static uint32 prevFreq = 14000; + static uint8 prevVolume = 0; + + uint32 freq; + int16 acceletateState; + int16 brakeState; + uint8 volume; + bool isPlayerVeh; + bool vehSlowdown; + + if (params.m_fDistance >= SQR(SOUND_INTENSITY)) + return; + + if (FindPlayerVehicle() == params.m_pVehicle) + isPlayerVeh = true; + else +#ifdef FIX_BUGS + isPlayerVeh = CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle == params.m_pVehicle; +#else + isPlayerVeh = CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle != nil; +#endif + if (params.m_pVehicle->m_modelIndex == MI_RCBANDIT) { + if (((CAutomobile*)params.m_pVehicle)->m_nDriveWheelsOnGround != 0) { + volume = Min(127, 127.0f * Abs(params.m_fVelocityChange) * 3.0f); + freq = 8000.0f * Abs(params.m_fVelocityChange) + 14000; + } else { + volume = 127; + freq = 25000; + } + if (isPlayerVeh) { + volume = clamp2(volume, prevVolume, 7); + freq = clamp2(freq, prevFreq, 800); + } + if (volume > 0) { + CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance); + m_sQueueSample.m_nVolume = ComputeVolume(volume, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 2; + m_sQueueSample.m_nSampleIndex = SFX_RC_REV; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_nFrequency = freq; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = volume; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(SFX_RC_REV); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(SFX_RC_REV); + m_sQueueSample.m_fSpeedMultiplier = 3.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 4; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + if (isPlayerVeh) { + prevFreq = freq; + prevVolume = volume; + } + } else if (params.m_pVehicle != nil) { + if (isPlayerVeh) { + acceletateState = Pads[0].GetAccelerate(); + brakeState = Pads[0].GetBrake(); + } else { + acceletateState = 255.0f * params.m_pVehicle->m_fGasPedal; + brakeState = 255.0f * params.m_pVehicle->m_fBrakePedal; + } + if (acceletateState < brakeState) + acceletateState = brakeState; + if (acceletateState <= 0) { + vehSlowdown = true; + volume = 127; + freq = 18000; + } else { + vehSlowdown = false; + volume = Min(127, (127 * acceletateState / 255) * 3.0f * Abs(params.m_fVelocityChange)); + freq = Min(22000, (8000 * acceletateState / 255 + 14000) * 3.0f * Abs(params.m_fVelocityChange)); + } + if (isPlayerVeh && !vehSlowdown) { + volume = clamp2(volume, prevVolume, 7); + freq = clamp2(freq, prevFreq, 800); + } + if (!vehSlowdown) +#ifdef THIS_IS_STUPID + freq += 8000.0f * Abs(DotProduct(params.m_pVehicle->GetUp(), CVector(0.0f, 1.0f, 0.0f))); +#else + freq += 8000.0f * Abs(params.m_pVehicle->GetUp().y); +#endif + if (params.m_pVehicle->bIsDrowning) + volume /= 4; + if (volume > 0) { + CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance); + m_sQueueSample.m_nVolume = ComputeVolume(volume, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + if (vehSlowdown) { + m_sQueueSample.m_nCounter = 0; + m_sQueueSample.m_nSampleIndex = SFX_RC_IDLE; + m_sQueueSample.m_nReleasingVolumeDivider = 6; + } else { + m_sQueueSample.m_nCounter = 2; + m_sQueueSample.m_nSampleIndex = SFX_RC_REV; + m_sQueueSample.m_nReleasingVolumeDivider = 4; + } + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nFrequency = freq; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = volume; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 3.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + if (isPlayerVeh) { + if (vehSlowdown) { + prevFreq = freq; + prevVolume = volume; + } + } + } +} + +void +cAudioManager::ProcessModelHeliVehicle(cVehicleParams& params) +{ + const float SOUND_INTENSITY = 35.0f; + + static uint32 prevFreq = 22050; + + uint32 freq; + bool isPlayerVeh; + int16 acceletateState; + int16 brakeState; + + if (params.m_fDistance >= SQR(SOUND_INTENSITY)) + return; + + if (FindPlayerVehicle() == params.m_pVehicle) + isPlayerVeh = true; + else +#ifdef FIX_BUGS + isPlayerVeh = CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle == params.m_pVehicle; +#else + isPlayerVeh = CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle != nil; +#endif + if (isPlayerVeh) { + brakeState = Pads[0].GetBrake(); + acceletateState = Max(Pads[0].GetAccelerate(), Abs(Pads[0].GetCarGunUpDown()) * 2); + } else { + acceletateState = 255.0f * params.m_pVehicle->m_fGasPedal; + brakeState = 255.0f * params.m_pVehicle->m_fBrakePedal; + } + if (acceletateState < brakeState) + acceletateState = brakeState; + freq = clamp2(5 * acceletateState + 22050, prevFreq, 30); + CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance); + m_sQueueSample.m_nVolume = ComputeVolume(70, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 2; + m_sQueueSample.m_nSampleIndex = SFX_CAR_RC_HELI; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nFrequency = freq; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = 70; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(SFX_CAR_RC_HELI); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(SFX_CAR_RC_HELI); + m_sQueueSample.m_fSpeedMultiplier = 3.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 4; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + if (isPlayerVeh) + prevFreq = freq; +} + +bool +cAudioManager::ProcessVehicleRoadNoise(cVehicleParams& params) +{ + const float SOUND_INTENSITY = 95.0f; + + int32 emittingVol; + uint32 freq; + float multiplier; + int sampleFreq; + float velocity; + uint8 wheelsOnGround; + + if (params.m_fDistance >= SQR(SOUND_INTENSITY)) + return false; + + if (params.m_fDistance >= SQR(SOUND_INTENSITY)) + return false; + switch (params.m_VehicleType) { + case VEHICLE_TYPE_CAR: + wheelsOnGround = ((CAutomobile*)params.m_pVehicle)->m_nWheelsOnGround; + break; + case VEHICLE_TYPE_BIKE: + wheelsOnGround = ((CBike*)params.m_pVehicle)->m_nWheelsOnGround; + break; + default: + wheelsOnGround = 4; + break; + } + if (params.m_pTransmission == nil || wheelsOnGround == 0) + return true; + + velocity = Abs(params.m_fVelocityChange); + if (velocity > 0.0f) { + CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance); + emittingVol = 30.f * Min(1.f, velocity / (0.5f * params.m_pTransmission->fMaxVelocity)); + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 0; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + if (params.m_pVehicle->m_nSurfaceTouched == SURFACE_WATER) { + m_sQueueSample.m_nSampleIndex = SFX_BOAT_WATER_LOOP; + freq = 6050 * emittingVol / 30 + 16000; + } else { + m_sQueueSample.m_nSampleIndex = SFX_ROAD_NOISE; + multiplier = (m_sQueueSample.m_fDistance / SOUND_INTENSITY) * 0.5f; + sampleFreq = SampleManager.GetSampleBaseFrequency(SFX_ROAD_NOISE); + freq = (sampleFreq * multiplier) + ((3 * sampleFreq) / 4); + } + m_sQueueSample.m_nFrequency = freq; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 6.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 4; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + + return true; +} + +bool +cAudioManager::ProcessWetRoadNoise(cVehicleParams& params) +{ + const float SOUND_INTENSITY = 30.0f; + + float relativeVelocity; + int32 emittingVol; + float multiplier; + int freq; + float velocity; + uint8 wheelsOnGround; + + if (params.m_fDistance >= SQR(SOUND_INTENSITY)) + return false; + switch (params.m_VehicleType) { + case VEHICLE_TYPE_CAR: + wheelsOnGround = ((CAutomobile*)params.m_pVehicle)->m_nWheelsOnGround; + break; + case VEHICLE_TYPE_BIKE: + wheelsOnGround = ((CBike*)params.m_pVehicle)->m_nWheelsOnGround; + break; + default: + wheelsOnGround = 4; + break; + } + if (params.m_pTransmission == nil || wheelsOnGround == 0) + return true; + + velocity = Abs(params.m_fVelocityChange); + if (velocity > 0.0f) { + CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance); + relativeVelocity = Min(1.0f, velocity / (0.5f * params.m_pTransmission->fMaxVelocity)); + emittingVol = 23.0f * relativeVelocity * CWeather::WetRoads; + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 1; + m_sQueueSample.m_nSampleIndex = SFX_ROAD_NOISE; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + multiplier = (m_sQueueSample.m_fDistance / SOUND_INTENSITY) * 0.5f; + freq = SampleManager.GetSampleBaseFrequency(SFX_ROAD_NOISE); + m_sQueueSample.m_nFrequency = freq + freq * multiplier; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 6.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 4; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + + return true; +} + +void +cAudioManager::ProcessVehicleEngine(cVehicleParams& params) +{ + const float SOUND_INTENSITY = 50.0f; + + CVehicle* playerVeh; + CVehicle* veh; + CAutomobile* automobile; + cTransmission* transmission; + CBike* bike; + tWheelState* wheelState; + float* gasPedalAudioPtr; + + int32 freq = 0; + uint8 currentGear; + uint8 emittingVol; + int8 wheelsOnGround; + int8 wheelsOnGroundPrev; + float relativeGearChange; + float relativeChange; + float modificator; + float traction; + bool isMoped; + bool caddyBool; + + isMoped = false; + caddyBool = false; + traction = 0.0f; + if (params.m_fDistance >= SQR(SOUND_INTENSITY)) + return; + playerVeh = FindPlayerVehicle(); + veh = params.m_pVehicle; + if (playerVeh == veh && veh->GetStatus() == STATUS_WRECKED) { + SampleManager.StopChannel(m_nActiveSamples); + return; + } + if (!veh->bEngineOn) + return; + CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance); + if (playerVeh == veh && veh->m_modelIndex != MI_CADDY) { + ProcessPlayersVehicleEngine(params, params.m_pVehicle); + return; + } + transmission = params.m_pTransmission; + if (transmission != nil) { + switch (veh->m_modelIndex) { + case MI_PIZZABOY: + case MI_FAGGIO: + isMoped = true; + currentGear = transmission->nNumberOfGears; + break; + case MI_CADDY: + currentGear = transmission->nNumberOfGears; + caddyBool = true; + break; + default: + currentGear = veh->m_nCurrentGear; + break; + } + switch (params.m_VehicleType) { + case VEHICLE_TYPE_CAR: + automobile = (CAutomobile*)veh; + wheelsOnGround = automobile->m_nDriveWheelsOnGround; + wheelsOnGroundPrev = automobile->m_nDriveWheelsOnGroundPrev; + wheelState = automobile->m_aWheelState; + gasPedalAudioPtr = &automobile->m_fGasPedalAudio; + break; + case VEHICLE_TYPE_BIKE: + bike = (CBike*)veh; + wheelsOnGround = bike->m_nDriveWheelsOnGround; + wheelsOnGroundPrev = bike->m_nDriveWheelsOnGroundPrev; + wheelState = bike->m_aWheelState; + gasPedalAudioPtr = &bike->m_fGasPedalAudio; + break; + default: + debug(" ** AUDIOLOG: Unrecognised vehicle type %d in ProcessVehicleEngine() * \n", params.m_VehicleType); + return; + } + + if (wheelsOnGround != 0) { + if (!veh->bIsHandbrakeOn || isMoped && caddyBool) { //mb bug, bcs it's can't be true together + if (veh->GetStatus() == STATUS_SIMPLE || isMoped || caddyBool) { + traction = 0.0f; + } else { + switch (transmission->nDriveType) { + case '4': + if (params.m_VehicleType == VEHICLE_TYPE_BIKE) { + for (int i = 0; i < 2; i++) + if (wheelState[i] == WHEEL_STATE_SPINNING) + traction += 0.1f; + } else { + for (int i = 0; i < 4; i++) + if (wheelState[i] == WHEEL_STATE_SPINNING) + traction += 0.05f; + } + break; + case 'F': + if (params.m_VehicleType == VEHICLE_TYPE_BIKE) { + if (wheelState[BIKEWHEEL_FRONT] == WHEEL_STATE_SPINNING) + traction += 0.2f; + } else { + if (wheelState[CARWHEEL_FRONT_LEFT] == WHEEL_STATE_SPINNING) + traction += 0.1f; + if (wheelState[CARWHEEL_FRONT_RIGHT] == WHEEL_STATE_SPINNING) + traction += 0.1f; + } + break; + case 'R': + if (params.m_VehicleType == VEHICLE_TYPE_BIKE) { + if (wheelState[BIKEWHEEL_REAR] == WHEEL_STATE_SPINNING) + traction += 0.2f; + } else { + if (wheelState[CARWHEEL_REAR_LEFT] == WHEEL_STATE_SPINNING) + traction += 0.1f; + if (wheelState[CARWHEEL_REAR_RIGHT] == WHEEL_STATE_SPINNING) + traction += 0.1f; + } + break; + default: + break; + } + } + } else if (params.m_fVelocityChange == 0.0f) { + traction = 0.9f; + } + if (transmission->fMaxVelocity <= 0.0f) { + relativeChange = 0.0f; + modificator = 0.0f; + } else { + if (!isMoped && !caddyBool) { + if (currentGear != 0) { + relativeGearChange = Min(1.0f, + params.m_fVelocityChange - transmission->Gears[currentGear].fShiftDownVelocity) / transmission->fMaxVelocity * 2.5f; + if (traction == 0.0f && veh->GetStatus() != STATUS_SIMPLE && + params.m_fVelocityChange < transmission->Gears[1].fShiftUpVelocity) + traction = 0.7f; + relativeChange = traction * *gasPedalAudioPtr * 0.95f + (1.0f - traction) * relativeGearChange; + } else { + relativeChange = Min(1.0f, + 1.0f - Abs((params.m_fVelocityChange - transmission->Gears[0].fShiftDownVelocity) / transmission->fMaxReverseVelocity)); + } + modificator = relativeChange; + } else { + modificator = Min(1.0f, Abs(params.m_fVelocityChange / transmission->fMaxVelocity > 1.0f)); + } + } + } else { + if (wheelsOnGroundPrev != 0) + *gasPedalAudioPtr *= 0.4f; + relativeChange = *gasPedalAudioPtr; + modificator = relativeChange; + } + if (currentGear != 0 || wheelsOnGround == 0) + freq = 1200 * currentGear + 18000.0f * modificator + 14000; + else if (params.m_VehicleType == VEHICLE_TYPE_BIKE) + freq = 22050; + else + freq = 13000.0f * modificator + 14000; + if (modificator >= 0.75f) + emittingVol = 90; + else + emittingVol = modificator * (4.0f / 3.0f) * 15.0f + 75; + } else { + modificator = 0.0f; + emittingVol = 75; + } + if (veh->bIsDrowning) + emittingVol /= 4; + if (caddyBool) { + emittingVol = 100.0f * modificator; + freq = 2130.0f * modificator + 4270; + m_sQueueSample.m_nCounter = 2; + } + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + if (!caddyBool) { + if (veh->GetStatus() == STATUS_SIMPLE) { + if (modificator < 0.02f) { + m_sQueueSample.m_nSampleIndex = aVehicleSettings[params.m_nIndex].m_nBank - CAR_SFX_BANKS_OFFSET + SFX_CAR_IDLE_1; + m_sQueueSample.m_nCounter = 52; + freq = 10000.0f * modificator + 22050; + } else { + m_sQueueSample.m_nSampleIndex = aVehicleSettings[params.m_nIndex].m_nAccelerationSampleIndex; + m_sQueueSample.m_nCounter = 2; + } + } else { + if (veh->m_fGasPedal < 0.02f) { + m_sQueueSample.m_nSampleIndex = aVehicleSettings[params.m_nIndex].m_nBank - CAR_SFX_BANKS_OFFSET + SFX_CAR_IDLE_1; + m_sQueueSample.m_nCounter = 52; + freq = 10000.0f * modificator + 22050; + } else { + m_sQueueSample.m_nSampleIndex = aVehicleSettings[params.m_nIndex].m_nAccelerationSampleIndex; + m_sQueueSample.m_nCounter = 2; + } + } + m_sQueueSample.m_nFrequency = freq + 100 * m_sQueueSample.m_nBankIndex % 1000; + } else { + if (FindVehicleOfPlayer() == params.m_pVehicle) + m_sQueueSample.m_nSampleIndex = SFX_CAR_AFTER_ACCEL_12; + else + m_sQueueSample.m_nSampleIndex = SFX_CAR_REV_12; + m_sQueueSample.m_nFrequency = freq + 20 * m_sQueueSample.m_nBankIndex % 100; + } + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + if (m_sQueueSample.m_nSampleIndex == SFX_CAR_IDLE_5 || m_sQueueSample.m_nSampleIndex == SFX_CAR_REV_5) + m_sQueueSample.m_nFrequency /= 2; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 6.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 8; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } +} + +void +cAudioManager::UpdateGasPedalAudio(CVehicle* veh, int vehType) +{ + float gasPedal = Abs(veh->m_fGasPedal); + float* gasPealAudioPtr; + + switch(vehType) { + case VEHICLE_TYPE_CAR: gasPealAudioPtr = &((CAutomobile *)veh)->m_fGasPedalAudio; break; + case VEHICLE_TYPE_BIKE: gasPealAudioPtr = &((CBike *)veh)->m_fGasPedalAudio; break; + default: return; + } + if (*gasPealAudioPtr < gasPedal) + *gasPealAudioPtr = Min(*gasPealAudioPtr + 0.09f, gasPedal); + else + *gasPealAudioPtr = Max(*gasPealAudioPtr - 0.07f, gasPedal); +} + +void +cAudioManager::PlayerJustGotInCar() const +{ + if (m_bIsInitialised) + bPlayerJustEnteredCar = true; +} + +void +cAudioManager::PlayerJustLeftCar(void) const +{ + // UNUSED: This is a perfectly empty function. +} + +void +cAudioManager::AddPlayerCarSample(uint8 emittingVolume, int32 freq, uint32 sample, uint8 bank, uint8 counter, bool notLooping) +{ + m_sQueueSample.m_nVolume = ComputeVolume(emittingVolume, 50.f, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = counter; + m_sQueueSample.m_nSampleIndex = sample; +#ifdef GTA_PS2 + m_sQueueSample.m_nBankIndex = bank; +#else + m_sQueueSample.m_nBankIndex = SFX_BANK_0; +#endif // GTA_PS2 + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 0; + m_sQueueSample.m_nFrequency = freq; + if (notLooping) { + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nReleasingVolumeDivider = 8; + } else { + m_sQueueSample.m_nLoopCount = 1; + } + m_sQueueSample.m_nEmittingVolume = emittingVolume; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 6.0f; + m_sQueueSample.m_fSoundIntensity = 50.0f; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } +} + +void +cAudioManager::ProcessCesna(cVehicleParams ¶ms) +{ + if(params.m_fDistance < SQR(200)) { + CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance); + m_sQueueSample.m_nVolume = ComputeVolume(80, 200.f, m_sQueueSample.m_fDistance); + if(m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 52; + m_sQueueSample.m_nSampleIndex = SFX_CESNA_IDLE; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 0; + m_sQueueSample.m_nFrequency = 12500; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nReleasingVolumeDivider = 8; + m_sQueueSample.m_nEmittingVolume = 80; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 4.0f; + m_sQueueSample.m_fSoundIntensity = 200.0f; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + if(params.m_fDistance < SQR(90)) { + m_sQueueSample.m_nVolume = ComputeVolume(80, 90.f, m_sQueueSample.m_fDistance); + if(m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 2; + m_sQueueSample.m_nSampleIndex = SFX_CESNA_REV; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nFrequency = 25000; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nReleasingVolumeDivider = 4; + m_sQueueSample.m_nEmittingVolume = 80; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 4.0f; + m_sQueueSample.m_fSoundIntensity = 90.0f; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + } +} + +void +cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams& params, CVehicle* veh) +{ + static int32 GearFreqAdj[] = { 6000, 6000, 3400, 1200, 0, -1000 }; + + tWheelState* wheelState; + CAutomobile* automobile; + CBike* bike; + CVector pos; + float* gasPedalAudioPtr; + + int32 accelerateState; + int32 brakeState; + int32 freq; + int32 baseFreq; + int32 freqModifier; + uint32 gearSoundLength; + uint32 soundOffset; + uint8 engineSoundType; + uint8 wheelInUseCounter; + uint8 wheelsOnGround; + uint8 vol; + uint8 currentGear; + uint8 wheelsOnGroundPrev; + + float accelerationMultipler; + float gasPedalAudio; + float velocityChangeForAudio; + float relativeVelocityChange; + float time; + bool channelUsed; + bool lostTraction; + bool noGearBox; + bool stuckInSand; + bool processedAccelSampleStopped; + bool isMoped; + + static uint32 gearSoundStartTime = CTimer::GetTimeInMilliseconds(); + static int32 nCruising = 0; + static int16 LastAccel = 0; + static uint8 CurrentPretendGear = 1; + static bool bLostTractionLastFrame = false; + static bool bHandbrakeOnLastFrame = false; + static bool bAccelSampleStopped = true; + + lostTraction = false; + isMoped = params.m_pVehicle->m_modelIndex == MI_PIZZABOY || params.m_pVehicle->m_modelIndex == MI_FAGGIO; + processedAccelSampleStopped = false; + if (bPlayerJustEnteredCar) { + bAccelSampleStopped = true; + bPlayerJustEnteredCar = false; + nCruising = 0; + LastAccel = 0; + bLostTractionLastFrame = false; + CurrentPretendGear = 1; + bHandbrakeOnLastFrame = false; + } + if (CReplay::IsPlayingBack()) { + accelerateState = (255.0f * clamp(params.m_pVehicle->m_fGasPedal, 0.0f, 1.0f)); + brakeState = (255.0f * clamp(params.m_pVehicle->m_fBrakePedal, 0.0f, 1.0f)); + } else { + accelerateState = Pads[0].GetAccelerate(); + brakeState = Pads[0].GetBrake(); + } + channelUsed = SampleManager.GetChannelUsedFlag(m_nActiveSamples); + if (isMoped) { + CurrentPretendGear = params.m_pTransmission->nNumberOfGears; + currentGear = CurrentPretendGear; + if (params.m_pVehicle->bIsHandbrakeOn) { + brakeState = 0; + nCruising = 0; + LastAccel = 0; + accelerateState = 0; + } else { + nCruising = 1; + } + } else { + currentGear = params.m_pVehicle->m_nCurrentGear; + } + + switch (params.m_VehicleType) { + case VEHICLE_TYPE_CAR: + automobile = (CAutomobile*)params.m_pVehicle; + wheelsOnGround = automobile->m_nDriveWheelsOnGround; + wheelsOnGroundPrev = automobile->m_nDriveWheelsOnGroundPrev; + gasPedalAudioPtr = &automobile->m_fGasPedalAudio; + wheelState = automobile->m_aWheelState; + velocityChangeForAudio = automobile->m_fVelocityChangeForAudio; + break; + case VEHICLE_TYPE_BIKE: + bike = (CBike*)params.m_pVehicle; + wheelsOnGround = bike->m_nDriveWheelsOnGround; + wheelsOnGroundPrev = bike->m_nDriveWheelsOnGroundPrev; + gasPedalAudioPtr = &bike->m_fGasPedalAudio; + wheelState = bike->m_aWheelState; + velocityChangeForAudio = bike->m_fVelocityChangeForAudio; + break; + default: + debug(" ** AUDIOLOG: Unrecognised vehicle type %d in ProcessVehicleEngine() * \n", params.m_VehicleType); + return; + } + if (!isMoped) { + switch (params.m_pTransmission->nDriveType) { + case '4': + if (params.m_VehicleType != VEHICLE_TYPE_BIKE) { + wheelInUseCounter = 0; + for (uint8 i = 0; i < 4; i++) { + if (wheelState[i] != WHEEL_STATE_NORMAL) + ++wheelInUseCounter; + } + if (wheelInUseCounter > 2) + lostTraction = true; + } + break; + case 'F': + if (params.m_VehicleType == VEHICLE_TYPE_BIKE) { + if (wheelState[BIKEWHEEL_FRONT] != WHEEL_STATE_NORMAL) + lostTraction = true; + } else { + if ((wheelState[CARWHEEL_FRONT_LEFT] != WHEEL_STATE_NORMAL || wheelState[CARWHEEL_FRONT_RIGHT] != WHEEL_STATE_NORMAL) && + (wheelState[CARWHEEL_REAR_LEFT] != WHEEL_STATE_NORMAL || wheelState[CARWHEEL_REAR_RIGHT] != WHEEL_STATE_NORMAL)) + lostTraction = true; + } + break; + case 'R': + if (params.m_VehicleType == VEHICLE_TYPE_BIKE) { + if (wheelState[BIKEWHEEL_REAR] != WHEEL_STATE_NORMAL) + lostTraction = true; + } else { + if (wheelState[CARWHEEL_REAR_LEFT] != WHEEL_STATE_NORMAL || wheelState[CARWHEEL_REAR_RIGHT] != WHEEL_STATE_NORMAL) + lostTraction = true; + } + break; + default: + break; + } + } + if (params.m_fVelocityChange != 0.0f) { + time = params.m_pVehicle->m_vecMoveSpeed.z / params.m_fVelocityChange; + if (time > 0.0f) + freqModifier = -(Min(0.2f, time) * 3000.0f * 5.0f); + else + freqModifier = -(Max(-0.2f, time) * 3000.0f * 5.0f); + if (params.m_fVelocityChange < -0.001f) + freqModifier = -freqModifier; + } else + freqModifier = 0; + if (params.m_VehicleType == VEHICLE_TYPE_BIKE && bike->bExtraSpeed) + freqModifier += 1400; + gearSoundLength = 0; + engineSoundType = aVehicleSettings[params.m_nIndex].m_nBank; + soundOffset = 3 * (engineSoundType - CAR_SFX_BANKS_OFFSET); + noGearBox = false; + switch (engineSoundType) { + case SFX_BANK_PONTIAC: + gearSoundLength = 2526; + break; + case SFX_BANK_PORSCHE: + gearSoundLength = 3587; + break; + case SFX_BANK_SPIDER: + gearSoundLength = 4898; + break; + case SFX_BANK_MERC: + gearSoundLength = 4003; + break; + case SFX_BANK_TRUCK: + gearSoundLength = 6289; + break; + case SFX_BANK_HOTROD: + gearSoundLength = 2766; + break; + case SFX_BANK_COBRA: + gearSoundLength = 3523; + break; + case SFX_BANK_PONTIAC_SLOW: + gearSoundLength = 2773; + break; + case SFX_BANK_CADILLAC: + gearSoundLength = 2560; + break; + case SFX_BANK_PATHFINDER: + gearSoundLength = 4228; + break; + case SFX_BANK_PACARD: + gearSoundLength = 4648; + break; + case SFX_BANK_VTWIN: + gearSoundLength = 3480; + break; + case SFX_BANK_HONDA250: + gearSoundLength = 2380; + break; + case SFX_BANK_SPORTS_BIKE: + gearSoundLength = 2410; + break; + default: + noGearBox = true; + break; + } + if (!channelUsed || nCruising || noGearBox) { + gearSoundStartTime = CTimer::GetTimeInMilliseconds(); + } else { + gearSoundLength -= 1000; + if (CTimer::GetTimeInMilliseconds() - gearSoundStartTime > gearSoundLength) { + channelUsed = false; + gearSoundStartTime = CTimer::GetTimeInMilliseconds(); + } + } + relativeVelocityChange = 2.0f * params.m_fVelocityChange / params.m_pTransmission->fMaxVelocity; + accelerationMultipler = clamp(relativeVelocityChange, 0.0f, 1.0f); + gasPedalAudio = accelerationMultipler; + switch (engineSoundType) { + case SFX_BANK_MOPED: + ++soundOffset; + break; + case SFX_BANK_HONDA250: + soundOffset += 2; + break; + case SFX_BANK_SPORTS_BIKE: + soundOffset += 3; + break; + default: + break; + } + if (accelerateState <= 0) { + if (params.m_fVelocityChange < -0.001f) { + if (channelUsed) { + SampleManager.StopChannel(m_nActiveSamples); + bAccelSampleStopped = true; + } + if (wheelsOnGround == 0 || params.m_pVehicle->bIsHandbrakeOn || lostTraction) + gasPedalAudio = *gasPedalAudioPtr; + else if (params.m_VehicleType == VEHICLE_TYPE_BIKE) + gasPedalAudio = 0.0f; + else + gasPedalAudio = Min(1.0f, params.m_fVelocityChange / params.m_pTransmission->fMaxReverseVelocity); + *gasPedalAudioPtr = Max(0.0f, gasPedalAudio); + } else if (LastAccel > 0) { + if (channelUsed) { + SampleManager.StopChannel(m_nActiveSamples); + bAccelSampleStopped = true; + } + nCruising = 0; + if (wheelsOnGround == 0 + || params.m_pVehicle->bIsHandbrakeOn + || lostTraction + || params.m_fVelocityChange < 0.01f && *gasPedalAudioPtr > 0.2f) { + if (isMoped) { + gasPedalAudio = 0.0f; + } else { + *gasPedalAudioPtr *= 0.6f; + gasPedalAudio = *gasPedalAudioPtr; + } + } + if (gasPedalAudio > 0.05f) { + freq = (5000.f * (gasPedalAudio - 0.05f) * 20.f / 19) + 19000; + vol = (25.0f * (gasPedalAudio - 0.05f) * 20.f / 19) + 40; + if (params.m_pVehicle->bIsDrowning) + vol /= 4; + if (engineSoundType == SFX_BANK_TRUCK) + freq /= 2; + AddPlayerCarSample(vol, freq, soundOffset + SFX_CAR_FINGER_OFF_ACCEL_1, engineSoundType, 63, false); + } + } + freq = (10000.f * gasPedalAudio) + 22050; + vol = 110 - (40.0f * gasPedalAudio); + if (engineSoundType == SFX_BANK_TRUCK) + freq /= 2; + if (params.m_pVehicle->bIsDrowning) + vol /= 4; + AddPlayerCarSample(vol, freq, engineSoundType - CAR_SFX_BANKS_OFFSET + SFX_CAR_IDLE_1, SFX_BANK_0, 52, true); + + CurrentPretendGear = Max(1, currentGear); + } + else { + if (nCruising == 0){ + stuckInSand = params.m_VehicleType == VEHICLE_TYPE_CAR && ((CAutomobile*)params.m_pVehicle)->bStuckInSand; + if (accelerateState < 150 || wheelsOnGround == 0 || params.m_pVehicle->bIsHandbrakeOn || lostTraction + || (currentGear < 2 && params.m_fVelocityChange - velocityChangeForAudio < 0.01f) || brakeState > 0) { + + if (((wheelsOnGround && !params.m_pVehicle->bIsHandbrakeOn && !lostTraction ) || stuckInSand) && brakeState <= 0) { + baseFreq = (8000.0f * accelerationMultipler) + 16000; + vol = (25.0f * accelerationMultipler) + 60; + *gasPedalAudioPtr = accelerationMultipler; + } else { + if (wheelsOnGround == 0 && wheelsOnGroundPrev != 0 || (params.m_pVehicle->bIsHandbrakeOn && !bHandbrakeOnLastFrame || lostTraction && !bLostTractionLastFrame) + && wheelsOnGround != 0) { + *gasPedalAudioPtr *= 0.6f; + } + freqModifier = 0; + if (engineSoundType != SFX_BANK_GOLF_CART && engineSoundType != SFX_BANK_CAR_CHAINSAW) + baseFreq = (25000.0f * *gasPedalAudioPtr) + 14000; + else + baseFreq = (15000.0f * *gasPedalAudioPtr) + 14000; + vol = (25.0f * *gasPedalAudioPtr) + 60; + } + freq = freqModifier + baseFreq; + if (engineSoundType == SFX_BANK_TRUCK) + freq /= 2; + if (channelUsed) { + SampleManager.StopChannel(m_nActiveSamples); + bAccelSampleStopped = true; + } + if (params.m_pVehicle->bIsDrowning) + vol /= 4; + AddPlayerCarSample(vol, freq, engineSoundType - CAR_SFX_BANKS_OFFSET + SFX_CAR_REV_1, SFX_BANK_0, 2, true); + } else { + TranslateEntity(&m_sQueueSample.m_vecPos, &pos); + if (bAccelSampleStopped) { + if (CurrentPretendGear != 1 || currentGear != 2) + CurrentPretendGear = Max(1, currentGear - 1); + processedAccelSampleStopped = true; + bAccelSampleStopped = false; + } + if (channelUsed) { + SampleManager.SetChannelEmittingVolume(m_nActiveSamples, 120); + SampleManager.SetChannel3DPosition(m_nActiveSamples, pos.x, pos.y, pos.z); + SampleManager.SetChannel3DDistances(m_nActiveSamples, 50.0f, 12.5f); + freq = (GearFreqAdj[CurrentPretendGear] + freqModifier + 22050) ; + if (engineSoundType == SFX_BANK_TRUCK) + freq /= 2; + SampleManager.SetChannelFrequency(m_nActiveSamples, freq); + if (!channelUsed) { + SampleManager.SetChannelReverbFlag(m_nActiveSamples, m_bDynamicAcousticModelingStatus != false); + SampleManager.StartChannel(m_nActiveSamples); + } + } else if (processedAccelSampleStopped) { + gearSoundStartTime = CTimer::GetTimeInMilliseconds(); + params.m_pVehicle->bAudioChangingGear = true; + if (!SampleManager.InitialiseChannel(m_nActiveSamples, soundOffset + SFX_CAR_ACCEL_1, SFX_BANK_0)) + return; + SampleManager.SetChannelLoopCount(m_nActiveSamples, 1); + SampleManager.SetChannelLoopPoints(m_nActiveSamples, 0, -1); + + SampleManager.SetChannelEmittingVolume(m_nActiveSamples, 120); + SampleManager.SetChannel3DPosition(m_nActiveSamples, pos.x, pos.y, pos.z); + SampleManager.SetChannel3DDistances(m_nActiveSamples, 50.0f, 12.5f); + freq = (GearFreqAdj[CurrentPretendGear] + freqModifier + 22050); + if (engineSoundType == SFX_BANK_TRUCK) + freq /= 2; + SampleManager.SetChannelFrequency(m_nActiveSamples, freq); + if (!channelUsed) { + SampleManager.SetChannelReverbFlag(m_nActiveSamples, m_bDynamicAcousticModelingStatus != false); + SampleManager.StartChannel(m_nActiveSamples); + } + } else if (CurrentPretendGear < params.m_pTransmission->nNumberOfGears - 1) { + ++CurrentPretendGear; + gearSoundStartTime = CTimer::GetTimeInMilliseconds(); + params.m_pVehicle->bAudioChangingGear = true; + if (!SampleManager.InitialiseChannel(m_nActiveSamples, soundOffset + SFX_CAR_ACCEL_1, SFX_BANK_0)) + return; + SampleManager.SetChannelLoopCount(m_nActiveSamples, 1); + SampleManager.SetChannelLoopPoints(m_nActiveSamples, 0, -1); + + SampleManager.SetChannelEmittingVolume(m_nActiveSamples, 120); + SampleManager.SetChannel3DPosition(m_nActiveSamples, pos.x, pos.y, pos.z); + SampleManager.SetChannel3DDistances(m_nActiveSamples, 50.0f, 12.5f); + freq = (GearFreqAdj[CurrentPretendGear] + freqModifier + 22050); + if (engineSoundType == SFX_BANK_TRUCK) + freq /= 2; + SampleManager.SetChannelFrequency(m_nActiveSamples, freq); + if (!channelUsed) { + SampleManager.SetChannelReverbFlag(m_nActiveSamples, m_bDynamicAcousticModelingStatus != false); + SampleManager.StartChannel(m_nActiveSamples); + } + } else { + nCruising = 1; + goto PlayCruising; + } + } + } else { +PlayCruising: + bAccelSampleStopped = true; + SampleManager.StopChannel(m_nActiveSamples); + if (isMoped || accelerateState >= 150 && wheelsOnGround && brakeState <= 0 && !params.m_pVehicle->bIsHandbrakeOn + && !lostTraction && currentGear >= params.m_pTransmission->nNumberOfGears - 1) { + if (accelerateState >= 220 && params.m_fVelocityChange + 0.001f >= velocityChangeForAudio) { + if (nCruising < 800) + ++nCruising; + } else if (nCruising > 3) { + --nCruising; + } + freq = 27 * nCruising + freqModifier + 22050; + if (engineSoundType == SFX_BANK_TRUCK) + freq /= 2; + AddPlayerCarSample(120, freq, soundOffset + SFX_CAR_AFTER_ACCEL_1, engineSoundType, 64, true); + } else { + nCruising = 0; + } + } + } + LastAccel = accelerateState; + bHandbrakeOnLastFrame = params.m_pVehicle->bIsHandbrakeOn; + bLostTractionLastFrame = lostTraction; + return; +} + +bool +cAudioManager::ProcessVehicleSkidding(cVehicleParams& params) +{ + const float SOUND_INTENSITY = 40.0f; + + CAutomobile *automobile; + CBike *bike; + uint8 numWheels; + uint8 wheelsOnGround; + float gasPedalAudio; + tWheelState* wheelStateArr; + + + cTransmission *transmission; + int32 emittingVol; + float newSkidVal = 0.0f; + float skidVal = 0.0f; + + if (params.m_fDistance >= SQR(SOUND_INTENSITY)) + return false; + switch (params.m_VehicleType) { + case VEHICLE_TYPE_CAR: + automobile = (CAutomobile*)params.m_pVehicle; + numWheels = 4; + wheelStateArr = automobile->m_aWheelState; + wheelsOnGround = automobile->m_nWheelsOnGround; + gasPedalAudio = automobile->m_fGasPedalAudio; + break; + case VEHICLE_TYPE_BIKE: + bike = (CBike*)params.m_pVehicle; + numWheels = 2; + wheelStateArr = bike->m_aWheelState; + wheelsOnGround = bike->m_nWheelsOnGround; + gasPedalAudio = bike->m_fGasPedalAudio; + break; + default: + debug("\n * AUDIOLOG: ProcessVehicleSkidding() Unsupported vehicle type %d * \n", params.m_VehicleType); + return true; + } + if (wheelsOnGround == 0) + return true; + CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance); + + for (int32 i = 0; i < numWheels; i++) { + if (wheelStateArr[i] == WHEEL_STATE_NORMAL) + continue; + transmission = params.m_pTransmission; + switch (transmission->nDriveType) { + case '4': + newSkidVal = GetVehicleDriveWheelSkidValue(params.m_pVehicle, wheelStateArr[i], gasPedalAudio, transmission, params.m_fVelocityChange); + break; + case 'F': + if (i == CARWHEEL_FRONT_LEFT || i == CARWHEEL_FRONT_RIGHT) + newSkidVal = GetVehicleDriveWheelSkidValue(params.m_pVehicle, wheelStateArr[i], gasPedalAudio, transmission, params.m_fVelocityChange); + else + newSkidVal = GetVehicleNonDriveWheelSkidValue(params.m_pVehicle, wheelStateArr[i], transmission, params.m_fVelocityChange); + break; + case 'R': + if (i == CARWHEEL_REAR_LEFT || i == CARWHEEL_REAR_RIGHT) + newSkidVal = GetVehicleDriveWheelSkidValue(params.m_pVehicle, wheelStateArr[i], gasPedalAudio, transmission, params.m_fVelocityChange); + else + newSkidVal = GetVehicleNonDriveWheelSkidValue(params.m_pVehicle, wheelStateArr[i], transmission, params.m_fVelocityChange); + break; + default: + break; + } + skidVal = Max(skidVal, newSkidVal); + } + + if (skidVal > 0.0f) { + emittingVol = 50.f * skidVal; + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 3; + switch (params.m_pVehicle->m_nSurfaceTouched) { + case SURFACE_GRASS: + case SURFACE_HEDGE: + m_sQueueSample.m_nSampleIndex = SFX_RAIN; + emittingVol /= 4; + m_sQueueSample.m_nFrequency = 13000.f * skidVal + 35000.f; + m_sQueueSample.m_nVolume /= 4; + if (m_sQueueSample.m_nVolume == 0) + return true; + break; + case SURFACE_GRAVEL: + case SURFACE_MUD_DRY: + case SURFACE_SAND: + case SURFACE_WATER: + case SURFACE_SAND_BEACH: + m_sQueueSample.m_nSampleIndex = SFX_GRAVEL_SKID; + m_sQueueSample.m_nFrequency = 6000.f * skidVal + 10000.f; + break; + + default: + m_sQueueSample.m_nSampleIndex = SFX_SKID; + m_sQueueSample.m_nFrequency = 5000.f * skidVal + 11000.f; + if (params.m_VehicleType == VEHICLE_TYPE_BIKE) + m_sQueueSample.m_nFrequency += 2000; + break; + } + + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 8; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 3.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + return true; +} + +float +cAudioManager::GetVehicleDriveWheelSkidValue(CVehicle *veh, tWheelState wheelState, float gasPedalAudio, cTransmission *transmission, float velocityChange) +{ + float relativeVelChange = 0.0f; + float velChange; + float relativeVel; + + switch (wheelState) + { + case WHEEL_STATE_SPINNING: + if (gasPedalAudio > 0.4f) + relativeVelChange = (gasPedalAudio - 0.4f) * (5.0f / 3.0f) * 0.75f; + break; + case WHEEL_STATE_SKIDDING: + relativeVelChange = Min(1.0f, Abs(velocityChange) / transmission->fMaxVelocity); + break; + case WHEEL_STATE_FIXED: + relativeVel = gasPedalAudio; + if (relativeVel > 0.4f) + relativeVel = (gasPedalAudio - 0.4f) * (5.0f / 3.0f); + + velChange = Abs(velocityChange); + if (velChange > 0.04f) + relativeVelChange = Min(1.0f, velChange / transmission->fMaxVelocity); + if (relativeVel > relativeVelChange) + relativeVelChange = relativeVel; + + break; + default: + break; + } + + return Max(relativeVelChange, Min(1.0f, Abs(veh->m_vecTurnSpeed.z) * 20.0f)); +} + +float +cAudioManager::GetVehicleNonDriveWheelSkidValue(CVehicle *veh, tWheelState wheelState, cTransmission *transmission, float velocityChange) +{ + float relativeVelChange = 0.0f; + + if (wheelState == WHEEL_STATE_SKIDDING) + relativeVelChange = Min(1.0f, Abs(velocityChange) / transmission->fMaxVelocity); + + return Max(relativeVelChange, Min(1.0f, Abs(veh->m_vecTurnSpeed.z) * 20.0f)); +} + +bool +cAudioManager::ProcessVehicleHorn(cVehicleParams& params) +{ + const float SOUND_INTENSITY = 40.0f; + + CVehicle *veh; + uint8 volume; + + if (params.m_fDistance >= SQR(SOUND_INTENSITY)) + return false; + + veh = params.m_pVehicle; + if (veh->m_bSirenOrAlarm && UsesSirenSwitching(params)) + return true; + + if (veh->m_modelIndex == MI_MRWHOOP) + return true; + + if (veh->IsAlarmOn()) + return true; + + if (veh->m_nCarHornTimer != 0) { + if (veh->GetStatus() != STATUS_PLAYER) { + veh->m_nCarHornTimer = Min(44, veh->m_nCarHornTimer); + if (veh->m_nCarHornTimer == 44) + veh->m_nCarHornPattern = (m_FrameCounter + m_sQueueSample.m_nEntityIndex) & 7; + + if (!hornPatternsArray[veh->m_nCarHornPattern][44 - veh->m_nCarHornTimer]) + return true; + } + + CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance); + volume = veh->bIsDrowning ? 20 : 80; + m_sQueueSample.m_nVolume = ComputeVolume(volume, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 4; + m_sQueueSample.m_nSampleIndex = aVehicleSettings[params.m_nIndex].m_nHornSample; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 2; + m_sQueueSample.m_nFrequency = aVehicleSettings[params.m_nIndex].m_nHornFrequency; + m_sQueueSample.m_nLoopCount = 0; +#ifdef FIX_BUGS + m_sQueueSample.m_nEmittingVolume = volume; +#else + m_sQueueSample.m_nEmittingVolume = 80; +#endif + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 5.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 4; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + return true; +} + +bool +cAudioManager::UsesSiren(cVehicleParams& params) const +{ + return params.m_pVehicle->UsesSiren(); +} + +bool +cAudioManager::UsesSirenSwitching(cVehicleParams& params) const +{ + if (params.m_nIndex == FIRETRUK || params.m_nIndex == MRWHOOP) + return false; + return UsesSiren(params); +} + +bool +cAudioManager::ProcessVehicleSirenOrAlarm(cVehicleParams& params) +{ + const float SOUND_INTENSITY = 110.0f; + + CVehicle *veh; + uint8 volume; + + if (params.m_fDistance >= SQR(SOUND_INTENSITY)) + return false; + + veh = params.m_pVehicle; + if (!veh->m_bSirenOrAlarm && !veh->IsAlarmOn()) + return true; + + if (veh->IsAlarmOn()) { + if (CTimer::GetTimeInMilliseconds() > veh->m_nCarHornTimer) + veh->m_nCarHornTimer = CTimer::GetTimeInMilliseconds() + 750; + + if (veh->m_nCarHornTimer < CTimer::GetTimeInMilliseconds() + 375) + return true; + } + + CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance); + volume = veh->bIsDrowning ? 20 : 80; + m_sQueueSample.m_nVolume = ComputeVolume(volume, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 5; + if (UsesSiren(params)) { + if (params.m_pVehicle->GetStatus() == STATUS_ABANDONED) + return true; + if (veh->m_nCarHornTimer != 0 && params.m_nIndex != FIRETRUK && params.m_nIndex != MRWHOOP) { + m_sQueueSample.m_nSampleIndex = SFX_SIREN_FAST; + if (params.m_nIndex == FBIRANCH) + m_sQueueSample.m_nFrequency = 12668; + else + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_SIREN_FAST); + m_sQueueSample.m_nCounter = 60; + } else if (params.m_nIndex == VICECHEE) { + m_sQueueSample.m_nSampleIndex = SFX_POLICE_SIREN_SLOW; + m_sQueueSample.m_nFrequency = 11440; + } else { + m_sQueueSample.m_nSampleIndex = aVehicleSettings[params.m_nIndex].m_nSirenOrAlarmSample; + m_sQueueSample.m_nFrequency = aVehicleSettings[params.m_nIndex].m_nSirenOrAlarmFrequency; + } + } else { + m_sQueueSample.m_nSampleIndex = aVehicleSettings[params.m_nIndex].m_nHornSample; + m_sQueueSample.m_nFrequency = aVehicleSettings[params.m_nIndex].m_nHornFrequency; + } + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = volume; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 7.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 5; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + return true; +} + +bool +cAudioManager::UsesReverseWarning(int32 model) const +{ + return model == LINERUN || model == FIRETRUK || model == BUS || model == COACH || model == PACKER || model == FLATBED; +} + +bool +cAudioManager::ProcessVehicleReverseWarning(cVehicleParams& params) +{ + const float SOUND_INTENSITY = 50.0f; + + CVehicle *veh = params.m_pVehicle; + uint8 volume; + + if (params.m_fDistance >= SQR(SOUND_INTENSITY)) + return false; + + if (veh->bEngineOn && veh->m_fGasPedal < 0.0f) { + CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance); + volume = veh->bIsDrowning ? 15 : 60; + m_sQueueSample.m_nVolume = ComputeVolume(volume, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 12; + m_sQueueSample.m_nSampleIndex = SFX_REVERSE_WARNING; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 2; + m_sQueueSample.m_nFrequency = (100 * m_sQueueSample.m_nEntityIndex & 1023) + SampleManager.GetSampleBaseFrequency(SFX_REVERSE_WARNING); + m_sQueueSample.m_nLoopCount = 0; +#ifdef FIX_BUGS + m_sQueueSample.m_nEmittingVolume = volume; +#else + m_sQueueSample.m_nEmittingVolume = 60; +#endif + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 3.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + return true; +} + +bool +cAudioManager::ProcessVehicleDoors(cVehicleParams& params) +{ + const float SOUND_INTENSITY = 40.0f; + + CAutomobile *automobile; + int8 doorState; + int32 emittingVol; + float velocity; + + if (params.m_fDistance >= SQR(SOUND_INTENSITY)) + return false; + + automobile = (CAutomobile *)params.m_pVehicle; + CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance); + for (int32 i = 0; i < ARRAY_SIZE(automobile->Doors); i++) { + if (automobile->Damage.GetDoorStatus(i) == DOOR_STATUS_SWINGING) { + doorState = automobile->Doors[i].m_nDoorState; + if (doorState == DOORST_OPEN || doorState == DOORST_CLOSED) { + velocity = Min(0.3f, Abs(automobile->Doors[i].m_fAngVel)); + if (velocity > 0.0035f) { + emittingVol = (100.0f * velocity * 10.0f / 3.0f); + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = i + 6; + m_sQueueSample.m_nSampleIndex = m_anRandomTable[1] % 6 + SFX_COL_CAR_PANEL_1; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex) + RandomDisplacement(1000); + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 10; + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_fSpeedMultiplier = 1.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = true; + AddSampleToRequestedQueue(); + } + } + } + } + } + return true; +} + +bool +cAudioManager::ProcessAirBrakes(cVehicleParams& params) +{ + const float SOUND_INTENSITY = 30.0f; + CAutomobile *automobile; + uint8 volume; + + if (params.m_fDistance > SQR(SOUND_INTENSITY)) + return false; + automobile = (CAutomobile *)params.m_pVehicle; + if (!automobile->bEngineOn) + return true; + + if ((automobile->m_fVelocityChangeForAudio < 0.025f || params.m_fVelocityChange >= 0.025f) && + (automobile->m_fVelocityChangeForAudio > -0.025f || params.m_fVelocityChange <= 0.025f)) + return true; + + CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance); + volume = m_anRandomTable[0] % 10 + 70; + m_sQueueSample.m_nVolume = ComputeVolume(volume, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 13; + m_sQueueSample.m_nSampleIndex = SFX_AIR_BRAKES; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_AIR_BRAKES); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16); + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 10; + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nEmittingVolume = volume; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + + return true; +} + +bool +cAudioManager::HasAirBrakes(int32 model) const +{ + return model == LINERUN || model == FIRETRUK || model == TRASH || model == BUS || model == BARRACKS + || model == COACH || model == PACKER || model == FLATBED; +} + +bool +cAudioManager::ProcessEngineDamage(cVehicleParams& params) +{ + const float SOUND_INTENSITY = 40.0f; + + float health; + uint8 emittingVolume; + + if (params.m_fDistance >= SQR(SOUND_INTENSITY)) + return false; + if (params.m_pVehicle->m_modelIndex == MI_CADDY) + return true; + if (params.m_pVehicle->GetStatus() == STATUS_WRECKED) + return true; + health = params.m_pVehicle->m_fHealth; + if (health < 390.0f) { + if (health < 250.0f) { + emittingVolume = 60; + m_sQueueSample.m_nSampleIndex = SFX_CAR_ON_FIRE; + m_sQueueSample.m_nReleasingVolumeModificator = 7; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CAR_ON_FIRE); + } else { + emittingVolume = 30; + m_sQueueSample.m_nSampleIndex = SFX_PALM_TREE_LO; + m_sQueueSample.m_nReleasingVolumeModificator = 7; + m_sQueueSample.m_nFrequency = 27000; + } + CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance); + if (params.m_pVehicle->bIsDrowning) + emittingVolume /= 2; + m_sQueueSample.m_nVolume = ComputeVolume(emittingVolume, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 28; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = emittingVolume; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + return true; +} + +bool +cAudioManager::ProcessCarBombTick(cVehicleParams& params) +{ + const float SOUND_INTENSITY = 40.0f; + const uint8 EMITTING_VOLUME = 60; + + uint8 bombType; + + if (params.m_fDistance >= SQR(SOUND_INTENSITY)) + return false; + if (params.m_pVehicle->bEngineOn) { + switch (params.m_VehicleType) { + case VEHICLE_TYPE_CAR: + bombType = params.m_pVehicle->m_bombType; + break; + case VEHICLE_TYPE_BIKE: + bombType = params.m_pVehicle->m_bombType; + break; + default: + debug("\n * AUDIOLOG: ProcessCarBombTick() Unsupported vehicle type %d * \n", params.m_VehicleType); + return true; + break; + } + if (bombType == CARBOMB_TIMEDACTIVE) { + CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance); + m_sQueueSample.m_nVolume = ComputeVolume(EMITTING_VOLUME, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 35; + m_sQueueSample.m_nSampleIndex = SFX_COUNTDOWN; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 0; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_COUNTDOWN); + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = EMITTING_VOLUME; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + } + return true; +} + +void +cAudioManager::ProcessVehicleOneShots(cVehicleParams& params) +{ + int16 event; + uint8 emittingVol; + float relVol; + float vol; + bool noReflections; + bool isHeli; + float maxDist; + static uint8 GunIndex = 53; + + for (int i = 0; i < m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_AudioEvents; i++) { + noReflections = false; + isHeli = false; + m_sQueueSample.m_bRequireReflection = false; + event = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i]; + switch (event) { + case SOUND_CAR_DOOR_CLOSE_BONNET: + case SOUND_CAR_DOOR_CLOSE_BUMPER: + case SOUND_CAR_DOOR_CLOSE_FRONT_LEFT: + case SOUND_CAR_DOOR_CLOSE_FRONT_RIGHT: + case SOUND_CAR_DOOR_CLOSE_BACK_LEFT: + case SOUND_CAR_DOOR_CLOSE_BACK_RIGHT: { + const float SOUND_INTENSITY = 50.0f; + maxDist = SQR(SOUND_INTENSITY); + emittingVol = m_anRandomTable[2] % 5 + 122; + switch (aVehicleSettings[params.m_nIndex].m_bDoorType) { + case OLD_DOOR: + m_sQueueSample.m_nSampleIndex = SFX_OLD_CAR_DOOR_CLOSE; + break; + case NEW_DOOR: + m_sQueueSample.m_nSampleIndex = SFX_NEW_CAR_DOOR_CLOSE; + break; + case TRUCK_DOOR: + m_sQueueSample.m_nSampleIndex = SFX_TRUCK_DOOR_CLOSE; + break; + case BUS_DOOR: + m_sQueueSample.m_nSampleIndex = SFX_AIR_BRAKES; + break; + default: + m_sQueueSample.m_nSampleIndex = SFX_NEW_CAR_DOOR_CLOSE; + break; + } + m_sQueueSample.m_nBankIndex = SFX_BANK_0; +#ifdef THIS_IS_STUPID + m_sQueueSample.m_nCounter = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i] + 22; +#else + m_sQueueSample.m_nCounter = event + 22; +#endif + if (params.m_pVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_HELI) + m_sQueueSample.m_nFrequency = 28062; + else + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bRequireReflection = true; + break; + } + case SOUND_CAR_DOOR_OPEN_BONNET: + case SOUND_CAR_DOOR_OPEN_BUMPER: + case SOUND_CAR_DOOR_OPEN_FRONT_LEFT: + case SOUND_CAR_DOOR_OPEN_FRONT_RIGHT: + case SOUND_CAR_DOOR_OPEN_BACK_LEFT: + case SOUND_CAR_DOOR_OPEN_BACK_RIGHT: { + const float SOUND_INTENSITY = 50.0f; + maxDist = SQR(SOUND_INTENSITY); + emittingVol = m_anRandomTable[1] % 10 + 117; + switch (aVehicleSettings[params.m_nIndex].m_bDoorType) { + case OLD_DOOR: + m_sQueueSample.m_nSampleIndex = SFX_OLD_CAR_DOOR_OPEN; + break; + case TRUCK_DOOR: + m_sQueueSample.m_nSampleIndex = SFX_TRUCK_DOOR_OPEN; + break; + case BUS_DOOR: + m_sQueueSample.m_nSampleIndex = SFX_AIR_BRAKES; + break; + default: + m_sQueueSample.m_nSampleIndex = SFX_NEW_CAR_DOOR_OPEN; + break; + } + m_sQueueSample.m_nBankIndex = SFX_BANK_0; +#ifdef THIS_IS_STUPID + m_sQueueSample.m_nCounter = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i] + 10; +#else + m_sQueueSample.m_nCounter = event + 10; +#endif + if (params.m_pVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_HELI) + m_sQueueSample.m_nFrequency = 23459; + else + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bRequireReflection = true; + break; + } + case SOUND_CAR_WINDSHIELD_CRACK: { + const float SOUND_INTENSITY = 40.0f; + maxDist = SQR(SOUND_INTENSITY); + m_sQueueSample.m_nSampleIndex = SFX_GLASS_CRACK; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = 68; + emittingVol = m_anRandomTable[1] % 30 + 80; //GetRandomNumberInRange(1, 80, 109) + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_GLASS_CRACK); + m_sQueueSample.m_nReleasingVolumeModificator = 5; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + } break; + case SOUND_CAR_JUMP: + case SOUND_CAR_JUMP_2: { + const float SOUND_INTENSITY = 35.0f; + static uint8 WheelIndex = 82; + maxDist = SQR(SOUND_INTENSITY); +#ifdef THIS_IS_STUPID + if (m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i] == SOUND_CAR_JUMP_2) { +#else + if (event == SOUND_CAR_JUMP_2) { +#endif + m_sQueueSample.m_nSampleIndex = SFX_TYRE_BURST_B; + emittingVol = Max(50.0f, 2 * (60.0f * m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i])); + } else { + m_sQueueSample.m_nSampleIndex = SFX_TYRE_BUMP; + emittingVol = Max(80.f, 2 * (100.0f * m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i])); + } + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = WheelIndex++; + if (WheelIndex > 85) + WheelIndex = 82; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_TYRE_BUMP); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16); + if (params.m_VehicleType == VEHICLE_TYPE_BIKE) + m_sQueueSample.m_nFrequency *= 2; + m_sQueueSample.m_nReleasingVolumeModificator = 6; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + break; + } + case SOUND_CAR_TYRE_POP: { + const float SOUND_INTENSITY = 60.0f; + static uint8 WheelIndex = 91; + m_sQueueSample.m_nSampleIndex = SFX_TYRE_BURST; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = WheelIndex++; + if (WheelIndex > 94) + WheelIndex = 91; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_TYRE_BURST); + m_sQueueSample.m_nFrequency += RandomDisplacement(2000); + m_sQueueSample.m_nReleasingVolumeModificator = 2; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + maxDist = SQR(SOUND_INTENSITY); + emittingVol = m_anRandomTable[4] % 10 + 117; + break; + } + case SOUND_CAR_ENGINE_START: { + const float SOUND_INTENSITY = 40.0f; + if (params.m_pVehicle->GetVehicleAppearance() != VEHICLE_APPEARANCE_CAR + || params.m_pVehicle->m_modelIndex == MI_CADDY) + continue; + emittingVol = 60; + maxDist = SQR(SOUND_INTENSITY); + m_sQueueSample.m_nSampleIndex = SFX_CAR_STARTER; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = 33; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CAR_STARTER); + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bRequireReflection = true; + break; + } + case SOUND_CAR_LIGHT_BREAK: { + const float SOUND_INTENSITY = 30.0f; + m_sQueueSample.m_nSampleIndex = SFX_GLASS_SHARD_1; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = 37; + m_sQueueSample.m_nFrequency = 9 * SampleManager.GetSampleBaseFrequency(SFX_GLASS_SHARD_1) / 10; + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 8); + m_sQueueSample.m_nReleasingVolumeModificator = 5; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + maxDist = SQR(SOUND_INTENSITY); + emittingVol = m_anRandomTable[4] % 10 + 30; + break; + } + case SOUND_CAR_HYDRAULIC_1: + case SOUND_CAR_HYDRAULIC_2: { + const float SOUND_INTENSITY = 35.0f; + if (event == SOUND_CAR_HYDRAULIC_1) + m_sQueueSample.m_nFrequency = 15600; + else + m_sQueueSample.m_nFrequency = 13118; + m_sQueueSample.m_nSampleIndex = SFX_SUSPENSION_FAST_MOVE; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = 51; + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 8); + m_sQueueSample.m_nReleasingVolumeModificator = 5; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + maxDist = SQR(SOUND_INTENSITY); + emittingVol = m_anRandomTable[0] % 15 + 55; + break; + } + case SOUND_CAR_HYDRAULIC_3: { + const float SOUND_INTENSITY = 35.0f; + m_sQueueSample.m_nSampleIndex = SFX_SUSPENSION_SLOW_MOVE_LOOP; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = 86; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_SUSPENSION_SLOW_MOVE_LOOP); + m_sQueueSample.m_nReleasingVolumeModificator = 5; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_nReleasingVolumeDivider = 7; + noReflections = true; + maxDist = SQR(SOUND_INTENSITY); + emittingVol = m_anRandomTable[0] % 15 + 55; + break; + } + case SOUND_CAR_JERK: { + const float SOUND_INTENSITY = 35.0f; + m_sQueueSample.m_nSampleIndex = SFX_SHAG_SUSPENSION; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = 87; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_SHAG_SUSPENSION); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 8); + m_sQueueSample.m_nReleasingVolumeModificator = 5; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + maxDist = SQR(SOUND_INTENSITY); + emittingVol = m_anRandomTable[1] % 15 + 55; + break; + } + case SOUND_CAR_SPLASH: { + const float SOUND_INTENSITY = 60.0f; + static uint8 WaveIndex = 41; + vol = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]; + if (vol <= 150.0f) + continue; + if (vol > 800.0f) + m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i] = 800.0f; + relVol = (m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i] - 150.0f) / 650.0f; + m_sQueueSample.m_nSampleIndex = (m_anRandomTable[0] & 1) + SFX_BOAT_SPLASH_1; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = WaveIndex++; + if (WaveIndex > 46) + WaveIndex = 41; + m_sQueueSample.m_nFrequency = (7000.0f * relVol) + 6000; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + emittingVol = (35.0f * relVol); + maxDist = SQR(SOUND_INTENSITY); + break; + } + /*case SOUND_17: { + const float SOUND_INTENSITY = 50.0f; + m_sQueueSample.m_nSampleIndex = SFX_POLICE_BOAT_THUMB_OFF; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = 47; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_POLICE_BOAT_THUMB_OFF) + RandomDisplacement(600); + m_sQueueSample.m_nReleasingVolumeModificator = 2; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + emittingVol = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]; + maxDist = SQR(SOUND_INTENSITY); + break; + }*/ +#ifdef GTA_TRAIN + case SOUND_TRAIN_DOOR_CLOSE: + case SOUND_TRAIN_DOOR_OPEN: { + const float SOUND_INTENSITY = 35.0f; + m_sQueueSample.m_nSampleIndex = SFX_AIR_BRAKES; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = 59; + m_sQueueSample.m_nFrequency = RandomDisplacement(1000) + 11025; + m_sQueueSample.m_nReleasingVolumeModificator = 5; + m_sQueueSample.m_fSpeedMultiplier = 5.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + maxDist = SQR(SOUND_INTENSITY); + emittingVol = m_anRandomTable[1] % 20 + 70; + break; + } +#endif + case SOUND_CAR_TANK_TURRET_ROTATE: { + const float SOUND_INTENSITY = 40.0f; + vol = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]; + if (vol > 24.0f / 625.0f) + vol = 24.0f / 625.0f; + m_sQueueSample.m_nSampleIndex = SFX_TANK_TURRET; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = 79; + m_sQueueSample.m_nFrequency = (3000.0f * vol * 625.0f / 24.0f) + 9000; + m_sQueueSample.m_nReleasingVolumeModificator = 2; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + emittingVol = (37.0f * vol * 625.0f / 24.0f) + 90; + maxDist = SQR(SOUND_INTENSITY); + noReflections = true; + break; + } + case SOUND_CAR_BOMB_TICK: { + const float SOUND_INTENSITY = 30.0f; + m_sQueueSample.m_nSampleIndex = SFX_BOMB_BEEP; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = 80; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_BOMB_BEEP); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + maxDist = SQR(SOUND_INTENSITY); + m_sQueueSample.m_bRequireReflection = true; + emittingVol = 60; + break; + } + case SOUND_PLANE_ON_GROUND: { + const float SOUND_INTENSITY = 180.0f; + m_sQueueSample.m_nSampleIndex = SFX_JUMBO_LAND_WHEELS; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = 81; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_JUMBO_LAND_WHEELS); + m_sQueueSample.m_nReleasingVolumeModificator = 2; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + maxDist = SQR(SOUND_INTENSITY); + emittingVol = m_anRandomTable[4] % 25 + 75; + break; + } + case SOUND_HELI_BLADE:{ + const float SOUND_INTENSITY = 35.0f; + static uint8 HeliIndex = 89; + relVol = ((CAutomobile*)params.m_pVehicle)->m_aWheelSpeed[1] * 50.0f / 11.0f; + if (relVol < 0.2f || relVol == 1.0f) + continue; + emittingVol = (1.0f - relVol) * 70.0f; + maxDist = SQR(SOUND_INTENSITY); + m_sQueueSample.m_nSampleIndex = SFX_CAR_HELI_ROT; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = HeliIndex++; + if (HeliIndex > 90) + HeliIndex = 89; + m_sQueueSample.m_nFrequency = (8000.0f * relVol) + 16000; + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); + m_sQueueSample.m_nReleasingVolumeModificator = 2; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + break; + } + case SOUND_WEAPON_SHOT_FIRED: { + const float SOUND_INTENSITY = 120.0f; + CVehicle *playerVeh; + CPlayerPed *playerPed; + + switch (params.m_pVehicle->m_modelIndex) { + case MI_HUNTER: + case MI_CHOPPER: + case MI_SEASPAR: + case MI_SPARROW: + case MI_MAVERICK: + case MI_VCNMAV: + if (params.m_pVehicle->m_modelIndex == MI_HUNTER) { + if (Pads[0].GetHandBrake() == 0) { + playerVeh = FindPlayerVehicle(); + playerPed = FindPlayerPed(); + if (playerVeh == nil && playerPed != nil) { + if (playerPed->m_attachedTo != nil && playerPed->m_attachedTo->GetType() == ENTITY_TYPE_VEHICLE) + playerVeh = (CVehicle*)playerPed->m_attachedTo; + } + if (playerVeh != params.m_pVehicle) { + m_sQueueSample.m_nSampleIndex = SFX_M60_LEFT; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + } else { + m_sQueueSample.m_nSampleIndex = SFX_ROCKET_LEFT; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + } + } else { + m_sQueueSample.m_nSampleIndex = SFX_M60_LEFT; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + } + } else { + m_sQueueSample.m_nSampleIndex = SFX_M60_LEFT; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + } + maxDist = SQR(SOUND_INTENSITY); + m_sQueueSample.m_nCounter = GunIndex++; + emittingVol = MAX_VOLUME; + if (GunIndex > 58) + GunIndex = 53; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_M60_LEFT); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16); + m_sQueueSample.m_nReleasingVolumeModificator = 2; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bRequireReflection = true; + isHeli = true; + break; + default: + { + maxDist = SQR(SOUND_INTENSITY); +#ifdef FIX_BUGS + int32 sampleIndex; + int32 frequency; + CPed *pPed = params.m_pVehicle->pDriver; + if(!pPed) + break; + if(!pPed->HasWeaponSlot(WEAPONSLOT_SUBMACHINEGUN)) { + sampleIndex = SFX_UZI_LEFT; + frequency = SampleManager.GetSampleBaseFrequency(sampleIndex); + frequency += RandomDisplacement(frequency / 32); + } else + switch(pPed->GetWeapon(WEAPONSLOT_SUBMACHINEGUN).m_eWeaponType) { + case WEAPONTYPE_TEC9: + sampleIndex = SFX_TEC_LEFT; + frequency = RandomDisplacement(500) + 17000; + break; + case WEAPONTYPE_SILENCED_INGRAM: + sampleIndex = SFX_TEC_LEFT; + frequency = RandomDisplacement(1000) + 34000; + break; + case WEAPONTYPE_MP5: + sampleIndex = SFX_MP5_LEFT; + frequency = SampleManager.GetSampleBaseFrequency(sampleIndex); + frequency += RandomDisplacement(frequency / 32); + break; + default: + sampleIndex = SFX_UZI_LEFT; + frequency = SampleManager.GetSampleBaseFrequency(sampleIndex); + frequency += RandomDisplacement(frequency / 32); + break; + } + m_sQueueSample.m_nSampleIndex = sampleIndex; +#else + m_sQueueSample.m_nSampleIndex = SFX_UZI_LEFT; +#endif + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = GunIndex++; + emittingVol = m_anRandomTable[2] % 15 + 65; + if(GunIndex > 58) GunIndex = 53; +#ifdef FIX_BUGS + m_sQueueSample.m_nFrequency = frequency; +#else + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_UZI_LEFT); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16); +#endif + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bRequireReflection = true; + break; + } + } + break; + } + case SOUND_WEAPON_HIT_VEHICLE: { + const float SOUND_INTENSITY = 40.0f; + m_sQueueSample.m_nSampleIndex = m_anRandomTable[m_sQueueSample.m_nEntityIndex % ARRAY_SIZE(m_anRandomTable)] % 6 + SFX_BULLET_CAR_1; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = 34; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); + m_sQueueSample.m_nReleasingVolumeModificator = 7; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + maxDist = SQR(SOUND_INTENSITY); + emittingVol = m_anRandomTable[3] % 20 + 90; + break; + } + case SOUND_BOMB_TIMED_ACTIVATED: + case SOUND_91: + case SOUND_BOMB_ONIGNITION_ACTIVATED: + case SOUND_BOMB_TICK: { + const float SOUND_INTENSITY = 50.0f; + m_sQueueSample.m_nSampleIndex = SFX_ARM_BOMB; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = 36; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_ARM_BOMB); + m_sQueueSample.m_nReleasingVolumeModificator = 0; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bRequireReflection = true; + emittingVol = 50; + maxDist = SQR(SOUND_INTENSITY); + break; + } + case SOUND_PED_HELI_PLAYER_FOUND: { + cPedParams pedParams; + pedParams.m_bDistanceCalculated = params.m_bDistanceCalculated; + pedParams.m_fDistance = params.m_fDistance; + SetupPedComments(pedParams, SOUND_PED_HELI_PLAYER_FOUND); + continue; + } + /* case SOUND_PED_BODYCAST_HIT: + pedParams.m_pPed = nil; + pedParams.m_bDistanceCalculated = false; + pedParams.m_fDistance = 0.0f; + pedParams.m_bDistanceCalculated = params.m_bDistanceCalculated; + pedParams.m_fDistance = params.m_fDistance; + SetupPedComments(&pedParams, SOUND_PED_BODYCAST_HIT); + continue; */ + case SOUND_PED_VCPA_PLAYER_FOUND: { + cPedParams pedParams; + pedParams.m_bDistanceCalculated = params.m_bDistanceCalculated; + pedParams.m_fDistance = params.m_fDistance; + SetupPedComments(pedParams, SOUND_PED_VCPA_PLAYER_FOUND); + continue; + } + case SOUND_WATER_FALL: { + const float SOUND_INTENSITY = 40.0f; + static uint32 WaterFallFrame = 0; + if (m_FrameCounter <= WaterFallFrame) + continue; + WaterFallFrame = m_FrameCounter + 6; + m_sQueueSample.m_nSampleIndex = SFX_SPLASH_1; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = 15; + m_sQueueSample.m_nFrequency = RandomDisplacement(1000) + 16000; + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + maxDist = SQR(SOUND_INTENSITY); + m_sQueueSample.m_bRequireReflection = true; + emittingVol = m_anRandomTable[4] % 20 + 90; + break; + } + case SOUND_SPLATTER: { + const float SOUND_INTENSITY = 40.0f; + static uint8 CrunchOffset = 0; + m_sQueueSample.m_nSampleIndex = CrunchOffset + SFX_PED_CRUNCH_1; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = 48; + m_sQueueSample.m_nFrequency = RandomDisplacement(6000) + 16000; + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + ++CrunchOffset; + maxDist = SQR(SOUND_INTENSITY); + emittingVol = m_anRandomTable[4] % 20 + 55; + CrunchOffset %= 2; + m_sQueueSample.m_bRequireReflection = true; + break; + } + case SOUND_CAR_PED_COLLISION: { + const float SOUND_INTENSITY = 40.0f; + vol = Min(20.0f, m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]); + emittingVol = Min(127, (3 * (vol / 20.0f * 127.f)) / 2); + if (emittingVol == 0) + continue; + + m_sQueueSample.m_nSampleIndex = SFX_FIGHT_1; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = 50; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16); + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + maxDist = SQR(SOUND_INTENSITY); + break; + } + default: + continue; + } + if (params.m_fDistance < maxDist) { + CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance); + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + if (noReflections) { + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_bReleasingSoundFlag = false; + } else { + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_bReleasingSoundFlag = true; + } + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bReverbFlag = true; + if (isHeli) { + if (0.2f * m_sQueueSample.m_fSoundIntensity > m_sQueueSample.m_fDistance) { + m_sQueueSample.m_bIs2D = true; + m_sQueueSample.m_nOffset = 0; +#ifdef THIS_IS_STUPID + goto AddSample; +#else + AddSampleToRequestedQueue(); + m_sQueueSample.m_nOffset = 127; + m_sQueueSample.m_nSampleIndex++; + m_sQueueSample.m_nCounter = GunIndex++; + if (GunIndex > 58) + GunIndex = 53; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + continue; +#endif + } + isHeli = false; + } + m_sQueueSample.m_bIs2D = false; +#ifdef THIS_IS_STUPID +AddSample: + AddSampleToRequestedQueue(); + if (isHeli) { + m_sQueueSample.m_nOffset = 127; + m_sQueueSample.m_nSampleIndex++; + m_sQueueSample.m_nCounter = GunIndex++; + if (GunIndex > 58) + GunIndex = 53; + m_sQueueSample.m_bRequireReflection = 0; + AddSampleToRequestedQueue(); + } +#else + AddSampleToRequestedQueue(); +#endif + continue; + + } + } + } +} + +#ifdef GTA_TRAIN +bool +cAudioManager::ProcessTrainNoise(cVehicleParams& params) +{ + const float SOUND_INTENSITY = 300.0f; + + CTrain *train; + uint8 emittingVol; + float speedMultipler; + + if (params.m_fDistance >= SQR(SOUND_INTENSITY)) + return false; + + if (params.m_fVelocityChange > 0.0f) { + CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance); + train = (CTrain *)params.m_pVehicle; + speedMultipler = Min(1.0f, train->m_fSpeed * 250.f / 51.f); + emittingVol = (75.f * speedMultipler); + if (train->m_fWagonPosition == 0.0f) { + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 32; + m_sQueueSample.m_nSampleIndex = SFX_TRAIN_FAR; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 2; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_TRAIN_FAR); + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 3.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + const float SOUND_INTENSITY = 70.0f; + if (params.m_fDistance < SQR(SOUND_INTENSITY)) { + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 33; + m_sQueueSample.m_nSampleIndex = SFX_TRAIN_NEAR; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 5; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_TRAIN_NEAR) + 100 * m_sQueueSample.m_nEntityIndex % 987; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 6.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + } + return true; +} +#endif +bool +cAudioManager::ProcessBoatEngine(cVehicleParams& params) +{ + CBoat *boat; + float padRelativeAccerate; + + bool isV12 = false; + static int32 LastFreq = 2000; + static int8 LastVol = 0; + + static const float intensity = 90.0f; + + if (params.m_fDistance < SQR(intensity)) { + boat = (CBoat *)params.m_pVehicle; + if(boat->GetStatus() == STATUS_WRECKED) + return true; + + float freqModificator; + float volModificator; + int BaseVol; + int BaseFreq; + + switch(boat->GetModelIndex()) { + case MI_RIO: + freqModificator = 490.0f; + volModificator = 60.0f; + BaseVol = 20; + BaseFreq = 1888; + break; + case MI_PREDATOR: + case MI_SQUALO: + case MI_SPEEDER: + case MI_COASTG: + case MI_DINGHY: + case MI_JETMAX: + freqModificator = 6000.0f; + volModificator = 60.0f; + isV12 = true; + BaseFreq = 9000; + BaseVol = 20; + break; + case MI_REEFER: + freqModificator = 715.0f; + volModificator = 80.0f; + BaseVol = 0; + BaseFreq = 3775; + break; + case MI_TROPIC: + case MI_MARQUIS: + freqModificator = 463.0f; + volModificator = 60.0f; + BaseVol = 20; + BaseFreq = 1782; + break; + default: + return true; + } + + bool bIsPlayerVeh; + + if(FindPlayerVehicle() == params.m_pVehicle) { + float padAccelerate = Max(Pads[0].GetAccelerate(), Pads[0].GetBrake()); + padRelativeAccerate = padAccelerate / 255.0f; + bIsPlayerVeh = true; + } else { + padRelativeAccerate = Max(params.m_pVehicle->m_fGasPedal, params.m_pVehicle->m_fBrakePedal); + bIsPlayerVeh = false; + } + + int Freq = BaseFreq + (padRelativeAccerate * freqModificator); + int Vol = BaseVol + (padRelativeAccerate * volModificator); + + if(!boat->bPropellerInWater) + Freq = (9 * Freq) / 8; + + if(bIsPlayerVeh) { + if(Freq > LastFreq) { + if(isV12) + Freq = Min(Freq, LastFreq + 100); + else + Freq = Min(Freq, LastFreq + 15); + } else { + if(isV12) + Freq = Max(Freq, LastFreq - 100); + else + Freq = Max(Freq, LastFreq - 15); + } + if(Vol > LastVol) + Vol = Min(Vol, LastVol + 3); + else + Vol = Max(Vol, LastVol - 3); + } + + if (Vol > 0) { + CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance); + m_sQueueSample.m_nVolume = ComputeVolume(Vol, intensity, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nFrequency = Freq; + m_sQueueSample.m_nCounter = 40; + if (isV12) + m_sQueueSample.m_nSampleIndex = SFX_BOAT_V12_LOOP; + else + m_sQueueSample.m_nSampleIndex = SFX_BOAT_CRUISER_LOOP; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = Vol; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_fSoundIntensity = intensity; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 7; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + + if(boat->GetModelIndex() == MI_REEFER) { + CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance); + m_sQueueSample.m_nVolume = ComputeVolume(80, intensity, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nFrequency = 6000; + m_sQueueSample.m_nCounter = 39; + m_sQueueSample.m_nSampleIndex = SFX_FISHING_BOAT_IDLE; + m_sQueueSample.m_nFrequency += (m_sQueueSample.m_nEntityIndex * 65536) % 1000; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = 80; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_fSoundIntensity = intensity; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 7; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + if(bIsPlayerVeh) { + LastFreq = Freq; + LastVol = Vol; + } + return true; + } + return false; +} + +bool +cAudioManager::ProcessBoatMovingOverWater(cVehicleParams& params) +{ + float velocityChange; + int32 vol; + float multiplier; + + if (params.m_fDistance > SQR(50)) + return false; + + velocityChange = Abs(params.m_fVelocityChange); + if (velocityChange <= 0.0005f && ((CBoat*)params.m_pVehicle)->bBoatInWater) + return true; + + velocityChange = Min(0.75f, velocityChange); + multiplier = (velocityChange - 0.0005f) / (1499.0f / 2000.0f); + CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance); + vol = (30.f * multiplier); + m_sQueueSample.m_nVolume = ComputeVolume(vol, 50.f, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 38; + m_sQueueSample.m_nSampleIndex = SFX_BOAT_WATER_LOOP; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nFrequency = (6050.f * multiplier) + 16000; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = vol; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_fSoundIntensity = 50.0f; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 6; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + + return true; +} + +void +cAudioManager::ProcessCarHeli(cVehicleParams& params) +{ + const float SOUND_INTENSITY = 250.0f; + + CVehicle* playerVeh; + CVehicle* veh; + CAutomobile* automobile; + CBoat* boat; + + uint8 emittingVol; + int16 brakeState; + int16 accelerateState; + uint32 freq; + float propellerSpeed; + float freqModifier; //may be relate to angle with horison + float cameraAngle; + bool distanceCalculatedOld; + float distanceOld; + CVector vecPosOld; + + float volumeModifier;//TODO find better name + bool hunterBool; + + static uint32 freqFrontPrev = 14287; + static uint32 freqPropellerPrev = 7143; + static uint32 freqSkimmerPrev = 14287; + + boat = nil; + automobile = nil; + hunterBool = false; + + if (params.m_fDistance >= SQR(SOUND_INTENSITY)) + return; + + playerVeh = FindPlayerVehicle(); + veh = params.m_pVehicle; + if (playerVeh == veh) { + accelerateState = Pads[0].GetAccelerate(); + brakeState = Pads[0].GetBrake(); + } else { + accelerateState = veh->m_fGasPedal * 255.0f; + brakeState = veh->m_fBrakePedal * 255.0f; + } + freqModifier = Abs(veh->GetUp().y); + cameraAngle = (DotProduct(veh->m_matrix.GetForward(), TheCamera.GetForward()) + 1.0f) / 2.0f; + if (veh->m_modelIndex == MI_SKIMMER) { + boat = (CBoat*)veh; + propellerSpeed = boat->m_fMovingSpeed * 50.0f / 11.0f; + } else if (params.m_VehicleType == VEHICLE_TYPE_HELI) { + propellerSpeed = 1.0f; + } else { + automobile = (CAutomobile*)veh; + propellerSpeed = automobile->m_aWheelSpeed[1] * 50.0f / 11.0f; + } + + if (propellerSpeed == 0.0f) + return; + + propellerSpeed = Min(1.0f, propellerSpeed); + CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance); + + + //sound on long distances + if (m_sQueueSample.m_fDistance >= 40.0f) + emittingVol = propellerSpeed * 75.0f; + else if (m_sQueueSample.m_fDistance >= 25.0f) + emittingVol = (m_sQueueSample.m_fDistance - 25.0f) * (75.0f * propellerSpeed) / 15.0f; + else + emittingVol = 0; + if (emittingVol != 0) { + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 88; + if (boat != nil) { + m_sQueueSample.m_nSampleIndex = SFX_SEAPLANE_PRO3; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + if (accelerateState > 0 || brakeState > 0) + m_sQueueSample.m_nFrequency = 4600 + Min(1.0f, (Max(accelerateState, brakeState) / 255.0f) * freqModifier) * 563; + else + m_sQueueSample.m_nFrequency = 3651 + Min(1.0f, freqModifier) * 949; + } else { + m_sQueueSample.m_nSampleIndex = SFX_HELI_1; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + } + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 2; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 6.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 5; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + + if (params.m_fDistance >= SQR(140.0f)) + return; + + if (propellerSpeed >= 0.4f) + volumeModifier = (propellerSpeed - 0.4f) * 5.0f / 3.0f; + else + volumeModifier = 0.0f; + if (!boat) { + freq = Min(1300, 7000.0f * freqModifier); + if (playerVeh == veh && (accelerateState > 0 || brakeState > 0) && freq < 1300)//unnesesary freqModifier alredy <= 1300 + freq = 1300; + if (veh->m_modelIndex == MI_HUNTER) + hunterBool = true; + } + + + //sound from front of helicopter + emittingVol = (1.0f - cameraAngle) * volumeModifier * 127.0f; + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, 140.0f, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 3; + if (hunterBool) { + m_sQueueSample.m_nSampleIndex = SFX_HELI_APACHE_1; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nFrequency = (volumeModifier + 1.0f) * 16000 + freq; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 6.0f; + m_sQueueSample.m_fSoundIntensity = 140.0f; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 5; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } else if (boat != nil) { + m_sQueueSample.m_nSampleIndex = SFX_SEAPLANE_PRO1; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + + if (accelerateState > 0 || brakeState > 0) + m_sQueueSample.m_nFrequency = 18000 + Min(1.0f, freqModifier * (Max(accelerateState, brakeState) / 255.0f)) * 2204; + else + m_sQueueSample.m_nFrequency = 14287 + Min(1.0f, freqModifier) * 3713; + if (propellerSpeed < 1.0f) + m_sQueueSample.m_nFrequency = (propellerSpeed + 1.0f) * (m_sQueueSample.m_nFrequency / 2.0f); + m_sQueueSample.m_nFrequency = clamp2(m_sQueueSample.m_nFrequency, freqFrontPrev, 197); + freqFrontPrev = m_sQueueSample.m_nFrequency; + + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 6.0f; + m_sQueueSample.m_fSoundIntensity = 140.0f; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 5; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } else { + m_sQueueSample.m_nSampleIndex = SFX_CAR_HELI_MAI; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nFrequency = (volumeModifier + 1) * 16000 + freq; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 6.0f; + m_sQueueSample.m_fSoundIntensity = 140.0f; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 5; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + + + //after accel rotor sound + emittingVol = ((cameraAngle + 1.0f) * volumeModifier * 127.0f) / 2.0f; + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, 140.0f, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 1; + if (hunterBool) { + m_sQueueSample.m_nSampleIndex = SFX_HELI_APACHE_2; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nFrequency = (volumeModifier + 1) * 16000 + freq; + } else if (boat) { + m_sQueueSample.m_nSampleIndex = SFX_SEAPLANE_PRO2; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + + if (accelerateState > 0 || brakeState > 0) + m_sQueueSample.m_nFrequency = 9000 + Min(1.0f, (Max(accelerateState, brakeState) / 255) * freqModifier) * 1102; + else + m_sQueueSample.m_nFrequency = 7143 + Min(1.0f, freqModifier) * 1857; + + if (propellerSpeed < 1.0f) + m_sQueueSample.m_nFrequency = (propellerSpeed + 1) * (m_sQueueSample.m_nFrequency / 2); + + m_sQueueSample.m_nFrequency = clamp2(m_sQueueSample.m_nFrequency, freqPropellerPrev, 98); + freqPropellerPrev = m_sQueueSample.m_nFrequency; + } else { + m_sQueueSample.m_nSampleIndex = SFX_CAR_HELI_MAI2; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nFrequency = (volumeModifier + 1) * 16000 + freq; + } + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 6.0f; + m_sQueueSample.m_fSoundIntensity = 140.0f; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 5; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + + + //engine starting sound + if (boat == nil && params.m_VehicleType != VEHICLE_TYPE_HELI && m_sQueueSample.m_fDistance < 30.0f) { //strange way to check if automobile != nil + if (automobile->bEngineOn) { + if (propellerSpeed < 1.0f) { + emittingVol = (1.0f - propellerSpeed / 2.0f) * 70.0f; + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, 30.0f, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume) { + if (hunterBool) { + m_sQueueSample.m_nSampleIndex = SFX_HELI_APACHE_4; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + freq = 3000.0f * propellerSpeed + 30000; + } else { + m_sQueueSample.m_nSampleIndex = SFX_CAR_HELI_STA; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + freq = 3000.0f * propellerSpeed + 6000; + } + m_sQueueSample.m_nFrequency = freq; + m_sQueueSample.m_nCounter = 12; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 6.0f; + m_sQueueSample.m_fSoundIntensity = 30.0f; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 30; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + } + } + + + if (boat) { + if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_FIXED && m_sQueueSample.m_fDistance < 20.0f && propellerSpeed > 0.0f) { + m_sQueueSample.m_nVolume = ComputeVolume(propellerSpeed * 100.0f, 20.0f, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume) { + + if (accelerateState > 0 || brakeState > 0) + m_sQueueSample.m_nFrequency = 18000 + Min(1.0f, (Max(accelerateState, brakeState) / 255.0f) * freqModifier) * 2204; + else + m_sQueueSample.m_nFrequency = 14287 + Min(1.0f, freqModifier) * 3713; + if (propellerSpeed < 1.0f) + m_sQueueSample.m_nFrequency = (propellerSpeed + 1) * (m_sQueueSample.m_nFrequency / 2.0f); + m_sQueueSample.m_nFrequency = clamp2(m_sQueueSample.m_nFrequency, freqSkimmerPrev, 197); + freqSkimmerPrev = m_sQueueSample.m_nFrequency; + + m_sQueueSample.m_nSampleIndex = SFX_SEAPLANE_PRO4; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = 12; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = propellerSpeed * 100.0f; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(SFX_SEAPLANE_PRO4); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(SFX_SEAPLANE_PRO4); + m_sQueueSample.m_fSpeedMultiplier = 5.0f; + m_sQueueSample.m_fSoundIntensity = 20.0f; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 7; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + } else { + //vacuum cleaner sound + vecPosOld = m_sQueueSample.m_vecPos; + distanceCalculatedOld = params.m_bDistanceCalculated; + distanceOld = params.m_fDistance; + + if (automobile != nil) + automobile->GetComponentWorldPosition(CAR_BOOT, m_sQueueSample.m_vecPos); + else if (params.m_VehicleType == VEHICLE_TYPE_HELI) + m_sQueueSample.m_vecPos = CVector(0.0f, -10.0f, 0.0f); //this is from android, but for real it's not used + + params.m_bDistanceCalculated = false; + params.m_fDistance = GetDistanceSquared(m_sQueueSample.m_vecPos); + if (params.m_fDistance < SQR(27.0f)) { + CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance); + m_sQueueSample.m_nVolume = ComputeVolume(volumeModifier * 25.0f, 27.0f, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume) { + m_sQueueSample.m_nCounter = 2; + m_sQueueSample.m_nSampleIndex = hunterBool ? SFX_HELI_APACHE_3 : SFX_CAR_HELI_REA; + m_sQueueSample.m_nBankIndex = 0; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_nFrequency = (volumeModifier + 1.0f) * 16000; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = volumeModifier * 25.0f; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 6.0f; + m_sQueueSample.m_fSoundIntensity = 27.0f; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 5; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + + m_sQueueSample.m_vecPos = vecPosOld; + params.m_bDistanceCalculated = distanceCalculatedOld; + params.m_fDistance = distanceOld; + } +} + +void +cAudioManager::ProcessVehicleFlatTyre(cVehicleParams& params) +{ + const float SOUND_INTENSITY = 60.0f; + + CAutomobile* automobile; + CBike* bike; + bool wheelBurst; + uint8 emittingVol; + + float modifier; + + if (params.m_fDistance >= SQR(SOUND_INTENSITY)) + return; + + switch (params.m_VehicleType) { + case VEHICLE_TYPE_CAR: + automobile = (CAutomobile*)params.m_pVehicle; + wheelBurst = false; + for (int i = 0; i < 4; i++) + if (automobile->Damage.GetWheelStatus(i) == WHEEL_STATUS_BURST && automobile->m_aWheelTimer[i] > 0.0f) + wheelBurst = true; + if (!wheelBurst) + return; + break; + case VEHICLE_TYPE_BIKE: + bike = (CBike*)params.m_pVehicle; + wheelBurst = false; + for(int i = 0; i < 2; i++) + if (bike->m_wheelStatus[i] == WHEEL_STATUS_BURST && bike->m_aWheelTimer[i] > 0.0f) + wheelBurst = true; + if (!wheelBurst) + return; + break; + default: + return; + } + modifier = Min(1.0f, Abs(params.m_fVelocityChange) / (0.3f * params.m_pTransmission->fMaxVelocity)); + if (modifier > 0.01f) { //mb can be replaced by (emittingVol > 1) + emittingVol = (100.0f * modifier); + CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance); + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume) { + m_sQueueSample.m_nCounter = 95; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 5; + m_sQueueSample.m_nSampleIndex = SFX_TYRE_BURST_L; + m_sQueueSample.m_nFrequency = (5500.0f * modifier) + 8000; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(SFX_TYRE_BURST_L); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(SFX_TYRE_BURST_L); + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } +} + +//TODO use it in ProcessVehicle +void +cAudioManager::ProcessPlane(cVehicleParams& params) +{ + switch (params.m_nIndex) { + case AIRTRAIN: + ProcessJumbo(params); + break; + case DEADDODO: + ProcessCesna(params); + break; + default: + break; + } +} + +#pragma region JUMBO +uint8 gJumboVolOffsetPercentage; + +void +DoJumboVolOffset() +{ + if (!(AudioManager.GetFrameCounter() % (AudioManager.GetRandomNumber(0) % 6 + 3))) + gJumboVolOffsetPercentage = AudioManager.GetRandomNumber(1) % 60; +} + +void +cAudioManager::ProcessJumbo(cVehicleParams& params) +{ + CPlane *plane; + float position; + + if (params.m_fDistance >= SQR(440)) + return; + + CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance); + plane = (CPlane*)params.m_pVehicle; + DoJumboVolOffset(); + position = PlanePathPosition[plane->m_nPlaneId]; + if (position <= TakeOffPoint) { + if (plane->m_fSpeed > 0.103344f) { + ProcessJumboAccel(plane); + } else { + ProcessJumboTaxi(); + } + } else if (position <= TakeOffPoint + 300.0f) { + ProcessJumboTakeOff(plane); + } else if (position <= LandingPoint - 350.0f) { + ProcessJumboFlying(); + } else if (position <= LandingPoint) { + ProcessJumboLanding(plane); + } else if (plane->m_fSpeed > 0.103344f) { + ProcessJumboDecel(plane); + } else { + ProcessJumboTaxi(); + } +} + +void +cAudioManager::ProcessJumboTaxi() +{ + if (SetupJumboFlySound(20)) { + if (SetupJumboTaxiSound(75)) + SetupJumboWhineSound(18, 29500); + } +} + +void +cAudioManager::ProcessJumboAccel(CPlane *plane) +{ + int32 engineFreq; + int32 vol; + float modificator; + float freqModifier; + + if (SetupJumboFlySound(20)) { + modificator = Min(1.0f, (plane->m_fSpeed - 0.103344f) * 1.6760077f); + if (SetupJumboRumbleSound(MAX_VOLUME * modificator) && SetupJumboTaxiSound((1.0f - modificator) * 75.f)) { + if (modificator < 0.2f) { + freqModifier = modificator * 5.0f; + vol = MAX_VOLUME * freqModifier; + engineFreq = 6050.0f * freqModifier + 16000; + } else { + freqModifier = 1.0f; + engineFreq = 22050; + vol = MAX_VOLUME; + } + SetupJumboEngineSound(vol, engineFreq); + SetupJumboWhineSound(18, 14600.0f * freqModifier + 29500); + } + } +} + +void +cAudioManager::ProcessJumboTakeOff(CPlane *plane) +{ + const float modificator = (PlanePathPosition[plane->m_nPlaneId] - TakeOffPoint) / 300.f; + + if (SetupJumboFlySound((107.f * modificator) + 20) && SetupJumboRumbleSound(MAX_VOLUME * (1.f - modificator))) { + if (SetupJumboEngineSound(MAX_VOLUME, 22050)) + SetupJumboWhineSound(18.f * (1.f - modificator), 44100); + } +} + +void +cAudioManager::ProcessJumboFlying() +{ + if (SetupJumboFlySound(MAX_VOLUME)) + SetupJumboEngineSound(63, 22050); +} + +void +cAudioManager::ProcessJumboLanding(CPlane *plane) +{ + const float modificator = (LandingPoint - PlanePathPosition[plane->m_nPlaneId]) / 350.f; + if (SetupJumboFlySound(107.f * modificator + 20)) { + if (SetupJumboTaxiSound(75.f * (1.f - modificator))) { + SetupJumboEngineSound(MAX_VOLUME, 22050); + SetupJumboWhineSound(18.f * (1.f - modificator), 14600.f * modificator + 29500); + } + } +} + +void +cAudioManager::ProcessJumboDecel(CPlane *plane) +{ + if (SetupJumboFlySound(20) && SetupJumboTaxiSound(75)) { + const float modificator = Min(1.f, (plane->m_fSpeed - 0.103344f) * 1.6760077f); + SetupJumboEngineSound(MAX_VOLUME * modificator, 6050.f * modificator + 16000); + SetupJumboWhineSound(18, 29500); + } +} + +bool +cAudioManager::SetupJumboTaxiSound(uint8 vol) +{ + const float SOUND_INTENSITY = 180.0f; + if (m_sQueueSample.m_fDistance >= SOUND_INTENSITY) + return false; + + uint8 emittingVol = (vol / 2) + ((vol / 2) * m_sQueueSample.m_fDistance / SOUND_INTENSITY); + + if (m_sQueueSample.m_fDistance / SOUND_INTENSITY < 0.7f) + emittingVol -= emittingVol * gJumboVolOffsetPercentage / 100; + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 1; + m_sQueueSample.m_nSampleIndex = SFX_JUMBO_TAXI; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_nFrequency = GetJumboTaxiFreq(); + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 4.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 4; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + return true; +} + +bool +cAudioManager::SetupJumboWhineSound(uint8 emittingVol, uint32 freq) +{ + const float SOUND_INTENSITY = 170.0f; + + if (m_sQueueSample.m_fDistance >= SOUND_INTENSITY) + return false; + + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 2; + m_sQueueSample.m_nSampleIndex = SFX_JUMBO_WHINE; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_nFrequency = freq; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 4.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 4; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + return true; +} + +bool +cAudioManager::SetupJumboEngineSound(uint8 vol, uint32 freq) +{ + const float SOUND_INTENSITY = 180.0f; + if (m_sQueueSample.m_fDistance >= SOUND_INTENSITY) + return false; + + uint8 emittingVol = vol - gJumboVolOffsetPercentage / 100; + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 3; + m_sQueueSample.m_nSampleIndex = SFX_JUMBO_ENGINE; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_nFrequency = freq; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 4.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 4; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + return true; +} + +bool +cAudioManager::SetupJumboFlySound(uint8 emittingVol) +{ + const float SOUND_INTENSITY = 440.0f; + if(m_sQueueSample.m_fDistance >= SOUND_INTENSITY) return false; + + int32 vol = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + m_sQueueSample.m_nVolume = vol; + if(m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 0; + m_sQueueSample.m_nSampleIndex = SFX_JUMBO_DIST_FLY; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_JUMBO_DIST_FLY); + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 4.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 5; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; // todo port fix to re3 + AddSampleToRequestedQueue(); + } + return true; +} + +bool +cAudioManager::SetupJumboRumbleSound(uint8 emittingVol) +{ + const float SOUND_INTENSITY = 240.0f; + if (m_sQueueSample.m_fDistance >= SOUND_INTENSITY) + return false; + + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 5; + m_sQueueSample.m_nSampleIndex = SFX_JUMBO_RUMBLE; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_bIs2D = true; + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_JUMBO_RUMBLE); + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 4.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 12; + m_sQueueSample.m_nOffset = 0; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + m_sQueueSample.m_nCounter = 6; + m_sQueueSample.m_nSampleIndex = SFX_JUMBO_RUMBLE; + m_sQueueSample.m_nFrequency += 200; + m_sQueueSample.m_nOffset = MAX_VOLUME; + AddSampleToRequestedQueue(); + } + return true; +} + +int32 +cAudioManager::GetJumboTaxiFreq() const +{ + return (1.f / 180 * 10950 * m_sQueueSample.m_fDistance) + 22050; // todo port fix to re3 +} + +#pragma endregion Some jumbo crap + +#pragma endregion All the vehicle audio code + +#pragma region PED AUDIO +void +cAudioManager::ProcessPed(CPhysical *ped) +{ + cPedParams params; + + m_sQueueSample.m_vecPos = ped->GetPosition(); + + params.m_bDistanceCalculated = false; + params.m_pPed = (CPed *)ped; + params.m_fDistance = GetDistanceSquared(m_sQueueSample.m_vecPos); + ProcessPedOneShots(params); +} + +void +cAudioManager::ProcessPedOneShots(cPedParams ¶ms) +{ + uint8 emittingVol; + int32 sampleIndex; + + CPed *ped = params.m_pPed; + + bool narrowSoundRange; + int16 sound; + bool stereo; + CWeapon *weapon; + float maxDist = 0.f; // uninitialized variable + + static uint8 iSound = 21; + static uint32 iSplashFrame = 0; + + weapon = params.m_pPed->GetWeapon(); + for (uint32 i = 0; i < m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_AudioEvents; i++) { + stereo = false; + narrowSoundRange = false; + m_sQueueSample.m_bRequireReflection = false; + sound = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i]; + switch (sound) { + case SOUND_STEP_START: + case SOUND_STEP_END: + if (params.m_pPed->bIsInTheAir) + continue; + emittingVol = m_anRandomTable[3] % 15 + 45; + if (FindPlayerPed() != m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_pEntity) + emittingVol /= 2; + maxDist = 400.f; + switch (params.m_pPed->m_nSurfaceTouched) { + case SURFACE_GRASS: + sampleIndex = m_anRandomTable[1] % 5 + SFX_FOOTSTEP_GRASS_1; + break; + case SURFACE_GRAVEL: + case SURFACE_MUD_DRY: + sampleIndex = m_anRandomTable[4] % 5 + SFX_FOOTSTEP_GRAVEL_1; + break; + case SURFACE_CAR: + case SURFACE_GARAGE_DOOR: + case SURFACE_CAR_PANEL: + case SURFACE_THICK_METAL_PLATE: + case SURFACE_SCAFFOLD_POLE: + case SURFACE_LAMP_POST: + case SURFACE_FIRE_HYDRANT: + case SURFACE_GIRDER: + case SURFACE_METAL_CHAIN_FENCE: + case SURFACE_CONTAINER: + case SURFACE_NEWS_VENDOR: + sampleIndex = m_anRandomTable[0] % 5 + SFX_FOOTSTEP_METAL_1; + break; + case SURFACE_SAND: + sampleIndex = (m_anRandomTable[4] & 3) + SFX_FOOTSTEP_SAND_1; + break; + case SURFACE_WATER: + sampleIndex = (m_anRandomTable[3] & 3) + SFX_FOOTSTEP_WATER_1; + break; + case SURFACE_WOOD_CRATES: + case SURFACE_WOOD_BENCH: + case SURFACE_WOOD_SOLID: + sampleIndex = m_anRandomTable[2] % 5 + SFX_FOOTSTEP_WOOD_1; + break; + case SURFACE_HEDGE: + sampleIndex = m_anRandomTable[2] % 5 + SFX_COL_VEG_1; + break; + default: + sampleIndex = m_anRandomTable[2] % 5 + SFX_FOOTSTEP_CONCRETE_1; + break; + } + m_sQueueSample.m_nSampleIndex = sampleIndex; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i] - SOUND_STEP_START + 1; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 17); + switch (params.m_pPed->m_nMoveState) { + case PEDMOVE_WALK: + emittingVol /= 4; + m_sQueueSample.m_nFrequency = 9 * m_sQueueSample.m_nFrequency / 10; + break; + case PEDMOVE_RUN: + emittingVol /= 2; + m_sQueueSample.m_nFrequency = 11 * m_sQueueSample.m_nFrequency / 10; + break; + case PEDMOVE_SPRINT: + m_sQueueSample.m_nFrequency = 12 * m_sQueueSample.m_nFrequency / 10; + break; + default: + break; + } + m_sQueueSample.m_nReleasingVolumeModificator = 5; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 20.0f; + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bRequireReflection = true; + break; + case SOUND_FALL_LAND: + case SOUND_FALL_COLLAPSE: + if (ped->bIsInTheAir) + continue; + maxDist = SQR(30); + emittingVol = m_anRandomTable[3] % 20 + 80; + if (ped->m_nSurfaceTouched == SURFACE_WATER) { + m_sQueueSample.m_nSampleIndex = (m_anRandomTable[3] & 3) + SFX_FOOTSTEP_WATER_1; + } else if (sound == SOUND_FALL_LAND) { + m_sQueueSample.m_nSampleIndex = SFX_BODY_LAND; + } else { + m_sQueueSample.m_nSampleIndex = SFX_BODY_LAND_AND_FALL; + } + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = 1; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 17); + m_sQueueSample.m_nReleasingVolumeModificator = 2; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 30.0f; + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bRequireReflection = true; + break; + case SOUND_FIGHT_37: + m_sQueueSample.m_nSampleIndex = SFX_FIGHT_1; + m_sQueueSample.m_nFrequency = 18000; + goto AddFightSound; + case SOUND_FIGHT_38: + m_sQueueSample.m_nSampleIndex = SFX_FIGHT_1; + m_sQueueSample.m_nFrequency = 16500; + goto AddFightSound; + case SOUND_FIGHT_39: + m_sQueueSample.m_nSampleIndex = SFX_FIGHT_1; + m_sQueueSample.m_nFrequency = 20000; + goto AddFightSound; + case SOUND_FIGHT_40: + m_sQueueSample.m_nSampleIndex = SFX_FIGHT_2; + m_sQueueSample.m_nFrequency = 18000; + goto AddFightSound; + case SOUND_FIGHT_41: + m_sQueueSample.m_nSampleIndex = SFX_FIGHT_2; + m_sQueueSample.m_nFrequency = 16500; + goto AddFightSound; + case SOUND_FIGHT_42: + m_sQueueSample.m_nSampleIndex = SFX_FIGHT_2; + m_sQueueSample.m_nFrequency = 20000; + goto AddFightSound; + case SOUND_FIGHT_43: + m_sQueueSample.m_nSampleIndex = SFX_FIGHT_4; + m_sQueueSample.m_nFrequency = 18000; + goto AddFightSound; + case SOUND_FIGHT_44: + m_sQueueSample.m_nSampleIndex = SFX_FIGHT_4; + m_sQueueSample.m_nFrequency = 16500; + goto AddFightSound; + case SOUND_FIGHT_45: + m_sQueueSample.m_nSampleIndex = SFX_FIGHT_4; + m_sQueueSample.m_nFrequency = 20000; + goto AddFightSound; + case SOUND_FIGHT_46: + case SOUND_187: + m_sQueueSample.m_nSampleIndex = SFX_FIGHT_5; + m_sQueueSample.m_nFrequency = 18000; + goto AddFightSound; + case SOUND_FIGHT_47: + m_sQueueSample.m_nSampleIndex = SFX_FIGHT_5; + m_sQueueSample.m_nFrequency = 16500; + goto AddFightSound; + case SOUND_FIGHT_48: + m_sQueueSample.m_nSampleIndex = SFX_FIGHT_5; + m_sQueueSample.m_nFrequency = 20000; + AddFightSound: + { + uint32 soundParams = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]; // wtf? storing int as float + uint8 damagerType = soundParams & 0xFF; + uint32 weaponType = soundParams >> 8; + + if (damagerType == ENTITY_TYPE_PED) { + if (weaponType == WEAPONTYPE_BRASSKNUCKLE) { + CPed* ped = params.m_pPed; + uint32 fightMove = ped->m_curFightMove; + if (fightMove == FIGHTMOVE_BACKLEFT || fightMove == FIGHTMOVE_STDPUNCH || fightMove == FIGHTMOVE_PUNCH || + ped->m_nPedState == PED_ATTACK) { + CEntity* damageEntity = ped->m_pDamageEntity; + if (!damageEntity) + m_sQueueSample.m_nSampleIndex = m_anRandomTable[3] % 2 + SFX_HAMMER_HIT_1; + else if (damageEntity->GetType() != ENTITY_TYPE_PED) + m_sQueueSample.m_nSampleIndex = m_anRandomTable[3] % 2 + SFX_HAMMER_HIT_1; + else if (((CPed*)damageEntity)->m_curFightMove != FIGHTMOVE_HITHEAD) + m_sQueueSample.m_nSampleIndex = m_anRandomTable[3] % 2 + SFX_HAMMER_HIT_1; + else + m_sQueueSample.m_nSampleIndex = SFX_HAMMER_HIT_1; + } + } + } + else { + m_sQueueSample.m_nSampleIndex = m_anRandomTable[4] % 6 + SFX_COL_CAR_PANEL_1; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16); + } + } + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = iSound; + narrowSoundRange = true; + ++iSound; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 30.0f; + maxDist = SQR(30); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + emittingVol = m_anRandomTable[3] % 26 + 100; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bRequireReflection = true; + break; + case SOUND_WEAPON_BAT_ATTACK: + case SOUND_WEAPON_KNIFE_ATTACK: + { + uint32 soundParams = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]; // wtf? storing int as float + uint8 damagerType = soundParams & 0xFF; + uint32 weaponType = soundParams >> 8; + if (damagerType == ENTITY_TYPE_PED) { + switch (weaponType) { + case WEAPONTYPE_SCREWDRIVER: + case WEAPONTYPE_KNIFE: + case WEAPONTYPE_CLEAVER: + case WEAPONTYPE_MACHETE: + case WEAPONTYPE_KATANA: + if (sound == SOUND_WEAPON_KNIFE_ATTACK) + m_sQueueSample.m_nSampleIndex = SFX_KNIFE_SLASH; + else + m_sQueueSample.m_nSampleIndex = SFX_KNIFE_STAB; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); + break; + case WEAPONTYPE_HAMMER: + m_sQueueSample.m_nSampleIndex = m_anRandomTable[3] % 2 + SFX_HAMMER_HIT_1; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); + break; + default: + m_sQueueSample.m_nSampleIndex = SFX_BAT_HIT_LEFT; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nFrequency = RandomDisplacement(2000) + 22000; + stereo = true; + break; + } + } + else { + m_sQueueSample.m_nSampleIndex = m_anRandomTable[4] % 6 + SFX_COL_CAR_PANEL_1; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16); + } + m_sQueueSample.m_nCounter = iSound++; + narrowSoundRange = true; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 30.0f; + maxDist = SQR(30); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + emittingVol = m_anRandomTable[2] % 20 + 100; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bRequireReflection = true; + break; + } + case SOUND_WEAPON_CHAINSAW_ATTACK: + if (FindVehicleOfPlayer()) + continue; + m_sQueueSample.m_nSampleIndex = SFX_CAR_ACCEL_13; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; // SFX_BANK_CAR_CHAINSAW + m_sQueueSample.m_nCounter = 70; + m_sQueueSample.m_nFrequency = 27000; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 3.0f; + m_sQueueSample.m_fSoundIntensity = 50.0f; + maxDist = SQR(50); + m_sQueueSample.m_nLoopCount = 0; + emittingVol = 100; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(SFX_CAR_ACCEL_13); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(SFX_CAR_ACCEL_13); + m_sQueueSample.m_nEmittingVolume = 100; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 5; + break; + case SOUND_WEAPON_CHAINSAW_IDLE: + if (FindVehicleOfPlayer()) + continue; + m_sQueueSample.m_nSampleIndex = SFX_CAR_AFTER_ACCEL_13; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; // SFX_BANK_CAR_CHAINSAW + m_sQueueSample.m_nCounter = 68; + m_sQueueSample.m_nFrequency = 27000; + m_sQueueSample.m_nReleasingVolumeModificator = 2; + m_sQueueSample.m_fSpeedMultiplier = 3.0f; + m_sQueueSample.m_fSoundIntensity = 60.0f; + maxDist = SQR(60); + m_sQueueSample.m_nLoopCount = 0; + emittingVol = 100; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(SFX_CAR_AFTER_ACCEL_13); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(SFX_CAR_AFTER_ACCEL_13); + m_sQueueSample.m_nEmittingVolume = 100; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 5; + break; + case SOUND_WEAPON_CHAINSAW_MADECONTACT: + if (FindVehicleOfPlayer()) + continue; + if ((int32)m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i] != ENTITY_TYPE_PED) + ReportCollision(params.m_pPed, params.m_pPed, SURFACE_CAR, SURFACE_TARMAC, 0.0f, 0.09f); + m_sQueueSample.m_nSampleIndex = SFX_CAR_AFTER_ACCEL_13; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; // SFX_BANK_CAR_CHAINSAW + m_sQueueSample.m_nCounter = 68; + m_sQueueSample.m_nFrequency = RandomDisplacement(500) + 22000; + m_sQueueSample.m_nReleasingVolumeModificator = 2; + m_sQueueSample.m_fSpeedMultiplier = 3.0f; + m_sQueueSample.m_fSoundIntensity = 60.0f; + maxDist = SQR(60); + m_sQueueSample.m_nLoopCount = 0; + emittingVol = 100; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(SFX_CAR_AFTER_ACCEL_13); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(SFX_CAR_AFTER_ACCEL_13); + m_sQueueSample.m_nEmittingVolume = 100; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 5; + break; + case SOUND_WEAPON_SHOT_FIRED: + weapon = ped->GetWeapon(); + if (!weapon) + continue; + switch (weapon->m_eWeaponType) { + case WEAPONTYPE_ROCKET: + case WEAPONTYPE_ROCKETLAUNCHER: + m_sQueueSample.m_nSampleIndex = SFX_ROCKET_LEFT; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = iSound++; + narrowSoundRange = true; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_ROCKET_LEFT); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 120.0f; + maxDist = SQR(120); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + emittingVol = m_anRandomTable[0] % 20 + 80; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bRequireReflection = true; + stereo = true; + break; + case WEAPONTYPE_COLT45: + m_sQueueSample.m_nSampleIndex = SFX_COLT45_LEFT; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = iSound++; + narrowSoundRange = true; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_COLT45_LEFT); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 120.0f; + maxDist = SQR(120); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + emittingVol = m_anRandomTable[1] % 10 + 90; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bRequireReflection = true; + stereo = true; + break; + case WEAPONTYPE_PYTHON: + m_sQueueSample.m_nSampleIndex = SFX_PYTHON_LEFT; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = iSound++; + narrowSoundRange = true; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_PYTHON_LEFT); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 120.0f; + maxDist = SQR(120); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + emittingVol = 127; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bRequireReflection = true; + stereo = true; + break; + case WEAPONTYPE_SHOTGUN: + case WEAPONTYPE_STUBBY_SHOTGUN: + m_sQueueSample.m_nSampleIndex = SFX_SHOTGUN_LEFT; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = iSound++; + narrowSoundRange = true; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_SHOTGUN_LEFT); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 120.0f; + maxDist = SQR(120); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + emittingVol = m_anRandomTable[2] % 10 + 100; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bRequireReflection = true; + stereo = true; + break; + case WEAPONTYPE_SPAS12_SHOTGUN: + m_sQueueSample.m_nSampleIndex = SFX_SPAS12_LEFT; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = iSound++; + narrowSoundRange = true; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_SPAS12_LEFT); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 120.0f; + maxDist = SQR(120); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + emittingVol = m_anRandomTable[2] % 10 + 100; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bRequireReflection = true; + stereo = true; + break; + case WEAPONTYPE_TEC9: + m_sQueueSample.m_nSampleIndex = SFX_TEC_LEFT; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = iSound++; + narrowSoundRange = true; + m_sQueueSample.m_nFrequency = RandomDisplacement(500) + 17000; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 120.0f; + maxDist = SQR(120); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + emittingVol = m_anRandomTable[3] % 15 + 70; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + stereo = true; + break; + case WEAPONTYPE_UZI: + case WEAPONTYPE_MINIGUN: + m_sQueueSample.m_nSampleIndex = SFX_UZI_LEFT; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = iSound++; + narrowSoundRange = true; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_UZI_LEFT); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 120.0f; + maxDist = SQR(120); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + emittingVol = m_anRandomTable[3] % 15 + 70; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + stereo = true; + break; + case WEAPONTYPE_SILENCED_INGRAM: + m_sQueueSample.m_nSampleIndex = SFX_TEC_LEFT; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = iSound++; + narrowSoundRange = true; + m_sQueueSample.m_nFrequency = RandomDisplacement(1000) + 34000; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 120.0f; + maxDist = SQR(120); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + emittingVol = m_anRandomTable[3] % 15 + 70; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + stereo = true; + break; + case WEAPONTYPE_MP5: + m_sQueueSample.m_nSampleIndex = SFX_MP5_LEFT; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = iSound++; + narrowSoundRange = true; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_MP5_LEFT); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 120.0f; + maxDist = SQR(120); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + emittingVol = m_anRandomTable[3] % 15 + 70; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + stereo = true; + break; + case WEAPONTYPE_M4: + m_sQueueSample.m_nSampleIndex = SFX_RUGER_LEFT; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = iSound++; + narrowSoundRange = true; + m_sQueueSample.m_nFrequency = RandomDisplacement(1000) + 43150; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 120.0f; + maxDist = SQR(120); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + emittingVol = m_anRandomTable[3] % 15 + 90; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + stereo = true; + break; + case WEAPONTYPE_RUGER: + m_sQueueSample.m_nSampleIndex = SFX_RUGER_LEFT; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = iSound++; + narrowSoundRange = true; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RUGER_LEFT); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 120.0f; + maxDist = SQR(120); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + emittingVol = m_anRandomTable[3] % 15 + 90; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + stereo = true; + break; + case WEAPONTYPE_SNIPERRIFLE: + case WEAPONTYPE_LASERSCOPE: + m_sQueueSample.m_nSampleIndex = SFX_SNIPER_LEFT; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = iSound++; + narrowSoundRange = true; + if (weapon->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE) + m_sQueueSample.m_nFrequency = 25472; + else + m_sQueueSample.m_nFrequency = 20182; + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 120.0f; + maxDist = SQR(120); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + emittingVol = m_anRandomTable[4] % 10 + 110; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bRequireReflection = true; + stereo = true; + break; + case WEAPONTYPE_FLAMETHROWER: + m_sQueueSample.m_nSampleIndex = SFX_FLAMETHROWER_LEFT; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = 9; + emittingVol = 90; + m_sQueueSample.m_nFrequency = (10 * m_sQueueSample.m_nEntityIndex & 2047) + SampleManager.GetSampleBaseFrequency(SFX_FLAMETHROWER_LEFT); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 4.0f; + m_sQueueSample.m_fSoundIntensity = 60.0f; + maxDist = SQR(60); + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nEmittingVolume = 90; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 6; + stereo = true; + break; + case WEAPONTYPE_M60: + case WEAPONTYPE_HELICANNON: + m_sQueueSample.m_nSampleIndex = SFX_M60_LEFT; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = iSound++; + narrowSoundRange = true; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_M60_LEFT); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 120.0f; + maxDist = SQR(120); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + emittingVol = 127; + m_sQueueSample.m_nEmittingVolume = 127; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + stereo = true; + break; + default: + continue; + } + break; + case SOUND_WEAPON_RELOAD: + switch ((int32)m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]) { + case WEAPONTYPE_ROCKET: + case WEAPONTYPE_ROCKETLAUNCHER: + m_sQueueSample.m_nSampleIndex = SFX_ROCKET_RELOAD; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_ROCKET_RELOAD); + break; + case WEAPONTYPE_COLT45: + case WEAPONTYPE_PYTHON: + m_sQueueSample.m_nSampleIndex = SFX_PISTOL_RELOAD; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_PISTOL_RELOAD) + RandomDisplacement(300); + break; + case WEAPONTYPE_SHOTGUN: + case WEAPONTYPE_SPAS12_SHOTGUN: + case WEAPONTYPE_STUBBY_SHOTGUN: + case WEAPONTYPE_RUGER: + m_sQueueSample.m_nSampleIndex = SFX_AK47_RELOAD; + m_sQueueSample.m_nFrequency = 30290; + break; + case WEAPONTYPE_TEC9: + case WEAPONTYPE_UZI: + case WEAPONTYPE_SILENCED_INGRAM: + case WEAPONTYPE_MP5: + case WEAPONTYPE_M4: + case WEAPONTYPE_M60: + case WEAPONTYPE_HELICANNON: + m_sQueueSample.m_nSampleIndex = SFX_AK47_RELOAD; + m_sQueueSample.m_nFrequency = 39243; + break; + case WEAPONTYPE_SNIPERRIFLE: + case WEAPONTYPE_LASERSCOPE: + m_sQueueSample.m_nSampleIndex = SFX_RIFLE_RELOAD; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RIFLE_RELOAD); + break; + default: + continue; + } + emittingVol = 75; + m_sQueueSample.m_nCounter = iSound++; + narrowSoundRange = true; + m_sQueueSample.m_nFrequency += RandomDisplacement(300); + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nReleasingVolumeModificator = 5; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 30.0f; + maxDist = SQR(30); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_nEmittingVolume = 75; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bRequireReflection = true; + break; + case SOUND_WEAPON_AK47_BULLET_ECHO: + { + uint32 weaponType = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]; + switch (weaponType) { + case WEAPONTYPE_SPAS12_SHOTGUN: + m_sQueueSample.m_nSampleIndex = SFX_SPAS12_TAIL_LEFT; + break; + case WEAPONTYPE_TEC9: + case WEAPONTYPE_SILENCED_INGRAM: + m_sQueueSample.m_nSampleIndex = SFX_TEC_TAIL; + break; + case WEAPONTYPE_UZI: + case WEAPONTYPE_MP5: + m_sQueueSample.m_nSampleIndex = SFX_UZI_END_LEFT; + break; + case WEAPONTYPE_M4: + case WEAPONTYPE_RUGER: + case WEAPONTYPE_SNIPERRIFLE: + case WEAPONTYPE_LASERSCOPE: + m_sQueueSample.m_nSampleIndex = SFX_RUGER_TAIL; + break; + case WEAPONTYPE_M60: + case WEAPONTYPE_HELICANNON: + m_sQueueSample.m_nSampleIndex = SFX_M60_TAIL_LEFT; + break; + default: + continue; + } + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = iSound++; + narrowSoundRange = true; + switch (weaponType) { + case WEAPONTYPE_TEC9: + m_sQueueSample.m_nFrequency = 13000; + break; + case WEAPONTYPE_SILENCED_INGRAM: + m_sQueueSample.m_nFrequency = 26000; + break; + case WEAPONTYPE_M4: + m_sQueueSample.m_nFrequency = 15600; + break; + case WEAPONTYPE_SNIPERRIFLE: + m_sQueueSample.m_nFrequency = 9959; + break; + case WEAPONTYPE_LASERSCOPE: + m_sQueueSample.m_nFrequency = 7904; + break; + default: + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + break; + } + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 120.0f; + maxDist = SQR(120); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + emittingVol = m_anRandomTable[4] % 10 + 80; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bRequireReflection = true; + break; + } + case SOUND_WEAPON_FLAMETHROWER_FIRE: + m_sQueueSample.m_nSampleIndex = SFX_FLAMETHROWER_START_LEFT; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = iSound++; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_FLAMETHROWER_START_LEFT); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 4.0f; + m_sQueueSample.m_fSoundIntensity = 60.0f; + maxDist = SQR(60); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + emittingVol = 70; + m_sQueueSample.m_nEmittingVolume = 70; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + break; + case SOUND_WEAPON_HIT_PED: + m_sQueueSample.m_nSampleIndex = SFX_BULLET_PED; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = iSound++; + narrowSoundRange = true; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_BULLET_PED); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 8); + m_sQueueSample.m_nReleasingVolumeModificator = 7; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 30.0f; + maxDist = SQR(30); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + emittingVol = m_anRandomTable[0] % 20 + 90; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + break; + case SOUND_SPLASH: + if (m_FrameCounter <= iSplashFrame) + continue; + iSplashFrame = m_FrameCounter + 6; + m_sQueueSample.m_nSampleIndex = SFX_SPLASH_1; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = iSound++; + narrowSoundRange = true; + m_sQueueSample.m_nFrequency = RandomDisplacement(1400) + 20000; + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 40.0f; + maxDist = SQR(40); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + emittingVol = m_anRandomTable[2] % 30 + 70; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bRequireReflection = true; + break; + case SOUND_MELEE_ATTACK_START: + { + uint32 weaponType = ((uint32)m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]) >> 8; + switch (weaponType) + { + case WEAPONTYPE_SCREWDRIVER: + case WEAPONTYPE_KNIFE: + case WEAPONTYPE_CLEAVER: + case WEAPONTYPE_MACHETE: + case WEAPONTYPE_KATANA: + m_sQueueSample.m_nSampleIndex = SFX_KNIFE_SWING; + break; + default: + m_sQueueSample.m_nSampleIndex = SFX_GOLF_CLUB_SWING; + break; + } + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = iSound++; + narrowSoundRange = true; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 30.0f; + if (weaponType == WEAPONTYPE_UNARMED || weaponType == WEAPONTYPE_BRASSKNUCKLE) + emittingVol = m_anRandomTable[1] % 10 + 35; + else + emittingVol = m_anRandomTable[2] % 20 + 70; + maxDist = SQR(30); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bRequireReflection = true; + break; + } + case SOUND_SKATING: + { + uint32 soundParams = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]; + uint8 param1 = soundParams & 0xFF; + uint32 param2 = soundParams >> 8; + m_sQueueSample.m_nSampleIndex = (m_anRandomTable[3] & 1) + SFX_SKATE_1; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = iSound; + stereo = true; + ++iSound; + m_sQueueSample.m_nFrequency = m_anRandomTable[1] % 1000 + 17000; + if (param2 == 0) + m_sQueueSample.m_nFrequency = (3 * m_sQueueSample.m_nFrequency) / 4; + m_sQueueSample.m_nReleasingVolumeModificator = 6; + m_sQueueSample.m_fSpeedMultiplier = 3.0f; + m_sQueueSample.m_fSoundIntensity = 20.0f; + maxDist = SQR(20); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + emittingVol = (m_anRandomTable[2] % 20 + 70) * param1 / 127; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bRequireReflection = true; + break; + } + case SOUND_WEAPON_MINIGUN_ATTACK: + m_sQueueSample.m_nSampleIndex = SFX_MINIGUN_FIRE_LEFT; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = 68; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_MINIGUN_FIRE_LEFT); + m_sQueueSample.m_nReleasingVolumeModificator = 2; + m_sQueueSample.m_fSpeedMultiplier = 3.0f; + m_sQueueSample.m_fSoundIntensity = 150.0f; + emittingVol = 127; + maxDist = SQR(150); + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(SFX_MINIGUN_FIRE_LEFT); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(SFX_MINIGUN_FIRE_LEFT); + m_sQueueSample.m_nEmittingVolume = 127; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + break; + case SOUND_WEAPON_MINIGUN_2: + m_sQueueSample.m_nSampleIndex = SFX_MINIGUN_FIRE_RIGHT; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = 69; + m_sQueueSample.m_nFrequency = 18569; + m_sQueueSample.m_nReleasingVolumeModificator = 2; + m_sQueueSample.m_fSpeedMultiplier = 3.0f; + m_sQueueSample.m_fSoundIntensity = 150.0f; + emittingVol = 127.0f * m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]; + maxDist = SQR(150); + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(SFX_MINIGUN_FIRE_RIGHT); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(SFX_MINIGUN_FIRE_RIGHT); + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + break; + case SOUND_WEAPON_MINIGUN_3: + m_sQueueSample.m_nSampleIndex = SFX_MINIGUN_STOP; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = 69; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_MINIGUN_STOP); + m_sQueueSample.m_nReleasingVolumeModificator = 4; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 150.0f; + maxDist = SQR(150); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + emittingVol = 127; + m_sQueueSample.m_nEmittingVolume = 127; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bRequireReflection = true; + break; + case SOUND_SHIRT_WIND_FLAP: + if (params.m_pPed->IsPlayer() && params.m_pPed->m_pMyVehicle) { + if (m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i] > 0.0f) { + if (m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i] > 1.0f) + m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i] = 1.0f; + + emittingVol = 90.0f * m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]; + + switch (params.m_pPed->m_pMyVehicle->GetModelIndex()) + { + case MI_ANGEL: + case MI_FREEWAY: + m_sQueueSample.m_nSampleIndex = SFX_CAR_WIND_17; + break; + case MI_PIZZABOY: + case MI_FAGGIO: + m_sQueueSample.m_nSampleIndex = SFX_CAR_WIND_18; + break; + case MI_PCJ600: + m_sQueueSample.m_nSampleIndex = SFX_CAR_WIND_20; + break; + case MI_SANCHEZ: + m_sQueueSample.m_nSampleIndex = SFX_CAR_WIND_19; + break; + default: + continue; + }; + + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = 71; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 3.0f; + m_sQueueSample.m_fSoundIntensity = 15.0f; + maxDist = SQR(15); + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + } + } + continue; + default: + SetupPedComments(params, sound); + continue; + } + + if (narrowSoundRange && iSound > 60) + iSound = 21; + if (params.m_fDistance < maxDist) { + CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance); + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + if (stereo) { + if (m_sQueueSample.m_fDistance < 0.2f * m_sQueueSample.m_fSoundIntensity) { + m_sQueueSample.m_bIs2D = true; + m_sQueueSample.m_nOffset = 0; + } else { + stereo = false; + } + } + m_sQueueSample.m_bReverbFlag = true; + AddSampleToRequestedQueue(); + if (stereo) { + m_sQueueSample.m_nOffset = 127; + ++m_sQueueSample.m_nSampleIndex; + if (m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i] != SOUND_WEAPON_SHOT_FIRED || + weapon->m_eWeaponType != WEAPONTYPE_FLAMETHROWER) { + m_sQueueSample.m_nCounter = iSound++; + if (iSound > 60) + iSound = 21; + } else { + ++m_sQueueSample.m_nCounter; + } + AddSampleToRequestedQueue(); + } + } + } + } +} + +void +cAudioManager::SetPedTalkingStatus(CPed *ped, uint8 status) +{ + if (ped != nil) + ped->m_canTalk = status; +} + +void +cAudioManager::SetPlayersMood(uint8 mood, uint32 time) +{ + if (!m_bIsInitialised) return; + + if (mood < MAX_PLAYER_MOODS) { + m_nPlayerMood = mood; + m_nPlayerMoodTimer = CTimer::GetTimeInMilliseconds() + time; + } + +} + +void +cAudioManager::SetupPedComments(cPedParams ¶ms, uint16 sound) +{ + CPed *ped = params.m_pPed; + uint8 emittingVol; + float soundIntensity; + tPedComment pedComment; + + if(ped != nil) { + if(!ped->m_canTalk) return; + m_bGenericSfx = false; + pedComment.m_nSampleIndex = GetPedCommentSfx(ped, sound); + if(pedComment.m_nSampleIndex == NO_SAMPLE) return; + soundIntensity = 40.0f; + } else { + m_bGenericSfx = true; + switch(sound) { + case SOUND_PED_HELI_PLAYER_FOUND: + soundIntensity = 400.0f; + pedComment.m_nSampleIndex = GetRandomNumberInRange(m_sQueueSample.m_nEntityIndex % 4, SFX_POLICE_HELI_1, SFX_POLICE_HELI_20); + break; + case SOUND_PED_VCPA_PLAYER_FOUND: + soundIntensity = 400.0f; +#ifdef FIX_BUGS + pedComment.m_nSampleIndex = m_anRandomTable[m_sQueueSample.m_nEntityIndex % 4] % 23 + SFX_POLICE_BOAT_1; +#else + pedComment.m_nSampleIndex = m_anRandomTable[m_sQueueSample.m_nEntityIndex % 4] % 29 + SFX_POLICE_BOAT_1; +#endif + break; + case SOUND_INJURED_PED_MALE_OUCH: + soundIntensity = 40.0f; + pedComment.m_nSampleIndex = GetRandomNumberInRange(m_sQueueSample.m_nEntityIndex % 4, SFX_GENERIC_MALE_GRUNT_1, SFX_GENERIC_MALE_GRUNT_41); + break; + case SOUND_INJURED_PED_FEMALE: + soundIntensity = 40.0f; + pedComment.m_nSampleIndex = GetRandomNumberInRange(m_sQueueSample.m_nEntityIndex % 4, SFX_GENERIC_FEMALE_GRUNT_1, SFX_GENERIC_FEMALE_GRUNT_33); + break; + default: + return; + } + } + + if(params.m_fDistance < SQR(soundIntensity)) { + CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance); + if(CWorld::GetIsLineOfSightClear(TheCamera.GetPosition(), m_sQueueSample.m_vecPos, true, false, false, false, false, false)) + emittingVol = MAX_VOLUME; + else + emittingVol = 31; + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, soundIntensity, m_sQueueSample.m_fDistance); + pedComment.m_nProcess = 10; + if(m_sQueueSample.m_nVolume != 0) { + pedComment.m_nEntityIndex = m_sQueueSample.m_nEntityIndex; + pedComment.m_vecPos = m_sQueueSample.m_vecPos; + pedComment.m_fDistance = m_sQueueSample.m_fDistance; + pedComment.m_bVolume = m_sQueueSample.m_nVolume; + m_sPedComments.Add(&pedComment); + } + } +} + +uint32 +cAudioManager::GetPedCommentSfx(CPed *ped, int32 sound) +{ + if(ped->m_nPedState != PED_FALL || sound == MI_VICE8 || sound == MI_WFYG1 || sound == MI_WFYG2) { + if(ped->m_getUpTimer == UINT32_MAX || ped->m_getUpTimer > CTimer::GetTimeInMilliseconds()) { + if(sound != SOUND_PED_DAMAGE && sound != SOUND_PED_HIT && sound != SOUND_PED_LAND) return NO_SAMPLE; + } + if(ped->IsPlayer()) return GetPlayerTalkSfx(ped, sound); + switch(ped->GetModelIndex()) { + case MI_PLAYER: return GetPlayerTalkSfx(ped, sound); + case MI_COP: return GetCopTalkSfx(ped, sound); + case MI_SWAT: return GetSwatTalkSfx(ped, sound); + case MI_FBI: return GetFBITalkSfx(ped, sound); + case MI_ARMY: return GetGenericMaleTalkSfx(ped, sound); + case MI_MEDIC: return GetMedicTalkSfx(ped, sound); + case MI_FIREMAN: return GetFiremanTalkSfx(ped, sound); + case MI_MALE01: return GetDefaultTalkSfx(ped, sound); + case MI_HFYST: return GetHFYSTTalkSfx(ped, sound); + case MI_HFOST: return GetHFOSTTalkSfx(ped, sound); + case MI_HMYST: return GetHMYSTTalkSfx(ped, sound); + case MI_HMOST: return GetHMOSTTalkSfx(ped, sound); + case MI_HFYRI: return GetHFYRITalkSfx(ped, sound); + case MI_HFORI: return GetHFORITalkSfx(ped, sound); + case MI_HMYRI: return GetHMYRITalkSfx(ped, sound); + case MI_HMORI: return GetHMORITalkSfx(ped, sound); + case MI_HFYBE: return GetHFYBETalkSfx(ped, sound); + case MI_HFOBE: return GetHFOBETalkSfx(ped, sound); + case MI_HMYBE: return GetHMYBETalkSfx(ped, sound); + case MI_HMOBE: return GetHMOBETalkSfx(ped, sound); + case MI_HFYBU: return GetHFYBUTalkSfx(ped, sound); + case MI_HFYMD: return GetHFYMDTalkSfx(ped, sound); + case MI_HFYCG: return GetHFYCGTalkSfx(ped, sound); + case MI_HFYPR: return GetHFYPRTalkSfx(ped, sound); + case MI_HFOTR: return GetHFOTRTalkSfx(ped, sound); + case MI_HMOTR: return GetHMOTRTalkSfx(ped, sound); + case MI_HMYAP: return GetHMYAPTalkSfx(ped, sound); + case MI_HMOCA: return GetHMOCATalkSfx(ped, sound); + case MI_BMODK: return GetBMODKTalkSfx(ped, sound); + case MI_BMYKR: return GetBMYCRTalkSfx(ped, sound); + case MI_BFYST: return GetBFYSTTalkSfx(ped, sound); + case MI_BFOST: return GetBFOSTTalkSfx(ped, sound); + case MI_BMYST: return GetBMYSTTalkSfx(ped, sound); + case MI_BMOST: return GetBMOSTTalkSfx(ped, sound); + case MI_BFYRI: return GetBFYRITalkSfx(ped, sound); + case MI_BFORI: return GetBFORITalkSfx(ped, sound); + case MI_BMYRI: return GetBMYRITalkSfx(ped, sound); + case MI_BFYBE: return GetBFYBETalkSfx(ped, sound); + case MI_BMYBE: return GetBMYBETalkSfx(ped, sound); + case MI_BFOBE: return GetBFOBETalkSfx(ped, sound); + case MI_BMOBE: return GetBMOBETalkSfx(ped, sound); + case MI_BMYBU: return GetBMYBUTalkSfx(ped, sound); + case MI_BFYPR: return GetBFYPRTalkSfx(ped, sound); + case MI_BFOTR: return GetBFOTRTalkSfx(ped, sound); + case MI_BMOTR: return GetBMOTRTalkSfx(ped, sound); + case MI_BMYPI: return GetBMYPITalkSfx(ped, sound); + case MI_BMYBB: return GetBMYBBTalkSfx(ped, sound); + case MI_WMYCR: return GetWMYCRTalkSfx(ped, sound); + case MI_WFYST: return GetWFYSTTalkSfx(ped, sound); + case MI_WFOST: return GetWFOSTTalkSfx(ped, sound); + case MI_WMYST: return GetWMYSTTalkSfx(ped, sound); + case MI_WMOST: return GetWMOSTTalkSfx(ped, sound); + case MI_WFYRI: return GetWFYRITalkSfx(ped, sound); + case MI_WFORI: return GetWFORITalkSfx(ped, sound); + case MI_WMYRI: return GetWMYRITalkSfx(ped, sound); + case MI_WMORI: return GetWMORITalkSfx(ped, sound); + case MI_WFYBE: return GetWFYBETalkSfx(ped, sound); + case MI_WMYBE: return GetWMYBETalkSfx(ped, sound); + case MI_WFOBE: return GetWFOBETalkSfx(ped, sound); + case MI_WMOBE: return GetWMOBETalkSfx(ped, sound); + case MI_WMYCW: return GetWMYCWTalkSfx(ped, sound); + case MI_WMYGO: return GetWMYGOTalkSfx(ped, sound); + case MI_WFOGO: return GetWFOGOTalkSfx(ped, sound); + case MI_WMOGO: return GetWMOGOTalkSfx(ped, sound); + case MI_WFYLG: return GetWFYLGTalkSfx(ped, sound); + case MI_WMYLG: return GetWMYLGTalkSfx(ped, sound); + case MI_WFYBU: return GetWFYBUTalkSfx(ped, sound); + case MI_WMYBU: return GetWMYBUTalkSfx(ped, sound); + case MI_WMOBU: return GetWMOBUTalkSfx(ped, sound); + case MI_WFYPR: return GetWFYPRTalkSfx(ped, sound); + case MI_WFOTR: return GetWFOTRTalkSfx(ped, sound); + case MI_WMOTR: return GetWMOTRTalkSfx(ped, sound); + case MI_WMYPI: return GetWMYPITalkSfx(ped, sound); + case MI_WMOCA: return GetWMOCATalkSfx(ped, sound); + case MI_WFYJG: return GetWFYJGTalkSfx(ped, sound); + case MI_WMYJG: return GetWMYJGTalkSfx(ped, sound); + case MI_WFYSK: return GetWFYSKTalkSfx(ped, sound); + case MI_WMYSK: return GetWMYSKTalkSfx(ped, sound); + case MI_WFYSH: return GetWFYSHTalkSfx(ped, sound); + case MI_WFOSH: return GetWFOSHTalkSfx(ped, sound); + case MI_JFOTO: return GetJFOTOTalkSfx(ped, sound); + case MI_JMOTO: return GetJMOTOTalkSfx(ped, sound); + case MI_CBA: + case MI_CBB: return GetCBTalkSfx(ped, sound); + case MI_HNA: + case MI_HNB: return GetHNTalkSfx(ped, sound); + case MI_SGA: + case MI_SGB: return GetSGTalkSfx(ped, sound); + case MI_CLA: + case MI_CLB: return GetCLTalkSfx(ped, sound); + case MI_GDA: + case MI_GDB: return GetGDTalkSfx(ped, sound); + case MI_BKA: + case MI_BKB: return GetBKTalkSfx(ped, sound); + case MI_PGA: + case MI_PGB: return GetPGTalkSfx(ped, sound); + case MI_VICE1: + case MI_VICE2: + case MI_VICE3: + case MI_VICE4: + case MI_VICE5: + case MI_VICE6: + case MI_VICE7: + case MI_VICE8: return GetVICETalkSfx(ped, sound, ped->GetModelIndex()); + case MI_WFYG1: return GetWFYG1TalkSfx(ped, sound); + case MI_WFYG2: return GetWFYG2TalkSfx(ped, sound); + case MI_SPECIAL01: + case MI_SPECIAL02: + case MI_SPECIAL03: + case MI_SPECIAL04: + case MI_SPECIAL05: + case MI_SPECIAL06: + case MI_SPECIAL07: + case MI_SPECIAL08: + case MI_SPECIAL09: + case MI_SPECIAL10: + case MI_SPECIAL11: + case MI_SPECIAL12: + case MI_SPECIAL13: + case MI_SPECIAL14: + case MI_SPECIAL15: + case MI_SPECIAL16: + case MI_SPECIAL17: + case MI_SPECIAL18: + case MI_SPECIAL19: + case MI_SPECIAL20: + case MI_SPECIAL21: return NO_SAMPLE; + default: return GetGenericMaleTalkSfx(ped, sound); + } + } + + return NO_SAMPLE; +} + +void +cAudioManager::GetPhrase(uint32 &phrase, uint32 &prevPhrase, uint32 sample, uint32 maxOffset) const +{ + phrase = sample + m_anRandomTable[m_sQueueSample.m_nEntityIndex & 3] % maxOffset; + + // check if the same sfx like last time, if yes, then try use next one, + // if exceeded range, then choose first available sample + if (phrase == prevPhrase && ++phrase >= sample + maxOffset) + phrase = sample; + prevPhrase = phrase; +} + +#pragma region PED_COMMENTS + +#define cooldown_phrase(count) static uint8 cooldown = 0;\ +if (cooldown != 0) {\ + if (++cooldown == count) cooldown = 0;\ + return NO_SAMPLE;\ +}\ +cooldown = 1; + +uint32 +cAudioManager::GetPlayerTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + if(m_bIsPlayerShutUp) return NO_SAMPLE; + switch(sound) { + case SOUND_PED_DEATH: return 9796; + case SOUND_PED_DAMAGE: + case SOUND_PED_BULLET_HIT: GetPhrase(sfx, ped->m_lastComment, 9815, 33); break; + case SOUND_PED_HIT: + case SOUND_PED_DEFEND: GetPhrase(sfx, ped->m_lastComment, 9883, 42); break; + case SOUND_PED_LAND: GetPhrase(sfx, ped->m_lastComment, 9848, 35); break; + case SOUND_PED_BURNING: GetPhrase(sfx, ped->m_lastComment, 9925, 16); break; + case SOUND_PED_PLAYER_REACTTOCOP: + switch(m_nPlayerMood) { + case PLAYER_MOOD_ANGRY: + GetPhrase(sfx, ped->m_lastComment, 8694, 38); + break; + case PLAYER_MOOD_WISECRACKING: + GetPhrase(sfx, ped->m_lastComment, 9615, 20); + break; + default: + GetPhrase(sfx, ped->m_lastComment, 9046, 22); + break; + } + break; + case SOUND_PED_ON_FIRE: { + cooldown_phrase(8); + switch(m_nPlayerMood) { + case PLAYER_MOOD_PISSED_OFF: + GetPhrase(sfx, ped->m_lastComment, 9586, 29); + break; + case PLAYER_MOOD_ANGRY: + GetPhrase(sfx, ped->m_lastComment, 9007, 39); + break; + case PLAYER_MOOD_WISECRACKING: + GetPhrase(sfx, ped->m_lastComment, 9787, 9); + break; + default: + GetPhrase(sfx, ped->m_lastComment, 9322, 35); + break; + } + break; + } + case SOUND_PED_AIMING: { + cooldown_phrase(8); + switch(m_nPlayerMood) { + case PLAYER_MOOD_PISSED_OFF: + GetPhrase(sfx, ped->m_lastComment, 9561, 25); + break; + case PLAYER_MOOD_ANGRY: + GetPhrase(sfx, ped->m_lastComment, 8937, 52); + break; + case PLAYER_MOOD_WISECRACKING: + GetPhrase(sfx, ped->m_lastComment, 9758, 19); + break; + default: + GetPhrase(sfx, ped->m_lastComment, 9275, 39); + break; + } + break; + } + case SOUND_PED_CAR_JACKING: { + cooldown_phrase(4); + switch(m_nPlayerMood) { + case PLAYER_MOOD_PISSED_OFF: + GetPhrase(sfx, ped->m_lastComment, 9483, 36); + break; + case PLAYER_MOOD_ANGRY: + GetPhrase(sfx, ped->m_lastComment, 8876, 43); + break; + case PLAYER_MOOD_WISECRACKING: + GetPhrase(sfx, ped->m_lastComment, 9706, 18); + break; + default: + GetPhrase(sfx, ped->m_lastComment, 9202, 40); + break; + } + break; + } + case SOUND_PED_MUGGING: { + cooldown_phrase(8); + switch(m_nPlayerMood) { + case PLAYER_MOOD_PISSED_OFF: + GetPhrase(sfx, ped->m_lastComment, 9519, 25); + break; + case PLAYER_MOOD_ANGRY: + GetPhrase(sfx, ped->m_lastComment, 8919, 12); + break; + case PLAYER_MOOD_WISECRACKING: + GetPhrase(sfx, ped->m_lastComment, 9724, 23); + break; + default: + GetPhrase(sfx, ped->m_lastComment, 9242, 11); + break; + } + break; + } + case SOUND_PED_CAR_JACKED: { + cooldown_phrase(4); + switch(m_nPlayerMood) { + case PLAYER_MOOD_PISSED_OFF: + GetPhrase(sfx, ped->m_lastComment, 9462, 21); + break; + case PLAYER_MOOD_ANGRY: + GetPhrase(sfx, ped->m_lastComment, 8843, 33); + break; + case PLAYER_MOOD_WISECRACKING: + GetPhrase(sfx, ped->m_lastComment, 9688, 18); + break; + default: + GetPhrase(sfx, ped->m_lastComment, 9178, 24); + break; + } + break; + } + case SOUND_PED_PLAYER_AFTERSEX: GetPhrase(sfx, ped->m_lastComment, 9797, 18); break; + case SOUND_PED_PLAYER_BEFORESEX: + switch(m_nPlayerMood) { + case PLAYER_MOOD_ANGRY: + GetPhrase(sfx, ped->m_lastComment, 8989, 18); + break; + case PLAYER_MOOD_WISECRACKING: + GetPhrase(sfx, ped->m_lastComment, 9777, 10); + break; + default: + GetPhrase(sfx, ped->m_lastComment, 9314, 8); + break; + } + break; + case SOUND_PED_PLAYER_FARFROMCOPS: { + cooldown_phrase(4); + switch(m_nPlayerMood) { + case PLAYER_MOOD_ANGRY: + GetPhrase(sfx, ped->m_lastComment, 8732, 9); + break; + case PLAYER_MOOD_WISECRACKING: + GetPhrase(sfx, ped->m_lastComment, 9635, 7); + break; + default: + GetPhrase(sfx, ped->m_lastComment, 9068, 20); + break; + } + break; + } + case SOUND_PED_ATTACK: { + cooldown_phrase(4); + switch(m_nPlayerMood) { + case PLAYER_MOOD_PISSED_OFF: + GetPhrase(sfx, ped->m_lastComment, 9401, 61); + break; + case PLAYER_MOOD_ANGRY: + GetPhrase(sfx, ped->m_lastComment, 8782, 61); + break; + case PLAYER_MOOD_WISECRACKING: + GetPhrase(sfx, ped->m_lastComment, 9661, 27); + break; + default: + GetPhrase(sfx, ped->m_lastComment, 9131, 47); + break; + } + break; + } + case SOUND_PED_CRASH_VEHICLE: + case SOUND_PED_CRASH_CAR: + case SOUND_PED_ANNOYED_DRIVER: { + cooldown_phrase(4); + switch(m_nPlayerMood) { + case PLAYER_MOOD_PISSED_OFF: + GetPhrase(sfx, ped->m_lastComment, 9357, 44); + break; + case PLAYER_MOOD_ANGRY: + GetPhrase(sfx, ped->m_lastComment, 8741, 41); + break; + case PLAYER_MOOD_WISECRACKING: + GetPhrase(sfx, ped->m_lastComment, 9642, 19); + break; + default: + GetPhrase(sfx, ped->m_lastComment, 9088, 43); + break; + } + break; + } + case SOUND_PED_SOLICIT: { + cooldown_phrase(4); + switch(m_nPlayerMood) { + case PLAYER_MOOD_PISSED_OFF: + GetPhrase(sfx, ped->m_lastComment, 9544, 17); + break; + case PLAYER_MOOD_ANGRY: + GetPhrase(sfx, ped->m_lastComment, 8931, 6); + break; + case PLAYER_MOOD_WISECRACKING: + GetPhrase(sfx, ped->m_lastComment, 9747, 11); + break; + default: + GetPhrase(sfx, ped->m_lastComment, 9253, 22); + break; + } + break; + } + default: return GetGenericMaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetCopTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + PedState objective; + switch(sound) { + case SOUND_PED_ARREST_COP: GetPhrase(sfx, ped->m_lastComment, 8469, 4); break; + case SOUND_PED_PULLOUTWEAPON: GetPhrase(sfx, ped->m_lastComment, 8473, 3); break; + case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 8500, 2); break; + case SOUND_PED_COP_UNK_129: GetPhrase(sfx, ped->m_lastComment, 8510, 4); break; + case SOUND_PED_COP_MANYCOPSAROUND: GetPhrase(sfx, ped->m_lastComment, 8508, 2); break; + case SOUND_PED_GUNAIMEDAT2: GetPhrase(sfx, ped->m_lastComment, 8498, 2); break; + case SOUND_PED_COP_ALONE: GetPhrase(sfx, ped->m_lastComment, 8504, 4); break; + case SOUND_PED_GUNAIMEDAT3: GetPhrase(sfx, ped->m_lastComment, 8485, 2); break; + case SOUND_PED_COP_REACTION: { + cooldown_phrase(4); + GetPhrase(sfx, ped->m_lastComment, 8502, 2); + break; + } + case SOUND_PED_COP_LITTLECOPSAROUND: + objective = FindPlayerPed()->m_nPedState; + if(objective == PED_ARRESTED || objective == PED_DEAD || objective == PED_DIE) return NO_SAMPLE; + GetPhrase(sfx, ped->m_lastComment, 8481, 4); + break; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 8494, 4); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 8491, 3); break; + case SOUND_PED_PED_COLLISION: + if(FindPlayerPed()->m_pWanted->GetWantedLevel() <= 0) return NO_SAMPLE; + GetPhrase(sfx, ped->m_lastComment, 8476, 5); + break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return 45 * (m_sQueueSample.m_nEntityIndex % 5) + sfx; +} + +uint32 +cAudioManager::GetSwatTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + switch(sound) { + case SOUND_PED_COP_HELIPILOTPHRASE: GetPhrase(sfx, ped->m_lastComment, 3285, 7); break; + case SOUND_PED_COP_UNK_129: GetPhrase(sfx, ped->m_lastComment, 3292, 4); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 3282, 3); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + sfx += 14 * (m_sQueueSample.m_nEntityIndex % 3); + return sfx; +} + +uint32 +cAudioManager::GetFBITalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + switch(sound) { + case SOUND_PED_COP_UNK_129: GetPhrase(sfx, ped->m_lastComment, 3240u, 4u); break; + case SOUND_PED_COP_MANYCOPSAROUND: GetPhrase(sfx, ped->m_lastComment, 3237u, 3u); break; + case SOUND_PED_GUNAIMEDAT2: sfx = 3236; break; + case SOUND_PED_GUNAIMEDAT3: GetPhrase(sfx, ped->m_lastComment, 3228u, 4u); break; + case SOUND_PED_CRASH_VEHICLE: + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 3232u, 4u); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + sfx += 16 * (m_sQueueSample.m_nEntityIndex % 3); + return sfx; +} + +uint32 +cAudioManager::GetArmyTalkSfx(CPed *ped, int16 sound) +{ + return GetGenericMaleTalkSfx(ped, sound); +} + +uint32 +cAudioManager::GetMedicTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + switch(sound) { + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 3162, 6); break; + case SOUND_PED_HEALING: GetPhrase(sfx, ped->m_lastComment, 3178, 17); break; + case SOUND_PED_LEAVE_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 3168, 10); break; // SFX_MEDIC_VOICE_1_GET_OUT_VAN_CHAT_1 + default: return GetGenericMaleTalkSfx(ped, sound); + } + sfx += 33 * (m_sQueueSample.m_nEntityIndex % 2); + return sfx; +} + +uint32 +cAudioManager::GetFiremanTalkSfx(CPed *ped, int16 sound) +{ + return GetGenericMaleTalkSfx(ped, sound); +} + +uint32 +cAudioManager::GetDefaultTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 2033, 12); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 2045, 12); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 2075, 4); break; + case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 2098, 4); break; + case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 2108, 5); break; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 2004, 16); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 1979, 19); break; + case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 2079, 19); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 2020, 13); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 1939, 15); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 1898, 16); break; + case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 2070, 5); break; + case SOUND_153: GetPhrase(sfx, ped->m_lastComment, 1998, 6); break; + case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 2102, 6); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 1914, 25); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 1954, 25); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetHFYSTTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + switch(sound) { + case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 5736, 5); break; + case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 5747, 4); break; + case SOUND_PED_MUGGING: GetPhrase(sfx, ped->m_lastComment, 5755, 4); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 5741, 6); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 5753, 2); break; + case SOUND_PED_TAXI_WAIT: return 5759; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 5722, 7); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 5712, 10); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 5729, 7); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 5695, 8); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 5678, 7); break; + case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 5751, 2); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 5685, 10); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 5703, 9); break; + default: return GetGenericFemaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetHFOSTTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 4382, 6); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 4388, 8); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 4398, 3); break; + case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 4401, 2); break; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 4363, 8); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 4353, 10); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 4371, 11); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 4334, 8); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 4313, 9); break; + case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 4396, 2); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 4322, 12); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 4342, 11); break; + default: return GetGenericFemaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetHMYSTTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 7961, 6); break; + case SOUND_PED_ACCIDENTREACTION1: return 7971; + case SOUND_PED_TAXI_WAIT: return 7974; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 7946, 6); break; + case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 7967, 4); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 7954, 7); break; + case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 7952, 2); break; + case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 7972, 2); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 7922, 13); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 7935, 11); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetHMOSTTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 5820, 5); break; + case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 5831, 3); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 5825, 6); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 5836, 2); break; + case SOUND_PED_TAXI_WAIT: return 5838; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 5805, 8); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 5795, 9); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 5813, 7); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 5777, 7); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 5760, 7); break; + case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 5834, 2); break; + case SOUND_PED_CHAT_SEXY: return 5804; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 5767, 10); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 5784, 11); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetHFYRITalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 6965, 5); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 6970, 6); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 6978, 4); break; + case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 6986, 2); break; + case SOUND_PED_TAXI_WAIT: return 6991; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 6948, 10); break; + case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 6982, 4); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 6958, 7); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 6940, 8); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 6923, 8); break; + case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 6976, 2); break; + case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 6988, 3); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 6931, 9); break; + default: return GetGenericFemaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetHFORITalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 7244, 6); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 7250, 9); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 7261, 2); break; + case SOUND_PED_ACCIDENTREACTION1: return 7267; + case SOUND_PED_TAXI_WAIT: return 7270; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 7229, 6); break; + case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 7263, 4); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 7237, 7); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 7222, 7); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 7206, 6); break; + case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 7259, 2); break; + case SOUND_153: GetPhrase(sfx, ped->m_lastComment, 7235, 2); break; + case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 7268, 2); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 7212, 10); break; + default: return GetGenericFemaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetHMYRITalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 5890, 7); break; + case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 5905, 3); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 5897, 8); break; + case SOUND_PED_ROBBED: return 5908; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 5873, 5); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 5864, 9); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 5878, 12); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 5856, 8); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 5839, 7); break; + case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 5909, 3); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 5846, 10); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetHMORITalkSfx(CPed *ped, int16 sound) +{ + + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 4454, 5); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 4459, 8); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 4469, 3); break; + case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 4478, 2); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 4436, 7); break; + case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 4472, 6); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 4443, 11); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 4422, 6); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 4403, 8); break; + case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 4467, 2); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 4411, 11); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 4428, 8); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetHFYBETalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 6897, 7); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 6904, 7); break; + case SOUND_PED_TAXI_WAIT: return 6922; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 6878, 11); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 6889, 8); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 6862, 6); break; + case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 6911, 2); break; + case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 6920, 2); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 6854, 8); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 6868, 10); break; + default: return GetGenericFemaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetHFOBETalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 1018, 5); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 1023, 6); break; + case SOUND_PED_ACCIDENTREACTION1: return 1035; + case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 1038, 2); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 1006, 7); break; + case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 1031, 4); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 1013, 5); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 990, 6); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 973, 6); break; + case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 1029, 2); break; + case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 1036, 2); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 979, 11); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 996, 10); break; + default: return GetGenericFemaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetHMYBETalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 4892, 6); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 4902, 12); break; + case SOUND_PED_ACCIDENTREACTION1: return 4917; + case SOUND_PED_UNK_126: GetPhrase(sfx, ped->m_lastComment, 4898, 4); break; + case SOUND_PED_TAXI_WAIT: return 4920; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 4874, 8); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 4862, 7); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 4882, 10); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 4845, 7); break; + case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 4914, 3); break; + case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 4869, 5); break; + case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 4918, 2); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 4835, 10); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 4852, 10); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetHMOBETalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 4703, 3); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 4709, 6); break; + case SOUND_PED_UNK_126: GetPhrase(sfx, ped->m_lastComment, 4706, 3); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 4690, 9); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 4672, 10); break; + case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 4699, 4); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 4682, 8); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + + return sfx; +} + +uint32 +cAudioManager::GetHFYBUTalkSfx(CPed *ped, int16 sound) +{ + + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 4771, 5); break; + case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 4782, 3); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 4776, 6); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 4787, 2); break; + case SOUND_PED_ACCIDENTREACTION1: return 4789; + case SOUND_PED_TAXI_WAIT: return 4790; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 4752, 7); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 4742, 10); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 4759, 12); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 4734, 8); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 4715, 8); break; + case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 4785, 2); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 4723, 11); break; + default: return GetGenericFemaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetHFYMDTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 6014, 5); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 6019, 2); break; + case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 6021, 3); break; + case SOUND_PED_TAXI_WAIT: return 8231; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 6005, 9); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 5997, 8); break; + case SOUND_PED_SOLICIT: GetPhrase(sfx, ped->m_lastComment, 6024, 15); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 5988, 9); break; + default: return GetGenericFemaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetHFYCGTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 4808, 5); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 4813, 2); break; + case SOUND_PED_ACCIDENTREACTION1: return 4819; + case SOUND_PED_TAXI_WAIT: return 8231; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 4800, 8); break; + case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 4815, 4); break; + case SOUND_PED_SOLICIT: GetPhrase(sfx, ped->m_lastComment, 4820, 14); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 4791, 9); break; + default: return GetGenericFemaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetHFYPRTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 5964, 6); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 5970, 2); break; + case SOUND_PED_ACCIDENTREACTION1: return 5972; + case SOUND_PED_PLAYER_BEFORESEX: GetPhrase(sfx, ped->m_lastComment, 5956, 8); break; + case SOUND_PED_TAXI_WAIT: return 5987; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 5946, 10); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 5934, 9); break; + case SOUND_PED_SOLICIT: GetPhrase(sfx, ped->m_lastComment, 5973, 14); break; + case SOUND_153: GetPhrase(sfx, ped->m_lastComment, 5943, 3); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 5912, 10); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 5922, 12); break; + default: return GetGenericFemaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetHFOTRTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 4660, 5); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 4665, 2); break; + case SOUND_PED_ACCIDENTREACTION1: return 4667; + case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 4670, 2); break; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 4654, 6); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 4646, 8); break; + case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 4668, 2); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 4623, 11); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 4634, 12); break; + default: return GetGenericFemaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetHMOTRTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 4515, 6); break; + case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 4521, 2); break; + case SOUND_PED_TAXI_WAIT: return 4534; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 4508, 7); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 4497, 11); break; + case SOUND_PED_SOLICIT: GetPhrase(sfx, ped->m_lastComment, 4526, 8); break; + case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 4523, 3); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 4480, 8); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 4488, 9); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetHMYAPTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 4591, 7); break; + case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 4605, 4); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 4598, 7); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 4611, 2); break; + case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 4619, 2); break; + case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 4621, 2); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 4573, 9); break; + case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 4613, 6); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 4585, 6); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 4555, 9); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 4535, 9); break; + case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 4609, 2); break; + case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 4582, 3); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 4544, 11); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 4564, 9); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetHMOCATalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 3506, 5); break; + case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 3521, 11); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 3511, 10); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 3532, 7); break; + case SOUND_PED_TAXI_WAIT: return 3541; + case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 3539, 2); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 3486, 8); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 3478, 8); break; + case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 3504, 2); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 3494, 10); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetBMODKTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 6831, 4); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 6838, 9); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 6847, 2); break; + case SOUND_PED_UNK_126: GetPhrase(sfx, ped->m_lastComment, 6835, 3); break; + case SOUND_PED_TAXI_WAIT: return 6853; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 6817, 7); break; + case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 6849, 4); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 6824, 7); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 6794, 10); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 6776, 8); break; + case SOUND_PED_147: + GetPhrase(sfx, ped->m_lastComment, 6805, 11); + switch(sfx) { + case 6809: + case 6810: + case 6811: GetPhrase(sfx, ped->m_lastComment, 6805, 4); break; + default: break; + } + break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 6784, 10); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetBMYCRTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 6578, 6); break; + case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 6594, 12); break; + case SOUND_PED_MUGGING: GetPhrase(sfx, ped->m_lastComment, 6609, 6); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 6588, 6); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 6606, 3); break; + case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 6615, 2); break; + case SOUND_PED_UNK_126: GetPhrase(sfx, ped->m_lastComment, 6584, 4); break; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 6563, 8); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 6553, 8); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 6571, 7); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 6544, 9); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 6521, 12); break; + case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 6561, 2); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 6533, 11); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetBFYSTTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 7184, 4); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 7188, 5); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 7195, 2); break; + case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 7203, 2); break; + case SOUND_PED_TAXI_WAIT: return 7205; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 7167, 9); break; + case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 7197, 6); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 7176, 8); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 7149, 9); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 7132, 8); break; + case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 7193, 2); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 7140, 9); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 7158, 9); break; + default: return GetGenericFemaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetBFOSTTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 7046, 5); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 7051, 8); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 7061, 2); break; + case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 7067, 2); break; + case SOUND_PED_TAXI_WAIT: return 7069; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 7027, 11); break; + case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 7063, 4); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 7038, 8); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 7009, 8); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 6992, 7); break; + case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 7059, 2); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 6999, 10); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 7017, 10); break; + default: return GetGenericFemaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetBMYSTTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 6413, 6); break; + case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 6427, 4); break; + case SOUND_PED_MUGGING: GetPhrase(sfx, ped->m_lastComment, 6433, 4); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 6419, 8); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 6431, 2); break; + case SOUND_PED_TAXI_WAIT: return 6437; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 6400, 6); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 6392, 8); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 6406, 7); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 6371, 9); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 6352, 8); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 6360, 11); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 6380, 12); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetBMOSTTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 4292, 9); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 4307, 4); break; + case SOUND_PED_ACCIDENTREACTION1: return 4311; + case SOUND_PED_TAXI_WAIT: return 4312; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 4272, 7); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 4258, 8); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 4279, 13); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 4232, 8); break; + case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 4301, 6); break; + case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 4266, 6); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 4215, 17); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 4240, 18); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetBFYRITalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 6161, 4); break; + case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 6173, 4); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 6165, 8); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 6179, 3); break; + case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 6188, 2); break; + case SOUND_PED_TAXI_WAIT: return 6194; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 6143, 8); break; + case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 6182, 6); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 6154, 7); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 6135, 8); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 6117, 9); break; + case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 6177, 2); break; + case SOUND_153: GetPhrase(sfx, ped->m_lastComment, 6151, 3); break; + case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 6190, 4); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 6126, 9); break; + default: return GetGenericFemaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetBFORITalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 7110, 5); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 7115, 4); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 7121, 2); break; + case SOUND_PED_ACCIDENTREACTION1: return 7127; + case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 7130, 2); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 7094, 9); break; + case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 7123, 4); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 7103, 7); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 7087, 7); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 7070, 8); break; + case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 7119, 2); break; + case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 7128, 2); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 7078, 9); break; + default: return GetGenericFemaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetBMYRITalkSfx(CPed *ped, int16 sound) +{ + + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 5430, 7); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 5437, 4); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 5443, 2); break; + case SOUND_PED_ACCIDENTREACTION1: return 5449; + case SOUND_PED_TAXI_WAIT: return 5453; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 5414, 8); break; + case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 5445, 4); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 5423, 7); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 5407, 7); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 5394, 6); break; + case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 5441, 2); break; + case SOUND_PED_CHAT_SEXY: return 5422; + case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 5450, 3); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 5400, 7); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetBFYBETalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 6255, 6); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 6261, 8); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 6273, 5); break; + case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 6284, 2); break; + case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 6290, 3); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 6233, 10); break; + case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 6278, 6); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 6247, 8); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 6207, 8); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 6195, 12); break; + case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 6269, 4); break; + case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 6243, 4); break; + case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 6286, 4); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 6217, 16); break; + default: return GetGenericFemaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetBMYBETalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 956, 4); break; + case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 966, 3); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 960, 6); break; + case SOUND_PED_ROBBED: return 970; + case SOUND_PED_ACCIDENTREACTION1: return 971; + case SOUND_PED_TAXI_WAIT: return 972; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 940, 8); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 928, 10); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 948, 8); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 910, 8); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 892, 8); break; + case SOUND_PED_WAIT_DOUBLEBACK: return 969; + case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 938, 2); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 900, 10); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 918, 10); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetBFOBETalkSfx(CPed *ped, int16 sound) +{ + + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 8213, 5); break; + case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 8223, 4); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 8218, 5); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 8227, 2); break; + case SOUND_PED_TAXI_WAIT: return 8231; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 8197, 9); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 8206, 7); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 8182, 7); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 8166, 8); break; + case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 8229, 2); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 8174, 8); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 8189, 8); break; + default: return GetGenericFemaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetBMOBETalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 7611, 5); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 7616, 6); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 7622, 4); break; + case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 7626, 3); break; + case SOUND_PED_TAXI_WAIT: return 7632; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 7594, 10); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 7583, 11); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 7604, 7); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 7564, 9); break; + case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 7629, 3); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 7559, 5); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 7573, 10); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetBMYBUTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 5500, 5); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 5507, 6); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 5513, 2); break; + case SOUND_PED_ACCIDENTREACTION1: return 5515; + case SOUND_PED_UNK_126: GetPhrase(sfx, ped->m_lastComment, 5505, 2); break; + case SOUND_PED_TAXI_WAIT: return 5518; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 5488, 5); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 5476, 10); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 5493, 7); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 5469, 7); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 5454, 8); break; + case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 5486, 2); break; + case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 5516, 2); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 5462, 7); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetBFYPRTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 5369, 5); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 5374, 2); break; + case SOUND_PED_ACCIDENTREACTION1: return 5376; + case SOUND_PED_PLAYER_BEFORESEX: GetPhrase(sfx, ped->m_lastComment, 5362, 7); break; + case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 5392, 2); break; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 5355, 7); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 5348, 7); break; + case SOUND_PED_SOLICIT: GetPhrase(sfx, ped->m_lastComment, 5379, 13); break; + case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 5377, 2); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 5324, 11); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 5335, 13); break; + default: return GetGenericFemaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetBFOTRTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 5232, 6); break; + case SOUND_PED_MUGGING: GetPhrase(sfx, ped->m_lastComment, 5240, 3); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 5238, 2); break; + case SOUND_PED_ACCIDENTREACTION1: return 5243; + case SOUND_PED_TAXI_WAIT: return 5252; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 5226, 6); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 5217, 9); break; + case SOUND_PED_SOLICIT: GetPhrase(sfx, ped->m_lastComment, 5247, 5); break; + case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 5244, 3); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 5192, 10); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 5202, 15); break; + default: return GetGenericFemaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetBMOTRTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 6327, 5); break; + case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 6343, 1); break; + case SOUND_PED_UNK_126: GetPhrase(sfx, ped->m_lastComment, 6332, 4); break; + case SOUND_PED_TAXI_WAIT: return 6351; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 6313, 11); break; + case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 6336, 7); break; + case SOUND_PED_SOLICIT: GetPhrase(sfx, ped->m_lastComment, 6344, 7); break; + case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 6324, 3); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 6293, 10); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 6303, 10); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetBMYPITalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 4033, 5); break; + case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 4044, 4); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 4038, 6); break; + case SOUND_PED_ROBBED: return 4048; + case SOUND_PED_ACCIDENTREACTION1: return 4049; + case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 4050, 2); break; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 4012, 8); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 3998, 10); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 4020, 13); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 3993, 5); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 3978, 6); break; + case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 4008, 4); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 3984, 9); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetBMYBBTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 639, 5); break; + case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 659, 9); break; + case SOUND_PED_MUGGING: GetPhrase(sfx, ped->m_lastComment, 691, 8); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 648, 11); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 686, 5); break; + case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 699, 6); break; + case SOUND_PED_UNK_126: GetPhrase(sfx, ped->m_lastComment, 644, 4); break; + case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 711, 3); break; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 618, 12); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 584, 18); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 630, 9); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 554, 9); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 524, 13); break; + case SOUND_PED_149: GetPhrase(sfx, ped->m_lastComment, 668, 16); break; + case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 684, 2); break; + case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 602, 16); break; + case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 705, 6); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 537, 17); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 563, 21); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetWMYCRTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 5056, 5); break; + case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 5061, 6); break; + case SOUND_PED_MUGGING: GetPhrase(sfx, ped->m_lastComment, 5070, 5); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 5067, 3); break; + case SOUND_PED_TAXI_WAIT: return 5075; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 5040, 7); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 5030, 10); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 5047, 9); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 5021, 9); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 5003, 18); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetWFYSTTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 8445, 5); break; + case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 8456, 4); break; + case SOUND_PED_MUGGING: GetPhrase(sfx, ped->m_lastComment, 8463, 4); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 8450, 6); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 8461, 2); break; + case SOUND_PED_ACCIDENTREACTION1: return 8467; + case SOUND_PED_TAXI_WAIT: return 8468; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 8430, 7); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 8420, 10); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 8437, 8); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 8402, 8); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 8386, 6); break; + case SOUND_PED_WAIT_DOUBLEBACK: return 8460; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 8392, 10); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 8410, 10); break; + default: return GetGenericFemaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetWFOSTTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 8354, 4); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 8358, 8); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 8369, 5); break; + case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 8381, 4); break; + case SOUND_PED_TAXI_WAIT: return 8385; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 8332, 12); break; + case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 8374, 7); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 8344, 10); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 8305, 11); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 8274, 12); break; + case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 8366, 3); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 8286, 19); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 8316, 16); break; + default: return GetGenericFemaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetWMYSTTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 3947, 5); break; + case SOUND_PED_MUGGING: GetPhrase(sfx, ped->m_lastComment, 3963, 5); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 3955, 5); break; + case SOUND_PED_ROBBED: return 3962; + case SOUND_PED_ACCIDENTREACTION1: return 3975; + case SOUND_PED_UNK_126: GetPhrase(sfx, ped->m_lastComment, 3952, 3); break; + case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 3976, 2); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 3930, 10); break; + case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 3968, 7); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 3942, 5); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 3912, 8); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 3893, 8); break; + case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 3960, 2); break; + case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 3940, 2); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 3901, 11); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 3920, 10); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetWMOSTTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 5170, 5); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 5178, 4); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 5188, 2); break; + case SOUND_PED_ACCIDENTREACTION1: return 5190; + case SOUND_PED_UNK_126: GetPhrase(sfx, ped->m_lastComment, 5175, 3); break; + case SOUND_PED_TAXI_WAIT: return 5191; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 5155, 8); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 5145, 8); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 5163, 7); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 5129, 7); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 5111, 8); break; + case SOUND_PED_149: GetPhrase(sfx, ped->m_lastComment, 5182, 4); break; + case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 5186, 2); break; + case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 5153, 2); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 5119, 10); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 5136, 9); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetWFYRITalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 5299, 5); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 5304, 7); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 5313, 2); break; + case SOUND_PED_ACCIDENTREACTION1: return 5320; + case SOUND_PED_TAXI_WAIT: return 5323; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 5280, 9); break; + case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 5315, 5); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 5291, 8); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 5271, 9); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 5253, 8); break; + case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 5311, 2); break; + case SOUND_153: GetPhrase(sfx, ped->m_lastComment, 5289, 2); break; + case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 5321, 2); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 5261, 10); break; + default: return GetGenericFemaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetWFORITalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 7825, 6); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 7831, 6); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 7839, 3); break; + case SOUND_PED_ACCIDENTREACTION1: return 7842; + case SOUND_PED_TAXI_WAIT: return 7846; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 7810, 7); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 7799, 11); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 7817, 8); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 7789, 10); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 7771, 7); break; + case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 7837, 2); break; + case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 7843, 3); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 7778, 11); break; + default: return GetGenericFemaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetWMYRITalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 4186, 8); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 4194, 8); break; + case SOUND_PED_ACCIDENTREACTION1: return 4208; + case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 4213, 2); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 4163, 9); break; + case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 4203, 5); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 4175, 11); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 4144, 9); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 4126, 10); break; + case SOUND_PED_WAIT_DOUBLEBACK: return 4202; + case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 4172, 3); break; + case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 4209, 4); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 4136, 8); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetWMORITalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 6668, 9); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 6677, 6); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 6685, 4); break; + case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 6701, 2); break; + case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 6707, 2); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 6647, 10); break; + case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 6689, 12); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 6660, 8); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 6641, 6); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 6617, 10); break; + case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 6683, 2); break; + case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 6657, 3); break; + case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 6703, 4); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 6627, 14); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetWFYBETalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 7752, 5); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 7757, 4); break; + case SOUND_PED_ACCIDENTREACTION1: return 7766; + case SOUND_PED_TAXI_WAIT: return 7770; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 7738, 8); break; + case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 7761, 5); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 7746, 6); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 7722, 6); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 7704, 7); break; + case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 7767, 3); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 7711, 11); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 7728, 10); break; + default: return GetGenericFemaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetWMYBETalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 8127, 8); break; + case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 8142, 3); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 8135, 7); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 8105, 12); break; + case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 8155, 5); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 8119, 8); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 8086, 8); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 8063, 9); break; + case SOUND_PED_149: GetPhrase(sfx, ped->m_lastComment, 8145, 7); break; + case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 8152, 3); break; + case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 8117, 2); break; + case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 8160, 6); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 8072, 14); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 8094, 11); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetWFOBETalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 6093, 5); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 6098, 4); break; + case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 6109, 3); break; + case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 6115, 2); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 6075, 8); break; + case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 6102, 7); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 6083, 10); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 6058, 7); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 6040, 8); break; + case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 6112, 3); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 6048, 10); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 6065, 10); break; + default: return GetGenericFemaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetWMOBETalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 3759, 5); break; + case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 3772, 4); break; + case SOUND_PED_MUGGING: GetPhrase(sfx, ped->m_lastComment, 3792, 6); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 3764, 8); break; + case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 3802, 2); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 3742, 8); break; + case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 3798, 4); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 3752, 7); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 3724, 8); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 3706, 6); break; + case SOUND_PED_149: GetPhrase(sfx, ped->m_lastComment, 3776, 16); break; + case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 3750, 2); break; + case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 3804, 2); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 3712, 12); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 3732, 10); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetWMYCWTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 5650, 6); break; + case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 5670, 4); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 5659, 6); break; + case SOUND_PED_ROBBED: return 5676; + case SOUND_PED_TAXI_WAIT: return 5677; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 5635, 8); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 5622, 10); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 5643, 7); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 5598, 9); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 5580, 9); break; + case SOUND_PED_149: GetPhrase(sfx, ped->m_lastComment, 5665, 5); break; + case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 5674, 2); break; + case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 5632, 3); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 5589, 9); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 5607, 15); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetWMYGOTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 7679, 5); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 7684, 6); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 7690, 2); break; + case SOUND_PED_ACCIDENTREACTION1: return 7698; + case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 7701, 3); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 7659, 11); break; + case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 7692, 6); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 7672, 7); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 7642, 7); break; + case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 7670, 2); break; + case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 7699, 2); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 7633, 9); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 7649, 10); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetWFOGOTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 7904, 5); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 7909, 6); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 7915, 2); break; + case SOUND_PED_ACCIDENTREACTION1: return 7919; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 7883, 14); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 7874, 9); break; + case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 7917, 2); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 7897, 7); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 7855, 8); break; + case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 7920, 2); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 7847, 8); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 7863, 11); break; + default: return GetGenericFemaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetWMOGOTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 4982, 5); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 4987, 6); break; + case SOUND_PED_ACCIDENTREACTION1: return 4998; + case SOUND_PED_TAXI_WAIT: return 5002; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 4961, 13); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 4947, 12); break; + case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 4993, 5); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 4974, 8); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 4929, 9); break; + case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 4959, 2); break; + case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 4999, 3); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 4921, 8); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 4938, 9); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetWFYLGTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 8267, 5); break; + case SOUND_PED_ACCIDENTREACTION1: return 8272; + case SOUND_PED_TAXI_WAIT: return 8273; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 8260, 7); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 8252, 8); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 8232, 10); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 8242, 10); break; + default: return GetGenericFemaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetWMYLGTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 3698, 6); break; + case SOUND_PED_ACCIDENTREACTION1: return 3704; + case SOUND_PED_TAXI_WAIT: return 3705; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 3691, 7); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 3682, 9); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 3662, 10); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 3672, 10); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetWFYBUTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 7309, 8); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 7317, 8); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 7325, 4); break; + case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 7340, 2); break; + case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 7329, 8); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 7301, 8); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 7292, 9); break; + case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 7337, 3); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 7271, 21); break; + default: return GetGenericFemaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetWMYBUTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 3862, 6); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 3870, 5); break; + case SOUND_PED_ROBBED: return 3880; + case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 3884, 2); break; + case SOUND_PED_UNK_126: GetPhrase(sfx, ped->m_lastComment, 3868, 2); break; + case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 3891, 2); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 3845, 10); break; + case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 3881, 3); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 3857, 5); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 3826, 9); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 3706, 6); break; + case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 3875, 5); break; + case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 3855, 2); break; + case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 3886, 5); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 3815, 11); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 3835, 10); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetWMOBUTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 6753, 6); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 6759, 7); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 6769, 2); break; + case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 6771, 3); break; + case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 6774, 2); break; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 6743, 3); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 6733, 8); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 6746, 7); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 6726, 7); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 6709, 7); break; + case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 6766, 3); break; + case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 6741, 2); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 6716, 10); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetWFYPRTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 4101, 6); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 4107, 2); break; + case SOUND_PED_ACCIDENTREACTION1: return 4109; + case SOUND_PED_PLAYER_BEFORESEX: GetPhrase(sfx, ped->m_lastComment, 4096, 5); break; + case SOUND_PED_TAXI_WAIT: return 4125; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 4087, 9); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 4077, 10); break; + case SOUND_PED_SOLICIT: GetPhrase(sfx, ped->m_lastComment, 4110, 15); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 4052, 11); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 4063, 14); break; + default: return GetGenericFemaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetWFOTRTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 7371, 6); break; + case SOUND_PED_ACCIDENTREACTION1: return 7383; + case SOUND_PED_TAXI_WAIT: return 7393; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 7362, 9); break; + case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 7377, 6); break; + case SOUND_PED_SOLICIT: GetPhrase(sfx, ped->m_lastComment, 7384, 9); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 7342, 11); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 7353, 9); break; + default: return GetGenericFemaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetWMOTRTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 7542, 5); break; + case SOUND_PED_ACCIDENTREACTION1: return 7547; + case SOUND_PED_TAXI_WAIT: return 7558; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 7536, 6); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 7517, 17); break; + case SOUND_PED_SOLICIT: GetPhrase(sfx, ped->m_lastComment, 7551, 7); break; + case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 7534, 2); break; + case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 7548, 3); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 7494, 10); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 7504, 13); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetWMYPITalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 6496, 5); break; + case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 6509, 4); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 6503, 6); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 6513, 2); break; + case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 6515, 2); break; + case SOUND_PED_UNK_126: GetPhrase(sfx, ped->m_lastComment, 6501, 2); break; + case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 6517, 4); break; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 6479, 7); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 6465, 8); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 6488, 8); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 6457, 8); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 6439, 8); break; + case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 6473, 6); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 6447, 10); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetWMOCATalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 8032, 6); break; + case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 8048, 11); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 8038, 10); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 8059, 2); break; + case SOUND_PED_ACCIDENTREACTION1: return 8061; + case SOUND_PED_TAXI_WAIT: return 8062; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 8015, 8); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 8003, 10); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 8023, 9); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 7993, 10); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 7975, 12); break; + case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 8013, 2); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 7987, 6); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetWFYJGTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 7414, 4); break; + case SOUND_PED_ACCIDENTREACTION1: sfx = 7424; break; + case SOUND_PED_TAXI_WAIT: sfx = 7425; break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 7406, 8); break; + case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 7418, 6); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 7394, 12); break; + default: return GetGenericFemaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetWMYJGTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 5098, 4); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 5102, 2); break; + case SOUND_PED_ACCIDENTREACTION1: return 5109; + case SOUND_PED_TAXI_WAIT: return 5110; + case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 5104, 5); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 5076, 10); break; + case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 5096, 2); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 5086, 10); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetWFYSKTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 3652, 5); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 3657, 2); break; + case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 3659, 2); break; + case SOUND_PED_TAXI_WAIT: return 3661; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 3641, 11); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 3632, 9); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 3603, 11); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 3614, 18); break; + default: return GetGenericFemaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetWMYSKTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 5563, 5); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 5573, 2); break; + case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 5575, 2); break; + case SOUND_PED_UNK_126: GetPhrase(sfx, ped->m_lastComment, 5568, 3); break; + case SOUND_PED_TAXI_WAIT: return 5579; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 5558, 5); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 5546, 10); break; + case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 5571, 2); break; + case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 5556, 2); break; + case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 5577, 2); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 5519, 14); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 5533, 13); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetWFYSHTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 7459, 9); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 7470, 2); break; + case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 7483, 4); break; + case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 7492, 2); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 7448, 11); break; + case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 7472, 11); break; + case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 7468, 2); break; + case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 7487, 5); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 7426, 12); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 7438, 10); break; + default: return GetGenericFemaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetWFOSHTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 3571, 10); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 3583, 2); break; + case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 3594, 3); break; + case SOUND_PED_TAXI_WAIT: return 3602; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 3561, 10); break; + case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 3585, 9); break; + case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 3581, 2); break; + case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 3597, 5); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 3542, 10); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 3552, 9); break; + default: return GetGenericFemaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetJFOTOTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 811, 4); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 815, 5); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 821, 2); break; + case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 828, 2); break; + case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 831, 2); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 796, 9); break; + case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 823, 5); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 805, 6); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 775, 8); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 757, 8); break; + case SOUND_PED_WAIT_DOUBLEBACK: return 820; + case SOUND_PED_CHAT_EVENT: return 830; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 765, 10); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 783, 13); break; + default: return GetGenericFemaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetJMOTOTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 874, 4); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 878, 4); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 883, 2); break; + case SOUND_PED_ACCIDENTREACTION1: return 889; + case SOUND_PED_TAXI_WAIT: return 891; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 862, 6); break; + case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 885, 4); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 868, 6); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 849, 6); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 833, 8); break; + case SOUND_PED_WAIT_DOUBLEBACK: return 882; + case SOUND_PED_CHAT_EVENT: return 890; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 841, 8); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 855, 7); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetCBTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 2178, 5); break; + case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 2187, 5); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 2183, 4); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 2194, 2); break; + case SOUND_PED_ACCIDENTREACTION1: sfx = 2196; break; + case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 2197, 2); break; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 2161, 9); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 2150, 9); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 2170, 8); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 2132, 8); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 2113, 8); break; + case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 2192, 2); break; + case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 2159, 2); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 2121, 11); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 2140, 10); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return 86 * (m_sQueueSample.m_nEntityIndex % 3) + sfx; +} + +uint32 +cAudioManager::GetHNTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 2692, 5); break; + case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 2703, 4); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 2697, 6); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 2711, 3); break; + case SOUND_PED_ACCIDENTREACTION1: sfx = 2714; break; + case SOUND_PED_TAXI_WAIT: sfx = 2715; break; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 2673, 10); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 2661, 10); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 2683, 9); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 2638, 9); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 2617, 9); break; + case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 2707, 4); break; + case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 2671, 2); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 2626, 12); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 2647, 14); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return 99 * (m_sQueueSample.m_nEntityIndex % 3) + sfx; +} + +uint32 +cAudioManager::GetSGTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 1104, 5); break; + case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 1114, 5); break; + case SOUND_PED_MUGGING: GetPhrase(sfx, ped->m_lastComment, 1124, 5); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 1109, 5); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 1121, 3); break; + case SOUND_PED_ACCIDENTREACTION1: sfx = 1129; break; + case SOUND_PED_TAXI_WAIT: sfx = 1132; break; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 1088, 10); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 1076, 9); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 1098, 6); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 1058, 6); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 1040, 8); break; + case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 1119, 2); break; + case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 1085, 3); break; + case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 1130, 2); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 1048, 10); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 1064, 12); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + if(ped->GetModelIndex() == MI_SGB) sfx += 93; + return sfx; +} + +uint32 +cAudioManager::GetCLTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 1299, 5); break; + case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 1310, 5); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 1304, 6); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 1317, 2); break; + case SOUND_PED_ACCIDENTREACTION1: sfx = 1319; break; + case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 1320, 2); break; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 1281, 10); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 1266, 13); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 1291, 8); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 1246, 10); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 1226, 10); break; + case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 1315, 2); break; + case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 1279, 2); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 1236, 10); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 1256, 10); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return 96 * (m_sQueueSample.m_nEntityIndex % 3) + sfx; +} + +uint32 +cAudioManager::GetGDTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 1762, 6); break; + case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 1770, 2); break; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 1755, 7); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 1744, 9); break; + case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 1768, 2); break; + case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 1753, 2); break; + case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 1772, 2); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 1724, 10); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 1734, 10); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return 50 * (m_sQueueSample.m_nEntityIndex % 3) + sfx; +} + +uint32 +cAudioManager::GetBKTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 2429, 5); break; + case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 2442, 4); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 2434, 8); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 2448, 2); break; + case SOUND_PED_ACCIDENTREACTION1: sfx = 2450; break; + case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 2451, 2); break; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 2412, 9); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 2403, 9); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 2421, 8); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 2371, 10); break; + case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 2446, 2); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 2381, 10); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 2391, 12); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return 82 * (m_sQueueSample.m_nEntityIndex % 3) + sfx; +} + +uint32 +cAudioManager::GetPGTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 1561, 4); break; + case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 1570, 5); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 1565, 5); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 1577, 2); break; + case SOUND_PED_ACCIDENTREACTION1: sfx = 1579; break; + case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 1582, 2); break; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 1551, 5); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 1542, 7); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 1556, 5); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 1529, 5); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 1514, 10); break; + case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 1575, 2); break; + case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 1549, 2); break; + case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 1580, 2); break; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 1524, 5); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 1534, 8); break; + default: return GetGenericMaleTalkSfx(ped, sound); + } + return 70 * (m_sQueueSample.m_nEntityIndex % 3) + sfx; +} + +uint32 +cAudioManager::GetVICETalkSfx(CPed *ped, int16 sound, int16 model) +{ + uint32 sfx; + if(model == MI_VICE6) { + + switch(sound) { + case SOUND_PED_ARREST_COP: GetPhrase(sfx, ped->m_lastComment, 1894, 3); break; + case SOUND_PED_MIAMIVICE_EXITING_CAR: return 1897; + default: return GetGenericMaleTalkSfx(ped, sound); + } + } + switch(sound) { + case SOUND_PED_ARREST_COP: GetPhrase(sfx, ped->m_lastComment, 1874, 3); break; + case SOUND_PED_MIAMIVICE_EXITING_CAR: sfx = 1877; break; + + default: return GetGenericMaleTalkSfx(ped, sound); + } + sfx += 4 * (m_sQueueSample.m_nEntityIndex % 5); + return sfx; +} + +uint32 +cAudioManager::GetWFYG1TalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 3383, 6); break; + case SOUND_PED_MUGGING: GetPhrase(sfx, ped->m_lastComment, 3399, 2); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 3389, 5); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 3397, 2); break; + case SOUND_PED_ACCIDENTREACTION1: return 3403; + case SOUND_PED_TAXI_WAIT: return 3405; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 3372, 4); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 3361, 9); break; + case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 3401, 2); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 3376, 7); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 3342, 9); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 3324, 7); break; + case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 3394, 3); break; + case SOUND_153: GetPhrase(sfx, ped->m_lastComment, 3370, 2); break; + case SOUND_PED_CHAT_EVENT: return 3404; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 3331, 11); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 3351, 10); break; + default: return GetGenericFemaleTalkSfx(ped, sound); + } + return sfx; +} + +uint32 +cAudioManager::GetWFYG2TalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + switch(sound) { + case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 3464, 3); break; + case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 3467, 5); break; + case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 3473, 2); break; + case SOUND_PED_TAXI_WAIT: return 3476; + case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 3452, 5); break; + case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 3440, 8); break; + case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 3457, 7); break; + case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 3422, 9); break; + case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 3406, 5); break; + case SOUND_PED_WAIT_DOUBLEBACK: return 3472; + case SOUND_153: GetPhrase(sfx, ped->m_lastComment, 3448, 4); break; + case SOUND_PED_CHAT_EVENT: return 3475; + case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 3411, 11); break; + case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 3431, 9); break; + default: return GetGenericFemaleTalkSfx(ped, sound); + } + + return sfx; +} + +uint32 +cAudioManager::GetGenericMaleTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + + m_bGenericSfx = true; + switch(sound) { + case SOUND_PED_DEATH: GetPhrase(sfx, ped->m_lastComment, SFX_GENERIC_MALE_DEATH_1, 41); break; + case SOUND_PED_BULLET_HIT: + case SOUND_PED_DEFEND: GetPhrase(sfx, ped->m_lastComment, SFX_GENERIC_MALE_GRUNT_1, 41); break; + case SOUND_PED_BURNING: GetPhrase(sfx, ped->m_lastComment, SFX_GENERIC_MALE_FIRE_1, 32); break; + case SOUND_PED_FLEE_SPRINT: GetPhrase(sfx, ped->m_lastComment, SFX_GENERIC_MALE_PANIC_1, 35); break; + default: return NO_SAMPLE; + } + return sfx; +} + +uint32 +cAudioManager::GetGenericFemaleTalkSfx(CPed *ped, int16 sound) +{ + uint32 sfx; + m_bGenericSfx = true; + switch(sound) { + case SOUND_PED_DEATH: GetPhrase(sfx, ped->m_lastComment, 2931, 22); break; + case SOUND_PED_BULLET_HIT: + case SOUND_PED_DEFEND: GetPhrase(sfx, ped->m_lastComment, 2953, 33); break; + case SOUND_PED_BURNING: GetPhrase(sfx, ped->m_lastComment, 2914, 17); break; + case SOUND_PED_FLEE_SPRINT: GetPhrase(sfx, ped->m_lastComment, 2986, 27); break; + default: return NO_SAMPLE; + } + return sfx; +} + +void +cPedComments::Add(tPedComment *com) +{ + uint8 index; + + if (m_nCommentsInBank[m_nActiveBank] >= NUM_PED_COMMENTS_SLOTS) { + index = m_nIndexMap[m_nActiveBank][NUM_PED_COMMENTS_SLOTS - 1]; + if (m_asPedComments[m_nActiveBank][index].m_bVolume > com->m_bVolume) + return; + } else { + index = m_nCommentsInBank[m_nActiveBank]++; + } + + m_asPedComments[m_nActiveBank][index] = *com; + + uint32 i = 0; + if (index != 0) { + for (i = 0; i < index; i++) { + if (m_asPedComments[m_nActiveBank][m_nIndexMap[m_nActiveBank][i]].m_bVolume < m_asPedComments[m_nActiveBank][index].m_bVolume) { + break; + } + } + + if (i < index) + memmove(&m_nIndexMap[m_nActiveBank][i + 1], &m_nIndexMap[m_nActiveBank][i], NUM_PED_COMMENTS_SLOTS - 1 - i); + } + + m_nIndexMap[m_nActiveBank][i] = index; +} + +void +cPedComments::Process() +{ + uint32 sampleIndex; + uint8 actualUsedBank; + tPedComment *comment; + bool prevUsed = false; + static uint8 counter = 0; + static int32 prevSamples[10]; + + if(AudioManager.m_nUserPause != 0) return; + + if(m_nCommentsInBank[m_nActiveBank]) { + for(int i = 0; i < ARRAY_SIZE(prevSamples); i++) { + if(m_asPedComments[m_nActiveBank][m_nIndexMap[m_nActiveBank][0]].m_nSampleIndex == + prevSamples[(counter + 1 + i) % ARRAY_SIZE(prevSamples)]) { + m_asPedComments[m_nActiveBank][m_nIndexMap[m_nActiveBank][0]].m_nProcess = -1; + prevUsed = true; + break; + } + } + if(!prevUsed) { + sampleIndex = m_asPedComments[m_nActiveBank][m_nIndexMap[m_nActiveBank][0]].m_nSampleIndex; + if(!SampleManager.IsPedCommentLoaded(sampleIndex)) { +#if defined(GTA_PC) && !defined(FIX_BUGS) + if(!m_bDelay) +#endif + SampleManager.LoadPedComment(sampleIndex); + } else { + AudioManager.m_sQueueSample.m_nEntityIndex = m_asPedComments[m_nActiveBank][m_nIndexMap[m_nActiveBank][0]].m_nEntityIndex; + AudioManager.m_sQueueSample.m_nCounter = 0; + AudioManager.m_sQueueSample.m_nSampleIndex = sampleIndex; + AudioManager.m_sQueueSample.m_nBankIndex = SFX_BANK_PED_COMMENTS; + AudioManager.m_sQueueSample.m_nReleasingVolumeModificator = 3; + AudioManager.m_sQueueSample.m_nVolume = m_asPedComments[m_nActiveBank][m_nIndexMap[m_nActiveBank][0]].m_bVolume; + AudioManager.m_sQueueSample.m_fDistance = m_asPedComments[m_nActiveBank][m_nIndexMap[m_nActiveBank][0]].m_fDistance; + AudioManager.m_sQueueSample.m_nLoopCount = 1; + AudioManager.m_sQueueSample.m_nLoopStart = 0; + AudioManager.m_sQueueSample.m_nLoopEnd = -1; + AudioManager.m_sQueueSample.m_nEmittingVolume = MAX_VOLUME; + AudioManager.m_sQueueSample.m_fSpeedMultiplier = 3.0f; + AudioManager.m_sQueueSample.m_fSoundIntensity = 40.0f; + AudioManager.m_sQueueSample.m_bReleasingSoundFlag = true; + AudioManager.m_sQueueSample.m_vecPos = m_asPedComments[m_nActiveBank][m_nIndexMap[m_nActiveBank][0]].m_vecPos; + AudioManager.m_sQueueSample.m_bReverbFlag = true; + AudioManager.m_sQueueSample.m_bRequireReflection = true; + AudioManager.m_sQueueSample.m_bIs2D = false; +#ifdef FIX_BUGS + if (sampleIndex >= 8694 && sampleIndex < TOTAL_AUDIO_SAMPLES) { // check if player sfx, TODO: enum + AudioManager.m_sQueueSample.m_bIs2D = true; + AudioManager.m_sQueueSample.m_nOffset = 63; + } +#endif // FIX_BUGS + AudioManager.m_sQueueSample.m_nFrequency = + SampleManager.GetSampleBaseFrequency(AudioManager.m_sQueueSample.m_nSampleIndex) + AudioManager.RandomDisplacement(750); + if(CTimer::GetIsSlowMotionActive()) AudioManager.m_sQueueSample.m_nFrequency /= 2; + m_asPedComments[m_nActiveBank][m_nIndexMap[m_nActiveBank][0]].m_nProcess = -1; + prevSamples[counter++] = sampleIndex; + if(counter == 10) counter = 0; + AudioManager.AddSampleToRequestedQueue(); +#if defined(GTA_PC) && !defined(FIX_BUGS) + m_nDelayTimer = CTimer::GetTimeInMilliseconds(); + m_bDelay = true; +#endif + } + } + } + + // Switch bank + if (m_nActiveBank) { + actualUsedBank = SFX_BANK_PED_COMMENTS; + m_nActiveBank = SFX_BANK_0; + } else { + actualUsedBank = SFX_BANK_0; + m_nActiveBank = SFX_BANK_PED_COMMENTS; + } + comment = m_asPedComments[actualUsedBank]; + for (uint32 i = 0; i < m_nCommentsInBank[actualUsedBank]; i++) { + if (m_asPedComments[actualUsedBank][m_nIndexMap[actualUsedBank][i]].m_nProcess > 0) { + --m_asPedComments[actualUsedBank][m_nIndexMap[actualUsedBank][i]].m_nProcess; + Add(&comment[m_nIndexMap[actualUsedBank][i]]); + } + } + + for (uint32 i = 0; i < NUM_PED_COMMENTS_SLOTS; i++) { + m_nIndexMap[actualUsedBank][i] = NUM_PED_COMMENTS_SLOTS; + } + m_nCommentsInBank[actualUsedBank] = 0; +#if defined(GTA_PC) && !defined(FIX_BUGS) + if(m_bDelay) + if(CTimer::GetTimeInMilliseconds() - m_nDelayTimer > 6000) m_bDelay = false; +#endif +} + +#undef cooldown_phrase + +#pragma endregion + +#pragma endregion All the ped audio code + +void +cAudioManager::ProcessExplosions(int32 explosion) +{ + uint8 type; + float distSquared; + + for (uint8 i = 0; i < ARRAY_SIZE(gaExplosion); i++) { + if (CExplosion::DoesExplosionMakeSound(i) && CExplosion::GetExplosionActiveCounter(i) == 1) { + CExplosion::ResetExplosionActiveCounter(i); + type = CExplosion::GetExplosionType(i); + switch (type) { + case EXPLOSION_GRENADE: + case EXPLOSION_ROCKET: + case EXPLOSION_BARREL: + case EXPLOSION_TANK_GRENADE: + m_sQueueSample.m_fSoundIntensity = 200.0f; + m_sQueueSample.m_nSampleIndex = SFX_EXPLOSION_2; + m_sQueueSample.m_nFrequency = RandomDisplacement(1000) + 19000; + m_sQueueSample.m_nReleasingVolumeModificator = 0; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_bRequireReflection = true; + break; + case EXPLOSION_MOLOTOV: + m_sQueueSample.m_fSoundIntensity = 150.0f; + m_sQueueSample.m_nSampleIndex = SFX_EXPLOSION_3; + m_sQueueSample.m_nFrequency = RandomDisplacement(1000) + 19000; + m_sQueueSample.m_nReleasingVolumeModificator = 0; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_bRequireReflection = false; + break; + case EXPLOSION_MINE: + case EXPLOSION_HELI_BOMB: + m_sQueueSample.m_fSoundIntensity = 200.0f; + m_sQueueSample.m_nSampleIndex = SFX_ROCKET_LEFT; + m_sQueueSample.m_nFrequency = RandomDisplacement(1000) + 12347; + m_sQueueSample.m_nReleasingVolumeModificator = 0; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_bRequireReflection = true; + break; + default: + m_sQueueSample.m_fSoundIntensity = 200.0f; + m_sQueueSample.m_nSampleIndex = SFX_EXPLOSION_1; + m_sQueueSample.m_nFrequency = RandomDisplacement(1000) + 19500; + if (type == EXPLOSION_HELI) + m_sQueueSample.m_nFrequency = 8 * m_sQueueSample.m_nFrequency / 10; //same *= 8 / 10; + m_sQueueSample.m_nReleasingVolumeModificator = 0; + m_sQueueSample.m_nBankIndex = SFX_BANK_GENERIC_EXTRA; + break; + } + m_sQueueSample.m_vecPos = *CExplosion::GetExplosionPosition(i); + distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); + if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) { + m_sQueueSample.m_fDistance = Sqrt(distSquared); + m_sQueueSample.m_nVolume = ComputeVolume(MAX_VOLUME, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = i; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_nEmittingVolume = MAX_VOLUME; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_bReverbFlag = true; + AddSampleToRequestedQueue(); + } + } + } + } +} + +void +cAudioManager::ProcessFires(int32) +{ + CEntity *entity; + uint8 emittingVol; + float distSquared; + + for (uint8 i = 0; i < NUM_FIRES; i++) { + if (gFireManager.m_aFires[i].m_bIsOngoing && gFireManager.m_aFires[i].m_bAudioSet) { + entity = gFireManager.m_aFires[i].m_pEntity; + if (entity) { + switch (entity->GetType()) { + case ENTITY_TYPE_BUILDING: + m_sQueueSample.m_fSoundIntensity = 80.0f; + m_sQueueSample.m_nSampleIndex = SFX_CAR_ON_FIRE; + emittingVol = 100; + m_sQueueSample.m_nFrequency = 8 * SampleManager.GetSampleBaseFrequency(SFX_CAR_ON_FIRE) / 10; + m_sQueueSample.m_nFrequency += i * (m_sQueueSample.m_nFrequency / 64); + m_sQueueSample.m_nReleasingVolumeModificator = 6; + break; + case ENTITY_TYPE_PED: + m_sQueueSample.m_fSoundIntensity = 25.0f; + m_sQueueSample.m_nSampleIndex = SFX_PED_ON_FIRE; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_PED_ON_FIRE); + emittingVol = 60; + m_sQueueSample.m_nFrequency += i * (m_sQueueSample.m_nFrequency / 64); + m_sQueueSample.m_nReleasingVolumeModificator = 10; + break; + default: + m_sQueueSample.m_fSoundIntensity = 80.0f; + m_sQueueSample.m_nSampleIndex = SFX_CAR_ON_FIRE; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CAR_ON_FIRE); + m_sQueueSample.m_nFrequency += i * (m_sQueueSample.m_nFrequency / 64); + emittingVol = 80; + m_sQueueSample.m_nReleasingVolumeModificator = 8; + } + } else { + m_sQueueSample.m_fSoundIntensity = 80.0f; + m_sQueueSample.m_nSampleIndex = SFX_CAR_ON_FIRE; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CAR_ON_FIRE); + emittingVol = 80; + m_sQueueSample.m_nReleasingVolumeModificator = 8; + } + m_sQueueSample.m_vecPos = gFireManager.m_aFires[i].m_vecPos; + distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); + if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) { + m_sQueueSample.m_fDistance = Sqrt(distSquared); + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = i; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_nReleasingVolumeDivider = 10; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + if (gFireManager.m_aFires[i].m_bExtinguishedWithWater) { + gFireManager.m_aFires[i].m_bExtinguishedWithWater = false; + emittingVol = 100.0f * gFireManager.m_aFires[i].m_fWaterExtinguishCountdown; + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nSampleIndex = SFX_JUMBO_TAXI; + m_sQueueSample.m_nFrequency = 19591; + m_sQueueSample.m_nFrequency += i * (m_sQueueSample.m_nFrequency / 64); + m_sQueueSample.m_nReleasingVolumeModificator = 9; + m_sQueueSample.m_nCounter = i + 40; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_nReleasingVolumeDivider = 10; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + } + } +} + +void +cAudioManager::ProcessWaterCannon(int32) +{ + const float SOUND_INTENSITY = 30.0f; + + for (int32 i = 0; i < NUM_WATERCANNONS; i++) { + if (CWaterCannons::aCannons[i].m_nId) { + m_sQueueSample.m_vecPos = CWaterCannons::aCannons[0].m_avecPos[CWaterCannons::aCannons[i].m_nCur]; + float distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); + if (distSquared < SQR(SOUND_INTENSITY)) { + m_sQueueSample.m_fDistance = Sqrt(distSquared); + m_sQueueSample.m_nVolume = ComputeVolume(50, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_nSampleIndex = SFX_JUMBO_TAXI; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nFrequency = 15591; + m_sQueueSample.m_nReleasingVolumeModificator = 5; + m_sQueueSample.m_nCounter = i; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_nReleasingVolumeDivider = 8; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nEmittingVolume = 50; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + } + } +} + +//positon of arcade machines +CVector aVecExtraSoundPosition[] = { CVector(-1042.546f, 88.794f, 11.324f), CVector(-1004.476f, 181.697f, 11.324f) }; + +void +cAudioManager::ProcessExtraSounds() +{ + const float SOUND_INTENSITY = 18.0f; + const uint8 EMITTING_VOLUME = 50; + + float distance; + + for (int i = 0; i < ARRAY_SIZE(aVecExtraSoundPosition); i++) { + m_sQueueSample.m_vecPos = aVecExtraSoundPosition[i]; + distance = GetDistanceSquared(m_sQueueSample.m_vecPos); + if (distance < SQR(SOUND_INTENSITY)) { + m_sQueueSample.m_fDistance = Sqrt(distance); + m_sQueueSample.m_nVolume = ComputeVolume(EMITTING_VOLUME, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = i; + m_sQueueSample.m_nSampleIndex = SFX_ARCADE; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_ARCADE); + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeModificator = 4; + m_sQueueSample.m_fSpeedMultiplier = 3.0f; + m_sQueueSample.m_nEmittingVolume = EMITTING_VOLUME; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(SFX_ARCADE); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(SFX_ARCADE); + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bRequireReflection = false; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + AddSampleToRequestedQueue(); + } + } + } +} + +void +cAudioManager::ProcessEscalators() +{ + const float SOUND_INTENSITY = 30.0f; + const uint8 EMITTING_VOLUME = 26; + + float distance; + + for (int i = 0; i < CEscalators::NumEscalators; i++) { + if (!CEscalators::GetEscalator(i).IsActive()) + continue; + m_sQueueSample.m_vecPos = CEscalators::GetEscalator(i).GetPosition(); + distance = GetDistanceSquared(m_sQueueSample.m_vecPos); + if (distance < SQR(SOUND_INTENSITY)) { + m_sQueueSample.m_fDistance = Sqrt(distance); + m_sQueueSample.m_nVolume = ComputeVolume(EMITTING_VOLUME, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nSampleIndex = SFX_BOAT_V12_LOOP; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nFrequency = i * 50 % 250 + 3973; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 3.0f; + m_sQueueSample.m_nReleasingVolumeDivider = 5; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_nCounter = i; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = EMITTING_VOLUME; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(SFX_BOAT_V12_LOOP); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(SFX_BOAT_V12_LOOP); + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + } +} + +#pragma region SCRIPT_OBJECTS +const int SCRIPT_OBJECT_INTENSITY_S = 30; +const int SCRIPT_OBJECT_INTENSITY_L = 80; + +void +cAudioManager::ProcessScriptObject(int32 id) +{ + if (MusicManager.m_nMusicMode == MUSICMODE_GAME) { + cAudioScriptObject* entity = (cAudioScriptObject*)m_asAudioEntities[id].m_pEntity; + if (entity != nil) { + m_sQueueSample.m_vecPos = entity->Posn; + if (m_asAudioEntities[id].m_AudioEvents == 1) + ProcessOneShotScriptObject(m_asAudioEntities[id].m_awAudioEvent[0]); + else + ProcessLoopingScriptObject(entity->AudioId); + } + } +} + +void +cAudioManager::ProcessOneShotScriptObject(uint8 sound) +{ + CPlayerPed *playerPed; + uint8 emittingVolume; + float distSquared; + + static uint8 iSound = 0; + + switch (sound) { + case SCRIPT_SOUND_POLICE_CELL_DOOR_CLUNK: + m_sQueueSample.m_fSoundIntensity = 40.0f; + m_sQueueSample.m_nSampleIndex = SFX_COL_GATE; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nFrequency = 10600; + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + emittingVolume = 60; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bRequireReflection = true; + break; + case SCRIPT_SOUND_GARAGE_DOOR_CLUNK: + m_sQueueSample.m_fSoundIntensity = 80.0f; + m_sQueueSample.m_nSampleIndex = SFX_COL_CAR_PANEL_2; // huh? + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nFrequency = 22000; + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); + m_sQueueSample.m_nReleasingVolumeModificator = 4; + emittingVolume = 60; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bRequireReflection = true; + break; + case SCRIPT_SOUND_SHOOTING_RANGE_TARGET_HIT: + case SCRIPT_SOUND_BULLET_HIT_GROUND_1: + case SCRIPT_SOUND_BULLET_HIT_GROUND_2: + case SCRIPT_SOUND_BULLET_HIT_GROUND_3: + m_sQueueSample.m_fSoundIntensity = 50.0f; + m_sQueueSample.m_nSampleIndex = m_anRandomTable[iSound % 5] % 3 + SFX_BULLET_WALL_1; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); + m_sQueueSample.m_nReleasingVolumeModificator = 9; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_bIs2D = false; + emittingVolume = m_anRandomTable[2] % 20 + 90; + break; + case SCRIPT_SOUND_WILLIE_CARD_SWIPE: + emittingVolume = 70; + m_sQueueSample.m_fSoundIntensity = 40.0f; + m_sQueueSample.m_nSampleIndex = SFX_BOMB_BEEP; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nFrequency = 20159; + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_fSpeedMultiplier = 1.0f; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bRequireReflection = false; + break; + case SCRIPT_SOUND_MALE_AMBULANCE_OUCH: + { + cPedParams pedParams; + pedParams.m_fDistance = GetDistanceSquared(m_sQueueSample.m_vecPos); + SetupPedComments(pedParams, SOUND_INJURED_PED_MALE_OUCH); + return; + } + case SCRIPT_SOUND_FEMALE_AMBULANCE_OUCH: + { + cPedParams pedParams; + pedParams.m_fDistance = GetDistanceSquared(m_sQueueSample.m_vecPos); + SetupPedComments(pedParams, SOUND_INJURED_PED_FEMALE); + return; + } + case SCRIPT_SOUND_SEAPLANE_LOW_FUEL: + m_sQueueSample.m_fSoundIntensity = 1000.0f; + m_sQueueSample.m_nSampleIndex = SFX_SEAPLANE_LOW; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + emittingVolume = 100; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CAR_HORN_JEEP); // BUG? + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_bIs2D = true; + m_sQueueSample.m_bRequireReflection = false; + break; + case SCRIPT_SOUND_PAYPHONE_RINGING: + m_sQueueSample.m_fSoundIntensity = 80.0f; + m_sQueueSample.m_nSampleIndex = SFX_PHONE_RING; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + emittingVolume = 80; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_PHONE_RING); + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bRequireReflection = false; + break; + case SCRIPT_SOUND_GLASS_BREAK_L: + m_sQueueSample.m_fSoundIntensity = 60.0f; + m_sQueueSample.m_nSampleIndex = SFX_GLASS_SMASH; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + emittingVolume = 70; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_GLASS_SMASH); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_bIs2D = false; + break; + case SCRIPT_SOUND_GLASS_BREAK_S: + m_sQueueSample.m_fSoundIntensity = 60.0f; + m_sQueueSample.m_nSampleIndex = SFX_GLASS_SMASH; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + emittingVolume = 60; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_GLASS_SMASH); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_bIs2D = false; + break; + case SCRIPT_SOUND_GLASS_CRACK: + m_sQueueSample.m_fSoundIntensity = 60.0f; + m_sQueueSample.m_nSampleIndex = SFX_GLASS_CRACK; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + emittingVolume = 70; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_GLASS_CRACK); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bRequireReflection = true; + break; + case SCRIPT_SOUND_GLASS_LIGHT_BREAK: + m_sQueueSample.m_fSoundIntensity = 55.0f; + m_sQueueSample.m_nSampleIndex = (m_anRandomTable[4] & 3) + SFX_GLASS_SHARD_1; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nFrequency = RandomDisplacement(2000) + 19000; + m_sQueueSample.m_nReleasingVolumeModificator = 9; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_bIs2D = false; + emittingVolume = RandomDisplacement(11) + 25; + break; + case SCRIPT_SOUND_BOX_DESTROYED_1: + m_sQueueSample.m_fSoundIntensity = 60.0f; + m_sQueueSample.m_nSampleIndex = SFX_WOODEN_BOX_SMASH; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nFrequency = RandomDisplacement(1500) + 18600; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bRequireReflection = true; + emittingVolume = m_anRandomTable[2] % 20 + 80; + break; + case SCRIPT_SOUND_BOX_DESTROYED_2: + m_sQueueSample.m_fSoundIntensity = 60.0f; + m_sQueueSample.m_nSampleIndex = SFX_CARDBOARD_BOX_SMASH; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nFrequency = RandomDisplacement(1500) + 18600; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bRequireReflection = true; + emittingVolume = m_anRandomTable[2] % 20 + 80; + break; + case SCRIPT_SOUND_METAL_COLLISION: + m_sQueueSample.m_fSoundIntensity = 60.0f; + m_sQueueSample.m_nSampleIndex = m_anRandomTable[3] % 5 + SFX_COL_CAR_1; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bRequireReflection = true; + emittingVolume = m_anRandomTable[2] % 30 + 70; + break; + case SCRIPT_SOUND_TIRE_COLLISION: + m_sQueueSample.m_fSoundIntensity = 60.0f; + m_sQueueSample.m_nSampleIndex = SFX_TYRE_BUMP; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bRequireReflection = true; + emittingVolume = m_anRandomTable[2] % 30 + 60; + break; + case SCRIPT_SOUND_HIT_BALL: + m_sQueueSample.m_fSoundIntensity = 60.0f; + m_sQueueSample.m_nSampleIndex = SFX_HIT_BALL; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16); + m_sQueueSample.m_nReleasingVolumeModificator = 5; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bRequireReflection = true; + emittingVolume = m_anRandomTable[2] % 30 + 60; + break; + case SCRIPT_SOUND_GUNSHELL_DROP: + playerPed = FindPlayerPed(); + if (playerPed) { + switch (playerPed->m_nSurfaceTouched) { + case SURFACE_GRASS: + case SURFACE_GRAVEL: + case SURFACE_MUD_DRY: + case SURFACE_TRANSPARENT_CLOTH: + case SURFACE_PED: + case SURFACE_SAND: + case SURFACE_RUBBER: + case SURFACE_HEDGE: + case SURFACE_SAND_BEACH: + m_sQueueSample.m_nSampleIndex = SFX_BULLET_SHELL_HIT_GROUND_2; + m_sQueueSample.m_nFrequency = RandomDisplacement(600) + 10600; + m_sQueueSample.m_nReleasingVolumeModificator = 18; + break; + case SURFACE_WATER: + return; + default: + m_sQueueSample.m_nSampleIndex = SFX_BULLET_SHELL_HIT_GROUND_1; + m_sQueueSample.m_nFrequency = RandomDisplacement(1500) + 30000; + m_sQueueSample.m_nReleasingVolumeModificator = 15; + break; + } + } else { + m_sQueueSample.m_nSampleIndex = SFX_BULLET_SHELL_HIT_GROUND_1; + m_sQueueSample.m_nFrequency = RandomDisplacement(1500) + 30000; + m_sQueueSample.m_nReleasingVolumeModificator = 15; + } + m_sQueueSample.m_fSoundIntensity = 20.0f; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_bIs2D = false; + emittingVolume = m_anRandomTable[2] % 20 + 30; + break; + case SCRIPT_SOUND_GUNSHELL_DROP_SOFT: + m_sQueueSample.m_nSampleIndex = SFX_BULLET_SHELL_HIT_GROUND_2; + m_sQueueSample.m_nFrequency = RandomDisplacement(500) + 11000; + m_sQueueSample.m_nReleasingVolumeModificator = 18; + m_sQueueSample.m_fSoundIntensity = 20.0f; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_bIs2D = false; + emittingVolume = m_anRandomTable[2] % 20 + 30; + break; + default: + return; + } + + distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); + if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) { + m_sQueueSample.m_fDistance = Sqrt(distSquared); + m_sQueueSample.m_nVolume = ComputeVolume(emittingVolume, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = iSound++; + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_nEmittingVolume = emittingVolume; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_bReverbFlag = true; + AddSampleToRequestedQueue(); + } + } +} + +void +cAudioManager::ProcessLoopingScriptObject(uint8 sound) +{ + uint8 emittingVolume; + float distSquared; + + switch(sound) { + case SCRIPT_SOUND_BANK_ALARM_LOOP: + m_sQueueSample.m_fSoundIntensity = 80.0f; + m_sQueueSample.m_nSampleIndex = SFX_BUILDINGS_BANK_ALARM; + m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_BANK_ALARM; + emittingVolume = 90; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_BUILDINGS_BANK_ALARM); + m_sQueueSample.m_nReleasingVolumeModificator = 2; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_bIs2D = false; + break; + case SCRIPT_SOUND_POLICE_CELL_DOOR_SLIDING_LOOP: + case SCRIPT_SOUND_GARAGE_DOOR_SLIDING_LOOP: + m_sQueueSample.m_fSoundIntensity = 80.0f; + m_sQueueSample.m_nSampleIndex = SFX_GARAGE_DOOR_LOOP; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + emittingVolume = 90; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_GARAGE_DOOR_LOOP); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_bIs2D = false; + break; + case SCRIPT_SOUND_SNORING_LOOP: + m_sQueueSample.m_fSoundIntensity = 6.0f; + m_sQueueSample.m_nSampleIndex = SFX_BUILDING_SNORE; + m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_SNORING; + emittingVolume = 25; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_BUILDING_SNORE); + m_sQueueSample.m_nReleasingVolumeModificator = 6; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 3.0f; + m_sQueueSample.m_bIs2D = false; + break; + case SCRIPT_SOUND_SHOOTING_RANGE_TARGET_MOVING_LOOP: + m_sQueueSample.m_fSoundIntensity = 40.0f; + m_sQueueSample.m_nSampleIndex = SFX_TANK_TURRET; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + emittingVolume = 60; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_TANK_TURRET); + m_sQueueSample.m_nReleasingVolumeModificator = 4; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_bIs2D = false; + break; + case SCRIPT_SOUND_NEW_BUILDING_BAR_1: + m_sQueueSample.m_nSampleIndex = SFX_BUILDING_BAR_1; + m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_BAR_1; + m_sQueueSample.m_fSoundIntensity = 80.0f; + emittingVolume = 127; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 15; + m_sQueueSample.m_fSpeedMultiplier = 4.0f; + m_sQueueSample.m_bIs2D = false; + break; + case SCRIPT_SOUND_NEW_BUILDING_BAR_2: + m_sQueueSample.m_nSampleIndex = SFX_BUILDING_BAR_2; + m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_BAR_2; + m_sQueueSample.m_fSoundIntensity = 80.0f; + emittingVolume = 127; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 15; + m_sQueueSample.m_fSpeedMultiplier = 4.0f; + m_sQueueSample.m_bIs2D = false; + break; + case SCRIPT_SOUND_NEW_BUILDING_BAR_3: + m_sQueueSample.m_nSampleIndex = SFX_BUILDING_BAR_3; + m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_BAR_3; + m_sQueueSample.m_fSoundIntensity = 80.0f; + emittingVolume = 127; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 15; + m_sQueueSample.m_fSpeedMultiplier = 4.0f; + m_sQueueSample.m_bIs2D = false; + break; + case SCRIPT_SOUND_NEW_BUILDING_BAR_4: + m_sQueueSample.m_nSampleIndex = SFX_BUILDING_BAR_4; + m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_BAR_4; + m_sQueueSample.m_fSoundIntensity = 80.0f; + emittingVolume = 127; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 15; + m_sQueueSample.m_fSpeedMultiplier = 4.0f; + m_sQueueSample.m_bIs2D = false; + break; + case SCRIPT_SOUND_NEW_BUILDING_MALIBU_1: + if(MusicManager.m_nPlayingTrack == STREAMED_SOUND_MALIBU_AMBIENT) return; + m_sQueueSample.m_nSampleIndex = SFX_BUILDING_MAL1; + m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_MALIBU_1; + MusicManager.SetMalibuClubTrackPos(SCRIPT_SOUND_NEW_BUILDING_MALIBU_1); + m_sQueueSample.m_fSoundIntensity = 80.0f; + emittingVolume = 127; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 15; + m_sQueueSample.m_fSpeedMultiplier = 4.0f; + m_sQueueSample.m_bIs2D = false; + break; + case SCRIPT_SOUND_NEW_BUILDING_MALIBU_2: + if(MusicManager.m_nPlayingTrack == STREAMED_SOUND_MALIBU_AMBIENT) return; + m_sQueueSample.m_nSampleIndex = SFX_BUILDING_MAL2; + m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_MALIBU_2; + MusicManager.SetMalibuClubTrackPos(SCRIPT_SOUND_NEW_BUILDING_MALIBU_2); + m_sQueueSample.m_fSoundIntensity = 80.0f; + emittingVolume = 127; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 15; + m_sQueueSample.m_fSpeedMultiplier = 4.0f; + m_sQueueSample.m_bIs2D = false; + break; + case SCRIPT_SOUND_NEW_BUILDING_MALIBU_3: + if(MusicManager.m_nPlayingTrack == STREAMED_SOUND_MALIBU_AMBIENT) return; + m_sQueueSample.m_nSampleIndex = SFX_BUILDING_MAL3; + m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_MALIBU_3; + MusicManager.SetMalibuClubTrackPos(SCRIPT_SOUND_NEW_BUILDING_MALIBU_3); + m_sQueueSample.m_fSoundIntensity = 80.0f; + emittingVolume = 127; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 15; + m_sQueueSample.m_fSpeedMultiplier = 4.0f; + m_sQueueSample.m_bIs2D = false; + break; + case SCRIPT_SOUND_NEW_BUILDING_STRIP_1: + if(MusicManager.m_nPlayingTrack == STREAMED_SOUND_STRIPCLUB_AMBIENT) return; + m_sQueueSample.m_nSampleIndex = SFX_BUILDING_STR1; + m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_STRIP_1; + MusicManager.SetStripClubTrackPos(SCRIPT_SOUND_NEW_BUILDING_STRIP_1); + m_sQueueSample.m_fSoundIntensity = 80.0f; + emittingVolume = 127; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 15; + m_sQueueSample.m_fSpeedMultiplier = 4.0f; + m_sQueueSample.m_bIs2D = false; + break; + case SCRIPT_SOUND_NEW_BUILDING_STRIP_2: + if(MusicManager.m_nPlayingTrack == STREAMED_SOUND_STRIPCLUB_AMBIENT) return; + m_sQueueSample.m_nSampleIndex = SFX_BUILDING_STR2; + m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_STRIP_2; + MusicManager.SetStripClubTrackPos(SCRIPT_SOUND_NEW_BUILDING_STRIP_2); + m_sQueueSample.m_fSoundIntensity = 80.0f; + emittingVolume = 127; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 15; + m_sQueueSample.m_fSpeedMultiplier = 4.0f; + m_sQueueSample.m_bIs2D = false; + break; + case SCRIPT_SOUND_NEW_BUILDING_STRIP_3: + if(MusicManager.m_nPlayingTrack == STREAMED_SOUND_STRIPCLUB_AMBIENT) return; + m_sQueueSample.m_nSampleIndex = SFX_BUILDING_STR3; + m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_STRIP_3; + MusicManager.SetStripClubTrackPos(SCRIPT_SOUND_NEW_BUILDING_STRIP_3); + m_sQueueSample.m_fSoundIntensity = 80.0f; + emittingVolume = 127; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 15; + m_sQueueSample.m_fSpeedMultiplier = 4.0f; + m_sQueueSample.m_bIs2D = false; + break; + case SCRIPT_SOUND_NEW_BUILDING_CHURCH: + m_sQueueSample.m_nSampleIndex = SFX_BUILDING_CHURCH; + m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_CHURCH; + m_sQueueSample.m_fSoundIntensity = 80.0f; + emittingVolume = 127; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nReleasingVolumeDivider = 15; + m_sQueueSample.m_fSpeedMultiplier = 4.0f; + m_sQueueSample.m_bIs2D = false; + break; + case SCRIPT_SOUND_NEW_WATERFALL: + emittingVolume = 30; + m_sQueueSample.m_fSoundIntensity = 80.0f; + m_sQueueSample.m_nSampleIndex = SFX_BOAT_WATER_LOOP; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nFrequency = 20812; + m_sQueueSample.m_nReleasingVolumeModificator = 4; + m_sQueueSample.m_nReleasingVolumeDivider = 9; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_bIs2D = false; + break; + default: return; + } + + distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); + if(distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) { + m_sQueueSample.m_fDistance = Sqrt(distSquared); + m_sQueueSample.m_nVolume = ComputeVolume(emittingVolume, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); + if(m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 0; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_nEmittingVolume = emittingVolume; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } +} +#pragma endregion All the code for script object audio on the map + +void +cAudioManager::ProcessWeather(int32 id) +{ + uint8 vol; + float x; + float y; + float modifier; + float wind; + + static uint8 iSound = 0; + + if (m_asAudioEntities[id].m_AudioEvents != 0 && m_asAudioEntities[id].m_awAudioEvent[0] == SOUND_LIGHTNING) { + if (m_asAudioEntities[id].m_afVolume[0] >= 10.f) { + m_sQueueSample.m_nSampleIndex = SFX_EXPLOSION_1; + m_sQueueSample.m_nBankIndex = SFX_BANK_GENERIC_EXTRA; + m_sQueueSample.m_nFrequency = RandomDisplacement(500) + 4000; + vol = (m_asAudioEntities[id].m_afVolume[0] - 10.0f) + 40; + } else { + m_sQueueSample.m_nSampleIndex = SFX_EXPLOSION_2; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nFrequency = RandomDisplacement(500) + 4000; + vol = (m_asAudioEntities[id].m_afVolume[0]) + 35; + } + m_sQueueSample.m_nVolume = vol; + if (TheCamera.SoundDistUp < 20.0f) + m_sQueueSample.m_nVolume /= 2; + if (iSound == 4) + iSound = 0; + m_sQueueSample.m_nCounter = iSound++; + m_sQueueSample.m_nReleasingVolumeModificator = 0; + m_sQueueSample.m_nOffset = (m_anRandomTable[2] & 15) + 55; + m_sQueueSample.m_bIs2D = true; + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_nEmittingVolume = m_sQueueSample.m_nVolume; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_bReverbFlag = false; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + if (CWeather::Rain > 0.0f && (!CCullZones::CamNoRain() || !CCullZones::PlayerNoRain())) { + m_sQueueSample.m_nSampleIndex = SFX_RAIN; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RAIN); + m_sQueueSample.m_nVolume = (uint8)(25.0f * CWeather::Rain); + m_sQueueSample.m_nCounter = 4; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nReleasingVolumeModificator = 0; + m_sQueueSample.m_nOffset = 63; + m_sQueueSample.m_bIs2D = true; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 30; + m_sQueueSample.m_bReverbFlag = false; + m_sQueueSample.m_nEmittingVolume = m_sQueueSample.m_nVolume; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + x = 0.0f; + y = 0.0f; + CWindModifiers::FindWindModifier(TheCamera.GetPosition(), &x, &y); + modifier = Max(Abs(x), Abs(y)) * 10.0f; + modifier = Min(1.0f, modifier); + wind = Max(CWeather::Wind, modifier); + if (wind > 0.0f && CObject::fDistToNearestTree < 75.0f) { + m_sQueueSample.m_nSampleIndex = SFX_PALM_TREE_LO; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_PALM_TREE_LO); + m_sQueueSample.m_nVolume = (m_anRandomTable[1] % 10 + 45.0f) * (75.0f - CObject::fDistToNearestTree) * (4.0f / 300.0f) * wind; + m_sQueueSample.m_nCounter = 5; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_nOffset = 63; + m_sQueueSample.m_bIs2D = true; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 7; + m_sQueueSample.m_bReverbFlag = false; + m_sQueueSample.m_nEmittingVolume = m_sQueueSample.m_nVolume; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + CObject::fDistToNearestTree = 999999.9f; + } +} + +void +cAudioManager::ProcessFrontEnd() +{ + bool stereo; + bool processedPickup; + bool processedMission; + bool staticFreq; + bool center; + int16 sample; + + static uint8 iSound = 0; + static uint32 cPickupNextFrame = 0; + static uint32 cPartMisComNextFrame = 0; + static uint32 radioDial = SFX_RADIO_DIAL_1; + + for (uint32 i = 0; i < m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_AudioEvents; i++) { + staticFreq = false; + processedPickup = false; + center = false; + processedMission = false; + stereo = false; + switch (m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i]) { + case SOUND_WEAPON_SNIPER_SHOT_NO_ZOOM: + m_sQueueSample.m_nSampleIndex = SFX_ERROR_FIRE_RIFLE; + break; + case SOUND_WEAPON_ROCKET_SHOT_NO_ZOOM: + m_sQueueSample.m_nSampleIndex = SFX_ERROR_FIRE_ROCKET_LAUNCHER; + break; + case SOUND_GARAGE_NO_MONEY: + case SOUND_GARAGE_BAD_VEHICLE: + case SOUND_GARAGE_BOMB_ALREADY_SET: + m_sQueueSample.m_nSampleIndex = SFX_WEAPON_LEFT; + stereo = true; + staticFreq = true; + center = true; + break; + case SOUND_GARAGE_OPENING: + case SOUND_71: //case SOUND_41: + case SOUND_GARAGE_VEHICLE_DECLINED: + case SOUND_GARAGE_VEHICLE_ACCEPTED: + case SOUND_EVIDENCE_PICKUP: + case SOUND_UNLOAD_GOLD: + stereo = true; + processedPickup = true; + m_sQueueSample.m_nSampleIndex = SFX_MONEY_LEFT; + break; + case SOUND_GARAGE_BOMB1_SET: + case SOUND_GARAGE_BOMB2_SET: + case SOUND_GARAGE_BOMB3_SET: + case SOUND_PICKUP_WEAPON_BOUGHT: + case SOUND_PICKUP_WEAPON: + center = true; + processedPickup = true; + m_sQueueSample.m_nSampleIndex = SFX_WEAPON_LEFT; + stereo = true; + break; + case SOUND_PICKUP_HEALTH: + case SOUND_81: //case SOUND_4B: + case SOUND_PICKUP_ADRENALINE: + case SOUND_PICKUP_ARMOUR: + stereo = true; + processedPickup = true; + m_sQueueSample.m_nSampleIndex = SFX_MONEY_LEFT; + break; + case SOUND_80: + stereo = true; + processedPickup = true; + m_sQueueSample.m_nSampleIndex = SFX_WEAPON_LEFT; + center = true; + staticFreq = true; + break; + case SOUND_PICKUP_BONUS: + case SOUND_FRONTEND_MENU_STARTING: + case SOUND_HUD: + stereo = true; + m_sQueueSample.m_nSampleIndex = SFX_INFO_LEFT; + center = true; + break; + case SOUND_PICKUP_MONEY: + stereo = true; + processedPickup = true; + m_sQueueSample.m_nSampleIndex = SFX_MONEY_LEFT; + break; + case SOUND_PICKUP_HIDDEN_PACKAGE: + case SOUND_PICKUP_PACMAN_PILL: + case SOUND_PICKUP_PACMAN_PACKAGE: + case SOUND_PICKUP_FLOAT_PACKAGE: + center = true; + processedPickup = true; + m_sQueueSample.m_nSampleIndex = SFX_PART_MISSION_COMPLETE_LEFT; + stereo = true; + break; + case SOUND_RACE_START_3: + case SOUND_RACE_START_2: + case SOUND_RACE_START_1: + case SOUND_PART_MISSION_COMPLETE: + stereo = true; + m_sQueueSample.m_nSampleIndex = SFX_PART_MISSION_COMPLETE_LEFT; + processedMission = true; + center = true; + break; + case SOUND_RACE_START_GO: + stereo = true; + m_sQueueSample.m_nSampleIndex = SFX_GO_LEFT; + center = true; + break; + case SOUND_CLOCK_TICK: + m_sQueueSample.m_nSampleIndex = SFX_TIMER; + break; + case SOUND_FRONTEND_RADIO_TURN_OFF: + case SOUND_FRONTEND_RADIO_TURN_ON: + m_sQueueSample.m_nSampleIndex = SFX_RADIO_CLICK; + break; + case SOUND_FRONTEND_HURRICANE: + m_sQueueSample.m_nSampleIndex = SFX_HURRICANE_MA; + break; + case SOUND_BULLETTRACE_1: + case SOUND_BULLETTRACE_2: + m_sQueueSample.m_nSampleIndex = (m_anRandomTable[0] % 2) + SFX_BULLET_PASS_1; + break; + case SOUND_AMMUNATION_IMRAN_ARM_BOMB: + m_sQueueSample.m_nSampleIndex = SFX_ARM_BOMB; + break; + case SOUND_RADIO_CHANGE: + m_sQueueSample.m_nSampleIndex = (m_anRandomTable[1] % 2) ? radioDial + 1 : radioDial + 2; + if (m_sQueueSample.m_nSampleIndex > SFX_RADIO_DIAL_12) + m_sQueueSample.m_nSampleIndex -= 12; + radioDial = m_sQueueSample.m_nSampleIndex; + break; + case SOUND_FRONTEND_HIGHLIGHT_OPTION: + stereo = true; + m_sQueueSample.m_nSampleIndex = SFX_FE_HIGHLIGHT_LEFT; + break; + case SOUND_FRONTEND_ENTER_OR_ADJUST: + stereo = true; + m_sQueueSample.m_nSampleIndex = SFX_FE_SELECT_LEFT; + break; + case SOUND_FRONTEND_BACK: + stereo = true; + m_sQueueSample.m_nSampleIndex = SFX_FE_BACK_LEFT; + break; + case SOUND_FRONTEND_FAIL: + stereo = true; + m_sQueueSample.m_nSampleIndex = SFX_FE_ERROR_LEFT; + break; + case SOUND_FRONTEND_AUDIO_TEST: + m_sQueueSample.m_nSampleIndex = m_anRandomTable[0] % 3 + SFX_FE_NOISE_BURST_1; + break; + default: + continue; + } + + if (processedPickup) { + if (m_FrameCounter <= cPickupNextFrame) + continue; + cPickupNextFrame = m_FrameCounter + 5; + } else if (processedMission) { + if (m_FrameCounter <= cPartMisComNextFrame) + continue; + cPartMisComNextFrame = m_FrameCounter + 5; + } + + sample = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i]; + + if (sample == SOUND_FRONTEND_RADIO_TURN_OFF) + m_sQueueSample.m_nFrequency = 28509; + else if (sample == SOUND_FRONTEND_RADIO_TURN_ON) + m_sQueueSample.m_nFrequency = 32000; + else if (sample == SOUND_BULLETTRACE_1 || sample == SOUND_BULLETTRACE_2) { + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); + } else if (staticFreq) + m_sQueueSample.m_nFrequency = 5382; + else + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + + m_sQueueSample.m_nVolume = 127; + if (m_sQueueSample.m_nSampleIndex == SFX_HURRICANE_MA && CWeather::Wind > 1.0f) + m_sQueueSample.m_nVolume = (CWeather::Wind - 1.0f) * m_sQueueSample.m_nVolume; + m_sQueueSample.m_nCounter = iSound++; + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_nBankIndex = SFX_BANK_FRONT_END_MENU; + m_sQueueSample.m_nReleasingVolumeModificator = 0; + m_sQueueSample.m_bIs2D = true; + m_sQueueSample.m_nEmittingVolume = m_sQueueSample.m_nVolume; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_fDistance = 1.0f; + if (stereo) + m_sQueueSample.m_nOffset = 0; + else { + sample = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i]; + if (sample == SOUND_BULLETTRACE_1) { + m_sQueueSample.m_nOffset = 20; + m_sQueueSample.m_nVolume = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]; + m_sQueueSample.m_nReleasingVolumeModificator = 10; + m_sQueueSample.m_fDistance = 100.0f; + } + if (sample == SOUND_BULLETTRACE_2) { + m_sQueueSample.m_nOffset = 107; + m_sQueueSample.m_nVolume = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]; + m_sQueueSample.m_nReleasingVolumeModificator = 10; + m_sQueueSample.m_fDistance = 100.0f; + } + m_sQueueSample.m_nOffset = 63; + } + m_sQueueSample.m_bReverbFlag = false; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + if (stereo) { + ++m_sQueueSample.m_nSampleIndex; + m_sQueueSample.m_nCounter = iSound++; + m_sQueueSample.m_nOffset = 127 - m_sQueueSample.m_nOffset; + AddSampleToRequestedQueue(); + } + if (center) { + ++m_sQueueSample.m_nSampleIndex; + m_sQueueSample.m_nCounter = iSound++; + m_sQueueSample.m_nOffset = 63; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + AddSampleToRequestedQueue(); + } + } +} + +/*void +cAudioManager::ProcessCrane() +{ + CCrane *crane = (CCrane *)m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_pEntity; + float distSquared; + bool distCalculated = false; + static const int intensity = 80; + + if (crane) { + if (crane->m_nCraneStatus == CCrane::ACTIVATED) { + if (crane->m_nCraneState != CCrane::IDLE) { + m_sQueueSample.m_vecPos = crane->m_pCraneEntity->GetPosition(); + distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); + if (distSquared < SQR(intensity)) { + CalculateDistance(distCalculated, distSquared); + m_sQueueSample.m_nVolume = ComputeVolume(100, 80.f, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 0; + m_sQueueSample.m_nSampleIndex = SFX_CRANE_MAGNET; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 2; + m_sQueueSample.m_nFrequency = 6000; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = 100; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 4.0f; + m_sQueueSample.m_fSoundIntensity = intensity; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + if (m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_AudioEvents) { + m_sQueueSample.m_nCounter = 1; + m_sQueueSample.m_nSampleIndex = SFX_COL_CAR_2; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_COL_CAR_2); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = true; + AddSampleToRequestedQueue(); + } + } + } + } + } +}*/ + +void +cAudioManager::ProcessProjectiles() +{ + uint8 emittingVol; + float distSquared; + + for (int32 i = 0; i < NUM_PROJECTILES; i++) { + if (CProjectileInfo::GetProjectileInfo(i)->m_bInUse) { + switch (CProjectileInfo::GetProjectileInfo(i)->m_eWeaponType) { + case WEAPONTYPE_TEARGAS: + emittingVol = 80; + m_sQueueSample.m_fSoundIntensity = 40.0f; + m_sQueueSample.m_nSampleIndex = SFX_PALM_TREE_LO; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nFrequency = 13879; + m_sQueueSample.m_nReleasingVolumeModificator = 7; + break; + case WEAPONTYPE_MOLOTOV: + emittingVol = 50; + m_sQueueSample.m_fSoundIntensity = 30.0f; + m_sQueueSample.m_nSampleIndex = SFX_PED_ON_FIRE; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nFrequency = 32 * SampleManager.GetSampleBaseFrequency(SFX_PED_ON_FIRE) / 25; + m_sQueueSample.m_nReleasingVolumeModificator = 7; + break; + case WEAPONTYPE_ROCKET: + emittingVol = 127; + m_sQueueSample.m_fSoundIntensity = 90.0f; + m_sQueueSample.m_nSampleIndex = SFX_ROCKET_FLY; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_ROCKET_FLY); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + break; + default: + return; + } + m_sQueueSample.m_fSpeedMultiplier = 4.0f; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_vecPos = CProjectileInfo::ms_apProjectile[i]->GetPosition(); + distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); + if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) { + m_sQueueSample.m_fDistance = Sqrt(distSquared); + m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = i; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } + } + } +} + +void +cAudioManager::ProcessGarages() +{ + const float SOUND_INTENSITY = 80.0f; + + CEntity *entity; + uint8 state; + uint32 sampleIndex; + uint8 j; + float distSquared; + bool distCalculated; + + static uint8 iSound = 32; + + for (uint32 i = 0; i < CGarages::NumGarages; ++i) { + if (CGarages::aGarages[i].m_eGarageType == GARAGE_NONE) + continue; + entity = CGarages::aGarages[i].m_pDoor1; + if (entity == nil) + continue; + m_sQueueSample.m_vecPos = entity->GetPosition(); + distCalculated = false; + distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); + if (distSquared < SQR(SOUND_INTENSITY)) { + state = CGarages::aGarages[i].m_eGarageState; + // while is here just to exit prematurely and avoid goto + while (state == GS_OPENING || state == GS_CLOSING || state == GS_AFTERDROPOFF) { + CalculateDistance(distCalculated, distSquared); + m_sQueueSample.m_nVolume = ComputeVolume(90, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + if (CGarages::aGarages[i].m_eGarageType == GARAGE_CRUSHER) { + if (CGarages::aGarages[i].m_eGarageState == GS_AFTERDROPOFF) { + if (m_FrameCounter & 1) { + if (m_anRandomTable[1] & 1) + sampleIndex = m_anRandomTable[2] % 5 + SFX_COL_CAR_1; + else + sampleIndex = m_anRandomTable[2] % 6 + SFX_COL_CAR_PANEL_1; + m_sQueueSample.m_nSampleIndex = sampleIndex; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex) / 2; + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_nCounter = iSound++; + if (iSound < 32) + iSound = 32; + } else break; // premature exit to go straight to the for loop + } else { + m_sQueueSample.m_nSampleIndex = SFX_FISHING_BOAT_IDLE; + m_sQueueSample.m_nFrequency = 6543; + + m_sQueueSample.m_nCounter = i; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_bReleasingSoundFlag = false; + } + } else { + m_sQueueSample.m_nSampleIndex = SFX_GARAGE_DOOR_LOOP; + m_sQueueSample.m_nFrequency = 13961; + + m_sQueueSample.m_nCounter = i; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_bReleasingSoundFlag = false; + } + + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_nEmittingVolume = 90; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + break; + } + } + for (j = 0; j < m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_AudioEvents; ++j) { + switch (m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[j]) { + case SOUND_GARAGE_DOOR_CLOSED: + case SOUND_GARAGE_DOOR_OPENED: + if (distSquared < SQR(SOUND_INTENSITY)) { + CalculateDistance(distCalculated, distSquared); + m_sQueueSample.m_nVolume = ComputeVolume(60, SOUND_INTENSITY, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + if (CGarages::aGarages[i].m_eGarageType == GARAGE_CRUSHER) { + m_sQueueSample.m_nSampleIndex = SFX_COL_CAR_PANEL_2; + m_sQueueSample.m_nFrequency = 6735; + } else if (m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[j] == SOUND_GARAGE_DOOR_OPENED) { + m_sQueueSample.m_nSampleIndex = SFX_COL_CAR_PANEL_2; + m_sQueueSample.m_nFrequency = 22000; + } else { + m_sQueueSample.m_nSampleIndex = SFX_COL_GARAGE_DOOR_1; + m_sQueueSample.m_nFrequency = 18000; + } + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nReleasingVolumeModificator = 4; + m_sQueueSample.m_nEmittingVolume = 60; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bReverbFlag = true; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_nCounter = iSound++; + if (iSound < 32) + iSound = 32; + m_sQueueSample.m_bRequireReflection = true; + AddSampleToRequestedQueue(); + } + } + break; + default: + break; + } + } + } +} + +void +cAudioManager::ProcessFireHydrant() +{ + const float SOUND_INTENSITY = 35; + + float distSquared; + bool distCalculated = false; + + m_sQueueSample.m_vecPos = ((CEntity *)m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_pEntity)->GetPosition(); + distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); + if (distSquared < SQR(SOUND_INTENSITY)) { + CalculateDistance(distCalculated, distSquared); + m_sQueueSample.m_nVolume = ComputeVolume(40, 35.0f, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nSampleIndex = SFX_JUMBO_TAXI; + m_sQueueSample.m_nReleasingVolumeModificator = 4; + m_sQueueSample.m_nFrequency = 15591; + m_sQueueSample.m_nCounter = 0; + m_sQueueSample.m_nEmittingVolume = 40; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_bRequireReflection = false; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + AddSampleToRequestedQueue(); + } + } +} +#ifdef GTA_BRIDGE +#pragma region BRIDGE +const int bridgeIntensity = 400; + +void +cAudioManager::ProcessBridge() +{ + float dist; + bool distCalculated = false; + + if (CBridge::pLiftRoad) { + m_sQueueSample.m_vecPos = CBridge::pLiftRoad->GetPosition(); + dist = GetDistanceSquared(m_sQueueSample.m_vecPos); + if (dist < SQR(450.0f)) { + CalculateDistance(distCalculated, dist); + switch (CBridge::State) { + case STATE_BRIDGE_LOCKED: + case STATE_LIFT_PART_IS_UP: + case STATE_LIFT_PART_ABOUT_TO_MOVE_UP: + ProcessBridgeWarning(); + break; + case STATE_LIFT_PART_MOVING_DOWN: + case STATE_LIFT_PART_MOVING_UP: + ProcessBridgeWarning(); + ProcessBridgeMotor(); + break; + default: + break; + } + ProcessBridgeOneShots(); + } + } +} + +void +cAudioManager::ProcessBridgeWarning() +{ + if (CStats::CommercialPassed && m_sQueueSample.m_fDistance < 450.f) { + m_sQueueSample.m_nVolume = ComputeVolume(100, 450.f, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 0; + m_sQueueSample.m_nSampleIndex = SFX_BRIDGE_OPEN_WARNING; + m_sQueueSample.m_nBankIndex = SAMPLEBANK_EXTRAS; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_BRIDGE_OPEN_WARNING); + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = 100; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_fSoundIntensity = 450.0f; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 8; + m_sQueueSample.m_bReverbFlag = false; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } +} + +void +cAudioManager::ProcessBridgeMotor() +{ + if (m_sQueueSample.m_fDistance < bridgeIntensity) { + m_sQueueSample.m_nVolume = ComputeVolume(MAX_VOLUME, bridgeIntensity, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 1; + m_sQueueSample.m_nSampleIndex = SFX_FISHING_BOAT_IDLE; // todo check sfx name + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_nFrequency = 5500; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = MAX_VOLUME; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_fSoundIntensity = bridgeIntensity; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_bReverbFlag = false; + AddSampleToRequestedQueue(); + } + } +} + +void +cAudioManager::ProcessBridgeOneShots() +{ + if (CBridge::State == STATE_LIFT_PART_IS_UP && CBridge::OldState == STATE_LIFT_PART_MOVING_UP) + m_sQueueSample.m_nSampleIndex = SFX_COL_CONTAINER_1; + else if (CBridge::State == STATE_LIFT_PART_IS_DOWN && CBridge::OldState == STATE_LIFT_PART_MOVING_DOWN) + m_sQueueSample.m_nSampleIndex = SFX_COL_CONTAINER_1; + else if (CBridge::State == STATE_LIFT_PART_MOVING_UP && CBridge::OldState == STATE_LIFT_PART_ABOUT_TO_MOVE_UP) + m_sQueueSample.m_nSampleIndex = SFX_COL_CONTAINER_1; + else if (CBridge::State == STATE_LIFT_PART_MOVING_DOWN && CBridge::OldState == STATE_LIFT_PART_IS_UP) + m_sQueueSample.m_nSampleIndex = SFX_COL_CONTAINER_1; + else return; + + if (m_sQueueSample.m_fDistance < bridgeIntensity) { + m_sQueueSample.m_nVolume = ComputeVolume(MAX_VOLUME, bridgeIntensity, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume != 0) { + m_sQueueSample.m_nCounter = 2; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nEmittingVolume = MAX_VOLUME; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_fSpeedMultiplier = 2.0f; + m_sQueueSample.m_fSoundIntensity = bridgeIntensity; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bReverbFlag = false; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); + } + } +} +#pragma endregion +#endif + +#pragma region MISSION_AUDIO +bool g_bMissionAudioLoadFailed[MISSION_AUDIO_SLOTS]; + +struct MissionAudioData { + const char *m_pName; + int32 m_nId; +}; + + +const MissionAudioData MissionAudioNameSfxAssoc[] = { + {"mobring", STREAMED_SOUND_MISSION_MOBR1}, {"pagring", STREAMED_SOUND_MISSION_PAGER}, {"carrev", STREAMED_SOUND_MISSION_CARREV}, + {"bikerev", STREAMED_SOUND_MISSION_BIKEREV}, {"liftop", STREAMED_SOUND_MISSION_LIFTOP}, {"liftcl", STREAMED_SOUND_MISSION_LIFTCL}, + {"liftrun", STREAMED_SOUND_MISSION_LIFTRUN}, {"liftbel", STREAMED_SOUND_MISSION_LIFTBEL}, {"inlift", STREAMED_SOUND_MISSION_INLIFT}, + {"caml", STREAMED_SOUND_MISSION_CAMERAL}, {"camr", STREAMED_SOUND_MISSION_CAMERAR}, {"cheer1", STREAMED_SOUND_MISSION_CHEER1}, + {"cheer2", STREAMED_SOUND_MISSION_CHEER2}, {"cheer3", STREAMED_SOUND_MISSION_CHEER3}, {"cheer4", STREAMED_SOUND_MISSION_CHEER4}, + {"ooh1", STREAMED_SOUND_MISSION_OOH1}, {"ooh2", STREAMED_SOUND_MISSION_OOH2}, {"race1", STREAMED_SOUND_MISSION_RACE1}, + {"race2", STREAMED_SOUND_MISSION_RACE2}, {"race3", STREAMED_SOUND_MISSION_RACE3}, {"race4", STREAMED_SOUND_MISSION_RACE4}, + {"race5", STREAMED_SOUND_MISSION_RACE5}, {"race6", STREAMED_SOUND_MISSION_RACE6}, {"race7", STREAMED_SOUND_MISSION_RACE7}, + {"race8", STREAMED_SOUND_MISSION_RACE8}, {"race9", STREAMED_SOUND_MISSION_RACE9}, {"race10", STREAMED_SOUND_MISSION_RACE10}, + {"race11", STREAMED_SOUND_MISSION_RACE11}, {"race12", STREAMED_SOUND_MISSION_RACE12}, {"race13", STREAMED_SOUND_MISSION_RACE13}, + {"race14", STREAMED_SOUND_MISSION_RACE14}, {"race15", STREAMED_SOUND_MISSION_RACE15}, {"hot1", STREAMED_SOUND_MISSION_HOT1}, + {"hot2", STREAMED_SOUND_MISSION_HOT2}, {"hot3", STREAMED_SOUND_MISSION_HOT3}, {"hot4", STREAMED_SOUND_MISSION_HOT4}, + {"hot5", STREAMED_SOUND_MISSION_HOT5}, {"hot6", STREAMED_SOUND_MISSION_HOT6}, {"hot7", STREAMED_SOUND_MISSION_HOT7}, + {"hot8", STREAMED_SOUND_MISSION_HOT8}, {"hot9", STREAMED_SOUND_MISSION_HOT9}, {"hot10", STREAMED_SOUND_MISSION_HOT10}, + {"hot11", STREAMED_SOUND_MISSION_HOT11}, {"hot12", STREAMED_SOUND_MISSION_HOT12}, {"hot13", STREAMED_SOUND_MISSION_HOT13}, + {"hot14", STREAMED_SOUND_MISSION_HOT14}, {"hot15", STREAMED_SOUND_MISSION_HOT15}, {"lanstp1", STREAMED_SOUND_MISSION_LANSTP1}, + {"lanstp2", STREAMED_SOUND_MISSION_LANSTP2}, {"lanamu1", STREAMED_SOUND_MISSION_LANAMU1}, {"lanamu2", STREAMED_SOUND_MISSION_LANAMU2}, + {"airhrnl", STREAMED_SOUND_MISSION_AIRHORNL}, {"airhrnr", STREAMED_SOUND_MISSION_AIRHORNR}, {"sniper", STREAMED_SOUND_MISSION_SNIPSCRL}, + {"snipsh", STREAMED_SOUND_MISSION_SNIPSHORT}, {"bloroof", STREAMED_SOUND_MISSION_BLOWROOF}, {"sfx_01", STREAMED_SOUND_MISSION_SFX_01}, + {"sfx_02", STREAMED_SOUND_MISSION_SFX_02}, {"LAW1_1", STREAMED_SOUND_MISSION_LAW1_1}, {"LAW1_2", STREAMED_SOUND_MISSION_LAW1_2}, + {"LAW1_3", STREAMED_SOUND_MISSION_LAW1_3}, {"LAW1_4", STREAMED_SOUND_MISSION_LAW1_4}, {"LAW1_5", STREAMED_SOUND_MISSION_LAW1_5}, + {"LAW1_6", STREAMED_SOUND_MISSION_LAW1_6}, {"LAW1_7", STREAMED_SOUND_MISSION_LAW1_7}, {"LAW1_8", STREAMED_SOUND_MISSION_LAW1_8}, + {"LAW1_9", STREAMED_SOUND_MISSION_LAW1_9}, {"LAW1_10", STREAMED_SOUND_MISSION_LAW1_10}, {"LAW2_1", STREAMED_SOUND_MISSION_LAW2_1}, + {"LAW2_2", STREAMED_SOUND_MISSION_LAW2_2}, {"LAW2_3", STREAMED_SOUND_MISSION_LAW2_3}, {"LAW2_4", STREAMED_SOUND_MISSION_LAW2_4}, + {"LAW2_5", STREAMED_SOUND_MISSION_LAW2_5}, {"LAW2_6", STREAMED_SOUND_MISSION_LAW2_6}, {"LAW2_7", STREAMED_SOUND_MISSION_LAW2_7}, + {"LAW2_8", STREAMED_SOUND_MISSION_LAW2_8}, {"LAW2_9", STREAMED_SOUND_MISSION_LAW2_9}, {"LAW2_10", STREAMED_SOUND_MISSION_LAW2_10}, + {"LAW3_1", STREAMED_SOUND_MISSION_LAW3_1}, {"LAW3_2", STREAMED_SOUND_MISSION_LAW3_2}, {"LAW3_3", STREAMED_SOUND_MISSION_LAW3_3}, + {"LAW3_4", STREAMED_SOUND_MISSION_LAW3_4}, {"LAW3_5", STREAMED_SOUND_MISSION_LAW3_5}, {"LAW3_6", STREAMED_SOUND_MISSION_LAW3_6}, + {"LAW3_10", STREAMED_SOUND_MISSION_LAW3_10}, {"LAW3_11", STREAMED_SOUND_MISSION_LAW3_11}, {"LAW3_12", STREAMED_SOUND_MISSION_LAW3_12}, + {"LAW3_13", STREAMED_SOUND_MISSION_LAW3_13}, {"LAW3_14", STREAMED_SOUND_MISSION_LAW3_14}, {"LAW3_16", STREAMED_SOUND_MISSION_LAW3_16}, + {"LAW3_17", STREAMED_SOUND_MISSION_LAW3_17}, {"LAW3_18", STREAMED_SOUND_MISSION_LAW3_18}, {"LAW3_19", STREAMED_SOUND_MISSION_LAW3_19}, + {"LAW3_20", STREAMED_SOUND_MISSION_LAW3_20}, {"LAW3_21", STREAMED_SOUND_MISSION_LAW3_21}, {"LAW3_22", STREAMED_SOUND_MISSION_LAW3_22}, + {"LAW3_23", STREAMED_SOUND_MISSION_LAW3_23}, {"LAW3_24", STREAMED_SOUND_MISSION_LAW3_24}, {"LAW3_25", STREAMED_SOUND_MISSION_LAW3_25}, + {"LAW4_1a", STREAMED_SOUND_MISSION_LAW4_1A}, {"LAW4_1b", STREAMED_SOUND_MISSION_LAW4_1B}, {"LAW4_1c", STREAMED_SOUND_MISSION_LAW4_1C}, + {"LAW4_1d", STREAMED_SOUND_MISSION_LAW4_1D}, {"LAW4_10", STREAMED_SOUND_MISSION_LAW4_10}, {"LAW4_3", STREAMED_SOUND_MISSION_LAW4_3}, + {"LAW4_4", STREAMED_SOUND_MISSION_LAW4_4}, {"LAW4_5", STREAMED_SOUND_MISSION_LAW4_5}, {"LAW4_6", STREAMED_SOUND_MISSION_LAW4_6}, + {"LAW4_7", STREAMED_SOUND_MISSION_LAW4_7}, {"LAW4_8", STREAMED_SOUND_MISSION_LAW4_8}, {"LAW4_9", STREAMED_SOUND_MISSION_LAW4_9}, + {"COL1_1", STREAMED_SOUND_MISSION_COL1_1}, {"COL1_2", STREAMED_SOUND_MISSION_COL1_2}, {"COL1_3", STREAMED_SOUND_MISSION_COL1_3}, + {"COL1_4", STREAMED_SOUND_MISSION_COL1_4}, {"COL1_5", STREAMED_SOUND_MISSION_COL1_5}, {"COL1_6", STREAMED_SOUND_MISSION_COL1_6}, + {"COL1_7", STREAMED_SOUND_MISSION_COL1_7}, {"COL1_8", STREAMED_SOUND_MISSION_COL1_8}, {"COL2_1", STREAMED_SOUND_MISSION_COL2_1}, + {"COL2_2", STREAMED_SOUND_MISSION_COL2_2}, {"COL2_3", STREAMED_SOUND_MISSION_COL2_3}, {"COL2_4", STREAMED_SOUND_MISSION_COL2_4}, + {"COL2_5", STREAMED_SOUND_MISSION_COL2_5}, {"COL2_6a", STREAMED_SOUND_MISSION_COL2_6A}, {"COL2_7", STREAMED_SOUND_MISSION_COL2_7}, + {"COL2_8", STREAMED_SOUND_MISSION_COL2_8}, {"COL2_9", STREAMED_SOUND_MISSION_COL2_9}, {"COL2_10", STREAMED_SOUND_MISSION_COL2_10}, + {"COL2_11", STREAMED_SOUND_MISSION_COL2_11}, {"COL2_12", STREAMED_SOUND_MISSION_COL2_12}, {"COL2_13", STREAMED_SOUND_MISSION_COL2_13}, + {"COL2_14", STREAMED_SOUND_MISSION_COL2_14}, {"COL2_15", STREAMED_SOUND_MISSION_COL2_15}, {"COL2_16", STREAMED_SOUND_MISSION_COL2_16}, + {"COL3_1", STREAMED_SOUND_MISSION_COL3_1}, {"COL3_2", STREAMED_SOUND_MISSION_COL3_2}, {"COL3_2a", STREAMED_SOUND_MISSION_COL3_2A}, + {"COL3_2b", STREAMED_SOUND_MISSION_COL3_2B}, {"COL3_3", STREAMED_SOUND_MISSION_COL3_3}, {"COL3_4", STREAMED_SOUND_MISSION_COL3_4}, + {"COL3_5", STREAMED_SOUND_MISSION_COL3_5}, {"COL3_6", STREAMED_SOUND_MISSION_COL3_6}, {"COL3_7", STREAMED_SOUND_MISSION_COL3_7}, + {"COL3_8", STREAMED_SOUND_MISSION_COL3_8}, {"COL3_9", STREAMED_SOUND_MISSION_COL3_9}, {"COL3_10", STREAMED_SOUND_MISSION_COL3_10}, + {"COL3_11", STREAMED_SOUND_MISSION_COL3_11}, {"COL3_12", STREAMED_SOUND_MISSION_COL3_12}, {"COL3_13", STREAMED_SOUND_MISSION_COL3_13}, + {"COL3_14", STREAMED_SOUND_MISSION_COL3_14}, {"COL3_15", STREAMED_SOUND_MISSION_COL3_15}, {"COL3_16", STREAMED_SOUND_MISSION_COL3_16}, + {"COL3_17", STREAMED_SOUND_MISSION_COL3_17}, {"COL3_18", STREAMED_SOUND_MISSION_COL3_18}, {"COL3_19", STREAMED_SOUND_MISSION_COL3_19}, + {"COL3_20", STREAMED_SOUND_MISSION_COL3_20}, {"COL3_21", STREAMED_SOUND_MISSION_COL3_21}, {"COL3_23", STREAMED_SOUND_MISSION_COL3_23}, + {"COL3_24", STREAMED_SOUND_MISSION_COL3_24}, {"COL3_25", STREAMED_SOUND_MISSION_COL3_25}, {"COL4_1", STREAMED_SOUND_MISSION_COL4_1}, + {"COL4_2", STREAMED_SOUND_MISSION_COL4_2}, {"COL4_3", STREAMED_SOUND_MISSION_COL4_3}, {"COL4_4", STREAMED_SOUND_MISSION_COL4_4}, + {"COL4_5", STREAMED_SOUND_MISSION_COL4_5}, {"COL4_6", STREAMED_SOUND_MISSION_COL4_6}, {"COL4_7", STREAMED_SOUND_MISSION_COL4_7}, + {"COL4_8", STREAMED_SOUND_MISSION_COL4_8}, {"COL4_9", STREAMED_SOUND_MISSION_COL4_9}, {"COL4_10", STREAMED_SOUND_MISSION_COL4_10}, + {"COL4_11", STREAMED_SOUND_MISSION_COL4_11}, {"COL4_12", STREAMED_SOUND_MISSION_COL4_12}, {"COL4_13", STREAMED_SOUND_MISSION_COL4_13}, + {"COL4_14", STREAMED_SOUND_MISSION_COL4_14}, {"COL4_15", STREAMED_SOUND_MISSION_COL4_15}, {"COL4_16", STREAMED_SOUND_MISSION_COL4_16}, + {"COL4_17", STREAMED_SOUND_MISSION_COL4_17}, {"COL4_18", STREAMED_SOUND_MISSION_COL4_18}, {"COL4_19", STREAMED_SOUND_MISSION_COL4_19}, + {"COL4_20", STREAMED_SOUND_MISSION_COL4_20}, {"COL4_21", STREAMED_SOUND_MISSION_COL4_21}, {"COL4_22", STREAMED_SOUND_MISSION_COL4_22}, + {"COL4_23", STREAMED_SOUND_MISSION_COL4_23}, {"COL4_24", STREAMED_SOUND_MISSION_COL4_24}, {"COL4_25", STREAMED_SOUND_MISSION_COL4_25}, + {"COL4_26", STREAMED_SOUND_MISSION_COL4_26}, {"COL5_1", STREAMED_SOUND_MISSION_COL5_1}, {"COL5_2", STREAMED_SOUND_MISSION_COL5_2}, + {"COL5_3", STREAMED_SOUND_MISSION_COL5_3}, {"COL5_4", STREAMED_SOUND_MISSION_COL5_4}, {"COL5_5", STREAMED_SOUND_MISSION_COL5_5}, + {"COL5_6", STREAMED_SOUND_MISSION_COL5_6}, {"COL5_7", STREAMED_SOUND_MISSION_COL5_7}, {"COL5_8", STREAMED_SOUND_MISSION_COL5_8}, + {"COL5_9", STREAMED_SOUND_MISSION_COL5_9}, {"COL5_10", STREAMED_SOUND_MISSION_COL5_10}, {"COL5_11", STREAMED_SOUND_MISSION_COL5_11}, + {"COL5_12", STREAMED_SOUND_MISSION_COL5_12}, {"COL5_13", STREAMED_SOUND_MISSION_COL5_13}, {"COL5_14", STREAMED_SOUND_MISSION_COL5_14}, + {"COL5_15", STREAMED_SOUND_MISSION_COL5_15}, {"COL5_16", STREAMED_SOUND_MISSION_COL5_16}, {"COL5_17", STREAMED_SOUND_MISSION_COL5_17}, + {"COL5_18", STREAMED_SOUND_MISSION_COL5_18}, {"COL5_19", STREAMED_SOUND_MISSION_COL5_19}, {"COL5_20", STREAMED_SOUND_MISSION_COL5_20}, + {"COL5_21", STREAMED_SOUND_MISSION_COL5_21}, {"COL5_22", STREAMED_SOUND_MISSION_COL5_22}, {"COK1_1", STREAMED_SOUND_MISSION_COK1_1}, + {"COK1_2", STREAMED_SOUND_MISSION_COK1_2}, {"COK1_3", STREAMED_SOUND_MISSION_COK1_3}, {"COK1_4", STREAMED_SOUND_MISSION_COK1_4}, + {"COK1_5", STREAMED_SOUND_MISSION_COK1_5}, {"COK1_6", STREAMED_SOUND_MISSION_COK1_6}, {"COK2_1", STREAMED_SOUND_MISSION_COK2_1}, + {"COK2_2", STREAMED_SOUND_MISSION_COK2_2}, {"COK2_3", STREAMED_SOUND_MISSION_COK2_3}, {"COK2_4", STREAMED_SOUND_MISSION_COK2_4}, + {"COK2_5", STREAMED_SOUND_MISSION_COK2_5}, {"COK2_6", STREAMED_SOUND_MISSION_COK2_6}, {"COK2_7a", STREAMED_SOUND_MISSION_COK2_7A}, + {"COK2_7b", STREAMED_SOUND_MISSION_COK2_7B}, {"COK2_7c", STREAMED_SOUND_MISSION_COK2_7C}, {"COK2_8a", STREAMED_SOUND_MISSION_COK2_8A}, + {"COK2_8b", STREAMED_SOUND_MISSION_COK2_8B}, {"COK2_8c", STREAMED_SOUND_MISSION_COK2_8C}, {"COK2_8d", STREAMED_SOUND_MISSION_COK2_8D}, + {"COK2_9", STREAMED_SOUND_MISSION_COK2_9}, {"COK210a", STREAMED_SOUND_MISSION_COK210A}, {"COK210b", STREAMED_SOUND_MISSION_COK210B}, + {"COK210c", STREAMED_SOUND_MISSION_COK210C}, {"COK212a", STREAMED_SOUND_MISSION_COK212A}, {"COK212b", STREAMED_SOUND_MISSION_COK212B}, + {"COK2_13", STREAMED_SOUND_MISSION_COK2_13}, {"COK2_14", STREAMED_SOUND_MISSION_COK2_14}, {"COK2_15", STREAMED_SOUND_MISSION_COK2_15}, + {"COK2_16", STREAMED_SOUND_MISSION_COK2_16}, {"COK2_20", STREAMED_SOUND_MISSION_COK2_20}, {"COK2_21", STREAMED_SOUND_MISSION_COK2_21}, + {"COK2_22", STREAMED_SOUND_MISSION_COK2_22}, {"COK3_1", STREAMED_SOUND_MISSION_COK3_1}, {"COK3_2", STREAMED_SOUND_MISSION_COK3_2}, + {"COK3_3", STREAMED_SOUND_MISSION_COK3_3}, {"COK3_4", STREAMED_SOUND_MISSION_COK3_4}, {"COK4_1", STREAMED_SOUND_MISSION_COK4_1}, + {"COK4_2", STREAMED_SOUND_MISSION_COK4_2}, {"COK4_3", STREAMED_SOUND_MISSION_COK4_3}, {"COK4_4", STREAMED_SOUND_MISSION_COK4_4}, + {"COK4_5", STREAMED_SOUND_MISSION_COK4_5}, {"COK4_6", STREAMED_SOUND_MISSION_COK4_6}, {"COK4_7", STREAMED_SOUND_MISSION_COK4_7}, + {"COK4_8", STREAMED_SOUND_MISSION_COK4_8}, {"COK4_9", STREAMED_SOUND_MISSION_COK4_9}, {"COK4_9A", STREAMED_SOUND_MISSION_COK4_9A}, + {"COK4_10", STREAMED_SOUND_MISSION_COK4_10}, {"COK4_11", STREAMED_SOUND_MISSION_COK4_11}, {"COK4_12", STREAMED_SOUND_MISSION_COK4_12}, + {"COK4_13", STREAMED_SOUND_MISSION_COK4_13}, {"COK4_14", STREAMED_SOUND_MISSION_COK4_14}, {"COK4_15", STREAMED_SOUND_MISSION_COK4_15}, + {"COK4_16", STREAMED_SOUND_MISSION_COK4_16}, {"COK4_17", STREAMED_SOUND_MISSION_COK4_17}, {"COK4_18", STREAMED_SOUND_MISSION_COK4_18}, + {"COK4_19", STREAMED_SOUND_MISSION_COK4_19}, {"COK4_20", STREAMED_SOUND_MISSION_COK4_20}, {"COK4_21", STREAMED_SOUND_MISSION_COK4_21}, + {"COK4_22", STREAMED_SOUND_MISSION_COK4_22}, {"COK4_23", STREAMED_SOUND_MISSION_COK4_23}, {"COK4_24", STREAMED_SOUND_MISSION_COK4_24}, + {"COK4_25", STREAMED_SOUND_MISSION_COK4_25}, {"COK4_26", STREAMED_SOUND_MISSION_COK4_26}, {"COK4_27", STREAMED_SOUND_MISSION_COK4_27}, + {"RESC_1", STREAMED_SOUND_MISSION_RESC_1}, {"RESC_2", STREAMED_SOUND_MISSION_RESC_2}, {"RESC_3", STREAMED_SOUND_MISSION_RESC_3}, + {"RESC_4", STREAMED_SOUND_MISSION_RESC_4}, {"RESC_5", STREAMED_SOUND_MISSION_RESC_5}, {"RESC_6", STREAMED_SOUND_MISSION_RESC_6}, + {"RESC_7", STREAMED_SOUND_MISSION_RESC_7}, {"RESC_8", STREAMED_SOUND_MISSION_RESC_8}, {"RESC_9", STREAMED_SOUND_MISSION_RESC_9}, + {"RESC_10", STREAMED_SOUND_MISSION_RESC_10}, {"ASS_1", STREAMED_SOUND_MISSION_ASS_1}, {"ASS_2", STREAMED_SOUND_MISSION_ASS_2}, + {"ASS_3", STREAMED_SOUND_MISSION_ASS_3}, {"ASS_4", STREAMED_SOUND_MISSION_ASS_4}, {"ASS_5", STREAMED_SOUND_MISSION_ASS_5}, + {"ASS_6", STREAMED_SOUND_MISSION_ASS_6}, {"ASS_7", STREAMED_SOUND_MISSION_ASS_7}, {"ASS_8", STREAMED_SOUND_MISSION_ASS_8}, + {"ASS_9", STREAMED_SOUND_MISSION_ASS_9}, {"ASS_10", STREAMED_SOUND_MISSION_ASS_10}, {"ASS_11", STREAMED_SOUND_MISSION_ASS_11}, + {"ASS_12", STREAMED_SOUND_MISSION_ASS_12}, {"ASS_13", STREAMED_SOUND_MISSION_ASS_13}, {"ASS_14", STREAMED_SOUND_MISSION_ASS_14}, + {"BUD1_1", STREAMED_SOUND_MISSION_BUD1_1}, {"BUD1_2", STREAMED_SOUND_MISSION_BUD1_2}, {"BUD1_3", STREAMED_SOUND_MISSION_BUD1_3}, + {"BUD1_4", STREAMED_SOUND_MISSION_BUD1_4}, {"BUD1_5", STREAMED_SOUND_MISSION_BUD1_5}, {"BUD1_9", STREAMED_SOUND_MISSION_BUD1_9}, + {"BUD1_10", STREAMED_SOUND_MISSION_BUD1_10}, {"BUD2_1", STREAMED_SOUND_MISSION_BUD2_1}, {"BUD2_2", STREAMED_SOUND_MISSION_BUD2_2}, + {"BUD2_3", STREAMED_SOUND_MISSION_BUD2_3}, {"BUD2_4", STREAMED_SOUND_MISSION_BUD2_4}, {"BUD2_5", STREAMED_SOUND_MISSION_BUD2_5}, + {"BUD2_6", STREAMED_SOUND_MISSION_BUD2_6}, {"BUD2_7", STREAMED_SOUND_MISSION_BUD2_7}, {"BUD3_1a", STREAMED_SOUND_MISSION_BUD3_1A}, + {"BUD3_1b", STREAMED_SOUND_MISSION_BUD3_1B}, {"BUD3_1", STREAMED_SOUND_MISSION_BUD3_1}, {"BUD3_2", STREAMED_SOUND_MISSION_BUD3_2}, + {"BUD3_3", STREAMED_SOUND_MISSION_BUD3_3}, {"BUD3_4", STREAMED_SOUND_MISSION_BUD3_4}, {"BUD3_1c", STREAMED_SOUND_MISSION_BUD3_1C}, + {"BUD3_5", STREAMED_SOUND_MISSION_BUD3_5}, {"BUD3_6", STREAMED_SOUND_MISSION_BUD3_6}, {"BUD3_7", STREAMED_SOUND_MISSION_BUD3_7}, + {"BUD3_8a", STREAMED_SOUND_MISSION_BUD3_8A}, {"BUD3_8b", STREAMED_SOUND_MISSION_BUD3_8B}, {"BUD3_8c", STREAMED_SOUND_MISSION_BUD3_8C}, + {"BUD3_9a", STREAMED_SOUND_MISSION_BUD3_9A}, {"BUD3_9b", STREAMED_SOUND_MISSION_BUD3_9B}, {"BUD3_9c", STREAMED_SOUND_MISSION_BUD3_9C}, + {"CAP1_2", STREAMED_SOUND_MISSION_CAP1_2}, {"CAP1_3", STREAMED_SOUND_MISSION_CAP1_3}, {"CAP1_4", STREAMED_SOUND_MISSION_CAP1_4}, + {"CAP1_5", STREAMED_SOUND_MISSION_CAP1_5}, {"CAP1_6", STREAMED_SOUND_MISSION_CAP1_6}, {"CAP1_7", STREAMED_SOUND_MISSION_CAP1_7}, + {"CAP1_8", STREAMED_SOUND_MISSION_CAP1_8}, {"CAP1_9", STREAMED_SOUND_MISSION_CAP1_9}, {"CAP1_10", STREAMED_SOUND_MISSION_CAP1_10}, + {"CAP1_11", STREAMED_SOUND_MISSION_CAP1_11}, {"CAP1_12", STREAMED_SOUND_MISSION_CAP1_12}, {"FINKILL", STREAMED_SOUND_MISSION_FINKILL}, + {"FIN_1a", STREAMED_SOUND_MISSION_FIN_1A}, {"FIN_1b", STREAMED_SOUND_MISSION_FIN_1B}, {"FIN_1c", STREAMED_SOUND_MISSION_FIN_1C}, + {"FIN_2b", STREAMED_SOUND_MISSION_FIN_2B}, {"FIN_2c", STREAMED_SOUND_MISSION_FIN_2C}, {"FIN_3", STREAMED_SOUND_MISSION_FIN_3}, + {"FIN_4", STREAMED_SOUND_MISSION_FIN_4}, {"FIN_5", STREAMED_SOUND_MISSION_FIN_5}, {"FIN_6", STREAMED_SOUND_MISSION_FIN_6}, + {"FIN_10", STREAMED_SOUND_MISSION_FIN_10}, {"FIN_11a", STREAMED_SOUND_MISSION_FIN_11A}, {"FIN_11b", STREAMED_SOUND_MISSION_FIN_11B}, + {"FIN_12a", STREAMED_SOUND_MISSION_FIN_12A}, {"FIN_12b", STREAMED_SOUND_MISSION_FIN_12B}, {"FIN_12c", STREAMED_SOUND_MISSION_FIN_12C}, + {"FIN_13", STREAMED_SOUND_MISSION_FIN_13}, {"BNK1_1", STREAMED_SOUND_MISSION_BNK1_1}, {"BNK1_2", STREAMED_SOUND_MISSION_BNK1_2}, + {"BNK1_3", STREAMED_SOUND_MISSION_BNK1_3}, {"BNK1_4", STREAMED_SOUND_MISSION_BNK1_4}, {"BNK1_5", STREAMED_SOUND_MISSION_BNK1_5}, + {"BNK1_6", STREAMED_SOUND_MISSION_BNK1_6}, {"BNK1_7", STREAMED_SOUND_MISSION_BNK1_7}, {"BNK1_8", STREAMED_SOUND_MISSION_BNK1_8}, + {"BNK1_10", STREAMED_SOUND_MISSION_BNK1_10}, {"BNK1_11", STREAMED_SOUND_MISSION_BNK1_11}, {"BNK1_12", STREAMED_SOUND_MISSION_BNK1_12}, + {"BNK1_13", STREAMED_SOUND_MISSION_BNK1_13}, {"BNK1_14", STREAMED_SOUND_MISSION_BNK1_14}, {"BNK2_1", STREAMED_SOUND_MISSION_BNK2_1}, + {"BNK2_2", STREAMED_SOUND_MISSION_BNK2_2}, {"BNK2_3", STREAMED_SOUND_MISSION_BNK2_3}, {"BNK2_4", STREAMED_SOUND_MISSION_BNK2_4}, + {"BNK2_5", STREAMED_SOUND_MISSION_BNK2_5}, {"BNK2_6", STREAMED_SOUND_MISSION_BNK2_6}, {"BNK2_7", STREAMED_SOUND_MISSION_BNK2_7}, + {"BNK2_8", STREAMED_SOUND_MISSION_BNK2_8}, {"BNK2_9", STREAMED_SOUND_MISSION_BNK2_9}, {"BNK3_1", STREAMED_SOUND_MISSION_BNK3_1}, + {"BNK3_2", STREAMED_SOUND_MISSION_BNK3_2}, {"BNK3_3a", STREAMED_SOUND_MISSION_BNK3_3A}, {"BNK3_3b", STREAMED_SOUND_MISSION_BNK3_3B}, + {"BNK3_3c", STREAMED_SOUND_MISSION_BNK3_3C}, {"BNK3_4a", STREAMED_SOUND_MISSION_BNK3_4A}, {"BNK3_4b", STREAMED_SOUND_MISSION_BNK3_4B}, + {"BNK3_4c", STREAMED_SOUND_MISSION_BNK3_4C}, {"BNK4_1", STREAMED_SOUND_MISSION_BNK4_1}, {"BNK4_2", STREAMED_SOUND_MISSION_BNK4_2}, + {"BNK4_3A", STREAMED_SOUND_MISSION_BNK4_3A}, {"BNK4_3B", STREAMED_SOUND_MISSION_BNK4_3B}, {"BNK4_3C", STREAMED_SOUND_MISSION_BNK4_3C}, + {"BNK4_3D", STREAMED_SOUND_MISSION_BNK4_3D}, {"BNK4_3E", STREAMED_SOUND_MISSION_BNK4_3E}, {"BNK4_3F", STREAMED_SOUND_MISSION_BNK4_3F}, + {"BNK4_3G", STREAMED_SOUND_MISSION_BNK4_3G}, {"BNK4_3H", STREAMED_SOUND_MISSION_BNK4_3H}, {"BNK4_3I", STREAMED_SOUND_MISSION_BNK4_3I}, + {"BNK4_3J", STREAMED_SOUND_MISSION_BNK4_3J}, {"BNK4_3K", STREAMED_SOUND_MISSION_BNK4_3K}, {"BNK4_3M", STREAMED_SOUND_MISSION_BNK4_3M}, + {"BNK4_3O", STREAMED_SOUND_MISSION_BNK4_3O}, {"BNK4_3P", STREAMED_SOUND_MISSION_BNK4_3P}, {"BNK4_3Q", STREAMED_SOUND_MISSION_BNK4_3Q}, + {"BNK4_3R", STREAMED_SOUND_MISSION_BNK4_3R}, {"BNK4_3S", STREAMED_SOUND_MISSION_BNK4_3S}, {"BNK4_3T", STREAMED_SOUND_MISSION_BNK4_3T}, + {"BNK4_3U", STREAMED_SOUND_MISSION_BNK4_3U}, {"BNK4_3V", STREAMED_SOUND_MISSION_BNK4_3V}, {"BNK4_4a", STREAMED_SOUND_MISSION_BNK4_4A}, + {"BNK4_4b", STREAMED_SOUND_MISSION_BNK4_4B}, {"BNK4_5", STREAMED_SOUND_MISSION_BNK4_5}, {"BNK4_6", STREAMED_SOUND_MISSION_BNK4_6}, + {"BNK4_7", STREAMED_SOUND_MISSION_BNK4_7}, {"BNK4_8", STREAMED_SOUND_MISSION_BNK4_8}, {"BNK4_9", STREAMED_SOUND_MISSION_BNK4_9}, + {"BNK4_10", STREAMED_SOUND_MISSION_BNK4_10}, {"BNK4_11", STREAMED_SOUND_MISSION_BNK4_11}, {"BK4_12a", STREAMED_SOUND_MISSION_BK4_12A}, + {"BK4_12b", STREAMED_SOUND_MISSION_BK4_12B}, {"BK4_12c", STREAMED_SOUND_MISSION_BK4_12C}, {"BNK4_13", STREAMED_SOUND_MISSION_BNK4_13}, + {"BK4_14a", STREAMED_SOUND_MISSION_BK4_14A}, {"BK4_14b", STREAMED_SOUND_MISSION_BK4_14B}, {"BNK4_15", STREAMED_SOUND_MISSION_BNK4_15}, + {"BNK4_16", STREAMED_SOUND_MISSION_BNK4_16}, {"BNK4_17", STREAMED_SOUND_MISSION_BNK4_17}, {"BNK4_18", STREAMED_SOUND_MISSION_BNK4_18}, + {"BK4_19a", STREAMED_SOUND_MISSION_BK4_19A}, {"BK4_19b", STREAMED_SOUND_MISSION_BK4_19B}, {"BK4_20a", STREAMED_SOUND_MISSION_BK4_20A}, + {"BK4_20b", STREAMED_SOUND_MISSION_BK4_20B}, {"BNK4_21", STREAMED_SOUND_MISSION_BNK4_21}, {"BNK422a", STREAMED_SOUND_MISSION_BNK422A}, + {"BNK422b", STREAMED_SOUND_MISSION_BNK422B}, {"BK4_23a", STREAMED_SOUND_MISSION_BK4_23A}, {"BK4_23b", STREAMED_SOUND_MISSION_BK4_23B}, + {"BK4_23c", STREAMED_SOUND_MISSION_BK4_23C}, {"BK4_23d", STREAMED_SOUND_MISSION_BK4_23D}, {"BK4_24a", STREAMED_SOUND_MISSION_BK4_24A}, + {"BK4_24b", STREAMED_SOUND_MISSION_BK4_24B}, {"BNK4_25", STREAMED_SOUND_MISSION_BNK4_25}, {"BNK4_26", STREAMED_SOUND_MISSION_BNK4_26}, + {"BNK4_27", STREAMED_SOUND_MISSION_BNK4_27}, {"BNK4_28", STREAMED_SOUND_MISSION_BNK4_28}, {"BNK4_29", STREAMED_SOUND_MISSION_BNK4_29}, + {"BNK4_30", STREAMED_SOUND_MISSION_BNK4_30}, {"BK4_31a", STREAMED_SOUND_MISSION_BK4_31A}, {"BK4_31b", STREAMED_SOUND_MISSION_BK4_31B}, + {"BNK4_32", STREAMED_SOUND_MISSION_BNK4_32}, {"BK4_34a", STREAMED_SOUND_MISSION_BK4_34A}, {"BK4_34b", STREAMED_SOUND_MISSION_BK4_34B}, + {"BK4_35a", STREAMED_SOUND_MISSION_BK4_35A}, {"BK4_35b", STREAMED_SOUND_MISSION_BK4_35B}, {"BNK4_36", STREAMED_SOUND_MISSION_BNK4_36}, + {"BNK4_37", STREAMED_SOUND_MISSION_BNK4_37}, {"BNK4_38", STREAMED_SOUND_MISSION_BNK4_38}, {"BNK_39", STREAMED_SOUND_MISSION_BNK4_39}, + {"BK4_40a", STREAMED_SOUND_MISSION_BK4_40A}, {"BK4_40b", STREAMED_SOUND_MISSION_BK4_40B}, {"BNK4_41", STREAMED_SOUND_MISSION_BNK4_41}, + {"BNK4_42", STREAMED_SOUND_MISSION_BNK4_42}, {"BNK4_43", STREAMED_SOUND_MISSION_BNK4_43}, {"BNK4_44", STREAMED_SOUND_MISSION_BNK4_44}, + {"BNK4_45", STREAMED_SOUND_MISSION_BNK4_45}, {"BNK4_46", STREAMED_SOUND_MISSION_BNK4_46}, {"BNK4_47", STREAMED_SOUND_MISSION_BNK4_47}, + {"BNK4_48", STREAMED_SOUND_MISSION_BNK4_48}, {"BNK4_49", STREAMED_SOUND_MISSION_BNK4_49}, {"BNK450A", STREAMED_SOUND_MISSION_BNK450A}, + {"BNK450B", STREAMED_SOUND_MISSION_BNK450B}, {"BNK4_51", STREAMED_SOUND_MISSION_BNK4_51}, {"BNK4_94", STREAMED_SOUND_MISSION_BNK4_94}, + {"BNK4_95", STREAMED_SOUND_MISSION_BNK4_95}, {"BNK4_96", STREAMED_SOUND_MISSION_BNK4_96}, {"BNK4_97", STREAMED_SOUND_MISSION_BNK4_97}, + {"BNK4_98", STREAMED_SOUND_MISSION_BNK4_98}, {"BNK4_99", STREAMED_SOUND_MISSION_BNK4_99}, {"CNT1_1", STREAMED_SOUND_MISSION_CNT1_1}, + {"CNT1_2", STREAMED_SOUND_MISSION_CNT1_2}, {"CNT1_3", STREAMED_SOUND_MISSION_CNT1_3}, {"CNT1_4", STREAMED_SOUND_MISSION_CNT1_4}, + {"CNT1_5", STREAMED_SOUND_MISSION_CNT1_5}, {"CNT2_1", STREAMED_SOUND_MISSION_CNT2_1}, {"CNT2_2", STREAMED_SOUND_MISSION_CNT2_2}, + {"CNT2_3", STREAMED_SOUND_MISSION_CNT2_3}, {"CNT2_4", STREAMED_SOUND_MISSION_CNT2_4}, {"PORN1_1", STREAMED_SOUND_MISSION_PORN1_1}, + {"PORN1_2", STREAMED_SOUND_MISSION_PORN1_2}, {"PORN1_3", STREAMED_SOUND_MISSION_PORN1_3}, {"PRN1_3A", STREAMED_SOUND_MISSION_PRN1_3A}, + {"PORN1_4", STREAMED_SOUND_MISSION_PORN1_4}, {"PORN1_5", STREAMED_SOUND_MISSION_PORN1_5}, {"PORN1_6", STREAMED_SOUND_MISSION_PORN1_6}, + {"PORN1_7", STREAMED_SOUND_MISSION_PORN1_7}, {"PORN1_8", STREAMED_SOUND_MISSION_PORN1_8}, {"PORN1_9", STREAMED_SOUND_MISSION_PORN1_9}, + {"PRN1_10", STREAMED_SOUND_MISSION_PRN1_10}, {"PRN1_11", STREAMED_SOUND_MISSION_PRN1_11}, {"PRN1_12", STREAMED_SOUND_MISSION_PRN1_12}, + {"PRN1_13", STREAMED_SOUND_MISSION_PRN1_13}, {"PRN1_14", STREAMED_SOUND_MISSION_PRN1_14}, {"PRN1_15", STREAMED_SOUND_MISSION_PRN1_15}, + {"PRN1_16", STREAMED_SOUND_MISSION_PRN1_16}, {"PRN1_17", STREAMED_SOUND_MISSION_PRN1_17}, {"PRN1_18", STREAMED_SOUND_MISSION_PRN1_18}, + {"PRN1_19", STREAMED_SOUND_MISSION_PRN1_19}, {"PRN1_20", STREAMED_SOUND_MISSION_PRN1_20}, {"PRN1_21", STREAMED_SOUND_MISSION_PRN1_21}, + {"PORN3_1", STREAMED_SOUND_MISSION_PORN3_1}, {"PORN3_2", STREAMED_SOUND_MISSION_PORN3_2}, {"PORN3_3", STREAMED_SOUND_MISSION_PORN3_3}, + {"PORN3_4", STREAMED_SOUND_MISSION_PORN3_4}, {"TAX1_1", STREAMED_SOUND_MISSION_TAX1_1}, {"TAX1_2", STREAMED_SOUND_MISSION_TAX1_2}, + {"TAX1_3", STREAMED_SOUND_MISSION_TAX1_3}, {"TAX1_4", STREAMED_SOUND_MISSION_TAX1_4}, {"TAX1_5", STREAMED_SOUND_MISSION_TAX1_5}, + {"TAX2_1", STREAMED_SOUND_MISSION_TAX2_1}, {"TAX2_2", STREAMED_SOUND_MISSION_TAX2_2}, {"TAX2_3", STREAMED_SOUND_MISSION_TAX2_3}, + {"TAX2_4", STREAMED_SOUND_MISSION_TAX2_4}, {"TAX2_5", STREAMED_SOUND_MISSION_TAX2_5}, {"TAX2_6", STREAMED_SOUND_MISSION_TAX2_6}, + {"TAX2_7", STREAMED_SOUND_MISSION_TAX2_7}, {"TAX3_1", STREAMED_SOUND_MISSION_TAX3_1}, {"TAX3_2", STREAMED_SOUND_MISSION_TAX3_2}, + {"TAX3_3", STREAMED_SOUND_MISSION_TAX3_3}, {"TAX3_4", STREAMED_SOUND_MISSION_TAX3_4}, {"TAX3_5", STREAMED_SOUND_MISSION_TAX3_5}, + {"TEX1_1", STREAMED_SOUND_MISSION_TEX1_1}, {"TEX1_2", STREAMED_SOUND_MISSION_TEX1_2}, {"TEX1_3", STREAMED_SOUND_MISSION_TEX1_3}, + {"TEX1_4", STREAMED_SOUND_MISSION_TEX1_4}, {"TEX1_5", STREAMED_SOUND_MISSION_TEX1_5}, {"TEX1_6", STREAMED_SOUND_MISSION_TEX1_6}, + {"TEX2_1", STREAMED_SOUND_MISSION_TEX2_1}, {"TEX3_1", STREAMED_SOUND_MISSION_TEX3_1}, {"TEX3_2", STREAMED_SOUND_MISSION_TEX3_2}, + {"TEX3_3", STREAMED_SOUND_MISSION_TEX3_3}, {"TEX3_4", STREAMED_SOUND_MISSION_TEX3_4}, {"TEX3_5", STREAMED_SOUND_MISSION_TEX3_5}, + {"TEX3_6", STREAMED_SOUND_MISSION_TEX3_6}, {"TEX3_7", STREAMED_SOUND_MISSION_TEX3_7}, {"TEX3_8", STREAMED_SOUND_MISSION_TEX3_8}, + {"PHIL1_2", STREAMED_SOUND_MISSION_PHIL1_2}, {"PHIL1_3", STREAMED_SOUND_MISSION_PHIL1_3}, {"PHIL2_1", STREAMED_SOUND_MISSION_PHIL2_1}, + {"PHIL2_2", STREAMED_SOUND_MISSION_PHIL2_2}, {"PHIL2_3", STREAMED_SOUND_MISSION_PHIL2_3}, {"PHIL2_4", STREAMED_SOUND_MISSION_PHIL2_4}, + {"PHIL2_5", STREAMED_SOUND_MISSION_PHIL2_5}, {"PHIL2_6", STREAMED_SOUND_MISSION_PHIL2_6}, {"PHIL2_7", STREAMED_SOUND_MISSION_PHIL2_7}, + {"PHIL2_8", STREAMED_SOUND_MISSION_PHIL2_8}, {"PHIL2_9", STREAMED_SOUND_MISSION_PHIL2_9}, {"PHIL210", STREAMED_SOUND_MISSION_PHIL210}, + {"PHIL211", STREAMED_SOUND_MISSION_PHIL211}, {"BIKE1_1", STREAMED_SOUND_MISSION_BIKE1_1}, {"BIKE1_2", STREAMED_SOUND_MISSION_BIKE1_2}, + {"BIKE1_3", STREAMED_SOUND_MISSION_BIKE1_3}, {"ROK1_1a", STREAMED_SOUND_MISSION_ROK1_1A}, {"ROK1_1b", STREAMED_SOUND_MISSION_ROK1_1B}, + {"ROK1_5", STREAMED_SOUND_MISSION_ROK1_5}, {"ROK1_6", STREAMED_SOUND_MISSION_ROK1_6}, {"ROK1_7", STREAMED_SOUND_MISSION_ROK1_7}, + {"ROK1_8", STREAMED_SOUND_MISSION_ROK1_8}, {"ROK1_9", STREAMED_SOUND_MISSION_ROK1_9}, {"PSYCH_1", STREAMED_SOUND_MISSION_PSYCH_1}, + {"PSYCH_2", STREAMED_SOUND_MISSION_PSYCH_2}, {"ROK2_01", STREAMED_SOUND_MISSION_ROK2_01}, {"ROK3_1", STREAMED_SOUND_MISSION_ROK3_1}, + {"ROK3_2", STREAMED_SOUND_MISSION_ROK3_2}, {"ROK3_3", STREAMED_SOUND_MISSION_ROK3_3}, {"ROK3_4", STREAMED_SOUND_MISSION_ROK3_4}, + {"ROK3_5", STREAMED_SOUND_MISSION_ROK3_5}, {"ROK3_6", STREAMED_SOUND_MISSION_ROK3_6}, {"ROK3_7", STREAMED_SOUND_MISSION_ROK3_7}, + {"ROK3_8", STREAMED_SOUND_MISSION_ROK3_8}, {"ROK3_9", STREAMED_SOUND_MISSION_ROK3_9}, {"ROK3_10", STREAMED_SOUND_MISSION_ROK3_10}, + {"ROK3_11", STREAMED_SOUND_MISSION_ROK3_11}, {"ROK3_12", STREAMED_SOUND_MISSION_ROK3_12}, {"ROK3_13", STREAMED_SOUND_MISSION_ROK3_13}, + {"ROK3_14", STREAMED_SOUND_MISSION_ROK3_14}, {"ROK3_15", STREAMED_SOUND_MISSION_ROK3_15}, {"ROK3_16", STREAMED_SOUND_MISSION_ROK3_16}, + {"ROK3_17", STREAMED_SOUND_MISSION_ROK3_17}, {"ROK3_18", STREAMED_SOUND_MISSION_ROK3_18}, {"ROK3_19", STREAMED_SOUND_MISSION_ROK3_19}, + {"ROK3_20", STREAMED_SOUND_MISSION_ROK3_20}, {"ROK3_21", STREAMED_SOUND_MISSION_ROK3_21}, {"ROK3_22", STREAMED_SOUND_MISSION_ROK3_22}, + {"ROK3_23", STREAMED_SOUND_MISSION_ROK3_23}, {"ROK3_24", STREAMED_SOUND_MISSION_ROK3_24}, {"ROK3_25", STREAMED_SOUND_MISSION_ROK3_25}, + {"ROK3_26", STREAMED_SOUND_MISSION_ROK3_26}, {"ROK3_27", STREAMED_SOUND_MISSION_ROK3_27}, {"ROK3_62", STREAMED_SOUND_MISSION_ROK3_62}, + {"ROK3_63", STREAMED_SOUND_MISSION_ROK3_63}, {"ROK3_64", STREAMED_SOUND_MISSION_ROK3_64}, {"ROK3_65", STREAMED_SOUND_MISSION_ROK3_65}, + {"ROK3_66", STREAMED_SOUND_MISSION_ROK3_66}, {"ROK3_67", STREAMED_SOUND_MISSION_ROK3_67}, {"ROK3_68", STREAMED_SOUND_MISSION_ROK3_68}, + {"ROK3_69", STREAMED_SOUND_MISSION_ROK3_69}, {"ROK3_70", STREAMED_SOUND_MISSION_ROK3_70}, {"ROK3_71", STREAMED_SOUND_MISSION_ROK3_71}, + {"ROK3_73", STREAMED_SOUND_MISSION_ROK3_73}, {"HAT_1a", STREAMED_SOUND_MISSION_HAT_1A}, {"intro1", STREAMED_SOUND_MISSION_INTRO1}, + {"intro2", STREAMED_SOUND_MISSION_INTRO2}, {"intro3", STREAMED_SOUND_MISSION_INTRO3}, {"intro4", STREAMED_SOUND_MISSION_INTRO4}, + {"CUB1_1", STREAMED_SOUND_MISSION_CUB1_1}, {"CUB1_2", STREAMED_SOUND_MISSION_CUB1_2}, {"CUB1_3", STREAMED_SOUND_MISSION_CUB1_3}, + {"CUB1_4", STREAMED_SOUND_MISSION_CUB1_4}, {"CUB1_5", STREAMED_SOUND_MISSION_CUB1_5}, {"CUB1_6", STREAMED_SOUND_MISSION_CUB1_6}, + {"CUB1_7", STREAMED_SOUND_MISSION_CUB1_7}, {"CUB1_8", STREAMED_SOUND_MISSION_CUB1_8}, {"CUB1_9", STREAMED_SOUND_MISSION_CUB1_9}, + {"CUB1_10", STREAMED_SOUND_MISSION_CUB1_10}, {"CUB2_1", STREAMED_SOUND_MISSION_CUB2_1}, {"CUB2_2", STREAMED_SOUND_MISSION_CUB2_2}, + {"CUB2_3a", STREAMED_SOUND_MISSION_CUB2_3A}, {"CUB2_3b", STREAMED_SOUND_MISSION_CUB2_3B}, {"CUB2_3c", STREAMED_SOUND_MISSION_CUB2_3C}, + {"CUB2_4a", STREAMED_SOUND_MISSION_CUB2_4A}, {"CUB2_5", STREAMED_SOUND_MISSION_CUB2_5}, {"CUB2_6", STREAMED_SOUND_MISSION_CUB2_6}, + {"CUB2_7", STREAMED_SOUND_MISSION_CUB2_7}, {"CUB2_8", STREAMED_SOUND_MISSION_CUB2_8}, {"CUB2_9", STREAMED_SOUND_MISSION_CUB2_9}, + {"CUB2_10", STREAMED_SOUND_MISSION_CUB2_10}, {"CUB2_11", STREAMED_SOUND_MISSION_CUB2_11}, {"CUB3_1", STREAMED_SOUND_MISSION_CUB3_1}, + {"CUB3_2", STREAMED_SOUND_MISSION_CUB3_2}, {"CUB3_3", STREAMED_SOUND_MISSION_CUB3_3}, {"CUB3_4", STREAMED_SOUND_MISSION_CUB3_4}, + {"CUB4_1", STREAMED_SOUND_MISSION_CUB4_1}, {"CUB4_2", STREAMED_SOUND_MISSION_CUB4_2}, {"CUB4_3", STREAMED_SOUND_MISSION_CUB4_3}, + {"CUB4_4", STREAMED_SOUND_MISSION_CUB4_4}, {"CUB4_5", STREAMED_SOUND_MISSION_CUB4_5}, {"CUB4_5A", STREAMED_SOUND_MISSION_CUB4_5A}, + {"CUB4_6", STREAMED_SOUND_MISSION_CUB4_6}, {"CUB4_7", STREAMED_SOUND_MISSION_CUB4_7}, {"CUB4_8", STREAMED_SOUND_MISSION_CUB4_8}, + {"CUB4_9", STREAMED_SOUND_MISSION_CUB4_9}, {"CUB4_10", STREAMED_SOUND_MISSION_CUB4_10}, {"CUB4_11", STREAMED_SOUND_MISSION_CUB4_11}, + {"CUB4_12", STREAMED_SOUND_MISSION_CUB4_12}, {"CUB4_13", STREAMED_SOUND_MISSION_CUB4_13}, {"CUB4_14", STREAMED_SOUND_MISSION_CUB4_14}, + {"CUB4_15", STREAMED_SOUND_MISSION_CUB4_15}, {"CUB4_16", STREAMED_SOUND_MISSION_CUB4_16}, {"golf_1", STREAMED_SOUND_MISSION_GOLF_1}, + {"golf_2", STREAMED_SOUND_MISSION_GOLF_2}, {"golf_3", STREAMED_SOUND_MISSION_GOLF_3}, {"bar_1", STREAMED_SOUND_MISSION_BAR_1}, + {"bar_2", STREAMED_SOUND_MISSION_BAR_2}, {"bar_3", STREAMED_SOUND_MISSION_BAR_3}, {"bar_4", STREAMED_SOUND_MISSION_BAR_4}, + {"bar_5", STREAMED_SOUND_MISSION_BAR_5}, {"bar_6", STREAMED_SOUND_MISSION_BAR_6}, {"bar_7", STREAMED_SOUND_MISSION_BAR_7}, + {"bar_8", STREAMED_SOUND_MISSION_BAR_8}, {"strip_1", STREAMED_SOUND_MISSION_STRIP_1}, {"strip_2", STREAMED_SOUND_MISSION_STRIP_2}, + {"strip_3", STREAMED_SOUND_MISSION_STRIP_3}, {"strip_4", STREAMED_SOUND_MISSION_STRIP_4}, {"strip_5", STREAMED_SOUND_MISSION_STRIP_5}, + {"strip_6", STREAMED_SOUND_MISSION_STRIP_6}, {"strip_7", STREAMED_SOUND_MISSION_STRIP_7}, {"strip_8", STREAMED_SOUND_MISSION_STRIP_8}, + {"strip_9", STREAMED_SOUND_MISSION_STRIP_9}, {"star_1", STREAMED_SOUND_MISSION_STAR_1}, {"star_2", STREAMED_SOUND_MISSION_STAR_2}, + {"star_3", STREAMED_SOUND_MISSION_STAR_3}, {"star_4", STREAMED_SOUND_MISSION_STAR_4}, {"mob_01a", STREAMED_SOUND_MISSION_MOB_01A}, + {"mob_01b", STREAMED_SOUND_MISSION_MOB_01B}, {"mob_01c", STREAMED_SOUND_MISSION_MOB_01C}, {"mob_02a", STREAMED_SOUND_MISSION_MOB_02A}, + {"mob_02b", STREAMED_SOUND_MISSION_MOB_02B}, {"mob_02c", STREAMED_SOUND_MISSION_MOB_02C}, {"mob_03a", STREAMED_SOUND_MISSION_MOB_03A}, + {"mob_03b", STREAMED_SOUND_MISSION_MOB_03B}, {"mob_03c", STREAMED_SOUND_MISSION_MOB_03C}, {"mob_03d", STREAMED_SOUND_MISSION_MOB_03D}, + {"mob_03e", STREAMED_SOUND_MISSION_MOB_03E}, {"shark_1", STREAMED_SOUND_MISSION_SHARK_1}, {"shark_2", STREAMED_SOUND_MISSION_SHARK_2}, + {"shark_3", STREAMED_SOUND_MISSION_SHARK_3}, {"shark_4", STREAMED_SOUND_MISSION_SHARK_4}, {"shark_5", STREAMED_SOUND_MISSION_SHARK_5}, + {"mob_04a", STREAMED_SOUND_MISSION_MOB_04A}, {"mob_04b", STREAMED_SOUND_MISSION_MOB_04B}, {"mob_04c", STREAMED_SOUND_MISSION_MOB_04C}, + {"mob_04d", STREAMED_SOUND_MISSION_MOB_04D}, {"mob_05a", STREAMED_SOUND_MISSION_MOB_05A}, {"mob_05b", STREAMED_SOUND_MISSION_MOB_05B}, + {"mob_05c", STREAMED_SOUND_MISSION_MOB_05C}, {"mob_05d", STREAMED_SOUND_MISSION_MOB_05D}, {"mob_06a", STREAMED_SOUND_MISSION_MOB_06A}, + {"mob_06b", STREAMED_SOUND_MISSION_MOB_06B}, {"mob_06c", STREAMED_SOUND_MISSION_MOB_06C}, {"mob_07a", STREAMED_SOUND_MISSION_MOB_07A}, + {"mob_07b", STREAMED_SOUND_MISSION_MOB_07B}, {"mob_08a", STREAMED_SOUND_MISSION_MOB_08A}, {"mob_08b", STREAMED_SOUND_MISSION_MOB_08B}, + {"mob_08c", STREAMED_SOUND_MISSION_MOB_08C}, {"mob_08d", STREAMED_SOUND_MISSION_MOB_08D}, {"mob_08e", STREAMED_SOUND_MISSION_MOB_08E}, + {"mob_08f", STREAMED_SOUND_MISSION_MOB_08F}, {"mob_08g", STREAMED_SOUND_MISSION_MOB_08G}, {"mob_09a", STREAMED_SOUND_MISSION_MOB_09A}, + {"mob_09b", STREAMED_SOUND_MISSION_MOB_09B}, {"mob_09c", STREAMED_SOUND_MISSION_MOB_09C}, {"mob_09d", STREAMED_SOUND_MISSION_MOB_09D}, + {"mob_09e", STREAMED_SOUND_MISSION_MOB_09E}, {"mob_09f", STREAMED_SOUND_MISSION_MOB_09F}, {"mob_10a", STREAMED_SOUND_MISSION_MOB_10A}, + {"mob_10b", STREAMED_SOUND_MISSION_MOB_10B}, {"mob_10c", STREAMED_SOUND_MISSION_MOB_10C}, {"mob_10d", STREAMED_SOUND_MISSION_MOB_10D}, + {"mob_10e", STREAMED_SOUND_MISSION_MOB_10E}, {"mob_11a", STREAMED_SOUND_MISSION_MOB_11A}, {"mob_11b", STREAMED_SOUND_MISSION_MOB_11B}, + {"mob_11c", STREAMED_SOUND_MISSION_MOB_11C}, {"mob_11d", STREAMED_SOUND_MISSION_MOB_11D}, {"mob_11e", STREAMED_SOUND_MISSION_MOB_11E}, + {"mob_11f", STREAMED_SOUND_MISSION_MOB_11F}, {"mob_14a", STREAMED_SOUND_MISSION_MOB_14A}, {"mob_14b", STREAMED_SOUND_MISSION_MOB_14B}, + {"mob_14c", STREAMED_SOUND_MISSION_MOB_14C}, {"mob_14d", STREAMED_SOUND_MISSION_MOB_14D}, {"mob_14e", STREAMED_SOUND_MISSION_MOB_14E}, + {"mob_14f", STREAMED_SOUND_MISSION_MOB_14F}, {"mob_14g", STREAMED_SOUND_MISSION_MOB_14G}, {"mob_14h", STREAMED_SOUND_MISSION_MOB_14H}, + {"mob_16a", STREAMED_SOUND_MISSION_MOB_16A}, {"mob_16b", STREAMED_SOUND_MISSION_MOB_16B}, {"mob_16c", STREAMED_SOUND_MISSION_MOB_16C}, + {"mob_16d", STREAMED_SOUND_MISSION_MOB_16D}, {"mob_16e", STREAMED_SOUND_MISSION_MOB_16E}, {"mob_16f", STREAMED_SOUND_MISSION_MOB_16F}, + {"mob_16g", STREAMED_SOUND_MISSION_MOB_16G}, {"mob_17a", STREAMED_SOUND_MISSION_MOB_17A}, {"mob_17b", STREAMED_SOUND_MISSION_MOB_17B}, + {"mob_17c", STREAMED_SOUND_MISSION_MOB_17C}, {"mob_17d", STREAMED_SOUND_MISSION_MOB_17D}, {"mob_17e", STREAMED_SOUND_MISSION_MOB_17E}, + {"mob_17g", STREAMED_SOUND_MISSION_MOB_17G}, {"mob_17h", STREAMED_SOUND_MISSION_MOB_17H}, {"mob_17i", STREAMED_SOUND_MISSION_MOB_17I}, + {"mob_17j", STREAMED_SOUND_MISSION_MOB_17J}, {"mob_17k", STREAMED_SOUND_MISSION_MOB_17K}, {"mob_17l", STREAMED_SOUND_MISSION_MOB_17L}, + {"mob_18a", STREAMED_SOUND_MISSION_MOB_18A}, {"mob_18b", STREAMED_SOUND_MISSION_MOB_18B}, {"mob_18c", STREAMED_SOUND_MISSION_MOB_18C}, + {"mob_18d", STREAMED_SOUND_MISSION_MOB_18D}, {"mob_18e", STREAMED_SOUND_MISSION_MOB_18E}, {"mob_18f", STREAMED_SOUND_MISSION_MOB_18F}, + {"mob_18g", STREAMED_SOUND_MISSION_MOB_18G}, {"mob_20a", STREAMED_SOUND_MISSION_MOB_20A}, {"mob_20b", STREAMED_SOUND_MISSION_MOB_20B}, + {"mob_20c", STREAMED_SOUND_MISSION_MOB_20C}, {"mob_20d", STREAMED_SOUND_MISSION_MOB_20D}, {"mob_20e", STREAMED_SOUND_MISSION_MOB_20E}, + {"mob_24a", STREAMED_SOUND_MISSION_MOB_24A}, {"mob_24b", STREAMED_SOUND_MISSION_MOB_24B}, {"mob_24c", STREAMED_SOUND_MISSION_MOB_24C}, + {"mob_24d", STREAMED_SOUND_MISSION_MOB_24D}, {"mob_24e", STREAMED_SOUND_MISSION_MOB_24E}, {"mob_24f", STREAMED_SOUND_MISSION_MOB_24F}, + {"mob_24g", STREAMED_SOUND_MISSION_MOB_24G}, {"mob_24h", STREAMED_SOUND_MISSION_MOB_24H}, {"mob_25a", STREAMED_SOUND_MISSION_MOB_25A}, + {"mob_25b", STREAMED_SOUND_MISSION_MOB_25B}, {"mob_25c", STREAMED_SOUND_MISSION_MOB_25C}, {"mob_25d", STREAMED_SOUND_MISSION_MOB_25D}, + {"mob_26a", STREAMED_SOUND_MISSION_MOB_26A}, {"mob_26b", STREAMED_SOUND_MISSION_MOB_26B}, {"mob_26c", STREAMED_SOUND_MISSION_MOB_26C}, + {"mob_26d", STREAMED_SOUND_MISSION_MOB_26D}, {"mob_26e", STREAMED_SOUND_MISSION_MOB_26E}, {"mob_29a", STREAMED_SOUND_MISSION_MOB_29A}, + {"mob_29b", STREAMED_SOUND_MISSION_MOB_29B}, {"mob_29c", STREAMED_SOUND_MISSION_MOB_29C}, {"mob_29d", STREAMED_SOUND_MISSION_MOB_29D}, + {"mob_29e", STREAMED_SOUND_MISSION_MOB_29E}, {"mob_29f", STREAMED_SOUND_MISSION_MOB_29F}, {"mob_29g", STREAMED_SOUND_MISSION_MOB_29G}, + {"mob_30a", STREAMED_SOUND_MISSION_MOB_30A}, {"mob_30b", STREAMED_SOUND_MISSION_MOB_30B}, {"mob_30c", STREAMED_SOUND_MISSION_MOB_30C}, + {"mob_30d", STREAMED_SOUND_MISSION_MOB_30D}, {"mob_30e", STREAMED_SOUND_MISSION_MOB_30E}, {"mob_30f", STREAMED_SOUND_MISSION_MOB_30F}, + {"mob_33a", STREAMED_SOUND_MISSION_MOB_33A}, {"mob_33b", STREAMED_SOUND_MISSION_MOB_33B}, {"mob_33c", STREAMED_SOUND_MISSION_MOB_33C}, + {"mob_33d", STREAMED_SOUND_MISSION_MOB_33D}, {"mob_34a", STREAMED_SOUND_MISSION_MOB_34A}, {"mob_34b", STREAMED_SOUND_MISSION_MOB_34B}, + {"mob_34c", STREAMED_SOUND_MISSION_MOB_34C}, {"mob_34d", STREAMED_SOUND_MISSION_MOB_34D}, {"mob_35a", STREAMED_SOUND_MISSION_MOB_35A}, + {"mob_35b", STREAMED_SOUND_MISSION_MOB_35B}, {"mob_35c", STREAMED_SOUND_MISSION_MOB_35C}, {"mob_35d", STREAMED_SOUND_MISSION_MOB_35D}, + {"mob_36a", STREAMED_SOUND_MISSION_MOB_36A}, {"mob_36b", STREAMED_SOUND_MISSION_MOB_36B}, {"mob_36c", STREAMED_SOUND_MISSION_MOB_36C}, + {"mob_40a", STREAMED_SOUND_MISSION_MOB_40A}, {"mob_40b", STREAMED_SOUND_MISSION_MOB_40B}, {"mob_40c", STREAMED_SOUND_MISSION_MOB_40C}, + {"mob_40d", STREAMED_SOUND_MISSION_MOB_40D}, {"mob_40e", STREAMED_SOUND_MISSION_MOB_40E}, {"mob_40f", STREAMED_SOUND_MISSION_MOB_40F}, + {"mob_40g", STREAMED_SOUND_MISSION_MOB_40G}, {"mob_40h", STREAMED_SOUND_MISSION_MOB_40H}, {"mob_40i", STREAMED_SOUND_MISSION_MOB_40I}, + {"mob_41a", STREAMED_SOUND_MISSION_MOB_41A}, {"mob_41b", STREAMED_SOUND_MISSION_MOB_41B}, {"mob_41c", STREAMED_SOUND_MISSION_MOB_41C}, + {"mob_41d", STREAMED_SOUND_MISSION_MOB_41D}, {"mob_41e", STREAMED_SOUND_MISSION_MOB_41E}, {"mob_41f", STREAMED_SOUND_MISSION_MOB_41F}, + {"mob_41g", STREAMED_SOUND_MISSION_MOB_41G}, {"mob_41h", STREAMED_SOUND_MISSION_MOB_41H}, {"mob_42a", STREAMED_SOUND_MISSION_MOB_42A}, + {"mob_42b", STREAMED_SOUND_MISSION_MOB_42B}, {"mob_42c", STREAMED_SOUND_MISSION_MOB_42C}, {"mob_42d", STREAMED_SOUND_MISSION_MOB_42D}, + {"mob_42e", STREAMED_SOUND_MISSION_MOB_42E}, {"mob_43a", STREAMED_SOUND_MISSION_MOB_43A}, {"mob_43b", STREAMED_SOUND_MISSION_MOB_43B}, + {"mob_43c", STREAMED_SOUND_MISSION_MOB_43C}, {"mob_43d", STREAMED_SOUND_MISSION_MOB_43D}, {"mob_43e", STREAMED_SOUND_MISSION_MOB_43E}, + {"mob_43f", STREAMED_SOUND_MISSION_MOB_43F}, {"mob_43g", STREAMED_SOUND_MISSION_MOB_43G}, {"mob_43h", STREAMED_SOUND_MISSION_MOB_43H}, + {"mob_45a", STREAMED_SOUND_MISSION_MOB_45A}, {"mob_45b", STREAMED_SOUND_MISSION_MOB_45B}, {"mob_45c", STREAMED_SOUND_MISSION_MOB_45C}, + {"mob_45d", STREAMED_SOUND_MISSION_MOB_45D}, {"mob_45e", STREAMED_SOUND_MISSION_MOB_45E}, {"mob_45f", STREAMED_SOUND_MISSION_MOB_45F}, + {"mob_45g", STREAMED_SOUND_MISSION_MOB_45G}, {"mob_45h", STREAMED_SOUND_MISSION_MOB_45H}, {"mob_45i", STREAMED_SOUND_MISSION_MOB_45I}, + {"mob_45j", STREAMED_SOUND_MISSION_MOB_45J}, {"mob_45k", STREAMED_SOUND_MISSION_MOB_45K}, {"mob_45l", STREAMED_SOUND_MISSION_MOB_45L}, + {"mob_45m", STREAMED_SOUND_MISSION_MOB_45M}, {"mob_45n", STREAMED_SOUND_MISSION_MOB_45N}, {"mob_46a", STREAMED_SOUND_MISSION_MOB_46A}, + {"mob_46b", STREAMED_SOUND_MISSION_MOB_46B}, {"mob_46c", STREAMED_SOUND_MISSION_MOB_46C}, {"mob_46d", STREAMED_SOUND_MISSION_MOB_46D}, + {"mob_46e", STREAMED_SOUND_MISSION_MOB_46E}, {"mob_46f", STREAMED_SOUND_MISSION_MOB_46F}, {"mob_46g", STREAMED_SOUND_MISSION_MOB_46G}, + {"mob_46h", STREAMED_SOUND_MISSION_MOB_46H}, {"mob_47a", STREAMED_SOUND_MISSION_MOB_47A}, {"mob_52a", STREAMED_SOUND_MISSION_MOB_52A}, + {"mob_52b", STREAMED_SOUND_MISSION_MOB_52B}, {"mob_52c", STREAMED_SOUND_MISSION_MOB_52C}, {"mob_52d", STREAMED_SOUND_MISSION_MOB_52D}, + {"mob_52e", STREAMED_SOUND_MISSION_MOB_52E}, {"mob_52f", STREAMED_SOUND_MISSION_MOB_52F}, {"mob_52g", STREAMED_SOUND_MISSION_MOB_52G}, + {"mob_52h", STREAMED_SOUND_MISSION_MOB_52H}, {"mob_54a", STREAMED_SOUND_MISSION_MOB_54A}, {"mob_54b", STREAMED_SOUND_MISSION_MOB_54B}, + {"mob_54c", STREAMED_SOUND_MISSION_MOB_54C}, {"mob_54d", STREAMED_SOUND_MISSION_MOB_54D}, {"mob_54e", STREAMED_SOUND_MISSION_MOB_54E}, + {"mob_55a", STREAMED_SOUND_MISSION_MOB_55A}, {"mob_55b", STREAMED_SOUND_MISSION_MOB_55B}, {"mob_55c", STREAMED_SOUND_MISSION_MOB_55C}, + {"mob_55d", STREAMED_SOUND_MISSION_MOB_55D}, {"mob_55e", STREAMED_SOUND_MISSION_MOB_55E}, {"mob_55f", STREAMED_SOUND_MISSION_MOB_55F}, + {"mob_56a", STREAMED_SOUND_MISSION_MOB_56A}, {"mob_56b", STREAMED_SOUND_MISSION_MOB_56B}, {"mob_56c", STREAMED_SOUND_MISSION_MOB_56C}, + {"mob_56d", STREAMED_SOUND_MISSION_MOB_56D}, {"mob_56e", STREAMED_SOUND_MISSION_MOB_56E}, {"mob_56f", STREAMED_SOUND_MISSION_MOB_56F}, + {"mob_57a", STREAMED_SOUND_MISSION_MOB_57A}, {"mob_57b", STREAMED_SOUND_MISSION_MOB_57B}, {"mob_57c", STREAMED_SOUND_MISSION_MOB_57C}, + {"mob_57d", STREAMED_SOUND_MISSION_MOB_57D}, {"mob_57e", STREAMED_SOUND_MISSION_MOB_57E}, {"mob_58a", STREAMED_SOUND_MISSION_MOB_58A}, + {"mob_58b", STREAMED_SOUND_MISSION_MOB_58B}, {"mob_58c", STREAMED_SOUND_MISSION_MOB_58C}, {"mob_58d", STREAMED_SOUND_MISSION_MOB_58D}, + {"mob_58e", STREAMED_SOUND_MISSION_MOB_58E}, {"mob_58f", STREAMED_SOUND_MISSION_MOB_58F}, {"mob_58g", STREAMED_SOUND_MISSION_MOB_58G}, + {"mob_61a", STREAMED_SOUND_MISSION_MOB_61A}, {"mob_61b", STREAMED_SOUND_MISSION_MOB_61B}, {"mob_62a", STREAMED_SOUND_MISSION_MOB_62A}, + {"mob_62b", STREAMED_SOUND_MISSION_MOB_62B}, {"mob_62c", STREAMED_SOUND_MISSION_MOB_62C}, {"mob_62d", STREAMED_SOUND_MISSION_MOB_62D}, + {"mob_63a", STREAMED_SOUND_MISSION_MOB_63A}, {"mob_63b", STREAMED_SOUND_MISSION_MOB_63B}, {"mob_63c", STREAMED_SOUND_MISSION_MOB_63C}, + {"mob_63d", STREAMED_SOUND_MISSION_MOB_63D}, {"mob_63e", STREAMED_SOUND_MISSION_MOB_63E}, {"mob_63f", STREAMED_SOUND_MISSION_MOB_63F}, + {"mob_63g", STREAMED_SOUND_MISSION_MOB_63G}, {"mob_63h", STREAMED_SOUND_MISSION_MOB_63H}, {"mob_63i", STREAMED_SOUND_MISSION_MOB_63I}, + {"mob_63j", STREAMED_SOUND_MISSION_MOB_63J}, {"mob_66a", STREAMED_SOUND_MISSION_MOB_66A}, {"mob_66b", STREAMED_SOUND_MISSION_MOB_66B}, + {"mob_68a", STREAMED_SOUND_MISSION_MOB_68A}, {"mob_68b", STREAMED_SOUND_MISSION_MOB_68B}, {"mob_68c", STREAMED_SOUND_MISSION_MOB_68C}, + {"mob_68d", STREAMED_SOUND_MISSION_MOB_68D}, {"mob_70a", STREAMED_SOUND_MISSION_MOB_70A}, {"mob_70b", STREAMED_SOUND_MISSION_MOB_70B}, + {"mob_71a", STREAMED_SOUND_MISSION_MOB_71A}, {"mob_71b", STREAMED_SOUND_MISSION_MOB_71B}, {"mob_71c", STREAMED_SOUND_MISSION_MOB_71C}, + {"mob_71d", STREAMED_SOUND_MISSION_MOB_71D}, {"mob_71e", STREAMED_SOUND_MISSION_MOB_71E}, {"mob_71f", STREAMED_SOUND_MISSION_MOB_71F}, + {"mob_71g", STREAMED_SOUND_MISSION_MOB_71G}, {"mob_71h", STREAMED_SOUND_MISSION_MOB_71H}, {"mob_71i", STREAMED_SOUND_MISSION_MOB_71I}, + {"mob_71j", STREAMED_SOUND_MISSION_MOB_71J}, {"mob_71k", STREAMED_SOUND_MISSION_MOB_71K}, {"mob_71l", STREAMED_SOUND_MISSION_MOB_71L}, + {"mob_71m", STREAMED_SOUND_MISSION_MOB_71M}, {"mob_71n", STREAMED_SOUND_MISSION_MOB_71N}, {"mob_72a", STREAMED_SOUND_MISSION_MOB_72A}, + {"mob_72b", STREAMED_SOUND_MISSION_MOB_72B}, {"mob_72c", STREAMED_SOUND_MISSION_MOB_72C}, {"mob_72d", STREAMED_SOUND_MISSION_MOB_72D}, + {"mob_72e", STREAMED_SOUND_MISSION_MOB_72E}, {"mob_72f", STREAMED_SOUND_MISSION_MOB_72F}, {"mob_72g", STREAMED_SOUND_MISSION_MOB_72G}, + {"mob_73a", STREAMED_SOUND_MISSION_MOB_73A}, {"mob_73c", STREAMED_SOUND_MISSION_MOB_73C}, {"mob_73d", STREAMED_SOUND_MISSION_MOB_73D}, + {"mob_73f", STREAMED_SOUND_MISSION_MOB_73F}, {"mob_73g", STREAMED_SOUND_MISSION_MOB_73G}, {"mob_73i", STREAMED_SOUND_MISSION_MOB_73I}, + {"mob_95a", STREAMED_SOUND_MISSION_MOB_95A}, {"mob_96a", STREAMED_SOUND_MISSION_MOB_96A}, {"mob_98a", STREAMED_SOUND_MISSION_MOB_98A}, + {"mob_99a", STREAMED_SOUND_MISSION_MOB_99A}, {"job1_1b", STREAMED_SOUND_MISSION_JOB1_1B}, {"job1_1c", STREAMED_SOUND_MISSION_JOB1_1C}, + {"job1_1d", STREAMED_SOUND_MISSION_JOB1_1D}, {"job2_1b", STREAMED_SOUND_MISSION_JOB2_1B}, {"job2_2", STREAMED_SOUND_MISSION_JOB2_2}, + {"job2_3", STREAMED_SOUND_MISSION_JOB2_3}, {"job2_4", STREAMED_SOUND_MISSION_JOB2_4}, {"job2_5", STREAMED_SOUND_MISSION_JOB2_5}, + {"job2_6", STREAMED_SOUND_MISSION_JOB2_6}, {"job2_7", STREAMED_SOUND_MISSION_JOB2_7}, {"job2_8", STREAMED_SOUND_MISSION_JOB2_8}, + {"job2_9", STREAMED_SOUND_MISSION_JOB2_9}, {"job3_1", STREAMED_SOUND_MISSION_JOB3_1}, {"job3_2", STREAMED_SOUND_MISSION_JOB3_2}, + {"job3_3", STREAMED_SOUND_MISSION_JOB3_3}, {"job4_1", STREAMED_SOUND_MISSION_JOB4_1}, {"job4_2", STREAMED_SOUND_MISSION_JOB4_2}, + {"job4_3", STREAMED_SOUND_MISSION_JOB4_3}, {"job5_1", STREAMED_SOUND_MISSION_JOB5_1}, {"job5_2", STREAMED_SOUND_MISSION_JOB5_2}, + {"job5_3", STREAMED_SOUND_MISSION_JOB5_3}, {"bjm1_20", STREAMED_SOUND_MISSION_BJM1_20}, {"bjm1_4", STREAMED_SOUND_MISSION_BJM1_4}, + {"bjm1_5", STREAMED_SOUND_MISSION_BJM1_5}, {"merc_39", STREAMED_SOUND_MISSION_MERC_39}, {"mono_1", STREAMED_SOUND_MISSION_MONO_1}, + {"mono_2", STREAMED_SOUND_MISSION_MONO_2}, {"mono_3", STREAMED_SOUND_MISSION_MONO_3}, {"mono_4", STREAMED_SOUND_MISSION_MONO_4}, + {"mono_5", STREAMED_SOUND_MISSION_MONO_5}, {"mono_6", STREAMED_SOUND_MISSION_MONO_6}, {"mono_7", STREAMED_SOUND_MISSION_MONO_7}, + {"mono_8", STREAMED_SOUND_MISSION_MONO_8}, {"mono_9", STREAMED_SOUND_MISSION_MONO_9}, {"mono10", STREAMED_SOUND_MISSION_MONO10}, + {"mono11", STREAMED_SOUND_MISSION_MONO11}, {"mono12", STREAMED_SOUND_MISSION_MONO12}, {"mono13", STREAMED_SOUND_MISSION_MONO13}, + {"mono14", STREAMED_SOUND_MISSION_MONO14}, {"mono15", STREAMED_SOUND_MISSION_MONO15}, {"mono16", STREAMED_SOUND_MISSION_MONO16}, + {"fud_01", STREAMED_SOUND_MISSION_FUD_01}, {"fud_02", STREAMED_SOUND_MISSION_FUD_02}, {"fud_03", STREAMED_SOUND_MISSION_FUD_03}, + {"fud_04", STREAMED_SOUND_MISSION_FUD_04}, {"fud_05", STREAMED_SOUND_MISSION_FUD_05}, {"fud_06", STREAMED_SOUND_MISSION_FUD_06}, + {"fud_07", STREAMED_SOUND_MISSION_FUD_07}, {"fud_08", STREAMED_SOUND_MISSION_FUD_08}, {"fud_09", STREAMED_SOUND_MISSION_FUD_09}, + {"fud_10", STREAMED_SOUND_MISSION_FUD_10}, {"fud_11", STREAMED_SOUND_MISSION_FUD_11}, {"fud_12", STREAMED_SOUND_MISSION_FUD_12}, + {"fud_13", STREAMED_SOUND_MISSION_FUD_13}, {"fud_14", STREAMED_SOUND_MISSION_FUD_14}, {"fud_15", STREAMED_SOUND_MISSION_FUD_15}, + {"fud_16", STREAMED_SOUND_MISSION_FUD_16}, {"fud_17", STREAMED_SOUND_MISSION_FUD_17}, {"fud_18", STREAMED_SOUND_MISSION_FUD_18}, + {"fud_19", STREAMED_SOUND_MISSION_FUD_19}, {"fud_20", STREAMED_SOUND_MISSION_FUD_20}, {"burg_01", STREAMED_SOUND_MISSION_BURG_01}, + {"burg_02", STREAMED_SOUND_MISSION_BURG_02}, {"burg_03", STREAMED_SOUND_MISSION_BURG_03}, {"burg_04", STREAMED_SOUND_MISSION_BURG_04}, + {"burg_05", STREAMED_SOUND_MISSION_BURG_05}, {"burg_06", STREAMED_SOUND_MISSION_BURG_06}, {"burg_07", STREAMED_SOUND_MISSION_BURG_07}, + {"burg_08", STREAMED_SOUND_MISSION_BURG_08}, {"burg_09", STREAMED_SOUND_MISSION_BURG_09}, {"burg_10", STREAMED_SOUND_MISSION_BURG_10}, + {"burg_11", STREAMED_SOUND_MISSION_BURG_11}, {"burg_12", STREAMED_SOUND_MISSION_BURG_12}, {"crust01", STREAMED_SOUND_MISSION_CRUST01}, + {"crust02", STREAMED_SOUND_MISSION_CRUST02}, {"crust03", STREAMED_SOUND_MISSION_CRUST03}, {"crust04", STREAMED_SOUND_MISSION_CRUST04}, + {"crust05", STREAMED_SOUND_MISSION_CRUST05}, {"crust06", STREAMED_SOUND_MISSION_CRUST06}, {"crust07", STREAMED_SOUND_MISSION_CRUST07}, + {"crust08", STREAMED_SOUND_MISSION_CRUST08}, {"crust09", STREAMED_SOUND_MISSION_CRUST09}, {"band_01", STREAMED_SOUND_MISSION_BAND_01}, + {"band_02", STREAMED_SOUND_MISSION_BAND_02}, {"band_03", STREAMED_SOUND_MISSION_BAND_03}, {"band_04", STREAMED_SOUND_MISSION_BAND_04}, + {"band_05", STREAMED_SOUND_MISSION_BAND_05}, {"band_06", STREAMED_SOUND_MISSION_BAND_06}, {"band_07", STREAMED_SOUND_MISSION_BAND_07}, + {"band_08", STREAMED_SOUND_MISSION_BAND_08}, {"shaft01", STREAMED_SOUND_MISSION_SHAFT01}, {"shaft02", STREAMED_SOUND_MISSION_SHAFT02}, + {"shaft03", STREAMED_SOUND_MISSION_SHAFT03}, {"shaft04", STREAMED_SOUND_MISSION_SHAFT04}, {"shaft05", STREAMED_SOUND_MISSION_SHAFT05}, + {"shaft06", STREAMED_SOUND_MISSION_SHAFT06}, {"shaft07", STREAMED_SOUND_MISSION_SHAFT07}, {"shaft08", STREAMED_SOUND_MISSION_SHAFT08}, + {"piss_01", STREAMED_SOUND_MISSION_PISS_01}, {"piss_02", STREAMED_SOUND_MISSION_PISS_02}, {"piss_03", STREAMED_SOUND_MISSION_PISS_03}, + {"piss_04", STREAMED_SOUND_MISSION_PISS_04}, {"piss_05", STREAMED_SOUND_MISSION_PISS_05}, {"piss_06", STREAMED_SOUND_MISSION_PISS_06}, + {"piss_07", STREAMED_SOUND_MISSION_PISS_07}, {"piss_08", STREAMED_SOUND_MISSION_PISS_08}, {"piss_09", STREAMED_SOUND_MISSION_PISS_09}, + {"piss_10", STREAMED_SOUND_MISSION_PISS_10}, {"piss_11", STREAMED_SOUND_MISSION_PISS_11}, {"piss_12", STREAMED_SOUND_MISSION_PISS_12}, + {"piss_13", STREAMED_SOUND_MISSION_PISS_13}, {"piss_14", STREAMED_SOUND_MISSION_PISS_14}, {"piss_15", STREAMED_SOUND_MISSION_PISS_15}, + {"piss_16", STREAMED_SOUND_MISSION_PISS_16}, {"piss_17", STREAMED_SOUND_MISSION_PISS_17}, {"piss_18", STREAMED_SOUND_MISSION_PISS_18}, + {"piss_19", STREAMED_SOUND_MISSION_PISS_19}, {"gimme01", STREAMED_SOUND_MISSION_GIMME01}, {"gimme02", STREAMED_SOUND_MISSION_GIMME02}, + {"gimme03", STREAMED_SOUND_MISSION_GIMME03}, {"gimme04", STREAMED_SOUND_MISSION_GIMME04}, {"gimme05", STREAMED_SOUND_MISSION_GIMME05}, + {"gimme06", STREAMED_SOUND_MISSION_GIMME06}, {"gimme07", STREAMED_SOUND_MISSION_GIMME07}, {"gimme08", STREAMED_SOUND_MISSION_GIMME08}, + {"gimme09", STREAMED_SOUND_MISSION_GIMME09}, {"gimme10", STREAMED_SOUND_MISSION_GIMME10}, {"gimme11", STREAMED_SOUND_MISSION_GIMME11}, + {"gimme12", STREAMED_SOUND_MISSION_GIMME12}, {"gimme13", STREAMED_SOUND_MISSION_GIMME13}, {"gimme14", STREAMED_SOUND_MISSION_GIMME14}, + {"gimme15", STREAMED_SOUND_MISSION_GIMME15}, {"bust_01", STREAMED_SOUND_MISSION_BUST_01}, {"bust_02", STREAMED_SOUND_MISSION_BUST_02}, + {"bust_03", STREAMED_SOUND_MISSION_BUST_03}, {"bust_04", STREAMED_SOUND_MISSION_BUST_04}, {"bust_05", STREAMED_SOUND_MISSION_BUST_05}, + {"bust_06", STREAMED_SOUND_MISSION_BUST_06}, {"bust_07", STREAMED_SOUND_MISSION_BUST_07}, {"bust_08", STREAMED_SOUND_MISSION_BUST_08}, + {"bust_09", STREAMED_SOUND_MISSION_BUST_09}, {"bust_10", STREAMED_SOUND_MISSION_BUST_10}, {"bust_11", STREAMED_SOUND_MISSION_BUST_11}, + {"bust_12", STREAMED_SOUND_MISSION_BUST_12}, {"bust_13", STREAMED_SOUND_MISSION_BUST_13}, {"bust_14", STREAMED_SOUND_MISSION_BUST_14}, + {"bust_15", STREAMED_SOUND_MISSION_BUST_15}, {"bust_16", STREAMED_SOUND_MISSION_BUST_16}, {"bust_17", STREAMED_SOUND_MISSION_BUST_17}, + {"bust_18", STREAMED_SOUND_MISSION_BUST_18}, {"bust_19", STREAMED_SOUND_MISSION_BUST_19}, {"bust_20", STREAMED_SOUND_MISSION_BUST_20}, + {"bust_21", STREAMED_SOUND_MISSION_BUST_21}, {"bust_22", STREAMED_SOUND_MISSION_BUST_22}, {"bust_23", STREAMED_SOUND_MISSION_BUST_23}, + {"bust_24", STREAMED_SOUND_MISSION_BUST_24}, {"bust_25", STREAMED_SOUND_MISSION_BUST_25}, {"bust_26", STREAMED_SOUND_MISSION_BUST_26}, + {"bust_27", STREAMED_SOUND_MISSION_BUST_27}, {"bust_28", STREAMED_SOUND_MISSION_BUST_28}, {nil, 0} }; + +int32 +FindMissionAudioSfx(const char *name) +{ + for (uint32 i = 0; MissionAudioNameSfxAssoc[i].m_pName != nil; ++i) { + if (!CGeneral::faststricmp(MissionAudioNameSfxAssoc[i].m_pName, name)) + return MissionAudioNameSfxAssoc[i].m_nId; + } + debug("Can't find mission audio %s", name); + return NO_SAMPLE; +} + +bool +cAudioManager::MissionScriptAudioUsesPoliceChannel(int32 soundMission) const +{ + return false; +} + +void +cAudioManager::PreloadMissionAudio(uint8 slot, Const char *name) +{ + if (m_bIsInitialised && slot < MISSION_AUDIO_SLOTS) { + int32 missionAudioSfx = FindMissionAudioSfx(name); + if (missionAudioSfx != NO_SAMPLE) { + m_sMissionAudio.m_nSampleIndex[slot] = missionAudioSfx; + m_sMissionAudio.m_nLoadingStatus[slot] = LOADING_STATUS_NOT_LOADED; + m_sMissionAudio.m_nPlayStatus[slot] = PLAY_STATUS_STOPPED; + m_sMissionAudio.m_bIsPlaying[slot] = false; + m_sMissionAudio.m_nMissionAudioCounter[slot] = m_nTimeSpent * SampleManager.GetStreamedFileLength(missionAudioSfx) / 1000; + m_sMissionAudio.m_nMissionAudioCounter[slot] *= 4; + m_sMissionAudio.m_bIsPlayed[slot] = false; + m_sMissionAudio.m_bPredefinedProperties[slot] = true; + g_bMissionAudioLoadFailed[slot] = false; + } + } +} + +uint8 +cAudioManager::GetMissionAudioLoadingStatus(uint8 slot) const +{ + if (m_bIsInitialised && slot < MISSION_AUDIO_SLOTS) + return m_sMissionAudio.m_nLoadingStatus[slot]; + + return LOADING_STATUS_LOADED; +} + +void +cAudioManager::SetMissionAudioLocation(uint8 slot, float x, float y, float z) +{ + if (m_bIsInitialised && slot < MISSION_AUDIO_SLOTS) { + m_sMissionAudio.m_bPredefinedProperties[slot] = false; + m_sMissionAudio.m_vecPos[slot] = CVector(x, y, z); + } +} + +void +cAudioManager::PlayLoadedMissionAudio(uint8 slot) +{ + if (m_bIsInitialised && slot < MISSION_AUDIO_SLOTS && m_sMissionAudio.m_nSampleIndex[slot] != NO_SAMPLE && m_sMissionAudio.m_nLoadingStatus[slot] == LOADING_STATUS_LOADED && + m_sMissionAudio.m_nPlayStatus[slot] == PLAY_STATUS_STOPPED) + m_sMissionAudio.m_bIsPlayed[slot] = true; +} + +bool +cAudioManager::ShouldDuckMissionAudio(uint8 slot) const +{ + if (IsMissionAudioSamplePlaying(slot)) + return m_sMissionAudio.m_nSampleIndex[slot] != STREAMED_SOUND_MISSION_ROK2_01; + return false; +} + +bool +cAudioManager::IsMissionAudioSamplePlaying(uint8 slot) const +{ + if (m_bIsInitialised) { + if (slot < MISSION_AUDIO_SLOTS) + return m_sMissionAudio.m_nPlayStatus[slot] == PLAY_STATUS_PLAYING; + else + return true; + } else { + static int32 cPretendFrame[MISSION_AUDIO_SLOTS] = { 1, 1 }; + + return (cPretendFrame[slot]++ % 64) != 0; + } +} + +bool +cAudioManager::IsMissionAudioSampleFinished(uint8 slot) +{ + if (m_bIsInitialised) { + if (slot < MISSION_AUDIO_SLOTS) + return m_sMissionAudio.m_nPlayStatus[slot] == PLAY_STATUS_FINISHED; + else + return true; + } + + static int32 cPretendFrame[MISSION_AUDIO_SLOTS] = { 1, 1 }; + + return (cPretendFrame[slot]++ % 64) == 0; +} + +void +cAudioManager::ClearMissionAudio(uint8 slot) +{ + if (m_bIsInitialised && slot < MISSION_AUDIO_SLOTS) { + m_sMissionAudio.m_nSampleIndex[slot] = NO_SAMPLE; + m_sMissionAudio.m_nLoadingStatus[slot] = LOADING_STATUS_NOT_LOADED; + m_sMissionAudio.m_nPlayStatus[slot] = PLAY_STATUS_STOPPED; + m_sMissionAudio.m_bIsPlaying[slot] = false; + m_sMissionAudio.m_bIsPlayed[slot] = false; + m_sMissionAudio.m_bPredefinedProperties[slot] = true; + m_sMissionAudio.m_nMissionAudioCounter[slot] = 0; + m_sMissionAudio.m_bIsMobile[slot] = false; + SampleManager.StopStreamedFile(slot + 1); + } +} + +void +cAudioManager::ProcessMissionAudioSlot(uint8 slot) +{ + float dist; + uint8 emittingVol; + uint8 pan; + float distSquared; + CVector vec; + + static uint8 nCheckPlayingDelay[MISSION_AUDIO_SLOTS] = { 0, 0 }; + static uint8 nFramesUntilFailedLoad[MISSION_AUDIO_SLOTS] = { 0, 0 }; + static uint8 nFramesForPretendPlaying[MISSION_AUDIO_SLOTS] = { 0, 0 }; + + if (m_sMissionAudio.m_nSampleIndex[slot] == NO_SAMPLE) return; + + switch (m_sMissionAudio.m_nLoadingStatus[slot]) { + case LOADING_STATUS_NOT_LOADED: + SampleManager.PreloadStreamedFile(m_sMissionAudio.m_nSampleIndex[slot], slot + 1); + m_sMissionAudio.m_nLoadingStatus[slot] = LOADING_STATUS_LOADED; + nFramesUntilFailedLoad[slot] = 0; + break; + case LOADING_STATUS_LOADED: + if (!m_sMissionAudio.m_bIsPlayed[slot]) + return; + if (g_bMissionAudioLoadFailed[slot]) { + if (m_bTimerJustReset) { + ClearMissionAudio(slot); + SampleManager.StopStreamedFile(slot + 1); + nFramesForPretendPlaying[slot] = 0; + nCheckPlayingDelay[slot] = 0; + nFramesUntilFailedLoad[slot] = 0; + } else if (!m_nUserPause) { + if (++nFramesForPretendPlaying[slot] < 90) { + m_sMissionAudio.m_nPlayStatus[slot] = PLAY_STATUS_PLAYING; + } else { + m_sMissionAudio.m_nPlayStatus[slot] = PLAY_STATUS_FINISHED; + m_sMissionAudio.m_nSampleIndex[slot] = NO_SAMPLE; + } + } + break; + } + switch (m_sMissionAudio.m_nPlayStatus[slot]) { + case PLAY_STATUS_STOPPED: + if (MissionScriptAudioUsesPoliceChannel(m_sMissionAudio.m_nSampleIndex[slot])) { + SetMissionScriptPoliceAudio(m_sMissionAudio.m_nSampleIndex[slot]); + } else { + if (m_nUserPause) + SampleManager.PauseStream(1, slot + 1); + if (m_sMissionAudio.m_bPredefinedProperties[slot]) { + if (m_sMissionAudio.m_nSampleIndex[slot] == STREAMED_SOUND_MISSION_CAMERAL) + SampleManager.SetStreamedVolumeAndPan(80, 0, 1, slot + 1); + else if (m_sMissionAudio.m_nSampleIndex[slot] == STREAMED_SOUND_MISSION_CAMERAR) + SampleManager.SetStreamedVolumeAndPan(80, 127, 1, slot + 1); + else + SampleManager.SetStreamedVolumeAndPan(80, 63, 1, slot + 1); + } else { + distSquared = GetDistanceSquared(m_sMissionAudio.m_vecPos[slot]); + if (distSquared >= SQR(80.0f)) { + emittingVol = 0; + pan = 63; + } else { + emittingVol = 80; + if (distSquared > 0.0f) { + dist = Sqrt(distSquared); + emittingVol = ComputeVolume(80, 80.0f, dist); + } + TranslateEntity(&m_sMissionAudio.m_vecPos[slot], &vec); + pan = ComputePan(80.f, &vec); + } + SampleManager.SetStreamedVolumeAndPan(emittingVol, pan, 1, slot + 1); + } + SampleManager.StartPreloadedStreamedFile(slot + 1); + } + m_sMissionAudio.m_nPlayStatus[slot] = PLAY_STATUS_PLAYING; + nCheckPlayingDelay[slot] = 30; + if (m_sMissionAudio.m_nSampleIndex[slot] >= STREAMED_SOUND_MISSION_MOB_01A && m_sMissionAudio.m_nSampleIndex[slot] <= STREAMED_SOUND_MISSION_MOB_99A) + m_sMissionAudio.m_bIsMobile[slot] = true; + break; + case PLAY_STATUS_PLAYING: + if (m_bTimerJustReset) { + ClearMissionAudio(slot); + SampleManager.StopStreamedFile(slot + 1); + break; + } + if (MissionScriptAudioUsesPoliceChannel(m_sMissionAudio.m_nSampleIndex[slot])) { + if (!m_nUserPause) { + if (nCheckPlayingDelay[slot]) { + --nCheckPlayingDelay[slot]; + } else if (GetMissionScriptPoliceAudioPlayingStatus() == PLAY_STATUS_FINISHED || m_sMissionAudio.m_nMissionAudioCounter[slot]-- == 0) { + m_sMissionAudio.m_nPlayStatus[slot] = PLAY_STATUS_FINISHED; + m_sMissionAudio.m_nSampleIndex[slot] = NO_SAMPLE; + SampleManager.StopStreamedFile(slot + 1); + m_sMissionAudio.m_nMissionAudioCounter[slot] = 0; + } + } + } else if (m_sMissionAudio.m_bIsPlaying[slot]) { + if (SampleManager.IsStreamPlaying(slot + 1) || m_nUserPause || m_nPreviousUserPause) { + if (m_nUserPause) + SampleManager.PauseStream(1, slot + 1); + else + { + SampleManager.PauseStream(0, slot + 1); + if (!m_sMissionAudio.m_bPredefinedProperties[slot]) { + distSquared = GetDistanceSquared(m_sMissionAudio.m_vecPos[slot]); + if (distSquared >= SQR(80.0f)) { + emittingVol = 0; + pan = 63; + } else { + emittingVol = 127; + if (distSquared > 0.0f) { + dist = Sqrt(distSquared); + emittingVol = ComputeVolume(127, 80.0f, dist); + } + TranslateEntity(&m_sMissionAudio.m_vecPos[slot], &vec); + pan = ComputePan(80.f, &vec); + } + SampleManager.SetStreamedVolumeAndPan(emittingVol, pan, 1, slot + 1); + } + } + } else if (m_sMissionAudio.m_nSampleIndex[slot] == STREAMED_SOUND_MISSION_ROK2_01) { + m_sMissionAudio.m_nPlayStatus[slot] = PLAY_STATUS_STOPPED; + } else { + m_sMissionAudio.m_nPlayStatus[slot] = PLAY_STATUS_FINISHED; + if (m_sMissionAudio.m_nSampleIndex[slot] >= STREAMED_SOUND_MISSION_MOB_01A && m_sMissionAudio.m_nSampleIndex[slot] <= STREAMED_SOUND_MISSION_MOB_99A) + m_sMissionAudio.m_bIsMobile[slot] = false; + m_sMissionAudio.m_nSampleIndex[slot] = NO_SAMPLE; + SampleManager.StopStreamedFile(slot + 1); + m_sMissionAudio.m_nMissionAudioCounter[slot] = 0; + } + } else { + if (m_nUserPause) + break; + if (nCheckPlayingDelay[slot]--) { + if (!SampleManager.IsStreamPlaying(slot + 1)) + break; + nCheckPlayingDelay[slot] = 0; + } + m_sMissionAudio.m_bIsPlaying[slot] = true; + } + break; + default: + break; + } + break; + case LOADING_STATUS_FAILED: + if (++nFramesUntilFailedLoad[slot] >= 120) { + nFramesForPretendPlaying[slot] = 0; + g_bMissionAudioLoadFailed[slot] = true; + nFramesUntilFailedLoad[slot] = 0; + m_sMissionAudio.m_nLoadingStatus[slot] = LOADING_STATUS_LOADED; + } + break; + default: + break; + } +} + +void +cAudioManager::ProcessMissionAudio() +{ + if (!m_bIsInitialised) return; + + for (int i = 0; i < MISSION_AUDIO_SLOTS; i++) + ProcessMissionAudioSlot(i); + + if (m_sMissionAudio.m_bIsMobile[0] || m_sMissionAudio.m_bIsMobile[1]) + field_5538 = 64; + else if (field_5538 < 127) { + field_5538 += 5; + if (field_5538 > 127) + field_5538 = 127; + } +} +#pragma endregion All the mission audio stuff diff --git a/src/audio/AudioManager.cpp b/src/audio/AudioManager.cpp new file mode 100644 index 0000000..2304b4c --- /dev/null +++ b/src/audio/AudioManager.cpp @@ -0,0 +1,1086 @@ +#include "common.h" + +#include "AudioManager.h" +#include "audio_enums.h" + +#include "AudioScriptObject.h" +#include "MusicManager.h" +#include "Timer.h" +#include "DMAudio.h" +#include "sampman.h" +#include "Camera.h" +#include "World.h" +#include "ZoneCull.h" + +cAudioManager AudioManager; + +const int channels = ARRAY_SIZE(AudioManager.m_asActiveSamples); +const int policeChannel = channels + 1; +const int allChannels = channels + 2; + +#define SPEED_OF_SOUND 343.f +#define TIME_SPENT 40 + +cAudioManager::cAudioManager() +{ + m_bIsInitialised = false; + m_bReverb = true; + field_6 = 0; + m_fSpeedOfSound = SPEED_OF_SOUND / TIME_SPENT; + m_nTimeSpent = TIME_SPENT; + m_nActiveSamples = NUM_SOUNDS_SAMPLES_SLOTS; + m_nActiveSampleQueue = 1; + ClearRequestedQueue(); + m_nActiveSampleQueue = 0; + ClearRequestedQueue(); + ClearActiveSamples(); + GenerateIntegerRandomNumberTable(); + field_4 = 0; + m_bDynamicAcousticModelingStatus = true; + + for (int i = 0; i < NUM_AUDIOENTITIES; i++) { + m_asAudioEntities[i].m_bIsUsed = false; + m_anAudioEntityIndices[i] = NUM_AUDIOENTITIES; + } + m_nAudioEntitiesTotal = 0; + m_FrameCounter = 0; + m_bFifthFrameFlag = false; + m_bTimerJustReset = false; + m_nTimer = 0; +} + +cAudioManager::~cAudioManager() +{ + if (m_bIsInitialised) + Terminate(); +} + +void +cAudioManager::Initialise() +{ + if (!m_bIsInitialised) { + PreInitialiseGameSpecificSetup(); + m_bIsInitialised = SampleManager.Initialise(); + if (m_bIsInitialised) { + m_nActiveSamples = SampleManager.GetMaximumSupportedChannels(); + if (m_nActiveSamples <= 1) { + Terminate(); + } else { + --m_nActiveSamples; + PostInitialiseGameSpecificSetup(); + InitialisePoliceRadioZones(); + InitialisePoliceRadio(); + MusicManager.Initialise(); + } + } + } +} + +void +cAudioManager::Terminate() +{ + if (m_bIsInitialised) { + MusicManager.Terminate(); + + for (uint32 i = 0; i < NUM_AUDIOENTITIES; i++) { + m_asAudioEntities[i].m_bIsUsed = false; + m_anAudioEntityIndices[i] = ARRAY_SIZE(m_anAudioEntityIndices); + } + + m_nAudioEntitiesTotal = 0; + m_sAudioScriptObjectManager.m_nScriptObjectEntityTotal = 0; + PreTerminateGameSpecificShutdown(); + + for (uint32 i = 0; i < MAX_SFX_BANKS; i++) { + if (SampleManager.IsSampleBankLoaded(i)) + SampleManager.UnloadSampleBank(i); + } + + SampleManager.Terminate(); + + m_bIsInitialised = false; + PostTerminateGameSpecificShutdown(); + } +} + +void +cAudioManager::Service() +{ + GenerateIntegerRandomNumberTable(); + if (m_bTimerJustReset) { + ResetAudioLogicTimers(m_nTimer); + MusicManager.ResetTimers(m_nTimer); + m_bTimerJustReset = false; + } + if (m_bIsInitialised) { + m_nPreviousUserPause = m_nUserPause; + m_nUserPause = CTimer::GetIsUserPaused(); + UpdateReflections(); + ServiceSoundEffects(); + MusicManager.Service(); + } +} + +int32 +cAudioManager::CreateEntity(eAudioType type, void *entity) +{ + if (!m_bIsInitialised) + return AEHANDLE_ERROR_NOAUDIOSYS; + if (!entity) + return AEHANDLE_ERROR_NOENTITY; + if (type >= TOTAL_AUDIO_TYPES) + return AEHANDLE_ERROR_BADAUDIOTYPE; + for (uint32 i = 0; i < ARRAY_SIZE(m_asAudioEntities); i++) { + if (!m_asAudioEntities[i].m_bIsUsed) { + m_asAudioEntities[i].m_bIsUsed = true; + m_asAudioEntities[i].m_bStatus = false; + m_asAudioEntities[i].m_nType = type; + m_asAudioEntities[i].m_pEntity = entity; + m_asAudioEntities[i].m_awAudioEvent[0] = SOUND_NO_SOUND; + m_asAudioEntities[i].m_awAudioEvent[1] = SOUND_NO_SOUND; + m_asAudioEntities[i].m_awAudioEvent[2] = SOUND_NO_SOUND; + m_asAudioEntities[i].m_awAudioEvent[3] = SOUND_NO_SOUND; + m_asAudioEntities[i].m_AudioEvents = 0; + m_anAudioEntityIndices[m_nAudioEntitiesTotal++] = i; + return i; + } + } + return AEHANDLE_ERROR_NOFREESLOT; +} + +void +cAudioManager::DestroyEntity(int32 id) +{ + if (m_bIsInitialised && id >= 0 && id < NUM_AUDIOENTITIES && m_asAudioEntities[id].m_bIsUsed) { + m_asAudioEntities[id].m_bIsUsed = false; + for (int32 i = 0; i < m_nAudioEntitiesTotal; ++i) { + if (id == m_anAudioEntityIndices[i]) { + if (i < NUM_AUDIOENTITIES - 1) + memmove(&m_anAudioEntityIndices[i], &m_anAudioEntityIndices[i + 1], NUM_AUDIOENTITY_EVENTS * (m_nAudioEntitiesTotal - (i + 1))); + m_anAudioEntityIndices[--m_nAudioEntitiesTotal] = NUM_AUDIOENTITIES; + return; + } + } + } +} + +void +cAudioManager::SetEntityStatus(int32 id, uint8 status) +{ + if (m_bIsInitialised && id >= 0 && id < NUM_AUDIOENTITIES && m_asAudioEntities[id].m_bIsUsed) + m_asAudioEntities[id].m_bStatus = status; +} + +void +cAudioManager::PlayOneShot(int32 index, uint16 sound, float vol) +{ + static const uint8 OneShotPriority[] = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 4, 2, 5, 5, 3, 5, 2, 2, 1, 1, 3, 1, 3, 3, 1, 1, 1, 1, 4, 4, 4, 3, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 6, 1, 1, 1, 1, 1, 1, 3, 4, 2, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 3, 1, 1, 1, 9, 0, 0, 0, 1, 2, 2, 0, 0, 2, 3, 3, 3, 5, 1, 1, + 1, 1, 1, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 4, 7, 1, 4, 3, 4, 2, 2, 2, 3, 1, 2, 1, 3, 5, 3, 4, 6, 4, 6, 3, 0, 0, 0, 0, 0, + 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 3, 1, 1, 2, 1, 1, 0, 0, 0, 0, 0, 3, 3, 1, 0 }; + + if (m_bIsInitialised) { + if (index >= 0 && index < NUM_AUDIOENTITIES) { + tAudioEntity &entity = m_asAudioEntities[index]; + if (entity.m_bIsUsed) { + if (sound < SOUND_TOTAL_SOUNDS) { + if (entity.m_nType == AUDIOTYPE_SCRIPTOBJECT) { + if (m_sAudioScriptObjectManager.m_nScriptObjectEntityTotal < ARRAY_SIZE(m_sAudioScriptObjectManager.m_anScriptObjectEntityIndices)) { + entity.m_awAudioEvent[0] = sound; + entity.m_AudioEvents = 1; + m_sAudioScriptObjectManager.m_anScriptObjectEntityIndices[m_sAudioScriptObjectManager.m_nScriptObjectEntityTotal++] = index; + } + } else { + int32 i = 0; + while (true) { + if (i >= entity.m_AudioEvents) { + if (entity.m_AudioEvents < ARRAY_SIZE(entity.m_awAudioEvent)) { + entity.m_awAudioEvent[i] = sound; + entity.m_afVolume[i] = vol; + ++entity.m_AudioEvents; + } + return; + } + if (OneShotPriority[entity.m_awAudioEvent[i]] > OneShotPriority[sound]) + break; + ++i; + } + if (i < NUM_AUDIOENTITY_EVENTS - 1) { + memmove(&entity.m_awAudioEvent[i + 1], &entity.m_awAudioEvent[i], (NUM_AUDIOENTITY_EVENTS - 1 - i) * NUM_AUDIOENTITY_EVENTS / 2); + memmove(&entity.m_afVolume[i + 1], &entity.m_afVolume[i], (NUM_AUDIOENTITY_EVENTS - 1 - i) * NUM_AUDIOENTITY_EVENTS); + } + entity.m_awAudioEvent[i] = sound; + entity.m_afVolume[i] = vol; + if (entity.m_AudioEvents < ARRAY_SIZE(entity.m_awAudioEvent)) + ++entity.m_AudioEvents; + } + } + } + } + } +} + +void +cAudioManager::SetMP3BoostVolume(uint8 volume) const +{ + SampleManager.SetMP3BoostVolume(volume); +} + +void +cAudioManager::SetEffectsMasterVolume(uint8 volume) const +{ + SampleManager.SetEffectsMasterVolume(volume); +} + +void +cAudioManager::SetMusicMasterVolume(uint8 volume) const +{ + SampleManager.SetMusicMasterVolume(volume); +} + +void +cAudioManager::SetEffectsFadeVol(uint8 volume) const +{ + SampleManager.SetEffectsFadeVolume(volume); +} + +void +cAudioManager::SetMonoMode(uint8 mono) +{ + SampleManager.SetMonoMode(mono); +} + +void +cAudioManager::SetMusicFadeVol(uint8 volume) const +{ + SampleManager.SetMusicFadeVolume(volume); +} + +void +cAudioManager::ResetTimers(uint32 time) +{ + if (m_bIsInitialised) { + m_bTimerJustReset = true; + m_nTimer = time; + ClearRequestedQueue(); + if (m_nActiveSampleQueue) { + m_nActiveSampleQueue = 0; + ClearRequestedQueue(); + m_nActiveSampleQueue = 1; + } else { + m_nActiveSampleQueue = 1; + ClearRequestedQueue(); + m_nActiveSampleQueue = 0; + } + ClearActiveSamples(); + ClearMissionAudio(0); + ClearMissionAudio(1); + SampleManager.StopChannel(policeChannel); + SampleManager.SetEffectsFadeVolume(0); + SampleManager.SetMusicFadeVolume(0); + MusicManager.ResetMusicAfterReload(); + m_bIsPlayerShutUp = false; +#ifdef AUDIO_OAL + SampleManager.Service(); +#endif + } +} + +void +cAudioManager::DestroyAllGameCreatedEntities() +{ + cAudioScriptObject *entity; + + if (m_bIsInitialised) { + for (uint32 i = 0; i < ARRAY_SIZE(m_asAudioEntities); i++) { + if (m_asAudioEntities[i].m_bIsUsed) { + switch (m_asAudioEntities[i].m_nType) { + case AUDIOTYPE_PHYSICAL: + case AUDIOTYPE_EXPLOSION: + case AUDIOTYPE_WEATHER: + //case AUDIOTYPE_CRANE: + case AUDIOTYPE_GARAGE: + case AUDIOTYPE_FIREHYDRANT: + DestroyEntity(i); + break; + case AUDIOTYPE_SCRIPTOBJECT: + entity = (cAudioScriptObject *)m_asAudioEntities[i].m_pEntity; + if (entity) { + delete entity; + m_asAudioEntities[i].m_pEntity = nil; + } + DestroyEntity(i); + break; + default: + break; + } + } + } + m_sAudioScriptObjectManager.m_nScriptObjectEntityTotal = 0; + } +} + +uint8 +cAudioManager::GetNum3DProvidersAvailable() const +{ + if (m_bIsInitialised) + return SampleManager.GetNum3DProvidersAvailable(); + return 0; +} + +char * +cAudioManager::Get3DProviderName(uint8 id) const +{ + if (!m_bIsInitialised) + return nil; +#ifdef AUDIO_OAL + id = clamp(id, 0, SampleManager.GetNum3DProvidersAvailable() - 1); +#else + // We don't want that either since it will crash the game, but skipping for now + if (id >= SampleManager.GetNum3DProvidersAvailable()) + return nil; +#endif + return SampleManager.Get3DProviderName(id); +} + +int8 +cAudioManager::GetCurrent3DProviderIndex() const +{ + if (m_bIsInitialised) + return SampleManager.GetCurrent3DProviderIndex(); + + return -1; +} + +int8 +cAudioManager::AutoDetect3DProviders() const +{ + if (m_bIsInitialised) + return SampleManager.AutoDetect3DProviders(); + + return -1; +} + +int8 +cAudioManager::SetCurrent3DProvider(uint8 which) +{ + if (!m_bIsInitialised) + return -1; + for (uint8 i = 0; i < m_nActiveSamples + 1; ++i) + SampleManager.StopChannel(i); + ClearRequestedQueue(); + if (m_nActiveSampleQueue == 0) + m_nActiveSampleQueue = 1; + else + m_nActiveSampleQueue = 0; + ClearRequestedQueue(); + ClearActiveSamples(); + int8 current = SampleManager.SetCurrent3DProvider(which); + if (current > 0) { + m_nActiveSamples = SampleManager.GetMaximumSupportedChannels(); + if (m_nActiveSamples > 1) + --m_nActiveSamples; + } + return current; +} + +void +cAudioManager::SetSpeakerConfig(int32 conf) const +{ + SampleManager.SetSpeakerConfig(conf); +} + +bool +cAudioManager::IsMP3RadioChannelAvailable() const +{ + if (m_bIsInitialised) + return SampleManager.IsMP3RadioChannelAvailable(); + + return false; +} + +void +cAudioManager::ReleaseDigitalHandle() const +{ + if (m_bIsInitialised) { + SampleManager.ReleaseDigitalHandle(); + } +} + +void +cAudioManager::ReacquireDigitalHandle() const +{ + if (m_bIsInitialised) { + SampleManager.ReacquireDigitalHandle(); + } +} + +void +cAudioManager::SetDynamicAcousticModelingStatus(uint8 status) +{ + m_bDynamicAcousticModelingStatus = status!=0; +} + +bool +cAudioManager::CheckForAnAudioFileOnCD() const +{ + return SampleManager.CheckForAnAudioFileOnCD(); +} + +uint8 +cAudioManager::GetCDAudioDriveLetter() const +{ + if(m_bIsInitialised) return SampleManager.GetCDAudioDriveLetter(); + return 0; +} + +bool +cAudioManager::IsAudioInitialised() const +{ + return m_bIsInitialised; +} + +void +cAudioManager::ServiceSoundEffects() +{ + m_bFifthFrameFlag = (m_FrameCounter++ % 5) == 0; + if (m_nUserPause && !m_nPreviousUserPause) { + for (int32 i = 0; i < allChannels; i++) + SampleManager.StopChannel(i); + + ClearRequestedQueue(); + if (m_nActiveSampleQueue) { + m_nActiveSampleQueue = 0; + ClearRequestedQueue(); + m_nActiveSampleQueue = 1; + } else { + m_nActiveSampleQueue = 1; + ClearRequestedQueue(); + m_nActiveSampleQueue = 0; + } + ClearActiveSamples(); + } + m_nActiveSampleQueue = m_nActiveSampleQueue == 1 ? 0 : 1; + if(m_bReverb) ProcessReverb(); + ProcessSpecial(); + ClearRequestedQueue(); + InterrogateAudioEntities(); + m_sPedComments.Process(); + ServicePoliceRadio(); + ServiceCollisions(); + AddReleasingSounds(); + ProcessMissionAudio(); +#ifdef GTA_PC + AdjustSamplesVolume(); +#endif + ProcessActiveQueues(); +#ifdef AUDIO_OAL + SampleManager.Service(); +#endif + for (int32 i = 0; i < m_sAudioScriptObjectManager.m_nScriptObjectEntityTotal; ++i) { + cAudioScriptObject *object = (cAudioScriptObject *)m_asAudioEntities[m_sAudioScriptObjectManager.m_anScriptObjectEntityIndices[i]].m_pEntity; + delete object; + m_asAudioEntities[m_sAudioScriptObjectManager.m_anScriptObjectEntityIndices[i]].m_pEntity = nil; + DestroyEntity(m_sAudioScriptObjectManager.m_anScriptObjectEntityIndices[i]); + } + m_sAudioScriptObjectManager.m_nScriptObjectEntityTotal = 0; +} + +uint8 +cAudioManager::ComputeVolume(uint8 emittingVolume, float soundIntensity, float distance) const +{ + float newSoundIntensity; + float newEmittingVolume; + + if (soundIntensity <= 0.0f) + return 0; + + newSoundIntensity = soundIntensity / 5.0f; + if (newSoundIntensity > distance) + return emittingVolume; + + newEmittingVolume = emittingVolume * SQR((soundIntensity - newSoundIntensity - (distance - newSoundIntensity)) + / (soundIntensity - newSoundIntensity)); + return Min(127u, newEmittingVolume); +} + +void +cAudioManager::TranslateEntity(Const CVector *in, CVector *out) const +{ + *out = MultiplyInverse(TheCamera.GetMatrix(), *in); +} + +int32 +cAudioManager::ComputePan(float dist, CVector *vec) +{ + const uint8 PanTable[64] = { 0, 3, 8, 12, 16, 19, 22, 24, 26, 28, 30, 31, 33, 34, 36, 37, 39, 40, 41, 42, 44, 45, 46, 47, 48, 49, 49, 50, 51, 52, 53, 53, + 54, 55, 55, 56, 56, 57, 57, 58, 58, 58, 59, 59, 59, 60, 60, 61, 61, 61, 61, 62, 62, 62, 62, 62, 63, 63, 63, 63, 63, 63, 63, 63}; + int32 index = Min(63, Abs(int32(vec->x / (dist / 64.f)))); + + if (vec->x > 0.f) + return Max(20, 63 - PanTable[index]); + return Min(107, PanTable[index] + 63); +} + +uint32 +cAudioManager::ComputeDopplerEffectedFrequency(uint32 oldFreq, float position1, float position2, float speedMultiplier) const +{ + uint32 newFreq = oldFreq; + if (!TheCamera.Get_Just_Switched_Status() && speedMultiplier != 0.0f) { + float dist = position2 - position1; + if (dist != 0.0f) { + float speedOfSource = (dist / m_nTimeSpent) * speedMultiplier; + if (m_fSpeedOfSound > Abs(speedOfSource)) { + speedOfSource = clamp2(speedOfSource, 0.0f, 1.5f); + newFreq = (oldFreq * m_fSpeedOfSound) / (speedOfSource + m_fSpeedOfSound); + } + } + } + return newFreq; +} + +int32 +cAudioManager::RandomDisplacement(uint32 seed) const +{ + int32 value; + + static bool bPos = true; + static uint32 Adjustment = 0; + + if (!seed) + return 0; + + value = m_anRandomTable[(Adjustment + seed) % 5] % seed; + Adjustment += value; + + if (value % 2) { + bPos = !bPos; + } + if (!bPos) + value = -value; + return value; +} + +void +cAudioManager::InterrogateAudioEntities() +{ + for (int32 i = 0; i < m_nAudioEntitiesTotal; i++) { + ProcessEntity(m_anAudioEntityIndices[i]); + m_asAudioEntities[m_anAudioEntityIndices[i]].m_AudioEvents = 0; + } +} + +void +cAudioManager::AddSampleToRequestedQueue() +{ + int32 calculatedVolume; + uint8 sampleIndex; + bool bReflections; + + if (m_sQueueSample.m_nSampleIndex < TOTAL_AUDIO_SAMPLES) { + calculatedVolume = m_sQueueSample.m_nReleasingVolumeModificator * (MAX_VOLUME - m_sQueueSample.m_nVolume); + sampleIndex = m_SampleRequestQueuesStatus[m_nActiveSampleQueue]; + if (sampleIndex >= m_nActiveSamples) { + sampleIndex = m_abSampleQueueIndexTable[m_nActiveSampleQueue][m_nActiveSamples - 1]; + if (m_asSamples[m_nActiveSampleQueue][sampleIndex].m_nCalculatedVolume <= calculatedVolume) + return; + } else { + ++m_SampleRequestQueuesStatus[m_nActiveSampleQueue]; + } + m_sQueueSample.m_nCalculatedVolume = calculatedVolume; + m_sQueueSample.m_bLoopEnded = false; + if (m_sQueueSample.m_bIs2D || CCullZones::InRoomForAudio()) { + m_sQueueSample.m_bRequireReflection = false; + m_sQueueSample.m_nLoopsRemaining = 0; + } + if (m_bDynamicAcousticModelingStatus && m_sQueueSample.m_nLoopCount) { + bReflections = m_sQueueSample.m_bRequireReflection; + } else { + bReflections = false; + m_sQueueSample.m_nLoopsRemaining = 0; + } + m_sQueueSample.m_bRequireReflection = false; + + if ( m_bReverb && m_sQueueSample.m_bIs2D ) + m_sQueueSample.field_4C = 30; + + if (!m_bDynamicAcousticModelingStatus) + m_sQueueSample.m_bReverbFlag = false; + + m_asSamples[m_nActiveSampleQueue][sampleIndex] = m_sQueueSample; + + AddDetailsToRequestedOrderList(sampleIndex); + if (bReflections) + AddReflectionsToRequestedQueue(); + } +} +void +cAudioManager::AddDetailsToRequestedOrderList(uint8 sample) +{ + uint32 i = 0; + if (sample != 0) { + for (; i < sample; i++) { + if (m_asSamples[m_nActiveSampleQueue][m_abSampleQueueIndexTable[m_nActiveSampleQueue][i]].m_nCalculatedVolume > + m_asSamples[m_nActiveSampleQueue][sample].m_nCalculatedVolume) + break; + } + if (i < sample) { + memmove(&m_abSampleQueueIndexTable[m_nActiveSampleQueue][i + 1], &m_abSampleQueueIndexTable[m_nActiveSampleQueue][i], m_nActiveSamples - i - 1); + } + } + m_abSampleQueueIndexTable[m_nActiveSampleQueue][i] = sample; +} + +void +cAudioManager::AddReflectionsToRequestedQueue() +{ +#ifdef FIX_BUGS + uint32 oldFreq = 0; +#else + uint32 oldFreq; +#endif + float reflectionDistance; + int32 noise; + uint8 emittingVolume; + + uint32 oldCounter = m_sQueueSample.m_nCounter; + float oldDist = m_sQueueSample.m_fDistance; + CVector oldPos = m_sQueueSample.m_vecPos; + if ( CTimer::GetIsSlowMotionActive() ) { + emittingVolume = m_sQueueSample.m_nVolume; + oldFreq = m_sQueueSample.m_nFrequency; + } else { + emittingVolume = (9 * m_sQueueSample.m_nVolume) / 16; + } + m_sQueueSample.m_fSoundIntensity /= 2.f; + + int halfOldFreq = oldFreq >> 1; + + for (uint32 i = 0; i < ARRAY_SIZE(m_afReflectionsDistances); i++) { + if ( CTimer::GetIsSlowMotionActive() ) + m_afReflectionsDistances[i] = GetRandomNumberInRange(i % 4, 0, 2) * 100.f / 8.f; + + reflectionDistance = m_afReflectionsDistances[i]; + if (reflectionDistance > 0.0f && reflectionDistance < 100.f && reflectionDistance < m_sQueueSample.m_fSoundIntensity) { + m_sQueueSample.m_nLoopsRemaining = CTimer::GetIsSlowMotionActive() ? (reflectionDistance * 800.f / 1029.f) : (reflectionDistance * 500.f / 1029.f); + if (m_sQueueSample.m_nLoopsRemaining > 3) { + m_sQueueSample.m_fDistance = m_afReflectionsDistances[i]; + m_sQueueSample.m_nEmittingVolume = emittingVolume; + m_sQueueSample.m_nVolume = ComputeVolume(emittingVolume, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); + + if (m_sQueueSample.m_nVolume > emittingVolume / 16) { + m_sQueueSample.m_nCounter = oldCounter + (i + 1) * 256; + if (m_sQueueSample.m_nLoopCount) { + if ( CTimer::GetIsSlowMotionActive() ) { + m_sQueueSample.m_nFrequency = halfOldFreq + ((halfOldFreq * i) / ARRAY_SIZE(m_afReflectionsDistances)); + } else { + noise = RandomDisplacement(m_sQueueSample.m_nFrequency / 32); + if (noise <= 0) + m_sQueueSample.m_nFrequency += noise; + else + m_sQueueSample.m_nFrequency -= noise; + } + } + m_sQueueSample.m_nReleasingVolumeModificator += 20; + m_sQueueSample.m_vecPos = m_avecReflectionsPos[i]; + AddSampleToRequestedQueue(); + } + } + } + } + m_sQueueSample.m_vecPos = oldPos; + m_sQueueSample.m_fDistance = oldDist; +} + +void +cAudioManager::UpdateReflections() +{ + CVector camPos = TheCamera.GetPosition(); + CColPoint colpoint; + CEntity *ent; + + if (m_FrameCounter % 8 == 0) { + m_avecReflectionsPos[0] = camPos; + m_avecReflectionsPos[0].y += 100.f; + if (CWorld::ProcessLineOfSight(camPos, m_avecReflectionsPos[0], colpoint, ent, true, false, false, true, false, true, true)) + m_afReflectionsDistances[0] = Distance(camPos, colpoint.point); + else + m_afReflectionsDistances[0] = 100.0f; + + } else if ((m_FrameCounter + 1) % 8 == 0) { + m_avecReflectionsPos[1] = camPos; + m_avecReflectionsPos[1].y -= 100.0f; + if (CWorld::ProcessLineOfSight(camPos, m_avecReflectionsPos[1], colpoint, ent, true, false, false, true, false, true, true)) + m_afReflectionsDistances[1] = Distance(camPos, colpoint.point); + else + m_afReflectionsDistances[1] = 100.0f; + + } else if ((m_FrameCounter + 2) % 8 == 0) { + m_avecReflectionsPos[2] = camPos; + m_avecReflectionsPos[2].x -= 100.0f; + if (CWorld::ProcessLineOfSight(camPos, m_avecReflectionsPos[2], colpoint, ent, true, false, false, true, false, true, true)) + m_afReflectionsDistances[2] = Distance(camPos, colpoint.point); + else + m_afReflectionsDistances[2] = 100.0f; + + } else if ((m_FrameCounter + 3) % 8 == 0) { + m_avecReflectionsPos[3] = camPos; + m_avecReflectionsPos[3].x += 100.0f; + if (CWorld::ProcessLineOfSight(camPos, m_avecReflectionsPos[3], colpoint, ent, true, false, false, true, false, true, true)) + m_afReflectionsDistances[3] = Distance(camPos, colpoint.point); + else + m_afReflectionsDistances[3] = 100.0f; + + } else if ((m_FrameCounter + 4) % 8 == 0) { + camPos.y += 1.0f; + m_avecReflectionsPos[4] = camPos; + m_avecReflectionsPos[4].z += 100.0f; + if (CWorld::ProcessVerticalLine(camPos, m_avecReflectionsPos[4].z, colpoint, ent, true, false, false, false, true, false, nil)) + m_afReflectionsDistances[4] = colpoint.point.z - camPos.z; + else + m_afReflectionsDistances[4] = 100.0f; + + } else if ((m_FrameCounter + 5) % 8 == 0) { + camPos.y -= 1.0f; + m_avecReflectionsPos[5] = camPos; + m_avecReflectionsPos[5].z += 100.0f; + if (CWorld::ProcessVerticalLine(camPos, m_avecReflectionsPos[5].z, colpoint, ent, true, false, false, false, true, false, nil)) + m_afReflectionsDistances[5] = colpoint.point.z - camPos.z; + else + m_afReflectionsDistances[5] = 100.0f; + + } else if ((m_FrameCounter + 6) % 8 == 0) { + camPos.x -= 1.0f; + m_avecReflectionsPos[6] = camPos; + m_avecReflectionsPos[6].z += 100.0f; + if (CWorld::ProcessVerticalLine(camPos, m_avecReflectionsPos[6].z, colpoint, ent, true, false, false, false, true, false, nil)) + m_afReflectionsDistances[6] = colpoint.point.z - camPos.z; + else + m_afReflectionsDistances[6] = 100.0f; + + } else if ((m_FrameCounter + 7) % 8 == 0) { + camPos.x += 1.0f; + m_avecReflectionsPos[7] = camPos; + m_avecReflectionsPos[7].z += 100.0f; + if (CWorld::ProcessVerticalLine(camPos, m_avecReflectionsPos[7].z, colpoint, ent, true, false, false, false, true, false, nil)) + m_afReflectionsDistances[7] = colpoint.point.z - camPos.z; + else + m_afReflectionsDistances[7] = 100.0f; + } +} + +void +cAudioManager::AddReleasingSounds() +{ + bool toProcess[44]; // why not 27? + + int8 queue = m_nActiveSampleQueue == 0 ? 1 : 0; + + for (int32 i = 0; i < m_SampleRequestQueuesStatus[queue]; i++) { + tSound &sample = m_asSamples[queue][m_abSampleQueueIndexTable[queue][i]]; + if (sample.m_bLoopEnded) + continue; + + toProcess[i] = false; + for (int32 j = 0; j < m_SampleRequestQueuesStatus[m_nActiveSampleQueue]; j++) { + if (sample.m_nEntityIndex == m_asSamples[m_nActiveSampleQueue][m_abSampleQueueIndexTable[m_nActiveSampleQueue][j]].m_nEntityIndex && + sample.m_nCounter == m_asSamples[m_nActiveSampleQueue][m_abSampleQueueIndexTable[m_nActiveSampleQueue][j]].m_nCounter) { + toProcess[i] = true; + break; + } + } + if (!toProcess[i]) { + if (sample.m_nCounter <= 255 || !sample.m_nLoopsRemaining) { + if (!sample.m_nReleasingVolumeDivider) + continue; + if (!sample.m_nLoopCount) { + if (sample.m_nVolumeChange == -1) { + sample.m_nVolumeChange = sample.m_nVolume / sample.m_nReleasingVolumeDivider; + if (sample.m_nVolumeChange <= 0) + sample.m_nVolumeChange = 1; + } + if (sample.m_nVolume <= sample.m_nVolumeChange) { + sample.m_nReleasingVolumeDivider = 0; + continue; + } + sample.m_nVolume -= sample.m_nVolumeChange; + } + --sample.m_nReleasingVolumeDivider; + if (m_bFifthFrameFlag) { + if (sample.m_nReleasingVolumeModificator < 20) + ++sample.m_nReleasingVolumeModificator; + } + sample.m_bReleasingSoundFlag = false; + } + memcpy(&m_sQueueSample, &sample, sizeof(tSound)); + AddSampleToRequestedQueue(); + } + } +} + +void +cAudioManager::ProcessActiveQueues() +{ + CVector position; + uint32 freqDivided; + uint32 loopCount; + uint8 emittingVol; + uint8 vol; + uint8 offset; + float x; + bool flag; + bool missionState; + + for (int32 i = 0; i < m_nActiveSamples; i++) { + m_asSamples[m_nActiveSampleQueue][i].m_bIsProcessed = false; + m_asActiveSamples[i].m_bIsProcessed = false; + } + for (int32 i = 0; i < m_SampleRequestQueuesStatus[m_nActiveSampleQueue]; i++) { + tSound& sample = m_asSamples[m_nActiveSampleQueue][m_abSampleQueueIndexTable[m_nActiveSampleQueue][i]]; + if (sample.m_nSampleIndex != NO_SAMPLE) { + for (int32 j = 0; j < m_nActiveSamples; j++) { + if (sample.m_nEntityIndex == m_asActiveSamples[j].m_nEntityIndex && + sample.m_nCounter == m_asActiveSamples[j].m_nCounter && + sample.m_nSampleIndex == m_asActiveSamples[j].m_nSampleIndex) { + if (sample.m_nLoopCount) { + + if (m_FrameCounter & 1) { + if (!(j & 1)) { + flag = false; + } else { + flag = true; + } + } else if (j & 1) { + flag = false; + } else { + flag = true; + } + + if (flag && !SampleManager.GetChannelUsedFlag(j)) { + sample.m_bLoopEnded = true; + m_asActiveSamples[j].m_bLoopEnded = true; + m_asActiveSamples[j].m_nSampleIndex = NO_SAMPLE; + m_asActiveSamples[j].m_nEntityIndex = AEHANDLE_NONE; + continue; + } + if (!sample.m_nReleasingVolumeDivider) + sample.m_nReleasingVolumeDivider = 1; + } + sample.m_bIsProcessed = true; + m_asActiveSamples[j].m_bIsProcessed = true; + sample.m_nVolumeChange = -1; + if (!sample.m_bReleasingSoundFlag) { + if (sample.m_bIs2D) { + if (field_4) { + emittingVol = 2 * Min(63, sample.m_nEmittingVolume); + } else { + emittingVol = sample.m_nEmittingVolume; + } + SampleManager.SetChannelFrequency(j, sample.m_nFrequency); + SampleManager.SetChannelEmittingVolume(j, emittingVol); + } else { + m_asActiveSamples[j].m_fDistance = sample.m_fDistance; + sample.m_nFrequency = ComputeDopplerEffectedFrequency( + sample.m_nFrequency, + m_asActiveSamples[j].m_fDistance, + sample.m_fDistance, + sample.m_fSpeedMultiplier); + + if (sample.m_nFrequency != m_asActiveSamples[j].m_nFrequency) { + m_asActiveSamples[j].m_nFrequency = clamp2((int32)sample.m_nFrequency, (int32)m_asActiveSamples[j].m_nFrequency, 6000); + SampleManager.SetChannelFrequency(j, m_asActiveSamples[j].m_nFrequency); + } + if (sample.m_nEmittingVolume != m_asActiveSamples[j].m_nEmittingVolume) { + vol = clamp2((int8)sample.m_nEmittingVolume, (int8)m_asActiveSamples[j].m_nEmittingVolume, 10); + + if (field_4) { + emittingVol = 2 * Min(63, vol); + } else { + emittingVol = vol; + } + + missionState = false; + for (int32 k = 0; k < ARRAY_SIZE(m_sMissionAudio.m_bIsMobile); k++) { + if (m_sMissionAudio.m_bIsMobile[k]) { + missionState = true; + break; + } + } + if (missionState) { + emittingVol = (emittingVol * field_5538) / 127; + } else { + if (field_5538 < 127) + emittingVol = (emittingVol * field_5538) / 127; + } + + SampleManager.SetChannelEmittingVolume(j, emittingVol); + m_asActiveSamples[j].m_nEmittingVolume = vol; + } + TranslateEntity(&sample.m_vecPos, &position); + SampleManager.SetChannel3DPosition(j, position.x, position.y, position.z); + SampleManager.SetChannel3DDistances(j, sample.m_fSoundIntensity, 0.25f * sample.m_fSoundIntensity); + } + SampleManager.SetChannelReverbFlag(j, sample.m_bReverbFlag); + break; //continue for i + } + sample.m_bIsProcessed = false; + m_asActiveSamples[j].m_bIsProcessed = false; + //continue for j + } + } + } + } + for (int32 i = 0; i < m_nActiveSamples; i++) { + if (m_asActiveSamples[i].m_nSampleIndex != NO_SAMPLE && !m_asActiveSamples[i].m_bIsProcessed) { + SampleManager.StopChannel(i); + m_asActiveSamples[i].m_nSampleIndex = NO_SAMPLE; + m_asActiveSamples[i].m_nEntityIndex = AEHANDLE_NONE; + } + } + for (uint8 i = 0; i < m_SampleRequestQueuesStatus[m_nActiveSampleQueue]; i++) { + tSound& sample = m_asSamples[m_nActiveSampleQueue][m_abSampleQueueIndexTable[m_nActiveSampleQueue][i]]; + if (!sample.m_bIsProcessed && !sample.m_bLoopEnded && + m_asAudioEntities[sample.m_nEntityIndex].m_bIsUsed && sample.m_nSampleIndex < NO_SAMPLE) { + if (sample.m_nCounter > 255 && sample.m_nLoopCount && sample.m_nLoopsRemaining) { + sample.m_nLoopsRemaining--; + sample.m_nReleasingVolumeDivider = 1; + } else { + for (uint8 j = 0; j < m_nActiveSamples; j++) { + uint8 k = (j + field_6) % m_nActiveSamples; + if (!m_asActiveSamples[k].m_bIsProcessed) { + if (sample.m_nLoopCount != 0) { + freqDivided = sample.m_nFrequency / m_nTimeSpent; + loopCount = sample.m_nLoopCount * SampleManager.GetSampleLength(sample.m_nSampleIndex); + if (freqDivided == 0) + continue; + sample.m_nReleasingVolumeDivider = loopCount / freqDivided + 1; + } + memcpy(&m_asActiveSamples[k], &sample, sizeof(tSound)); + if (!m_asActiveSamples[k].m_bIs2D) + TranslateEntity(&m_asActiveSamples[k].m_vecPos, &position); + if (field_4) { + emittingVol = 2 * Min(63, m_asActiveSamples[k].m_nEmittingVolume); + } else { + emittingVol = m_asActiveSamples[k].m_nEmittingVolume; + } + if (SampleManager.InitialiseChannel(k, m_asActiveSamples[k].m_nSampleIndex, m_asActiveSamples[k].m_nBankIndex)) { + SampleManager.SetChannelFrequency(k, m_asActiveSamples[k].m_nFrequency); + bool isMobile = false; + for (int32 l = 0; l < ARRAY_SIZE(m_sMissionAudio.m_bIsMobile); l++) { + if (m_sMissionAudio.m_bIsMobile[l]) { + isMobile = true; + break; + } + } + if (!isMobile || m_asActiveSamples[k].m_bIs2D) { + if (field_5538 < 127) + emittingVol *= field_5538 / 127; + vol = emittingVol; + } else { + vol = (emittingVol * field_5538 / 127); + } + SampleManager.SetChannelEmittingVolume(k, vol); + SampleManager.SetChannelLoopPoints(k, m_asActiveSamples[k].m_nLoopStart, m_asActiveSamples[k].m_nLoopEnd); + SampleManager.SetChannelLoopCount(k, m_asActiveSamples[k].m_nLoopCount); + SampleManager.SetChannelReverbFlag(k, m_asActiveSamples[k].m_bReverbFlag); + if (m_asActiveSamples[k].m_bIs2D) { + offset = m_asActiveSamples[k].m_nOffset; + if (offset == 63) { + x = 0.0f; + } else if (offset >= 63) { + x = (offset - 63) * 1000.0f / 63; + } else { + x = -(63 - offset) * 1000.0f / 63; //same like line below + } + position = CVector(x, 0.0f, 0.0f); + m_asActiveSamples[k].m_fSoundIntensity = 100000.0f; + } + SampleManager.SetChannel3DPosition(k, position.x, position.y, position.z); + SampleManager.SetChannel3DDistances(k, m_asActiveSamples[k].m_fSoundIntensity, 0.25f * m_asActiveSamples[k].m_fSoundIntensity); + SampleManager.StartChannel(k); + } + m_asActiveSamples[k].m_bIsProcessed = true; + sample.m_bIsProcessed = true; + sample.m_nVolumeChange = -1; + break; + } + } + } + } + } + field_6 %= m_nActiveSamples; +} + +void +cAudioManager::ClearRequestedQueue() +{ + for (int32 i = 0; i < m_nActiveSamples; i++) { + m_abSampleQueueIndexTable[m_nActiveSampleQueue][i] = m_nActiveSamples; + } + m_SampleRequestQueuesStatus[m_nActiveSampleQueue] = 0; +} + +void +cAudioManager::ClearActiveSamples() +{ + for (uint8 i = 0; i < m_nActiveSamples; i++) { + m_asActiveSamples[i].m_nEntityIndex = AEHANDLE_NONE; + m_asActiveSamples[i].m_nCounter = 0; + m_asActiveSamples[i].m_nSampleIndex = NO_SAMPLE; + m_asActiveSamples[i].m_nBankIndex = INVALID_SFX_BANK; + m_asActiveSamples[i].m_bIs2D = false; + m_asActiveSamples[i].m_nReleasingVolumeModificator = 5; + m_asActiveSamples[i].m_nFrequency = 0; + m_asActiveSamples[i].m_nVolume = 0; + m_asActiveSamples[i].m_nEmittingVolume = 0; + m_asActiveSamples[i].m_fDistance = 0.0f; + m_asActiveSamples[i].m_bIsProcessed = false; + m_asActiveSamples[i].m_bLoopEnded = false; + m_asActiveSamples[i].m_nLoopCount = 1; + m_asActiveSamples[i].m_nLoopStart = 0; + m_asActiveSamples[i].m_nLoopEnd = -1; + m_asActiveSamples[i].m_fSpeedMultiplier = 0.0f; + m_asActiveSamples[i].m_fSoundIntensity = 200.0f; + m_asActiveSamples[i].m_nOffset = 63; + m_asActiveSamples[i].m_bReleasingSoundFlag = false; + m_asActiveSamples[i].m_nCalculatedVolume = 0; + m_asActiveSamples[i].m_nReleasingVolumeDivider = 0; + m_asActiveSamples[i].m_nVolumeChange = -1; + m_asActiveSamples[i].m_vecPos = CVector(0.0f, 0.0f, 0.0f); + m_asActiveSamples[i].m_bReverbFlag = false; + m_asActiveSamples[i].m_nLoopsRemaining = 0; + m_asActiveSamples[i].m_bRequireReflection = false; + } +} + +void +cAudioManager::GenerateIntegerRandomNumberTable() +{ + for (int32 i = 0; i < ARRAY_SIZE(m_anRandomTable); i++) { + m_anRandomTable[i] = myrand(); + } +} + +#ifdef GTA_PC +void +cAudioManager::AdjustSamplesVolume() +{ + for (int i = 0; i < m_SampleRequestQueuesStatus[m_nActiveSampleQueue]; i++) { + tSound *pSample = &m_asSamples[m_nActiveSampleQueue][m_abSampleQueueIndexTable[m_nActiveSampleQueue][i] + 1]; + + if (!pSample->m_bIs2D) + pSample->m_nEmittingVolume = ComputeEmittingVolume(pSample->m_nEmittingVolume, pSample->m_fSoundIntensity, pSample->m_fDistance); + } +} + +uint8 +cAudioManager::ComputeEmittingVolume(uint8 emittingVolume, float intensity, float dist) +{ + float quatIntensity = intensity / 4.0f; + float diffIntensity = intensity - quatIntensity; + if (dist > diffIntensity) + return (quatIntensity - (dist - diffIntensity)) * (float)emittingVolume / quatIntensity; + return emittingVolume; +} +#endif diff --git a/src/audio/AudioManager.h b/src/audio/AudioManager.h new file mode 100644 index 0000000..14eacda --- /dev/null +++ b/src/audio/AudioManager.h @@ -0,0 +1,551 @@ +#pragma once + +#include "audio_enums.h" +#include "AudioCollision.h" +#include "PoliceRadio.h" +#include "VehicleModelInfo.h" +#include "Vehicle.h" + +class tSound +{ +public: + int32 m_nEntityIndex; + int32 m_nCounter; + int32 m_nSampleIndex; + uint8 m_nBankIndex; + bool m_bIs2D; + int32 m_nReleasingVolumeModificator; + uint32 m_nFrequency; + uint8 m_nVolume; + float m_fDistance; + int32 m_nLoopCount; + int32 m_nLoopStart; + int32 m_nLoopEnd; + uint8 m_nEmittingVolume; + float m_fSpeedMultiplier; + float m_fSoundIntensity; + bool m_bReleasingSoundFlag; + CVector m_vecPos; + bool m_bReverbFlag; + uint8 m_nLoopsRemaining; + bool m_bRequireReflection; // Used for oneshots + uint8 m_nOffset; + uint8 field_4C; + int32 m_nReleasingVolumeDivider; + bool m_bIsProcessed; + bool m_bLoopEnded; + int32 m_nCalculatedVolume; + int8 m_nVolumeChange; +}; + +VALIDATE_SIZE(tSound, 96); + +class CPhysical; +class CAutomobile; + +class tAudioEntity +{ +public: + eAudioType m_nType; + void *m_pEntity; + bool m_bIsUsed; + uint8 m_bStatus; + int16 m_awAudioEvent[NUM_AUDIOENTITY_EVENTS]; + float m_afVolume[NUM_AUDIOENTITY_EVENTS]; + uint8 m_AudioEvents; +}; + +VALIDATE_SIZE(tAudioEntity, 40); + +class tPedComment +{ +public: + uint32 m_nSampleIndex; + int32 m_nEntityIndex; + CVector m_vecPos; + float m_fDistance; + uint8 m_bVolume; + int8 m_nProcess; +}; + +VALIDATE_SIZE(tPedComment, 28); + +class cPedComments +{ +public: + tPedComment m_asPedComments[NUM_PED_COMMENTS_BANKS][NUM_PED_COMMENTS_SLOTS]; + uint8 m_nIndexMap[NUM_PED_COMMENTS_BANKS][NUM_PED_COMMENTS_SLOTS]; + uint8 m_nCommentsInBank[NUM_PED_COMMENTS_BANKS]; + uint8 m_nActiveBank; +#ifdef GTA_PC + bool m_bDelay; + uint32 m_nDelayTimer; +#endif + + cPedComments() + { + for (int i = 0; i < NUM_PED_COMMENTS_SLOTS; i++) + for (int j = 0; j < NUM_PED_COMMENTS_BANKS; j++) { + m_asPedComments[j][i].m_nProcess = -1; + m_nIndexMap[j][i] = NUM_PED_COMMENTS_SLOTS; + } + + for (int i = 0; i < NUM_PED_COMMENTS_BANKS; i++) + m_nCommentsInBank[i] = 0; + m_nActiveBank = 0; + } + void Add(tPedComment *com); // done + void Process(); // done +}; + +VALIDATE_SIZE(cPedComments, 0x490); + +class CEntity; + +#define MISSION_AUDIO_SLOTS (2) + +// So instead of doing cMissionAudio [2] they've added [2] to every field of the struct... +// Only someone with a VERY EXTRAORDINARY mind could have come up with that +class cMissionAudio +{ +public: + CVector m_vecPos[MISSION_AUDIO_SLOTS]; + bool m_bPredefinedProperties[MISSION_AUDIO_SLOTS]; + int32 m_nSampleIndex[MISSION_AUDIO_SLOTS]; + uint8 m_nLoadingStatus[MISSION_AUDIO_SLOTS]; + uint8 m_nPlayStatus[MISSION_AUDIO_SLOTS]; + bool m_bIsPlaying[MISSION_AUDIO_SLOTS]; + int32 m_nMissionAudioCounter[MISSION_AUDIO_SLOTS]; + bool m_bIsPlayed[MISSION_AUDIO_SLOTS]; + bool m_bIsMobile[MISSION_AUDIO_SLOTS]; +}; +VALIDATE_SIZE(cMissionAudio, 0x38); + +// name made up +class cAudioScriptObjectManager +{ +public: + int32 m_anScriptObjectEntityIndices[NUM_SCRIPT_MAX_ENTITIES]; + int32 m_nScriptObjectEntityTotal; + + cAudioScriptObjectManager() { m_nScriptObjectEntityTotal = 0; } + ~cAudioScriptObjectManager() { m_nScriptObjectEntityTotal = 0; } +}; + + +class cTransmission; +class CPlane; +class CVehicle; +class CPed; + +class cPedParams +{ +public: + bool m_bDistanceCalculated; + float m_fDistance; + CPed *m_pPed; + + cPedParams() + { + m_bDistanceCalculated = false; + m_fDistance = 0.0f; + m_pPed = nil; + } +}; + +class cVehicleParams +{ +public: + int32 m_VehicleType; + bool m_bDistanceCalculated; + float m_fDistance; + CVehicle *m_pVehicle; + cTransmission *m_pTransmission; + int32 m_nIndex; + float m_fVelocityChange; + + cVehicleParams() + { + m_VehicleType = -1; + m_bDistanceCalculated = false; + m_fDistance = 0.0f; + m_pVehicle = nil; + m_pTransmission = nil; + m_nIndex = 0; + m_fVelocityChange = 0.0f; + } +}; + +VALIDATE_SIZE(cVehicleParams, 0x1C); + +enum { + REFLECTION_NORTH = 0, + REFLECTION_SOUTH, + REFLECTION_WEST, + REFLECTION_EAST, + REFLECTION_CEIL_NORTH, + REFLECTION_CEIL_SOUTH, + REFLECTION_CEIL_WEST, + REFLECTION_CEIL_EAST, + MAX_REFLECTIONS, +}; + +class cAudioManager +{ +public: + bool m_bIsInitialised; + uint8 m_bReverb; // unused + bool m_bFifthFrameFlag; + uint8 m_nActiveSamples; + uint8 field_4; // unused + bool m_bDynamicAcousticModelingStatus; + int8 field_6; + float m_fSpeedOfSound; + bool m_bTimerJustReset; + int32 m_nTimer; + tSound m_sQueueSample; + uint8 m_nActiveSampleQueue; + tSound m_asSamples[NUM_SOUNDS_SAMPLES_BANKS][NUM_SOUNDS_SAMPLES_SLOTS]; + uint8 m_abSampleQueueIndexTable[NUM_SOUNDS_SAMPLES_BANKS][NUM_SOUNDS_SAMPLES_SLOTS]; + uint8 m_SampleRequestQueuesStatus[NUM_SOUNDS_SAMPLES_BANKS]; + tSound m_asActiveSamples[NUM_SOUNDS_SAMPLES_SLOTS]; + tAudioEntity m_asAudioEntities[NUM_AUDIOENTITIES]; + int32 m_anAudioEntityIndices[NUM_AUDIOENTITIES]; + int32 m_nAudioEntitiesTotal; + CVector m_avecReflectionsPos[NUM_AUDIO_REFLECTIONS]; + float m_afReflectionsDistances[NUM_AUDIO_REFLECTIONS]; + cAudioScriptObjectManager m_sAudioScriptObjectManager; + + // miami + uint8 m_bIsPlayerShutUp; + uint8 m_nPlayerMood; + uint32 m_nPlayerMoodTimer; + uint8 field_rest[4]; + bool m_bGenericSfx; + + cPedComments m_sPedComments; + int32 m_nFireAudioEntity; + int32 m_nWaterCannonEntity; + int32 m_nPoliceChannelEntity; + cPoliceRadioQueue m_sPoliceRadioQueue; + int32 m_nFrontEndEntity; + int32 m_nCollisionEntity; + cAudioCollisionManager m_sCollisionManager; + int32 m_nProjectileEntity; +#ifdef GTA_BRIDGE + int32 m_nBridgeEntity; +#endif + int32 m_nEscalatorEntity; + int32 m_nExtraSoundsEntity; + cMissionAudio m_sMissionAudio; + uint8 field_5538; // something related to phone dialogues + int32 m_anRandomTable[5]; + uint8 m_nTimeSpent; + uint8 m_nUserPause; + uint8 m_nPreviousUserPause; + uint32 m_FrameCounter; + + cAudioManager(); + ~cAudioManager(); + + // getters + uint32 GetFrameCounter() const { return m_FrameCounter; } // done + float GetReflectionsDistance(int32 idx) const { return m_afReflectionsDistances[idx]; } // done + int32 GetRandomNumber(int32 idx) const { return m_anRandomTable[idx]; } + int32 GetRandomNumberInRange(int32 idx, int32 low, int32 high) const { return (m_anRandomTable[idx] % (high - low + 1)) + low; } + bool IsMissionAudioSamplePlaying(uint8 slot) const; // { return m_sMissionAudio.m_nPlayStatus == 1; } + bool ShouldDuckMissionAudio(uint8 slot) const; + + // "Should" be in alphabetic order, except "getXTalkSfx" + void AddDetailsToRequestedOrderList(uint8 sample); // done (inlined in vc) + void AddPlayerCarSample(uint8 emittingVolume, int32 freq, uint32 sample, uint8 bank, uint8 counter, bool notLooping); // done + void AddReflectionsToRequestedQueue(); // done + void AddReleasingSounds(); // done + void AddSampleToRequestedQueue(); // done + void AgeCrimes(); // done (inlined in vc) + + void CalculateDistance(bool &condition, float dist); // done + bool CheckForAnAudioFileOnCD() const; // done + void ClearActiveSamples(); // done + void ClearMissionAudio(uint8 slot); // done (inlined in vc) + void ClearRequestedQueue(); // done (inlined in vc) + uint32 ComputeDopplerEffectedFrequency(uint32 oldFreq, float position1, float position2, float speedMultiplier) const; // done + int32 ComputePan(float, CVector *); // done + uint8 ComputeVolume(uint8 emittingVolume, float soundIntensity, float distance) const; // done + int32 CreateEntity(eAudioType type, void *entity); // done + + void DestroyAllGameCreatedEntities(); // done + void DestroyEntity(int32 id); // done (inlined in vc) + void DoPoliceRadioCrackle(); // done + + // functions returning talk sfx, + // order from GetPedCommentSfx + uint32 GetPlayerTalkSfx(CPed *ped, int16 sound); + uint32 GetCopTalkSfx(CPed *ped, int16 sound); + uint32 GetSwatTalkSfx(CPed *ped, int16 sound); + uint32 GetFBITalkSfx(CPed *ped, int16 sound); + uint32 GetArmyTalkSfx(CPed *ped, int16 sound); + uint32 GetMedicTalkSfx(CPed *ped, int16 sound); + uint32 GetFiremanTalkSfx(CPed *ped, int16 sound); + uint32 GetDefaultTalkSfx(CPed *ped, int16 sound); + uint32 GetHFYSTTalkSfx(CPed *ped, int16 sound); + uint32 GetHFOSTTalkSfx(CPed *ped, int16 sound); + uint32 GetHMYSTTalkSfx(CPed *ped, int16 sound); + uint32 GetHMOSTTalkSfx(CPed *ped, int16 sound); + uint32 GetHFYRITalkSfx(CPed *ped, int16 sound); + uint32 GetHFORITalkSfx(CPed *ped, int16 sound); + uint32 GetHMYRITalkSfx(CPed *ped, int16 sound); + uint32 GetHMORITalkSfx(CPed *ped, int16 sound); + uint32 GetHFYBETalkSfx(CPed *ped, int16 sound); + uint32 GetHFOBETalkSfx(CPed *ped, int16 sound); + uint32 GetHMYBETalkSfx(CPed *ped, int16 sound); + uint32 GetHMOBETalkSfx(CPed *ped, int16 sound); + uint32 GetHFYBUTalkSfx(CPed *ped, int16 sound); + uint32 GetHFYMDTalkSfx(CPed *ped, int16 sound); + uint32 GetHFYCGTalkSfx(CPed *ped, int16 sound); + uint32 GetHFYPRTalkSfx(CPed *ped, int16 sound); + uint32 GetHFOTRTalkSfx(CPed *ped, int16 sound); + uint32 GetHMOTRTalkSfx(CPed *ped, int16 sound); + uint32 GetHMYAPTalkSfx(CPed *ped, int16 sound); + uint32 GetHMOCATalkSfx(CPed *ped, int16 sound); + uint32 GetBMODKTalkSfx(CPed *ped, int16 sound); + uint32 GetBMYCRTalkSfx(CPed *ped, int16 sound); + uint32 GetBFYSTTalkSfx(CPed *ped, int16 sound); + uint32 GetBFOSTTalkSfx(CPed *ped, int16 sound); + uint32 GetBMYSTTalkSfx(CPed *ped, int16 sound); + uint32 GetBMOSTTalkSfx(CPed *ped, int16 sound); + uint32 GetBFYRITalkSfx(CPed *ped, int16 sound); + uint32 GetBFORITalkSfx(CPed *ped, int16 sound); + uint32 GetBMYRITalkSfx(CPed *ped, int16 sound); + uint32 GetBFYBETalkSfx(CPed *ped, int16 sound); + uint32 GetBMYBETalkSfx(CPed *ped, int16 sound); + uint32 GetBFOBETalkSfx(CPed *ped, int16 sound); + uint32 GetBMOBETalkSfx(CPed *ped, int16 sound); + uint32 GetBMYBUTalkSfx(CPed *ped, int16 sound); + uint32 GetBFYPRTalkSfx(CPed *ped, int16 sound); + uint32 GetBFOTRTalkSfx(CPed *ped, int16 sound); + uint32 GetBMOTRTalkSfx(CPed *ped, int16 sound); + uint32 GetBMYPITalkSfx(CPed *ped, int16 sound); + uint32 GetBMYBBTalkSfx(CPed *ped, int16 sound); + uint32 GetWMYCRTalkSfx(CPed *ped, int16 sound); + uint32 GetWFYSTTalkSfx(CPed *ped, int16 sound); + uint32 GetWFOSTTalkSfx(CPed *ped, int16 sound); + uint32 GetWMYSTTalkSfx(CPed *ped, int16 sound); + uint32 GetWMOSTTalkSfx(CPed *ped, int16 sound); + uint32 GetWFYRITalkSfx(CPed *ped, int16 sound); + uint32 GetWFORITalkSfx(CPed *ped, int16 sound); + uint32 GetWMYRITalkSfx(CPed *ped, int16 sound); + uint32 GetWMORITalkSfx(CPed *ped, int16 sound); + uint32 GetWFYBETalkSfx(CPed *ped, int16 sound); + uint32 GetWMYBETalkSfx(CPed *ped, int16 sound); + uint32 GetWFOBETalkSfx(CPed *ped, int16 sound); + uint32 GetWMOBETalkSfx(CPed *ped, int16 sound); + uint32 GetWMYCWTalkSfx(CPed *ped, int16 sound); + uint32 GetWMYGOTalkSfx(CPed *ped, int16 sound); + uint32 GetWFOGOTalkSfx(CPed *ped, int16 sound); + uint32 GetWMOGOTalkSfx(CPed *ped, int16 sound); + uint32 GetWFYLGTalkSfx(CPed *ped, int16 sound); + uint32 GetWMYLGTalkSfx(CPed *ped, int16 sound); + uint32 GetWFYBUTalkSfx(CPed *ped, int16 sound); + uint32 GetWMYBUTalkSfx(CPed *ped, int16 sound); + uint32 GetWMOBUTalkSfx(CPed *ped, int16 sound); + uint32 GetWFYPRTalkSfx(CPed *ped, int16 sound); + uint32 GetWFOTRTalkSfx(CPed *ped, int16 sound); + uint32 GetWMOTRTalkSfx(CPed *ped, int16 sound); + uint32 GetWMYPITalkSfx(CPed *ped, int16 sound); + uint32 GetWMOCATalkSfx(CPed *ped, int16 sound); + uint32 GetWFYJGTalkSfx(CPed *ped, int16 sound); + uint32 GetWMYJGTalkSfx(CPed *ped, int16 sound); + uint32 GetWFYSKTalkSfx(CPed *ped, int16 sound); + uint32 GetWMYSKTalkSfx(CPed *ped, int16 sound); + uint32 GetWFYSHTalkSfx(CPed *ped, int16 sound); + uint32 GetWFOSHTalkSfx(CPed *ped, int16 sound); + uint32 GetJFOTOTalkSfx(CPed *ped, int16 sound); + uint32 GetJMOTOTalkSfx(CPed *ped, int16 sound); + uint32 GetCBTalkSfx(CPed *ped, int16 sound); + uint32 GetHNTalkSfx(CPed *ped, int16 sound); + uint32 GetSGTalkSfx(CPed *ped, int16 sound); + uint32 GetCLTalkSfx(CPed *ped, int16 sound); + uint32 GetGDTalkSfx(CPed *ped, int16 sound); + uint32 GetBKTalkSfx(CPed *ped, int16 sound); + uint32 GetPGTalkSfx(CPed *ped, int16 sound); + uint32 GetVICETalkSfx(CPed *ped, int16 sound, int16 model); + uint32 GetWFYG1TalkSfx(CPed *ped, int16 sound); + uint32 GetWFYG2TalkSfx(CPed *ped, int16 sound); + + uint32 GetGenericMaleTalkSfx(CPed *ped, int16 sound); // todo names (inlined in vc) + uint32 GetGenericFemaleTalkSfx(CPed *ped, int16 sound); // todo names (inlined in vc) + // end of functions returning talk sfx + + void GenerateIntegerRandomNumberTable(); // done + char *Get3DProviderName(uint8 id) const; // done + uint8 GetCDAudioDriveLetter() const; // done + int8 GetCurrent3DProviderIndex() const; // done + int8 AutoDetect3DProviders() const; // done + float GetCollisionLoopingRatio(uint32 a, uint32 b, float c) const; // not used + float GetCollisionOneShotRatio(int32 a, float b) const; // done + float GetCollisionRatio(float a, float b, float c, float d) const; // done (inlined in vc) + float GetDistanceSquared(const CVector &v) const; // done (inlined in vc) + int32 GetJumboTaxiFreq() const; // done (inlined in vc) + uint8 GetMissionAudioLoadingStatus(uint8 slot) const; // done + int8 GetMissionScriptPoliceAudioPlayingStatus() const; // done + uint8 GetNum3DProvidersAvailable() const; // done + uint32 GetPedCommentSfx(CPed *ped, int32 sound); // done + void GetPhrase(uint32 &phrase, uint32 &prevPhrase, uint32 sample, uint32 maxOffset) const; // done + float GetVehicleDriveWheelSkidValue(CVehicle *veh, tWheelState wheelState, float gasPedalAudio, cTransmission *transmission, + float velocityChange); // done + float GetVehicleNonDriveWheelSkidValue(CVehicle *veh, tWheelState wheelState, cTransmission *transmission, float velocityChange); // done + + bool HasAirBrakes(int32 model) const; // done + + void Initialise(); // done + void InitialisePoliceRadio(); // done + void InitialisePoliceRadioZones(); // done + void InterrogateAudioEntities(); // done (inlined) + bool IsAudioInitialised() const; // done + bool IsMissionAudioSampleFinished(uint8 slot); // done + bool IsMP3RadioChannelAvailable() const; // done + + bool MissionScriptAudioUsesPoliceChannel(int32 soundMission) const; //done + + void PlayLoadedMissionAudio(uint8 slot); // done + void PlayOneShot(int32 index, uint16 sound, float vol); // done + void PlaySuspectLastSeen(float x, float y, float z); // done + void PlayerJustGotInCar() const; // done + void PlayerJustLeftCar() const; // done + void PostInitialiseGameSpecificSetup(); // done + void PostTerminateGameSpecificShutdown(); // done + void PreInitialiseGameSpecificSetup() const; // done + void PreloadMissionAudio(uint8 slot, Const char *name); // done + void PreTerminateGameSpecificShutdown(); // done + /// processX - main logic of adding new sounds + void ProcessActiveQueues(); // done + bool ProcessAirBrakes(cVehicleParams& params); // done + bool ProcessBoatEngine(cVehicleParams& params); + bool ProcessBoatMovingOverWater(cVehicleParams& params); //done +#ifdef GTA_BRIDGE + void ProcessBridge(); // done(bcs not exists in VC) + void ProcessBridgeMotor(); // done(bcs not exists in VC) + void ProcessBridgeOneShots(); // done(bcs not exists in VC) + void ProcessBridgeWarning(); // done(bcs not exists in VC) +#endif + bool ProcessCarBombTick(cVehicleParams& params); // done + void ProcessCarHeli(cVehicleParams& params); // done + void ProcessCesna(cVehicleParams& params); // done + //void ProcessCrane(); // done(bcs not exists in VC) + bool ProcessEngineDamage(cVehicleParams& params); // done + void ProcessEntity(int32 sound); // done + void ProcessExplosions(int32 explosion); // done + void ProcessFireHydrant(); // done + void ProcessFires(int32 entity); // done + void ProcessFrontEnd(); // done + void ProcessGarages(); // done + void ProcessJumbo(cVehicleParams& params); // done + void ProcessJumboAccel(CPlane *plane); // done + void ProcessJumboDecel(CPlane *plane); // done + void ProcessJumboFlying(); // done + void ProcessJumboLanding(CPlane *plane); // done + void ProcessJumboTakeOff(CPlane *plane); // done + void ProcessJumboTaxi(); // done + void ProcessLoopingScriptObject(uint8 sound); // done + void ProcessMissionAudio(); // done + void ProcessMissionAudioSlot(uint8 slot); // done + void ProcessModelHeliVehicle(cVehicleParams& params); // done + void ProcessModelVehicle(cVehicleParams& params); // done + void ProcessOneShotScriptObject(uint8 sound); // + void ProcessPed(CPhysical *ped); // done + void ProcessPedOneShots(cPedParams ¶ms); // + void ProcessPhysical(int32 id); // done + void ProcessPlane(cVehicleParams& params); // done + void ProcessPlayerMood(); // done + void ProcessPlayersVehicleEngine(cVehicleParams& params, CVehicle* veh); // done + void ProcessProjectiles(); // done + void ProcessRainOnVehicle(cVehicleParams& params); // done + void ProcessReverb() const; // done + bool ProcessReverseGear(cVehicleParams& params); // done + void ProcessScriptObject(int32 id); // done + void ProcessSpecial(); // done +#ifdef GTA_TRAIN + bool ProcessTrainNoise(cVehicleParams *params); //done(bcs not exists in VC) +#endif + void ProcessVehicle(CVehicle *vehicle); // done + bool ProcessVehicleDoors(cVehicleParams ¶ms); // done + void ProcessVehicleEngine(cVehicleParams ¶ms); // done + void ProcessVehicleFlatTyre(cVehicleParams ¶ms); // done + bool ProcessVehicleHorn(cVehicleParams ¶ms); // done + void ProcessVehicleOneShots(cVehicleParams ¶ms); // done + bool ProcessVehicleReverseWarning(cVehicleParams ¶ms); // done + bool ProcessVehicleRoadNoise(cVehicleParams ¶ms); // done + bool ProcessVehicleSirenOrAlarm(cVehicleParams ¶ms); // done + bool ProcessVehicleSkidding(cVehicleParams ¶ms); // done + void ProcessWaterCannon(int32); // done + void ProcessWeather(int32 id); // done + bool ProcessWetRoadNoise(cVehicleParams& params); // done + void ProcessEscalators(); // done + void ProcessExtraSounds(); // done + + int32 RandomDisplacement(uint32 seed) const; // done + void ReacquireDigitalHandle() const; // done + void ReleaseDigitalHandle() const; // done + void ReportCollision(CEntity *entity1, CEntity *entity2, uint8 surface1, uint8 surface2, float collisionPower, float intensity2); // done + void ReportCrime(eCrimeType crime, const CVector &pos); // done + void ResetAudioLogicTimers(uint32 timer); // done + void ResetPoliceRadio(); // done + void ResetTimers(uint32 time); // done + + void Service(); // done + void ServiceCollisions(); // done + void ServicePoliceRadio(); // done + void ServicePoliceRadioChannel(uint8 wantedLevel); // done + void ServiceSoundEffects(); // done + int8 SetCurrent3DProvider(uint8 which); // done + void SetDynamicAcousticModelingStatus(uint8 status); // done + void SetEffectsFadeVol(uint8 volume) const; // done + void SetEffectsMasterVolume(uint8 volume) const; // done + void SetMP3BoostVolume(uint8 volume) const; // done + void SetEntityStatus(int32 id, uint8 status); // done + uint32 SetLoopingCollisionRequestedSfxFreqAndGetVol(const cAudioCollision &audioCollision); // done + void SetMissionAudioLocation(uint8 slot, float x, float y, float z); // done + void SetMissionScriptPoliceAudio(int32 sfx) const; // inlined and optimized + void SetMonoMode(uint8 mono); // done + void SetMusicFadeVol(uint8 volume) const; // done + void SetMusicMasterVolume(uint8 volume) const; // done + void SetSpeakerConfig(int32 conf) const; // done + void SetUpLoopingCollisionSound(const cAudioCollision &col, uint8 counter); // done + void SetUpOneShotCollisionSound(const cAudioCollision &col); // done + bool SetupCrimeReport(); // done + bool SetupJumboEngineSound(uint8 vol, uint32 freq); // done + bool SetupJumboFlySound(uint8 emittingVol); // done + bool SetupJumboRumbleSound(uint8 emittingVol); // done + bool SetupJumboTaxiSound(uint8 vol); // done + bool SetupJumboWhineSound(uint8 emittingVol, uint32 freq); // done + void SetupPedComments(cPedParams ¶ms, uint16 sound); // done + void SetupSuspectLastSeenReport(); + + void Terminate(); // done + void TranslateEntity(Const CVector *v1, CVector *v2) const; // done + + void UpdateGasPedalAudio(CVehicle *veh, int vehType); // done + void UpdateReflections(); // done + bool UsesReverseWarning(int32 model) const; // done + bool UsesSiren(cVehicleParams ¶ms) const; // done + bool UsesSirenSwitching(cVehicleParams ¶ms) const; // done + + CVehicle *FindVehicleOfPlayer(); // done + void SetPedTalkingStatus(CPed *ped, uint8 status); // done + void SetPlayersMood(uint8 mood, uint32 time); // done + + float Sqrt(float v) const { return v <= 0.0f ? 0.0f : ::Sqrt(v); } + +#ifdef GTA_PC + // only used in pc + void AdjustSamplesVolume(); // done (inlined) + uint8 ComputeEmittingVolume(uint8 emittingVolume, float intensity, float dist); // done (inlined) +#endif +}; + +#ifdef AUDIO_MSS +static_assert(sizeof(cAudioManager) == 0x5558, "cAudioManager: error"); +#endif + +extern cAudioManager AudioManager; diff --git a/src/audio/AudioSamples.h b/src/audio/AudioSamples.h new file mode 100644 index 0000000..5c5d857 --- /dev/null +++ b/src/audio/AudioSamples.h @@ -0,0 +1,817 @@ +#pragma once + +#include "common.h" + +enum eSfxSample +{ + SFX_CAR_HORN_JEEP = 0, + SFX_CAR_HORN_BMW328, + SFX_CAR_HORN_BUS, + SFX_CAR_HORN_BUS2, + SFX_CAR_HORN_56CHEV, + SFX_CAR_HORN_PICKUP, + SFX_CAR_HORN_PORSCHE, + SFX_CAR_HORN_TRUCK, + + SFX_CAR_HELI_MAI, // 8 + SFX_CAR_HELI_MAI2, // 9 + SFX_CAR_HELI_REA, // 10 + SFX_CAR_HELI_STA, // 11 + SFX_CAR_HELI_ROT, // 12 + SFX_CAR_HELI_FAR, // 13 + SFX_CAR_HELI_ROL, // 14 + + SFX_OLD_CAR_DOOR_OPEN, + SFX_OLD_CAR_DOOR_CLOSE, + SFX_NEW_CAR_DOOR_OPEN, + SFX_NEW_CAR_DOOR_CLOSE, + SFX_TRUCK_DOOR_OPEN, + SFX_TRUCK_DOOR_CLOSE, + SFX_REVERSE_GEAR, + SFX_REVERSE_GEAR_2, + SFX_CAR_STARTER, // 23 + SFX_ROAD_NOISE, // 24 + SFX_SKID, // 25 + SFX_GRAVEL_SKID, // 26 + SFX_POLICE_SIREN_SLOW, + SFX_SIREN_FAST, // 28 + SFX_AMBULANCE_SIREN_SLOW, + SFX_REVERSE_WARNING, + SFX_ICE_CREAM_TUNE, + SFX_AIR_BRAKES, // 32 + SFX_TYRE_BUMP, // 33 + SFX_TYRE_BURST_B, // 34 + SFX_TYRE_BURST, // 35 + SFX_TYRE_BURST_L, // 36 + SFX_PALM_TREE_LO, // 37 + SFX_BULLET_PASS_1, // 38 + SFX_BULLET_PASS_2, // 39 + SFX_SKATE_1, // 40 + SFX_SKATE_2, // 41 + SFX_FOOTSTEP_CONCRETE_1, + SFX_FOOTSTEP_CONCRETE_2, + SFX_FOOTSTEP_CONCRETE_3, + SFX_FOOTSTEP_CONCRETE_4, + SFX_FOOTSTEP_CONCRETE_5, + SFX_EXPLOSION_1, // 47 + SFX_EXPLOSION_2, // 48 + SFX_EXPLOSION_3, // 49 + SFX_COLT45_LEFT, // 50 + SFX_COLT45_RIGHT, // 51 + SFX_AK47_LEFT, // 52 + SFX_AK47_RIGHT, // 53 + SFX_UZI_LEFT, // 54 + SFX_UZI_RIGHT, // 55 + SFX_UZI_END_LEFT, // 56 + SFX_SNIPER_LEFT, // 57 + SFX_SNIPER_RIGHT, // 58 + SFX_ROCKET_LEFT, // 59 + SFX_ROCKET_RIGHT, // 60 + SFX_ROCKET_FLY, // 61 + SFX_FLAMETHROWER_LEFT, // 62 + SFX_FLAMETHROWER_RIGHT, // 63 + SFX_FLAMETHROWER_START_LEFT, // 64 + SFX_FLAMETHROWER_START_RIGHT, // 65 + SFX_SHOTGUN_LEFT, // 66 + SFX_SHOTGUN_RIGH, // 67 + SFX_M60_LEFT, // 68 + SFX_M60_RIGHT, // 69 + SFX_M60_TAIL_LEFT, // 70 + SFX_TEC_LEFT, // 71 + SFX_TEC_RIGHT, // 72 + SFX_TEC_TAIL, // 73 + SFX_RUGER_LEFT, // 74 + SFX_RUGER_RIGHT, // 75 + SFX_RUGER_TAIL, // 76 + SFX_PISTOL_RELOAD, // 77 + SFX_AK47_RELOAD, // 78 + SFX_ROCKET_RELOAD, // 79 + SFX_RIFLE_RELOAD, // 80 + SFX_GOLF_CLUB_SWING, // 81 + SFX_MINIGUN_FIRE_LEFT, // 82 + SFX_MINIGUN_FIRE_RIGHT, // 83 + SFX_MINIGUN_STOP, // 84 + SFX_SPAS12_LEFT, // 85 + SFX_SPAS12_RIGHT, // 86 + SFX_SPAS12_TAIL_LEFT, // 87 + SFX_PYTHON_LEFT, // 88 + SFX_PYTHON_RIGHT, // 89 + SFX_MP5_LEFT, // 90 + SFX_MP5_RIGHT, // 91 + SFX_COL_TARMAC_1, // 92 + SFX_COL_TARMAC_2, // 93 + SFX_COL_TARMAC_3, // 94 + SFX_COL_TARMAC_4, // 95 + SFX_COL_TARMAC_5, // 96 + SFX_COL_GRASS_1, + SFX_COL_GRAVEL_1, + SFX_COL_MUD_1, + SFX_COL_GARAGE_DOOR_1, + SFX_COL_CAR_PANEL_1, + SFX_COL_CAR_PANEL_2, + SFX_COL_CAR_PANEL_3, + SFX_COL_CAR_PANEL_4, + SFX_COL_CAR_PANEL_5, + SFX_COL_CAR_PANEL_6, + SFX_COL_THICK_METAL_PLATE_1, + SFX_COL_SCAFFOLD_POLE_1, + SFX_COL_LAMP_POST_1, + SFX_COL_HYDRANT_1, + SFX_COL_METAL_CHAIN_FENCE_1, + SFX_COL_METAL_CHAIN_FENCE_2, + SFX_COL_METAL_CHAIN_FENCE_3, + SFX_COL_METAL_CHAIN_FENCE_4, + SFX_COL_PED_1, // 115 + SFX_COL_PED_2, // 116 + SFX_COL_SAND_1, + SFX_COL_WOOD_CRATES_1, + SFX_COL_WOOD_CRATES_2, + SFX_COL_WOOD_CRATES_3, + SFX_COL_WOOD_CRATES_4, + SFX_COL_WOOD_BENCH_1, + SFX_COL_WOOD_BENCH_2, + SFX_COL_WOOD_BENCH_3, + SFX_COL_WOOD_BENCH_4, + SFX_COL_WOOD_SOLID_1, + SFX_COL_VEG_1, // 127 + SFX_COL_VEG_2, // 128 + SFX_COL_VEG_3, // 129 + SFX_COL_VEG_4, // 130 + SFX_COL_VEG_5, // 131 + SFX_COL_CONTAINER_1, + SFX_COL_NEWS_VENDOR_1, + SFX_COL_NEWS_VENDOR_2, + SFX_COL_NEWS_VENDOR_3, + SFX_COL_CAR_1, // 136 + SFX_COL_CAR_2, // 137 + SFX_COL_CAR_3, // 138 + SFX_COL_CAR_4, // 139 + SFX_COL_CAR_5, // 140 + SFX_COL_CARDBOARD_1, + SFX_COL_CARDBOARD_2, + SFX_COL_GATE, // 143 + SFX_SCRAPE_CAR_1, // 144 + SFX_CRATE_SMASH, + SFX_GLASS_CRACK, // 146 + SFX_GLASS_SMASH, // 147 + SFX_GLASS_SHARD_1, + SFX_GLASS_SHARD_2, + SFX_GLASS_SHARD_3, + SFX_GLASS_SHARD_4, + SFX_PED_ON_FIRE, // 152 + SFX_CAR_ON_FIRE, // 153 + SFX_RAIN, // 154 + SFX_HURRICANE_MA, // 155 + SFX_BULLET_SHELL_HIT_GROUND_1, + SFX_BULLET_SHELL_HIT_GROUND_2, + SFX_BULLET_PED, // 158 + SFX_BULLET_CAR_1, // 159 + SFX_BULLET_CAR_2, // 160 + SFX_BULLET_CAR_3, // 161 + SFX_BULLET_WALL_1, // 162 + SFX_BULLET_WALL_2, // 163 + SFX_BULLET_WALL_3, // 164 + SFX_BAT_HIT_LEFT, // 165 + SFX_BAT_HIT_RIGH, // 166 + SFX_FIGHT_1, // 167 + SFX_FIGHT_2, // 168 + SFX_FIGHT_4, // 169 + SFX_FIGHT_5, // 170 + SFX_KNIFE_SWING, // 171 + SFX_KNIFE_SLASH, // 172 + SFX_KNIFE_STAB, // 173 + SFX_HAMMER_HIT_1, // 174 + SFX_HAMMER_HIT_2, // 175 + SFX_GARAGE_DOOR_LOOP, // 176 + SFX_COUNTDOWN, // 177 + SFX_ARM_BOMB, // 178 + SFX_POLICE_RADIO_CRACKLE, // 179 + + SFX_WEVE_GOT, + SFX_THERES, + SFX_RESPOND_TO, + SFX_A_10, + SFX_IN, + SFX_NORTH, + SFX_EAST, + SFX_SOUTH, + SFX_WEST, + SFX_CENTRAL, + SFX_POLICE_RADIO_MESSAGE_NOISE_1, + SFX_POLICE_RADIO_SUSPECT, + SFX_POLICE_RADIO_LAST_SEEN, + SFX_POLICE_RADIO_ON_FOOT, + SFX_POLICE_RADIO_IN_A, + SFX_POLICE_RADIO_DARK, + SFX_POLICE_RADIO_LIGHT, + SFX_POLICE_RADIO_BRIGHT, + + SFX_CRIME_1, + SFX_CRIME_2, + SFX_CRIME_3, + SFX_CRIME_4, + SFX_CRIME_5, + SFX_CRIME_6, + SFX_CRIME_7, + SFX_CRIME_8, + SFX_CRIME_9, + SFX_CRIME_10, + SFX_CRIME_11, + SFX_CRIME_12, + SFX_POLICE_RADIO_VICE_CITY, + SFX_POLICE_RADIO_VICE_CITY_BEACH, + SFX_POLICE_RADIO_VICE_CITY_MAINLAND, + SFX_POLICE_RADIO_OCEAN_BEACH, //??? + SFX_POLICE_RADIO_WASHINGTON_BEACH, + SFX_POLICE_RADIO_VICE_POINT, + SFX_POLICE_RADIO_LEAF_LINKS, + SFX_POLICE_RADIO_STRAFISH_ISLAND, //??????????? + SFX_POLICE_RADIO_VICE_PORT, + SFX_POLICE_RADIO_LITTLE_HAVANA, + SFX_POLICE_RADIO_LITTLE_HAITI, + SFX_POLICE_RADIO_PRAWN_ISLAND, //??????????? IS THAT HOW SHE PRONOUNCES ISLAND? + SFX_POLICE_RADIO_DOWNTOWN, + SFX_POLICE_RADIO_ESCOBAR_INTERNATIONAL, + SFX_POLICE_RADIO_BLACK, + SFX_POLICE_RADIO_WHITE, + SFX_POLICE_RADIO_BLUE, + SFX_POLICE_RADIO_RED, + SFX_POLICE_RADIO_PURPLE, + SFX_POLICE_RADIO_YELLOW, + SFX_POLICE_RADIO_GREY, + SFX_POLICE_RADIO_ORANGE, + SFX_POLICE_RADIO_GREEN, + SFX_POLICE_RADIO_SILVER, + SFX_POLICE_RADIO_AMBULANCE, + SFX_POLICE_RADIO_2_DOOR, + SFX_POLICE_RADIO_TRUCK, + SFX_POLICE_RADIO_FIRE_TRUCK, + SFX_POLICE_RADIO_PICKUP, + SFX_POLICE_RADIO_POLICE_CAR, + SFX_POLICE_RADIO_BOAT, + SFX_POLICE_RADIO_BUGGY, + SFX_POLICE_RADIO_BUS, + SFX_POLICE_RADIO_COACH, + SFX_POLICE_RADIO_CRUISER, + SFX_POLICE_RADIO_DINGHY, + SFX_POLICE_RADIO_GARBAGE_TRUCK, + SFX_POLICE_RADIO_GOLF_CART, + SFX_POLICE_RADIO_HEARSE, + SFX_POLICE_RADIO_HELICOPTER, + SFX_POLICE_RADIO_ICE_CREAM_VAN, + SFX_POLICE_RADIO_LOWRIDER, + SFX_POLICE_RADIO_MOPED, + SFX_POLICE_RADIO_MOTOBIKE, + SFX_POLICE_RADIO_OFFROAD, + SFX_POLICE_RADIO_PLANE, + SFX_POLICE_RADIO_RIG, + SFX_POLICE_RADIO_SEDAN, + SFX_POLICE_RADIO_SPEEDBOAT, + SFX_POLICE_RADIO_SPORTS_CAR, + SFX_POLICE_RADIO_STATION_WAGON, + SFX_POLICE_RADIO_STRETCH, + SFX_POLICE_RADIO_SWAT_VAN, + SFX_POLICE_RADIO_TANK, + SFX_POLICE_RADIO_TAXI, + SFX_POLICE_RADIO_VAN, + + SFX_HELI_1, // 198 + SFX_PHONE_RING, // 199 + SFX_CAR_REV_1, // PONT + SFX_CAR_REV_2, // PORSHE + SFX_CAR_REV_3, // SPIDER + SFX_CAR_REV_4, // MERC + SFX_CAR_REV_5, // TRUC + SFX_CAR_REV_6, // HOTROD + SFX_CAR_REV_7, // COBRA + SFX_CAR_REV_8, // PONT2 + SFX_CAR_REV_9, // CADI + SFX_CAR_REV_10, // PATHFINDER + SFX_CAR_REV_11, // PACARD + SFX_CAR_REV_12, // GOLFCART + SFX_CAR_REV_13, // SFX_CAR_IDLE_GOL + SFX_CAR_REV_14, // SFX_CAR_IDLE_GOL + SFX_CAR_REV_15, // SFX_CAR_IDLE_GOL + SFX_CAR_REV_16, // SFX_CAR_IDLE_GOL + SFX_CAR_REV_17, // VTWI + SFX_MOPED_REV, // just moped + SFX_CAR_REV_19, // HOND(A) + SFX_CAR_REV_20, // SPOR(TCAR) + SFX_CAR_IDLE_1, // PONT + SFX_CAR_IDLE_2, // PORSHE + SFX_CAR_IDLE_3, // SPIDER + SFX_CAR_IDLE_4, // MERC + SFX_CAR_IDLE_5, // TRUC + SFX_CAR_IDLE_6, // HOTROD + SFX_CAR_IDLE_7, // COBRA + SFX_CAR_IDLE_8, // PONT2 + SFX_CAR_IDLE_9, // CADI + SFX_CAR_IDLE_10, // PATHFINDER + SFX_CAR_IDLE_11, // PACARD + SFX_CAR_IDLE_12, // GOLFCART + SFX_CAR_IDLE_13, // SFX_CAR_IDLE_GOL + SFX_CAR_IDLE_14, // SFX_CAR_IDLE_GOL + SFX_CAR_IDLE_15, // SFX_CAR_IDLE_GOL + SFX_CAR_IDLE_16, // SFX_CAR_IDLE_GOL + SFX_CAR_IDLE_17, // VTWI + SFX_MOPED_IDLE, // 237 + SFX_CAR_IDLE_19, // HOND(A) + SFX_CAR_IDLE_20, // SPOR(TCAR) + SFX_JUMBO_DIST_FLY, + SFX_JUMBO_TAXI, // 241 + SFX_JUMBO_WHINE, // 242 + SFX_JUMBO_ENGINE, // 243 + SFX_JUMBO_RUMBLE, // 244 + SFX_JUMBO_LAND_WHEELS, + SFX_BOAT_CRUISER_LOOP, // 246 + SFX_BOAT_V12_LOOP, // 247 + SFX_BOAT_WATER_LOOP, + SFX_BOAT_SPLASH_1, + SFX_BOAT_SPLASH_2, + SFX_FISHING_BOAT_IDLE, + SFX_CAR_RAIN_1, // 252 + SFX_CAR_RAIN_2, // 253 + SFX_CAR_RAIN_3, // 254 + SFX_CAR_RAIN_4, // 255 + SFX_SPLASH_1, // 256 + SFX_PED_CRUNCH_1, // 257 + SFX_PED_CRUNCH_2, // 258 + SFX_WOODEN_BOX_SMASH, + SFX_CARDBOARD_BOX_SMASH, + SFX_ERROR_FIRE_ROCKET_LAUNCHER, + SFX_ERROR_FIRE_RIFLE, + SFX_TANK_TURRET, // 263 + SFX_BODY_LAND_AND_FALL, + SFX_BODY_LAND, // 265 + SFX_BOMB_BEEP, // 266 + SFX_TIMER_BEEP, // 267 + SFX_SUSPENSION_FAST_MOVE, + SFX_SUSPENSION_SLOW_MOVE_LOOP, + SFX_SHAG_SUSPENSION, + SFX_HIT_BALL, // 271 + SFX_ARCADE, // 272 + SFX_CESNA_IDLE, // 273 + SFX_CESNA_REV, // 274 + SFX_RADIO_CLICK, // 275 + SFX_RADIO_DIAL_1, // 276 + SFX_RADIO_DIAL_2, // 277 + SFX_RADIO_DIAL_3, // 278 + + // pc only + SFX_RADIO_DIAL_4, + SFX_RADIO_DIAL_5, + SFX_RADIO_DIAL_6, + SFX_RADIO_DIAL_7, + SFX_RADIO_DIAL_8, + SFX_RADIO_DIAL_9, + SFX_RADIO_DIAL_10, + SFX_RADIO_DIAL_11, + SFX_RADIO_DIAL_12, + + SFX_INFO_LEFT, // 279 + SFX_INFO_RIGHT, // 280 + SFX_INFO_CENTRE, // 281 + SFX_MONEY_LEFT, // 282 + SFX_MONEY_RIGHT, // 283 + SFX_WEAPON_LEFT, // 284 + SFX_WEAPON_RIGHT, // 285 + SFX_WEAPON_CENTRE, // 286 + SFX_PART_MISSION_COMPLETE_LEFT, // 287 + SFX_PART_MISSION_COMPLETE_RIGHT, // 288 + SFX_PART_MISSION_COMPLETE_CENTRE, // 289 + SFX_GO_LEFT, // 290 + SFX_GO_RIGHT, // 291 + SFX_GO_CENTRE, // 292 + SFX_TIMER, // 293 + SFX_EMPTY, // 294 + + SFX_FE_HIGHLIGHT_LEFT, // + SFX_FE_HIGHLIGHT_RIGHT, // + SFX_FE_SELECT_LEFT, // + SFX_FE_SELECT_RIGHT, // + SFX_FE_BACK_LEFT, // + SFX_FE_BACK_RIGHT, // + SFX_FE_ERROR_LEFT, // + SFX_FE_ERROR_RIGHT, // + SFX_FE_NOISE_BURST_1, + SFX_FE_NOISE_BURST_2, + SFX_FE_NOISE_BURST_3, + + SFX_CAR_ACCEL_1, + SFX_CAR_AFTER_ACCEL_1, + SFX_CAR_FINGER_OFF_ACCEL_1, + + SFX_CAR_ACCEL_2, + SFX_CAR_AFTER_ACCEL_2, + SFX_CAR_FINGER_OFF_ACCEL_2, + + SFX_CAR_ACCEL_3, + SFX_CAR_AFTER_ACCEL_3, + SFX_CAR_FINGER_OFF_ACCEL_3, + + SFX_CAR_ACCEL_4, + SFX_CAR_AFTER_ACCEL_4, + SFX_CAR_FINGER_OFF_ACCEL_4, + + SFX_CAR_ACCEL_5, + SFX_CAR_AFTER_ACCEL_5, + SFX_CAR_FINGER_OFF_ACCEL_5, + + SFX_CAR_ACCEL_6, + SFX_CAR_AFTER_ACCEL_6, + SFX_CAR_FINGER_OFF_ACCEL_6, + + SFX_CAR_ACCEL_7, + SFX_CAR_AFTER_ACCEL_7, + SFX_CAR_FINGER_OFF_ACCEL_7, + + SFX_CAR_ACCEL_8, + SFX_CAR_AFTER_ACCEL_8, + SFX_CAR_FINGER_OFF_ACCEL_8, + + SFX_CAR_ACCEL_9, + SFX_CAR_AFTER_ACCEL_9, + SFX_CAR_FINGER_OFF_ACCEL_9, + + SFX_CAR_ACCEL_10, + SFX_CAR_AFTER_ACCEL_10, + SFX_CAR_FINGER_OFF_ACCEL_10, + + SFX_CAR_ACCEL_11, + SFX_CAR_AFTER_ACCEL_11, + SFX_CAR_FINGER_OFF_ACCEL_11, + + SFX_CAR_ACCEL_12, + SFX_CAR_AFTER_ACCEL_12, + SFX_CAR_FINGER_OFF_ACCEL_12, + + // some CHAINSAW STUFF + // SFX_CAR_CHAINSAW, //10973 + // SFX_CAR_CHAINSAW, //10974 + // SFX_CAR_CHAINSAW, //10975 + SFX_CAR_ACCEL_13, + SFX_CAR_AFTER_ACCEL_13, + SFX_CAR_FINGER_OFF_ACCEL_13, + + SFX_RC_IDLE, // 10976 + SFX_RC_REV, // 10977 + SFX_RC_EMPTY, // 10978 + + SFX_CAR_RC_HELI, // 10979 + SFX_CAR_AFTER_ACCEL_15, // empty + SFX_CAR_FINGER_OFF_ACCEL_15, // empty + + SFX_CAR_ACCEL_16, // empty + SFX_CAR_AFTER_ACCEL_16, // empty + SFX_CAR_FINGER_OFF_ACCEL_16, // empty + + // bike stuff apparently + SFX_CAR_ACCEL_17, + SFX_CAR_AFTER_ACCEL_17, + SFX_CAR_FINGER_OFF_ACCEL_17, + SFX_CAR_WIND_17, + + SFX_CAR_ACCEL_18, + SFX_CAR_AFTER_ACCEL_18, + SFX_CAR_FINGER_OFF_ACCEL_18, + SFX_CAR_WIND_18, + + SFX_CAR_ACCEL_19, + SFX_CAR_AFTER_ACCEL_19, + SFX_CAR_FINGER_OFF_ACCEL_19, + SFX_CAR_WIND_19, + + SFX_CAR_ACCEL_20, + SFX_CAR_AFTER_ACCEL_20, + SFX_CAR_FINGER_OFF_ACCEL_20, + SFX_CAR_WIND_20, + + // some emptinnes here + SFX_CAR_ACCEL_21, + SFX_CAR_AFTER_ACCEL_21, + SFX_CAR_FINGER_OFF_ACCEL_21, + SFX_CAR_ACCEL_22, + SFX_CAR_AFTER_ACCEL_22, + SFX_CAR_FINGER_OFF_ACCEL_22, + + SFX_HELI_APACHE_1, + SFX_HELI_APACHE_2, + SFX_HELI_APACHE_3, + SFX_HELI_APACHE_4, + + // something padded for more heli? + SFX_HELI_UNUSED_1, + SFX_HELI_UNUSED_2, + SFX_HELI_UNUSED_3, + SFX_HELI_UNUSED_4, + + SFX_SEAPLANE_PRO1, // 11018 + SFX_SEAPLANE_PRO2, // 11019 + SFX_SEAPLANE_PRO3, // 11020 + SFX_SEAPLANE_PRO4, // 11021 + // low fuel + SFX_SEAPLANE_LOW, // 11022 + + // something padded for more plane? + SFX_PLANE_UNUSED_1, + SFX_PLANE_UNUSED_2, + SFX_PLANE_UNUSED_3, + SFX_PLANE_UNUSED_4, + + // script objects + SFX_BUILDINGS_BANK_ALARM, // 11027 + SFX_BUILDING_SNORE, // 11028 + SFX_BUILDING_BAR_1, // 11029 + SFX_BUILDING_BAR_2, // 11030 + SFX_BUILDING_BAR_3, // 11031 + SFX_BUILDING_BAR_4, // 11032 + SFX_BUILDING_MAL1, // 11033 + SFX_BUILDING_MAL2, // 11034 + SFX_BUILDING_MAL3, // 11035 + SFX_BUILDING_STR1, // 11036 + SFX_BUILDING_STR2, // 11037 + SFX_BUILDING_STR3, // 11038 + SFX_BUILDING_CHURCH, // 11039 + SFX_BUILDING_FAN_1, // 11040 + SFX_BUILDING_FAN_2, // 11041 + SFX_BUILDING_FAN_3, // 11042 + SFX_BUILDING_FAN_4, // 11043 + SFX_BUILDING_INSECTS_1, // 11044 + SFX_BUILDING_INSECTS_2, // 11045 + SFX_BUILDING_INSECTS_3, // 11046 + SFX_BUILDING_INSECTS_4, // 11047 + SFX_BUILDING_INSECTS_5, // 11048 + SFX_CLUB_1, // 11049 + SFX_CLUB_2, // 11050 + SFX_CLUB_3, // 11051 + SFX_CLUB_4, // 11052 + + SFX_FOOTSTEP_GRASS_1, + SFX_FOOTSTEP_GRASS_2, + SFX_FOOTSTEP_GRASS_3, + SFX_FOOTSTEP_GRASS_4, + SFX_FOOTSTEP_GRASS_5, + SFX_FOOTSTEP_GRAVEL_1, + SFX_FOOTSTEP_GRAVEL_2, + SFX_FOOTSTEP_GRAVEL_3, + SFX_FOOTSTEP_GRAVEL_4, + SFX_FOOTSTEP_GRAVEL_5, + SFX_FOOTSTEP_WOOD_1, + SFX_FOOTSTEP_WOOD_2, + SFX_FOOTSTEP_WOOD_3, + SFX_FOOTSTEP_WOOD_4, + SFX_FOOTSTEP_WOOD_5, + SFX_FOOTSTEP_METAL_1, + SFX_FOOTSTEP_METAL_2, + SFX_FOOTSTEP_METAL_3, + SFX_FOOTSTEP_METAL_4, + SFX_FOOTSTEP_METAL_5, + SFX_FOOTSTEP_WATER_1, + SFX_FOOTSTEP_WATER_2, + SFX_FOOTSTEP_WATER_3, + SFX_FOOTSTEP_WATER_4, + SFX_FOOTSTEP_SAND_1, + SFX_FOOTSTEP_SAND_2, + SFX_FOOTSTEP_SAND_3, + SFX_FOOTSTEP_SAND_4, + + // TODO: miami ped comments... THERE'S OVER 9000 + SFX_POLICE_BOAT_1 = 714, + SFX_POLICE_BOAT_2, + SFX_POLICE_BOAT_3, + SFX_POLICE_BOAT_4, + SFX_POLICE_BOAT_5, + SFX_POLICE_BOAT_6, + SFX_POLICE_BOAT_7, + SFX_POLICE_BOAT_8, + SFX_POLICE_BOAT_9, + SFX_POLICE_BOAT_10, + SFX_POLICE_BOAT_11, + SFX_POLICE_BOAT_12, + SFX_POLICE_BOAT_13, + SFX_POLICE_BOAT_14, + SFX_POLICE_BOAT_15, + SFX_POLICE_BOAT_16, + SFX_POLICE_BOAT_17, + SFX_POLICE_BOAT_18, + SFX_POLICE_BOAT_19, + SFX_POLICE_BOAT_20, + SFX_POLICE_BOAT_21, + SFX_POLICE_BOAT_22, + SFX_POLICE_BOAT_23, + + SFX_POLICE_HELI_1, + SFX_POLICE_HELI_2, + SFX_POLICE_HELI_3, + SFX_POLICE_HELI_4, + SFX_POLICE_HELI_5, + SFX_POLICE_HELI_6, + SFX_POLICE_HELI_7, + SFX_POLICE_HELI_8, + SFX_POLICE_HELI_9, + SFX_POLICE_HELI_10, + SFX_POLICE_HELI_11, + SFX_POLICE_HELI_12, + SFX_POLICE_HELI_13, + SFX_POLICE_HELI_14, + SFX_POLICE_HELI_15, + SFX_POLICE_HELI_16, + SFX_POLICE_HELI_17, + SFX_POLICE_HELI_18, + SFX_POLICE_HELI_19, + SFX_POLICE_HELI_20, + + SFX_GENERIC_FEMALE_GRUNT_1 = 2953, + SFX_GENERIC_FEMALE_GRUNT_2 = 2954, + SFX_GENERIC_FEMALE_GRUNT_3 = 2955, + SFX_GENERIC_FEMALE_GRUNT_4 = 2956, + SFX_GENERIC_FEMALE_GRUNT_5 = 2957, + SFX_GENERIC_FEMALE_GRUNT_6 = 2958, + SFX_GENERIC_FEMALE_GRUNT_7 = 2959, + SFX_GENERIC_FEMALE_GRUNT_8 = 2960, + SFX_GENERIC_FEMALE_GRUNT_9 = 2961, + SFX_GENERIC_FEMALE_GRUNT_10 = 2962, + SFX_GENERIC_FEMALE_GRUNT_11 = 2963, + SFX_GENERIC_FEMALE_GRUNT_12 = 2964, + SFX_GENERIC_FEMALE_GRUNT_13 = 2965, + SFX_GENERIC_FEMALE_GRUNT_14 = 2966, + SFX_GENERIC_FEMALE_GRUNT_15 = 2967, + SFX_GENERIC_FEMALE_GRUNT_16 = 2968, + SFX_GENERIC_FEMALE_GRUNT_17 = 2969, + SFX_GENERIC_FEMALE_GRUNT_18 = 2970, + SFX_GENERIC_FEMALE_GRUNT_19 = 2971, + SFX_GENERIC_FEMALE_GRUNT_20 = 2972, + SFX_GENERIC_FEMALE_GRUNT_21 = 2973, + SFX_GENERIC_FEMALE_GRUNT_22 = 2974, + SFX_GENERIC_FEMALE_GRUNT_23 = 2975, + SFX_GENERIC_FEMALE_GRUNT_24 = 2976, + SFX_GENERIC_FEMALE_GRUNT_25 = 2977, + SFX_GENERIC_FEMALE_GRUNT_26 = 2978, + SFX_GENERIC_FEMALE_GRUNT_27 = 2979, + SFX_GENERIC_FEMALE_GRUNT_28 = 2980, + SFX_GENERIC_FEMALE_GRUNT_29 = 2981, + SFX_GENERIC_FEMALE_GRUNT_30 = 2982, + SFX_GENERIC_FEMALE_GRUNT_31 = 2983, + SFX_GENERIC_FEMALE_GRUNT_32 = 2984, + SFX_GENERIC_FEMALE_GRUNT_33 = 2985, + SFX_GENERIC_MALE_FIRE_1 = 3013, + SFX_GENERIC_MALE_FIRE_2 = 3014, + SFX_GENERIC_MALE_FIRE_3 = 3015, + SFX_GENERIC_MALE_FIRE_4 = 3016, + SFX_GENERIC_MALE_FIRE_5 = 3017, + SFX_GENERIC_MALE_FIRE_6 = 3018, + SFX_GENERIC_MALE_FIRE_7 = 3019, + SFX_GENERIC_MALE_FIRE_8 = 3020, + SFX_GENERIC_MALE_FIRE_9 = 3021, + SFX_GENERIC_MALE_FIRE_10 = 3022, + SFX_GENERIC_MALE_FIRE_11 = 3023, + SFX_GENERIC_MALE_FIRE_12 = 3024, + SFX_GENERIC_MALE_FIRE_13 = 3025, + SFX_GENERIC_MALE_FIRE_14 = 3026, + SFX_GENERIC_MALE_FIRE_15 = 3027, + SFX_GENERIC_MALE_FIRE_16 = 3028, + SFX_GENERIC_MALE_FIRE_17 = 3029, + SFX_GENERIC_MALE_FIRE_18 = 3030, + SFX_GENERIC_MALE_FIRE_19 = 3031, + SFX_GENERIC_MALE_FIRE_20 = 3032, + SFX_GENERIC_MALE_FIRE_21 = 3033, + SFX_GENERIC_MALE_FIRE_22 = 3034, + SFX_GENERIC_MALE_FIRE_23 = 3035, + SFX_GENERIC_MALE_FIRE_24 = 3036, + SFX_GENERIC_MALE_FIRE_25 = 3037, + SFX_GENERIC_MALE_FIRE_26 = 3038, + SFX_GENERIC_MALE_FIRE_27 = 3039, + SFX_GENERIC_MALE_FIRE_28 = 3040, + SFX_GENERIC_MALE_FIRE_29 = 3041, + SFX_GENERIC_MALE_FIRE_30 = 3042, + SFX_GENERIC_MALE_FIRE_31 = 3043, + SFX_GENERIC_MALE_FIRE_32 = 3044, + SFX_GENERIC_MALE_DEATH_1 = 3045, + SFX_GENERIC_MALE_DEATH_2 = 3046, + SFX_GENERIC_MALE_DEATH_3 = 3047, + SFX_GENERIC_MALE_DEATH_4 = 3048, + SFX_GENERIC_MALE_DEATH_5 = 3049, + SFX_GENERIC_MALE_DEATH_6 = 3050, + SFX_GENERIC_MALE_DEATH_7 = 3051, + SFX_GENERIC_MALE_DEATH_8 = 3052, + SFX_GENERIC_MALE_DEATH_9 = 3053, + SFX_GENERIC_MALE_DEATH_10 = 3054, + SFX_GENERIC_MALE_DEATH_11 = 3055, + SFX_GENERIC_MALE_DEATH_12 = 3056, + SFX_GENERIC_MALE_DEATH_13 = 3057, + SFX_GENERIC_MALE_DEATH_14 = 3058, + SFX_GENERIC_MALE_DEATH_15 = 3059, + SFX_GENERIC_MALE_DEATH_16 = 3060, + SFX_GENERIC_MALE_DEATH_17 = 3061, + SFX_GENERIC_MALE_DEATH_18 = 3062, + SFX_GENERIC_MALE_DEATH_19 = 3063, + SFX_GENERIC_MALE_DEATH_20 = 3064, + SFX_GENERIC_MALE_DEATH_21 = 3065, + SFX_GENERIC_MALE_DEATH_22 = 3066, + SFX_GENERIC_MALE_DEATH_23 = 3067, + SFX_GENERIC_MALE_DEATH_24 = 3068, + SFX_GENERIC_MALE_DEATH_25 = 3069, + SFX_GENERIC_MALE_DEATH_26 = 3070, + SFX_GENERIC_MALE_DEATH_27 = 3071, + SFX_GENERIC_MALE_DEATH_28 = 3072, + SFX_GENERIC_MALE_DEATH_29 = 3073, + SFX_GENERIC_MALE_DEATH_30 = 3074, + SFX_GENERIC_MALE_DEATH_31 = 3075, + SFX_GENERIC_MALE_DEATH_32 = 3076, + SFX_GENERIC_MALE_DEATH_33 = 3077, + SFX_GENERIC_MALE_DEATH_34 = 3078, + SFX_GENERIC_MALE_DEATH_35 = 3079, + SFX_GENERIC_MALE_DEATH_36 = 3080, + SFX_GENERIC_MALE_DEATH_37 = 3081, + SFX_GENERIC_MALE_DEATH_38 = 3082, + SFX_GENERIC_MALE_DEATH_39 = 3083, + SFX_GENERIC_MALE_DEATH_40 = 3084, + SFX_GENERIC_MALE_DEATH_41 = 3085, + SFX_GENERIC_MALE_GRUNT_1 = 3086, + SFX_GENERIC_MALE_GRUNT_2 = 3087, + SFX_GENERIC_MALE_GRUNT_3 = 3088, + SFX_GENERIC_MALE_GRUNT_4 = 3089, + SFX_GENERIC_MALE_GRUNT_5 = 3090, + SFX_GENERIC_MALE_GRUNT_6 = 3091, + SFX_GENERIC_MALE_GRUNT_7 = 3092, + SFX_GENERIC_MALE_GRUNT_8 = 3093, + SFX_GENERIC_MALE_GRUNT_9 = 3094, + SFX_GENERIC_MALE_GRUNT_10 = 3095, + SFX_GENERIC_MALE_GRUNT_11 = 3096, + SFX_GENERIC_MALE_GRUNT_12 = 3097, + SFX_GENERIC_MALE_GRUNT_13 = 3098, + SFX_GENERIC_MALE_GRUNT_14 = 3099, + SFX_GENERIC_MALE_GRUNT_15 = 3100, + SFX_GENERIC_MALE_GRUNT_16 = 3101, + SFX_GENERIC_MALE_GRUNT_17 = 3102, + SFX_GENERIC_MALE_GRUNT_18 = 3103, + SFX_GENERIC_MALE_GRUNT_19 = 3104, + SFX_GENERIC_MALE_GRUNT_20 = 3105, + SFX_GENERIC_MALE_GRUNT_21 = 3106, + SFX_GENERIC_MALE_GRUNT_22 = 3107, + SFX_GENERIC_MALE_GRUNT_23 = 3108, + SFX_GENERIC_MALE_GRUNT_24 = 3109, + SFX_GENERIC_MALE_GRUNT_25 = 3110, + SFX_GENERIC_MALE_GRUNT_26 = 3111, + SFX_GENERIC_MALE_GRUNT_27 = 3112, + SFX_GENERIC_MALE_GRUNT_28 = 3113, + SFX_GENERIC_MALE_GRUNT_29 = 3114, + SFX_GENERIC_MALE_GRUNT_30 = 3115, + SFX_GENERIC_MALE_GRUNT_31 = 3116, + SFX_GENERIC_MALE_GRUNT_32 = 3117, + SFX_GENERIC_MALE_GRUNT_33 = 3118, + SFX_GENERIC_MALE_GRUNT_34 = 3119, + SFX_GENERIC_MALE_GRUNT_35 = 3120, + SFX_GENERIC_MALE_GRUNT_36 = 3121, + SFX_GENERIC_MALE_GRUNT_37 = 3122, + SFX_GENERIC_MALE_GRUNT_38 = 3123, + SFX_GENERIC_MALE_GRUNT_39 = 3124, + SFX_GENERIC_MALE_GRUNT_40 = 3125, + SFX_GENERIC_MALE_GRUNT_41 = 3126, + SFX_GENERIC_MALE_PANIC_1 = 3127, + SFX_GENERIC_MALE_PANIC_2 = 3128, + SFX_GENERIC_MALE_PANIC_3 = 3129, + SFX_GENERIC_MALE_PANIC_4 = 3130, + SFX_GENERIC_MALE_PANIC_5 = 3131, + SFX_GENERIC_MALE_PANIC_6 = 3132, + SFX_GENERIC_MALE_PANIC_7 = 3133, + SFX_GENERIC_MALE_PANIC_8 = 3134, + SFX_GENERIC_MALE_PANIC_9 = 3135, + SFX_GENERIC_MALE_PANIC_10 = 3136, + SFX_GENERIC_MALE_PANIC_11 = 3137, + SFX_GENERIC_MALE_PANIC_12 = 3138, + SFX_GENERIC_MALE_PANIC_13 = 3139, + SFX_GENERIC_MALE_PANIC_14 = 3140, + SFX_GENERIC_MALE_PANIC_15 = 3141, + SFX_GENERIC_MALE_PANIC_16 = 3142, + SFX_GENERIC_MALE_PANIC_17 = 3143, + SFX_GENERIC_MALE_PANIC_18 = 3144, + SFX_GENERIC_MALE_PANIC_19 = 3145, + SFX_GENERIC_MALE_PANIC_20 = 3146, + SFX_GENERIC_MALE_PANIC_21 = 3147, + SFX_GENERIC_MALE_PANIC_22 = 3148, + SFX_GENERIC_MALE_PANIC_23 = 3149, + SFX_GENERIC_MALE_PANIC_24 = 3150, + SFX_GENERIC_MALE_PANIC_25 = 3151, + SFX_GENERIC_MALE_PANIC_26 = 3152, + SFX_GENERIC_MALE_PANIC_27 = 3153, + SFX_GENERIC_MALE_PANIC_28 = 3154, + SFX_GENERIC_MALE_PANIC_29 = 3155, + SFX_GENERIC_MALE_PANIC_30 = 3156, + SFX_GENERIC_MALE_PANIC_31 = 3157, + SFX_GENERIC_MALE_PANIC_32 = 3158, + SFX_GENERIC_MALE_PANIC_33 = 3159, + SFX_GENERIC_MALE_PANIC_34 = 3160, + SFX_GENERIC_MALE_PANIC_35 = 3161, + + TOTAL_AUDIO_SAMPLES = 9941, + NO_SAMPLE, + + // shorthands + SAMPLEBANK_START = SFX_CAR_HORN_JEEP, + SAMPLEBANK_END = SFX_FOOTSTEP_SAND_4, + SAMPLEBANK_MAX = SFX_FOOTSTEP_SAND_4 + 1, + SAMPLEBANK_PED_START = SFX_FOOTSTEP_SAND_4 + 1, + SAMPLEBANK_PED_END = 9940, + SAMPLEBANK_PED_MAX = SAMPLEBANK_PED_END + 1, +}; diff --git a/src/audio/AudioScriptObject.cpp b/src/audio/AudioScriptObject.cpp new file mode 100644 index 0000000..ac30f75 --- /dev/null +++ b/src/audio/AudioScriptObject.cpp @@ -0,0 +1,98 @@ +#include "common.h" + +#include "AudioScriptObject.h" +#include "Pools.h" +#include "DMAudio.h" + +cAudioScriptObject::cAudioScriptObject() +{ + Reset(); +}; + +cAudioScriptObject::~cAudioScriptObject() +{ + Reset(); +}; + +void +cAudioScriptObject::Reset() +{ + AudioId = SCRIPT_SOUND_INVALID; + Posn = CVector(0.0f, 0.0f, 0.0f); + AudioEntity = AEHANDLE_NONE; +} + +void * +cAudioScriptObject::operator new(size_t sz) +{ + return CPools::GetAudioScriptObjectPool()->New(); +} + +void * +cAudioScriptObject::operator new(size_t sz, int handle) +{ + return CPools::GetAudioScriptObjectPool()->New(handle); +} + +void +cAudioScriptObject::operator delete(void *p, size_t sz) +{ + CPools::GetAudioScriptObjectPool()->Delete((cAudioScriptObject *)p); +} + +void +cAudioScriptObject::operator delete(void *p, int handle) +{ + CPools::GetAudioScriptObjectPool()->Delete((cAudioScriptObject *)p); +} + +void +cAudioScriptObject::LoadAllAudioScriptObjects(uint8 *buf, uint32 size) +{ + INITSAVEBUF + + CheckSaveHeader(buf, 'A', 'U', 'D', '\0', size - SAVE_HEADER_SIZE); + + int32 pool_size = ReadSaveBuf<int32>(buf); + for (int32 i = 0; i < pool_size; i++) { + int handle = ReadSaveBuf<int32>(buf); + cAudioScriptObject *p = new(handle) cAudioScriptObject; + assert(p != nil); + *p = ReadSaveBuf<cAudioScriptObject>(buf); + p->AudioEntity = DMAudio.CreateLoopingScriptObject(p); + } + + VALIDATESAVEBUF(size); +} + +void +cAudioScriptObject::SaveAllAudioScriptObjects(uint8 *buf, uint32 *size) +{ + INITSAVEBUF + + int32 pool_size = CPools::GetAudioScriptObjectPool()->GetNoOfUsedSpaces(); + *size = SAVE_HEADER_SIZE + sizeof(int32) + pool_size * (sizeof(cAudioScriptObject) + sizeof(int32)); + WriteSaveHeader(buf, 'A', 'U', 'D', '\0', *size - SAVE_HEADER_SIZE); + WriteSaveBuf(buf, pool_size); + + int32 i = CPools::GetAudioScriptObjectPool()->GetSize(); + while (i--) { + cAudioScriptObject *p = CPools::GetAudioScriptObjectPool()->GetSlot(i); + if (p != nil) { + WriteSaveBuf(buf, CPools::GetAudioScriptObjectPool()->GetIndex(p)); + WriteSaveBuf(buf, *p); + } + } + + VALIDATESAVEBUF(*size); +} + +void +PlayOneShotScriptObject(uint8 id, CVector const &pos) +{ + cAudioScriptObject *audioScriptObject = new cAudioScriptObject(); + audioScriptObject->Posn = pos; + audioScriptObject->AudioId = id; + audioScriptObject->AudioEntity = AEHANDLE_NONE; + DMAudio.CreateOneShotScriptObject(audioScriptObject); +} diff --git a/src/audio/AudioScriptObject.h b/src/audio/AudioScriptObject.h new file mode 100644 index 0000000..8110b2b --- /dev/null +++ b/src/audio/AudioScriptObject.h @@ -0,0 +1,26 @@ +#pragma once + +class cAudioScriptObject +{ +public: + int16 AudioId; + CVector Posn; + int32 AudioEntity; + + cAudioScriptObject(); + ~cAudioScriptObject(); + + void Reset(); /// ok + + static void* operator new(size_t); + static void* operator new(size_t, int); + static void operator delete(void*, size_t); + static void operator delete(void*, int); + + static void LoadAllAudioScriptObjects(uint8 *buf, uint32 size); + static void SaveAllAudioScriptObjects(uint8 *buf, uint32 *size); +}; + +VALIDATE_SIZE(cAudioScriptObject, 20); + +extern void PlayOneShotScriptObject(uint8 id, CVector const &pos);
\ No newline at end of file diff --git a/src/audio/DMAudio.cpp b/src/audio/DMAudio.cpp new file mode 100644 index 0000000..7c99e89 --- /dev/null +++ b/src/audio/DMAudio.cpp @@ -0,0 +1,382 @@ +#include "common.h" + +#include "DMAudio.h" +#include "MusicManager.h" +#include "AudioManager.h" +#include "AudioScriptObject.h" +#include "sampman.h" + +cDMAudio DMAudio; + +void +cDMAudio::Initialise(void) +{ + AudioManager.Initialise(); +} + +void +cDMAudio::Terminate(void) +{ + AudioManager.Terminate(); +} + +void +cDMAudio::Service(void) +{ + AudioManager.Service(); +} + +int32 +cDMAudio::CreateEntity(eAudioType type, void *UID) +{ + return AudioManager.CreateEntity(type, (CPhysical *)UID); +} + +void +cDMAudio::DestroyEntity(int32 audioEntity) +{ + AudioManager.DestroyEntity(audioEntity); +} + +void +cDMAudio::SetEntityStatus(int32 audioEntity, uint8 status) +{ + AudioManager.SetEntityStatus(audioEntity, status); +} + +void +cDMAudio::PlayOneShot(int32 audioEntity, uint16 oneShot, float volume) +{ + AudioManager.PlayOneShot(audioEntity, oneShot, volume); +} + +void +cDMAudio::DestroyAllGameCreatedEntities(void) +{ + AudioManager.DestroyAllGameCreatedEntities(); +} + +void +cDMAudio::SetMonoMode(uint8 mono) +{ + AudioManager.SetMonoMode(mono); +} + +void +cDMAudio::SetMP3BoostVolume(uint8 volume) +{ + uint8 vol = volume; + if (vol > MAX_VOLUME) vol = MAX_VOLUME; + + AudioManager.SetMP3BoostVolume(vol); +} + +void +cDMAudio::SetEffectsMasterVolume(uint8 volume) +{ + uint8 vol = volume; + if ( vol > MAX_VOLUME ) vol = MAX_VOLUME; + + AudioManager.SetEffectsMasterVolume(vol); +} + +void +cDMAudio::SetMusicMasterVolume(uint8 volume) +{ + uint8 vol = volume; + if ( vol > MAX_VOLUME ) vol = MAX_VOLUME; + + AudioManager.SetMusicMasterVolume(vol); +} + +void +cDMAudio::SetEffectsFadeVol(uint8 volume) +{ + uint8 vol = volume; + if ( vol > MAX_VOLUME ) vol = MAX_VOLUME; + + AudioManager.SetEffectsFadeVol(vol); +} + +void +cDMAudio::SetMusicFadeVol(uint8 volume) +{ + uint8 vol = volume; + if ( vol > MAX_VOLUME ) vol = MAX_VOLUME; + + AudioManager.SetMusicFadeVol(vol); +} + +uint8 +cDMAudio::GetNum3DProvidersAvailable(void) +{ + return AudioManager.GetNum3DProvidersAvailable(); +} + +char * +cDMAudio::Get3DProviderName(uint8 id) +{ + return AudioManager.Get3DProviderName(id); +} + +int8 cDMAudio::AutoDetect3DProviders(void) +{ + return AudioManager.AutoDetect3DProviders(); +} + +int8 +cDMAudio::GetCurrent3DProviderIndex(void) +{ + return AudioManager.GetCurrent3DProviderIndex(); +} + +int8 +cDMAudio::SetCurrent3DProvider(uint8 which) +{ + return AudioManager.SetCurrent3DProvider(which); +} + +void +cDMAudio::SetSpeakerConfig(int32 config) +{ + AudioManager.SetSpeakerConfig(config); +} + +bool +cDMAudio::IsMP3RadioChannelAvailable(void) +{ + return AudioManager.IsMP3RadioChannelAvailable(); +} + +void +cDMAudio::ReleaseDigitalHandle(void) +{ + AudioManager.ReleaseDigitalHandle(); +} + +void +cDMAudio::ReacquireDigitalHandle(void) +{ + AudioManager.ReacquireDigitalHandle(); +} + +void +cDMAudio::SetDynamicAcousticModelingStatus(uint8 status) +{ + AudioManager.SetDynamicAcousticModelingStatus(status); +} + +bool +cDMAudio::CheckForAnAudioFileOnCD(void) +{ + return AudioManager.CheckForAnAudioFileOnCD(); +} + +char +cDMAudio::GetCDAudioDriveLetter(void) +{ + return AudioManager.GetCDAudioDriveLetter(); +} + +bool +cDMAudio::IsAudioInitialised(void) +{ + return AudioManager.IsAudioInitialised(); +} + +void +cDMAudio::ReportCrime(eCrimeType crime, const CVector &pos) +{ + AudioManager.ReportCrime(crime, pos); +} + +int32 +cDMAudio::CreateLoopingScriptObject(cAudioScriptObject *scriptObject) +{ + int32 audioEntity = AudioManager.CreateEntity(AUDIOTYPE_SCRIPTOBJECT, scriptObject); + + if ( AEHANDLE_IS_OK(audioEntity) ) + AudioManager.SetEntityStatus(audioEntity, true); + + return audioEntity; +} + +void +cDMAudio::DestroyLoopingScriptObject(int32 audioEntity) +{ + AudioManager.DestroyEntity(audioEntity); +} + +void +cDMAudio::CreateOneShotScriptObject(cAudioScriptObject *scriptObject) +{ + int32 audioEntity = AudioManager.CreateEntity(AUDIOTYPE_SCRIPTOBJECT, scriptObject); + + if ( AEHANDLE_IS_OK(audioEntity) ) + { + AudioManager.SetEntityStatus(audioEntity, true); + AudioManager.PlayOneShot(audioEntity, scriptObject->AudioId, 0.0f); + } +} + +void +cDMAudio::PlaySuspectLastSeen(float x, float y, float z) +{ + AudioManager.PlaySuspectLastSeen(x, y, z); +} + +void +cDMAudio::ReportCollision(CEntity *entityA, CEntity *entityB, uint8 surfaceTypeA, uint8 surfaceTypeB, float collisionPower, float velocity) +{ + AudioManager.ReportCollision(entityA, entityB, surfaceTypeA, surfaceTypeB, collisionPower, velocity); +} + +void +cDMAudio::PlayFrontEndSound(uint16 frontend, uint32 volume) +{ + AudioManager.PlayOneShot(AudioManager.m_nFrontEndEntity, frontend, (float)volume); +} + +void +cDMAudio::PlayRadioAnnouncement(uint32 announcement) +{ + MusicManager.PlayAnnouncement(announcement); +} + +void +cDMAudio::PlayFrontEndTrack(uint32 track, uint8 frontendFlag) +{ + MusicManager.PlayFrontEndTrack(track, frontendFlag); +} + +void +cDMAudio::StopFrontEndTrack(void) +{ + MusicManager.StopFrontEndTrack(); +} + +void +cDMAudio::ResetTimers(uint32 time) +{ + AudioManager.ResetTimers(time); +} + +void +cDMAudio::ChangeMusicMode(uint8 mode) +{ + MusicManager.ChangeMusicMode(mode); +} + +void +cDMAudio::PreloadCutSceneMusic(uint32 track) +{ + MusicManager.PreloadCutSceneMusic(track); +} + +void +cDMAudio::PlayPreloadedCutSceneMusic(void) +{ + MusicManager.PlayPreloadedCutSceneMusic(); +} + +void +cDMAudio::StopCutSceneMusic(void) +{ + MusicManager.StopCutSceneMusic(); +} + +void +cDMAudio::PreloadMissionAudio(uint8 slot, Const char *missionAudio) +{ + AudioManager.PreloadMissionAudio(slot, missionAudio); +} + +uint8 +cDMAudio::GetMissionAudioLoadingStatus(uint8 slot) +{ + return AudioManager.GetMissionAudioLoadingStatus(slot); +} + +void +cDMAudio::SetMissionAudioLocation(uint8 slot, float x, float y, float z) +{ + AudioManager.SetMissionAudioLocation(slot, x, y, z); +} + +void +cDMAudio::PlayLoadedMissionAudio(uint8 slot) +{ + AudioManager.PlayLoadedMissionAudio(slot); +} + +bool +cDMAudio::IsMissionAudioSampleFinished(uint8 slot) +{ + return AudioManager.IsMissionAudioSampleFinished(slot); +} + +void +cDMAudio::ClearMissionAudio(uint8 slot) +{ + AudioManager.ClearMissionAudio(slot); +} + +uint8 +cDMAudio::GetRadioInCar(void) +{ + return MusicManager.GetRadioInCar(); +} + +void +cDMAudio::SetRadioInCar(uint32 radio) +{ + MusicManager.SetRadioInCar(radio); +} + +void +cDMAudio::SetRadioChannel(uint32 radio, int32 pos) +{ + MusicManager.SetRadioChannelByScript(radio, pos); +} + +void +cDMAudio::SetStartingTrackPositions(uint8 isStartGame) +{ + MusicManager.SetStartingTrackPositions(isStartGame); +} + +float * +cDMAudio::GetListenTimeArray() +{ + return MusicManager.GetListenTimeArray(); +} + +uint32 +cDMAudio::GetFavouriteRadioStation() +{ + return MusicManager.GetFavouriteRadioStation(); +} + +int32 +cDMAudio::GetRadioPosition(uint32 station) +{ + return MusicManager.GetRadioPosition(station); +} + +void +cDMAudio::SetPedTalkingStatus(CPed *ped, uint8 status) +{ + return AudioManager.SetPedTalkingStatus(ped, status); +} + +void +cDMAudio::SetPlayersMood(uint8 mood, uint32 time) +{ + return AudioManager.SetPlayersMood(mood, time); +} + +void +cDMAudio::ShutUpPlayerTalking(uint8 state) +{ + AudioManager.m_bIsPlayerShutUp = state; +}
\ No newline at end of file diff --git a/src/audio/DMAudio.h b/src/audio/DMAudio.h new file mode 100644 index 0000000..2c10043 --- /dev/null +++ b/src/audio/DMAudio.h @@ -0,0 +1,103 @@ +#pragma once + +#include "audio_enums.h" +#include "soundlist.h" +#include "Crime.h" + +#define AEHANDLE_IS_FAILED(h) ((h)<0) +#define AEHANDLE_IS_OK(h) ((h)>=0) + +#define NO_AUDIO_PROVIDER -3 +#define AUDIO_PROVIDER_NOT_DETERMINED -99 + +class cAudioScriptObject; +class CEntity; + +class cDMAudio +{ +public: + ~cDMAudio() + { } + + void Initialise(void); + void Terminate(void); + void Service(void); + + int32 CreateEntity(eAudioType type, void *UID); + void DestroyEntity(int32 audioEntity); + void SetEntityStatus(int32 audioEntity, uint8 status); + void PlayOneShot(int32 audioEntity, uint16 oneShot, float volume); + void DestroyAllGameCreatedEntities(void); + + void SetMonoMode(uint8 mono); + void SetMP3BoostVolume(uint8 volume); + void SetEffectsMasterVolume(uint8 volume); + void SetMusicMasterVolume(uint8 volume); + void SetEffectsFadeVol(uint8 volume); + void SetMusicFadeVol(uint8 volume); + + uint8 GetNum3DProvidersAvailable(void); + char *Get3DProviderName(uint8 id); + + int8 AutoDetect3DProviders(void); + + int8 GetCurrent3DProviderIndex(void); + int8 SetCurrent3DProvider(uint8 which); + + void SetSpeakerConfig(int32 config); + + bool IsMP3RadioChannelAvailable(void); + + void ReleaseDigitalHandle(void); + void ReacquireDigitalHandle(void); + + void SetDynamicAcousticModelingStatus(uint8 status); + + bool CheckForAnAudioFileOnCD(void); + + char GetCDAudioDriveLetter(void); + bool IsAudioInitialised(void); + + void ReportCrime(eCrimeType crime, CVector const &pos); + + int32 CreateLoopingScriptObject(cAudioScriptObject *scriptObject); + void DestroyLoopingScriptObject(int32 audioEntity); + void CreateOneShotScriptObject(cAudioScriptObject *scriptObject); + + void PlaySuspectLastSeen(float x, float y, float z); + + void ReportCollision(CEntity *entityA, CEntity *entityB, uint8 surfaceTypeA, uint8 surfaceTypeB, float collisionPower, float velocity); + + void PlayFrontEndSound(uint16 frontend, uint32 volume); + void PlayRadioAnnouncement(uint32 announcement); + void PlayFrontEndTrack(uint32 track, uint8 frontendFlag); + void StopFrontEndTrack(void); + + void ResetTimers(uint32 time); + + void ChangeMusicMode(uint8 mode); + + void PreloadCutSceneMusic(uint32 track); + void PlayPreloadedCutSceneMusic(void); + void StopCutSceneMusic(void); + + void PreloadMissionAudio(uint8 slot, Const char *missionAudio); + uint8 GetMissionAudioLoadingStatus(uint8 slot); + void SetMissionAudioLocation(uint8 slot, float x, float y, float z); + void PlayLoadedMissionAudio(uint8 slot); + bool IsMissionAudioSampleFinished(uint8 slot); + void ClearMissionAudio(uint8 slot); + + uint8 GetRadioInCar(void); + void SetRadioInCar(uint32 radio); + void SetRadioChannel(uint32 radio, int32 pos); + + void SetStartingTrackPositions(uint8 isStartGame); + float *GetListenTimeArray(); + uint32 GetFavouriteRadioStation(); + int32 GetRadioPosition(uint32 station); + void SetPedTalkingStatus(class CPed *ped, uint8 status); + void SetPlayersMood(uint8 mood, uint32 time); + void ShutUpPlayerTalking(uint8 state); +}; +extern cDMAudio DMAudio; diff --git a/src/audio/MusicManager.cpp b/src/audio/MusicManager.cpp new file mode 100644 index 0000000..f2e3cfd --- /dev/null +++ b/src/audio/MusicManager.cpp @@ -0,0 +1,1402 @@ +#include "common.h" +#include <time.h> +#include "soundlist.h" +#include "MusicManager.h" +#include "AudioManager.h" +#include "ControllerConfig.h" +#include "Camera.h" +#include "Font.h" +#include "Hud.h" +#include "ModelIndices.h" +#include "Replay.h" +#include "Pad.h" +#include "Text.h" +#include "Timer.h" +#include "World.h" +#include "sampman.h" +#include "Stats.h" +#include "Script.h" +#include "ZoneCull.h" +#include "Weather.h" +#include "DMAudio.h" +#include "GenericGameStorage.h" + +#if !defined FIX_BUGS && (defined RADIO_SCROLL_TO_PREV_STATION || defined RADIO_OFF_TEXT) +static_assert(false, "R*'s radio implementation is quite buggy, RADIO_SCROLL_TO_PREV_STATION and RADIO_OFF_TEXT won't work without FIX_BUGS"); +#endif + +cMusicManager MusicManager; +int32 gNumRetunePresses; +int32 gRetuneCounter; +bool g_bAnnouncementReadPosAlready; +uint8 RadioStaticCounter = 5; +uint32 RadioStaticTimer; + +CVector vecRiotPosition(300.7f, -322.0f, 12.0f); + +uint32 NewGameRadioTimers[10] = +{ + 948160, + 452150, + 2438150, + 3538230, + 3513100, + 4246050, + 1418050, + 3178240, + 471210, + 0 +}; + +cMusicManager::cMusicManager() +{ + m_bIsInitialised = false; + m_bDisabled = false; + m_nFrontendTrack = NO_TRACK; + m_nPlayingTrack = NO_TRACK; + m_nUpcomingMusicMode = MUSICMODE_DISABLED; + m_nMusicMode = MUSICMODE_DISABLED; + m_bSetNextStation = false; + + for (int i = 0; i < NUM_RADIOS; i++) + aListenTimeArray[i] = 0.0f; + + m_nLastTrackServiceTime = 0.0f; + m_nVolumeLatency = 0; + m_nCurrentVolume = 0; + m_nMaxVolume = 0; + m_nAnnouncement = NO_TRACK; + m_bAnnouncementInProgress = false; +} + +void +cMusicManager::ResetMusicAfterReload() +{ + float afRadioTime[NUM_RADIOS]; + + m_bRadioSetByScript = false; + m_nRadioStationScript = WILDSTYLE; + m_nRadioPosition = -1; + m_nAnnouncement = NO_TRACK; + m_bAnnouncementInProgress = false; + m_bSetNextStation = false; + RadioStaticTimer = 0; + gNumRetunePresses = 0; + gRetuneCounter = 0; + m_nFrontendTrack = NO_TRACK; + m_nPlayingTrack = NO_TRACK; + m_FrontendLoopFlag = false; + m_bTrackChangeStarted = false; + m_nNextTrack = NO_TRACK; + m_nNextLoopFlag = false; + m_bVerifyNextTrackStartedToPlay = false; + m_bGameplayAllowsRadio = false; + m_bRadioStreamReady = false; + nFramesSinceCutsceneEnded = -1; + m_bUserResumedGame = false; + m_bMusicModeChangeStarted = false; + m_bEarlyFrontendTrack = false; + m_nVolumeLatency = 0; + m_nCurrentVolume = 0; + m_nMaxVolume = 0; + + bool bRadioWasEverListened = false; + + for (int i = 0; i < NUM_RADIOS; i++) { + afRadioTime[i] = CStats::GetFavoriteRadioStationList(i); + if (!bRadioWasEverListened && afRadioTime[i] != 0.0f) + bRadioWasEverListened = true; + } + + if (!bRadioWasEverListened) return; + + for (int i = 0; i < NUM_RADIOS; i++) { + aListenTimeArray[i] = afRadioTime[i]; + int32 trackPos = GetSavedRadioStationPosition(i); + if (trackPos != -1) { + if (trackPos > m_aTracks[i].m_nLength) { + debug("Radio Track %d saved position is %d, Length is only %d\n", i, trackPos, m_aTracks[i].m_nLength); + trackPos %= m_aTracks[i].m_nLength; + } + m_aTracks[i].m_nPosition = trackPos; + m_aTracks[i].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode(); + } + } +} + +void +cMusicManager::SetStartingTrackPositions(uint8 isNewGameTimer) +{ + int pos; + + if (IsInitialised()) { + time_t timevalue = time(0); + if (timevalue == -1) { + pos = AudioManager.GetRandomNumber(0); + } else { + tm* pTm = localtime(&timevalue); + if (pTm->tm_sec == 0) + pTm->tm_sec = AudioManager.GetRandomNumber(0); + if (pTm->tm_min == 0) + pTm->tm_min = AudioManager.GetRandomNumber(1); + if (pTm->tm_hour == 0) + pTm->tm_hour = AudioManager.GetRandomNumber(2); + if (pTm->tm_mday == 0) + pTm->tm_mday = AudioManager.GetRandomNumber(3); + if (pTm->tm_mon == 0) + pTm->tm_mon = AudioManager.GetRandomNumber(4); + if (pTm->tm_year == 0) + pTm->tm_year = AudioManager.GetRandomNumber(3); + if (pTm->tm_wday == 0) + pTm->tm_wday = AudioManager.GetRandomNumber(2); + pos = pTm->tm_yday + * pTm->tm_wday + * pTm->tm_year + * pTm->tm_mon + * pTm->tm_mday + * pTm->tm_hour * pTm->tm_hour + * pTm->tm_min * pTm->tm_min + * pTm->tm_sec * pTm->tm_sec * pTm->tm_sec * pTm->tm_sec; + } + + for (int i = 0; i < TOTAL_STREAMED_SOUNDS; i++) { + m_aTracks[i].m_nLength = SampleManager.GetStreamedFileLength(i); + + if (i < STREAMED_SOUND_CITY_AMBIENT && isNewGameTimer) + m_aTracks[i].m_nPosition = NewGameRadioTimers[i]; + else if (i < STREAMED_SOUND_ANNOUNCE_BRIDGE_CLOSED) + m_aTracks[i].m_nPosition = (pos * AudioManager.GetRandomNumber(i % 5)) % m_aTracks[i].m_nLength; + else + m_aTracks[i].m_nPosition = 0; + + m_aTracks[i].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode(); + } + } +} + +bool +cMusicManager::Initialise() +{ + if (!IsInitialised()) { + m_bIsInitialised = true; + SetStartingTrackPositions(false); + m_bResetTimers = false; + m_nResetTime = 0; + m_bRadioSetByScript = false; + m_nRadioStationScript = WILDSTYLE; + m_nRadioPosition = -1; + m_nRadioInCar = NO_TRACK; + gRetuneCounter = 0; + gNumRetunePresses = 0; + m_nFrontendTrack = NO_TRACK; + m_nPlayingTrack = NO_TRACK; + m_nUpcomingMusicMode = MUSICMODE_DISABLED; + m_nMusicMode = MUSICMODE_DISABLED; + m_FrontendLoopFlag = false; + m_bTrackChangeStarted = false; + m_nNextTrack = NO_TRACK; + m_nNextLoopFlag = false; + m_bVerifyNextTrackStartedToPlay = false; + m_bGameplayAllowsRadio = false; + m_bRadioStreamReady = false; + nFramesSinceCutsceneEnded = -1; + m_bUserResumedGame = false; + m_bMusicModeChangeStarted = false; + m_nMusicModeToBeSet = MUSICMODE_DISABLED; + m_bEarlyFrontendTrack = false; + m_nVolumeLatency = 0; + m_nCurrentVolume = 0; + m_nMaxVolume = 0; + } + return m_bIsInitialised; +} + +void +cMusicManager::Terminate() +{ + if (!IsInitialised()) return; + + if (SampleManager.IsStreamPlaying(0)) { + SampleManager.StopStreamedFile(0); + m_nPlayingTrack = NO_TRACK; + } + m_bIsInitialised = false; +} + +void +cMusicManager::SetRadioChannelByScript(uint32 station, int32 pos) +{ + if (m_bIsInitialised) { + if (station == STREAMED_SOUND_RADIO_MP3_PLAYER) + station = STREAMED_SOUND_CITY_AMBIENT; + if (station <= STREAMED_SOUND_RADIO_POLICE) { + m_bRadioSetByScript = true; + m_nRadioStationScript = station; + m_nRadioPosition = pos == -1 ? -1 : pos % m_aTracks[station].m_nLength; + } + } +} + +bool +cMusicManager::PlayerInCar() +{ + CVehicle *vehicle = AudioManager.FindVehicleOfPlayer(); + if(!vehicle) + return false; + + int32 State = FindPlayerPed()->m_nPedState; + + if(State == PED_DRAG_FROM_CAR || State == PED_EXIT_CAR || State == PED_ARRESTED) + return false; + + if (vehicle->GetStatus() == STATUS_WRECKED) + return false; + + return true; +} + +uint32 +cMusicManager::GetRadioInCar(void) +{ + if (!m_bIsInitialised) return WILDSTYLE; + if (PlayerInCar()) { + CVehicle* veh = AudioManager.FindVehicleOfPlayer(); + if (veh != nil) { + if (UsesPoliceRadio(veh) || UsesTaxiRadio(veh)) { + if (m_nRadioInCar == NO_TRACK || (CReplay::IsPlayingBack() && AudioManager.m_nUserPause == 0)) + return STREAMED_SOUND_RADIO_POLICE; + return m_nRadioInCar; + } + else return veh->m_nRadioStation; + } + } + + if (m_nRadioInCar == NO_TRACK || (CReplay::IsPlayingBack() && AudioManager.m_nUserPause == 0)) + return RADIO_OFF; + return m_nRadioInCar; +} + +void +cMusicManager::SetRadioInCar(uint32 station) +{ + if (m_bIsInitialised) { + if (!PlayerInCar()) { + m_nRadioInCar = station; + return; + } + CVehicle* veh = AudioManager.FindVehicleOfPlayer(); + if (veh == nil) return; + if (UsesPoliceRadio(veh) || UsesTaxiRadio(veh)) + m_nRadioInCar = station; + else + veh->m_nRadioStation = station; + } +} + +void +cMusicManager::RecordRadioStats() +{ + if (m_nPlayingTrack < NUM_RADIOS) { + double time /*Rusty*/ = CTimer::GetTimeInMillisecondsPauseMode(); + if (time > m_nLastTrackServiceTime) + aListenTimeArray[m_nPlayingTrack] += time - m_nLastTrackServiceTime; + } +} + +void +cMusicManager::ChangeMusicMode(uint8 mode) +{ + if (!IsInitialised()) return; + + switch (mode) + { + case MUSICMODE_FRONTEND: m_nUpcomingMusicMode = MUSICMODE_FRONTEND; break; + case MUSICMODE_GAME: m_nUpcomingMusicMode = MUSICMODE_GAME; break; + case MUSICMODE_CUTSCENE: + m_nUpcomingMusicMode = MUSICMODE_CUTSCENE; + if (SampleManager.IsStreamPlaying(0)) { + if (m_nPlayingTrack != NO_TRACK) { + RecordRadioStats(); + m_aTracks[m_nPlayingTrack].m_nPosition = SampleManager.GetStreamedFilePosition(0); + m_aTracks[m_nPlayingTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode(); + } + } + SampleManager.StopStreamedFile(0); + while (SampleManager.IsStreamPlaying(0)) + SampleManager.StopStreamedFile(0); + m_nMusicMode = m_nUpcomingMusicMode; + m_bMusicModeChangeStarted = false; + m_bTrackChangeStarted = false; + m_nNextTrack = NO_TRACK; + m_nNextLoopFlag = false; + m_bVerifyNextTrackStartedToPlay = false; + m_nPlayingTrack = NO_TRACK; + m_nFrontendTrack = NO_TRACK; + m_bAnnouncementInProgress = false; + m_nAnnouncement = NO_TRACK; + g_bAnnouncementReadPosAlready = false; + break; + case MUSICMODE_DISABLE: m_nUpcomingMusicMode = MUSICMODE_DISABLED; break; + default: return; + } +} + +void +cMusicManager::ResetTimers(int32 time) +{ + m_bResetTimers = true; + m_nResetTime = time; +} + +void +cMusicManager::Service() +{ + if (m_bResetTimers) { + m_bResetTimers = false; + m_nLastTrackServiceTime = m_nResetTime; + } + + static bool bRadioStatsRecorded = false; + + if (!m_bIsInitialised || m_bDisabled) return; + + if (!m_bMusicModeChangeStarted) + m_nMusicModeToBeSet = m_nUpcomingMusicMode; + if (m_nMusicModeToBeSet == m_nMusicMode) { + if (!AudioManager.m_nUserPause || AudioManager.m_nPreviousUserPause || m_nMusicMode != MUSICMODE_FRONTEND) + { + switch (m_nMusicMode) + { + case MUSICMODE_FRONTEND: ServiceFrontEndMode(); break; + case MUSICMODE_GAME: ServiceGameMode(); break; + case MUSICMODE_CUTSCENE: SampleManager.SetStreamedVolumeAndPan(MAX_VOLUME, 63, 1, 0); break; + } + } + else + m_nMusicMode = MUSICMODE_DISABLED; + } else { + m_bMusicModeChangeStarted = true; + if (!m_bUserResumedGame && !AudioManager.m_nUserPause && AudioManager.m_nPreviousUserPause) + m_bUserResumedGame = true; + if (AudioManager.m_FrameCounter % 4 == 0) { + gNumRetunePresses = 0; + gRetuneCounter = 0; + m_bSetNextStation = false; + if (SampleManager.IsStreamPlaying(0)) { + if (m_nPlayingTrack != NO_TRACK && !bRadioStatsRecorded) + { + RecordRadioStats(); + m_aTracks[m_nPlayingTrack].m_nPosition = SampleManager.GetStreamedFilePosition(0); + m_aTracks[m_nPlayingTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode(); + bRadioStatsRecorded = true; + } + SampleManager.StopStreamedFile(0); + } else { + bRadioStatsRecorded = false; + m_nMusicMode = m_nMusicModeToBeSet; + m_bMusicModeChangeStarted = false; + m_bTrackChangeStarted = false; + m_nNextTrack = NO_TRACK; + m_nNextLoopFlag = false; + m_bVerifyNextTrackStartedToPlay = false; + m_nPlayingTrack = NO_TRACK; + if (m_bEarlyFrontendTrack) + m_bEarlyFrontendTrack = false; + else + m_nFrontendTrack = NO_TRACK; + } + } + } +} + +void +cMusicManager::ServiceFrontEndMode() +{ + static bool bRadioStatsRecorded = false; + + if (m_bAnnouncementInProgress) { + SampleManager.StopStreamedFile(0); + if (SampleManager.IsStreamPlaying(0)) + return; + g_bAnnouncementReadPosAlready = false; + m_nAnnouncement = NO_TRACK; + m_bAnnouncementInProgress = false; + m_nNextTrack = NO_TRACK; + m_nFrontendTrack = NO_TRACK; + m_nPlayingTrack = NO_TRACK; + } + + if (AudioManager.m_FrameCounter % 4 != 0) return; + + if (!m_bTrackChangeStarted && !m_bVerifyNextTrackStartedToPlay) { + m_nNextTrack = m_nFrontendTrack; + m_nNextLoopFlag = m_FrontendLoopFlag; + } + + if (m_nNextTrack == m_nPlayingTrack) { + if (SampleManager.IsStreamPlaying(0)) { + if (m_nVolumeLatency > 0) m_nVolumeLatency--; + else { + if (m_nCurrentVolume < m_nMaxVolume) + m_nCurrentVolume = Min(m_nMaxVolume, m_nCurrentVolume + 6); + SampleManager.SetStreamedVolumeAndPan(m_nCurrentVolume, 63, 0, 0); + } + } else { + if (m_nPlayingTrack == STREAMED_SOUND_RADIO_MP3_PLAYER) + SampleManager.StartStreamedFile(STREAMED_SOUND_RADIO_MP3_PLAYER, 0, 0); + else if (m_nPlayingTrack == STREAMED_SOUND_MISSION_COMPLETED && AudioManager.m_nUserPause == 0) + ChangeMusicMode(MUSICMODE_GAME); + } + } else { + m_bTrackChangeStarted = true; + if (m_bVerifyNextTrackStartedToPlay || !SampleManager.IsStreamPlaying(0)) { + bRadioStatsRecorded = false; + if (SampleManager.IsStreamPlaying(0) || m_nNextTrack == NO_TRACK) { + m_nPlayingTrack = m_nNextTrack; + m_bVerifyNextTrackStartedToPlay = false; + m_bTrackChangeStarted = false; + } else { + uint32 trackStartPos = (m_nNextTrack > STREAMED_SOUND_RADIO_POLICE) ? 0 : GetTrackStartPos(m_nNextTrack); + if (m_nNextTrack != NO_TRACK) { + SampleManager.SetStreamedFileLoopFlag(m_nNextLoopFlag, 0); + SampleManager.StartStreamedFile(m_nNextTrack, trackStartPos, 0); + m_nVolumeLatency = 3; + m_nCurrentVolume = 0; + m_nMaxVolume = 100; + SampleManager.SetStreamedVolumeAndPan(m_nCurrentVolume, 63, 0, 0); + if (m_nNextTrack < STREAMED_SOUND_CITY_AMBIENT) + m_nLastTrackServiceTime = CTimer::GetTimeInMillisecondsPauseMode(); + m_bVerifyNextTrackStartedToPlay = true; + } + } + } else { + if (m_nPlayingTrack != NO_TRACK && !bRadioStatsRecorded) { + m_aTracks[m_nPlayingTrack].m_nPosition = SampleManager.GetStreamedFilePosition(0); + m_aTracks[m_nPlayingTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode(); + RecordRadioStats(); + bRadioStatsRecorded = true; + } + SampleManager.SetStreamedVolumeAndPan(0, 63, 0, 0); + SampleManager.StopStreamedFile(0); + } + } +} + +void +cMusicManager::ServiceGameMode() +{ + CPed *ped = FindPlayerPed(); + CVehicle *vehicle = AudioManager.FindVehicleOfPlayer(); + m_bRadioStreamReady = m_bGameplayAllowsRadio; + m_bGameplayAllowsRadio = false; + + switch (CGame::currArea) + { + case AREA_HOTEL: + case AREA_MALL: + case AREA_STRIP_CLUB: + case AREA_DIRT: + case AREA_BLOOD: + case AREA_OVALRING: + case AREA_MALIBU_CLUB: + m_bGameplayAllowsRadio = false; + break; + default: + if (SampleManager.GetMusicVolume()) { + if (PlayerInCar()) + m_bGameplayAllowsRadio = true; + } else + m_bGameplayAllowsRadio = false; + break; + } + + if (!m_bGameplayAllowsRadio) { + nFramesSinceCutsceneEnded = -1; + gNumRetunePresses = 0; + gRetuneCounter = 0; + m_bSetNextStation = false; + } else if (ped) { + if(!ped->DyingOrDead() && vehicle) { +#ifdef GTA_PC + if (SampleManager.IsMP3RadioChannelAvailable() + && vehicle->m_nRadioStation < USERTRACK + && ControlsManager.GetIsKeyboardKeyJustDown(rsF9)) + { + if (!UsesPoliceRadio(vehicle) && !UsesTaxiRadio(vehicle)) { + gNumRetunePresses = 0; + gRetuneCounter = 20; + RadioStaticCounter = 0; + if (vehicle->m_nRadioStation < USERTRACK) + { + do + ++gNumRetunePresses; + while (gNumRetunePresses + vehicle->m_nRadioStation < USERTRACK); + } + } + } +#endif + if (CPad::GetPad(0)->ChangeStationJustDown()) + { + if (!UsesPoliceRadio(vehicle) && !UsesTaxiRadio(vehicle)) { + gNumRetunePresses++; + gRetuneCounter = 20; + RadioStaticCounter = 0; + } + } +#ifdef RADIO_SCROLL_TO_PREV_STATION + else if(CPad::GetPad(0)->GetMouseWheelDownJustDown() || CPad::GetPad(0)->GetMouseWheelUpJustDown()) { + if(!UsesPoliceRadio(vehicle) && !UsesTaxiRadio(vehicle)) { + int scrollNext = ControlsManager.GetControllerKeyAssociatedWithAction(VEHICLE_CHANGE_RADIO_STATION, MOUSE); + int scrollPrev = scrollNext == rsMOUSEWHEELUPBUTTON ? rsMOUSEWHEELDOWNBUTTON + : scrollNext == rsMOUSEWHEELDOWNBUTTON ? rsMOUSEWHEELUPBUTTON : -1; + + if(scrollPrev != -1 && !ControlsManager.IsAnyVehicleActionAssignedToMouseKey(scrollPrev)) { + gNumRetunePresses--; + gRetuneCounter = 20; + RadioStaticCounter = 0; + int track = gNumRetunePresses + vehicle->m_nRadioStation; + while(track < 0) track += NUM_RADIOS + 1; + while(track >= NUM_RADIOS + 1) track -= NUM_RADIOS + 1; + if(!DMAudio.IsMP3RadioChannelAvailable() && track == USERTRACK) gNumRetunePresses--; + } + } + } +#endif + } + } + + if (m_bUserResumedGame) + { + m_bRadioStreamReady = false; + m_bUserResumedGame = false; + } + if (m_nPlayingTrack == NO_TRACK && m_nFrontendTrack == NO_TRACK) + m_bRadioStreamReady = false; + + if (m_bGameplayAllowsRadio) + { + if (!m_bRadioStreamReady) + { + if(vehicle == nil) { + m_nFrontendTrack = STREAMED_SOUND_RADIO_WAVE; // huh? + return; + } + if(m_bRadioSetByScript) { + if(UsesPoliceRadio(vehicle)) + m_nFrontendTrack = STREAMED_SOUND_RADIO_POLICE; + else if(UsesTaxiRadio(vehicle)) + m_nFrontendTrack = STREAMED_SOUND_RADIO_TAXI; + else { + m_nFrontendTrack = m_nRadioStationScript; + vehicle->m_nRadioStation = m_nRadioStationScript; + } + if(m_nRadioPosition != -1) { + m_aTracks[m_nFrontendTrack].m_nPosition = m_nRadioPosition; + m_aTracks[m_nFrontendTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode(); + } + m_bRadioSetByScript = false; + return; + } + + // This starts the radio when you enter the car. + m_nFrontendTrack = GetCarTuning(); + return; + } + if (m_nAnnouncement < NO_TRACK) { + if ((m_bAnnouncementInProgress || m_nFrontendTrack == m_nPlayingTrack) && ServiceAnnouncement()) { + if (m_bAnnouncementInProgress) { + m_bSetNextStation = false; + gNumRetunePresses = 0; + gRetuneCounter = 0; + return; + } + if(m_nAnnouncement == NO_TRACK) { + m_nNextTrack = NO_TRACK; + m_nFrontendTrack = GetCarTuning(); + m_bSetNextStation = false; + gRetuneCounter = 0; + gNumRetunePresses = 0; + } + } + } + if (!m_bAnnouncementInProgress + && m_nAnnouncement == NO_TRACK + && m_nPlayingTrack == STREAMED_SOUND_RADIO_MP3_PLAYER + && !SampleManager.IsStreamPlaying(0)) + { + SampleManager.StartStreamedFile(STREAMED_SOUND_RADIO_MP3_PLAYER, 0, 0); + } + + if (!m_bRadioSetByScript) + { + // Because when you switch radio back and forth, gNumRetunePresses will be 0 but gRetuneCounter won't. +#ifdef RADIO_SCROLL_TO_PREV_STATION + if(gRetuneCounter != 0) { + if(gRetuneCounter > 1) + gRetuneCounter--; + else if(gRetuneCounter == 1) { + m_bSetNextStation = true; + gRetuneCounter = 0; + } + } +#else + if (gNumRetunePresses != 0) + { + if (--gRetuneCounter == 0) + { + m_bSetNextStation = true; + gRetuneCounter = 0; + } + } +#endif + if (gRetuneCounter) + { + int32 station = gNumRetunePresses + vehicle->m_nRadioStation; +#ifdef RADIO_SCROLL_TO_PREV_STATION + while (station < 0) station += NUM_RADIOS + 1; +#endif + while (station >= NUM_RADIOS + 1) station -= NUM_RADIOS + 1; + + // Scrolling back won't hit here, so increasing isn't problem + if (!DMAudio.IsMP3RadioChannelAvailable() && station == USERTRACK) + { + ++gNumRetunePresses; + station = RADIO_OFF; + } + if (station == RADIO_OFF) + { + if (gRetuneCounter == 19) // One less then what switching radio sets, so runs right after turning off radio + { + AudioManager.PlayOneShot(AudioManager.m_nFrontEndEntity, SOUND_FRONTEND_RADIO_TURN_OFF, 0.0f); + RadioStaticCounter = 5; + } + } + else + { +#ifdef RADIO_SCROLL_TO_PREV_STATION + if (vehicle->m_nRadioStation == RADIO_OFF && gRetuneCounter == 19) // Right after turning on the radio +#else + if (station == 0 && gRetuneCounter == 19) // Right after turning on the radio +#endif + AudioManager.PlayOneShot(AudioManager.m_nFrontEndEntity, SOUND_FRONTEND_RADIO_TURN_ON, 0.0f); + AudioManager.DoPoliceRadioCrackle(); + } + } + if (RadioStaticCounter < 2 && CTimer::GetTimeInMilliseconds() > RadioStaticTimer + 800) + { + AudioManager.PlayOneShot(AudioManager.m_nFrontEndEntity, SOUND_RADIO_CHANGE, 0.0f); + RadioStaticCounter++; + RadioStaticTimer = CTimer::GetTimeInMilliseconds(); + } + if (m_bSetNextStation) + m_nFrontendTrack = GetNextCarTuning(); + if (m_nFrontendTrack >= STREAMED_SOUND_CITY_AMBIENT && m_nFrontendTrack <= STREAMED_SOUND_AMBSIL_AMBIENT) + SetUpCorrectAmbienceTrack(); + ServiceTrack(vehicle, ped); + if (m_bSetNextStation) + m_bSetNextStation = false; + return; + } + if (UsesPoliceRadio(vehicle)) + m_nFrontendTrack = STREAMED_SOUND_RADIO_POLICE; + else if (UsesTaxiRadio(vehicle)) + m_nFrontendTrack = STREAMED_SOUND_RADIO_TAXI; + else { + m_nFrontendTrack = m_nRadioStationScript; + vehicle->m_nRadioStation = m_nRadioStationScript; + } + + if (m_nRadioPosition != -1) { + m_aTracks[m_nFrontendTrack].m_nPosition = m_nRadioPosition; + m_aTracks[m_nFrontendTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode(); + } + + gRetuneCounter = 0; + gNumRetunePresses = 0; + m_bSetNextStation = false; + m_bRadioSetByScript = false; + if (m_nFrontendTrack >= STREAMED_SOUND_CITY_AMBIENT && m_nFrontendTrack <= STREAMED_SOUND_AMBSIL_AMBIENT) + SetUpCorrectAmbienceTrack(); + ServiceTrack(vehicle, ped); + if (m_bSetNextStation) + m_bSetNextStation = false; + return; + } + + if (m_bAnnouncementInProgress) + { + SampleManager.StopStreamedFile(0); + if (SampleManager.IsStreamPlaying(0)) + return; + g_bAnnouncementReadPosAlready = false; + m_nAnnouncement = NO_TRACK; + m_bAnnouncementInProgress = false; + m_nNextTrack = NO_TRACK; + m_nFrontendTrack = NO_TRACK; + m_nPlayingTrack = NO_TRACK; + } + SetUpCorrectAmbienceTrack(); + ServiceTrack(nil, ped); +} + +void +cMusicManager::SetUpCorrectAmbienceTrack() +{ + switch (CGame::currArea) + { + case AREA_MAIN_MAP: + case AREA_EVERYWHERE: + if (CTheScripts::RiotIntensity != 0 && ((TheCamera.GetPosition() - vecRiotPosition).MagnitudeSqr() < SQR(65.0f))) + m_nFrontendTrack = STREAMED_SOUND_LAW4RIOT_AMBIENT; + else if (TheCamera.DistanceToWater <= 90.0f) { + if (CCullZones::bAtBeachForAudio) { + if (CWeather::OldWeatherType != WEATHER_HURRICANE && CWeather::NewWeatherType != WEATHER_HURRICANE || CWeather::Wind <= 1.0f) + m_nFrontendTrack = STREAMED_SOUND_BEACH_AMBIENT; + else + m_nFrontendTrack = STREAMED_SOUND_HAVANA_BEACH_AMBIENT; + } + else if (CWeather::OldWeatherType != WEATHER_HURRICANE && CWeather::NewWeatherType != WEATHER_HURRICANE || CWeather::Wind <= 1.0f) + m_nFrontendTrack = STREAMED_SOUND_WATER_AMBIENT; + else + m_nFrontendTrack = STREAMED_SOUND_HAVANA_WATER_AMBIENT; + } + else if (CWeather::OldWeatherType != WEATHER_HURRICANE && CWeather::NewWeatherType != WEATHER_HURRICANE || CWeather::Wind <= 1.0f) + m_nFrontendTrack = STREAMED_SOUND_CITY_AMBIENT; + else + m_nFrontendTrack = STREAMED_SOUND_HAVANA_CITY_AMBIENT; + break; + case AREA_HOTEL: + m_nFrontendTrack = STREAMED_SOUND_HOTEL_AMBIENT; + break; + case AREA_MALL: + m_nFrontendTrack = STREAMED_SOUND_MALL_AMBIENT; + break; + case AREA_STRIP_CLUB: + m_nFrontendTrack = STREAMED_SOUND_STRIPCLUB_AMBIENT; + break; + case AREA_DIRT: + case AREA_BLOOD: + case AREA_OVALRING: + m_nFrontendTrack = STREAMED_SOUND_DIRTRING_AMBIENT; + break; + case AREA_MALIBU_CLUB: + m_nFrontendTrack = STREAMED_SOUND_MALIBU_AMBIENT; + break; + case AREA_MANSION: + case AREA_BANK: + case AREA_LAWYERS: + case AREA_COFFEE_SHOP: + case AREA_CONCERT_HALL: + case AREA_STUDIO: + case AREA_RIFLE_RANGE: + case AREA_BIKER_BAR: + case AREA_POLICE_STATION: + m_nFrontendTrack = STREAMED_SOUND_AMBSIL_AMBIENT; + break; + } +} + +float +GetHeightScale() +{ + if (TheCamera.GetPosition().z > 20.0f) { + if (TheCamera.GetPosition().z < 50.0f) + return 1.0f - (TheCamera.GetPosition().z - 20.0f) / 30.0f; + return 0.0f; + } + return 1.0f; +} + +void +cMusicManager::ComputeAmbienceVol(uint8 reset, uint8& outVolume) +{ + static float fVol = 0.0f; + + float fHeightScale = GetHeightScale(); + + if (CTheScripts::RiotIntensity > 0) { + float distToRiotSq = (TheCamera.GetPosition() - vecRiotPosition).MagnitudeSqr(); + if (distToRiotSq < SQR(100.0f)) { + if (distToRiotSq >= SQR(65.0f)) + outVolume = (Sqrt(distToRiotSq) - 65.0f) / 35.0f * (127.0f * fHeightScale); + else if (distToRiotSq >= SQR(20.0f)) + outVolume = (CTheScripts::RiotIntensity * (1.0f - (Sqrt(distToRiotSq) - 20.0f) / 45.0f) * (127.0f * fHeightScale)) / MAX_VOLUME; + else + outVolume = (CTheScripts::RiotIntensity * (127.0f * fHeightScale)) / MAX_VOLUME; + return; + } + } + + if (reset) + fVol = 0.0f; + else if (fVol < 60.0f) { + if ((m_nPlayingTrack >= STREAMED_SOUND_HAVANA_CITY_AMBIENT) && (m_nPlayingTrack <= STREAMED_SOUND_HAVANA_BEACH_AMBIENT)) + fVol += 20.0f; + else + fVol += 1.0f; + fVol = Min(fVol, 60.0f); + } + + if ((m_nPlayingTrack >= STREAMED_SOUND_MALL_AMBIENT) && (m_nPlayingTrack <= STREAMED_SOUND_AMBSIL_AMBIENT)) { + outVolume = fVol; + return; + } + + if (CWeather::OldWeatherType == WEATHER_HURRICANE || CWeather::NewWeatherType == WEATHER_HURRICANE) { + if (CWeather::Wind > 1.0f) { + outVolume = (CWeather::Wind - 1.0f) * fVol; + return; + } + fVol = (1.0f - CWeather::Wind) * fVol; + } + + if (TheCamera.DistanceToWater > 140.0f) { + outVolume = fVol; + return; + } + + if (TheCamera.DistanceToWater > 90.0f) { + outVolume = ((TheCamera.DistanceToWater - 90.0f) / 50.0f * fVol * fHeightScale); + return; + } + + if (TheCamera.DistanceToWater > 40.0f) { + outVolume = fVol; + return; + } + + outVolume = (90.0f - fHeightScale) / 50.0f * fVol; +} + +bool +cMusicManager::ServiceAnnouncement() +{ + if (m_bAnnouncementInProgress) { + if (SampleManager.IsStreamPlaying(0)) + m_nPlayingTrack = m_nNextTrack; + else if (m_nPlayingTrack != NO_TRACK) { + m_nAnnouncement = NO_TRACK; + m_bAnnouncementInProgress = false; + m_nPlayingTrack = NO_TRACK; + } + return true; + } else if (SampleManager.IsStreamPlaying(0)) { + if (m_nPlayingTrack != NO_TRACK && !g_bAnnouncementReadPosAlready) { + RecordRadioStats(); + m_aTracks[m_nPlayingTrack].m_nPosition = SampleManager.GetStreamedFilePosition(0); + g_bAnnouncementReadPosAlready = true; + m_aTracks[m_nPlayingTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode(); + } + SampleManager.StopStreamedFile(0); + } else { + g_bAnnouncementReadPosAlready = false; + m_nPlayingTrack = NO_TRACK; + m_nNextTrack = m_nAnnouncement; + SampleManager.SetStreamedFileLoopFlag(0, 0); + SampleManager.StartStreamedFile(m_nNextTrack, 0, 0); + SampleManager.SetStreamedVolumeAndPan(MAX_VOLUME, 63, 0, 0); + m_bAnnouncementInProgress = true; + } + + return true; +} + +void +cMusicManager::ServiceTrack(CVehicle *veh, CPed *ped) +{ + static bool bRadioStatsRecorded = false; + static bool bRadioStatsRecorded2 = false; + uint8 volume; + if (!m_bTrackChangeStarted) + m_nNextTrack = m_nFrontendTrack; + if (gRetuneCounter != 0 || m_bSetNextStation) { + if (SampleManager.IsStreamPlaying(0)) { + if (m_nPlayingTrack != NO_TRACK && !bRadioStatsRecorded) { + m_aTracks[m_nPlayingTrack].m_nPosition = SampleManager.GetStreamedFilePosition(0); + m_aTracks[m_nPlayingTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode(); + RecordRadioStats(); + bRadioStatsRecorded = true; + } + SampleManager.SetStreamedVolumeAndPan(0, 63, 0, 0); + SampleManager.StopStreamedFile(0); + } + return; + } + + if (bRadioStatsRecorded) { + bRadioStatsRecorded = false; + m_nPlayingTrack = NO_TRACK; + } + + if (m_nNextTrack != m_nPlayingTrack) + { + m_bTrackChangeStarted = true; + SampleManager.SetStreamedVolumeAndPan(0, 63, 0, 0); + if (!(AudioManager.m_FrameCounter & 1)) { + if (m_bVerifyNextTrackStartedToPlay || !SampleManager.IsStreamPlaying(0)) { + bRadioStatsRecorded2 = false; + if (SampleManager.IsStreamPlaying(0)) { + m_nPlayingTrack = m_nNextTrack; + m_bVerifyNextTrackStartedToPlay = false; + m_bTrackChangeStarted = false; + if (veh) { +#ifdef FIX_BUGS + if (m_nPlayingTrack >= STREAMED_SOUND_CITY_AMBIENT && m_nPlayingTrack <= STREAMED_SOUND_AMBSIL_AMBIENT) + veh->m_nRadioStation = RADIO_OFF; + else if (m_nPlayingTrack < STREAMED_SOUND_CITY_AMBIENT) + veh->m_nRadioStation = m_nPlayingTrack; +#else + if (veh->m_nRadioStation >= STREAMED_SOUND_CITY_AMBIENT && veh->m_nRadioStation <= STREAMED_SOUND_AMBSIL_AMBIENT) + veh->m_nRadioStation = RADIO_OFF; + else + veh->m_nRadioStation = m_nPlayingTrack; +#endif + } + } else { + uint32 pos = GetTrackStartPos(m_nNextTrack); + if (m_nNextTrack != NO_TRACK) { + SampleManager.SetStreamedFileLoopFlag(1, 0); + SampleManager.StartStreamedFile(m_nNextTrack, pos, 0); + if (m_nFrontendTrack < STREAMED_SOUND_CITY_AMBIENT || m_nFrontendTrack > STREAMED_SOUND_AMBSIL_AMBIENT) + { + m_nVolumeLatency = 10; + m_nCurrentVolume = 0; + m_nMaxVolume = 100; + SampleManager.SetStreamedVolumeAndPan(m_nCurrentVolume, 63, 0, 0); + } + else + { + ComputeAmbienceVol(true, volume); + SampleManager.SetStreamedVolumeAndPan(volume, 63, 1, 0); + } + if (m_nNextTrack < STREAMED_SOUND_CITY_AMBIENT) + m_nLastTrackServiceTime = CTimer::GetTimeInMillisecondsPauseMode(); + m_bVerifyNextTrackStartedToPlay = true; + } + } + } else { + if (m_nPlayingTrack == NO_TRACK) + debug("m_nPlayingTrack == NO_TRACK, yet track playing - tidying up\n"); + else if (!bRadioStatsRecorded2) + { + m_aTracks[m_nPlayingTrack].m_nPosition = SampleManager.GetStreamedFilePosition(0); + m_aTracks[m_nPlayingTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode(); + bRadioStatsRecorded2 = true; + RecordRadioStats(); + if (m_nPlayingTrack >= STREAMED_SOUND_HAVANA_CITY_AMBIENT && m_nPlayingTrack <= STREAMED_SOUND_HAVANA_BEACH_AMBIENT) + { + if (m_nNextTrack >= STREAMED_SOUND_HAVANA_CITY_AMBIENT && m_nNextTrack <= STREAMED_SOUND_HAVANA_BEACH_AMBIENT) + AudioManager.PlayOneShot(AudioManager.m_nFrontEndEntity, SOUND_FRONTEND_HURRICANE, 0.0); + } + } + SampleManager.SetStreamedVolumeAndPan(0, 63, 0, 0); + SampleManager.StopStreamedFile(0); + } + } + return; + } + + if (m_nPlayingTrack >= STREAMED_SOUND_CITY_AMBIENT && m_nPlayingTrack <= STREAMED_SOUND_AMBSIL_AMBIENT) + { + ComputeAmbienceVol(false, volume); + SampleManager.SetStreamedVolumeAndPan(volume, 63, 1, 0); + return; + } + if (CTimer::GetIsSlowMotionActive()) + { + if (TheCamera.pTargetEntity) + { + float DistToTargetSq = (TheCamera.pTargetEntity->GetPosition() - TheCamera.GetPosition()).MagnitudeSqr(); + if (DistToTargetSq >= SQR(55.0f)) + { + SampleManager.SetStreamedVolumeAndPan(0, 63, 0, 0); + } + else if (DistToTargetSq >= SQR(10.0f)) + { + volume = (45.0f - (Sqrt(DistToTargetSq) - 10.0f)) / 45.0f * m_nCurrentVolume; + if (AudioManager.ShouldDuckMissionAudio(0) || AudioManager.ShouldDuckMissionAudio(1)) + volume /= 4; + + uint8 pan = 0; + if (volume > 0) + { + CVector panVec; + AudioManager.TranslateEntity(&TheCamera.pTargetEntity->GetPosition(), &panVec); + pan = AudioManager.ComputePan(55.0f, &panVec); + } + if (gRetuneCounter != 0) + volume = 0; + SampleManager.SetStreamedVolumeAndPan(volume, pan, 0, 0); + } + else if (AudioManager.ShouldDuckMissionAudio(0) || AudioManager.ShouldDuckMissionAudio(1)) + SampleManager.SetStreamedVolumeAndPan(m_nCurrentVolume, 63, 0, 0); + else if (gRetuneCounter != 0) + SampleManager.SetStreamedVolumeAndPan(0, 63, 0, 0); + else + SampleManager.SetStreamedVolumeAndPan(m_nCurrentVolume, 63, 0, 0); + } + } else if (AudioManager.ShouldDuckMissionAudio(0) || AudioManager.ShouldDuckMissionAudio(1)) { + SampleManager.SetStreamedVolumeAndPan(Min(m_nCurrentVolume, 25), 63, 0, 0); + nFramesSinceCutsceneEnded = 0; + } else { + if (nFramesSinceCutsceneEnded == -1) + volume = m_nCurrentVolume; + else if (nFramesSinceCutsceneEnded < 20) + { + volume = Min(m_nCurrentVolume, 25); + nFramesSinceCutsceneEnded++; + } + else if (nFramesSinceCutsceneEnded < 40) + { + volume = Min(m_nCurrentVolume, 3 * (nFramesSinceCutsceneEnded - 20) + 25); + nFramesSinceCutsceneEnded++; + } + else + { + volume = m_nCurrentVolume; + nFramesSinceCutsceneEnded = -1; + } + if (gRetuneCounter != 0) + volume = 0; + SampleManager.SetStreamedVolumeAndPan(volume, 63, 0, 0); + } + if (m_nVolumeLatency > 0) + m_nVolumeLatency--; + else if (m_nCurrentVolume < m_nMaxVolume) + m_nCurrentVolume = Min(m_nMaxVolume, m_nCurrentVolume + 6); +} + +void +cMusicManager::PreloadCutSceneMusic(uint32 track) +{ + if (IsInitialised() && !m_bDisabled && track < TOTAL_STREAMED_SOUNDS && m_nMusicMode == MUSICMODE_CUTSCENE) { + AudioManager.ResetPoliceRadio(); + while (SampleManager.IsStreamPlaying(0)) + SampleManager.StopStreamedFile(0); + SampleManager.PreloadStreamedFile(track, 0); + SampleManager.SetStreamedVolumeAndPan(MAX_VOLUME, 63, 1, 0); + m_nPlayingTrack = track; + } +} + +void +cMusicManager::PlayPreloadedCutSceneMusic(void) +{ + if (IsInitialised() && !m_bDisabled && m_nMusicMode == MUSICMODE_CUTSCENE) + SampleManager.StartPreloadedStreamedFile(0); +} + +void +cMusicManager::StopCutSceneMusic(void) +{ + if (IsInitialised() && !m_bDisabled && m_nMusicMode == MUSICMODE_CUTSCENE) { + SampleManager.StopStreamedFile(0); + m_nPlayingTrack = NO_TRACK; + } +} + +void +cMusicManager::PlayFrontEndTrack(uint32 track, uint8 loopFlag) +{ + if (IsInitialised() && !m_bDisabled && track < TOTAL_STREAMED_SOUNDS && (m_nUpcomingMusicMode == MUSICMODE_FRONTEND || m_nMusicMode == MUSICMODE_FRONTEND)) + { + m_nFrontendTrack = track; + m_FrontendLoopFlag = loopFlag; + if (m_nMusicMode != MUSICMODE_FRONTEND) + m_bEarlyFrontendTrack = true; + } +} + +void +cMusicManager::StopFrontEndTrack() +{ + if (m_nUpcomingMusicMode == MUSICMODE_FRONTEND || m_nMusicMode == MUSICMODE_FRONTEND) + m_nFrontendTrack = NO_TRACK; +} + +void +cMusicManager::PlayAnnouncement(uint32 announcement) +{ + if (IsInitialised() && !m_bDisabled && !m_bAnnouncementInProgress) + m_nAnnouncement = announcement; +} + +uint32 +cMusicManager::GetNextCarTuning() +{ + CVehicle *veh = AudioManager.FindVehicleOfPlayer(); + if (veh == nil) return STREAMED_SOUND_CITY_AMBIENT; + if (UsesPoliceRadio(veh)) return STREAMED_SOUND_RADIO_POLICE; + if (UsesTaxiRadio(veh)) return STREAMED_SOUND_RADIO_TAXI; + if (gNumRetunePresses != 0) { +#ifdef RADIO_SCROLL_TO_PREV_STATION + // m_nRadioStation is unsigned, so... + int station = veh->m_nRadioStation + gNumRetunePresses; + while(station < 0) station += NUM_RADIOS + 1; + while(station >= NUM_RADIOS + 1) station -= NUM_RADIOS + 1; + veh->m_nRadioStation = station; +#else + veh->m_nRadioStation += gNumRetunePresses; + while(veh->m_nRadioStation >= NUM_RADIOS + 1) + veh->m_nRadioStation -= NUM_RADIOS + 1; +#endif + DMAudio.IsMP3RadioChannelAvailable(); // woof, just call and do nothing =P they manipulate gNumRetunePresses on DisplayRadioStationName in this case + gNumRetunePresses = 0; + } + return veh->m_nRadioStation; +} + +uint32 +cMusicManager::GetCarTuning() +{ + CVehicle* veh = AudioManager.FindVehicleOfPlayer(); + if (veh == nil) return STREAMED_SOUND_CITY_AMBIENT; + if (UsesPoliceRadio(veh)) return STREAMED_SOUND_RADIO_POLICE; + if (UsesTaxiRadio(veh)) return STREAMED_SOUND_RADIO_TAXI; + if (veh->m_nRadioStation == USERTRACK && !SampleManager.IsMP3RadioChannelAvailable()) + veh->m_nRadioStation = AudioManager.GetRandomNumber(2) % USERTRACK; + return veh->m_nRadioStation; +} + +float* +cMusicManager::GetListenTimeArray() +{ + return aListenTimeArray; +} + +uint32 +cMusicManager::GetTrackStartPos(uint32 track) +{ + if (!IsInitialised()) return 0; + + uint32 pos = m_aTracks[track].m_nPosition; + if (CTimer::GetTimeInMillisecondsPauseMode() > m_aTracks[track].m_nLastPosCheckTimer) + pos += Min(CTimer::GetTimeInMillisecondsPauseMode() - m_aTracks[track].m_nLastPosCheckTimer, 270000); + else + m_aTracks[track].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode(); + + if (pos > m_aTracks[track].m_nLength) + pos %= m_aTracks[track].m_nLength; + return pos; +} + +uint32 +cMusicManager::GetRadioPosition(uint32 station) +{ + if (station < NUM_RADIOS) + return GetTrackStartPos(station); + return 0; +} + +uint32 +cMusicManager::GetFavouriteRadioStation() +{ + uint32 favstation = 0; + + for (int i = 1; i < NUM_RADIOS; i++) { + if (aListenTimeArray[i] > aListenTimeArray[favstation]) + favstation = i; + } + + return favstation; +} + +bool +cMusicManager::CheckForMusicInterruptions() +{ + return (m_nPlayingTrack == STREAMED_SOUND_MISSION_COMPLETED) || (m_nPlayingTrack == STREAMED_SOUND_CUTSCENE_FINALE); +} + +void +cMusicManager::SetMalibuClubTrackPos(uint8 scriptObject) +{ + if (!IsInitialised()) + m_aTracks[STREAMED_SOUND_MALIBU_AMBIENT].m_nPosition = 8640; + if (m_nNextTrack != STREAMED_SOUND_MALIBU_AMBIENT && m_nPlayingTrack != STREAMED_SOUND_MALIBU_AMBIENT) { + switch (scriptObject) + { + case SCRIPT_SOUND_NEW_BUILDING_MALIBU_1: + m_aTracks[STREAMED_SOUND_MALIBU_AMBIENT].m_nPosition = (AudioManager.m_anRandomTable[0] % 128) + 8640; + break; + case SCRIPT_SOUND_NEW_BUILDING_MALIBU_2: + m_aTracks[STREAMED_SOUND_MALIBU_AMBIENT].m_nPosition = (AudioManager.m_anRandomTable[0] % 128) + 286720; + break; + case SCRIPT_SOUND_NEW_BUILDING_MALIBU_3: + m_aTracks[STREAMED_SOUND_MALIBU_AMBIENT].m_nPosition = (AudioManager.m_anRandomTable[0] % 128) + 509120; + break; + } + m_aTracks[STREAMED_SOUND_MALIBU_AMBIENT].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode(); + } +} + +void +cMusicManager::SetStripClubTrackPos(uint8 scriptObject) +{ + if (!IsInitialised()) + m_aTracks[STREAMED_SOUND_STRIPCLUB_AMBIENT].m_nPosition = 0; + if (m_nNextTrack != STREAMED_SOUND_STRIPCLUB_AMBIENT && m_nPlayingTrack != STREAMED_SOUND_STRIPCLUB_AMBIENT) + { + switch (scriptObject) + { + case SCRIPT_SOUND_NEW_BUILDING_STRIP_1: + m_aTracks[STREAMED_SOUND_STRIPCLUB_AMBIENT].m_nPosition = AudioManager.m_anRandomTable[0] % 128; + break; + case SCRIPT_SOUND_NEW_BUILDING_STRIP_2: + m_aTracks[STREAMED_SOUND_STRIPCLUB_AMBIENT].m_nPosition = (AudioManager.m_anRandomTable[0] % 128) + 320200; + break; + case SCRIPT_SOUND_NEW_BUILDING_STRIP_3: + m_aTracks[STREAMED_SOUND_STRIPCLUB_AMBIENT].m_nPosition = (AudioManager.m_anRandomTable[0] % 128) + 672000; + break; + } + m_aTracks[STREAMED_SOUND_STRIPCLUB_AMBIENT].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode(); + } +} + +void +cMusicManager::DisplayRadioStationName() +{ + uint8 gStreamedSound; + static wchar *pCurrentStation = nil; + static uint8 cDisplay = 0; + + if(!CTimer::GetIsPaused() && !TheCamera.m_WideScreenOn && PlayerInCar() && + !CReplay::IsPlayingBack()) { + CVehicle *vehicle = AudioManager.FindVehicleOfPlayer(); + + if (vehicle) + { +#if defined RADIO_SCROLL_TO_PREV_STATION || defined FIX_BUGS // Because m_nFrontendTrack can have NO_TRACK + int track; +#else + uint8 track; +#endif + gStreamedSound = vehicle->m_nRadioStation; + if (gStreamedSound >= STREAMED_SOUND_CITY_AMBIENT && gStreamedSound <= STREAMED_SOUND_AMBSIL_AMBIENT) + gStreamedSound = RADIO_OFF; + if (gNumRetunePresses != 0) + { + track = gNumRetunePresses + gStreamedSound; +#ifdef RADIO_SCROLL_TO_PREV_STATION + while (track < 0) track += NUM_RADIOS + 1; +#endif + while (track >= NUM_RADIOS + 1) track -= NUM_RADIOS + 1; + + // We already handle this condition while scrolling back, on key press. No need to change this. + if (!DMAudio.IsMP3RadioChannelAvailable() && track == USERTRACK) + gNumRetunePresses++; + } + else + track = m_nFrontendTrack; + + wchar* string = nil; + switch (track) { + case WILDSTYLE: string = TheText.Get("FEA_FM0"); break; + case FLASH_FM: string = TheText.Get("FEA_FM1"); break; + case KCHAT: string = TheText.Get("FEA_FM2"); break; + case FEVER: string = TheText.Get("FEA_FM3"); break; + case V_ROCK: string = TheText.Get("FEA_FM4"); break; + case VCPR: string = TheText.Get("FEA_FM5"); break; + case RADIO_ESPANTOSO: string = TheText.Get("FEA_FM6"); break; + case EMOTION: string = TheText.Get("FEA_FM7"); break; + case WAVE: string = TheText.Get("FEA_FM8"); break; + case USERTRACK: + if (!SampleManager.IsMP3RadioChannelAvailable()) + return; + string = TheText.Get("FEA_MP3"); break; +#ifdef RADIO_OFF_TEXT + case STREAMED_SOUND_RADIO_POLICE: + case STREAMED_SOUND_RADIO_TAXI: + return; + default: { + // Otherwise pausing-resuming game will show RADIO OFF, since radio isn't set yet + if (m_nPlayingTrack == NO_TRACK && m_nFrontendTrack == NO_TRACK) + return; + + extern wchar WideErrorString[]; + + string = TheText.Get("FEA_NON"); + if (string == WideErrorString) { + pCurrentStation = nil; + return; + } + break; + } +#else + default: return; +#endif + }; + + if (pCurrentStation != string) { + pCurrentStation = string; + cDisplay = 60; + } + else { + if (cDisplay == 0) return; + cDisplay--; + } + + CFont::SetJustifyOff(); + CFont::SetBackgroundOff(); + CFont::SetScale(SCREEN_SCALE_X(0.8f), SCREEN_SCALE_Y(1.35f)); + CFont::SetPropOn(); + CFont::SetFontStyle(FONT_STANDARD); + CFont::SetCentreOn(); + CFont::SetCentreSize(SCREEN_STRETCH_X(DEFAULT_SCREEN_WIDTH)); + CFont::SetColor(CRGBA(0, 0, 0, 255)); + CFont::PrintString(SCREEN_WIDTH / 2 + SCREEN_SCALE_X(2.0f), SCREEN_SCALE_Y(22.0f) + SCREEN_SCALE_Y(2.0f), pCurrentStation); + + if (gNumRetunePresses) + CFont::SetColor(CRGBA(102, 133, 143, 255)); + else + CFont::SetColor(CRGBA(147, 196, 211, 255)); + + CFont::PrintString(SCREEN_WIDTH / 2, SCREEN_SCALE_Y(22.0f), pCurrentStation); + CFont::DrawFonts(); + } + } + // Always show station text after entering car. Same behaviour as III and SA. +#ifdef FIX_BUGS + else + pCurrentStation = nil; +#endif +} + +bool +cMusicManager::UsesPoliceRadio(CVehicle *veh) +{ + switch (veh->GetModelIndex()) + { + case MI_VCNMAV: + case MI_POLMAV: + case MI_COASTG: + case MI_RHINO: + case MI_BARRACKS: + return true; + case MI_MRWHOOP: + case MI_HUNTER: + return false; + } + return veh->UsesSiren(); +} + +bool +cMusicManager::UsesTaxiRadio(CVehicle *veh) +{ + if (veh->GetModelIndex() != MI_KAUFMAN) return false; + return CTheScripts::bPlayerHasMetDebbieHarry; +} + +void +cMusicManager::ServiceAmbience() +{ +} + +bool +cMusicManager::ChangeRadioChannel() +{ + return true; +} + +// these two are empty +void cMusicManager::Enable() {} +void cMusicManager::Disable() {} diff --git a/src/audio/MusicManager.h b/src/audio/MusicManager.h new file mode 100644 index 0000000..27456d7 --- /dev/null +++ b/src/audio/MusicManager.h @@ -0,0 +1,113 @@ +#pragma once + +#include "audio_enums.h" + +class tStreamedSample +{ +public: + uint32 m_nLength; + uint32 m_nPosition; + uint32 m_nLastPosCheckTimer; +}; + +class CVehicle; +class CPed; + +class cMusicManager +{ +public: + bool m_bIsInitialised; + bool m_bDisabled; + bool m_bSetNextStation; + uint8 m_nVolumeLatency; + uint8 m_nCurrentVolume; + uint8 m_nMaxVolume; + uint32 m_nAnnouncement; + bool m_bAnnouncementInProgress; + tStreamedSample m_aTracks[TOTAL_STREAMED_SOUNDS]; + bool m_bResetTimers; + uint32 m_nResetTime; + bool m_bRadioSetByScript; + uint8 m_nRadioStationScript; + int32 m_nRadioPosition; + uint32 m_nRadioInCar; + uint32 m_nFrontendTrack; + uint32 m_nPlayingTrack; + uint8 m_nUpcomingMusicMode; + uint8 m_nMusicMode; + bool m_FrontendLoopFlag; + bool m_bTrackChangeStarted; + uint32 m_nNextTrack; + bool m_nNextLoopFlag; + bool m_bVerifyNextTrackStartedToPlay; + bool m_bGameplayAllowsRadio; + bool m_bRadioStreamReady; + int8 nFramesSinceCutsceneEnded; + bool m_bUserResumedGame; + bool m_bMusicModeChangeStarted; + uint8 m_nMusicModeToBeSet; + bool m_bEarlyFrontendTrack; + float aListenTimeArray[NUM_RADIOS]; + float m_nLastTrackServiceTime; + +public: + cMusicManager(); + bool IsInitialised() { return m_bIsInitialised; } + uint8 GetMusicMode() { return m_nMusicMode; } + uint32 GetCurrentTrack() { return m_nPlayingTrack; } + + void ResetMusicAfterReload(); + void SetStartingTrackPositions(uint8 isNewGameTimer); + bool Initialise(); + void Terminate(); + + void ChangeMusicMode(uint8 mode); + void StopFrontEndTrack(); + + bool PlayerInCar(); + void DisplayRadioStationName(); + + void PlayAnnouncement(uint32); + void PlayFrontEndTrack(uint32, uint8); + void PreloadCutSceneMusic(uint32); + void PlayPreloadedCutSceneMusic(void); + void StopCutSceneMusic(void); + uint32 GetRadioInCar(void); + void SetRadioInCar(uint32); + void SetRadioChannelByScript(uint32, int32); + + void ResetTimers(int32); + void Service(); + void ServiceFrontEndMode(); + void ServiceGameMode(); + void ServiceAmbience(); + void ServiceTrack(CVehicle *veh, CPed *ped); + + bool UsesPoliceRadio(CVehicle *veh); + bool UsesTaxiRadio(CVehicle *veh); + uint32 GetTrackStartPos(uint32 track); + + void ComputeAmbienceVol(uint8 reset, uint8& outVolume); + bool ServiceAnnouncement(); + + uint32 GetCarTuning(); + uint32 GetNextCarTuning(); + bool ChangeRadioChannel(); + void RecordRadioStats(); + void SetUpCorrectAmbienceTrack(); + float *GetListenTimeArray(); + uint32 GetRadioPosition(uint32 station); + uint32 GetFavouriteRadioStation(); + void SetMalibuClubTrackPos(uint8 pos); + void SetStripClubTrackPos(uint8 pos); + bool CheckForMusicInterruptions(); + + void Enable(); + void Disable(); +}; + +VALIDATE_SIZE(cMusicManager, 0x95C); + +extern cMusicManager MusicManager; +extern bool g_bAnnouncementReadPosAlready; // we have a symbol of this so it was declared in .h +float GetHeightScale(); diff --git a/src/audio/PoliceRadio.cpp b/src/audio/PoliceRadio.cpp new file mode 100644 index 0000000..227d27d --- /dev/null +++ b/src/audio/PoliceRadio.cpp @@ -0,0 +1,747 @@ +#include "common.h" + +#include "DMAudio.h" + +#include "AudioManager.h" + +#include "AudioSamples.h" +#include "MusicManager.h" +#include "PlayerPed.h" +#include "PoliceRadio.h" +#include "Replay.h" +#include "Vehicle.h" +#include "World.h" +#include "Zones.h" +#include "sampman.h" +#include "Wanted.h" + +const int channels = ARRAY_SIZE(AudioManager.m_asActiveSamples); +const int policeChannel = channels + 1; + +struct tPoliceRadioZone { + char m_aName[8]; + uint32 m_nSampleIndex; + int32 field_12; +}; + +tPoliceRadioZone ZoneSfx[NUMAUDIOZONES]; + +int32 g_nMissionAudioSfx = TOTAL_AUDIO_SAMPLES; +int8 g_nMissionAudioPlayingStatus = 2; +uint8 gSpecialSuspectLastSeenReport; +uint32 gMinTimeToNextReport[NUM_CRIME_TYPES]; + +void +cAudioManager::InitialisePoliceRadioZones() +{ + for (int32 i = 0; i < NUMAUDIOZONES; i++) + memset(ZoneSfx[i].m_aName, 0, 8); + +#define SETZONESFX(i, name, sample) \ + strcpy(ZoneSfx[i].m_aName, name); \ + ZoneSfx[i].m_nSampleIndex = sample; + + SETZONESFX(0, "VICE_C", SFX_POLICE_RADIO_VICE_CITY); + SETZONESFX(1, "IND_ZON", SFX_POLICE_RADIO_VICE_CITY_BEACH); + SETZONESFX(2, "COM_ZON", SFX_POLICE_RADIO_VICE_CITY_MAINLAND); + SETZONESFX(3, "BEACH1", SFX_POLICE_RADIO_OCEAN_BEACH); + SETZONESFX(4, "BEACH2", SFX_POLICE_RADIO_WASHINGTON_BEACH); + SETZONESFX(5, "BEACH3", SFX_POLICE_RADIO_VICE_POINT); + SETZONESFX(6, "GOLFC", SFX_POLICE_RADIO_LEAF_LINKS); + SETZONESFX(7, "STARI", SFX_POLICE_RADIO_STRAFISH_ISLAND); + SETZONESFX(8, "DOCKS", SFX_POLICE_RADIO_VICE_PORT); + SETZONESFX(9, "HAVANA", SFX_POLICE_RADIO_LITTLE_HAVANA); + SETZONESFX(10, "HAITI", SFX_POLICE_RADIO_LITTLE_HAITI); + SETZONESFX(11, "PORNI", SFX_POLICE_RADIO_PRAWN_ISLAND); + SETZONESFX(12, "DTOWN", SFX_POLICE_RADIO_DOWNTOWN); + SETZONESFX(13, "A_PORT", SFX_POLICE_RADIO_ESCOBAR_INTERNATIONAL); + +#undef SETZONESFX +} + +void +cAudioManager::InitialisePoliceRadio() +{ + m_sPoliceRadioQueue.policeChannelTimer = 0; + m_sPoliceRadioQueue.policeChannelTimerSeconds = 0; + m_sPoliceRadioQueue.policeChannelCounterSeconds = 0; + for (int32 i = 0; i < ARRAY_SIZE(m_sPoliceRadioQueue.crimes); i++) + m_sPoliceRadioQueue.crimes[i].type = CRIME_NONE; + + SampleManager.SetChannelReverbFlag(policeChannel, false); + gSpecialSuspectLastSeenReport = false; + for (int32 i = 0; i < ARRAY_SIZE(gMinTimeToNextReport); i++) + gMinTimeToNextReport[i] = m_FrameCounter; +} + +void +cAudioManager::ResetPoliceRadio() +{ + if (!m_bIsInitialised) return; + if (SampleManager.GetChannelUsedFlag(policeChannel)) SampleManager.StopChannel(policeChannel); + InitialisePoliceRadio(); +} + +void +cAudioManager::SetMissionScriptPoliceAudio(int32 sfx) const +{ + if (!m_bIsInitialised) return; + if (g_nMissionAudioPlayingStatus != 1) { + g_nMissionAudioPlayingStatus = 0; + g_nMissionAudioSfx = sfx; + } +} + +int8 +cAudioManager::GetMissionScriptPoliceAudioPlayingStatus() const +{ + return g_nMissionAudioPlayingStatus; +} + +void +cAudioManager::DoPoliceRadioCrackle() +{ + m_sQueueSample.m_nEntityIndex = m_nPoliceChannelEntity; + m_sQueueSample.m_nCounter = 0; + m_sQueueSample.m_nSampleIndex = SFX_POLICE_RADIO_CRACKLE; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_bIs2D = true; + m_sQueueSample.m_nReleasingVolumeModificator = 10; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_POLICE_RADIO_CRACKLE); + m_sQueueSample.m_nVolume = m_anRandomTable[2] % 20 + 15; + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nEmittingVolume = m_sQueueSample.m_nVolume; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(SFX_POLICE_RADIO_CRACKLE); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(SFX_POLICE_RADIO_CRACKLE); + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_bReverbFlag = false; + m_sQueueSample.m_nOffset = 63; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + m_sQueueSample.m_bRequireReflection = false; + AddSampleToRequestedQueue(); +} + +void +cAudioManager::ServicePoliceRadio() +{ + int32 wantedLevel = 0; // uninitialized variable + static uint32 nLastSeen = 300; + + if(!m_bIsInitialised) return; + + if(m_nUserPause == 0) { + bool crimeReport = SetupCrimeReport(); +#ifdef FIX_BUGS // Crash at 0x5fe6ef + if(CReplay::IsPlayingBack() || !FindPlayerPed() || !FindPlayerPed()->m_pWanted) + return; +#endif + CPlayerPed *playerPed = FindPlayerPed(); + if (playerPed) { + wantedLevel = playerPed->m_pWanted->GetWantedLevel(); + if (!crimeReport) { + if (wantedLevel != 0) { + if (nLastSeen != 0) + --nLastSeen; + else { + nLastSeen = m_anRandomTable[1] % 1000 + 2000; + SetupSuspectLastSeenReport(); + } + } + } + } + } + ServicePoliceRadioChannel(wantedLevel); +} + +void +cAudioManager::ServicePoliceRadioChannel(uint8 wantedLevel) +{ + bool processed = false; + uint32 sample; + int32 freq; + + static int cWait = 0; + static bool bChannelOpen = false; + static uint8 bMissionAudioPhysicalPlayingStatus = 0; + static int32 PoliceChannelFreq = 22050; + + if (!m_bIsInitialised) return; + + if (m_nUserPause != 0) { + if (SampleManager.GetChannelUsedFlag(policeChannel)) SampleManager.StopChannel(policeChannel); + if (g_nMissionAudioSfx != NO_SAMPLE && bMissionAudioPhysicalPlayingStatus == 1 && + SampleManager.IsStreamPlaying(1)) { + SampleManager.PauseStream(1, 1); + } + } else { + if (m_nPreviousUserPause && g_nMissionAudioSfx != NO_SAMPLE && + bMissionAudioPhysicalPlayingStatus == 1) { + SampleManager.PauseStream(0, 1); + } + if (m_sPoliceRadioQueue.policeChannelTimer == 0) bChannelOpen = false; + if (cWait) { + --cWait; + return; + } + if (g_nMissionAudioSfx != NO_SAMPLE && !bChannelOpen) { + if (g_nMissionAudioPlayingStatus) { + if (g_nMissionAudioPlayingStatus == 1 && !bMissionAudioPhysicalPlayingStatus && + SampleManager.IsStreamPlaying(1)) { + bMissionAudioPhysicalPlayingStatus = 1; + } + if (bMissionAudioPhysicalPlayingStatus == 1) { + if (SampleManager.IsStreamPlaying(1)) { + DoPoliceRadioCrackle(); + } else { + bMissionAudioPhysicalPlayingStatus = 2; + g_nMissionAudioPlayingStatus = 2; + g_nMissionAudioSfx = NO_SAMPLE; + cWait = 30; + } + return; + } + } else if (!SampleManager.GetChannelUsedFlag(policeChannel)) { + SampleManager.PreloadStreamedFile(g_nMissionAudioSfx, 1); + SampleManager.SetStreamedVolumeAndPan(MAX_VOLUME, 63, 1, 1); + SampleManager.StartPreloadedStreamedFile(1); + g_nMissionAudioPlayingStatus = 1; + bMissionAudioPhysicalPlayingStatus = 0; + return; + } + } + if (bChannelOpen) DoPoliceRadioCrackle(); + if ((g_nMissionAudioSfx == NO_SAMPLE || g_nMissionAudioPlayingStatus != 1) && + !SampleManager.GetChannelUsedFlag(policeChannel) && m_sPoliceRadioQueue.policeChannelTimer) { + if (m_sPoliceRadioQueue.policeChannelTimer) { + sample = m_sPoliceRadioQueue.crimesSamples[m_sPoliceRadioQueue.policeChannelCounterSeconds]; + m_sPoliceRadioQueue.policeChannelTimer--; + m_sPoliceRadioQueue.policeChannelCounterSeconds = (m_sPoliceRadioQueue.policeChannelCounterSeconds + 1) % 60; + } else { + sample = NO_SAMPLE; + } + if (wantedLevel == 0) { + if (gSpecialSuspectLastSeenReport) { + gSpecialSuspectLastSeenReport = 0; + } else if (sample == SFX_POLICE_RADIO_MESSAGE_NOISE_1) { + bChannelOpen = false; + processed = true; + } + } + if (sample == NO_SAMPLE) { + if (!processed) cWait = 30; + } else { + SampleManager.InitialiseChannel(policeChannel, sample, 0); + switch (sample) { + case SFX_POLICE_RADIO_MESSAGE_NOISE_1: + freq = m_anRandomTable[4] % 2000 + 10025; + bChannelOpen = bChannelOpen == false; + break; + default: freq = SampleManager.GetSampleBaseFrequency(sample); break; + } + PoliceChannelFreq = freq; + SampleManager.SetChannelFrequency(policeChannel, freq); + SampleManager.SetChannelVolume(policeChannel, 100); + SampleManager.SetChannelPan(policeChannel, 63); + SampleManager.SetChannelLoopCount(policeChannel, 1); + SampleManager.SetChannelLoopPoints(policeChannel, 0, -1); + SampleManager.StartChannel(policeChannel); + } + if (processed) ResetPoliceRadio(); + } + } +} + +bool +cAudioManager::SetupCrimeReport() +{ + int16 audioZoneId; + CZone *zone; + float rangeX; + float rangeY; + float halfX; + float halfY; + float quarterX; + float quarterY; + int i; + int32 sampleIndex; + bool processed = false; + + if (MusicManager.m_nMusicMode == MUSICMODE_CUTSCENE) return false; + + if (60 - m_sPoliceRadioQueue.policeChannelTimer <= 9) { + AgeCrimes(); + return true; + } + + for (i = 0; i < ARRAY_SIZE(m_sPoliceRadioQueue.crimes); i++) { + if (m_sPoliceRadioQueue.crimes[i].type != CRIME_NONE) + break; + } + + if (i == ARRAY_SIZE(m_sPoliceRadioQueue.crimes)) return false; + audioZoneId = CTheZones::FindAudioZone(&m_sPoliceRadioQueue.crimes[i].position); + if (audioZoneId >= 0 && audioZoneId < NUMAUDIOZONES) { + zone = CTheZones::GetAudioZone(audioZoneId); + for (int j = 0; j < NUMAUDIOZONES; j++) { + if (strcmp(zone->name, ZoneSfx[j].m_aName) == 0) { + sampleIndex = ZoneSfx[j].m_nSampleIndex; + m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_MESSAGE_NOISE_1); + m_sPoliceRadioQueue.Add(m_anRandomTable[0] % 3 + SFX_WEVE_GOT); + m_sPoliceRadioQueue.Add(SFX_A_10); + switch (m_sPoliceRadioQueue.crimes[i].type) { + case CRIME_PED_BURNED: + case CRIME_HIT_PED_NASTYWEAPON: + m_sPoliceRadioQueue.crimes[i].type = CRIME_HIT_PED; + break; + case CRIME_COP_BURNED: + case CRIME_HIT_COP_NASTYWEAPON: + m_sPoliceRadioQueue.crimes[i].type = CRIME_HIT_COP; + break; + case CRIME_VEHICLE_BURNED: m_sPoliceRadioQueue.crimes[i].type = CRIME_STEAL_CAR; break; + case CRIME_DESTROYED_CESSNA: m_sPoliceRadioQueue.crimes[i].type = CRIME_SHOOT_HELI; break; + case CRIME_EXPLOSION: m_sPoliceRadioQueue.crimes[i].type = CRIME_STEAL_CAR; break; // huh? + default: break; + } +#ifdef FIX_BUGS + m_sPoliceRadioQueue.Add(m_sPoliceRadioQueue.crimes[i].type + SFX_CRIME_1 - 1); +#else + m_sPoliceRadioQueue.Add(m_sPoliceRadioQueue.crimes[i].type + SFX_CRIME_1); +#endif + m_sPoliceRadioQueue.Add(SFX_IN); + rangeX = zone->maxx - zone->minx; + rangeY = zone->maxy - zone->miny; + halfX = 0.5f * rangeX + zone->minx; + halfY = 0.5f * rangeY + zone->miny; + quarterX = 0.25f * rangeX; + quarterY = 0.25f * rangeY; + + if (m_sPoliceRadioQueue.crimes[i].position.y > halfY + quarterY) { + m_sPoliceRadioQueue.Add(SFX_NORTH); + processed = true; + } else if (m_sPoliceRadioQueue.crimes[i].position.y < halfY - quarterY) { + m_sPoliceRadioQueue.Add(SFX_SOUTH); + processed = true; + } + + if (m_sPoliceRadioQueue.crimes[i].position.x > halfX + quarterX) + m_sPoliceRadioQueue.Add(SFX_EAST); + else if (m_sPoliceRadioQueue.crimes[i].position.x < halfX - quarterX) + m_sPoliceRadioQueue.Add(SFX_WEST); + else if (!processed) + m_sPoliceRadioQueue.Add(SFX_CENTRAL); + + m_sPoliceRadioQueue.Add(sampleIndex); + m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_MESSAGE_NOISE_1); + m_sPoliceRadioQueue.Add(NO_SAMPLE); + break; + } + } + } + m_sPoliceRadioQueue.crimes[i].type = CRIME_NONE; + AgeCrimes(); + return true; +} + +void +cAudioManager::SetupSuspectLastSeenReport() +{ + CVehicle *veh; + uint8 color1; + int32 main_color; + int32 sample; + + int32 color_pre_modifier; + int32 color_post_modifier; + + const int32 gCarColourTable[][3] = { + {NO_SAMPLE, SFX_POLICE_RADIO_BLACK, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_WHITE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_BLUE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_RED, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_BLUE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_PURPLE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_YELLOW, NO_SAMPLE}, + {SFX_POLICE_RADIO_BRIGHT, SFX_POLICE_RADIO_BLUE, NO_SAMPLE}, + {SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_BLUE, SFX_POLICE_RADIO_GREY}, + {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_RED, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_RED, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_RED, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_RED, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_RED, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_RED, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_RED, NO_SAMPLE}, + {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_ORANGE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_ORANGE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_ORANGE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_ORANGE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_ORANGE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_ORANGE, NO_SAMPLE}, + {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_YELLOW, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_YELLOW, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_YELLOW, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_YELLOW, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_YELLOW, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_YELLOW, NO_SAMPLE}, + {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_GREEN, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_GREEN, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_GREEN, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_GREEN, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_GREEN, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_GREEN, NO_SAMPLE}, + {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_BLUE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_BLUE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_BLUE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_BLUE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_BLUE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_BLUE, NO_SAMPLE}, + {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_PURPLE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_PURPLE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_PURPLE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_PURPLE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_PURPLE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_PURPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_SILVER, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_SILVER, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_SILVER, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_SILVER, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_SILVER, NO_SAMPLE}, + {NO_SAMPLE, SFX_POLICE_RADIO_SILVER, NO_SAMPLE}, + {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}, + {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE} + }; + + if (MusicManager.m_nMusicMode != MUSICMODE_CUTSCENE) { + veh = FindVehicleOfPlayer(); + if (veh != nil) { + if (60 - m_sPoliceRadioQueue.policeChannelTimer > 9) { + color1 = veh->m_currentColour1; + if (color1 >= ARRAY_SIZE(gCarColourTable)) { + debug("\n *** UNKNOWN CAR COLOUR %d *** ", color1); + } else { + main_color = gCarColourTable[color1][1]; + color_pre_modifier = gCarColourTable[color1][0]; + color_post_modifier = gCarColourTable[color1][2]; + switch (veh->GetModelIndex()) { + case MI_LANDSTAL: + case MI_PATRIOT: + case MI_RANCHER: + case MI_FBIRANCH: + case MI_SANDKING: + sample = SFX_POLICE_RADIO_OFFROAD; + break; + case MI_IDAHO: + case MI_MANANA: + case MI_ESPERANT: + case MI_CUBAN: + case MI_STALLION: + case MI_SABRE: + case MI_SABRETUR: + case MI_VIRGO: + case MI_BLISTAC: + sample = SFX_POLICE_RADIO_2_DOOR; + break; + case MI_STINGER: + case MI_INFERNUS: + case MI_CHEETAH: + case MI_BANSHEE: + case MI_PHEONIX: + case MI_COMET: + case MI_DELUXO: + case MI_HOTRING: + sample = SFX_POLICE_RADIO_SPORTS_CAR; + break; + case MI_LINERUN: + sample = SFX_POLICE_RADIO_RIG; + break; + case MI_PEREN: + case MI_REGINA: + sample = SFX_POLICE_RADIO_STATION_WAGON; + break; + case MI_SENTINEL: + case MI_FBICAR: + case MI_WASHING: + case MI_SENTXS: + case MI_ADMIRAL: + case MI_GLENDALE: + case MI_OCEANIC: + case MI_HERMES: + case MI_GREENWOO: + sample = SFX_POLICE_RADIO_SEDAN; + break; + case MI_RIO: + sample = SFX_POLICE_RADIO_CRUISER; + break; + case MI_FIRETRUCK: + sample = SFX_POLICE_RADIO_FIRE_TRUCK; + break; + case MI_TRASH: + sample = SFX_POLICE_RADIO_GARBAGE_TRUCK; + break; + case MI_STRETCH: + case MI_LOVEFIST: + sample = SFX_POLICE_RADIO_STRETCH; + break; + case MI_VOODOO: + sample = SFX_POLICE_RADIO_LOWRIDER; + break; + case MI_PONY: + case MI_MOONBEAM: + case MI_SECURICA: + case MI_RUMPO: + case MI_GANGBUR: + case MI_YANKEE: + case MI_TOPFUN: + case MI_BURRITO: + case MI_SPAND: + sample = SFX_POLICE_RADIO_VAN; + break; + case MI_MULE: + case MI_BARRACKS: + case MI_PACKER: + case MI_FLATBED: + sample = SFX_POLICE_RADIO_TRUCK; + break; + case MI_AMBULAN: + sample = SFX_POLICE_RADIO_AMBULANCE; + break; + case MI_TAXI: + case MI_CABBIE: + case MI_ZEBRA: + case MI_KAUFMAN: + sample = SFX_POLICE_RADIO_TAXI; + break; + case MI_BOBCAT: + case MI_WALTON: + sample = SFX_POLICE_RADIO_PICKUP; + break; + case MI_MRWHOOP: + sample = SFX_POLICE_RADIO_ICE_CREAM_VAN; + break; + case MI_BFINJECT: + sample = SFX_POLICE_RADIO_BUGGY; + break; + case MI_HUNTER: + case MI_CHOPPER: + case MI_SEASPAR: + case MI_SPARROW: + case MI_MAVERICK: + case MI_VCNMAV: + case MI_POLMAV: + sample = SFX_POLICE_RADIO_HELICOPTER; + break; + case MI_POLICE: + sample = SFX_POLICE_RADIO_POLICE_CAR; + break; + case MI_ENFORCER: + sample = SFX_POLICE_RADIO_SWAT_VAN; + break; + case MI_PREDATOR: + case MI_SQUALO: + case MI_SPEEDER: + sample = SFX_POLICE_RADIO_SPEEDBOAT; + break; + case MI_BUS: + sample = SFX_POLICE_RADIO_BUS; + break; + case MI_RHINO: + sample = SFX_POLICE_RADIO_TANK; + break; + case MI_ANGEL: + case MI_PCJ600: + case MI_FREEWAY: + case MI_SANCHEZ: + sample = SFX_POLICE_RADIO_MOTOBIKE; + break; + case MI_COACH: + sample = SFX_POLICE_RADIO_COACH; + break; + case MI_ROMERO: + sample = SFX_POLICE_RADIO_HEARSE; + break; + case MI_PIZZABOY: + case MI_FAGGIO: + sample = SFX_POLICE_RADIO_MOPED; + break; + case MI_DEADDODO: + case MI_SKIMMER: + sample = SFX_POLICE_RADIO_PLANE; + break; + case MI_REEFER: + case MI_TROPIC: + case MI_COASTG: + case MI_MARQUIS: + case MI_JETMAX: + sample = SFX_POLICE_RADIO_BOAT; + break; + case MI_CADDY: + sample = SFX_POLICE_RADIO_GOLF_CART; + break; + case MI_DINGHY: + sample = SFX_POLICE_RADIO_DINGHY; + break; + default: + //debug("\n *** UNKNOWN CAR MODEL INDEX %d *** ", veh->GetModelIndex()); + return; + } + m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_MESSAGE_NOISE_1); + m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_SUSPECT); + if (m_anRandomTable[3] % 2) + m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_LAST_SEEN); + m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_IN_A); + if (color_pre_modifier != NO_SAMPLE) + m_sPoliceRadioQueue.Add(color_pre_modifier); + if (main_color != NO_SAMPLE) + m_sPoliceRadioQueue.Add(main_color); + if (color_post_modifier != NO_SAMPLE) + m_sPoliceRadioQueue.Add(color_post_modifier); + m_sPoliceRadioQueue.Add(sample); + m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_MESSAGE_NOISE_1); + m_sPoliceRadioQueue.Add(NO_SAMPLE); + } + } + } else if (60 - m_sPoliceRadioQueue.policeChannelTimer > 4) { + m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_MESSAGE_NOISE_1); + m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_SUSPECT); + m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_ON_FOOT); + m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_MESSAGE_NOISE_1); + m_sPoliceRadioQueue.Add(NO_SAMPLE); + } + } +} + +void +cAudioManager::ReportCrime(eCrimeType type, const CVector &pos) +{ + int32 lastCrime = ARRAY_SIZE(m_sPoliceRadioQueue.crimes); + if (m_bIsInitialised && MusicManager.m_nMusicMode != MUSICMODE_CUTSCENE && FindPlayerPed()->m_pWanted->GetWantedLevel() > 0 && + (type > CRIME_NONE || type < NUM_CRIME_TYPES) && m_FrameCounter >= gMinTimeToNextReport[type]) { + for (int32 i = 0; i < ARRAY_SIZE(m_sPoliceRadioQueue.crimes); i++) { + if (m_sPoliceRadioQueue.crimes[i].type != CRIME_NONE) { + if (m_sPoliceRadioQueue.crimes[i].type == type) { + m_sPoliceRadioQueue.crimes[i].position = pos; + m_sPoliceRadioQueue.crimes[i].timer = 0; + return; + } + } else + lastCrime = i; + } + + if (lastCrime < ARRAY_SIZE(m_sPoliceRadioQueue.crimes)) { + m_sPoliceRadioQueue.crimes[lastCrime].type = type; + m_sPoliceRadioQueue.crimes[lastCrime].position = pos; + m_sPoliceRadioQueue.crimes[lastCrime].timer = 0; + gMinTimeToNextReport[type] = m_FrameCounter + 500; + } + } +} + +void +cAudioManager::PlaySuspectLastSeen(float x, float y, float z) +{ + int16 audioZone; + CZone *zone; + float rangeX; + float rangeY; + float halfX; + float halfY; + float quarterX; + float quarterY; + int32 sample; + bool processed = false; + CVector vec = CVector(x, y, z); + + if (!m_bIsInitialised) return; + + if (MusicManager.m_nMusicMode != MUSICMODE_CUTSCENE && 60 - m_sPoliceRadioQueue.policeChannelTimer > 9) { + audioZone = CTheZones::FindAudioZone(&vec); + if (audioZone >= 0 && audioZone < NUMAUDIOZONES) { + zone = CTheZones::GetAudioZone(audioZone); + for (int i = 0; i < NUMAUDIOZONES; i++) { + if (strcmp(zone->name, ZoneSfx[i].m_aName) == 0) { + sample = ZoneSfx[i].m_nSampleIndex; + m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_MESSAGE_NOISE_1); + m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_SUSPECT); + m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_LAST_SEEN); + m_sPoliceRadioQueue.Add(SFX_IN); + rangeX = zone->maxx - zone->minx; + rangeY = zone->maxy - zone->miny; + halfX = 0.5f * rangeX + zone->minx; + halfY = 0.5f * rangeY + zone->miny; + quarterX = 0.25f * rangeX; + quarterY = 0.25f * rangeY; + + if (vec.y > halfY + quarterY) { + m_sPoliceRadioQueue.Add(SFX_NORTH); + processed = true; + } else if (vec.y < halfY - quarterY) { + m_sPoliceRadioQueue.Add(SFX_SOUTH); + processed = true; + } + + if (vec.x > halfX + quarterX) + m_sPoliceRadioQueue.Add(SFX_EAST); + else if (vec.x < halfX - quarterX) + m_sPoliceRadioQueue.Add(SFX_WEST); + else if (!processed) + m_sPoliceRadioQueue.Add(SFX_CENTRAL); + m_sPoliceRadioQueue.Add(sample); + m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_MESSAGE_NOISE_1); + m_sPoliceRadioQueue.Add(NO_SAMPLE); + gSpecialSuspectLastSeenReport = true; + break; + } + } + } + } +} + +void +cAudioManager::AgeCrimes() +{ + for (uint8 i = 0; i < ARRAY_SIZE(m_sPoliceRadioQueue.crimes); i++) { + if (m_sPoliceRadioQueue.crimes[i].type != CRIME_NONE) { + if (++m_sPoliceRadioQueue.crimes[i].timer > 1200) m_sPoliceRadioQueue.crimes[i].type = CRIME_NONE; + } + } +} diff --git a/src/audio/PoliceRadio.h b/src/audio/PoliceRadio.h new file mode 100644 index 0000000..d7c928e --- /dev/null +++ b/src/audio/PoliceRadio.h @@ -0,0 +1,46 @@ +#pragma once + +#include "Crime.h" + +struct cAMCrime { + int32 type; + CVector position; + uint16 timer; + + cAMCrime() + { + type = CRIME_NONE; + position = CVector(0.0f, 0.0f, 0.0f); + timer = 0; + } +}; + +VALIDATE_SIZE(cAMCrime, 20); + +class cPoliceRadioQueue +{ +public: + int32 crimesSamples[60]; + uint8 policeChannelTimer; + uint8 policeChannelTimerSeconds; + uint8 policeChannelCounterSeconds; + cAMCrime crimes[10]; + + cPoliceRadioQueue() + { + policeChannelTimerSeconds = 0; + policeChannelCounterSeconds = 0; + policeChannelTimer = 0; + } + + void Add(uint32 sample) + { + if (policeChannelTimer != 60) { + crimesSamples[policeChannelTimerSeconds] = sample; + policeChannelTimer++; + policeChannelTimerSeconds = (policeChannelTimerSeconds + 1) % 60; + } + } +}; + +VALIDATE_SIZE(cPoliceRadioQueue, 0x1BC); diff --git a/src/audio/audio_enums.h b/src/audio/audio_enums.h new file mode 100644 index 0000000..990b2d7 --- /dev/null +++ b/src/audio/audio_enums.h @@ -0,0 +1,1297 @@ +#pragma once + +enum eRadioStation +{ + WILDSTYLE, + FLASH_FM, + KCHAT, + FEVER, + V_ROCK, + VCPR, + RADIO_ESPANTOSO, + EMOTION, + WAVE, + USERTRACK, + NUM_RADIOS = 10, + POLICE_RADIO = 10, + RADIO_OFF = 10, + //TAXI_RADIO, +}; + +enum eMusicMode +{ + MUSICMODE_FRONTEND = 0, + MUSICMODE_GAME, + MUSICMODE_CUTSCENE, + MUSICMODE_DISABLE, + MUSICMODE_DISABLED, +}; + +enum ePlayerMood +{ + PLAYER_MOOD_CALM = 0, + PLAYER_MOOD_PISSED_OFF, + PLAYER_MOOD_ANGRY, + PLAYER_MOOD_WISECRACKING, + MAX_PLAYER_MOODS, +}; + +enum eStreamedSounds +{ + STREAMED_SOUND_RADIO_WILD, + STREAMED_SOUND_RADIO_FLASH, + STREAMED_SOUND_RADIO_KCHAT, + STREAMED_SOUND_RADIO_FEVER, + STREAMED_SOUND_RADIO_VROCK, + STREAMED_SOUND_RADIO_VCPR, + STREAMED_SOUND_RADIO_ESPANTOSO, + STREAMED_SOUND_RADIO_EMOTION, + STREAMED_SOUND_RADIO_WAVE, + STREAMED_SOUND_RADIO_MP3_PLAYER, + STREAMED_SOUND_CITY_AMBIENT, + STREAMED_SOUND_WATER_AMBIENT, + STREAMED_SOUND_BEACH_AMBIENT, + STREAMED_SOUND_HAVANA_CITY_AMBIENT, + STREAMED_SOUND_HAVANA_WATER_AMBIENT, + STREAMED_SOUND_HAVANA_BEACH_AMBIENT, + STREAMED_SOUND_MALL_AMBIENT, + STREAMED_SOUND_STRIPCLUB_AMBIENT, + STREAMED_SOUND_MALIBU_AMBIENT, + STREAMED_SOUND_HOTEL_AMBIENT, + STREAMED_SOUND_DIRTRING_AMBIENT, + STREAMED_SOUND_LAW4RIOT_AMBIENT, + STREAMED_SOUND_AMBSIL_AMBIENT, + STREAMED_SOUND_RADIO_POLICE, + STREAMED_SOUND_RADIO_TAXI, + STREAMED_SOUND_ANNOUNCE_BRIDGE_CLOSED, + STREAMED_SOUND_ANNOUNCE_BRIDGE_OPEN, + STREAMED_SOUND_CUTSCENE_ASS_1, + STREAMED_SOUND_CUTSCENE_ASS_2, + STREAMED_SOUND_CUTSCENE_BANK_1, + STREAMED_SOUND_CUTSCENE_BANK_2A, + STREAMED_SOUND_CUTSCENE_BANK_2B, + STREAMED_SOUND_CUTSCENE_BANK_3A, + STREAMED_SOUND_CUTSCENE_BANK_3B, + STREAMED_SOUND_CUTSCENE_BANK_4, + STREAMED_SOUND_CUTSCENE_BIKE_1, + STREAMED_SOUND_CUTSCENE_BIKE_2, + STREAMED_SOUND_CUTSCENE_BIKE_3, + STREAMED_SOUND_CUTSCENE_BUD_1, + STREAMED_SOUND_CUTSCENE_BUD_2, + STREAMED_SOUND_CUTSCENE_BUD_3, + STREAMED_SOUND_CUTSCENE_CAP_1, + STREAMED_SOUND_CUTSCENE_CAR_1, + STREAMED_SOUND_CUTSCENE_CNT_1A, + STREAMED_SOUND_CUTSCENE_CNT_1B, + STREAMED_SOUND_CUTSCENE_CNT_2, + STREAMED_SOUND_CUTSCENE_COK_1, + STREAMED_SOUND_CUTSCENE_COK_2A, + STREAMED_SOUND_CUTSCENE_COK_2B, + STREAMED_SOUND_CUTSCENE_COK_3, + STREAMED_SOUND_CUTSCENE_COK_4A, + STREAMED_SOUND_CUTSCENE_COK_4A2, + STREAMED_SOUND_CUTSCENE_COK_4B, + STREAMED_SOUND_CUTSCENE_COL_1, + STREAMED_SOUND_CUTSCENE_COL_2, + STREAMED_SOUND_CUTSCENE_COL_3A, + STREAMED_SOUND_CUTSCENE_COL_4A, + STREAMED_SOUND_CUTSCENE_COL_5A, + STREAMED_SOUND_CUTSCENE_COL_5B, + STREAMED_SOUND_CUTSCENE_CUB_1, + STREAMED_SOUND_CUTSCENE_CUB_2, + STREAMED_SOUND_CUTSCENE_CUB_3, + STREAMED_SOUND_CUTSCENE_CUB_4, + STREAMED_SOUND_CUTSCENE_DRUG_1, + STREAMED_SOUND_CUTSCENE_FIN, + STREAMED_SOUND_CUTSCENE_FIN2, + STREAMED_SOUND_CUTSCENE_FINALE, + STREAMED_SOUND_CUTSCENE_HAT_1, + STREAMED_SOUND_CUTSCENE_HAT_2, + STREAMED_SOUND_CUTSCENE_HAT_3, + STREAMED_SOUND_CUTSCENE_ICE_1, + STREAMED_SOUND_CUTSCENE_INT_A, + STREAMED_SOUND_CUTSCENE_INT_B, + STREAMED_SOUND_CUTSCENE_INT_D, + STREAMED_SOUND_CUTSCENE_INT_M, + STREAMED_SOUND_CUTSCENE_LAW_1A, + STREAMED_SOUND_CUTSCENE_LAW_1B, + STREAMED_SOUND_CUTSCENE_LAW_2A, + STREAMED_SOUND_CUTSCENE_LAW_2B, + STREAMED_SOUND_CUTSCENE_LAW_2C, + STREAMED_SOUND_CUTSCENE_LAW_3, + STREAMED_SOUND_CUTSCENE_LAW_4, + STREAMED_SOUND_CUTSCENE_PHIL_1, + STREAMED_SOUND_CUTSCENE_PHIL_2, + STREAMED_SOUND_CUTSCENE_PORN_1, + STREAMED_SOUND_CUTSCENE_PORN_2, + STREAMED_SOUND_CUTSCENE_PORN_3, + STREAMED_SOUND_CUTSCENE_PORN_4, + STREAMED_SOUND_CUTSCENE_RESC_1A, + STREAMED_SOUND_CUTSCENE_ROK_1, + STREAMED_SOUND_CUTSCENE_ROK_2, + STREAMED_SOUND_CUTSCENE_ROK_3A, + STREAMED_SOUND_CUTSCENE_STRIPA, + STREAMED_SOUND_CUTSCENE_TAX_1, + STREAMED_SOUND_CUTSCENE_TEX_1, + STREAMED_SOUND_CUTSCENE_TEX_2, + STREAMED_SOUND_CUTSCENE_TEX_3, + STREAMED_SOUND_CUTSCENE_GLIGHT, + STREAMED_SOUND_CUTSCENE_FIST, + STREAMED_SOUND_CUTSCENE_ELBURRO1_PH1, + STREAMED_SOUND_CUTSCENE_ELBURRO2_PH2, + STREAMED_SOUND_MISSION_COMPLETED, + STREAMED_SOUND_MISSION_COMPLETED4, + STREAMED_SOUND_MISSION_MOBR1, + STREAMED_SOUND_MISSION_PAGER, + STREAMED_SOUND_MISSION_CARREV, + STREAMED_SOUND_MISSION_BIKEREV, + STREAMED_SOUND_MISSION_LIFTOP, + STREAMED_SOUND_MISSION_LIFTCL, + STREAMED_SOUND_MISSION_LIFTRUN, + STREAMED_SOUND_MISSION_LIFTBEL, + STREAMED_SOUND_MISSION_INLIFT, + STREAMED_SOUND_MISSION_SFX_01, + STREAMED_SOUND_MISSION_SFX_02, + STREAMED_SOUND_MISSION_CAMERAL, + STREAMED_SOUND_MISSION_CAMERAR, + STREAMED_SOUND_MISSION_CHEER1, + STREAMED_SOUND_MISSION_CHEER2, + STREAMED_SOUND_MISSION_CHEER3, + STREAMED_SOUND_MISSION_CHEER4, + STREAMED_SOUND_MISSION_OOH1, + STREAMED_SOUND_MISSION_OOH2, + STREAMED_SOUND_MISSION_RACE1, + STREAMED_SOUND_MISSION_RACE2, + STREAMED_SOUND_MISSION_RACE3, + STREAMED_SOUND_MISSION_RACE4, + STREAMED_SOUND_MISSION_RACE5, + STREAMED_SOUND_MISSION_RACE6, + STREAMED_SOUND_MISSION_RACE7, + STREAMED_SOUND_MISSION_RACE8, + STREAMED_SOUND_MISSION_RACE9, + STREAMED_SOUND_MISSION_RACE10, + STREAMED_SOUND_MISSION_RACE11, + STREAMED_SOUND_MISSION_RACE12, + STREAMED_SOUND_MISSION_RACE13, + STREAMED_SOUND_MISSION_RACE14, + STREAMED_SOUND_MISSION_RACE15, + STREAMED_SOUND_MISSION_HOT1, + STREAMED_SOUND_MISSION_HOT2, + STREAMED_SOUND_MISSION_HOT3, + STREAMED_SOUND_MISSION_HOT4, + STREAMED_SOUND_MISSION_HOT5, + STREAMED_SOUND_MISSION_HOT6, + STREAMED_SOUND_MISSION_HOT7, + STREAMED_SOUND_MISSION_HOT8, + STREAMED_SOUND_MISSION_HOT9, + STREAMED_SOUND_MISSION_HOT10, + STREAMED_SOUND_MISSION_HOT11, + STREAMED_SOUND_MISSION_HOT12, + STREAMED_SOUND_MISSION_HOT13, + STREAMED_SOUND_MISSION_HOT14, + STREAMED_SOUND_MISSION_HOT15, + STREAMED_SOUND_MISSION_LANSTP1, + STREAMED_SOUND_MISSION_LANSTP2, + STREAMED_SOUND_MISSION_LANAMU1, + STREAMED_SOUND_MISSION_LANAMU2, + STREAMED_SOUND_MISSION_AIRHORNL, + STREAMED_SOUND_MISSION_AIRHORNR, + STREAMED_SOUND_MISSION_SNIPSCRL, + STREAMED_SOUND_MISSION_SNIPSHORT, + STREAMED_SOUND_MISSION_BLOWROOF, + STREAMED_SOUND_MISSION_ASS_1, + STREAMED_SOUND_MISSION_ASS_2, + STREAMED_SOUND_MISSION_ASS_3, + STREAMED_SOUND_MISSION_ASS_4, + STREAMED_SOUND_MISSION_ASS_5, + STREAMED_SOUND_MISSION_ASS_6, + STREAMED_SOUND_MISSION_ASS_7, + STREAMED_SOUND_MISSION_ASS_8, + STREAMED_SOUND_MISSION_ASS_9, + STREAMED_SOUND_MISSION_ASS_10, + STREAMED_SOUND_MISSION_ASS_11, + STREAMED_SOUND_MISSION_ASS_12, + STREAMED_SOUND_MISSION_ASS_13, + STREAMED_SOUND_MISSION_ASS_14, + STREAMED_SOUND_MISSION_BIKE1_1, + STREAMED_SOUND_MISSION_BIKE1_2, + STREAMED_SOUND_MISSION_BIKE1_3, + STREAMED_SOUND_MISSION_BNK1_1, + STREAMED_SOUND_MISSION_BNK1_2, + STREAMED_SOUND_MISSION_BNK1_3, + STREAMED_SOUND_MISSION_BNK1_4, + STREAMED_SOUND_MISSION_BNK1_5, + STREAMED_SOUND_MISSION_BNK1_6, + STREAMED_SOUND_MISSION_BNK1_7, + STREAMED_SOUND_MISSION_BNK1_8, + STREAMED_SOUND_MISSION_BNK1_10, + STREAMED_SOUND_MISSION_BNK1_11, + STREAMED_SOUND_MISSION_BNK1_12, + STREAMED_SOUND_MISSION_BNK1_13, + STREAMED_SOUND_MISSION_BNK1_14, + STREAMED_SOUND_MISSION_BNK2_1, + STREAMED_SOUND_MISSION_BNK2_2, + STREAMED_SOUND_MISSION_BNK2_3, + STREAMED_SOUND_MISSION_BNK2_4, + STREAMED_SOUND_MISSION_BNK2_5, + STREAMED_SOUND_MISSION_BNK2_6, + STREAMED_SOUND_MISSION_BNK2_7, + STREAMED_SOUND_MISSION_BNK2_8, + STREAMED_SOUND_MISSION_BNK2_9, + STREAMED_SOUND_MISSION_BNK3_1, + STREAMED_SOUND_MISSION_BNK3_2, + STREAMED_SOUND_MISSION_BNK3_3A, + STREAMED_SOUND_MISSION_BNK3_3B, + STREAMED_SOUND_MISSION_BNK3_3C, + STREAMED_SOUND_MISSION_BNK3_4A, + STREAMED_SOUND_MISSION_BNK3_4B, + STREAMED_SOUND_MISSION_BNK3_4C, + STREAMED_SOUND_MISSION_BNK4_1, + STREAMED_SOUND_MISSION_BNK4_2, + STREAMED_SOUND_MISSION_BNK4_3A, + STREAMED_SOUND_MISSION_BNK4_3B, + STREAMED_SOUND_MISSION_BNK4_3C, + STREAMED_SOUND_MISSION_BNK4_3D, + STREAMED_SOUND_MISSION_BNK4_3E, + STREAMED_SOUND_MISSION_BNK4_3F, + STREAMED_SOUND_MISSION_BNK4_3G, + STREAMED_SOUND_MISSION_BNK4_3H, + STREAMED_SOUND_MISSION_BNK4_3I, + STREAMED_SOUND_MISSION_BNK4_3J, + STREAMED_SOUND_MISSION_BNK4_3K, + STREAMED_SOUND_MISSION_BNK4_3M, + STREAMED_SOUND_MISSION_BNK4_3O, + STREAMED_SOUND_MISSION_BNK4_3P, + STREAMED_SOUND_MISSION_BNK4_3Q, + STREAMED_SOUND_MISSION_BNK4_3R, + STREAMED_SOUND_MISSION_BNK4_3S, + STREAMED_SOUND_MISSION_BNK4_3T, + STREAMED_SOUND_MISSION_BNK4_3U, + STREAMED_SOUND_MISSION_BNK4_3V, + STREAMED_SOUND_MISSION_BNK4_4A, + STREAMED_SOUND_MISSION_BNK4_4B, + STREAMED_SOUND_MISSION_BNK4_5, + STREAMED_SOUND_MISSION_BNK4_6, + STREAMED_SOUND_MISSION_BNK4_7, + STREAMED_SOUND_MISSION_BNK4_8, + STREAMED_SOUND_MISSION_BNK4_9, + STREAMED_SOUND_MISSION_BNK4_10, + STREAMED_SOUND_MISSION_BNK4_11, + STREAMED_SOUND_MISSION_BK4_12A, + STREAMED_SOUND_MISSION_BK4_12B, + STREAMED_SOUND_MISSION_BK4_12C, + STREAMED_SOUND_MISSION_BNK4_13, + STREAMED_SOUND_MISSION_BK4_14A, + STREAMED_SOUND_MISSION_BK4_14B, + STREAMED_SOUND_MISSION_BNK4_15, + STREAMED_SOUND_MISSION_BNK4_16, + STREAMED_SOUND_MISSION_BNK4_17, + STREAMED_SOUND_MISSION_BNK4_18, + STREAMED_SOUND_MISSION_BK4_19A, + STREAMED_SOUND_MISSION_BK4_19B, + STREAMED_SOUND_MISSION_BK4_20A, + STREAMED_SOUND_MISSION_BK4_20B, + STREAMED_SOUND_MISSION_BNK4_21, + STREAMED_SOUND_MISSION_BNK422A, + STREAMED_SOUND_MISSION_BNK422B, + STREAMED_SOUND_MISSION_BK4_23A, + STREAMED_SOUND_MISSION_BK4_23B, + STREAMED_SOUND_MISSION_BK4_23C, + STREAMED_SOUND_MISSION_BK4_23D, + STREAMED_SOUND_MISSION_BK4_24A, + STREAMED_SOUND_MISSION_BK4_24B, + STREAMED_SOUND_MISSION_BNK4_25, + STREAMED_SOUND_MISSION_BNK4_26, + STREAMED_SOUND_MISSION_BNK4_27, + STREAMED_SOUND_MISSION_BNK4_28, + STREAMED_SOUND_MISSION_BNK4_29, + STREAMED_SOUND_MISSION_BNK4_30, + STREAMED_SOUND_MISSION_BK4_31A, + STREAMED_SOUND_MISSION_BK4_31B, + STREAMED_SOUND_MISSION_BNK4_32, + STREAMED_SOUND_MISSION_BK4_34A, + STREAMED_SOUND_MISSION_BK4_34B, + STREAMED_SOUND_MISSION_BK4_35A, + STREAMED_SOUND_MISSION_BK4_35B, + STREAMED_SOUND_MISSION_BNK4_36, + STREAMED_SOUND_MISSION_BNK4_37, + STREAMED_SOUND_MISSION_BNK4_38, + STREAMED_SOUND_MISSION_BNK4_39, + STREAMED_SOUND_MISSION_BK4_40A, + STREAMED_SOUND_MISSION_BK4_40B, + STREAMED_SOUND_MISSION_BNK4_41, + STREAMED_SOUND_MISSION_BNK4_42, + STREAMED_SOUND_MISSION_BNK4_43, + STREAMED_SOUND_MISSION_BNK4_44, + STREAMED_SOUND_MISSION_BNK4_45, + STREAMED_SOUND_MISSION_BNK4_46, + STREAMED_SOUND_MISSION_BNK4_47, + STREAMED_SOUND_MISSION_BNK4_48, + STREAMED_SOUND_MISSION_BNK4_49, + STREAMED_SOUND_MISSION_BNK450A, + STREAMED_SOUND_MISSION_BNK450B, + STREAMED_SOUND_MISSION_BNK4_51, + STREAMED_SOUND_MISSION_BNK4_94, + STREAMED_SOUND_MISSION_BNK4_95, + STREAMED_SOUND_MISSION_BNK4_96, + STREAMED_SOUND_MISSION_BNK4_97, + STREAMED_SOUND_MISSION_BNK4_98, + STREAMED_SOUND_MISSION_BNK4_99, + STREAMED_SOUND_MISSION_BUD1_1, + STREAMED_SOUND_MISSION_BUD1_2, + STREAMED_SOUND_MISSION_BUD1_3, + STREAMED_SOUND_MISSION_BUD1_4, + STREAMED_SOUND_MISSION_BUD1_5, + STREAMED_SOUND_MISSION_BUD1_9, + STREAMED_SOUND_MISSION_BUD1_10, + STREAMED_SOUND_MISSION_BUD2_1, + STREAMED_SOUND_MISSION_BUD2_2, + STREAMED_SOUND_MISSION_BUD2_3, + STREAMED_SOUND_MISSION_BUD2_4, + STREAMED_SOUND_MISSION_BUD2_5, + STREAMED_SOUND_MISSION_BUD2_6, + STREAMED_SOUND_MISSION_BUD2_7, + STREAMED_SOUND_MISSION_BUD3_1, + STREAMED_SOUND_MISSION_BUD3_1A, + STREAMED_SOUND_MISSION_BUD3_1B, + STREAMED_SOUND_MISSION_BUD3_1C, + STREAMED_SOUND_MISSION_BUD3_2, + STREAMED_SOUND_MISSION_BUD3_3, + STREAMED_SOUND_MISSION_BUD3_4, + STREAMED_SOUND_MISSION_BUD3_5, + STREAMED_SOUND_MISSION_BUD3_6, + STREAMED_SOUND_MISSION_BUD3_7, + STREAMED_SOUND_MISSION_BUD3_8A, + STREAMED_SOUND_MISSION_BUD3_8B, + STREAMED_SOUND_MISSION_BUD3_8C, + STREAMED_SOUND_MISSION_BUD3_9A, + STREAMED_SOUND_MISSION_BUD3_9B, + STREAMED_SOUND_MISSION_BUD3_9C, + STREAMED_SOUND_MISSION_CAP1_2, + STREAMED_SOUND_MISSION_CAP1_3, + STREAMED_SOUND_MISSION_CAP1_4, + STREAMED_SOUND_MISSION_CAP1_5, + STREAMED_SOUND_MISSION_CAP1_6, + STREAMED_SOUND_MISSION_CAP1_7, + STREAMED_SOUND_MISSION_CAP1_8, + STREAMED_SOUND_MISSION_CAP1_9, + STREAMED_SOUND_MISSION_CAP1_10, + STREAMED_SOUND_MISSION_CAP1_11, + STREAMED_SOUND_MISSION_CAP1_12, + STREAMED_SOUND_MISSION_CNT1_1, + STREAMED_SOUND_MISSION_CNT1_2, + STREAMED_SOUND_MISSION_CNT1_3, + STREAMED_SOUND_MISSION_CNT1_4, + STREAMED_SOUND_MISSION_CNT1_5, + STREAMED_SOUND_MISSION_CNT2_1, + STREAMED_SOUND_MISSION_CNT2_2, + STREAMED_SOUND_MISSION_CNT2_3, + STREAMED_SOUND_MISSION_CNT2_4, + STREAMED_SOUND_MISSION_COK1_1, + STREAMED_SOUND_MISSION_COK1_2, + STREAMED_SOUND_MISSION_COK1_3, + STREAMED_SOUND_MISSION_COK1_4, + STREAMED_SOUND_MISSION_COK1_5, + STREAMED_SOUND_MISSION_COK1_6, + STREAMED_SOUND_MISSION_COK2_1, + STREAMED_SOUND_MISSION_COK2_2, + STREAMED_SOUND_MISSION_COK2_3, + STREAMED_SOUND_MISSION_COK2_4, + STREAMED_SOUND_MISSION_COK2_5, + STREAMED_SOUND_MISSION_COK2_6, + STREAMED_SOUND_MISSION_COK2_7A, + STREAMED_SOUND_MISSION_COK2_7B, + STREAMED_SOUND_MISSION_COK2_7C, + STREAMED_SOUND_MISSION_COK2_8A, + STREAMED_SOUND_MISSION_COK2_8B, + STREAMED_SOUND_MISSION_COK2_8C, + STREAMED_SOUND_MISSION_COK2_8D, + STREAMED_SOUND_MISSION_COK2_9, + STREAMED_SOUND_MISSION_COK210A, + STREAMED_SOUND_MISSION_COK210B, + STREAMED_SOUND_MISSION_COK210C, + STREAMED_SOUND_MISSION_COK212A, + STREAMED_SOUND_MISSION_COK212B, + STREAMED_SOUND_MISSION_COK2_13, + STREAMED_SOUND_MISSION_COK2_14, + STREAMED_SOUND_MISSION_COK2_15, + STREAMED_SOUND_MISSION_COK2_16, + STREAMED_SOUND_MISSION_COK2_20, + STREAMED_SOUND_MISSION_COK2_21, + STREAMED_SOUND_MISSION_COK2_22, + STREAMED_SOUND_MISSION_COK3_1, + STREAMED_SOUND_MISSION_COK3_2, + STREAMED_SOUND_MISSION_COK3_3, + STREAMED_SOUND_MISSION_COK3_4, + STREAMED_SOUND_MISSION_COK4_1, + STREAMED_SOUND_MISSION_COK4_2, + STREAMED_SOUND_MISSION_COK4_3, + STREAMED_SOUND_MISSION_COK4_4, + STREAMED_SOUND_MISSION_COK4_5, + STREAMED_SOUND_MISSION_COK4_6, + STREAMED_SOUND_MISSION_COK4_7, + STREAMED_SOUND_MISSION_COK4_8, + STREAMED_SOUND_MISSION_COK4_9, + STREAMED_SOUND_MISSION_COK4_9A, + STREAMED_SOUND_MISSION_COK4_10, + STREAMED_SOUND_MISSION_COK4_11, + STREAMED_SOUND_MISSION_COK4_12, + STREAMED_SOUND_MISSION_COK4_13, + STREAMED_SOUND_MISSION_COK4_14, + STREAMED_SOUND_MISSION_COK4_15, + STREAMED_SOUND_MISSION_COK4_16, + STREAMED_SOUND_MISSION_COK4_17, + STREAMED_SOUND_MISSION_COK4_18, + STREAMED_SOUND_MISSION_COK4_19, + STREAMED_SOUND_MISSION_COK4_20, + STREAMED_SOUND_MISSION_COK4_21, + STREAMED_SOUND_MISSION_COK4_22, + STREAMED_SOUND_MISSION_COK4_23, + STREAMED_SOUND_MISSION_COK4_24, + STREAMED_SOUND_MISSION_COK4_25, + STREAMED_SOUND_MISSION_COK4_26, + STREAMED_SOUND_MISSION_COK4_27, + STREAMED_SOUND_MISSION_COL1_1, + STREAMED_SOUND_MISSION_COL1_2, + STREAMED_SOUND_MISSION_COL1_3, + STREAMED_SOUND_MISSION_COL1_4, + STREAMED_SOUND_MISSION_COL1_5, + STREAMED_SOUND_MISSION_COL1_6, + STREAMED_SOUND_MISSION_COL1_7, + STREAMED_SOUND_MISSION_COL1_8, + STREAMED_SOUND_MISSION_COL2_1, + STREAMED_SOUND_MISSION_COL2_2, + STREAMED_SOUND_MISSION_COL2_3, + STREAMED_SOUND_MISSION_COL2_4, + STREAMED_SOUND_MISSION_COL2_5, + STREAMED_SOUND_MISSION_COL2_6A, + STREAMED_SOUND_MISSION_COL2_7, + STREAMED_SOUND_MISSION_COL2_8, + STREAMED_SOUND_MISSION_COL2_9, + STREAMED_SOUND_MISSION_COL2_10, + STREAMED_SOUND_MISSION_COL2_11, + STREAMED_SOUND_MISSION_COL2_12, + STREAMED_SOUND_MISSION_COL2_13, + STREAMED_SOUND_MISSION_COL2_14, + STREAMED_SOUND_MISSION_COL2_15, + STREAMED_SOUND_MISSION_COL2_16, + STREAMED_SOUND_MISSION_COL3_1, + STREAMED_SOUND_MISSION_COL3_2, + STREAMED_SOUND_MISSION_COL3_2A, + STREAMED_SOUND_MISSION_COL3_2B, + STREAMED_SOUND_MISSION_COL3_3, + STREAMED_SOUND_MISSION_COL3_4, + STREAMED_SOUND_MISSION_COL3_5, + STREAMED_SOUND_MISSION_COL3_6, + STREAMED_SOUND_MISSION_COL3_7, + STREAMED_SOUND_MISSION_COL3_8, + STREAMED_SOUND_MISSION_COL3_9, + STREAMED_SOUND_MISSION_COL3_10, + STREAMED_SOUND_MISSION_COL3_11, + STREAMED_SOUND_MISSION_COL3_12, + STREAMED_SOUND_MISSION_COL3_13, + STREAMED_SOUND_MISSION_COL3_14, + STREAMED_SOUND_MISSION_COL3_15, + STREAMED_SOUND_MISSION_COL3_16, + STREAMED_SOUND_MISSION_COL3_17, + STREAMED_SOUND_MISSION_COL3_18, + STREAMED_SOUND_MISSION_COL3_19, + STREAMED_SOUND_MISSION_COL3_20, + STREAMED_SOUND_MISSION_COL3_21, + STREAMED_SOUND_MISSION_COL3_23, + STREAMED_SOUND_MISSION_COL3_24, + STREAMED_SOUND_MISSION_COL3_25, + STREAMED_SOUND_MISSION_COL4_1, + STREAMED_SOUND_MISSION_COL4_2, + STREAMED_SOUND_MISSION_COL4_3, + STREAMED_SOUND_MISSION_COL4_4, + STREAMED_SOUND_MISSION_COL4_5, + STREAMED_SOUND_MISSION_COL4_6, + STREAMED_SOUND_MISSION_COL4_7, + STREAMED_SOUND_MISSION_COL4_8, + STREAMED_SOUND_MISSION_COL4_9, + STREAMED_SOUND_MISSION_COL4_10, + STREAMED_SOUND_MISSION_COL4_11, + STREAMED_SOUND_MISSION_COL4_12, + STREAMED_SOUND_MISSION_COL4_13, + STREAMED_SOUND_MISSION_COL4_14, + STREAMED_SOUND_MISSION_COL4_15, + STREAMED_SOUND_MISSION_COL4_16, + STREAMED_SOUND_MISSION_COL4_17, + STREAMED_SOUND_MISSION_COL4_18, + STREAMED_SOUND_MISSION_COL4_19, + STREAMED_SOUND_MISSION_COL4_20, + STREAMED_SOUND_MISSION_COL4_21, + STREAMED_SOUND_MISSION_COL4_22, + STREAMED_SOUND_MISSION_COL4_23, + STREAMED_SOUND_MISSION_COL4_24, + STREAMED_SOUND_MISSION_COL4_25, + STREAMED_SOUND_MISSION_COL4_26, + STREAMED_SOUND_MISSION_COL5_1, + STREAMED_SOUND_MISSION_COL5_2, + STREAMED_SOUND_MISSION_COL5_3, + STREAMED_SOUND_MISSION_COL5_4, + STREAMED_SOUND_MISSION_COL5_5, + STREAMED_SOUND_MISSION_COL5_6, + STREAMED_SOUND_MISSION_COL5_7, + STREAMED_SOUND_MISSION_COL5_8, + STREAMED_SOUND_MISSION_COL5_9, + STREAMED_SOUND_MISSION_COL5_10, + STREAMED_SOUND_MISSION_COL5_11, + STREAMED_SOUND_MISSION_COL5_12, + STREAMED_SOUND_MISSION_COL5_13, + STREAMED_SOUND_MISSION_COL5_14, + STREAMED_SOUND_MISSION_COL5_15, + STREAMED_SOUND_MISSION_COL5_16, + STREAMED_SOUND_MISSION_COL5_17, + STREAMED_SOUND_MISSION_COL5_18, + STREAMED_SOUND_MISSION_COL5_19, + STREAMED_SOUND_MISSION_COL5_20, + STREAMED_SOUND_MISSION_COL5_21, + STREAMED_SOUND_MISSION_COL5_22, + STREAMED_SOUND_MISSION_CUB1_1, + STREAMED_SOUND_MISSION_CUB1_2, + STREAMED_SOUND_MISSION_CUB1_3, + STREAMED_SOUND_MISSION_CUB1_4, + STREAMED_SOUND_MISSION_CUB1_5, + STREAMED_SOUND_MISSION_CUB1_6, + STREAMED_SOUND_MISSION_CUB1_7, + STREAMED_SOUND_MISSION_CUB1_8, + STREAMED_SOUND_MISSION_CUB1_9, + STREAMED_SOUND_MISSION_CUB1_10, + STREAMED_SOUND_MISSION_CUB2_1, + STREAMED_SOUND_MISSION_CUB2_2, + STREAMED_SOUND_MISSION_CUB2_3A, + STREAMED_SOUND_MISSION_CUB2_3B, + STREAMED_SOUND_MISSION_CUB2_3C, + STREAMED_SOUND_MISSION_CUB2_4A, + STREAMED_SOUND_MISSION_CUB2_5, + STREAMED_SOUND_MISSION_CUB2_6, + STREAMED_SOUND_MISSION_CUB2_7, + STREAMED_SOUND_MISSION_CUB2_8, + STREAMED_SOUND_MISSION_CUB2_9, + STREAMED_SOUND_MISSION_CUB2_10, + STREAMED_SOUND_MISSION_CUB2_11, + STREAMED_SOUND_MISSION_CUB3_1, + STREAMED_SOUND_MISSION_CUB3_2, + STREAMED_SOUND_MISSION_CUB3_3, + STREAMED_SOUND_MISSION_CUB3_4, + STREAMED_SOUND_MISSION_CUB4_1, + STREAMED_SOUND_MISSION_CUB4_2, + STREAMED_SOUND_MISSION_CUB4_3, + STREAMED_SOUND_MISSION_CUB4_4, + STREAMED_SOUND_MISSION_CUB4_5, + STREAMED_SOUND_MISSION_CUB4_5A, + STREAMED_SOUND_MISSION_CUB4_6, + STREAMED_SOUND_MISSION_CUB4_7, + STREAMED_SOUND_MISSION_CUB4_8, + STREAMED_SOUND_MISSION_CUB4_9, + STREAMED_SOUND_MISSION_CUB4_10, + STREAMED_SOUND_MISSION_CUB4_11, + STREAMED_SOUND_MISSION_CUB4_12, + STREAMED_SOUND_MISSION_CUB4_13, + STREAMED_SOUND_MISSION_CUB4_14, + STREAMED_SOUND_MISSION_CUB4_15, + STREAMED_SOUND_MISSION_CUB4_16, + STREAMED_SOUND_MISSION_GOLF_1, + STREAMED_SOUND_MISSION_GOLF_2, + STREAMED_SOUND_MISSION_GOLF_3, + STREAMED_SOUND_MISSION_BAR_1, + STREAMED_SOUND_MISSION_BAR_2, + STREAMED_SOUND_MISSION_BAR_3, + STREAMED_SOUND_MISSION_BAR_4, + STREAMED_SOUND_MISSION_BAR_5, + STREAMED_SOUND_MISSION_BAR_6, + STREAMED_SOUND_MISSION_BAR_7, + STREAMED_SOUND_MISSION_BAR_8, + STREAMED_SOUND_MISSION_STRIP_1, + STREAMED_SOUND_MISSION_STRIP_2, + STREAMED_SOUND_MISSION_STRIP_3, + STREAMED_SOUND_MISSION_STRIP_4, + STREAMED_SOUND_MISSION_STRIP_5, + STREAMED_SOUND_MISSION_STRIP_6, + STREAMED_SOUND_MISSION_STRIP_7, + STREAMED_SOUND_MISSION_STRIP_8, + STREAMED_SOUND_MISSION_STRIP_9, + STREAMED_SOUND_MISSION_STAR_1, + STREAMED_SOUND_MISSION_STAR_2, + STREAMED_SOUND_MISSION_STAR_3, + STREAMED_SOUND_MISSION_STAR_4, + STREAMED_SOUND_MISSION_FIN_1A, + STREAMED_SOUND_MISSION_FIN_1B, + STREAMED_SOUND_MISSION_FIN_1C, + STREAMED_SOUND_MISSION_FIN_2B, + STREAMED_SOUND_MISSION_FIN_2C, + STREAMED_SOUND_MISSION_FIN_3, + STREAMED_SOUND_MISSION_FIN_4, + STREAMED_SOUND_MISSION_FIN_5, + STREAMED_SOUND_MISSION_FIN_6, + STREAMED_SOUND_MISSION_FIN_10, + STREAMED_SOUND_MISSION_FIN_11A, + STREAMED_SOUND_MISSION_FIN_11B, + STREAMED_SOUND_MISSION_FIN_12A, + STREAMED_SOUND_MISSION_FIN_12B, + STREAMED_SOUND_MISSION_FIN_12C, + STREAMED_SOUND_MISSION_FIN_13, + STREAMED_SOUND_MISSION_FINKILL, + STREAMED_SOUND_MISSION_LAW1_1, + STREAMED_SOUND_MISSION_LAW1_2, + STREAMED_SOUND_MISSION_LAW1_3, + STREAMED_SOUND_MISSION_LAW1_4, + STREAMED_SOUND_MISSION_LAW1_5, + STREAMED_SOUND_MISSION_LAW1_6, + STREAMED_SOUND_MISSION_LAW1_7, + STREAMED_SOUND_MISSION_LAW1_8, + STREAMED_SOUND_MISSION_LAW1_9, + STREAMED_SOUND_MISSION_LAW1_10, + STREAMED_SOUND_MISSION_LAW2_1, + STREAMED_SOUND_MISSION_LAW2_2, + STREAMED_SOUND_MISSION_LAW2_3, + STREAMED_SOUND_MISSION_LAW2_4, + STREAMED_SOUND_MISSION_LAW2_5, + STREAMED_SOUND_MISSION_LAW2_6, + STREAMED_SOUND_MISSION_LAW2_7, + STREAMED_SOUND_MISSION_LAW2_8, + STREAMED_SOUND_MISSION_LAW2_9, + STREAMED_SOUND_MISSION_LAW2_10, + STREAMED_SOUND_MISSION_LAW3_1, + STREAMED_SOUND_MISSION_LAW3_2, + STREAMED_SOUND_MISSION_LAW3_3, + STREAMED_SOUND_MISSION_LAW3_4, + STREAMED_SOUND_MISSION_LAW3_5, + STREAMED_SOUND_MISSION_LAW3_6, + STREAMED_SOUND_MISSION_LAW3_10, + STREAMED_SOUND_MISSION_LAW3_11, + STREAMED_SOUND_MISSION_LAW3_12, + STREAMED_SOUND_MISSION_LAW3_13, + STREAMED_SOUND_MISSION_LAW3_14, + STREAMED_SOUND_MISSION_LAW3_16, + STREAMED_SOUND_MISSION_LAW3_17, + STREAMED_SOUND_MISSION_LAW3_18, + STREAMED_SOUND_MISSION_LAW3_19, + STREAMED_SOUND_MISSION_LAW3_20, + STREAMED_SOUND_MISSION_LAW3_21, + STREAMED_SOUND_MISSION_LAW3_22, + STREAMED_SOUND_MISSION_LAW3_23, + STREAMED_SOUND_MISSION_LAW3_24, + STREAMED_SOUND_MISSION_LAW3_25, + STREAMED_SOUND_MISSION_LAW4_1A, + STREAMED_SOUND_MISSION_LAW4_1B, + STREAMED_SOUND_MISSION_LAW4_1C, + STREAMED_SOUND_MISSION_LAW4_1D, + STREAMED_SOUND_MISSION_LAW4_10, + STREAMED_SOUND_MISSION_LAW4_3, + STREAMED_SOUND_MISSION_LAW4_4, + STREAMED_SOUND_MISSION_LAW4_5, + STREAMED_SOUND_MISSION_LAW4_6, + STREAMED_SOUND_MISSION_LAW4_7, + STREAMED_SOUND_MISSION_LAW4_8, + STREAMED_SOUND_MISSION_LAW4_9, + STREAMED_SOUND_MISSION_PHIL1_2, + STREAMED_SOUND_MISSION_PHIL1_3, + STREAMED_SOUND_MISSION_PHIL2_1, + STREAMED_SOUND_MISSION_PHIL2_2, + STREAMED_SOUND_MISSION_PHIL2_3, + STREAMED_SOUND_MISSION_PHIL2_4, + STREAMED_SOUND_MISSION_PHIL2_5, + STREAMED_SOUND_MISSION_PHIL2_6, + STREAMED_SOUND_MISSION_PHIL2_7, + STREAMED_SOUND_MISSION_PHIL2_8, + STREAMED_SOUND_MISSION_PHIL2_9, + STREAMED_SOUND_MISSION_PHIL210, + STREAMED_SOUND_MISSION_PHIL211, + STREAMED_SOUND_MISSION_PORN1_1, + STREAMED_SOUND_MISSION_PORN1_2, + STREAMED_SOUND_MISSION_PORN1_3, + STREAMED_SOUND_MISSION_PRN1_3A, + STREAMED_SOUND_MISSION_PORN1_4, + STREAMED_SOUND_MISSION_PORN1_5, + STREAMED_SOUND_MISSION_PORN1_6, + STREAMED_SOUND_MISSION_PORN1_7, + STREAMED_SOUND_MISSION_PORN1_8, + STREAMED_SOUND_MISSION_PORN1_9, + STREAMED_SOUND_MISSION_PRN1_10, + STREAMED_SOUND_MISSION_PRN1_11, + STREAMED_SOUND_MISSION_PRN1_12, + STREAMED_SOUND_MISSION_PRN1_13, + STREAMED_SOUND_MISSION_PRN1_14, + STREAMED_SOUND_MISSION_PRN1_15, + STREAMED_SOUND_MISSION_PRN1_16, + STREAMED_SOUND_MISSION_PRN1_17, + STREAMED_SOUND_MISSION_PRN1_18, + STREAMED_SOUND_MISSION_PRN1_19, + STREAMED_SOUND_MISSION_PRN1_20, + STREAMED_SOUND_MISSION_PRN1_21, + STREAMED_SOUND_MISSION_PORN3_1, + STREAMED_SOUND_MISSION_PORN3_2, + STREAMED_SOUND_MISSION_PORN3_3, + STREAMED_SOUND_MISSION_PORN3_4, + STREAMED_SOUND_MISSION_PSYCH_1, + STREAMED_SOUND_MISSION_PSYCH_2, + STREAMED_SOUND_MISSION_ROK2_01, + STREAMED_SOUND_MISSION_ROK3_1, + STREAMED_SOUND_MISSION_ROK3_2, + STREAMED_SOUND_MISSION_ROK3_3, + STREAMED_SOUND_MISSION_ROK3_4, + STREAMED_SOUND_MISSION_ROK3_5, + STREAMED_SOUND_MISSION_ROK3_6, + STREAMED_SOUND_MISSION_ROK3_7, + STREAMED_SOUND_MISSION_ROK3_8, + STREAMED_SOUND_MISSION_ROK3_9, + STREAMED_SOUND_MISSION_ROK3_10, + STREAMED_SOUND_MISSION_ROK3_11, + STREAMED_SOUND_MISSION_ROK3_12, + STREAMED_SOUND_MISSION_ROK3_13, + STREAMED_SOUND_MISSION_ROK3_14, + STREAMED_SOUND_MISSION_ROK3_15, + STREAMED_SOUND_MISSION_ROK3_16, + STREAMED_SOUND_MISSION_ROK3_17, + STREAMED_SOUND_MISSION_ROK3_18, + STREAMED_SOUND_MISSION_ROK3_19, + STREAMED_SOUND_MISSION_ROK3_20, + STREAMED_SOUND_MISSION_ROK3_21, + STREAMED_SOUND_MISSION_ROK3_22, + STREAMED_SOUND_MISSION_ROK3_23, + STREAMED_SOUND_MISSION_ROK3_24, + STREAMED_SOUND_MISSION_ROK3_25, + STREAMED_SOUND_MISSION_ROK3_26, + STREAMED_SOUND_MISSION_ROK3_27, + STREAMED_SOUND_MISSION_ROK3_62, + STREAMED_SOUND_MISSION_ROK3_63, + STREAMED_SOUND_MISSION_ROK3_64, + STREAMED_SOUND_MISSION_ROK3_65, + STREAMED_SOUND_MISSION_ROK3_66, + STREAMED_SOUND_MISSION_ROK3_67, + STREAMED_SOUND_MISSION_ROK3_68, + STREAMED_SOUND_MISSION_ROK3_69, + STREAMED_SOUND_MISSION_ROK3_70, + STREAMED_SOUND_MISSION_ROK3_71, + STREAMED_SOUND_MISSION_ROK3_73, + STREAMED_SOUND_MISSION_RESC_1, + STREAMED_SOUND_MISSION_RESC_2, + STREAMED_SOUND_MISSION_RESC_3, + STREAMED_SOUND_MISSION_RESC_4, + STREAMED_SOUND_MISSION_RESC_5, + STREAMED_SOUND_MISSION_RESC_6, + STREAMED_SOUND_MISSION_RESC_7, + STREAMED_SOUND_MISSION_RESC_8, + STREAMED_SOUND_MISSION_RESC_9, + STREAMED_SOUND_MISSION_RESC_10, + STREAMED_SOUND_MISSION_ROK1_1A, + STREAMED_SOUND_MISSION_ROK1_1B, + STREAMED_SOUND_MISSION_ROK1_5, + STREAMED_SOUND_MISSION_ROK1_6, + STREAMED_SOUND_MISSION_ROK1_7, + STREAMED_SOUND_MISSION_ROK1_8, + STREAMED_SOUND_MISSION_ROK1_9, + STREAMED_SOUND_MISSION_TAX1_1, + STREAMED_SOUND_MISSION_TAX1_2, + STREAMED_SOUND_MISSION_TAX1_3, + STREAMED_SOUND_MISSION_TAX1_4, + STREAMED_SOUND_MISSION_TAX1_5, + STREAMED_SOUND_MISSION_TAX2_1, + STREAMED_SOUND_MISSION_TAX2_2, + STREAMED_SOUND_MISSION_TAX2_3, + STREAMED_SOUND_MISSION_TAX2_4, + STREAMED_SOUND_MISSION_TAX2_5, + STREAMED_SOUND_MISSION_TAX2_6, + STREAMED_SOUND_MISSION_TAX2_7, + STREAMED_SOUND_MISSION_TAX3_1, + STREAMED_SOUND_MISSION_TAX3_2, + STREAMED_SOUND_MISSION_TAX3_3, + STREAMED_SOUND_MISSION_TAX3_4, + STREAMED_SOUND_MISSION_TAX3_5, + STREAMED_SOUND_MISSION_TEX1_1, + STREAMED_SOUND_MISSION_TEX1_2, + STREAMED_SOUND_MISSION_TEX1_3, + STREAMED_SOUND_MISSION_TEX1_4, + STREAMED_SOUND_MISSION_TEX1_5, + STREAMED_SOUND_MISSION_TEX1_6, + STREAMED_SOUND_MISSION_TEX2_1, + STREAMED_SOUND_MISSION_TEX3_1, + STREAMED_SOUND_MISSION_TEX3_2, + STREAMED_SOUND_MISSION_TEX3_3, + STREAMED_SOUND_MISSION_TEX3_4, + STREAMED_SOUND_MISSION_TEX3_5, + STREAMED_SOUND_MISSION_TEX3_6, + STREAMED_SOUND_MISSION_TEX3_7, + STREAMED_SOUND_MISSION_TEX3_8, + STREAMED_SOUND_MISSION_HAT_1A, + STREAMED_SOUND_MISSION_INTRO1, + STREAMED_SOUND_MISSION_INTRO2, + STREAMED_SOUND_MISSION_INTRO3, + STREAMED_SOUND_MISSION_INTRO4, + STREAMED_SOUND_MISSION_MOB_01A, + STREAMED_SOUND_MISSION_MOB_01B, + STREAMED_SOUND_MISSION_MOB_01C, + STREAMED_SOUND_MISSION_MOB_02A, + STREAMED_SOUND_MISSION_MOB_02B, + STREAMED_SOUND_MISSION_MOB_02C, + STREAMED_SOUND_MISSION_MOB_03A, + STREAMED_SOUND_MISSION_MOB_03B, + STREAMED_SOUND_MISSION_MOB_03C, + STREAMED_SOUND_MISSION_MOB_03D, + STREAMED_SOUND_MISSION_MOB_03E, + STREAMED_SOUND_MISSION_SHARK_1, + STREAMED_SOUND_MISSION_SHARK_2, + STREAMED_SOUND_MISSION_SHARK_3, + STREAMED_SOUND_MISSION_SHARK_4, + STREAMED_SOUND_MISSION_SHARK_5, + STREAMED_SOUND_MISSION_MOB_04A, + STREAMED_SOUND_MISSION_MOB_04B, + STREAMED_SOUND_MISSION_MOB_04C, + STREAMED_SOUND_MISSION_MOB_04D, + STREAMED_SOUND_MISSION_MOB_05A, + STREAMED_SOUND_MISSION_MOB_05B, + STREAMED_SOUND_MISSION_MOB_05C, + STREAMED_SOUND_MISSION_MOB_05D, + STREAMED_SOUND_MISSION_MOB_06A, + STREAMED_SOUND_MISSION_MOB_06B, + STREAMED_SOUND_MISSION_MOB_06C, + STREAMED_SOUND_MISSION_MOB_07A, + STREAMED_SOUND_MISSION_MOB_07B, + STREAMED_SOUND_MISSION_MOB_08A, + STREAMED_SOUND_MISSION_MOB_08B, + STREAMED_SOUND_MISSION_MOB_08C, + STREAMED_SOUND_MISSION_MOB_08D, + STREAMED_SOUND_MISSION_MOB_08E, + STREAMED_SOUND_MISSION_MOB_08F, + STREAMED_SOUND_MISSION_MOB_08G, + STREAMED_SOUND_MISSION_MOB_09A, + STREAMED_SOUND_MISSION_MOB_09B, + STREAMED_SOUND_MISSION_MOB_09C, + STREAMED_SOUND_MISSION_MOB_09D, + STREAMED_SOUND_MISSION_MOB_09E, + STREAMED_SOUND_MISSION_MOB_09F, + STREAMED_SOUND_MISSION_MOB_10A, + STREAMED_SOUND_MISSION_MOB_10B, + STREAMED_SOUND_MISSION_MOB_10C, + STREAMED_SOUND_MISSION_MOB_10D, + STREAMED_SOUND_MISSION_MOB_10E, + STREAMED_SOUND_MISSION_MOB_11A, + STREAMED_SOUND_MISSION_MOB_11B, + STREAMED_SOUND_MISSION_MOB_11C, + STREAMED_SOUND_MISSION_MOB_11D, + STREAMED_SOUND_MISSION_MOB_11E, + STREAMED_SOUND_MISSION_MOB_11F, + STREAMED_SOUND_MISSION_MOB_14A, + STREAMED_SOUND_MISSION_MOB_14B, + STREAMED_SOUND_MISSION_MOB_14C, + STREAMED_SOUND_MISSION_MOB_14D, + STREAMED_SOUND_MISSION_MOB_14E, + STREAMED_SOUND_MISSION_MOB_14F, + STREAMED_SOUND_MISSION_MOB_14G, + STREAMED_SOUND_MISSION_MOB_14H, + STREAMED_SOUND_MISSION_MOB_16A, + STREAMED_SOUND_MISSION_MOB_16B, + STREAMED_SOUND_MISSION_MOB_16C, + STREAMED_SOUND_MISSION_MOB_16D, + STREAMED_SOUND_MISSION_MOB_16E, + STREAMED_SOUND_MISSION_MOB_16F, + STREAMED_SOUND_MISSION_MOB_16G, + STREAMED_SOUND_MISSION_MOB_17A, + STREAMED_SOUND_MISSION_MOB_17B, + STREAMED_SOUND_MISSION_MOB_17C, + STREAMED_SOUND_MISSION_MOB_17D, + STREAMED_SOUND_MISSION_MOB_17E, + STREAMED_SOUND_MISSION_MOB_17G, + STREAMED_SOUND_MISSION_MOB_17H, + STREAMED_SOUND_MISSION_MOB_17I, + STREAMED_SOUND_MISSION_MOB_17J, + STREAMED_SOUND_MISSION_MOB_17K, + STREAMED_SOUND_MISSION_MOB_17L, + STREAMED_SOUND_MISSION_MOB_18A, + STREAMED_SOUND_MISSION_MOB_18B, + STREAMED_SOUND_MISSION_MOB_18C, + STREAMED_SOUND_MISSION_MOB_18D, + STREAMED_SOUND_MISSION_MOB_18E, + STREAMED_SOUND_MISSION_MOB_18F, + STREAMED_SOUND_MISSION_MOB_18G, + STREAMED_SOUND_MISSION_MOB_20A, + STREAMED_SOUND_MISSION_MOB_20B, + STREAMED_SOUND_MISSION_MOB_20C, + STREAMED_SOUND_MISSION_MOB_20D, + STREAMED_SOUND_MISSION_MOB_20E, + STREAMED_SOUND_MISSION_MOB_24A, + STREAMED_SOUND_MISSION_MOB_24B, + STREAMED_SOUND_MISSION_MOB_24C, + STREAMED_SOUND_MISSION_MOB_24D, + STREAMED_SOUND_MISSION_MOB_24E, + STREAMED_SOUND_MISSION_MOB_24F, + STREAMED_SOUND_MISSION_MOB_24G, + STREAMED_SOUND_MISSION_MOB_24H, + STREAMED_SOUND_MISSION_MOB_25A, + STREAMED_SOUND_MISSION_MOB_25B, + STREAMED_SOUND_MISSION_MOB_25C, + STREAMED_SOUND_MISSION_MOB_25D, + STREAMED_SOUND_MISSION_MOB_26A, + STREAMED_SOUND_MISSION_MOB_26B, + STREAMED_SOUND_MISSION_MOB_26C, + STREAMED_SOUND_MISSION_MOB_26D, + STREAMED_SOUND_MISSION_MOB_26E, + STREAMED_SOUND_MISSION_MOB_29A, + STREAMED_SOUND_MISSION_MOB_29B, + STREAMED_SOUND_MISSION_MOB_29C, + STREAMED_SOUND_MISSION_MOB_29D, + STREAMED_SOUND_MISSION_MOB_29E, + STREAMED_SOUND_MISSION_MOB_29F, + STREAMED_SOUND_MISSION_MOB_29G, + STREAMED_SOUND_MISSION_MOB_30A, + STREAMED_SOUND_MISSION_MOB_30B, + STREAMED_SOUND_MISSION_MOB_30C, + STREAMED_SOUND_MISSION_MOB_30D, + STREAMED_SOUND_MISSION_MOB_30E, + STREAMED_SOUND_MISSION_MOB_30F, + STREAMED_SOUND_MISSION_MOB_33A, + STREAMED_SOUND_MISSION_MOB_33B, + STREAMED_SOUND_MISSION_MOB_33C, + STREAMED_SOUND_MISSION_MOB_33D, + STREAMED_SOUND_MISSION_MOB_34A, + STREAMED_SOUND_MISSION_MOB_34B, + STREAMED_SOUND_MISSION_MOB_34C, + STREAMED_SOUND_MISSION_MOB_34D, + STREAMED_SOUND_MISSION_MOB_35A, + STREAMED_SOUND_MISSION_MOB_35B, + STREAMED_SOUND_MISSION_MOB_35C, + STREAMED_SOUND_MISSION_MOB_35D, + STREAMED_SOUND_MISSION_MOB_36A, + STREAMED_SOUND_MISSION_MOB_36B, + STREAMED_SOUND_MISSION_MOB_36C, + STREAMED_SOUND_MISSION_MOB_40A, + STREAMED_SOUND_MISSION_MOB_40B, + STREAMED_SOUND_MISSION_MOB_40C, + STREAMED_SOUND_MISSION_MOB_40D, + STREAMED_SOUND_MISSION_MOB_40E, + STREAMED_SOUND_MISSION_MOB_40F, + STREAMED_SOUND_MISSION_MOB_40G, + STREAMED_SOUND_MISSION_MOB_40H, + STREAMED_SOUND_MISSION_MOB_40I, + STREAMED_SOUND_MISSION_MOB_41A, + STREAMED_SOUND_MISSION_MOB_41B, + STREAMED_SOUND_MISSION_MOB_41C, + STREAMED_SOUND_MISSION_MOB_41D, + STREAMED_SOUND_MISSION_MOB_41E, + STREAMED_SOUND_MISSION_MOB_41F, + STREAMED_SOUND_MISSION_MOB_41G, + STREAMED_SOUND_MISSION_MOB_41H, + STREAMED_SOUND_MISSION_MOB_42A, + STREAMED_SOUND_MISSION_MOB_42B, + STREAMED_SOUND_MISSION_MOB_42C, + STREAMED_SOUND_MISSION_MOB_42D, + STREAMED_SOUND_MISSION_MOB_42E, + STREAMED_SOUND_MISSION_MOB_43A, + STREAMED_SOUND_MISSION_MOB_43B, + STREAMED_SOUND_MISSION_MOB_43C, + STREAMED_SOUND_MISSION_MOB_43D, + STREAMED_SOUND_MISSION_MOB_43E, + STREAMED_SOUND_MISSION_MOB_43F, + STREAMED_SOUND_MISSION_MOB_43G, + STREAMED_SOUND_MISSION_MOB_43H, + STREAMED_SOUND_MISSION_MOB_45A, + STREAMED_SOUND_MISSION_MOB_45B, + STREAMED_SOUND_MISSION_MOB_45C, + STREAMED_SOUND_MISSION_MOB_45D, + STREAMED_SOUND_MISSION_MOB_45E, + STREAMED_SOUND_MISSION_MOB_45F, + STREAMED_SOUND_MISSION_MOB_45G, + STREAMED_SOUND_MISSION_MOB_45H, + STREAMED_SOUND_MISSION_MOB_45I, + STREAMED_SOUND_MISSION_MOB_45J, + STREAMED_SOUND_MISSION_MOB_45K, + STREAMED_SOUND_MISSION_MOB_45L, + STREAMED_SOUND_MISSION_MOB_45M, + STREAMED_SOUND_MISSION_MOB_45N, + STREAMED_SOUND_MISSION_MOB_46A, + STREAMED_SOUND_MISSION_MOB_46B, + STREAMED_SOUND_MISSION_MOB_46C, + STREAMED_SOUND_MISSION_MOB_46D, + STREAMED_SOUND_MISSION_MOB_46E, + STREAMED_SOUND_MISSION_MOB_46F, + STREAMED_SOUND_MISSION_MOB_46G, + STREAMED_SOUND_MISSION_MOB_46H, + STREAMED_SOUND_MISSION_MOB_47A, + STREAMED_SOUND_MISSION_MOB_52A, + STREAMED_SOUND_MISSION_MOB_52B, + STREAMED_SOUND_MISSION_MOB_52C, + STREAMED_SOUND_MISSION_MOB_52D, + STREAMED_SOUND_MISSION_MOB_52E, + STREAMED_SOUND_MISSION_MOB_52F, + STREAMED_SOUND_MISSION_MOB_52G, + STREAMED_SOUND_MISSION_MOB_52H, + STREAMED_SOUND_MISSION_MOB_54A, + STREAMED_SOUND_MISSION_MOB_54B, + STREAMED_SOUND_MISSION_MOB_54C, + STREAMED_SOUND_MISSION_MOB_54D, + STREAMED_SOUND_MISSION_MOB_54E, + STREAMED_SOUND_MISSION_MOB_55A, + STREAMED_SOUND_MISSION_MOB_55B, + STREAMED_SOUND_MISSION_MOB_55C, + STREAMED_SOUND_MISSION_MOB_55D, + STREAMED_SOUND_MISSION_MOB_55E, + STREAMED_SOUND_MISSION_MOB_55F, + STREAMED_SOUND_MISSION_MOB_56A, + STREAMED_SOUND_MISSION_MOB_56B, + STREAMED_SOUND_MISSION_MOB_56C, + STREAMED_SOUND_MISSION_MOB_56D, + STREAMED_SOUND_MISSION_MOB_56E, + STREAMED_SOUND_MISSION_MOB_56F, + STREAMED_SOUND_MISSION_MOB_57A, + STREAMED_SOUND_MISSION_MOB_57B, + STREAMED_SOUND_MISSION_MOB_57C, + STREAMED_SOUND_MISSION_MOB_57D, + STREAMED_SOUND_MISSION_MOB_57E, + STREAMED_SOUND_MISSION_MOB_58A, + STREAMED_SOUND_MISSION_MOB_58B, + STREAMED_SOUND_MISSION_MOB_58C, + STREAMED_SOUND_MISSION_MOB_58D, + STREAMED_SOUND_MISSION_MOB_58E, + STREAMED_SOUND_MISSION_MOB_58F, + STREAMED_SOUND_MISSION_MOB_58G, + STREAMED_SOUND_MISSION_MOB_61A, + STREAMED_SOUND_MISSION_MOB_61B, + STREAMED_SOUND_MISSION_MOB_62A, + STREAMED_SOUND_MISSION_MOB_62B, + STREAMED_SOUND_MISSION_MOB_62C, + STREAMED_SOUND_MISSION_MOB_62D, + STREAMED_SOUND_MISSION_MOB_63A, + STREAMED_SOUND_MISSION_MOB_63B, + STREAMED_SOUND_MISSION_MOB_63C, + STREAMED_SOUND_MISSION_MOB_63D, + STREAMED_SOUND_MISSION_MOB_63E, + STREAMED_SOUND_MISSION_MOB_63F, + STREAMED_SOUND_MISSION_MOB_63G, + STREAMED_SOUND_MISSION_MOB_63H, + STREAMED_SOUND_MISSION_MOB_63I, + STREAMED_SOUND_MISSION_MOB_63J, + STREAMED_SOUND_MISSION_MOB_66A, + STREAMED_SOUND_MISSION_MOB_66B, + STREAMED_SOUND_MISSION_MOB_68A, + STREAMED_SOUND_MISSION_MOB_68B, + STREAMED_SOUND_MISSION_MOB_68C, + STREAMED_SOUND_MISSION_MOB_68D, + STREAMED_SOUND_MISSION_MOB_70A, + STREAMED_SOUND_MISSION_MOB_70B, + STREAMED_SOUND_MISSION_MOB_71A, + STREAMED_SOUND_MISSION_MOB_71B, + STREAMED_SOUND_MISSION_MOB_71C, + STREAMED_SOUND_MISSION_MOB_71D, + STREAMED_SOUND_MISSION_MOB_71E, + STREAMED_SOUND_MISSION_MOB_71F, + STREAMED_SOUND_MISSION_MOB_71G, + STREAMED_SOUND_MISSION_MOB_71H, + STREAMED_SOUND_MISSION_MOB_71I, + STREAMED_SOUND_MISSION_MOB_71J, + STREAMED_SOUND_MISSION_MOB_71K, + STREAMED_SOUND_MISSION_MOB_71L, + STREAMED_SOUND_MISSION_MOB_71M, + STREAMED_SOUND_MISSION_MOB_71N, + STREAMED_SOUND_MISSION_MOB_72A, + STREAMED_SOUND_MISSION_MOB_72B, + STREAMED_SOUND_MISSION_MOB_72C, + STREAMED_SOUND_MISSION_MOB_72D, + STREAMED_SOUND_MISSION_MOB_72E, + STREAMED_SOUND_MISSION_MOB_72F, + STREAMED_SOUND_MISSION_MOB_72G, + STREAMED_SOUND_MISSION_MOB_73A, + STREAMED_SOUND_MISSION_MOB_73C, + STREAMED_SOUND_MISSION_MOB_73D, + STREAMED_SOUND_MISSION_MOB_73F, + STREAMED_SOUND_MISSION_MOB_73G, + STREAMED_SOUND_MISSION_MOB_73I, + STREAMED_SOUND_MISSION_MOB_95A, + STREAMED_SOUND_MISSION_MOB_96A, + STREAMED_SOUND_MISSION_MOB_98A, + STREAMED_SOUND_MISSION_MOB_99A, + STREAMED_SOUND_MISSION_JOB1_1B, + STREAMED_SOUND_MISSION_JOB1_1C, + STREAMED_SOUND_MISSION_JOB1_1D, + STREAMED_SOUND_MISSION_JOB2_1B, + STREAMED_SOUND_MISSION_JOB2_2, + STREAMED_SOUND_MISSION_JOB2_3, + STREAMED_SOUND_MISSION_JOB2_4, + STREAMED_SOUND_MISSION_JOB2_5, + STREAMED_SOUND_MISSION_JOB2_6, + STREAMED_SOUND_MISSION_JOB2_7, + STREAMED_SOUND_MISSION_JOB2_8, + STREAMED_SOUND_MISSION_JOB2_9, + STREAMED_SOUND_MISSION_JOB3_1, + STREAMED_SOUND_MISSION_JOB3_2, + STREAMED_SOUND_MISSION_JOB3_3, + STREAMED_SOUND_MISSION_JOB4_1, + STREAMED_SOUND_MISSION_JOB4_2, + STREAMED_SOUND_MISSION_JOB4_3, + STREAMED_SOUND_MISSION_JOB5_1, + STREAMED_SOUND_MISSION_JOB5_2, + STREAMED_SOUND_MISSION_JOB5_3, + STREAMED_SOUND_MISSION_BJM1_20, + STREAMED_SOUND_MISSION_BJM1_4, + STREAMED_SOUND_MISSION_BJM1_5, + STREAMED_SOUND_MISSION_MERC_39, + STREAMED_SOUND_MISSION_MONO_1, + STREAMED_SOUND_MISSION_MONO_2, + STREAMED_SOUND_MISSION_MONO_3, + STREAMED_SOUND_MISSION_MONO_4, + STREAMED_SOUND_MISSION_MONO_5, + STREAMED_SOUND_MISSION_MONO_6, + STREAMED_SOUND_MISSION_MONO_7, + STREAMED_SOUND_MISSION_MONO_8, + STREAMED_SOUND_MISSION_MONO_9, + STREAMED_SOUND_MISSION_MONO10, + STREAMED_SOUND_MISSION_MONO11, + STREAMED_SOUND_MISSION_MONO12, + STREAMED_SOUND_MISSION_MONO13, + STREAMED_SOUND_MISSION_MONO14, + STREAMED_SOUND_MISSION_MONO15, + STREAMED_SOUND_MISSION_MONO16, + STREAMED_SOUND_MISSION_FUD_01, + STREAMED_SOUND_MISSION_FUD_02, + STREAMED_SOUND_MISSION_FUD_03, + STREAMED_SOUND_MISSION_FUD_04, + STREAMED_SOUND_MISSION_FUD_05, + STREAMED_SOUND_MISSION_FUD_06, + STREAMED_SOUND_MISSION_FUD_07, + STREAMED_SOUND_MISSION_FUD_08, + STREAMED_SOUND_MISSION_FUD_09, + STREAMED_SOUND_MISSION_FUD_10, + STREAMED_SOUND_MISSION_FUD_11, + STREAMED_SOUND_MISSION_FUD_12, + STREAMED_SOUND_MISSION_FUD_13, + STREAMED_SOUND_MISSION_FUD_14, + STREAMED_SOUND_MISSION_FUD_15, + STREAMED_SOUND_MISSION_FUD_16, + STREAMED_SOUND_MISSION_FUD_17, + STREAMED_SOUND_MISSION_FUD_18, + STREAMED_SOUND_MISSION_FUD_19, + STREAMED_SOUND_MISSION_FUD_20, + STREAMED_SOUND_MISSION_BURG_01, + STREAMED_SOUND_MISSION_BURG_02, + STREAMED_SOUND_MISSION_BURG_03, + STREAMED_SOUND_MISSION_BURG_04, + STREAMED_SOUND_MISSION_BURG_05, + STREAMED_SOUND_MISSION_BURG_06, + STREAMED_SOUND_MISSION_BURG_07, + STREAMED_SOUND_MISSION_BURG_08, + STREAMED_SOUND_MISSION_BURG_09, + STREAMED_SOUND_MISSION_BURG_10, + STREAMED_SOUND_MISSION_BURG_11, + STREAMED_SOUND_MISSION_BURG_12, + STREAMED_SOUND_MISSION_CRUST01, + STREAMED_SOUND_MISSION_CRUST02, + STREAMED_SOUND_MISSION_CRUST03, + STREAMED_SOUND_MISSION_CRUST04, + STREAMED_SOUND_MISSION_CRUST05, + STREAMED_SOUND_MISSION_CRUST06, + STREAMED_SOUND_MISSION_CRUST07, + STREAMED_SOUND_MISSION_CRUST08, + STREAMED_SOUND_MISSION_CRUST09, + STREAMED_SOUND_MISSION_BAND_01, + STREAMED_SOUND_MISSION_BAND_02, + STREAMED_SOUND_MISSION_BAND_03, + STREAMED_SOUND_MISSION_BAND_04, + STREAMED_SOUND_MISSION_BAND_05, + STREAMED_SOUND_MISSION_BAND_06, + STREAMED_SOUND_MISSION_BAND_07, + STREAMED_SOUND_MISSION_BAND_08, + STREAMED_SOUND_MISSION_SHAFT01, + STREAMED_SOUND_MISSION_SHAFT02, + STREAMED_SOUND_MISSION_SHAFT03, + STREAMED_SOUND_MISSION_SHAFT04, + STREAMED_SOUND_MISSION_SHAFT05, + STREAMED_SOUND_MISSION_SHAFT06, + STREAMED_SOUND_MISSION_SHAFT07, + STREAMED_SOUND_MISSION_SHAFT08, + STREAMED_SOUND_MISSION_PISS_01, + STREAMED_SOUND_MISSION_PISS_02, + STREAMED_SOUND_MISSION_PISS_03, + STREAMED_SOUND_MISSION_PISS_04, + STREAMED_SOUND_MISSION_PISS_05, + STREAMED_SOUND_MISSION_PISS_06, + STREAMED_SOUND_MISSION_PISS_07, + STREAMED_SOUND_MISSION_PISS_08, + STREAMED_SOUND_MISSION_PISS_09, + STREAMED_SOUND_MISSION_PISS_10, + STREAMED_SOUND_MISSION_PISS_11, + STREAMED_SOUND_MISSION_PISS_12, + STREAMED_SOUND_MISSION_PISS_13, + STREAMED_SOUND_MISSION_PISS_14, + STREAMED_SOUND_MISSION_PISS_15, + STREAMED_SOUND_MISSION_PISS_16, + STREAMED_SOUND_MISSION_PISS_17, + STREAMED_SOUND_MISSION_PISS_18, + STREAMED_SOUND_MISSION_PISS_19, + STREAMED_SOUND_MISSION_GIMME01, + STREAMED_SOUND_MISSION_GIMME02, + STREAMED_SOUND_MISSION_GIMME03, + STREAMED_SOUND_MISSION_GIMME04, + STREAMED_SOUND_MISSION_GIMME05, + STREAMED_SOUND_MISSION_GIMME06, + STREAMED_SOUND_MISSION_GIMME07, + STREAMED_SOUND_MISSION_GIMME08, + STREAMED_SOUND_MISSION_GIMME09, + STREAMED_SOUND_MISSION_GIMME10, + STREAMED_SOUND_MISSION_GIMME11, + STREAMED_SOUND_MISSION_GIMME12, + STREAMED_SOUND_MISSION_GIMME13, + STREAMED_SOUND_MISSION_GIMME14, + STREAMED_SOUND_MISSION_GIMME15, + STREAMED_SOUND_MISSION_BUST_01, + STREAMED_SOUND_MISSION_BUST_02, + STREAMED_SOUND_MISSION_BUST_03, + STREAMED_SOUND_MISSION_BUST_04, + STREAMED_SOUND_MISSION_BUST_05, + STREAMED_SOUND_MISSION_BUST_06, + STREAMED_SOUND_MISSION_BUST_07, + STREAMED_SOUND_MISSION_BUST_08, + STREAMED_SOUND_MISSION_BUST_09, + STREAMED_SOUND_MISSION_BUST_10, + STREAMED_SOUND_MISSION_BUST_11, + STREAMED_SOUND_MISSION_BUST_12, + STREAMED_SOUND_MISSION_BUST_13, + STREAMED_SOUND_MISSION_BUST_14, + STREAMED_SOUND_MISSION_BUST_15, + STREAMED_SOUND_MISSION_BUST_16, + STREAMED_SOUND_MISSION_BUST_17, + STREAMED_SOUND_MISSION_BUST_18, + STREAMED_SOUND_MISSION_BUST_19, + STREAMED_SOUND_MISSION_BUST_20, + STREAMED_SOUND_MISSION_BUST_21, + STREAMED_SOUND_MISSION_BUST_22, + STREAMED_SOUND_MISSION_BUST_23, + STREAMED_SOUND_MISSION_BUST_24, + STREAMED_SOUND_MISSION_BUST_25, + STREAMED_SOUND_MISSION_BUST_26, + STREAMED_SOUND_MISSION_BUST_27, + STREAMED_SOUND_MISSION_BUST_28, + TOTAL_STREAMED_SOUNDS, + NO_TRACK, +}; + +enum AudioEntityHandle { + AEHANDLE_NONE = -5, + AEHANDLE_ERROR_NOAUDIOSYS = -4, + AEHANDLE_ERROR_NOFREESLOT = -3, + AEHANDLE_ERROR_NOENTITY = -2, + AEHANDLE_ERROR_BADAUDIOTYPE = -1, +}; + +enum eAudioType +{ + AUDIOTYPE_PHYSICAL = 0, + AUDIOTYPE_EXPLOSION, + AUDIOTYPE_FIRE, + AUDIOTYPE_WEATHER, + AUDIOTYPE_SCRIPTOBJECT, +#ifdef GTA_BRIDGE + AUDIOTYPE_BRIDGE, +#endif + AUDIOTYPE_COLLISION, + AUDIOTYPE_FRONTEND, + AUDIOTYPE_PROJECTILE, + AUDIOTYPE_GARAGE, + AUDIOTYPE_FIREHYDRANT, + AUDIOTYPE_WATERCANNON, + AUDIOTYPE_ESCALATOR, + AUDIOTYPE_EXTRA_SOUNDS, + AUDIOTYPE_POLICERADIO, + TOTAL_AUDIO_TYPES, +}; diff --git a/src/audio/eax/eax-util.cpp b/src/audio/eax/eax-util.cpp new file mode 100644 index 0000000..42eef73 --- /dev/null +++ b/src/audio/eax/eax-util.cpp @@ -0,0 +1,706 @@ +/***********************************************************************************************\ +* * +* EAX-UTIL.CPP - utilities for EAX 3.0 * +* Function declaration for EAX Morphing * +* String names of the all the presets defined in eax-util.h * +* Arrays grouping together all the EAX presets in a scenario * +* * +************************************************************************************************/ + +#include "eax-util.h" +#include <math.h> + +// Function prototypes used by EAX3ListenerInterpolate +void Clamp(EAXVECTOR *eaxVector); +bool CheckEAX3LP(LPEAXLISTENERPROPERTIES lpEAX3LP); + + +/***********************************************************************************************\ +* +* Definition of the EAXMorph function - EAX3ListenerInterpolate +* +\***********************************************************************************************/ + +/* + EAX3ListenerInterpolate + lpStart - Initial EAX 3 Listener parameters + lpFinish - Final EAX 3 Listener parameters + flRatio - Ratio Destination : Source (0.0 == Source, 1.0 == Destination) + lpResult - Interpolated EAX 3 Listener parameters + bCheckValues - Check EAX 3.0 parameters are in range, default = false (no checking) +*/ +bool EAX3ListenerInterpolate(LPEAXLISTENERPROPERTIES lpStart, LPEAXLISTENERPROPERTIES lpFinish, + float flRatio, LPEAXLISTENERPROPERTIES lpResult, bool bCheckValues) +{ + EAXVECTOR StartVector, FinalVector; + + float flInvRatio; + + if (bCheckValues) + { + if (!CheckEAX3LP(lpStart)) + return false; + + if (!CheckEAX3LP(lpFinish)) + return false; + } + + if (flRatio >= 1.0f) + { + memcpy(lpResult, lpFinish, sizeof(EAXLISTENERPROPERTIES)); + return true; + } + else if (flRatio <= 0.0f) + { + memcpy(lpResult, lpStart, sizeof(EAXLISTENERPROPERTIES)); + return true; + } + + flInvRatio = (1.0f - flRatio); + + // Environment + lpResult->ulEnvironment = 26; // (UNDEFINED environment) + + // Environment Size + if (lpStart->flEnvironmentSize == lpFinish->flEnvironmentSize) + lpResult->flEnvironmentSize = lpStart->flEnvironmentSize; + else + lpResult->flEnvironmentSize = (float)exp( (log(lpStart->flEnvironmentSize) * flInvRatio) + (log(lpFinish->flEnvironmentSize) * flRatio) ); + + // Environment Diffusion + if (lpStart->flEnvironmentDiffusion == lpFinish->flEnvironmentDiffusion) + lpResult->flEnvironmentDiffusion = lpStart->flEnvironmentDiffusion; + else + lpResult->flEnvironmentDiffusion = (lpStart->flEnvironmentDiffusion * flInvRatio) + (lpFinish->flEnvironmentDiffusion * flRatio); + + // Room + if (lpStart->lRoom == lpFinish->lRoom) + lpResult->lRoom = lpStart->lRoom; + else + lpResult->lRoom = (int)( ((float)lpStart->lRoom * flInvRatio) + ((float)lpFinish->lRoom * flRatio) ); + + // Room HF + if (lpStart->lRoomHF == lpFinish->lRoomHF) + lpResult->lRoomHF = lpStart->lRoomHF; + else + lpResult->lRoomHF = (int)( ((float)lpStart->lRoomHF * flInvRatio) + ((float)lpFinish->lRoomHF * flRatio) ); + + // Room LF + if (lpStart->lRoomLF == lpFinish->lRoomLF) + lpResult->lRoomLF = lpStart->lRoomLF; + else + lpResult->lRoomLF = (int)( ((float)lpStart->lRoomLF * flInvRatio) + ((float)lpFinish->lRoomLF * flRatio) ); + + // Decay Time + if (lpStart->flDecayTime == lpFinish->flDecayTime) + lpResult->flDecayTime = lpStart->flDecayTime; + else + lpResult->flDecayTime = (float)exp( (log(lpStart->flDecayTime) * flInvRatio) + (log(lpFinish->flDecayTime) * flRatio) ); + + // Decay HF Ratio + if (lpStart->flDecayHFRatio == lpFinish->flDecayHFRatio) + lpResult->flDecayHFRatio = lpStart->flDecayHFRatio; + else + lpResult->flDecayHFRatio = (float)exp( (log(lpStart->flDecayHFRatio) * flInvRatio) + (log(lpFinish->flDecayHFRatio) * flRatio) ); + + // Decay LF Ratio + if (lpStart->flDecayLFRatio == lpFinish->flDecayLFRatio) + lpResult->flDecayLFRatio = lpStart->flDecayLFRatio; + else + lpResult->flDecayLFRatio = (float)exp( (log(lpStart->flDecayLFRatio) * flInvRatio) + (log(lpFinish->flDecayLFRatio) * flRatio) ); + + // Reflections + if (lpStart->lReflections == lpFinish->lReflections) + lpResult->lReflections = lpStart->lReflections; + else + lpResult->lReflections = (int)( ((float)lpStart->lReflections * flInvRatio) + ((float)lpFinish->lReflections * flRatio) ); + + // Reflections Delay + if (lpStart->flReflectionsDelay == lpFinish->flReflectionsDelay) + lpResult->flReflectionsDelay = lpStart->flReflectionsDelay; + else + lpResult->flReflectionsDelay = (float)exp( (log(lpStart->flReflectionsDelay+0.0001f) * flInvRatio) + (log(lpFinish->flReflectionsDelay+0.0001f) * flRatio) ); + + // Reflections Pan + + // To interpolate the vector correctly we need to ensure that both the initial and final vectors vectors are clamped to a length of 1.0f + StartVector = lpStart->vReflectionsPan; + FinalVector = lpFinish->vReflectionsPan; + + Clamp(&StartVector); + Clamp(&FinalVector); + + if (lpStart->vReflectionsPan.x == lpFinish->vReflectionsPan.x) + lpResult->vReflectionsPan.x = lpStart->vReflectionsPan.x; + else + lpResult->vReflectionsPan.x = FinalVector.x + (flInvRatio * (StartVector.x - FinalVector.x)); + + if (lpStart->vReflectionsPan.y == lpFinish->vReflectionsPan.y) + lpResult->vReflectionsPan.y = lpStart->vReflectionsPan.y; + else + lpResult->vReflectionsPan.y = FinalVector.y + (flInvRatio * (StartVector.y - FinalVector.y)); + + if (lpStart->vReflectionsPan.z == lpFinish->vReflectionsPan.z) + lpResult->vReflectionsPan.z = lpStart->vReflectionsPan.z; + else + lpResult->vReflectionsPan.z = FinalVector.z + (flInvRatio * (StartVector.z - FinalVector.z)); + + // Reverb + if (lpStart->lReverb == lpFinish->lReverb) + lpResult->lReverb = lpStart->lReverb; + else + lpResult->lReverb = (int)( ((float)lpStart->lReverb * flInvRatio) + ((float)lpFinish->lReverb * flRatio) ); + + // Reverb Delay + if (lpStart->flReverbDelay == lpFinish->flReverbDelay) + lpResult->flReverbDelay = lpStart->flReverbDelay; + else + lpResult->flReverbDelay = (float)exp( (log(lpStart->flReverbDelay+0.0001f) * flInvRatio) + (log(lpFinish->flReverbDelay+0.0001f) * flRatio) ); + + // Reverb Pan + + // To interpolate the vector correctly we need to ensure that both the initial and final vectors are clamped to a length of 1.0f + StartVector = lpStart->vReverbPan; + FinalVector = lpFinish->vReverbPan; + + Clamp(&StartVector); + Clamp(&FinalVector); + + if (lpStart->vReverbPan.x == lpFinish->vReverbPan.x) + lpResult->vReverbPan.x = lpStart->vReverbPan.x; + else + lpResult->vReverbPan.x = FinalVector.x + (flInvRatio * (StartVector.x - FinalVector.x)); + + if (lpStart->vReverbPan.y == lpFinish->vReverbPan.y) + lpResult->vReverbPan.y = lpStart->vReverbPan.y; + else + lpResult->vReverbPan.y = FinalVector.y + (flInvRatio * (StartVector.y - FinalVector.y)); + + if (lpStart->vReverbPan.z == lpFinish->vReverbPan.z) + lpResult->vReverbPan.z = lpStart->vReverbPan.z; + else + lpResult->vReverbPan.z = FinalVector.z + (flInvRatio * (StartVector.z - FinalVector.z)); + + // Echo Time + if (lpStart->flEchoTime == lpFinish->flEchoTime) + lpResult->flEchoTime = lpStart->flEchoTime; + else + lpResult->flEchoTime = (float)exp( (log(lpStart->flEchoTime) * flInvRatio) + (log(lpFinish->flEchoTime) * flRatio) ); + + // Echo Depth + if (lpStart->flEchoDepth == lpFinish->flEchoDepth) + lpResult->flEchoDepth = lpStart->flEchoDepth; + else + lpResult->flEchoDepth = (lpStart->flEchoDepth * flInvRatio) + (lpFinish->flEchoDepth * flRatio); + + // Modulation Time + if (lpStart->flModulationTime == lpFinish->flModulationTime) + lpResult->flModulationTime = lpStart->flModulationTime; + else + lpResult->flModulationTime = (float)exp( (log(lpStart->flModulationTime) * flInvRatio) + (log(lpFinish->flModulationTime) * flRatio) ); + + // Modulation Depth + if (lpStart->flModulationDepth == lpFinish->flModulationDepth) + lpResult->flModulationDepth = lpStart->flModulationDepth; + else + lpResult->flModulationDepth = (lpStart->flModulationDepth * flInvRatio) + (lpFinish->flModulationDepth * flRatio); + + // Air Absorption HF + if (lpStart->flAirAbsorptionHF == lpFinish->flAirAbsorptionHF) + lpResult->flAirAbsorptionHF = lpStart->flAirAbsorptionHF; + else + lpResult->flAirAbsorptionHF = (lpStart->flAirAbsorptionHF * flInvRatio) + (lpFinish->flAirAbsorptionHF * flRatio); + + // HF Reference + if (lpStart->flHFReference == lpFinish->flHFReference) + lpResult->flHFReference = lpStart->flHFReference; + else + lpResult->flHFReference = (float)exp( (log(lpStart->flHFReference) * flInvRatio) + (log(lpFinish->flHFReference) * flRatio) ); + + // LF Reference + if (lpStart->flLFReference == lpFinish->flLFReference) + lpResult->flLFReference = lpStart->flLFReference; + else + lpResult->flLFReference = (float)exp( (log(lpStart->flLFReference) * flInvRatio) + (log(lpFinish->flLFReference) * flRatio) ); + + // Room Rolloff Factor + if (lpStart->flRoomRolloffFactor == lpFinish->flRoomRolloffFactor) + lpResult->flRoomRolloffFactor = lpStart->flRoomRolloffFactor; + else + lpResult->flRoomRolloffFactor = (lpStart->flRoomRolloffFactor * flInvRatio) + (lpFinish->flRoomRolloffFactor * flRatio); + + // Flags + lpResult->ulFlags = (lpStart->ulFlags & lpFinish->ulFlags); + + // Clamp Delays + if (lpResult->flReflectionsDelay > EAXLISTENER_MAXREFLECTIONSDELAY) + lpResult->flReflectionsDelay = EAXLISTENER_MAXREFLECTIONSDELAY; + + if (lpResult->flReverbDelay > EAXLISTENER_MAXREVERBDELAY) + lpResult->flReverbDelay = EAXLISTENER_MAXREVERBDELAY; + + return true; +} + + +/* + CheckEAX3LP + Checks that the parameters in the EAX 3 Listener Properties structure are in-range +*/ +bool CheckEAX3LP(LPEAXLISTENERPROPERTIES lpEAX3LP) +{ + if ( (lpEAX3LP->lRoom < EAXLISTENER_MINROOM) || (lpEAX3LP->lRoom > EAXLISTENER_MAXROOM) ) + return false; + + if ( (lpEAX3LP->lRoomHF < EAXLISTENER_MINROOMHF) || (lpEAX3LP->lRoomHF > EAXLISTENER_MAXROOMHF) ) + return false; + + if ( (lpEAX3LP->lRoomLF < EAXLISTENER_MINROOMLF) || (lpEAX3LP->lRoomLF > EAXLISTENER_MAXROOMLF) ) + return false; + + if ( (lpEAX3LP->ulEnvironment < EAXLISTENER_MINENVIRONMENT) || (lpEAX3LP->ulEnvironment > EAXLISTENER_MAXENVIRONMENT) ) + return false; + + if ( (lpEAX3LP->flEnvironmentSize < EAXLISTENER_MINENVIRONMENTSIZE) || (lpEAX3LP->flEnvironmentSize > EAXLISTENER_MAXENVIRONMENTSIZE) ) + return false; + + if ( (lpEAX3LP->flEnvironmentDiffusion < EAXLISTENER_MINENVIRONMENTDIFFUSION) || (lpEAX3LP->flEnvironmentDiffusion > EAXLISTENER_MAXENVIRONMENTDIFFUSION) ) + return false; + + if ( (lpEAX3LP->flDecayTime < EAXLISTENER_MINDECAYTIME) || (lpEAX3LP->flDecayTime > EAXLISTENER_MAXDECAYTIME) ) + return false; + + if ( (lpEAX3LP->flDecayHFRatio < EAXLISTENER_MINDECAYHFRATIO) || (lpEAX3LP->flDecayHFRatio > EAXLISTENER_MAXDECAYHFRATIO) ) + return false; + + if ( (lpEAX3LP->flDecayLFRatio < EAXLISTENER_MINDECAYLFRATIO) || (lpEAX3LP->flDecayLFRatio > EAXLISTENER_MAXDECAYLFRATIO) ) + return false; + + if ( (lpEAX3LP->lReflections < EAXLISTENER_MINREFLECTIONS) || (lpEAX3LP->lReflections > EAXLISTENER_MAXREFLECTIONS) ) + return false; + + if ( (lpEAX3LP->flReflectionsDelay < EAXLISTENER_MINREFLECTIONSDELAY) || (lpEAX3LP->flReflectionsDelay > EAXLISTENER_MAXREFLECTIONSDELAY) ) + return false; + + if ( (lpEAX3LP->lReverb < EAXLISTENER_MINREVERB) || (lpEAX3LP->lReverb > EAXLISTENER_MAXREVERB) ) + return false; + + if ( (lpEAX3LP->flReverbDelay < EAXLISTENER_MINREVERBDELAY) || (lpEAX3LP->flReverbDelay > EAXLISTENER_MAXREVERBDELAY) ) + return false; + + if ( (lpEAX3LP->flEchoTime < EAXLISTENER_MINECHOTIME) || (lpEAX3LP->flEchoTime > EAXLISTENER_MAXECHOTIME) ) + return false; + + if ( (lpEAX3LP->flEchoDepth < EAXLISTENER_MINECHODEPTH) || (lpEAX3LP->flEchoDepth > EAXLISTENER_MAXECHODEPTH) ) + return false; + + if ( (lpEAX3LP->flModulationTime < EAXLISTENER_MINMODULATIONTIME) || (lpEAX3LP->flModulationTime > EAXLISTENER_MAXMODULATIONTIME) ) + return false; + + if ( (lpEAX3LP->flModulationDepth < EAXLISTENER_MINMODULATIONDEPTH) || (lpEAX3LP->flModulationDepth > EAXLISTENER_MAXMODULATIONDEPTH) ) + return false; + + if ( (lpEAX3LP->flAirAbsorptionHF < EAXLISTENER_MINAIRABSORPTIONHF) || (lpEAX3LP->flAirAbsorptionHF > EAXLISTENER_MAXAIRABSORPTIONHF) ) + return false; + + if ( (lpEAX3LP->flHFReference < EAXLISTENER_MINHFREFERENCE) || (lpEAX3LP->flHFReference > EAXLISTENER_MAXHFREFERENCE) ) + return false; + + if ( (lpEAX3LP->flLFReference < EAXLISTENER_MINLFREFERENCE) || (lpEAX3LP->flLFReference > EAXLISTENER_MAXLFREFERENCE) ) + return false; + + if ( (lpEAX3LP->flRoomRolloffFactor < EAXLISTENER_MINROOMROLLOFFFACTOR) || (lpEAX3LP->flRoomRolloffFactor > EAXLISTENER_MAXROOMROLLOFFFACTOR) ) + return false; + + if (lpEAX3LP->ulFlags & EAXLISTENERFLAGS_RESERVED) + return false; + + return true; +} + +/* + Clamp + Clamps the length of the vector to 1.0f +*/ +void Clamp(EAXVECTOR *eaxVector) +{ + float flMagnitude; + float flInvMagnitude; + + flMagnitude = (float)sqrt((eaxVector->x*eaxVector->x) + (eaxVector->y*eaxVector->y) + (eaxVector->z*eaxVector->z)); + + if (flMagnitude <= 1.0f) + return; + + flInvMagnitude = 1.0f / flMagnitude; + + eaxVector->x *= flInvMagnitude; + eaxVector->y *= flInvMagnitude; + eaxVector->z *= flInvMagnitude; +} + + +/***********************************************************************************************\ +* +* To assist those developers wishing to add EAX effects to their level editors, each of the + +* List of string names of the various EAX 3.0 presets defined in eax-util.h +* Arrays to group together presets of the same scenario +* +\***********************************************************************************************/ + + +////////////////////////////////////////////////////// +// Array of scenario names // +////////////////////////////////////////////////////// + +const char* EAX30_SCENARIO_NAMES[] = +{ + "Castle", + "Factory", + "IcePalace", + "SpaceStation", + "WoodenShip", + "Sports", + "Prefab", + "Domes and Pipes", + "Outdoors", + "Mood", + "Driving", + "City", + "Miscellaneous", + "Original" +}; + +////////////////////////////////////////////////////// +// Array of standardised location names // +////////////////////////////////////////////////////// + +const char* EAX30_LOCATION_NAMES[] = +{ + "Hall", + "Large Room", + "Medium Room", + "Small Room", + "Cupboard", + "Alcove", + "Long Passage", + "Short Passage", + "Courtyard" +}; + +////////////////////////////////////////////////////// +// Standardised Location effects can be accessed // +// from a matrix // +////////////////////////////////////////////////////// + +EAXLISTENERPROPERTIES EAX30_STANDARD_PRESETS[EAX30_NUM_STANDARD_SCENARIOS][EAX30_NUM_LOCATIONS]= +{ + {EAX30_PRESET_CASTLE_HALL, EAX30_PRESET_CASTLE_LARGEROOM, EAX30_PRESET_CASTLE_MEDIUMROOM, EAX30_PRESET_CASTLE_SMALLROOM, EAX30_PRESET_CASTLE_CUPBOARD, EAX30_PRESET_CASTLE_ALCOVE, EAX30_PRESET_CASTLE_LONGPASSAGE, EAX30_PRESET_CASTLE_SHORTPASSAGE, EAX30_PRESET_CASTLE_COURTYARD}, + {EAX30_PRESET_FACTORY_HALL, EAX30_PRESET_FACTORY_LARGEROOM, EAX30_PRESET_FACTORY_MEDIUMROOM, EAX30_PRESET_FACTORY_SMALLROOM, EAX30_PRESET_FACTORY_CUPBOARD, EAX30_PRESET_FACTORY_ALCOVE, EAX30_PRESET_FACTORY_LONGPASSAGE, EAX30_PRESET_FACTORY_SHORTPASSAGE, EAX30_PRESET_FACTORY_COURTYARD}, + {EAX30_PRESET_ICEPALACE_HALL, EAX30_PRESET_ICEPALACE_LARGEROOM, EAX30_PRESET_ICEPALACE_MEDIUMROOM, EAX30_PRESET_ICEPALACE_SMALLROOM, EAX30_PRESET_ICEPALACE_CUPBOARD, EAX30_PRESET_ICEPALACE_ALCOVE, EAX30_PRESET_ICEPALACE_LONGPASSAGE, EAX30_PRESET_ICEPALACE_SHORTPASSAGE, EAX30_PRESET_ICEPALACE_COURTYARD}, + {EAX30_PRESET_SPACESTATION_HALL,EAX30_PRESET_SPACESTATION_LARGEROOM,EAX30_PRESET_SPACESTATION_MEDIUMROOM, EAX30_PRESET_SPACESTATION_SMALLROOM,EAX30_PRESET_SPACESTATION_CUPBOARD, EAX30_PRESET_SPACESTATION_ALCOVE, EAX30_PRESET_SPACESTATION_LONGPASSAGE, EAX30_PRESET_SPACESTATION_SHORTPASSAGE, EAX30_PRESET_SPACESTATION_HALL}, + {EAX30_PRESET_WOODEN_HALL, EAX30_PRESET_WOODEN_LARGEROOM, EAX30_PRESET_WOODEN_MEDIUMROOM, EAX30_PRESET_WOODEN_SMALLROOM, EAX30_PRESET_WOODEN_CUPBOARD, EAX30_PRESET_WOODEN_ALCOVE, EAX30_PRESET_WOODEN_LONGPASSAGE, EAX30_PRESET_WOODEN_SHORTPASSAGE, EAX30_PRESET_WOODEN_COURTYARD}, +}; + + +/********************************************************************************************************/ + +////////////////////////////////////////////////////// +// Array of original environment names // +////////////////////////////////////////////////////// + +const char* EAX30_ORIGINAL_PRESET_NAMES[] = +{ + "Generic", + "Padded Cell", + "Room", + "Bathroom", + "Living Room", + "Stone Room", + "Auditorium", + "Concert Hall", + "Cave", + "Arena", + "Hangar", + "Carpetted Hallway", + "Hallway", + "Stone Corridor", + "Alley", + "Forest", + "City", + "Mountains", + "Quarry", + "Plain", + "Parking Lot", + "Sewer Pipe", + "Underwater", + "Drugged", + "Dizzy", + "Psychotic" +}; + +////////////////////////////////////////////////////// +// Sports effects matrix // +////////////////////////////////////////////////////// + +EAXLISTENERPROPERTIES EAX30_ORIGINAL_PRESETS[] = +{ + EAX30_PRESET_GENERIC, + EAX30_PRESET_PADDEDCELL, + EAX30_PRESET_ROOM, + EAX30_PRESET_BATHROOM, + EAX30_PRESET_LIVINGROOM, + EAX30_PRESET_STONEROOM, + EAX30_PRESET_AUDITORIUM, + EAX30_PRESET_CONCERTHALL, + EAX30_PRESET_CAVE, + EAX30_PRESET_ARENA, + EAX30_PRESET_HANGAR, + EAX30_PRESET_CARPETTEDHALLWAY, + EAX30_PRESET_HALLWAY, + EAX30_PRESET_STONECORRIDOR, + EAX30_PRESET_ALLEY, + EAX30_PRESET_FOREST, + EAX30_PRESET_CITY, + EAX30_PRESET_MOUNTAINS, + EAX30_PRESET_QUARRY, + EAX30_PRESET_PLAIN, + EAX30_PRESET_PARKINGLOT, + EAX30_PRESET_SEWERPIPE, + EAX30_PRESET_UNDERWATER, + EAX30_PRESET_DRUGGED, + EAX30_PRESET_DIZZY, + EAX30_PRESET_PSYCHOTIC +}; + +/********************************************************************************************************/ + +////////////////////////////////////////////////////// +// Array of sport environment names // +////////////////////////////////////////////////////// + +const char* EAX30_SPORTS_PRESET_NAMES[] = +{ + "Empty Stadium", + "Full Stadium", + "Stadium Tannoy", + "Squash Court", + "Small Swimming Pool", + "Large Swimming Pool", + "Gymnasium" +}; + +////////////////////////////////////////////////////// +// Sports effects matrix // +////////////////////////////////////////////////////// + +EAXLISTENERPROPERTIES EAX30_SPORTS_PRESETS[] = +{ + EAX30_PRESET_SPORT_EMPTYSTADIUM, + EAX30_PRESET_SPORT_FULLSTADIUM, + EAX30_PRESET_SPORT_STADIUMTANNOY, + EAX30_PRESET_SPORT_SQUASHCOURT, + EAX30_PRESET_SPORT_SMALLSWIMMINGPOOL, + EAX30_PRESET_SPORT_LARGESWIMMINGPOOL, + EAX30_PRESET_SPORT_GYMNASIUM +}; + +/********************************************************************************************************/ + +////////////////////////////////////////////////////// +// Array of prefab environment names // +////////////////////////////////////////////////////// + +const char* EAX30_PREFAB_PRESET_NAMES[] = +{ + "Workshop", + "School Room", + "Practise Room", + "Outhouse", + "Caravan" +}; + +////////////////////////////////////////////////////// +// Prefab effects matrix // +////////////////////////////////////////////////////// + +EAXLISTENERPROPERTIES EAX30_PREFAB_PRESETS[] = +{ + EAX30_PRESET_PREFAB_WORKSHOP, + EAX30_PRESET_PREFAB_SCHOOLROOM, + EAX30_PRESET_PREFAB_PRACTISEROOM, + EAX30_PRESET_PREFAB_OUTHOUSE, + EAX30_PRESET_PREFAB_CARAVAN +}; + +/********************************************************************************************************/ + +////////////////////////////////////////////////////// +// Array of Domes & Pipes environment names // +////////////////////////////////////////////////////// + +const char* EAX30_DOMESNPIPES_PRESET_NAMES[] = +{ + "Domed Tomb", + "Saint Paul's Dome", + "Small Pipe", + "Long Thin Pipe", + "Large Pipe", + "Resonant Pipe" +}; + +////////////////////////////////////////////////////// +// Domes & Pipes effects matrix // +////////////////////////////////////////////////////// + +EAXLISTENERPROPERTIES EAX30_DOMESNPIPES_PRESETS[] = +{ + EAX30_PRESET_DOME_TOMB, + EAX30_PRESET_DOME_SAINTPAULS, + EAX30_PRESET_PIPE_SMALL, + EAX30_PRESET_PIPE_LONGTHIN, + EAX30_PRESET_PIPE_LARGE, + EAX30_PRESET_PIPE_RESONANT +}; + +/********************************************************************************************************/ + +////////////////////////////////////////////////////// +// Array of Outdoors environment names // +////////////////////////////////////////////////////// + +const char* EAX30_OUTDOORS_PRESET_NAMES[] = +{ + "Backyard", + "Rolling Plains", + "Deep Canyon", + "Creek", + "Valley" +}; + +////////////////////////////////////////////////////// +// Outdoors effects matrix // +////////////////////////////////////////////////////// + +EAXLISTENERPROPERTIES EAX30_OUTDOORS_PRESETS[] = +{ + EAX30_PRESET_OUTDOORS_BACKYARD, + EAX30_PRESET_OUTDOORS_ROLLINGPLAINS, + EAX30_PRESET_OUTDOORS_DEEPCANYON, + EAX30_PRESET_OUTDOORS_CREEK, + EAX30_PRESET_OUTDOORS_VALLEY +}; + +/********************************************************************************************************/ + +////////////////////////////////////////////////////// +// Array of Mood environment names // +////////////////////////////////////////////////////// + +const char* EAX30_MOOD_PRESET_NAMES[] = +{ + "Heaven", + "Hell", + "Memory" +}; + +////////////////////////////////////////////////////// +// Mood effects matrix // +////////////////////////////////////////////////////// + +EAXLISTENERPROPERTIES EAX30_MOOD_PRESETS[] = +{ + EAX30_PRESET_MOOD_HEAVEN, + EAX30_PRESET_MOOD_HELL, + EAX30_PRESET_MOOD_MEMORY +}; + +/********************************************************************************************************/ + +////////////////////////////////////////////////////// +// Array of driving environment names // +////////////////////////////////////////////////////// + +const char* EAX30_DRIVING_PRESET_NAMES[] = +{ + "Race Commentator", + "Pit Garage", + "In-car (Stripped out racer)", + "In-car (Sportscar)", + "In-car (Luxury)", + "Full Grandstand", + "Empty Grandstand", + "Tunnel" +}; + +////////////////////////////////////////////////////// +// Driving effects matrix // +////////////////////////////////////////////////////// + +EAXLISTENERPROPERTIES EAX30_DRIVING_PRESETS[] = +{ + EAX30_PRESET_DRIVING_COMMENTATOR, + EAX30_PRESET_DRIVING_PITGARAGE, + EAX30_PRESET_DRIVING_INCAR_RACER, + EAX30_PRESET_DRIVING_INCAR_SPORTS, + EAX30_PRESET_DRIVING_INCAR_LUXURY, + EAX30_PRESET_DRIVING_FULLGRANDSTAND, + EAX30_PRESET_DRIVING_EMPTYGRANDSTAND, + EAX30_PRESET_DRIVING_TUNNEL +}; + +/********************************************************************************************************/ + +////////////////////////////////////////////////////// +// Array of City environment names // +////////////////////////////////////////////////////// + +const char* EAX30_CITY_PRESET_NAMES[] = +{ + "City Streets", + "Subway", + "Museum", + "Library", + "Underpass", + "Abandoned City" +}; + +////////////////////////////////////////////////////// +// City effects matrix // +////////////////////////////////////////////////////// + +EAXLISTENERPROPERTIES EAX30_CITY_PRESETS[] = +{ + EAX30_PRESET_CITY_STREETS, + EAX30_PRESET_CITY_SUBWAY, + EAX30_PRESET_CITY_MUSEUM, + EAX30_PRESET_CITY_LIBRARY, + EAX30_PRESET_CITY_UNDERPASS, + EAX30_PRESET_CITY_ABANDONED +}; + +/********************************************************************************************************/ + +////////////////////////////////////////////////////// +// Array of Misc environment names // +////////////////////////////////////////////////////// + +const char* EAX30_MISC_PRESET_NAMES[] = +{ + "Dusty Box Room", + "Chapel", + "Small Water Room" +}; + +////////////////////////////////////////////////////// +// Misc effects matrix // +////////////////////////////////////////////////////// + +EAXLISTENERPROPERTIES EAX30_MISC_PRESETS[] = +{ + EAX30_PRESET_DUSTYROOM, + EAX30_PRESET_CHAPEL, + EAX30_PRESET_SMALLWATERROOM +}; + diff --git a/src/audio/eax/eax-util.h b/src/audio/eax/eax-util.h new file mode 100644 index 0000000..441f011 --- /dev/null +++ b/src/audio/eax/eax-util.h @@ -0,0 +1,765 @@ +/*******************************************************************\ +* * +* EAX-UTIL.H - utilities for Environmental Audio Extensions v. 3.0 * +* Definitions of the Original 26 EAX Presets * +* Definitions for some new EAX Presets * +* Definitions of some Material Presets * +* Function declaration for EAX Morphing * +* * +\*******************************************************************/ + +#ifndef EAXUTIL_INCLUDED +#define EAXUTIL_INCLUDED + +#include <eax.h> + +/*********************************************************************************************** +* Function : EAX3ListenerInterpolate +* Params : lpStart - Initial EAX 3 Listener parameters +* : lpFinish - Final EAX 3 Listener parameters +* : flRatio - Ratio Destination : Source (0.0 == Source, 1.0 == Destination) +* : lpResult - Interpolated EAX 3 Listener parameters +* : bCheckValues - Check EAX 3.0 parameters are in range, + - default == false (no checking) +************************************************************************************************/ +bool EAX3ListenerInterpolate(EAXLISTENERPROPERTIES *lpStartEAX3LP, EAXLISTENERPROPERTIES *lpFinishEAX3LP, + float flRatio, EAXLISTENERPROPERTIES *lpResultEAX3LP, bool bCheckValues = false); + + +/***********************************************************************************************\ +* +* Legacy environment presets for use with DSPROPERTY_EAXLISTENER_ALLPARAMETERS. +* Each array conforms to the DSPROPSETID_EAX30_ListenerProperties structure defined in EAX.H. +* +************************************************************************************************/ + +// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS +#define EAX30_PRESET_GENERIC \ + {0, 7.5f, 1.000f, -1000, -100, 0, 1.49f, 0.83f, 1.00f, -2602, 0.007f, 0.00f,0.00f,0.00f, 200, 0.011f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } +#define EAX30_PRESET_PADDEDCELL \ + {1, 1.4f, 1.000f, -1000, -6000, 0, 0.17f, 0.10f, 1.00f, -1204, 0.001f, 0.00f,0.00f,0.00f, 207, 0.002f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } +#define EAX30_PRESET_ROOM \ + {2, 1.9f, 1.000f, -1000, -454, 0, 0.40f, 0.83f, 1.00f, -1646, 0.002f, 0.00f,0.00f,0.00f, 53, 0.003f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } +#define EAX30_PRESET_BATHROOM \ + {3, 1.4f, 1.000f, -1000, -1200, 0, 1.49f, 0.54f, 1.00f, -370, 0.007f, 0.00f,0.00f,0.00f, 1030, 0.011f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } +#define EAX30_PRESET_LIVINGROOM \ + {4, 2.5f, 1.000f, -1000, -6000, 0, 0.50f, 0.10f, 1.00f, -1376, 0.003f, 0.00f,0.00f,0.00f, -1104, 0.004f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } +#define EAX30_PRESET_STONEROOM \ + {5, 11.6f, 1.000f, -1000, -300, 0, 2.31f, 0.64f, 1.00f, -711, 0.012f, 0.00f,0.00f,0.00f, 83, 0.017f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } +#define EAX30_PRESET_AUDITORIUM \ + {6, 21.6f, 1.000f, -1000, -476, 0, 4.32f, 0.59f, 1.00f, -789, 0.020f, 0.00f,0.00f,0.00f, -289, 0.030f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } +#define EAX30_PRESET_CONCERTHALL \ + {7, 19.6f, 1.000f, -1000, -500, 0, 3.92f, 0.70f, 1.00f, -1230, 0.020f, 0.00f,0.00f,0.00f, -02, 0.029f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } +#define EAX30_PRESET_CAVE \ + {8, 14.6f, 1.000f, -1000, 0, 0, 2.91f, 1.30f, 1.00f, -602, 0.015f, 0.00f,0.00f,0.00f, -302, 0.022f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x1f } +#define EAX30_PRESET_ARENA \ + {9, 36.2f, 1.000f, -1000, -698, 0, 7.24f, 0.33f, 1.00f, -1166, 0.020f, 0.00f,0.00f,0.00f, 16, 0.030f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } +#define EAX30_PRESET_HANGAR \ + {10, 50.3f, 1.000f, -1000, -1000, 0, 10.05f, 0.23f, 1.00f, -602, 0.020f, 0.00f,0.00f,0.00f, 198, 0.030f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } +#define EAX30_PRESET_CARPETTEDHALLWAY \ + {11, 1.9f, 1.000f, -1000, -4000, 0, 0.30f, 0.10f, 1.00f, -1831, 0.002f, 0.00f,0.00f,0.00f, -1630, 0.030f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } +#define EAX30_PRESET_HALLWAY \ + {12, 1.8f, 1.000f, -1000, -300, 0, 1.49f, 0.59f, 1.00f, -1219, 0.007f, 0.00f,0.00f,0.00f, 441, 0.011f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } +#define EAX30_PRESET_STONECORRIDOR \ + {13, 13.5f, 1.000f, -1000, -237, 0, 2.70f, 0.79f, 1.00f, -1214, 0.013f, 0.00f,0.00f,0.00f, 395, 0.020f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } +#define EAX30_PRESET_ALLEY \ + {14, 7.5f, 0.300f, -1000, -270, 0, 1.49f, 0.86f, 1.00f, -1204, 0.007f, 0.00f,0.00f,0.00f, -4, 0.011f, 0.00f,0.00f,0.00f, 0.125f, 0.950f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } +#define EAX30_PRESET_FOREST \ + {15, 38.0f, 0.300f, -1000, -3300, 0, 1.49f, 0.54f, 1.00f, -2560, 0.162f, 0.00f,0.00f,0.00f, -229, 0.088f, 0.00f,0.00f,0.00f, 0.125f, 1.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } +#define EAX30_PRESET_CITY \ + {16, 7.5f, 0.500f, -1000, -800, 0, 1.49f, 0.67f, 1.00f, -2273, 0.007f, 0.00f,0.00f,0.00f, -1691, 0.011f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } +#define EAX30_PRESET_MOUNTAINS \ + {17, 100.0f, 0.270f, -1000, -2500, 0, 1.49f, 0.21f, 1.00f, -2780, 0.300f, 0.00f,0.00f,0.00f, -1434, 0.100f, 0.00f,0.00f,0.00f, 0.250f, 1.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x1f } +#define EAX30_PRESET_QUARRY \ + {18, 17.5f, 1.000f, -1000, -1000, 0, 1.49f, 0.83f, 1.00f, -10000, 0.061f, 0.00f,0.00f,0.00f, 500, 0.025f, 0.00f,0.00f,0.00f, 0.125f, 0.700f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } +#define EAX30_PRESET_PLAIN \ + {19, 42.5f, 0.210f, -1000, -2000, 0, 1.49f, 0.50f, 1.00f, -2466, 0.179f, 0.00f,0.00f,0.00f, -1926, 0.100f, 0.00f,0.00f,0.00f, 0.250f, 1.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } +#define EAX30_PRESET_PARKINGLOT \ + {20, 8.3f, 1.000f, -1000, 0, 0, 1.65f, 1.50f, 1.00f, -1363, 0.008f, 0.00f,0.00f,0.00f, -1153, 0.012f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x1f } +#define EAX30_PRESET_SEWERPIPE \ + {21, 1.7f, 0.800f, -1000, -1000, 0, 2.81f, 0.14f, 1.00f, 429, 0.014f, 0.00f,0.00f,0.00f, 1023, 0.021f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } +#define EAX30_PRESET_UNDERWATER \ + {22, 1.8f, 1.000f, -1000, -4000, 0, 1.49f, 0.10f, 1.00f, -449, 0.007f, 0.00f,0.00f,0.00f, 1700, 0.011f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 1.180f, 0.348f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } +#define EAX30_PRESET_DRUGGED \ + {23, 1.9f, 0.500f, -1000, 0, 0, 8.39f, 1.39f, 1.00f, -115, 0.002f, 0.00f,0.00f,0.00f, 985, 0.030f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 1.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x1f } +#define EAX30_PRESET_DIZZY \ + {24, 1.8f, 0.600f, -1000, -400, 0, 17.23f, 0.56f, 1.00f, -1713, 0.020f, 0.00f,0.00f,0.00f, -613, 0.030f, 0.00f,0.00f,0.00f, 0.250f, 1.000f, 0.810f, 0.310f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x1f } +#define EAX30_PRESET_PSYCHOTIC \ + {25, 1.0f, 0.500f, -1000, -151, 0, 7.56f, 0.91f, 1.00f, -626, 0.020f, 0.00f,0.00f,0.00f, 774, 0.030f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 4.000f, 1.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x1f } + + +/***********************************************************************************************\ +* +* New environment presets for use with DSPROPERTY_EAXLISTENER_ALLPARAMETERS. +* Each array conforms to the DSPROPSETID_EAX30_ListenerProperties structure defined in EAX.H. +* +************************************************************************************************/ + +// STANDARDISED-LOCATION SCENARIOS + +// CASTLE PRESETS + +// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS +#define EAX30_PRESET_CASTLE_SMALLROOM \ + { 26, 8.3f, 0.890f, -1100, -800, -2000, 1.22f, 0.83f, 0.31f, -100, 0.022f, 0.00f,0.00f,0.00f, 0, 0.011f, 0.00f,0.00f,0.00f, 0.138f, 0.080f, 0.250f, 0.000f, -5.0f, 5168.6f, 139.5f, 0.00f, 0x20 } +#define EAX30_PRESET_CASTLE_SHORTPASSAGE \ + { 26, 8.3f, 0.890f, -1000, -1000, -2000, 2.32f, 0.83f, 0.31f, -100, 0.007f, 0.00f,0.00f,0.00f, -500, 0.023f, 0.00f,0.00f,0.00f, 0.138f, 0.080f, 0.250f, 0.000f, -5.0f, 5168.6f, 139.5f, 0.00f, 0x20 } +#define EAX30_PRESET_CASTLE_MEDIUMROOM \ + { 26, 8.3f, 0.930f, -1000, -1100, -2000, 2.04f, 0.83f, 0.46f, -300, 0.022f, 0.00f,0.00f,0.00f, -200, 0.011f, 0.00f,0.00f,0.00f, 0.155f, 0.030f, 0.250f, 0.000f, -5.0f, 5168.6f, 139.5f, 0.00f, 0x20 } +#define EAX30_PRESET_CASTLE_LONGPASSAGE \ + { 26, 8.3f, 0.890f, -1000, -800, -2000, 3.42f, 0.83f, 0.31f, -200, 0.007f, 0.00f,0.00f,0.00f, -600, 0.023f, 0.00f,0.00f,0.00f, 0.138f, 0.080f, 0.250f, 0.000f, -5.0f, 5168.6f, 139.5f, 0.00f, 0x20 } +#define EAX30_PRESET_CASTLE_LARGEROOM \ + { 26, 8.3f, 0.820f, -1000, -1100, -1800, 2.53f, 0.83f, 0.50f, -900, 0.034f, 0.00f,0.00f,0.00f, -400, 0.016f, 0.00f,0.00f,0.00f, 0.185f, 0.070f, 0.250f, 0.000f, -5.0f, 5168.6f, 139.5f, 0.00f, 0x20 } +#define EAX30_PRESET_CASTLE_HALL \ + { 26, 8.3f, 0.810f, -1000, -1100, -1500, 3.14f, 0.79f, 0.62f, -1300, 0.056f, 0.00f,0.00f,0.00f, -500, 0.024f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5168.6f, 139.5f, 0.00f, 0x20 } +#define EAX30_PRESET_CASTLE_CUPBOARD \ + { 26, 8.3f, 0.890f, -1000, -1100, -2000, 0.67f, 0.87f, 0.31f, 300, 0.010f, 0.00f,0.00f,0.00f, 300, 0.007f, 0.00f,0.00f,0.00f, 0.138f, 0.080f, 0.250f, 0.000f, -5.0f, 5168.6f, 139.5f, 0.00f, 0x20 } +#define EAX30_PRESET_CASTLE_COURTYARD \ + { 26, 8.3f, 0.420f, -1100, -700, -900, 2.13f, 0.61f, 0.23f, -2300, 0.112f, 0.00f,0.00f,0.00f, -1500, 0.036f, 0.00f,0.00f,0.00f, 0.250f, 0.370f, 0.250f, 0.000f, -0.0f, 5000.0f, 250.0f, 0.00f, 0x1f } +#define EAX30_PRESET_CASTLE_ALCOVE \ + { 26, 8.3f, 0.890f, -1000, -600, -2000, 1.64f, 0.87f, 0.31f, -100, 0.007f, 0.00f,0.00f,0.00f, -500, 0.034f, 0.00f,0.00f,0.00f, 0.138f, 0.080f, 0.250f, 0.000f, -5.0f, 5168.6f, 139.5f, 0.00f, 0x20 } + + +// FACTORY PRESETS + +// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS +#define EAX30_PRESET_FACTORY_ALCOVE \ + { 26, 1.8f, 0.590f, -1200, -200, -600, 3.14f, 0.65f, 1.31f, 300, 0.010f, 0.00f,0.00f,0.00f, -1200, 0.038f, 0.00f,0.00f,0.00f, 0.114f, 0.100f, 0.250f, 0.000f, -0.0f, 3762.6f, 362.5f, 0.00f, 0x20 } +#define EAX30_PRESET_FACTORY_SHORTPASSAGE \ + { 26, 1.8f, 0.640f, -1200, -200, -600, 2.53f, 0.65f, 1.31f, 0, 0.010f, 0.00f,0.00f,0.00f, -600, 0.038f, 0.00f,0.00f,0.00f, 0.135f, 0.230f, 0.250f, 0.000f, -0.0f, 3762.6f, 362.5f, 0.00f, 0x20 } +#define EAX30_PRESET_FACTORY_MEDIUMROOM \ + { 26, 1.9f, 0.820f, -1200, -200, -600, 2.76f, 0.65f, 1.31f, -1100, 0.022f, 0.00f,0.00f,0.00f, -400, 0.023f, 0.00f,0.00f,0.00f, 0.174f, 0.070f, 0.250f, 0.000f, -0.0f, 3762.6f, 362.5f, 0.00f, 0x20 } +#define EAX30_PRESET_FACTORY_LONGPASSAGE \ + { 26, 1.8f, 0.640f, -1200, -200, -600, 4.06f, 0.65f, 1.31f, 0, 0.020f, 0.00f,0.00f,0.00f, -900, 0.037f, 0.00f,0.00f,0.00f, 0.135f, 0.230f, 0.250f, 0.000f, -0.0f, 3762.6f, 362.5f, 0.00f, 0x20 } +#define EAX30_PRESET_FACTORY_LARGEROOM \ + { 26, 1.9f, 0.750f, -1200, -300, -400, 4.24f, 0.51f, 1.31f, -1500, 0.039f, 0.00f,0.00f,0.00f, -600, 0.023f, 0.00f,0.00f,0.00f, 0.231f, 0.070f, 0.250f, 0.000f, -0.0f, 3762.6f, 362.5f, 0.00f, 0x20 } +#define EAX30_PRESET_FACTORY_HALL \ + { 26, 1.9f, 0.750f, -1000, -300, -400, 7.43f, 0.51f, 1.31f, -2400, 0.073f, 0.00f,0.00f,0.00f, -500, 0.027f, 0.00f,0.00f,0.00f, 0.250f, 0.070f, 0.250f, 0.000f, -0.0f, 3762.6f, 362.5f, 0.00f, 0x20 } +#define EAX30_PRESET_FACTORY_CUPBOARD \ + { 26, 1.7f, 0.630f, -1200, -200, -600, 0.49f, 0.65f, 1.31f, 200, 0.010f, 0.00f,0.00f,0.00f, 200, 0.032f, 0.00f,0.00f,0.00f, 0.107f, 0.070f, 0.250f, 0.000f, -0.0f, 3762.6f, 362.5f, 0.00f, 0x20 } +#define EAX30_PRESET_FACTORY_COURTYARD \ + { 26, 1.7f, 0.570f, -1000, -1000, -400, 2.32f, 0.29f, 0.56f, -2400, 0.090f, 0.00f,0.00f,0.00f, -2000, 0.039f, 0.00f,0.00f,0.00f, 0.250f, 0.290f, 0.250f, 0.000f, -0.0f, 3762.6f, 362.5f, 0.00f, 0x20 } +#define EAX30_PRESET_FACTORY_SMALLROOM \ + { 26, 1.8f, 0.820f, -1200, -200, -600, 1.72f, 0.65f, 1.31f, -300, 0.010f, 0.00f,0.00f,0.00f, -200, 0.024f, 0.00f,0.00f,0.00f, 0.119f, 0.070f, 0.250f, 0.000f, -0.0f, 3762.6f, 362.5f, 0.00f, 0x20 } + +// ICE PALACE PRESETS + +// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS +#define EAX30_PRESET_ICEPALACE_ALCOVE \ + { 26, 2.7f, 0.840f, -1000, -500, -1100, 2.76f, 1.46f, 0.28f, 100, 0.010f, 0.00f,0.00f,0.00f, -1200, 0.030f, 0.00f,0.00f,0.00f, 0.161f, 0.090f, 0.250f, 0.000f, -0.0f, 12428.5f, 99.6f, 0.00f, 0x20 } +#define EAX30_PRESET_ICEPALACE_SHORTPASSAGE \ + { 26, 2.7f, 0.750f, -1000, -500, -1100, 1.79f, 1.46f, 0.28f, -600, 0.010f, 0.00f,0.00f,0.00f, -700, 0.019f, 0.00f,0.00f,0.00f, 0.177f, 0.090f, 0.250f, 0.000f, -0.0f, 12428.5f, 99.6f, 0.00f, 0x20 } +#define EAX30_PRESET_ICEPALACE_MEDIUMROOM \ + { 26, 2.7f, 0.870f, -1000, -500, -700, 2.22f, 1.53f, 0.32f, -800, 0.039f, 0.00f,0.00f,0.00f, -1200, 0.027f, 0.00f,0.00f,0.00f, 0.186f, 0.120f, 0.250f, 0.000f, -0.0f, 12428.5f, 99.6f, 0.00f, 0x20 } +#define EAX30_PRESET_ICEPALACE_LONGPASSAGE \ + { 26, 2.7f, 0.770f, -1000, -500, -800, 3.01f, 1.46f, 0.28f, -200, 0.012f, 0.00f,0.00f,0.00f, -800, 0.025f, 0.00f,0.00f,0.00f, 0.186f, 0.040f, 0.250f, 0.000f, -0.0f, 12428.5f, 99.6f, 0.00f, 0x20 } +#define EAX30_PRESET_ICEPALACE_LARGEROOM \ + { 26, 2.9f, 0.810f, -1000, -500, -700, 3.14f, 1.53f, 0.32f, -1200, 0.039f, 0.00f,0.00f,0.00f, -1300, 0.027f, 0.00f,0.00f,0.00f, 0.214f, 0.110f, 0.250f, 0.000f, -0.0f, 12428.5f, 99.6f, 0.00f, 0x20 } +#define EAX30_PRESET_ICEPALACE_HALL \ + { 26, 2.9f, 0.760f, -1000, -700, -500, 5.49f, 1.53f, 0.38f, -1900, 0.054f, 0.00f,0.00f,0.00f, -1400, 0.052f, 0.00f,0.00f,0.00f, 0.226f, 0.110f, 0.250f, 0.000f, -0.0f, 12428.5f, 99.6f, 0.00f, 0x20 } +#define EAX30_PRESET_ICEPALACE_CUPBOARD \ + { 26, 2.7f, 0.830f, -1000, -600, -1300, 0.76f, 1.53f, 0.26f, 100, 0.012f, 0.00f,0.00f,0.00f, 100, 0.016f, 0.00f,0.00f,0.00f, 0.143f, 0.080f, 0.250f, 0.000f, -0.0f, 12428.5f, 99.6f, 0.00f, 0x20 } +#define EAX30_PRESET_ICEPALACE_COURTYARD \ + { 26, 2.9f, 0.590f, -1000, -1100, -1000, 2.04f, 1.20f, 0.38f, -2000, 0.073f, 0.00f,0.00f,0.00f, -2200, 0.043f, 0.00f,0.00f,0.00f, 0.235f, 0.480f, 0.250f, 0.000f, -0.0f, 12428.5f, 99.6f, 0.00f, 0x20 } +#define EAX30_PRESET_ICEPALACE_SMALLROOM \ + { 26, 2.7f, 0.840f, -1000, -500, -1100, 1.51f, 1.53f, 0.27f, -100, 0.010f, 0.00f,0.00f,0.00f, -900, 0.011f, 0.00f,0.00f,0.00f, 0.164f, 0.140f, 0.250f, 0.000f, -0.0f, 12428.5f, 99.6f, 0.00f, 0x20 } + +// SPACE STATION PRESETS + +// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS +#define EAX30_PRESET_SPACESTATION_ALCOVE \ + { 26, 1.5f, 0.780f, -1100, -300, -100, 1.16f, 0.81f, 0.55f, 300, 0.007f, 0.00f,0.00f,0.00f, -500, 0.018f, 0.00f,0.00f,0.00f, 0.192f, 0.210f, 0.250f, 0.000f, -5.0f, 3316.1f, 458.2f, 0.00f, 0x20 } +#define EAX30_PRESET_SPACESTATION_MEDIUMROOM \ + { 26, 1.5f, 0.750f, -1000, -400, -100, 3.01f, 0.50f, 0.55f, -1000, 0.034f, 0.00f,0.00f,0.00f, -700, 0.035f, 0.00f,0.00f,0.00f, 0.209f, 0.310f, 0.250f, 0.000f, -5.0f, 3316.1f, 458.2f, 0.00f, 0x20 } +#define EAX30_PRESET_SPACESTATION_SHORTPASSAGE \ + { 26, 1.5f, 0.870f, -1000, -400, -100, 3.57f, 0.50f, 0.55f, 0, 0.012f, 0.00f,0.00f,0.00f, -600, 0.016f, 0.00f,0.00f,0.00f, 0.172f, 0.200f, 0.250f, 0.000f, -5.0f, 3316.1f, 458.2f, 0.00f, 0x20 } +#define EAX30_PRESET_SPACESTATION_LONGPASSAGE \ + { 26, 1.9f, 0.820f, -1000, -400, -100, 4.62f, 0.62f, 0.55f, 0, 0.012f, 0.00f,0.00f,0.00f, -800, 0.031f, 0.00f,0.00f,0.00f, 0.250f, 0.230f, 0.250f, 0.000f, -5.0f, 3316.1f, 458.2f, 0.00f, 0x20 } +#define EAX30_PRESET_SPACESTATION_LARGEROOM \ + { 26, 1.8f, 0.810f, -1000, -400, -100, 3.89f, 0.38f, 0.61f, -1200, 0.056f, 0.00f,0.00f,0.00f, -800, 0.035f, 0.00f,0.00f,0.00f, 0.233f, 0.280f, 0.250f, 0.000f, -5.0f, 3316.1f, 458.2f, 0.00f, 0x20 } +#define EAX30_PRESET_SPACESTATION_HALL \ + { 26, 1.9f, 0.870f, -1000, -400, -100, 7.11f, 0.38f, 0.61f, -1500, 0.100f, 0.00f,0.00f,0.00f, -1000, 0.047f, 0.00f,0.00f,0.00f, 0.250f, 0.250f, 0.250f, 0.000f, -5.0f, 3316.1f, 458.2f, 0.00f, 0x20 } +#define EAX30_PRESET_SPACESTATION_CUPBOARD \ + { 26, 1.4f, 0.560f, -1000, -300, -100, 0.79f, 0.81f, 0.55f, 200, 0.007f, 0.00f,0.00f,0.00f, 400, 0.018f, 0.00f,0.00f,0.00f, 0.181f, 0.310f, 0.250f, 0.000f, -5.0f, 3316.1f, 458.2f, 0.00f, 0x20 } +#define EAX30_PRESET_SPACESTATION_SMALLROOM \ + { 26, 1.5f, 0.700f, -1000, -300, -100, 1.72f, 0.82f, 0.55f, -400, 0.007f, 0.00f,0.00f,0.00f, -500, 0.013f, 0.00f,0.00f,0.00f, 0.188f, 0.260f, 0.250f, 0.000f, -5.0f, 3316.1f, 458.2f, 0.00f, 0x20 } + +// WOODEN GALLEON PRESETS + +// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS +#define EAX30_PRESET_WOODEN_ALCOVE \ + { 26, 7.5f, 1.000f, -1100, -1800, -1000, 1.22f, 0.62f, 0.91f, -100, 0.012f, 0.00f,0.00f,0.00f, -600, 0.024f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 4705.0f, 99.6f, 0.00f, 0x3f } +#define EAX30_PRESET_WOODEN_SHORTPASSAGE \ + { 26, 7.5f, 1.000f, -1100, -1800, -1000, 1.45f, 0.50f, 0.87f, -300, 0.012f, 0.00f,0.00f,0.00f, -700, 0.024f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 4705.0f, 99.6f, 0.00f, 0x3f } +#define EAX30_PRESET_WOODEN_MEDIUMROOM \ + { 26, 7.5f, 1.000f, -1200, -2000, -1100, 1.07f, 0.42f, 0.82f, -300, 0.039f, 0.00f,0.00f,0.00f, -400, 0.029f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 4705.0f, 99.6f, 0.00f, 0x3f } +#define EAX30_PRESET_WOODEN_LONGPASSAGE \ + { 26, 7.5f, 1.000f, -1100, -2000, -1000, 1.79f, 0.40f, 0.79f, -200, 0.020f, 0.00f,0.00f,0.00f, -1000, 0.036f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 4705.0f, 99.6f, 0.00f, 0x3f } +#define EAX30_PRESET_WOODEN_LARGEROOM \ + { 26, 7.5f, 1.000f, -1200, -2100, -1100, 1.45f, 0.33f, 0.82f, -300, 0.056f, 0.00f,0.00f,0.00f, -500, 0.049f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 4705.0f, 99.6f, 0.00f, 0x3f } +#define EAX30_PRESET_WOODEN_HALL \ + { 26, 7.5f, 1.000f, -1200, -2200, -1100, 1.95f, 0.30f, 0.82f, -300, 0.068f, 0.00f,0.00f,0.00f, -500, 0.063f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 4705.0f, 99.6f, 0.00f, 0x3f } +#define EAX30_PRESET_WOODEN_CUPBOARD \ + { 26, 7.5f, 1.000f, -1000, -1700, -1000, 0.56f, 0.46f, 0.91f, -100, 0.012f, 0.00f,0.00f,0.00f, -100, 0.028f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 4705.0f, 99.6f, 0.00f, 0x3f } +#define EAX30_PRESET_WOODEN_SMALLROOM \ + { 26, 7.5f, 1.000f, -1200, -1900, -1000, 0.79f, 0.32f, 0.87f, -200, 0.032f, 0.00f,0.00f,0.00f, -300, 0.029f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 4705.0f, 99.6f, 0.00f, 0x3f } +#define EAX30_PRESET_WOODEN_COURTYARD \ + { 26, 7.5f, 0.650f, -1700, -2200, -1000, 1.79f, 0.35f, 0.79f, -700, 0.063f, 0.00f,0.00f,0.00f, -2300, 0.032f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 4705.0f, 99.6f, 0.00f, 0x3f } + + +// OTHER SCENARIOS + +// SPORTS PRESETS + +// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS +#define EAX30_PRESET_SPORT_EMPTYSTADIUM \ + { 26, 7.2f, 1.000f, -1300, -700, -200, 6.26f, 0.51f, 1.10f, -2400, 0.183f, 0.00f,0.00f,0.00f, -1100, 0.038f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x20 } +#define EAX30_PRESET_SPORT_SQUASHCOURT \ + { 26, 7.5f, 0.750f, -1100, -1000, -200, 2.22f, 0.91f, 1.16f, -700, 0.007f, 0.00f,0.00f,0.00f, -300, 0.011f, 0.00f,0.00f,0.00f, 0.126f, 0.190f, 0.250f, 0.000f, -0.0f, 7176.9f, 211.2f, 0.00f, 0x20 } +#define EAX30_PRESET_SPORT_SMALLSWIMMINGPOOL \ + { 26, 36.2f, 0.700f, -1400, -200, -100, 2.76f, 1.25f, 1.14f, -400, 0.020f, 0.00f,0.00f,0.00f, -300, 0.030f, 0.00f,0.00f,0.00f, 0.179f, 0.150f, 0.895f, 0.190f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x0 } +#define EAX30_PRESET_SPORT_LARGESWIMMINGPOOL\ + { 26, 36.2f, 0.820f, -1200, -200, 0, 5.49f, 1.31f, 1.14f, -700, 0.039f, 0.00f,0.00f,0.00f, -800, 0.049f, 0.00f,0.00f,0.00f, 0.222f, 0.550f, 1.159f, 0.210f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x0 } +#define EAX30_PRESET_SPORT_GYMNASIUM \ + { 26, 7.5f, 0.810f, -1200, -700, -100, 3.14f, 1.06f, 1.35f, -800, 0.029f, 0.00f,0.00f,0.00f, -700, 0.045f, 0.00f,0.00f,0.00f, 0.146f, 0.140f, 0.250f, 0.000f, -0.0f, 7176.9f, 211.2f, 0.00f, 0x20 } +#define EAX30_PRESET_SPORT_FULLSTADIUM \ + { 26, 7.2f, 1.000f, -1300, -2300, -200, 5.25f, 0.17f, 0.80f, -2000, 0.188f, 0.00f,0.00f,0.00f, -1300, 0.038f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x20 } +#define EAX30_PRESET_SPORT_STADIUMTANNOY \ + { 26, 3.0f, 0.780f, -900, -500, -600, 2.53f, 0.88f, 0.68f, -1100, 0.230f, 0.00f,0.00f,0.00f, -600, 0.063f, 0.00f,0.00f,0.00f, 0.250f, 0.200f, 0.250f, 0.000f, -0.0f, 5000.0f, 250.0f, 0.00f, 0x20 } + +// PREFAB PRESETS + +// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS +#define EAX30_PRESET_PREFAB_WORKSHOP \ + { 26, 1.9f, 1.000f, -1000, -1700, -800, 0.76f, 1.00f, 1.00f, 0, 0.012f, 0.00f,0.00f,0.00f, -200, 0.012f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x0 } +#define EAX30_PRESET_PREFAB_SCHOOLROOM \ + { 26, 1.86f, 0.690f, -1100, -400, -600, 0.98f, 0.45f, 0.18f, 300, 0.017f, 0.00f,0.00f,0.00f, 0, 0.015f, 0.00f,0.00f,0.00f, 0.095f, 0.140f, 0.250f, 0.000f, -0.0f, 7176.9f, 211.2f, 0.00f, 0x20 } +#define EAX30_PRESET_PREFAB_PRACTISEROOM \ + { 26, 1.86f, 0.870f, -1000, -800, -600, 1.12f, 0.56f, 0.18f, 200, 0.010f, 0.00f,0.00f,0.00f, -200, 0.011f, 0.00f,0.00f,0.00f, 0.095f, 0.140f, 0.250f, 0.000f, -0.0f, 7176.9f, 211.2f, 0.00f, 0x20 } +#define EAX30_PRESET_PREFAB_OUTHOUSE \ + { 26, 80.3f, 0.820f, -1100, -1900, -1600, 1.38f, 0.38f, 0.35f, -100, 0.024f, 0.00f,0.00f,-0.00f, -800, 0.044f, 0.00f,0.00f,0.00f, 0.121f, 0.170f, 0.250f, 0.000f, -0.0f, 2854.4f, 107.5f, 0.00f, 0x0 } +#define EAX30_PRESET_PREFAB_CARAVAN \ + { 26, 8.3f, 1.000f, -1000, -2100, -1800, 0.43f, 1.50f, 1.00f, 0, 0.012f, 0.00f,0.00f,0.00f, 400, 0.012f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x1f } + // for US developers, a caravan is the same as a trailer =o) + + +// DOME AND PIPE PRESETS + +// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS +#define EAX30_PRESET_DOME_TOMB \ + { 26, 51.8f, 0.790f, -1000, -900, -1300, 4.18f, 0.21f, 0.10f, -825, 0.030f, 0.00f,0.00f,0.00f, -125, 0.022f, 0.00f,0.00f,0.00f, 0.177f, 0.190f, 0.250f, 0.000f, -5.0f, 2854.4f, 20.0f, 0.00f, 0x0 } +#define EAX30_PRESET_PIPE_SMALL \ + { 26, 50.3f, 1.000f, -1000, -900, -1300, 5.04f, 0.10f, 0.10f, -600, 0.032f, 0.00f,0.00f,0.00f, 400, 0.015f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 2854.4f, 20.0f, 0.00f, 0x3f } +#define EAX30_PRESET_DOME_SAINTPAULS \ + { 26, 50.3f, 0.870f, -1000, -900, -1300, 10.48f, 0.19f, 0.10f, -1500, 0.090f, 0.00f,0.00f,0.00f, -500, 0.042f, 0.00f,0.00f,0.00f, 0.250f, 0.120f, 0.250f, 0.000f, -5.0f, 2854.4f, 20.0f, 0.00f, 0x3f } +#define EAX30_PRESET_PIPE_LONGTHIN \ + { 26, 1.6f, 0.910f, -1200, -700, -1100, 9.21f, 0.18f, 0.10f, -300, 0.010f, 0.00f,0.00f,0.00f, -1000, 0.022f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 2854.4f, 20.0f, 0.00f, 0x0 } +#define EAX30_PRESET_PIPE_LARGE \ + { 26, 50.3f, 1.000f, -1000, -900, -1300, 8.45f, 0.10f, 0.10f, -800, 0.046f, 0.00f,0.00f,0.00f, 0, 0.032f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 2854.4f, 20.0f, 0.00f, 0x3f } +#define EAX30_PRESET_PIPE_RESONANT \ + { 26, 1.3f, 0.910f, -1200, -700, -1100, 6.81f, 0.18f, 0.10f, -300, 0.010f, 0.00f,0.00f,0.00f, -700, 0.022f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 2854.4f, 20.0f, 0.00f, 0x0 } + +// OUTDOORS PRESETS + +// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS +#define EAX30_PRESET_OUTDOORS_BACKYARD \ + { 26, 80.3f, 0.450f, -1100, -1200, -600, 1.12f, 0.34f, 0.46f, -1100, 0.049f, 0.00f,0.00f,-0.00f, -1300, 0.023f, 0.00f,0.00f,0.00f, 0.218f, 0.340f, 0.250f, 0.000f, -5.0f, 4399.1f, 242.9f, 0.00f, 0x0 } +#define EAX30_PRESET_OUTDOORS_ROLLINGPLAINS \ + { 26, 80.3f, 0.000f, -1100, -3900, -400, 2.13f, 0.21f, 0.46f, -2000, 0.300f, 0.00f,0.00f,-0.00f, -1500, 0.019f, 0.00f,0.00f,0.00f, 0.250f, 1.000f, 0.250f, 0.000f, -5.0f, 4399.1f, 242.9f, 0.00f, 0x0 } +#define EAX30_PRESET_OUTDOORS_DEEPCANYON \ + { 26, 80.3f, 0.740f, -1100, -1500, -400, 3.89f, 0.21f, 0.46f, -2000, 0.193f, 0.00f,0.00f,-0.00f, -1100, 0.019f, 0.00f,0.00f,0.00f, 0.250f, 1.000f, 0.250f, 0.000f, -5.0f, 4399.1f, 242.9f, 0.00f, 0x0 } +#define EAX30_PRESET_OUTDOORS_CREEK \ + { 26, 80.3f, 0.350f, -1100, -1500, -600, 2.13f, 0.21f, 0.46f, -1700, 0.115f, 0.00f,0.00f,-0.00f, -1100, 0.031f, 0.00f,0.00f,0.00f, 0.218f, 0.340f, 0.250f, 0.000f, -5.0f, 4399.1f, 242.9f, 0.00f, 0x0 } +#define EAX30_PRESET_OUTDOORS_VALLEY \ + { 26, 80.3f, 0.280f, -1100, -3100, -1600, 2.88f, 0.26f, 0.35f, -3200, 0.163f, 0.00f,0.00f,-0.00f, -1000, 0.100f, 0.00f,0.00f,0.00f, 0.250f, 0.340f, 0.250f, 0.000f, -0.0f, 2854.4f, 107.5f, 0.00f, 0x0 } + + +// MOOD PRESETS + +// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS +#define EAX30_PRESET_MOOD_HEAVEN \ + { 26, 19.6f, 0.940f, -1000, -200, -700, 5.04f, 1.12f, 0.56f, -1230, 0.020f, 0.00f,0.00f,0.00f, -200, 0.029f, 0.00f,0.00f,0.00f, 0.250f, 0.080f, 2.742f, 0.050f, -2.0f, 5000.0f, 250.0f, 0.00f, 0x3f } +#define EAX30_PRESET_MOOD_HELL \ + { 26, 100.0f, 0.570f, -1000, -900, -700, 3.57f, 0.49f, 2.00f, -10000, 0.020f, 0.00f,0.00f,0.00f, 100, 0.030f, 0.00f,0.00f,0.00f, 0.110f, 0.040f, 2.109f, 0.520f, -5.0f, 5000.0f, 139.5f, 0.00f, 0x40 } +#define EAX30_PRESET_MOOD_MEMORY \ + { 26, 8.0f, 0.850f, -1000, -400, -900, 4.06f, 0.82f, 0.56f, -2800, 0.000f, 0.00f,0.00f,0.00f, -500, 0.000f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.474f, 0.450f, -2.0f, 5000.0f, 250.0f, 0.00f, 0x0 } + +// DRIVING SIMULATION PRESETS + +// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS +#define EAX30_PRESET_DRIVING_COMMENTATOR \ + { 26, 3.0f, 0.000f, -900, -500, -600, 2.42f, 0.88f, 0.68f, -1400, 0.093f, 0.00f,0.00f,0.00f, -1200, 0.017f, 0.00f,0.00f,0.00f, 0.250f, 1.000f, 0.250f, 0.000f, -0.0f, 5000.0f, 250.0f, 0.00f, 0x20 } +#define EAX30_PRESET_DRIVING_PITGARAGE \ + { 26, 1.9f, 0.590f, -1400, -300, -500, 1.72f, 0.93f, 0.87f, -500, 0.000f, 0.00f,0.00f,0.00f, 0, 0.016f, 0.00f,0.00f,0.00f, 0.250f, 0.110f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x0 } +#define EAX30_PRESET_DRIVING_INCAR_RACER \ + { 26, 1.1f, 0.800f, -700, 0, -200, 0.17f, 2.00f, 0.41f, 500, 0.007f, 0.00f,0.00f,0.00f, -500, 0.015f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -0.0f, 10268.2f, 251.0f, 0.00f, 0x20 } +#define EAX30_PRESET_DRIVING_INCAR_SPORTS \ + { 26, 1.1f, 0.800f, -900, -400, 0, 0.17f, 0.75f, 0.41f, 0, 0.010f, 0.00f,0.00f,0.00f, -600, 0.000f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -0.0f, 10268.2f, 251.0f, 0.00f, 0x20 } +#define EAX30_PRESET_DRIVING_INCAR_LUXURY \ + { 26, 1.6f, 1.000f, -800, -2000, -600, 0.13f, 0.41f, 0.46f, -200, 0.010f, 0.00f,0.00f,0.00f, 300, 0.010f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -0.0f, 10268.2f, 251.0f, 0.00f, 0x20 } +#define EAX30_PRESET_DRIVING_FULLGRANDSTAND \ + { 26, 8.3f, 1.000f, -1100, -1100, -400, 3.01f, 1.37f, 1.28f, -900, 0.090f, 0.00f,0.00f,0.00f, -1700, 0.049f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 10420.2f, 250.0f, 0.00f, 0x1f } +#define EAX30_PRESET_DRIVING_EMPTYGRANDSTAND \ + { 26, 8.3f, 1.000f, -700, 0, -200, 4.62f, 1.75f, 1.40f, -1363, 0.090f, 0.00f,0.00f,0.00f, -1900, 0.049f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 10420.2f, 250.0f, 0.00f, 0x1f } +#define EAX30_PRESET_DRIVING_TUNNEL \ + { 26, 3.1f, 0.810f, -900, -800, -100, 3.42f, 0.94f, 1.31f, -300, 0.051f, 0.00f,0.00f,0.00f, -500, 0.047f, 0.00f,0.00f,0.00f, 0.214f, 0.050f, 0.250f, 0.000f, -0.0f, 5000.0f, 155.3f, 0.00f, 0x20 } + +// CITY PRESETS + +// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS +#define EAX30_PRESET_CITY_STREETS \ + { 26, 3.0f, 0.780f, -1100, -300, -100, 1.79f, 1.12f, 0.91f, -1700, 0.046f, 0.00f,0.00f,0.00f, -2800, 0.028f, 0.00f,0.00f,0.00f, 0.250f, 0.200f, 0.250f, 0.000f, -0.0f, 5000.0f, 250.0f, 0.00f, 0x20 } +#define EAX30_PRESET_CITY_SUBWAY \ + { 26, 3.0f, 0.740f, -1100, -300, -100, 3.01f, 1.23f, 0.91f, -700, 0.046f, 0.00f,0.00f,0.00f, -1000, 0.028f, 0.00f,0.00f,0.00f, 0.125f, 0.210f, 0.250f, 0.000f, -0.0f, 5000.0f, 250.0f, 0.00f, 0x20 } +#define EAX30_PRESET_CITY_MUSEUM \ + { 26, 80.3f, 0.820f, -1100, -1500, -1500, 3.28f, 1.40f, 0.57f, -1600, 0.039f, 0.00f,0.00f,-0.00f, -600, 0.034f, 0.00f,0.00f,0.00f, 0.130f, 0.170f, 0.250f, 0.000f, -0.0f, 2854.4f, 107.5f, 0.00f, 0x0 } +#define EAX30_PRESET_CITY_LIBRARY \ + { 26, 80.3f, 0.820f, -1100, -1100, -2100, 2.76f, 0.89f, 0.41f, -1100, 0.029f, 0.00f,0.00f,-0.00f, -500, 0.020f, 0.00f,0.00f,0.00f, 0.130f, 0.170f, 0.250f, 0.000f, -0.0f, 2854.4f, 107.5f, 0.00f, 0x0 } +#define EAX30_PRESET_CITY_UNDERPASS \ + { 26, 3.0f, 0.820f, -1500, -700, -100, 3.57f, 1.12f, 0.91f, -1500, 0.059f, 0.00f,0.00f,0.00f, -1100, 0.037f, 0.00f,0.00f,0.00f, 0.250f, 0.140f, 0.250f, 0.000f, -0.0f, 5000.0f, 250.0f, 0.00f, 0x20 } +#define EAX30_PRESET_CITY_ABANDONED \ + { 26, 3.0f, 0.690f, -1100, -200, -100, 3.28f, 1.17f, 0.91f, -1400, 0.044f, 0.00f,0.00f,0.00f, -2400, 0.024f, 0.00f,0.00f,0.00f, 0.250f, 0.200f, 0.250f, 0.000f, -0.0f, 5000.0f, 250.0f, 0.00f, 0x20 } + +// MISC ROOMS + +// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS +#define EAX30_PRESET_DUSTYROOM \ + { 26, 1.8f, 0.560f, -1100, -200, -300, 1.79f, 0.38f, 0.21f, -600, 0.002f, 0.00f,0.00f,0.00f, 200, 0.006f, 0.00f,0.00f,0.00f, 0.202f, 0.050f, 0.250f, 0.000f, -3.0f, 13046.0f, 163.3f, 0.00f, 0x20 } +#define EAX30_PRESET_CHAPEL \ + { 26, 19.6f, 0.840f, -1000, -500, 0, 4.62f, 0.64f, 1.23f, -700, 0.032f, 0.00f,0.00f,0.00f, -800, 0.049f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.110f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f } +#define EAX30_PRESET_SMALLWATERROOM \ + { 26, 36.2f, 0.700f, -1200, -698, 0, 1.51f, 1.25f, 1.14f, -100, 0.020f, 0.00f,0.00f,0.00f, 200, 0.030f, 0.00f,0.00f,0.00f, 0.179f, 0.150f, 0.895f, 0.190f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x0 } + +/********************************************************************************************************/ + +////////////////////////////////////////////////////// +// Effect Scenarios enumerated // +////////////////////////////////////////////////////// + +typedef enum +{ + EAX30_SCENARIO_CASTLE = 0, + EAX30_SCENARIO_FACTORY, + EAX30_SCENARIO_ICEPALACE, + EAX30_SCENARIO_SPACESTATION, + EAX30_SCENARIO_WOODGALLEON, + EAX30_SCENARIO_SPORTS, + EAX30_SCENARIO_PREFAB, + EAX30_SCENARIO_DOMESNPIPES, + EAX30_SCENARIO_OUTDOORS, + EAX30_SCENARIO_MOOD, + EAX30_SCENARIO_DRIVING, + EAX30_SCENARIO_CITY, + EAX30_SCENARIO_MISC, + EAX30_SCENARIO_ORIGINAL +} +EAX30_SCENARIO; + +////////////////////////////////////////////////////// +// Number of Effect Scenarios // +////////////////////////////////////////////////////// + +#define EAX30_NUM_SCENARIOS 14 + +////////////////////////////////////////////////////// +// Number of Effect Scenarios with standardised // +// locations // +////////////////////////////////////////////////////// + +#define EAX30_NUM_STANDARD_SCENARIOS 5 + +////////////////////////////////////////////////////// +// Array of scenario names // +////////////////////////////////////////////////////// + +extern const char* EAX30_SCENARIO_NAMES[]; + +////////////////////////////////////////////////////// +// Standardised Locations enumerated // +////////////////////////////////////////////////////// + +typedef enum +{ + EAX30_LOCATION_HALL = 0, + EAX30_LOCATION_LARGEROOM, + EAX30_LOCATION_MEDIUMROOM, + EAX30_LOCATION_SMALLROOM, + EAX30_LOCATION_CUPBOARD, + EAX30_LOCATION_ALCOVE, + EAX30_LOCATION_LONGPASSAGE, + EAX30_LOCATION_SHORTPASSAGE, + EAX30_LOCATION_COURTYARD +} +EAX30_LOCATION; + +////////////////////////////////////////////////////// +// Number of Standardised Locations // +////////////////////////////////////////////////////// + +#define EAX30_NUM_LOCATIONS 9 + +////////////////////////////////////////////////////// +// Array of standardised location names // +////////////////////////////////////////////////////// + +extern const char* EAX30_LOCATION_NAMES[]; + +////////////////////////////////////////////////////// +// Number of effects in each scenario // +////////////////////////////////////////////////////// + +#define EAX30_NUM_ORIGINAL_PRESETS 26 +#define EAX30_NUM_CASTLE_PRESETS EAX30_NUM_LOCATIONS +#define EAX30_NUM_FACTORY_PRESETS EAX30_NUM_LOCATIONS +#define EAX30_NUM_ICEPALACE_PRESETS EAX30_NUM_LOCATIONS +#define EAX30_NUM_SPACESTATION_PRESETS EAX30_NUM_LOCATIONS +#define EAX30_NUM_WOODGALLEON_PRESETS EAX30_NUM_LOCATIONS +#define EAX30_NUM_SPORTS_PRESETS 7 +#define EAX30_NUM_PREFAB_PRESETS 5 +#define EAX30_NUM_DOMESNPIPES_PRESETS 6 +#define EAX30_NUM_OUTDOORS_PRESETS 5 +#define EAX30_NUM_MOOD_PRESETS 3 +#define EAX30_NUM_DRIVING_PRESETS 8 +#define EAX30_NUM_CITY_PRESETS 6 +#define EAX30_NUM_MISC_PRESETS 3 + +////////////////////////////////////////////////////// +// Standardised Location effects can be accessed // +// from a matrix // +////////////////////////////////////////////////////// + +extern EAXLISTENERPROPERTIES EAX30_STANDARD_PRESETS[EAX30_NUM_STANDARD_SCENARIOS][EAX30_NUM_LOCATIONS]; + +/********************************************************************************************************/ + +////////////////////////////////////////////////////// +// Original Preset effects enumerated // +////////////////////////////////////////////////////// + +typedef enum +{ + ORIGINAL_GENERIC = 0, + ORIGINAL_PADDEDCELL, + ORIGINAL_ROOM, + ORIGINAL_BATHROOM, + ORIGINAL_LIVINGROOM, + ORIGINAL_STONEROOM, + ORIGINAL_AUDITORIUM, + ORIGINAL_CONCERTHALL, + ORIGINAL_CAVE, + ORIGINAL_ARENA, + ORIGINAL_HANGAR, + ORIGINAL_CARPETTEDHALLWAY, + ORIGINAL_HALLWAY, + ORIGINAL_STONECORRIDOR, + ORIGINAL_ALLEY, + ORIGINAL_FOREST, + ORIGINAL_CITY, + ORIGINAL_MOUNTAINS, + ORIGINAL_QUARRY, + ORIGINAL_PLAIN, + ORIGINAL_PARKINGLOT, + ORIGINAL_SEWERPIPE, + ORIGINAL_UNDERWATER, + ORIGINAL_DRUGGED, + ORIGINAL_DIZZY, + ORIGINAL_PSYCHOTIC +} +EAX30_ORIGINAL_PRESET_ENUMS; + +////////////////////////////////////////////////////// +// Array of original environment names // +////////////////////////////////////////////////////// + +extern const char* EAX30_ORIGINAL_PRESET_NAMES[]; + +////////////////////////////////////////////////////// +// Original effects matrix // +////////////////////////////////////////////////////// + +extern EAXLISTENERPROPERTIES EAX30_ORIGINAL_PRESETS[]; + +/********************************************************************************************************/ + +////////////////////////////////////////////////////// +// Sports scenario effects enumerated // +////////////////////////////////////////////////////// + +typedef enum +{ + SPORT_EMPTYSTADIUM=0, + SPORT_FULLSTADIUM, + SPORT_STADIUMTANNOY, + SPORT_SQUASHCOURT, + SPORT_SMALLSWIMMINGPOOL, + SPORT_LARGESWIMMINGPOOL, + SPORT_GYMNASIUM +} +EAX30_SPORTS_PRESET_ENUMS; + +////////////////////////////////////////////////////// +// Array of sport environment names // +////////////////////////////////////////////////////// + +extern const char* EAX30_SPORTS_PRESET_NAMES[]; + +////////////////////////////////////////////////////// +// Sports effects matrix // +////////////////////////////////////////////////////// + +extern EAXLISTENERPROPERTIES EAX30_SPORTS_PRESETS[]; + +/********************************************************************************************************/ + +////////////////////////////////////////////////////// +// Prefab scenario effects enumerated // +////////////////////////////////////////////////////// + +typedef enum +{ + PREFAB_WORKSHOP, + PREFAB_SCHOOLROOM, + PREFAB_PRACTISEROOM, + PREFAB_OUTHOUSE, + PREFAB_CARAVAN +} +EAX30_PREFAB_PRESET_ENUMS; + +////////////////////////////////////////////////////// +// Array of prefab environment names // +////////////////////////////////////////////////////// + +extern const char* EAX30_PREFAB_PRESET_NAMES[]; + +////////////////////////////////////////////////////// +// Prefab effects matrix // +////////////////////////////////////////////////////// + +extern EAXLISTENERPROPERTIES EAX30_PREFAB_PRESETS[]; + +/********************************************************************************************************/ + +////////////////////////////////////////////////////// +// Domes & Pipes effects enumerated // +////////////////////////////////////////////////////// + +typedef enum +{ + DOME_TOMB, + DOME_SAINTPAULS, + PIPE_SMALL, + PIPE_LONGTHIN, + PIPE_LARGE, + PIPE_RESONANT +} +EAX30_DOMESNPIPES_PRESET_ENUMS; + +////////////////////////////////////////////////////// +// Array of Domes & Pipes environment names // +////////////////////////////////////////////////////// + +extern const char* EAX30_DOMESNPIPES_PRESET_NAMES[]; + +////////////////////////////////////////////////////// +// Domes & Pipes effects matrix // +////////////////////////////////////////////////////// + +extern EAXLISTENERPROPERTIES EAX30_DOMESNPIPES_PRESETS[]; + +/********************************************************************************************************/ + +////////////////////////////////////////////////////// +// Outdoors scenario effects enumerated // +////////////////////////////////////////////////////// + +typedef enum +{ + OUTDOORS_BACKYARD, + OUTDOORS_ROLLINGPLAINS, + OUTDOORS_DEEPCANYON, + OUTDOORS_CREEK, + OUTDOORS_VALLEY +} +EAX30_OUTDOORS_PRESET_ENUMS; + +////////////////////////////////////////////////////// +// Array of Outdoors environment names // +////////////////////////////////////////////////////// + +extern const char* EAX30_OUTDOORS_PRESET_NAMES[]; + +////////////////////////////////////////////////////// +// Outdoors effects matrix // +////////////////////////////////////////////////////// + +extern EAXLISTENERPROPERTIES EAX30_OUTDOORS_PRESETS[]; + +/********************************************************************************************************/ + +////////////////////////////////////////////////////// +// Mood scenario effects enumerated // +////////////////////////////////////////////////////// + +typedef enum +{ + MOOD_HEAVEN, + MOOD_HELL, + MOOD_MEMORY +} +EAX30_MOOD_PRESET_ENUMS; + +////////////////////////////////////////////////////// +// Array of Mood environment names // +////////////////////////////////////////////////////// + +extern const char* EAX30_MOOD_PRESET_NAMES[]; + +////////////////////////////////////////////////////// +// Mood effects matrix // +////////////////////////////////////////////////////// + +extern EAXLISTENERPROPERTIES EAX30_MOOD_PRESETS[]; + +/********************************************************************************************************/ + +////////////////////////////////////////////////////// +// Driving scenario effects enumerated // +////////////////////////////////////////////////////// + +typedef enum +{ + DRIVING_COMMENTATOR, + DRIVING_PITGARAGE, + DRIVING_INCAR_RACER, + DRIVING_INCAR_SPORTS, + DRIVING_INCAR_LUXURY, + DRIVING_FULLGRANDSTAND, + DRIVING_EMPTYGRANDSTAND, + DRIVING_TUNNEL +} +EAX30_DRIVING_PRESET_ENUMS; + +////////////////////////////////////////////////////// +// Array of driving environment names // +////////////////////////////////////////////////////// + +extern const char* EAX30_DRIVING_PRESET_NAMES[]; + +////////////////////////////////////////////////////// +// Driving effects matrix // +////////////////////////////////////////////////////// + +extern EAXLISTENERPROPERTIES EAX30_DRIVING_PRESETS[]; + +/********************************************************************************************************/ + +////////////////////////////////////////////////////// +// City scenario effects enumerated // +////////////////////////////////////////////////////// + +typedef enum +{ + CITY_STREETS, + CITY_SUBWAY, + CITY_MUSEUM, + CITY_LIBRARY, + CITY_UNDERPASS, + CITY_ABANDONED +} +EAX30_CITY_PRESET_ENUMS; + +////////////////////////////////////////////////////// +// Array of City environment names // +////////////////////////////////////////////////////// + +extern const char* EAX30_CITY_PRESET_NAMES[]; + +////////////////////////////////////////////////////// +// City effects matrix // +////////////////////////////////////////////////////// + +extern EAXLISTENERPROPERTIES EAX30_CITY_PRESETS[]; + +/********************************************************************************************************/ + +////////////////////////////////////////////////////// +// Misc scenario effects enumerated // +////////////////////////////////////////////////////// + +typedef enum +{ + DUSTYROOM, + CHAPEL, + SMALLWATERROOM +} +EAX30_MISC_PRESET_ENUMS; + + +////////////////////////////////////////////////////// +// Array of Misc environment names // +////////////////////////////////////////////////////// + +extern const char* EAX30_MISC_PRESET_NAMES[]; + +////////////////////////////////////////////////////// +// Misc effects matrix // +////////////////////////////////////////////////////// + +extern EAXLISTENERPROPERTIES EAX30_MISC_PRESETS[]; + + +/***********************************************************************************************\ +* +* Material transmission presets +* +* Three values in this order :- +* +* 1. Occlusion (or Obstruction) +* 2. Occlusion LF Ratio (or Obstruction LF Ratio) +* 3. Occlusion Room Ratio +* +************************************************************************************************/ + + +// Single window material preset +#define EAX_MATERIAL_SINGLEWINDOW (-2800) +#define EAX_MATERIAL_SINGLEWINDOWLF 0.71f +#define EAX_MATERIAL_SINGLEWINDOWROOMRATIO 0.43f + +// Double window material preset +#define EAX_MATERIAL_DOUBLEWINDOW (-5000) +#define EAX_MATERIAL_DOUBLEWINDOWLF 0.40f +#define EAX_MATERIAL_DOUBLEWINDOWROOMRATIO 0.24f + +// Thin door material preset +#define EAX_MATERIAL_THINDOOR (-1800) +#define EAX_MATERIAL_THINDOORLF 0.66f +#define EAX_MATERIAL_THINDOORROOMRATIO 0.66f + +// Thick door material preset +#define EAX_MATERIAL_THICKDOOR (-4400) +#define EAX_MATERIAL_THICKDOORLF 0.64f +#define EAX_MATERIAL_THICKDOORROOMRATIO 0.27f + +// Wood wall material preset +#define EAX_MATERIAL_WOODWALL (-4000) +#define EAX_MATERIAL_WOODWALLLF 0.50f +#define EAX_MATERIAL_WOODWALLROOMRATIO 0.30f + +// Brick wall material preset +#define EAX_MATERIAL_BRICKWALL (-5000) +#define EAX_MATERIAL_BRICKWALLLF 0.60f +#define EAX_MATERIAL_BRICKWALLROOMRATIO 0.24f + +// Stone wall material preset +#define EAX_MATERIAL_STONEWALL (-6000) +#define EAX_MATERIAL_STONEWALLLF 0.68f +#define EAX_MATERIAL_STONEWALLROOMRATIO 0.20f + +// Curtain material preset +#define EAX_MATERIAL_CURTAIN (-1200) +#define EAX_MATERIAL_CURTAINLF 0.15f +#define EAX_MATERIAL_CURTAINROOMRATIO 1.00f + + +#endif // EAXUTIL_INCLUDED diff --git a/src/audio/eax/eax.h b/src/audio/eax/eax.h new file mode 100644 index 0000000..b221093 --- /dev/null +++ b/src/audio/eax/eax.h @@ -0,0 +1,536 @@ +/*******************************************************************\ +* * +* EAX.H - Environmental Audio Extensions version 3.0 * +* for OpenAL and DirectSound3D * +* * +********************************************************************/ + +#ifndef EAX_H_INCLUDED +#define EAX_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +#ifndef AUDIO_OAL + #include <dsound.h> + + /* + * EAX Wrapper Interface (using Direct X 7) {4FF53B81-1CE0-11d3-AAB8-00A0C95949D5} + */ + DEFINE_GUID(CLSID_EAXDirectSound, + 0x4ff53b81, + 0x1ce0, + 0x11d3, + 0xaa, 0xb8, 0x0, 0xa0, 0xc9, 0x59, 0x49, 0xd5); + + /* + * EAX Wrapper Interface (using Direct X 8) {CA503B60-B176-11d4-A094-D0C0BF3A560C} + */ + DEFINE_GUID(CLSID_EAXDirectSound8, + 0xca503b60, + 0xb176, + 0x11d4, + 0xa0, 0x94, 0xd0, 0xc0, 0xbf, 0x3a, 0x56, 0xc); + + + +#ifdef DIRECTSOUND_VERSION +#if DIRECTSOUND_VERSION >= 0x0800 + __declspec(dllimport) HRESULT WINAPI EAXDirectSoundCreate8(GUID*, LPDIRECTSOUND8*, IUnknown FAR *); + typedef HRESULT (FAR PASCAL *LPEAXDIRECTSOUNDCREATE8)(GUID*, LPDIRECTSOUND8*, IUnknown FAR*); +#endif +#endif + + __declspec(dllimport) HRESULT WINAPI EAXDirectSoundCreate(GUID*, LPDIRECTSOUND*, IUnknown FAR *); + typedef HRESULT (FAR PASCAL *LPEAXDIRECTSOUNDCREATE)(GUID*, LPDIRECTSOUND*, IUnknown FAR*); + + __declspec(dllimport) void CDECL GetCurrentVersion(LPDWORD major, LPDWORD minor); + typedef void (CDECL *LPGETCURRENTVERSION)(LPDWORD major, LPDWORD minor); + + +#else // AUDIO_OAL + #include <AL/al.h> + #include <string.h> + + #ifndef GUID_DEFINED + #define GUID_DEFINED + typedef struct _GUID + { + unsigned long Data1; + unsigned short Data2; + unsigned short Data3; + unsigned char Data4[8]; + } GUID; + #endif // !GUID_DEFINED + + #ifndef DEFINE_GUID + #ifndef INITGUID + #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + extern const GUID /*FAR*/ name + #else + #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + extern const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } + #endif // INITGUID + #endif // DEFINE_GUID + + + /* + * EAX OpenAL Extension + */ + typedef ALenum (*EAXSet)(const GUID*, ALuint, ALuint, ALvoid*, ALuint); + typedef ALenum (*EAXGet)(const GUID*, ALuint, ALuint, ALvoid*, ALuint); +#endif + +#pragma pack(push, 4) + +/* + * EAX 3.0 listener property set {A8FA6880-B476-11d3-BDB9-00C0F02DDF87} + */ +DEFINE_GUID(DSPROPSETID_EAX30_ListenerProperties, + 0xa8fa6882, + 0xb476, + 0x11d3, + 0xbd, 0xb9, 0x00, 0xc0, 0xf0, 0x2d, 0xdf, 0x87); + +// For compatibility with future EAX versions: +#define DSPROPSETID_EAX_ListenerProperties DSPROPSETID_EAX30_ListenerProperties + +typedef enum +{ + DSPROPERTY_EAXLISTENER_NONE, + DSPROPERTY_EAXLISTENER_ALLPARAMETERS, + DSPROPERTY_EAXLISTENER_ENVIRONMENT, + DSPROPERTY_EAXLISTENER_ENVIRONMENTSIZE, + DSPROPERTY_EAXLISTENER_ENVIRONMENTDIFFUSION, + DSPROPERTY_EAXLISTENER_ROOM, + DSPROPERTY_EAXLISTENER_ROOMHF, + DSPROPERTY_EAXLISTENER_ROOMLF, + DSPROPERTY_EAXLISTENER_DECAYTIME, + DSPROPERTY_EAXLISTENER_DECAYHFRATIO, + DSPROPERTY_EAXLISTENER_DECAYLFRATIO, + DSPROPERTY_EAXLISTENER_REFLECTIONS, + DSPROPERTY_EAXLISTENER_REFLECTIONSDELAY, + DSPROPERTY_EAXLISTENER_REFLECTIONSPAN, + DSPROPERTY_EAXLISTENER_REVERB, + DSPROPERTY_EAXLISTENER_REVERBDELAY, + DSPROPERTY_EAXLISTENER_REVERBPAN, + DSPROPERTY_EAXLISTENER_ECHOTIME, + DSPROPERTY_EAXLISTENER_ECHODEPTH, + DSPROPERTY_EAXLISTENER_MODULATIONTIME, + DSPROPERTY_EAXLISTENER_MODULATIONDEPTH, + DSPROPERTY_EAXLISTENER_AIRABSORPTIONHF, + DSPROPERTY_EAXLISTENER_HFREFERENCE, + DSPROPERTY_EAXLISTENER_LFREFERENCE, + DSPROPERTY_EAXLISTENER_ROOMROLLOFFFACTOR, + DSPROPERTY_EAXLISTENER_FLAGS +} DSPROPERTY_EAX_LISTENERPROPERTY; + +// OR these flags with property id +#define DSPROPERTY_EAXLISTENER_IMMEDIATE 0x00000000 // changes take effect immediately +#define DSPROPERTY_EAXLISTENER_DEFERRED 0x80000000 // changes take effect later +#define DSPROPERTY_EAXLISTENER_COMMITDEFERREDSETTINGS (DSPROPERTY_EAXLISTENER_NONE | \ + DSPROPERTY_EAXLISTENER_IMMEDIATE) + +typedef struct _EAXVECTOR { + float x; + float y; + float z; +} EAXVECTOR; + +// Use this structure for DSPROPERTY_EAXLISTENER_ALLPARAMETERS +// - all levels are hundredths of decibels +// - all times and delays are in seconds +// +// NOTE: This structure may change in future EAX versions. +// It is recommended to initialize fields by name: +// myListener.lRoom = -1000; +// myListener.lRoomHF = -100; +// ... +// myListener.dwFlags = myFlags /* see EAXLISTENERFLAGS below */ ; +// instead of: +// myListener = { -1000, -100, ... , 0x00000009 }; +// If you want to save and load presets in binary form, you +// should define your own structure to insure future compatibility. +// +typedef struct _EAXLISTENERPROPERTIES +{ + unsigned long ulEnvironment; // sets all listener properties + float flEnvironmentSize; // environment size in meters + float flEnvironmentDiffusion; // environment diffusion + long lRoom; // room effect level (at mid frequencies) + long lRoomHF; // relative room effect level at high frequencies + long lRoomLF; // relative room effect level at low frequencies + float flDecayTime; // reverberation decay time at mid frequencies + float flDecayHFRatio; // high-frequency to mid-frequency decay time ratio + float flDecayLFRatio; // low-frequency to mid-frequency decay time ratio + long lReflections; // early reflections level relative to room effect + float flReflectionsDelay; // initial reflection delay time + EAXVECTOR vReflectionsPan; // early reflections panning vector + long lReverb; // late reverberation level relative to room effect + float flReverbDelay; // late reverberation delay time relative to initial reflection + EAXVECTOR vReverbPan; // late reverberation panning vector + float flEchoTime; // echo time + float flEchoDepth; // echo depth + float flModulationTime; // modulation time + float flModulationDepth; // modulation depth + float flAirAbsorptionHF; // change in level per meter at high frequencies + float flHFReference; // reference high frequency + float flLFReference; // reference low frequency + float flRoomRolloffFactor; // like DS3D flRolloffFactor but for room effect + unsigned long ulFlags; // modifies the behavior of properties +} EAXLISTENERPROPERTIES, *LPEAXLISTENERPROPERTIES; + +// used by DSPROPERTY_EAXLISTENER_ENVIRONMENT +enum +{ + EAX_ENVIRONMENT_GENERIC, + EAX_ENVIRONMENT_PADDEDCELL, + EAX_ENVIRONMENT_ROOM, + EAX_ENVIRONMENT_BATHROOM, + EAX_ENVIRONMENT_LIVINGROOM, + EAX_ENVIRONMENT_STONEROOM, + EAX_ENVIRONMENT_AUDITORIUM, + EAX_ENVIRONMENT_CONCERTHALL, + EAX_ENVIRONMENT_CAVE, + EAX_ENVIRONMENT_ARENA, + EAX_ENVIRONMENT_HANGAR, + EAX_ENVIRONMENT_CARPETEDHALLWAY, + EAX_ENVIRONMENT_HALLWAY, + EAX_ENVIRONMENT_STONECORRIDOR, + EAX_ENVIRONMENT_ALLEY, + EAX_ENVIRONMENT_FOREST, + EAX_ENVIRONMENT_CITY, + EAX_ENVIRONMENT_MOUNTAINS, + EAX_ENVIRONMENT_QUARRY, + EAX_ENVIRONMENT_PLAIN, + EAX_ENVIRONMENT_PARKINGLOT, + EAX_ENVIRONMENT_SEWERPIPE, + EAX_ENVIRONMENT_UNDERWATER, + EAX_ENVIRONMENT_DRUGGED, + EAX_ENVIRONMENT_DIZZY, + EAX_ENVIRONMENT_PSYCHOTIC, + + EAX_ENVIRONMENT_UNDEFINED, + + EAX_ENVIRONMENT_COUNT +}; + +// Used by DSPROPERTY_EAXLISTENER_FLAGS +// +// Note: The number and order of flags may change in future EAX versions. +// It is recommended to use the flag defines as follows: +// myFlags = EAXLISTENERFLAGS_DECAYTIMESCALE | EAXLISTENERFLAGS_REVERBSCALE; +// instead of: +// myFlags = 0x00000009; +// +// These flags determine what properties are affected by environment size. +#define EAXLISTENERFLAGS_DECAYTIMESCALE 0x00000001 // reverberation decay time +#define EAXLISTENERFLAGS_REFLECTIONSSCALE 0x00000002 // reflection level +#define EAXLISTENERFLAGS_REFLECTIONSDELAYSCALE 0x00000004 // initial reflection delay time +#define EAXLISTENERFLAGS_REVERBSCALE 0x00000008 // reflections level +#define EAXLISTENERFLAGS_REVERBDELAYSCALE 0x00000010 // late reverberation delay time +#define EAXLISTENERFLAGS_ECHOTIMESCALE 0x00000040 // echo time +#define EAXLISTENERFLAGS_MODULATIONTIMESCALE 0x00000080 // modulation time + +// This flag limits high-frequency decay time according to air absorption. +#define EAXLISTENERFLAGS_DECAYHFLIMIT 0x00000020 + +#define EAXLISTENERFLAGS_RESERVED 0xFFFFFF00 // reserved future use + +// Property ranges and defaults: + +#define EAXLISTENER_MINENVIRONMENT 0 +#define EAXLISTENER_MAXENVIRONMENT (EAX_ENVIRONMENT_COUNT-1) +#define EAXLISTENER_DEFAULTENVIRONMENT EAX_ENVIRONMENT_GENERIC + +#define EAXLISTENER_MINENVIRONMENTSIZE 1.0f +#define EAXLISTENER_MAXENVIRONMENTSIZE 100.0f +#define EAXLISTENER_DEFAULTENVIRONMENTSIZE 7.5f + +#define EAXLISTENER_MINENVIRONMENTDIFFUSION 0.0f +#define EAXLISTENER_MAXENVIRONMENTDIFFUSION 1.0f +#define EAXLISTENER_DEFAULTENVIRONMENTDIFFUSION 1.0f + +#define EAXLISTENER_MINROOM (-10000) +#define EAXLISTENER_MAXROOM 0 +#define EAXLISTENER_DEFAULTROOM (-1000) + +#define EAXLISTENER_MINROOMHF (-10000) +#define EAXLISTENER_MAXROOMHF 0 +#define EAXLISTENER_DEFAULTROOMHF (-100) + +#define EAXLISTENER_MINROOMLF (-10000) +#define EAXLISTENER_MAXROOMLF 0 +#define EAXLISTENER_DEFAULTROOMLF 0 + +#define EAXLISTENER_MINDECAYTIME 0.1f +#define EAXLISTENER_MAXDECAYTIME 20.0f +#define EAXLISTENER_DEFAULTDECAYTIME 1.49f + +#define EAXLISTENER_MINDECAYHFRATIO 0.1f +#define EAXLISTENER_MAXDECAYHFRATIO 2.0f +#define EAXLISTENER_DEFAULTDECAYHFRATIO 0.83f + +#define EAXLISTENER_MINDECAYLFRATIO 0.1f +#define EAXLISTENER_MAXDECAYLFRATIO 2.0f +#define EAXLISTENER_DEFAULTDECAYLFRATIO 1.00f + +#define EAXLISTENER_MINREFLECTIONS (-10000) +#define EAXLISTENER_MAXREFLECTIONS 1000 +#define EAXLISTENER_DEFAULTREFLECTIONS (-2602) + +#define EAXLISTENER_MINREFLECTIONSDELAY 0.0f +#define EAXLISTENER_MAXREFLECTIONSDELAY 0.3f +#define EAXLISTENER_DEFAULTREFLECTIONSDELAY 0.007f + +#define EAXLISTENER_MINREVERB (-10000) +#define EAXLISTENER_MAXREVERB 2000 +#define EAXLISTENER_DEFAULTREVERB 200 + +#define EAXLISTENER_MINREVERBDELAY 0.0f +#define EAXLISTENER_MAXREVERBDELAY 0.1f +#define EAXLISTENER_DEFAULTREVERBDELAY 0.011f + +#define EAXLISTENER_MINECHOTIME 0.075f +#define EAXLISTENER_MAXECHOTIME 0.25f +#define EAXLISTENER_DEFAULTECHOTIME 0.25f + +#define EAXLISTENER_MINECHODEPTH 0.0f +#define EAXLISTENER_MAXECHODEPTH 1.0f +#define EAXLISTENER_DEFAULTECHODEPTH 0.0f + +#define EAXLISTENER_MINMODULATIONTIME 0.04f +#define EAXLISTENER_MAXMODULATIONTIME 4.0f +#define EAXLISTENER_DEFAULTMODULATIONTIME 0.25f + +#define EAXLISTENER_MINMODULATIONDEPTH 0.0f +#define EAXLISTENER_MAXMODULATIONDEPTH 1.0f +#define EAXLISTENER_DEFAULTMODULATIONDEPTH 0.0f + +#define EAXLISTENER_MINAIRABSORPTIONHF (-100.0f) +#define EAXLISTENER_MAXAIRABSORPTIONHF 0.0f +#define EAXLISTENER_DEFAULTAIRABSORPTIONHF (-5.0f) + +#define EAXLISTENER_MINHFREFERENCE 1000.0f +#define EAXLISTENER_MAXHFREFERENCE 20000.0f +#define EAXLISTENER_DEFAULTHFREFERENCE 5000.0f + +#define EAXLISTENER_MINLFREFERENCE 20.0f +#define EAXLISTENER_MAXLFREFERENCE 1000.0f +#define EAXLISTENER_DEFAULTLFREFERENCE 250.0f + +#define EAXLISTENER_MINROOMROLLOFFFACTOR 0.0f +#define EAXLISTENER_MAXROOMROLLOFFFACTOR 10.0f +#define EAXLISTENER_DEFAULTROOMROLLOFFFACTOR 0.0f + +#define EAXLISTENER_DEFAULTFLAGS (EAXLISTENERFLAGS_DECAYTIMESCALE | \ + EAXLISTENERFLAGS_REFLECTIONSSCALE | \ + EAXLISTENERFLAGS_REFLECTIONSDELAYSCALE | \ + EAXLISTENERFLAGS_REVERBSCALE | \ + EAXLISTENERFLAGS_REVERBDELAYSCALE | \ + EAXLISTENERFLAGS_DECAYHFLIMIT) + + + +/* +* EAX 3.0 buffer property set {A8FA6881-B476-11d3-BDB9-00C0F02DDF87} +*/ +DEFINE_GUID(DSPROPSETID_EAX30_BufferProperties, + 0xa8fa6881, + 0xb476, + 0x11d3, + 0xbd, 0xb9, 0x0, 0xc0, 0xf0, 0x2d, 0xdf, 0x87); + +// For compatibility with future EAX versions: +#define DSPROPSETID_EAX_BufferProperties DSPROPSETID_EAX30_BufferProperties +#define DSPROPSETID_EAX_SourceProperties DSPROPSETID_EAX30_BufferProperties + +typedef enum +{ + DSPROPERTY_EAXBUFFER_NONE, + DSPROPERTY_EAXBUFFER_ALLPARAMETERS, + DSPROPERTY_EAXBUFFER_OBSTRUCTIONPARAMETERS, + DSPROPERTY_EAXBUFFER_OCCLUSIONPARAMETERS, + DSPROPERTY_EAXBUFFER_EXCLUSIONPARAMETERS, + DSPROPERTY_EAXBUFFER_DIRECT, + DSPROPERTY_EAXBUFFER_DIRECTHF, + DSPROPERTY_EAXBUFFER_ROOM, + DSPROPERTY_EAXBUFFER_ROOMHF, + DSPROPERTY_EAXBUFFER_OBSTRUCTION, + DSPROPERTY_EAXBUFFER_OBSTRUCTIONLFRATIO, + DSPROPERTY_EAXBUFFER_OCCLUSION, + DSPROPERTY_EAXBUFFER_OCCLUSIONLFRATIO, + DSPROPERTY_EAXBUFFER_OCCLUSIONROOMRATIO, + DSPROPERTY_EAXBUFFER_OCCLUSIONDIRECTRATIO, + DSPROPERTY_EAXBUFFER_EXCLUSION, + DSPROPERTY_EAXBUFFER_EXCLUSIONLFRATIO, + DSPROPERTY_EAXBUFFER_OUTSIDEVOLUMEHF, + DSPROPERTY_EAXBUFFER_DOPPLERFACTOR, + DSPROPERTY_EAXBUFFER_ROLLOFFFACTOR, + DSPROPERTY_EAXBUFFER_ROOMROLLOFFFACTOR, + DSPROPERTY_EAXBUFFER_AIRABSORPTIONFACTOR, + DSPROPERTY_EAXBUFFER_FLAGS +} DSPROPERTY_EAX_BUFFERPROPERTY; + +// OR these flags with property id +#define DSPROPERTY_EAXBUFFER_IMMEDIATE 0x00000000 // changes take effect immediately +#define DSPROPERTY_EAXBUFFER_DEFERRED 0x80000000 // changes take effect later +#define DSPROPERTY_EAXBUFFER_COMMITDEFERREDSETTINGS (DSPROPERTY_EAXBUFFER_NONE | \ + DSPROPERTY_EAXBUFFER_IMMEDIATE) + +// Use this structure for DSPROPERTY_EAXBUFFER_ALLPARAMETERS +// - all levels are hundredths of decibels +// - all delays are in seconds +// +// NOTE: This structure may change in future EAX versions. +// It is recommended to initialize fields by name: +// myBuffer.lDirect = 0; +// myBuffer.lDirectHF = -200; +// ... +// myBuffer.dwFlags = myFlags /* see EAXBUFFERFLAGS below */ ; +// instead of: +// myBuffer = { 0, -200, ... , 0x00000003 }; +// +typedef struct _EAXBUFFERPROPERTIES +{ + long lDirect; // direct path level (at low and mid frequencies) + long lDirectHF; // relative direct path level at high frequencies + long lRoom; // room effect level (at low and mid frequencies) + long lRoomHF; // relative room effect level at high frequencies + long lObstruction; // main obstruction control (attenuation at high frequencies) + float flObstructionLFRatio; // obstruction low-frequency level re. main control + long lOcclusion; // main occlusion control (attenuation at high frequencies) + float flOcclusionLFRatio; // occlusion low-frequency level re. main control + float flOcclusionRoomRatio; // relative occlusion control for room effect + float flOcclusionDirectRatio; // relative occlusion control for direct path + long lExclusion; // main exlusion control (attenuation at high frequencies) + float flExclusionLFRatio; // exclusion low-frequency level re. main control + long lOutsideVolumeHF; // outside sound cone level at high frequencies + float flDopplerFactor; // like DS3D flDopplerFactor but per source + float flRolloffFactor; // like DS3D flRolloffFactor but per source + float flRoomRolloffFactor; // like DS3D flRolloffFactor but for room effect + float flAirAbsorptionFactor; // multiplies DSPROPERTY_EAXLISTENER_AIRABSORPTIONHF + unsigned long ulFlags; // modifies the behavior of properties +} EAXBUFFERPROPERTIES, *LPEAXBUFFERPROPERTIES; + +// Use this structure for DSPROPERTY_EAXBUFFER_OBSTRUCTION, +typedef struct _EAXOBSTRUCTIONPROPERTIES +{ + long lObstruction; + float flObstructionLFRatio; +} EAXOBSTRUCTIONPROPERTIES, *LPEAXOBSTRUCTIONPROPERTIES; + +// Use this structure for DSPROPERTY_EAXBUFFER_OCCLUSION +typedef struct _EAXOCCLUSIONPROPERTIES +{ + long lOcclusion; + float flOcclusionLFRatio; + float flOcclusionRoomRatio; + float flOcclusionDirectRatio; +} EAXOCCLUSIONPROPERTIES, *LPEAXOCCLUSIONPROPERTIES; + +// Use this structure for DSPROPERTY_EAXBUFFER_EXCLUSION +typedef struct _EAXEXCLUSIONPROPERTIES +{ + long lExclusion; + float flExclusionLFRatio; +} EAXEXCLUSIONPROPERTIES, *LPEAXEXCLUSIONPROPERTIES; + +// Used by DSPROPERTY_EAXBUFFER_FLAGS +// TRUE: value is computed automatically - property is an offset +// FALSE: value is used directly +// +// Note: The number and order of flags may change in future EAX versions. +// To insure future compatibility, use flag defines as follows: +// myFlags = EAXBUFFERFLAGS_DIRECTHFAUTO | EAXBUFFERFLAGS_ROOMAUTO; +// instead of: +// myFlags = 0x00000003; +// +#define EAXBUFFERFLAGS_DIRECTHFAUTO 0x00000001 // affects DSPROPERTY_EAXBUFFER_DIRECTHF +#define EAXBUFFERFLAGS_ROOMAUTO 0x00000002 // affects DSPROPERTY_EAXBUFFER_ROOM +#define EAXBUFFERFLAGS_ROOMHFAUTO 0x00000004 // affects DSPROPERTY_EAXBUFFER_ROOMHF + +#define EAXBUFFERFLAGS_RESERVED 0xFFFFFFF8 // reserved future use + +// Property ranges and defaults: + +#define EAXBUFFER_MINDIRECT (-10000) +#define EAXBUFFER_MAXDIRECT 1000 +#define EAXBUFFER_DEFAULTDIRECT 0 + +#define EAXBUFFER_MINDIRECTHF (-10000) +#define EAXBUFFER_MAXDIRECTHF 0 +#define EAXBUFFER_DEFAULTDIRECTHF 0 + +#define EAXBUFFER_MINROOM (-10000) +#define EAXBUFFER_MAXROOM 1000 +#define EAXBUFFER_DEFAULTROOM 0 + +#define EAXBUFFER_MINROOMHF (-10000) +#define EAXBUFFER_MAXROOMHF 0 +#define EAXBUFFER_DEFAULTROOMHF 0 + +#define EAXBUFFER_MINOBSTRUCTION (-10000) +#define EAXBUFFER_MAXOBSTRUCTION 0 +#define EAXBUFFER_DEFAULTOBSTRUCTION 0 + +#define EAXBUFFER_MINOBSTRUCTIONLFRATIO 0.0f +#define EAXBUFFER_MAXOBSTRUCTIONLFRATIO 1.0f +#define EAXBUFFER_DEFAULTOBSTRUCTIONLFRATIO 0.0f + +#define EAXBUFFER_MINOCCLUSION (-10000) +#define EAXBUFFER_MAXOCCLUSION 0 +#define EAXBUFFER_DEFAULTOCCLUSION 0 + +#define EAXBUFFER_MINOCCLUSIONLFRATIO 0.0f +#define EAXBUFFER_MAXOCCLUSIONLFRATIO 1.0f +#define EAXBUFFER_DEFAULTOCCLUSIONLFRATIO 0.25f + +#define EAXBUFFER_MINOCCLUSIONROOMRATIO 0.0f +#define EAXBUFFER_MAXOCCLUSIONROOMRATIO 10.0f +#define EAXBUFFER_DEFAULTOCCLUSIONROOMRATIO 1.5f + +#define EAXBUFFER_MINOCCLUSIONDIRECTRATIO 0.0f +#define EAXBUFFER_MAXOCCLUSIONDIRECTRATIO 10.0f +#define EAXBUFFER_DEFAULTOCCLUSIONDIRECTRATIO 1.0f + +#define EAXBUFFER_MINEXCLUSION (-10000) +#define EAXBUFFER_MAXEXCLUSION 0 +#define EAXBUFFER_DEFAULTEXCLUSION 0 + +#define EAXBUFFER_MINEXCLUSIONLFRATIO 0.0f +#define EAXBUFFER_MAXEXCLUSIONLFRATIO 1.0f +#define EAXBUFFER_DEFAULTEXCLUSIONLFRATIO 1.0f + +#define EAXBUFFER_MINOUTSIDEVOLUMEHF (-10000) +#define EAXBUFFER_MAXOUTSIDEVOLUMEHF 0 +#define EAXBUFFER_DEFAULTOUTSIDEVOLUMEHF 0 + +#define EAXBUFFER_MINDOPPLERFACTOR 0.0f +#define EAXBUFFER_MAXDOPPLERFACTOR 10.f +#define EAXBUFFER_DEFAULTDOPPLERFACTOR 0.0f + +#define EAXBUFFER_MINROLLOFFFACTOR 0.0f +#define EAXBUFFER_MAXROLLOFFFACTOR 10.f +#define EAXBUFFER_DEFAULTROLLOFFFACTOR 0.0f + +#define EAXBUFFER_MINROOMROLLOFFFACTOR 0.0f +#define EAXBUFFER_MAXROOMROLLOFFFACTOR 10.f +#define EAXBUFFER_DEFAULTROOMROLLOFFFACTOR 0.0f + +#define EAXBUFFER_MINAIRABSORPTIONFACTOR 0.0f +#define EAXBUFFER_MAXAIRABSORPTIONFACTOR 10.0f +#define EAXBUFFER_DEFAULTAIRABSORPTIONFACTOR 1.0f + +#define EAXBUFFER_DEFAULTFLAGS (EAXBUFFERFLAGS_DIRECTHFAUTO | \ + EAXBUFFERFLAGS_ROOMAUTO | \ + EAXBUFFERFLAGS_ROOMHFAUTO ) + +#pragma pack(pop) + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif diff --git a/src/audio/oal/aldlist.cpp b/src/audio/oal/aldlist.cpp new file mode 100644 index 0000000..881418c --- /dev/null +++ b/src/audio/oal/aldlist.cpp @@ -0,0 +1,305 @@ +/* + * Copyright (c) 2006, Creative Labs Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided + * that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this list of conditions and + * the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions + * and the following disclaimer in the documentation and/or other materials provided with the distribution. + * * Neither the name of Creative Labs Inc. nor the names of its contributors may be used to endorse or + * promote products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "aldlist.h" + +#ifndef _WIN32 +#define _stricmp strcasecmp +#define _strnicmp strncasecmp +#define _strdup strdup +#endif + +#ifdef AUDIO_OAL +/* + * Init call + */ +ALDeviceList::ALDeviceList() +{ + char *devices; + int index; + const char *defaultDeviceName; + const char *actualDeviceName; + + // DeviceInfo vector stores, for each enumerated device, it's device name, selection status, spec version #, and extension support + nNumOfDevices = 0; + + defaultDeviceIndex = 0; + + if (alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT")) { + devices = (char *)alcGetString(NULL, ALC_DEVICE_SPECIFIER); + defaultDeviceName = (char *)alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER); + + index = 0; + // go through device list (each device terminated with a single NULL, list terminated with double NULL) + while (*devices != '\0') { + if (strcmp(defaultDeviceName, devices) == 0) { + defaultDeviceIndex = index; + } + ALCdevice *device = alcOpenDevice(devices); + if (device) { + ALCcontext *context = alcCreateContext(device, NULL); + if (context) { + alcMakeContextCurrent(context); + // if new actual device name isn't already in the list, then add it... + actualDeviceName = alcGetString(device, ALC_DEVICE_SPECIFIER); + bool bNewName = true; + for (unsigned int i = 0; i < GetNumDevices(); i++) { + if (strcmp(GetDeviceName(i), actualDeviceName) == 0) { + bNewName = false; + } + } + if ((bNewName) && (actualDeviceName != NULL) && (strlen(actualDeviceName) > 0)) { + ALDEVICEINFO ALDeviceInfo; + ALDeviceInfo.bSelected = true; + ALDeviceInfo.strDeviceName = _strdup(actualDeviceName); + alcGetIntegerv(device, ALC_MAJOR_VERSION, sizeof(int), &ALDeviceInfo.iMajorVersion); + alcGetIntegerv(device, ALC_MINOR_VERSION, sizeof(int), &ALDeviceInfo.iMinorVersion); + + // Check for ALC Extensions + if (alcIsExtensionPresent(device, "ALC_EXT_CAPTURE") == AL_TRUE) + ALDeviceInfo.Extensions |= ADEXT_EXT_CAPTURE; + if (alcIsExtensionPresent(device, "ALC_EXT_EFX") == AL_TRUE) + ALDeviceInfo.Extensions |= ADEXT_EXT_EFX; + + // Check for AL Extensions + if (alIsExtensionPresent("AL_EXT_OFFSET") == AL_TRUE) + ALDeviceInfo.Extensions |= ADEXT_EXT_OFFSET; + + if (alIsExtensionPresent("AL_EXT_LINEAR_DISTANCE") == AL_TRUE) + ALDeviceInfo.Extensions |= ADEXT_EXT_LINEAR_DISTANCE; + if (alIsExtensionPresent("AL_EXT_EXPONENT_DISTANCE") == AL_TRUE) + ALDeviceInfo.Extensions |= ADEXT_EXT_EXPONENT_DISTANCE; + + if (alIsExtensionPresent("EAX2.0") == AL_TRUE) + ALDeviceInfo.Extensions |= ADEXT_EAX2; + if (alIsExtensionPresent("EAX3.0") == AL_TRUE) + ALDeviceInfo.Extensions |= ADEXT_EAX3; + if (alIsExtensionPresent("EAX4.0") == AL_TRUE) + ALDeviceInfo.Extensions |= ADEXT_EAX4; + if (alIsExtensionPresent("EAX5.0") == AL_TRUE) + ALDeviceInfo.Extensions |= ADEXT_EAX5; + + if (alIsExtensionPresent("EAX-RAM") == AL_TRUE) + ALDeviceInfo.Extensions |= ADEXT_EAX_RAM; + + // Get Source Count + ALDeviceInfo.uiSourceCount = GetMaxNumSources(); + + aDeviceInfo[nNumOfDevices++] = ALDeviceInfo; + } + alcMakeContextCurrent(NULL); + alcDestroyContext(context); + } + alcCloseDevice(device); + } + devices += strlen(devices) + 1; + index += 1; + } + } + + ResetFilters(); +} + +/* + * Exit call + */ +ALDeviceList::~ALDeviceList() +{ +} + +/* + * Returns the number of devices in the complete device list + */ +unsigned int ALDeviceList::GetNumDevices() +{ + return nNumOfDevices; +} + +/* + * Returns the device name at an index in the complete device list + */ +const char * ALDeviceList::GetDeviceName(unsigned int index) +{ + if (index < GetNumDevices()) + return aDeviceInfo[index].strDeviceName; + else + return NULL; +} + +/* + * Returns the major and minor version numbers for a device at a specified index in the complete list + */ +void ALDeviceList::GetDeviceVersion(unsigned int index, int *major, int *minor) +{ + if (index < GetNumDevices()) { + if (major) + *major = aDeviceInfo[index].iMajorVersion; + if (minor) + *minor = aDeviceInfo[index].iMinorVersion; + } + return; +} + +/* + * Returns the maximum number of Sources that can be generate on the given device + */ +unsigned int ALDeviceList::GetMaxNumSources(unsigned int index) +{ + if (index < GetNumDevices()) + return aDeviceInfo[index].uiSourceCount; + else + return 0; +} + +/* + * Checks if the extension is supported on the given device + */ +bool ALDeviceList::IsExtensionSupported(int index, unsigned short ext) +{ + return !!(aDeviceInfo[index].Extensions & ext); +} + +/* + * returns the index of the default device in the complete device list + */ +int ALDeviceList::GetDefaultDevice() +{ + return defaultDeviceIndex; +} + +/* + * Deselects devices which don't have the specified minimum version + */ +void ALDeviceList::FilterDevicesMinVer(int major, int minor) +{ + int dMajor, dMinor; + for (unsigned int i = 0; i < nNumOfDevices; i++) { + GetDeviceVersion(i, &dMajor, &dMinor); + if ((dMajor < major) || ((dMajor == major) && (dMinor < minor))) { + aDeviceInfo[i].bSelected = false; + } + } +} + +/* + * Deselects devices which don't have the specified maximum version + */ +void ALDeviceList::FilterDevicesMaxVer(int major, int minor) +{ + int dMajor, dMinor; + for (unsigned int i = 0; i < nNumOfDevices; i++) { + GetDeviceVersion(i, &dMajor, &dMinor); + if ((dMajor > major) || ((dMajor == major) && (dMinor > minor))) { + aDeviceInfo[i].bSelected = false; + } + } +} + +/* + * Deselects device which don't support the given extension name + */ +void +ALDeviceList::FilterDevicesExtension(unsigned short ext) +{ + for (unsigned int i = 0; i < nNumOfDevices; i++) { + if (!IsExtensionSupported(i, ext)) + aDeviceInfo[i].bSelected = false; + } +} + +/* + * Resets all filtering, such that all devices are in the list + */ +void ALDeviceList::ResetFilters() +{ + for (unsigned int i = 0; i < GetNumDevices(); i++) { + aDeviceInfo[i].bSelected = true; + } + filterIndex = 0; +} + +/* + * Gets index of first filtered device + */ +int ALDeviceList::GetFirstFilteredDevice() +{ + unsigned int i; + + for (i = 0; i < GetNumDevices(); i++) { + if (aDeviceInfo[i].bSelected == true) { + break; + } + } + filterIndex = i + 1; + return i; +} + +/* + * Gets index of next filtered device + */ +int ALDeviceList::GetNextFilteredDevice() +{ + unsigned int i; + + for (i = filterIndex; i < GetNumDevices(); i++) { + if (aDeviceInfo[i].bSelected == true) { + break; + } + } + filterIndex = i + 1; + return i; +} + +/* + * Internal function to detemine max number of Sources that can be generated + */ +unsigned int ALDeviceList::GetMaxNumSources() +{ + ALuint uiSources[256]; + unsigned int iSourceCount = 0; + + // Clear AL Error Code + alGetError(); + + // Generate up to 256 Sources, checking for any errors + for (iSourceCount = 0; iSourceCount < 256; iSourceCount++) + { + alGenSources(1, &uiSources[iSourceCount]); + if (alGetError() != AL_NO_ERROR) + break; + } + + // Release the Sources + alDeleteSources(iSourceCount, uiSources); + if (alGetError() != AL_NO_ERROR) + { + for (unsigned int i = 0; i < 256; i++) + { + alDeleteSources(1, &uiSources[i]); + } + } + + return iSourceCount; +} +#endif diff --git a/src/audio/oal/aldlist.h b/src/audio/oal/aldlist.h new file mode 100644 index 0000000..417bd31 --- /dev/null +++ b/src/audio/oal/aldlist.h @@ -0,0 +1,69 @@ +#ifndef ALDEVICELIST_H +#define ALDEVICELIST_H + +#include "oal_utils.h" + +#ifdef AUDIO_OAL +#pragma warning(disable: 4786) //disable warning "identifier was truncated to '255' characters in the browser information" + +enum +{ + ADEXT_EXT_CAPTURE = (1 << 0), + ADEXT_EXT_EFX = (1 << 1), + ADEXT_EXT_OFFSET = (1 << 2), + ADEXT_EXT_LINEAR_DISTANCE = (1 << 3), + ADEXT_EXT_EXPONENT_DISTANCE = (1 << 4), + ADEXT_EAX2 = (1 << 5), + ADEXT_EAX3 = (1 << 6), + ADEXT_EAX4 = (1 << 7), + ADEXT_EAX5 = (1 << 8), + ADEXT_EAX_RAM = (1 << 9), +}; + +struct ALDEVICEINFO { + const char *strDeviceName; + int iMajorVersion; + int iMinorVersion; + unsigned int uiSourceCount; + unsigned short Extensions; + bool bSelected; + + ALDEVICEINFO() : iMajorVersion(0), iMinorVersion(0), uiSourceCount(0), bSelected(false) + { + strDeviceName = NULL; + Extensions = 0; + } +}; + +typedef ALDEVICEINFO *LPALDEVICEINFO; + +class ALDeviceList +{ +private: + ALDEVICEINFO aDeviceInfo[64]; + unsigned int nNumOfDevices; + int defaultDeviceIndex; + int filterIndex; + +public: + ALDeviceList (); + ~ALDeviceList (); + unsigned int GetNumDevices(); + const char *GetDeviceName(unsigned int index); + void GetDeviceVersion(unsigned int index, int *major, int *minor); + unsigned int GetMaxNumSources(unsigned int index); + bool IsExtensionSupported(int index, unsigned short ext); + int GetDefaultDevice(); + void FilterDevicesMinVer(int major, int minor); + void FilterDevicesMaxVer(int major, int minor); + void FilterDevicesExtension(unsigned short ext); + void ResetFilters(); + int GetFirstFilteredDevice(); + int GetNextFilteredDevice(); + +private: + unsigned int GetMaxNumSources(); +}; +#endif + +#endif // ALDEVICELIST_H diff --git a/src/audio/oal/channel.cpp b/src/audio/oal/channel.cpp new file mode 100644 index 0000000..d1fd0ae --- /dev/null +++ b/src/audio/oal/channel.cpp @@ -0,0 +1,278 @@ +#include "common.h" + +#ifdef AUDIO_OAL +#include "channel.h" +#include "sampman.h" + +#ifndef _WIN32 +#include <float.h> +#endif + +extern bool IsFXSupported(); + +ALuint alSources[MAXCHANNELS+MAX2DCHANNELS]; +ALuint alFilters[MAXCHANNELS+MAX2DCHANNELS]; +ALuint alBuffers[MAXCHANNELS+MAX2DCHANNELS]; +bool bChannelsCreated = false; + +int32 CChannel::channelsThatNeedService = 0; + +void +CChannel::InitChannels() +{ + alGenSources(MAXCHANNELS+MAX2DCHANNELS, alSources); + alGenBuffers(MAXCHANNELS+MAX2DCHANNELS, alBuffers); + if (IsFXSupported()) + alGenFilters(MAXCHANNELS + MAX2DCHANNELS, alFilters); + bChannelsCreated = true; +} + +void +CChannel::DestroyChannels() +{ + if (bChannelsCreated) + { + alDeleteSources(MAXCHANNELS + MAX2DCHANNELS, alSources); + memset(alSources, 0, sizeof(alSources)); + alDeleteBuffers(MAXCHANNELS + MAX2DCHANNELS, alBuffers); + memset(alBuffers, 0, sizeof(alBuffers)); + if (IsFXSupported()) + { + alDeleteFilters(MAXCHANNELS + MAX2DCHANNELS, alFilters); + memset(alFilters, 0, sizeof(alFilters)); + } + bChannelsCreated = false; + } +} + + +CChannel::CChannel() +{ + Data = nil; + DataSize = 0; + SetDefault(); +} + +void CChannel::SetDefault() +{ + Pitch = 1.0f; + Gain = 1.0f; + Mix = 0.0f; + + Position[0] = 0.0f; Position[1] = 0.0f; Position[2] = 0.0f; + Distances[0] = 0.0f; Distances[1] = FLT_MAX; + + LoopCount = 1; + LastProcessedOffset = UINT32_MAX; + LoopPoints[0] = 0; LoopPoints[1] = -1; + + Frequency = MAX_FREQ; +} + +void CChannel::Reset() +{ + // Here is safe because ctor don't call this + if (LoopCount > 1) + channelsThatNeedService--; + + ClearBuffer(); + SetDefault(); +} + +void CChannel::Init(uint32 _id, bool Is2D) +{ + id = _id; + if ( HasSource() ) + { + alSourcei(alSources[id], AL_SOURCE_RELATIVE, AL_TRUE); + if ( IsFXSupported() ) + alSource3i(alSources[id], AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, 0, AL_FILTER_NULL); + + if ( Is2D ) + { + alSource3f(alSources[id], AL_POSITION, 0.0f, 0.0f, 0.0f); + alSourcef(alSources[id], AL_GAIN, 1.0f); + } + } +} + +void CChannel::Term() +{ + Stop(); + if ( HasSource() ) + { + if ( IsFXSupported() ) + { + alSource3i(alSources[id], AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, 0, AL_FILTER_NULL); + } + } +} + +void CChannel::Start() +{ + if ( !HasSource() ) return; + if ( !Data ) return; + + alBufferData(alBuffers[id], AL_FORMAT_MONO16, Data, DataSize, Frequency); + if ( LoopPoints[0] != 0 && LoopPoints[0] != -1 ) + alBufferiv(alBuffers[id], AL_LOOP_POINTS_SOFT, LoopPoints); + alSourcei(alSources[id], AL_BUFFER, alBuffers[id]); + alSourcePlay(alSources[id]); +} + +void CChannel::Stop() +{ + if ( HasSource() ) + alSourceStop(alSources[id]); + + Reset(); +} + +bool CChannel::HasSource() +{ + return alSources[id] != AL_NONE; +} + +bool CChannel::IsUsed() +{ + if ( HasSource() ) + { + ALint sourceState; + alGetSourcei(alSources[id], AL_SOURCE_STATE, &sourceState); + return sourceState == AL_PLAYING; + } + return false; +} + +void CChannel::SetPitch(float pitch) +{ + if ( !HasSource() ) return; + alSourcef(alSources[id], AL_PITCH, pitch); +} + +void CChannel::SetGain(float gain) +{ + if ( !HasSource() ) return; + alSourcef(alSources[id], AL_GAIN, gain); +} + +void CChannel::SetVolume(int32 vol) +{ + SetGain(ALfloat(vol) / MAX_VOLUME); +} + +void CChannel::SetSampleData(void *_data, size_t _DataSize, int32 freq) +{ + Data = _data; + DataSize = _DataSize; + Frequency = freq; +} + +void CChannel::SetCurrentFreq(uint32 freq) +{ + SetPitch(ALfloat(freq) / Frequency); +} + +void CChannel::SetLoopCount(int32 count) +{ + if ( !HasSource() ) return; + + // 0: loop indefinitely, 1: play one time, 2: play two times etc... + // only > 1 needs manual processing + + if (LoopCount > 1 && count < 2) + channelsThatNeedService--; + else if (LoopCount < 2 && count > 1) + channelsThatNeedService++; + + alSourcei(alSources[id], AL_LOOPING, count == 1 ? AL_FALSE : AL_TRUE); + LoopCount = count; +} + +bool CChannel::Update() +{ + if (!HasSource()) return false; + if (LoopCount < 2) return false; + + ALint state; + alGetSourcei(alSources[id], AL_SOURCE_STATE, &state); + if (state == AL_STOPPED) { + debug("Looping channels(%d in this case) shouldn't report AL_STOPPED, but nvm\n", id); + SetLoopCount(1); + return true; + } + + assert(channelsThatNeedService > 0 && "Ref counting is broken"); + + ALint offset; + alGetSourcei(alSources[id], AL_SAMPLE_OFFSET, &offset); + + // Rewound + if (offset < LastProcessedOffset) { + LoopCount--; + if (LoopCount == 1) { + // Playing last tune... + channelsThatNeedService--; + alSourcei(alSources[id], AL_LOOPING, AL_FALSE); + } + } + LastProcessedOffset = offset; + return true; +} + +void CChannel::SetLoopPoints(ALint start, ALint end) +{ + LoopPoints[0] = start; + LoopPoints[1] = end; +} + +void CChannel::SetPosition(float x, float y, float z) +{ + if ( !HasSource() ) return; + alSource3f(alSources[id], AL_POSITION, x, y, z); +} + +void CChannel::SetDistances(float max, float min) +{ + if ( !HasSource() ) return; + alSourcef (alSources[id], AL_MAX_DISTANCE, max); + alSourcef (alSources[id], AL_REFERENCE_DISTANCE, min); + alSourcef (alSources[id], AL_MAX_GAIN, 1.0f); + alSourcef (alSources[id], AL_ROLLOFF_FACTOR, 1.0f); +} + +void CChannel::SetPan(int32 pan) +{ + SetPosition((pan-63)/64.0f, 0.0f, Sqrt(1.0f-SQR((pan-63)/64.0f))); +} + +void CChannel::ClearBuffer() +{ + if ( !HasSource() ) return; + alSourcei(alSources[id], AL_LOOPING, AL_FALSE); + alSourcei(alSources[id], AL_BUFFER, AL_NONE); + Data = nil; + DataSize = 0; +} + +void CChannel::SetReverbMix(ALuint slot, float mix) +{ + if ( !IsFXSupported() ) return; + if ( !HasSource() ) return; + if ( alFilters[id] == AL_FILTER_NULL ) return; + + Mix = mix; + EAX3_SetReverbMix(alFilters[id], mix); + alSource3i(alSources[id], AL_AUXILIARY_SEND_FILTER, slot, 0, alFilters[id]); +} + +void CChannel::UpdateReverb(ALuint slot) +{ + if ( !IsFXSupported() ) return; + if ( !HasSource() ) return; + if ( alFilters[id] == AL_FILTER_NULL ) return; + EAX3_SetReverbMix(alFilters[id], Mix); + alSource3i(alSources[id], AL_AUXILIARY_SEND_FILTER, slot, 0, alFilters[id]); +} + +#endif diff --git a/src/audio/oal/channel.h b/src/audio/oal/channel.h new file mode 100644 index 0000000..b081be2 --- /dev/null +++ b/src/audio/oal/channel.h @@ -0,0 +1,54 @@ +#pragma once + +#ifdef AUDIO_OAL +#include "oal/oal_utils.h" +#include <AL/al.h> +#include <AL/alext.h> +#include <AL/efx.h> + + +class CChannel +{ + uint32 id; + float Pitch, Gain; + float Mix; + void *Data; + size_t DataSize; + int32 Frequency; + float Position[3]; + float Distances[2]; + int32 LoopCount; + ALint LoopPoints[2]; + ALint LastProcessedOffset; +public: + static int32 channelsThatNeedService; + + static void InitChannels(); + static void DestroyChannels(); + + CChannel(); + void SetDefault(); + void Reset(); + void Init(uint32 _id, bool Is2D = false); + void Term(); + void Start(); + void Stop(); + bool HasSource(); + bool IsUsed(); + void SetPitch(float pitch); + void SetGain(float gain); + void SetVolume(int32 vol); + void SetSampleData(void *_data, size_t _DataSize, int32 freq); + void SetCurrentFreq(uint32 freq); + void SetLoopCount(int32 count); + void SetLoopPoints(ALint start, ALint end); + void SetPosition(float x, float y, float z); + void SetDistances(float max, float min); + void SetPan(int32 pan); + void ClearBuffer(); + void SetReverbMix(ALuint slot, float mix); + void UpdateReverb(ALuint slot); + bool Update(); +}; + +#endif
\ No newline at end of file diff --git a/src/audio/oal/oal_utils.cpp b/src/audio/oal/oal_utils.cpp new file mode 100644 index 0000000..e4cb0b7 --- /dev/null +++ b/src/audio/oal/oal_utils.cpp @@ -0,0 +1,181 @@ +#include "common.h" +#include "oal_utils.h" + +#ifdef AUDIO_OAL + +/* + * When linking to a static openal-soft library, + * the extension function inside the openal library conflict with the variables here. + * Therefore declare these re3 owned symbols in a private namespace. + */ + +namespace re3_openal { + +LPALGENEFFECTS alGenEffects; +LPALDELETEEFFECTS alDeleteEffects; +LPALISEFFECT alIsEffect; +LPALEFFECTI alEffecti; +LPALEFFECTIV alEffectiv; +LPALEFFECTF alEffectf; +LPALEFFECTFV alEffectfv; +LPALGETEFFECTI alGetEffecti; +LPALGETEFFECTIV alGetEffectiv; +LPALGETEFFECTF alGetEffectf; +LPALGETEFFECTFV alGetEffectfv; +LPALGENAUXILIARYEFFECTSLOTS alGenAuxiliaryEffectSlots; +LPALDELETEAUXILIARYEFFECTSLOTS alDeleteAuxiliaryEffectSlots; +LPALISAUXILIARYEFFECTSLOT alIsAuxiliaryEffectSlot; +LPALAUXILIARYEFFECTSLOTI alAuxiliaryEffectSloti; +LPALAUXILIARYEFFECTSLOTIV alAuxiliaryEffectSlotiv; +LPALAUXILIARYEFFECTSLOTF alAuxiliaryEffectSlotf; +LPALAUXILIARYEFFECTSLOTFV alAuxiliaryEffectSlotfv; +LPALGETAUXILIARYEFFECTSLOTI alGetAuxiliaryEffectSloti; +LPALGETAUXILIARYEFFECTSLOTIV alGetAuxiliaryEffectSlotiv; +LPALGETAUXILIARYEFFECTSLOTF alGetAuxiliaryEffectSlotf; +LPALGETAUXILIARYEFFECTSLOTFV alGetAuxiliaryEffectSlotfv; +LPALGENFILTERS alGenFilters; +LPALDELETEFILTERS alDeleteFilters; +LPALISFILTER alIsFilter; +LPALFILTERI alFilteri; +LPALFILTERIV alFilteriv; +LPALFILTERF alFilterf; +LPALFILTERFV alFilterfv; +LPALGETFILTERI alGetFilteri; +LPALGETFILTERIV alGetFilteriv; +LPALGETFILTERF alGetFilterf; +LPALGETFILTERFV alGetFilterfv; + +} + +using namespace re3_openal; + +void EFXInit() +{ + /* Define a macro to help load the function pointers. */ +#define LOAD_PROC(T, x) ((x) = (T)alGetProcAddress(#x)) + LOAD_PROC(LPALGENEFFECTS, alGenEffects); + LOAD_PROC(LPALDELETEEFFECTS, alDeleteEffects); + LOAD_PROC(LPALISEFFECT, alIsEffect); + LOAD_PROC(LPALEFFECTI, alEffecti); + LOAD_PROC(LPALEFFECTIV, alEffectiv); + LOAD_PROC(LPALEFFECTF, alEffectf); + LOAD_PROC(LPALEFFECTFV, alEffectfv); + LOAD_PROC(LPALGETEFFECTI, alGetEffecti); + LOAD_PROC(LPALGETEFFECTIV, alGetEffectiv); + LOAD_PROC(LPALGETEFFECTF, alGetEffectf); + LOAD_PROC(LPALGETEFFECTFV, alGetEffectfv); + + LOAD_PROC(LPALGENFILTERS, alGenFilters); + LOAD_PROC(LPALDELETEFILTERS, alDeleteFilters); + LOAD_PROC(LPALISFILTER, alIsFilter); + LOAD_PROC(LPALFILTERI, alFilteri); + LOAD_PROC(LPALFILTERIV, alFilteriv); + LOAD_PROC(LPALFILTERF, alFilterf); + LOAD_PROC(LPALFILTERFV, alFilterfv); + LOAD_PROC(LPALGETFILTERI, alGetFilteri); + LOAD_PROC(LPALGETFILTERIV, alGetFilteriv); + LOAD_PROC(LPALGETFILTERF, alGetFilterf); + LOAD_PROC(LPALGETFILTERFV, alGetFilterfv); + + LOAD_PROC(LPALGENAUXILIARYEFFECTSLOTS, alGenAuxiliaryEffectSlots); + LOAD_PROC(LPALDELETEAUXILIARYEFFECTSLOTS, alDeleteAuxiliaryEffectSlots); + LOAD_PROC(LPALISAUXILIARYEFFECTSLOT, alIsAuxiliaryEffectSlot); + LOAD_PROC(LPALAUXILIARYEFFECTSLOTI, alAuxiliaryEffectSloti); + LOAD_PROC(LPALAUXILIARYEFFECTSLOTIV, alAuxiliaryEffectSlotiv); + LOAD_PROC(LPALAUXILIARYEFFECTSLOTF, alAuxiliaryEffectSlotf); + LOAD_PROC(LPALAUXILIARYEFFECTSLOTFV, alAuxiliaryEffectSlotfv); + LOAD_PROC(LPALGETAUXILIARYEFFECTSLOTI, alGetAuxiliaryEffectSloti); + LOAD_PROC(LPALGETAUXILIARYEFFECTSLOTIV, alGetAuxiliaryEffectSlotiv); + LOAD_PROC(LPALGETAUXILIARYEFFECTSLOTF, alGetAuxiliaryEffectSlotf); + LOAD_PROC(LPALGETAUXILIARYEFFECTSLOTFV, alGetAuxiliaryEffectSlotfv); +#undef LOAD_PROC +} + +void SetEffectsLevel(ALuint uiFilter, float level) +{ + alFilteri(uiFilter, AL_FILTER_TYPE, AL_FILTER_LOWPASS); + alFilterf(uiFilter, AL_LOWPASS_GAIN, 1.0f); + alFilterf(uiFilter, AL_LOWPASS_GAINHF, level); +} + +static inline float gain_to_mB(float gain) +{ + return (gain > 1e-5f) ? (float)(log10f(gain) * 2000.0f) : -10000l; +} + +static inline float mB_to_gain(float millibels) +{ + return (millibels > -10000.0f) ? powf(10.0f, millibels/2000.0f) : 0.0f; +} + +static inline float clampF(float val, float minval, float maxval) +{ + if(val >= maxval) return maxval; + if(val <= minval) return minval; + return val; +} + +void EAX3_Set(ALuint effect, const EAXLISTENERPROPERTIES *props) +{ + alEffecti (effect, AL_EFFECT_TYPE, AL_EFFECT_EAXREVERB); + alEffectf (effect, AL_EAXREVERB_DENSITY, clampF(powf(props->flEnvironmentSize, 3.0f) / 16.0f, 0.0f, 1.0f)); + alEffectf (effect, AL_EAXREVERB_DIFFUSION, props->flEnvironmentDiffusion); + alEffectf (effect, AL_EAXREVERB_GAIN, mB_to_gain((float)props->lRoom)); + alEffectf (effect, AL_EAXREVERB_GAINHF, mB_to_gain((float)props->lRoomHF)); + alEffectf (effect, AL_EAXREVERB_GAINLF, mB_to_gain((float)props->lRoomLF)); + alEffectf (effect, AL_EAXREVERB_DECAY_TIME, props->flDecayTime); + alEffectf (effect, AL_EAXREVERB_DECAY_HFRATIO, props->flDecayHFRatio); + alEffectf (effect, AL_EAXREVERB_DECAY_LFRATIO, props->flDecayLFRatio); + alEffectf (effect, AL_EAXREVERB_REFLECTIONS_GAIN, clampF(mB_to_gain((float)props->lReflections), AL_EAXREVERB_MIN_REFLECTIONS_GAIN, AL_EAXREVERB_MAX_REFLECTIONS_GAIN)); + alEffectf (effect, AL_EAXREVERB_REFLECTIONS_DELAY, props->flReflectionsDelay); + alEffectfv(effect, AL_EAXREVERB_REFLECTIONS_PAN, &props->vReflectionsPan.x); + alEffectf (effect, AL_EAXREVERB_LATE_REVERB_GAIN, clampF(mB_to_gain((float)props->lReverb), AL_EAXREVERB_MIN_LATE_REVERB_GAIN, AL_EAXREVERB_MAX_LATE_REVERB_GAIN)); + alEffectf (effect, AL_EAXREVERB_LATE_REVERB_DELAY, props->flReverbDelay); + alEffectfv(effect, AL_EAXREVERB_LATE_REVERB_PAN, &props->vReverbPan.x); + alEffectf (effect, AL_EAXREVERB_ECHO_TIME, props->flEchoTime); + alEffectf (effect, AL_EAXREVERB_ECHO_DEPTH, props->flEchoDepth); + alEffectf (effect, AL_EAXREVERB_MODULATION_TIME, props->flModulationTime); + alEffectf (effect, AL_EAXREVERB_MODULATION_DEPTH, props->flModulationDepth); + alEffectf (effect, AL_EAXREVERB_AIR_ABSORPTION_GAINHF, clampF(mB_to_gain(props->flAirAbsorptionHF), AL_EAXREVERB_MIN_AIR_ABSORPTION_GAINHF, AL_EAXREVERB_MAX_AIR_ABSORPTION_GAINHF)); + alEffectf (effect, AL_EAXREVERB_HFREFERENCE, props->flHFReference); + alEffectf (effect, AL_EAXREVERB_LFREFERENCE, props->flLFReference); + alEffectf (effect, AL_EAXREVERB_ROOM_ROLLOFF_FACTOR, props->flRoomRolloffFactor); + alEffecti (effect, AL_EAXREVERB_DECAY_HFLIMIT, (props->ulFlags&EAXLISTENERFLAGS_DECAYHFLIMIT) ? AL_TRUE : AL_FALSE); +} + +void EFX_Set(ALuint effect, const EAXLISTENERPROPERTIES *props) +{ + alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_REVERB); + + alEffectf(effect, AL_REVERB_DENSITY, clampF(powf(props->flEnvironmentSize, 3.0f) / 16.0f, 0.0f, 1.0f)); + alEffectf(effect, AL_REVERB_DIFFUSION, props->flEnvironmentDiffusion); + alEffectf(effect, AL_REVERB_GAIN, mB_to_gain((float)props->lRoom)); + alEffectf(effect, AL_REVERB_GAINHF, mB_to_gain((float)props->lRoomHF)); + alEffectf(effect, AL_REVERB_DECAY_TIME, props->flDecayTime); + alEffectf(effect, AL_REVERB_DECAY_HFRATIO, props->flDecayHFRatio); + alEffectf(effect, AL_REVERB_REFLECTIONS_GAIN, clampF(mB_to_gain((float)props->lReflections), AL_EAXREVERB_MIN_REFLECTIONS_GAIN, AL_EAXREVERB_MAX_REFLECTIONS_GAIN)); + alEffectf(effect, AL_REVERB_REFLECTIONS_DELAY, props->flReflectionsDelay); + alEffectf(effect, AL_REVERB_LATE_REVERB_GAIN, clampF(mB_to_gain((float)props->lReverb), AL_EAXREVERB_MIN_LATE_REVERB_GAIN, AL_EAXREVERB_MAX_LATE_REVERB_GAIN)); + alEffectf(effect, AL_REVERB_LATE_REVERB_DELAY, props->flReverbDelay); + alEffectf(effect, AL_REVERB_AIR_ABSORPTION_GAINHF, clampF(mB_to_gain(props->flAirAbsorptionHF), AL_EAXREVERB_MIN_AIR_ABSORPTION_GAINHF, AL_EAXREVERB_MAX_AIR_ABSORPTION_GAINHF)); + alEffectf(effect, AL_REVERB_ROOM_ROLLOFF_FACTOR, props->flRoomRolloffFactor); + alEffecti(effect, AL_REVERB_DECAY_HFLIMIT, (props->ulFlags&EAXLISTENERFLAGS_DECAYHFLIMIT) ? AL_TRUE : AL_FALSE); +} + +void EAX3_SetReverbMix(ALuint filter, float mix) +{ + //long vol=(long)linear_to_dB(mix); + //DSPROPERTY_EAXBUFFER_ROOMHF, + //DSPROPERTY_EAXBUFFER_ROOM, + //DSPROPERTY_EAXBUFFER_REVERBMIX, + + long mbvol = gain_to_mB(mix); + float mb = mbvol; + float mbhf = mbvol; + + alFilteri(filter, AL_FILTER_TYPE, AL_FILTER_LOWPASS); + alFilterf(filter, AL_LOWPASS_GAIN, mB_to_gain(Min(mb, 0.0f))); + alFilterf(filter, AL_LOWPASS_GAINHF, mB_to_gain(mbhf)); +} + +#endif
\ No newline at end of file diff --git a/src/audio/oal/oal_utils.h b/src/audio/oal/oal_utils.h new file mode 100644 index 0000000..f0fa090 --- /dev/null +++ b/src/audio/oal/oal_utils.h @@ -0,0 +1,54 @@ +#pragma once + +#ifdef AUDIO_OAL +#include "eax.h" +#include "AL/efx.h" + + +void EFXInit(); +void EAX3_Set(ALuint effect, const EAXLISTENERPROPERTIES *props); +void EFX_Set(ALuint effect, const EAXLISTENERPROPERTIES *props); +void EAX3_SetReverbMix(ALuint filter, float mix); +void SetEffectsLevel(ALuint uiFilter, float level); + +namespace re3_openal { + +extern LPALGENEFFECTS alGenEffects; +extern LPALDELETEEFFECTS alDeleteEffects; +extern LPALISEFFECT alIsEffect; +extern LPALEFFECTI alEffecti; +extern LPALEFFECTIV alEffectiv; +extern LPALEFFECTF alEffectf; +extern LPALEFFECTFV alEffectfv; +extern LPALGETEFFECTI alGetEffecti; +extern LPALGETEFFECTIV alGetEffectiv; +extern LPALGETEFFECTF alGetEffectf; +extern LPALGETEFFECTFV alGetEffectfv; +extern LPALGENAUXILIARYEFFECTSLOTS alGenAuxiliaryEffectSlots; +extern LPALDELETEAUXILIARYEFFECTSLOTS alDeleteAuxiliaryEffectSlots; +extern LPALISAUXILIARYEFFECTSLOT alIsAuxiliaryEffectSlot; +extern LPALAUXILIARYEFFECTSLOTI alAuxiliaryEffectSloti; +extern LPALAUXILIARYEFFECTSLOTIV alAuxiliaryEffectSlotiv; +extern LPALAUXILIARYEFFECTSLOTF alAuxiliaryEffectSlotf; +extern LPALAUXILIARYEFFECTSLOTFV alAuxiliaryEffectSlotfv; +extern LPALGETAUXILIARYEFFECTSLOTI alGetAuxiliaryEffectSloti; +extern LPALGETAUXILIARYEFFECTSLOTIV alGetAuxiliaryEffectSlotiv; +extern LPALGETAUXILIARYEFFECTSLOTF alGetAuxiliaryEffectSlotf; +extern LPALGETAUXILIARYEFFECTSLOTFV alGetAuxiliaryEffectSlotfv; +extern LPALGENFILTERS alGenFilters; +extern LPALDELETEFILTERS alDeleteFilters; +extern LPALISFILTER alIsFilter; +extern LPALFILTERI alFilteri; +extern LPALFILTERIV alFilteriv; +extern LPALFILTERF alFilterf; +extern LPALFILTERFV alFilterfv; +extern LPALGETFILTERI alGetFilteri; +extern LPALGETFILTERIV alGetFilteriv; +extern LPALGETFILTERF alGetFilterf; +extern LPALGETFILTERFV alGetFilterfv; + +} + +using namespace re3_openal; + +#endif diff --git a/src/audio/oal/stream.cpp b/src/audio/oal/stream.cpp new file mode 100644 index 0000000..ed73e94 --- /dev/null +++ b/src/audio/oal/stream.cpp @@ -0,0 +1,1413 @@ +#include "common.h" + +#ifdef AUDIO_OAL +#include "stream.h" +#include "sampman.h" + +#if defined _MSC_VER && !defined CMAKE_NO_AUTOLINK +#ifdef AUDIO_OAL_USE_SNDFILE +#pragma comment( lib, "libsndfile-1.lib" ) +#endif +#ifdef AUDIO_OAL_USE_MPG123 +#pragma comment( lib, "libmpg123-0.lib" ) +#endif +#endif +#ifdef AUDIO_OAL_USE_SNDFILE +#include <sndfile.h> +#endif +#ifdef AUDIO_OAL_USE_MPG123 +#include <mpg123.h> +#endif +#ifdef AUDIO_OAL_USE_OPUS +#include <opusfile.h> +#endif + +#ifndef _WIN32 +#include "crossplatform.h" +#endif + +/* +As we ran onto an issue of having different volume levels for mono streams +and stereo streams we are now handling all the stereo panning ourselves. +Each stream now has two sources - one panned to the left and one to the right, +and uses two separate buffers to store data for each individual channel. +For that we also have to reshuffle all decoded PCM stereo data from LRLRLRLR to +LLLLRRRR (handled by CSortStereoBuffer). +*/ + +class CSortStereoBuffer +{ + uint16* PcmBuf; + size_t BufSize; +public: + CSortStereoBuffer() : PcmBuf(nil), BufSize(0) {} + ~CSortStereoBuffer() + { + if (PcmBuf) + free(PcmBuf); + } + + uint16* GetBuffer(size_t size) + { + if (size == 0) return nil; + if (!PcmBuf) + { + BufSize = size; + PcmBuf = (uint16*)malloc(BufSize); + } + else if (BufSize < size) + { + BufSize = size; + PcmBuf = (uint16*)realloc(PcmBuf, size); + } + return PcmBuf; + } + + void SortStereo(void* buf, size_t size) + { + uint16* InBuf = (uint16*)buf; + uint16* OutBuf = GetBuffer(size); + + if (!OutBuf) return; + + size_t rightStart = size / 4; + for (size_t i = 0; i < size / 4; i++) + { + OutBuf[i] = InBuf[i*2]; + OutBuf[i+rightStart] = InBuf[i*2+1]; + } + + memcpy(InBuf, OutBuf, size); + } + +}; + +CSortStereoBuffer SortStereoBuffer; + +class CImaADPCMDecoder +{ + const uint16 StepTable[89] = { + 7, 8, 9, 10, 11, 12, 13, 14, + 16, 17, 19, 21, 23, 25, 28, 31, + 34, 37, 41, 45, 50, 55, 60, 66, + 73, 80, 88, 97, 107, 118, 130, 143, + 157, 173, 190, 209, 230, 253, 279, 307, + 337, 371, 408, 449, 494, 544, 598, 658, + 724, 796, 876, 963, 1060, 1166, 1282, 1411, + 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, + 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, + 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, + 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, + 32767 + }; + + int16 Sample, StepIndex; + +public: + CImaADPCMDecoder() + { + Init(0, 0); + } + + void Init(int16 _Sample, int16 _StepIndex) + { + Sample = _Sample; + StepIndex = _StepIndex; + } + + void Decode(uint8 *inbuf, int16 *_outbuf, size_t size) + { + int16* outbuf = _outbuf; + for (size_t i = 0; i < size; i++) + { + *(outbuf++) = DecodeSample(inbuf[i] & 0xF); + *(outbuf++) = DecodeSample(inbuf[i] >> 4); + } + } + + int16 DecodeSample(uint8 adpcm) + { + uint16 step = StepTable[StepIndex]; + + if (adpcm & 4) + StepIndex += ((adpcm & 3) + 1) * 2; + else + StepIndex--; + + StepIndex = clamp(StepIndex, 0, 88); + + int delta = step >> 3; + if (adpcm & 1) delta += step >> 2; + if (adpcm & 2) delta += step >> 1; + if (adpcm & 4) delta += step; + if (adpcm & 8) delta = -delta; + + int newSample = Sample + delta; + Sample = clamp(newSample, -32768, 32767); + return Sample; + } +}; + +class CWavFile : public IDecoder +{ + enum + { + WAVEFMT_PCM = 1, + WAVEFMT_IMA_ADPCM = 0x11, + WAVEFMT_XBOX_ADPCM = 0x69, + }; + + struct tDataHeader + { + uint32 ID; + uint32 Size; + }; + + struct tFormatHeader + { + uint16 AudioFormat; + uint16 NumChannels; + uint32 SampleRate; + uint32 ByteRate; + uint16 BlockAlign; + uint16 BitsPerSample; + uint16 extra[2]; // adpcm only + + tFormatHeader() { memset(this, 0, sizeof(*this)); } + }; + + FILE *m_pFile; + bool m_bIsOpen; + + tFormatHeader m_FormatHeader; + + uint32 m_DataStartOffset; // TODO: 64 bit? + uint32 m_nSampleCount; + uint32 m_nSamplesPerBlock; + + // ADPCM things + uint8 *m_pAdpcmBuffer; + int16 **m_ppPcmBuffers; + CImaADPCMDecoder *m_pAdpcmDecoders; + + void Close() + { + if (m_pFile) { + fclose(m_pFile); + m_pFile = nil; + } + delete[] m_pAdpcmBuffer; + delete[] m_ppPcmBuffers; + delete[] m_pAdpcmDecoders; + } + + uint32 GetCurrentSample() const + { + // TODO: 64 bit? + uint32 FilePos = ftell(m_pFile); + if (FilePos <= m_DataStartOffset) + return 0; + return (FilePos - m_DataStartOffset) / m_FormatHeader.BlockAlign * m_nSamplesPerBlock; + } + +public: + CWavFile(const char* path) : m_bIsOpen(false), m_DataStartOffset(0), m_nSampleCount(0), m_nSamplesPerBlock(0), m_pAdpcmBuffer(nil), m_ppPcmBuffers(nil), m_pAdpcmDecoders(nil) + { + m_pFile = fopen(path, "rb"); + if (!m_pFile) return; + +#define CLOSE_ON_ERROR(op)\ + if (op) { \ + Close(); \ + return; \ + } + + tDataHeader DataHeader; + + CLOSE_ON_ERROR(fread(&DataHeader, sizeof(DataHeader), 1, m_pFile) == 0); + CLOSE_ON_ERROR(DataHeader.ID != 'FFIR'); + + // TODO? validate filesizes + + int WAVE; + CLOSE_ON_ERROR(fread(&WAVE, 4, 1, m_pFile) == 0); + CLOSE_ON_ERROR(WAVE != 'EVAW') + CLOSE_ON_ERROR(fread(&DataHeader, sizeof(DataHeader), 1, m_pFile) == 0); + CLOSE_ON_ERROR(DataHeader.ID != ' tmf'); + + CLOSE_ON_ERROR(fread(&m_FormatHeader, Min(DataHeader.Size, sizeof(tFormatHeader)), 1, m_pFile) == 0); + CLOSE_ON_ERROR(DataHeader.Size > sizeof(tFormatHeader)); + + switch (m_FormatHeader.AudioFormat) + { + case WAVEFMT_XBOX_ADPCM: + m_FormatHeader.AudioFormat = WAVEFMT_IMA_ADPCM; + case WAVEFMT_IMA_ADPCM: + m_nSamplesPerBlock = (m_FormatHeader.BlockAlign / m_FormatHeader.NumChannels - 4) * 2 + 1; + m_pAdpcmBuffer = new uint8[m_FormatHeader.BlockAlign]; + m_ppPcmBuffers = new int16*[m_FormatHeader.NumChannels]; + m_pAdpcmDecoders = new CImaADPCMDecoder[m_FormatHeader.NumChannels]; + break; + case WAVEFMT_PCM: + m_nSamplesPerBlock = 1; + if (m_FormatHeader.BitsPerSample != 16) + { + debug("Unsupported PCM (%d bits), only signed 16-bit is supported (%s)\n", m_FormatHeader.BitsPerSample, path); + Close(); + return; + } + break; + default: + debug("Unsupported wav format 0x%x (%s)\n", m_FormatHeader.AudioFormat, path); + Close(); + return; + } + + while (true) { + CLOSE_ON_ERROR(fread(&DataHeader, sizeof(DataHeader), 1, m_pFile) == 0); + if (DataHeader.ID == 'atad') + break; + fseek(m_pFile, DataHeader.Size, SEEK_CUR); + // TODO? validate data size + // maybe check if there no extreme custom headers that might break this + } + + m_DataStartOffset = ftell(m_pFile); + m_nSampleCount = DataHeader.Size / m_FormatHeader.BlockAlign * m_nSamplesPerBlock; + + m_bIsOpen = true; +#undef CLOSE_ON_ERROR + } + + ~CWavFile() + { + Close(); + } + + bool IsOpened() + { + return m_bIsOpen; + } + + uint32 GetSampleSize() + { + return sizeof(uint16); + } + + uint32 GetSampleCount() + { + return m_nSampleCount; + } + + uint32 GetSampleRate() + { + return m_FormatHeader.SampleRate; + } + + uint32 GetChannels() + { + return m_FormatHeader.NumChannels; + } + + void Seek(uint32 milliseconds) + { + if (!IsOpened()) return; + fseek(m_pFile, m_DataStartOffset + ms2samples(milliseconds) / m_nSamplesPerBlock * m_FormatHeader.BlockAlign, SEEK_SET); + } + + uint32 Tell() + { + if (!IsOpened()) return 0; + return samples2ms(GetCurrentSample()); + } + +#define SAMPLES_IN_LINE (8) + + uint32 Decode(void* buffer) + { + if (!IsOpened()) return 0; + + if (m_FormatHeader.AudioFormat == WAVEFMT_PCM) + { + // just read the file and sort the samples + uint32 size = fread(buffer, 1, GetBufferSize(), m_pFile); + if (m_FormatHeader.NumChannels == 2) + SortStereoBuffer.SortStereo(buffer, size); + return size; + } + else if (m_FormatHeader.AudioFormat == WAVEFMT_IMA_ADPCM) + { + // trim the buffer size if we're at the end of our file + uint32 nMaxSamples = GetBufferSamples() / m_FormatHeader.NumChannels; + uint32 nSamplesLeft = m_nSampleCount - GetCurrentSample(); + nMaxSamples = Min(nMaxSamples, nSamplesLeft); + + // align sample count to our block + nMaxSamples = nMaxSamples / m_nSamplesPerBlock * m_nSamplesPerBlock; + + // count the size of output buffer + uint32 OutBufSizePerChannel = nMaxSamples * GetSampleSize(); + uint32 OutBufSize = OutBufSizePerChannel * m_FormatHeader.NumChannels; + + // calculate the pointers to individual channel buffers + for (uint32 i = 0; i < m_FormatHeader.NumChannels; i++) + m_ppPcmBuffers[i] = (int16*)((int8*)buffer + OutBufSizePerChannel * i); + + uint32 samplesRead = 0; + while (samplesRead < nMaxSamples) + { + // read the file + uint8 *pAdpcmBuf = m_pAdpcmBuffer; + if (fread(m_pAdpcmBuffer, 1, m_FormatHeader.BlockAlign, m_pFile) == 0) + return 0; + + // get the first sample in adpcm block and initialise the decoder(s) + for (uint32 i = 0; i < m_FormatHeader.NumChannels; i++) + { + int16 Sample = *(int16*)pAdpcmBuf; + pAdpcmBuf += sizeof(int16); + int16 Step = *(int16*)pAdpcmBuf; + pAdpcmBuf += sizeof(int16); + m_pAdpcmDecoders[i].Init(Sample, Step); + *(m_ppPcmBuffers[i]) = Sample; + m_ppPcmBuffers[i]++; + } + samplesRead++; + + // decode the rest of the block + for (uint32 s = 1; s < m_nSamplesPerBlock; s += SAMPLES_IN_LINE) + { + for (uint32 i = 0; i < m_FormatHeader.NumChannels; i++) + { + m_pAdpcmDecoders[i].Decode(pAdpcmBuf, m_ppPcmBuffers[i], SAMPLES_IN_LINE / 2); + pAdpcmBuf += SAMPLES_IN_LINE / 2; + m_ppPcmBuffers[i] += SAMPLES_IN_LINE; + } + samplesRead += SAMPLES_IN_LINE; + } + } + return OutBufSize; + } + return 0; + } +}; + +#ifdef AUDIO_OAL_USE_SNDFILE +class CSndFile : public IDecoder +{ + SNDFILE *m_pfSound; + SF_INFO m_soundInfo; +public: + CSndFile(const char *path) : + m_pfSound(nil) + { + memset(&m_soundInfo, 0, sizeof(m_soundInfo)); + m_pfSound = sf_open(path, SFM_READ, &m_soundInfo); + } + + ~CSndFile() + { + if ( m_pfSound ) + { + sf_close(m_pfSound); + m_pfSound = nil; + } + } + + bool IsOpened() + { + return m_pfSound != nil; + } + + uint32 GetSampleSize() + { + return sizeof(uint16); + } + + uint32 GetSampleCount() + { + return m_soundInfo.frames; + } + + uint32 GetSampleRate() + { + return m_soundInfo.samplerate; + } + + uint32 GetChannels() + { + return m_soundInfo.channels; + } + + void Seek(uint32 milliseconds) + { + if ( !IsOpened() ) return; + sf_seek(m_pfSound, ms2samples(milliseconds), SF_SEEK_SET); + } + + uint32 Tell() + { + if ( !IsOpened() ) return 0; + return samples2ms(sf_seek(m_pfSound, 0, SF_SEEK_CUR)); + } + + uint32 Decode(void *buffer) + { + if ( !IsOpened() ) return 0; + + size_t size = sf_read_short(m_pfSound, (short*)buffer, GetBufferSamples()) * GetSampleSize(); + if (GetChannels()==2) + SortStereoBuffer.SortStereo(buffer, size); + return size; + } +}; +#endif + +#ifdef AUDIO_OAL_USE_MPG123 +// fuzzy seek eliminates stutter when playing ADF but spams errors a lot (and breaks radio sometimes) +//#define MP3_USE_FUZZY_SEEK + +class CMP3File : public IDecoder +{ +protected: + mpg123_handle *m_pMH; + bool m_bOpened; + uint32 m_nRate; + uint32 m_nChannels; + + CMP3File() : + m_pMH(nil), + m_bOpened(false), + m_nRate(0), + m_nChannels(0) {} +public: + CMP3File(const char *path) : + m_pMH(nil), + m_bOpened(false), + m_nRate(0), + m_nChannels(0) + { + m_pMH = mpg123_new(nil, nil); + if ( m_pMH ) + { +#ifdef MP3_USE_FUZZY_SEEK + mpg123_param(m_pMH, MPG123_FLAGS, MPG123_FUZZY | MPG123_SEEKBUFFER | MPG123_GAPLESS | MPG123_QUIET, 0.0); +#else + mpg123_param(m_pMH, MPG123_FLAGS, MPG123_SEEKBUFFER | MPG123_GAPLESS, 0.0); +#endif + long rate = 0; + int channels = 0; + int encoding = 0; + + m_bOpened = mpg123_open(m_pMH, path) == MPG123_OK + && mpg123_getformat(m_pMH, &rate, &channels, &encoding) == MPG123_OK; + + m_nRate = rate; + m_nChannels = channels; + + if ( IsOpened() ) + { + mpg123_format_none(m_pMH); + mpg123_format(m_pMH, rate, channels, encoding); + } + } + } + + ~CMP3File() + { + if ( m_pMH ) + { + mpg123_close(m_pMH); + mpg123_delete(m_pMH); + m_pMH = nil; + } + } + + bool IsOpened() + { + return m_bOpened; + } + + uint32 GetSampleSize() + { + return sizeof(uint16); + } + + uint32 GetSampleCount() + { + if ( !IsOpened() ) return 0; + return mpg123_length(m_pMH); + } + + uint32 GetSampleRate() + { + return m_nRate; + } + + uint32 GetChannels() + { + return m_nChannels; + } + + void Seek(uint32 milliseconds) + { + if ( !IsOpened() ) return; + mpg123_seek(m_pMH, ms2samples(milliseconds), SEEK_SET); + } + + uint32 Tell() + { + if ( !IsOpened() ) return 0; + return samples2ms(mpg123_tell(m_pMH)); + } + + uint32 Decode(void *buffer) + { + if ( !IsOpened() ) return 0; + + size_t size; + int err = mpg123_read(m_pMH, (unsigned char *)buffer, GetBufferSize(), &size); +#if defined(__LP64__) || defined(_WIN64) + assert("We can't handle audio files more then 2 GB yet :shrug:" && (size < UINT32_MAX)); +#endif + if (err != MPG123_OK && err != MPG123_DONE) return 0; + if (GetChannels() == 2) + SortStereoBuffer.SortStereo(buffer, size); + return (uint32)size; + } +}; + +class CADFFile : public CMP3File +{ + static ssize_t r_read(void* fh, void* buf, size_t size) + { + size_t bytesRead = fread(buf, 1, size, (FILE*)fh); + uint8* _buf = (uint8*)buf; + for (size_t i = 0; i < size; i++) + _buf[i] ^= 0x22; + return bytesRead; + } + static off_t r_seek(void* fh, off_t pos, int seekType) + { + fseek((FILE*)fh, pos, seekType); + return ftell((FILE*)fh); + } + static void r_close(void* fh) + { + fclose((FILE*)fh); + } +public: + CADFFile(const char* path) + { + m_pMH = mpg123_new(nil, nil); + if (m_pMH) + { +#ifdef MP3_USE_FUZZY_SEEK + mpg123_param(m_pMH, MPG123_FLAGS, MPG123_FUZZY | MPG123_SEEKBUFFER | MPG123_GAPLESS | MPG123_QUIET, 0.0); +#else + mpg123_param(m_pMH, MPG123_FLAGS, MPG123_SEEKBUFFER | MPG123_GAPLESS, 0.0); +#endif + long rate = 0; + int channels = 0; + int encoding = 0; + + FILE* f = fopen(path, "rb"); + + m_bOpened = mpg123_replace_reader_handle(m_pMH, r_read, r_seek, r_close) == MPG123_OK + && mpg123_open_handle(m_pMH, f) == MPG123_OK && mpg123_getformat(m_pMH, &rate, &channels, &encoding) == MPG123_OK; + m_nRate = rate; + m_nChannels = channels; + + if (IsOpened()) + { + mpg123_format_none(m_pMH); + mpg123_format(m_pMH, rate, channels, encoding); + } + } + } +}; + +#endif +#define VAG_LINE_SIZE (0x10) +#define VAG_SAMPLES_IN_LINE (28) + +class CVagDecoder +{ + const double f[5][2] = { { 0.0, 0.0 }, + { 60.0 / 64.0, 0.0 }, + { 115.0 / 64.0, -52.0 / 64.0 }, + { 98.0 / 64.0, -55.0 / 64.0 }, + { 122.0 / 64.0, -60.0 / 64.0 } }; + + double s_1; + double s_2; +public: + CVagDecoder() + { + ResetState(); + } + + void ResetState() + { + s_1 = s_2 = 0.0; + } + + static short quantize(double sample) + { + int a = int(sample + 0.5); + return short(clamp(a, -32768, 32767)); + } + + void Decode(void* _inbuf, int16* _outbuf, size_t size) + { + uint8* inbuf = (uint8*)_inbuf; + int16* outbuf = _outbuf; + size &= ~(VAG_LINE_SIZE - 1); + + while (size > 0) { + double samples[VAG_SAMPLES_IN_LINE]; + + int predict_nr, shift_factor, flags; + predict_nr = *(inbuf++); + shift_factor = predict_nr & 0xf; + predict_nr >>= 4; + flags = *(inbuf++); + if (flags == 7) // TODO: ignore? + break; + for (int i = 0; i < VAG_SAMPLES_IN_LINE; i += 2) { + int d = *(inbuf++); + int16 s = int16((d & 0xf) << 12); + samples[i] = (double)(s >> shift_factor); + s = int16((d & 0xf0) << 8); + samples[i + 1] = (double)(s >> shift_factor); + } + + for (int i = 0; i < VAG_SAMPLES_IN_LINE; i++) { + samples[i] = samples[i] + s_1 * f[predict_nr][0] + s_2 * f[predict_nr][1]; + s_2 = s_1; + s_1 = samples[i]; + *(outbuf++) = quantize(samples[i] + 0.5); + } + size -= VAG_LINE_SIZE; + } + } +}; + +#define VB_BLOCK_SIZE (0x2000) +#define NUM_VAG_LINES_IN_BLOCK (VB_BLOCK_SIZE / VAG_LINE_SIZE) +#define NUM_VAG_SAMPLES_IN_BLOCK (NUM_VAG_LINES_IN_BLOCK * VAG_SAMPLES_IN_LINE) + +class CVbFile : public IDecoder +{ + FILE *m_pFile; + CVagDecoder *m_pVagDecoders; + + size_t m_FileSize; + size_t m_nNumberOfBlocks; + + uint32 m_nSampleRate; + uint8 m_nChannels; + bool m_bBlockRead; + uint16 m_LineInBlock; + size_t m_CurrentBlock; + + uint8 **m_ppVagBuffers; // buffers that cache actual ADPCM file data + int16 **m_ppPcmBuffers; + + void ReadBlock(int32 block = -1) + { + // just read next block if -1 + if (block != -1) + fseek(m_pFile, block * m_nChannels * VB_BLOCK_SIZE, SEEK_SET); + + for (int i = 0; i < m_nChannels; i++) + fread(m_ppVagBuffers[i], VB_BLOCK_SIZE, 1, m_pFile); + m_bBlockRead = true; + } + +public: + CVbFile(const char* path, uint32 nSampleRate = 32000, uint8 nChannels = 2) : m_nSampleRate(nSampleRate), m_nChannels(nChannels), m_pVagDecoders(nil), m_ppVagBuffers(nil), m_ppPcmBuffers(nil), + m_FileSize(0), m_nNumberOfBlocks(0), m_bBlockRead(false), m_LineInBlock(0), m_CurrentBlock(0) + { + m_pFile = fopen(path, "rb"); + if (!m_pFile) return; + + fseek(m_pFile, 0, SEEK_END); + m_FileSize = ftell(m_pFile); + fseek(m_pFile, 0, SEEK_SET); + + m_nNumberOfBlocks = m_FileSize / (nChannels * VB_BLOCK_SIZE); + m_pVagDecoders = new CVagDecoder[nChannels]; + m_ppVagBuffers = new uint8*[nChannels]; + m_ppPcmBuffers = new int16*[nChannels]; + for (uint8 i = 0; i < nChannels; i++) + m_ppVagBuffers[i] = new uint8[VB_BLOCK_SIZE]; + } + + ~CVbFile() + { + if (m_pFile) + { + fclose(m_pFile); + + delete[] m_pVagDecoders; + for (int i = 0; i < m_nChannels; i++) + delete[] m_ppVagBuffers[i]; + delete[] m_ppVagBuffers; + delete[] m_ppPcmBuffers; + } + } + + bool IsOpened() + { + return m_pFile != nil; + } + + uint32 GetSampleSize() + { + return sizeof(uint16); + } + + uint32 GetSampleCount() + { + if (!IsOpened()) return 0; + return m_nNumberOfBlocks * NUM_VAG_LINES_IN_BLOCK * VAG_SAMPLES_IN_LINE; + } + + uint32 GetSampleRate() + { + return m_nSampleRate; + } + + uint32 GetChannels() + { + return m_nChannels; + } + + void Seek(uint32 milliseconds) + { + if (!IsOpened()) return; + uint32 samples = ms2samples(milliseconds); + + // find the block of our sample + uint32 block = samples / NUM_VAG_SAMPLES_IN_BLOCK; + if (block > m_nNumberOfBlocks) + { + samples = 0; + block = 0; + } + if (block != m_CurrentBlock) + m_bBlockRead = false; + + // find a line of our sample within our block + uint32 remainingSamples = samples - block * NUM_VAG_SAMPLES_IN_BLOCK; + uint32 newLine = remainingSamples / VAG_SAMPLES_IN_LINE / VAG_LINE_SIZE; + + if (m_CurrentBlock != block || m_LineInBlock != newLine) + { + m_CurrentBlock = block; + m_LineInBlock = newLine; + for (uint32 i = 0; i < GetChannels(); i++) + m_pVagDecoders[i].ResetState(); + } + + } + + uint32 Tell() + { + if (!IsOpened()) return 0; + uint32 pos = (m_CurrentBlock * NUM_VAG_LINES_IN_BLOCK + m_LineInBlock) * VAG_SAMPLES_IN_LINE; + return samples2ms(pos); + } + + uint32 Decode(void* buffer) + { + if (!IsOpened()) return 0; + + if (m_CurrentBlock >= m_nNumberOfBlocks) return 0; + + // cache current ADPCM block + if (!m_bBlockRead) + ReadBlock(m_CurrentBlock); + + // trim the buffer size if we're at the end of our file + int numberOfRequiredLines = GetBufferSamples() / m_nChannels / VAG_SAMPLES_IN_LINE; + int numberOfRemainingLines = (m_nNumberOfBlocks - m_CurrentBlock) * NUM_VAG_LINES_IN_BLOCK - m_LineInBlock; + int bufSizePerChannel = Min(numberOfRequiredLines, numberOfRemainingLines) * VAG_SAMPLES_IN_LINE * GetSampleSize(); + + // calculate the pointers to individual channel buffers + for (uint32 i = 0; i < m_nChannels; i++) + m_ppPcmBuffers[i] = (int16*)((int8*)buffer + bufSizePerChannel * i); + + int size = 0; + while (size < bufSizePerChannel) + { + // decode the VAG lines + for (uint32 i = 0; i < m_nChannels; i++) + { + m_pVagDecoders[i].Decode(m_ppVagBuffers[i] + m_LineInBlock * VAG_LINE_SIZE, m_ppPcmBuffers[i], VAG_LINE_SIZE); + m_ppPcmBuffers[i] += VAG_SAMPLES_IN_LINE; + } + size += VAG_SAMPLES_IN_LINE * GetSampleSize(); + m_LineInBlock++; + + // block is over, read the next block + if (m_LineInBlock >= NUM_VAG_LINES_IN_BLOCK) + { + m_CurrentBlock++; + if (m_CurrentBlock >= m_nNumberOfBlocks) // end of file + break; + m_LineInBlock = 0; + ReadBlock(); + } + } + + return bufSizePerChannel * m_nChannels; + } +}; +#ifdef AUDIO_OAL_USE_OPUS +class COpusFile : public IDecoder +{ + OggOpusFile *m_FileH; + bool m_bOpened; + uint32 m_nRate; + uint32 m_nChannels; +public: + COpusFile(const char *path) : m_FileH(nil), + m_bOpened(false), + m_nRate(0), + m_nChannels(0) + { + int ret; + m_FileH = op_open_file(path, &ret); + + if (m_FileH) { + m_nChannels = op_head(m_FileH, 0)->channel_count; + m_nRate = 48000; + const OpusTags *tags = op_tags(m_FileH, 0); + for (int i = 0; i < tags->comments; i++) { + if (strncmp(tags->user_comments[i], "SAMPLERATE", sizeof("SAMPLERATE")-1) == 0) + { + sscanf(tags->user_comments[i], "SAMPLERATE=%i", &m_nRate); + break; + } + } + + m_bOpened = true; + } + } + + ~COpusFile() + { + if (m_FileH) + { + op_free(m_FileH); + m_FileH = nil; + } + } + + bool IsOpened() + { + return m_bOpened; + } + + uint32 GetSampleSize() + { + return sizeof(uint16); + } + + uint32 GetSampleCount() + { + if ( !IsOpened() ) return 0; + return op_pcm_total(m_FileH, 0); + } + + uint32 GetSampleRate() + { + return m_nRate; + } + + uint32 GetChannels() + { + return m_nChannels; + } + + void Seek(uint32 milliseconds) + { + if ( !IsOpened() ) return; + op_pcm_seek(m_FileH, ms2samples(milliseconds) / GetChannels()); + } + + uint32 Tell() + { + if ( !IsOpened() ) return 0; + return samples2ms(op_pcm_tell(m_FileH) * GetChannels()); + } + + uint32 Decode(void *buffer) + { + if ( !IsOpened() ) return 0; + + int size = op_read(m_FileH, (opus_int16 *)buffer, GetBufferSamples(), NULL); + + if (size < 0) + return 0; + + if (GetChannels() == 2) + SortStereoBuffer.SortStereo(buffer, size * m_nChannels * GetSampleSize()); + + return size * m_nChannels * GetSampleSize(); + } +}; +#endif + +void CStream::Initialise() +{ +#ifdef AUDIO_OAL_USE_MPG123 + mpg123_init(); +#endif +} + +void CStream::Terminate() +{ +#ifdef AUDIO_OAL_USE_MPG123 + mpg123_exit(); +#endif +} + +CStream::CStream(char *filename, ALuint *sources, ALuint (&buffers)[NUM_STREAMBUFFERS], uint32 overrideSampleRate) : + m_pAlSources(sources), + m_alBuffers(buffers), + m_pBuffer(nil), + m_bPaused(false), + m_bActive(false), + m_pSoundFile(nil), + m_bReset(false), + m_nVolume(0), + m_nPan(0), + m_nPosBeforeReset(0), + m_nLoopCount(1) + +{ +// Be case-insensitive on linux (from https://github.com/OneSadCookie/fcaseopen/) +#if !defined(_WIN32) + char *real = casepath(filename); + if (real) { + strcpy(m_aFilename, real); + free(real); + } else { +#else + { +#endif + strcpy(m_aFilename, filename); + } + + DEV("Stream %s\n", m_aFilename); + + if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".wav")], ".wav")) +#ifdef AUDIO_OAL_USE_SNDFILE + m_pSoundFile = new CSndFile(m_aFilename); +#else + m_pSoundFile = new CWavFile(m_aFilename); +#endif +#ifdef AUDIO_OAL_USE_MPG123 + else if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".mp3")], ".mp3")) + m_pSoundFile = new CMP3File(m_aFilename); + else if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".adf")], ".adf")) + m_pSoundFile = new CADFFile(m_aFilename); +#endif + else if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".vb")], ".VB")) + m_pSoundFile = new CVbFile(m_aFilename, overrideSampleRate); +#ifdef AUDIO_OAL_USE_OPUS + else if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".opus")], ".opus")) + m_pSoundFile = new COpusFile(m_aFilename); +#endif + else + m_pSoundFile = nil; + + if ( IsOpened() ) + { + m_pBuffer = malloc(m_pSoundFile->GetBufferSize()); + ASSERT(m_pBuffer!=nil); + + DEV("AvgSamplesPerSec: %d\n", m_pSoundFile->GetAvgSamplesPerSec()); + DEV("SampleCount: %d\n", m_pSoundFile->GetSampleCount()); + DEV("SampleRate: %d\n", m_pSoundFile->GetSampleRate()); + DEV("Channels: %d\n", m_pSoundFile->GetChannels()); + DEV("Buffer Samples: %d\n", m_pSoundFile->GetBufferSamples()); + DEV("Buffer sec: %f\n", (float(m_pSoundFile->GetBufferSamples()) / float(m_pSoundFile->GetChannels())/ float(m_pSoundFile->GetSampleRate()))); + DEV("Length MS: %02d:%02d\n", (m_pSoundFile->GetLength() / 1000) / 60, (m_pSoundFile->GetLength() / 1000) % 60); + + return; + } +} + +CStream::~CStream() +{ + Delete(); +} + +void CStream::Delete() +{ + Stop(); + ClearBuffers(); + + if ( m_pSoundFile ) + { + delete m_pSoundFile; + m_pSoundFile = nil; + } + + if ( m_pBuffer ) + { + free(m_pBuffer); + m_pBuffer = nil; + } +} + +bool CStream::HasSource() +{ + return (m_pAlSources[0] != AL_NONE) && (m_pAlSources[1] != AL_NONE); +} + +bool CStream::IsOpened() +{ + return m_pSoundFile && m_pSoundFile->IsOpened(); +} + +bool CStream::IsPlaying() +{ + if ( !HasSource() || !IsOpened() ) return false; + + if ( !m_bPaused ) + { + ALint sourceState[2]; + alGetSourcei(m_pAlSources[0], AL_SOURCE_STATE, &sourceState[0]); + alGetSourcei(m_pAlSources[1], AL_SOURCE_STATE, &sourceState[1]); + if (sourceState[0] == AL_PLAYING || sourceState[1] == AL_PLAYING) + return true; + } + + return false; +} + +void CStream::Pause() +{ + if ( !HasSource() ) return; + ALint sourceState = AL_PAUSED; + alGetSourcei(m_pAlSources[0], AL_SOURCE_STATE, &sourceState); + if (sourceState != AL_PAUSED) + alSourcePause(m_pAlSources[0]); + alGetSourcei(m_pAlSources[1], AL_SOURCE_STATE, &sourceState); + if (sourceState != AL_PAUSED) + alSourcePause(m_pAlSources[1]); +} + +void CStream::SetPause(bool bPause) +{ + if ( !HasSource() ) return; + if ( bPause ) + { + Pause(); + m_bPaused = true; + } + else + { + if (m_bPaused) + SetPlay(true); + m_bPaused = false; + } +} + +void CStream::SetPitch(float pitch) +{ + if ( !HasSource() ) return; + alSourcef(m_pAlSources[0], AL_PITCH, pitch); + alSourcef(m_pAlSources[1], AL_PITCH, pitch); +} + +void CStream::SetGain(float gain) +{ + if ( !HasSource() ) return; + alSourcef(m_pAlSources[0], AL_GAIN, gain); + alSourcef(m_pAlSources[1], AL_GAIN, gain); +} + +void CStream::SetPosition(int i, float x, float y, float z) +{ + if ( !HasSource() ) return; + alSource3f(m_pAlSources[i], AL_POSITION, x, y, z); +} + +void CStream::SetVolume(uint32 nVol) +{ + m_nVolume = nVol; + SetGain(ALfloat(nVol) / MAX_VOLUME); +} + +void CStream::SetPan(uint8 nPan) +{ + m_nPan = clamp((int8)nPan - 63, 0, 63); + SetPosition(0, (m_nPan - 63) / 64.0f, 0.0f, Sqrt(1.0f - SQR((m_nPan - 63) / 64.0f))); + + m_nPan = clamp((int8)nPan + 64, 64, 127); + SetPosition(1, (m_nPan - 63) / 64.0f, 0.0f, Sqrt(1.0f - SQR((m_nPan - 63) / 64.0f))); + + m_nPan = nPan; +} + +// Should only be called if source is stopped +void CStream::SetPosMS(uint32 nPos) +{ + if ( !IsOpened() ) return; + m_pSoundFile->Seek(nPos); + ClearBuffers(); +} + +uint32 CStream::GetPosMS() +{ + if ( !HasSource() ) return 0; + if ( !IsOpened() ) return 0; + + ALint offset; + //alGetSourcei(m_alSource, AL_SAMPLE_OFFSET, &offset); + alGetSourcei(m_pAlSources[0], AL_BYTE_OFFSET, &offset); + + return m_pSoundFile->Tell() + - m_pSoundFile->samples2ms(m_pSoundFile->GetBufferSamples() * (NUM_STREAMBUFFERS/2-1)) / m_pSoundFile->GetChannels() + + m_pSoundFile->samples2ms(offset/m_pSoundFile->GetSampleSize()) / m_pSoundFile->GetChannels(); +} + +uint32 CStream::GetLengthMS() +{ + if ( !IsOpened() ) return 0; + return m_pSoundFile->GetLength(); +} + +bool CStream::FillBuffer(ALuint *alBuffer) +{ + if ( !HasSource() ) + return false; + if ( !IsOpened() ) + return false; + if ( !(alBuffer[0] != AL_NONE && alIsBuffer(alBuffer[0])) ) + return false; + if ( !(alBuffer[1] != AL_NONE && alIsBuffer(alBuffer[1])) ) + return false; + + uint32 size = m_pSoundFile->Decode(m_pBuffer); + if( size == 0 ) + return false; + + uint32 channelSize = size / m_pSoundFile->GetChannels(); + + alBufferData(alBuffer[0], AL_FORMAT_MONO16, m_pBuffer, channelSize, m_pSoundFile->GetSampleRate()); + // TODO: use just one buffer if we play mono + if (m_pSoundFile->GetChannels() == 1) + alBufferData(alBuffer[1], AL_FORMAT_MONO16, m_pBuffer, channelSize, m_pSoundFile->GetSampleRate()); + else + alBufferData(alBuffer[1], AL_FORMAT_MONO16, (uint8*)m_pBuffer + channelSize, channelSize, m_pSoundFile->GetSampleRate()); + return true; +} + +int32 CStream::FillBuffers() +{ + int32 i = 0; + for ( i = 0; i < NUM_STREAMBUFFERS/2; i++ ) + { + if ( !FillBuffer(&m_alBuffers[i*2]) ) + break; + alSourceQueueBuffers(m_pAlSources[0], 1, &m_alBuffers[i*2]); + alSourceQueueBuffers(m_pAlSources[1], 1, &m_alBuffers[i*2+1]); + } + + return i; +} + +void CStream::ClearBuffers() +{ + if ( !HasSource() ) return; + + ALint buffersQueued[2]; + alGetSourcei(m_pAlSources[0], AL_BUFFERS_QUEUED, &buffersQueued[0]); + alGetSourcei(m_pAlSources[1], AL_BUFFERS_QUEUED, &buffersQueued[1]); + + ALuint value; + while (buffersQueued[0]--) + alSourceUnqueueBuffers(m_pAlSources[0], 1, &value); + while (buffersQueued[1]--) + alSourceUnqueueBuffers(m_pAlSources[1], 1, &value); +} + +bool CStream::Setup(bool imSureQueueIsEmpty) +{ + if ( IsOpened() ) + { + alSourcei(m_pAlSources[0], AL_LOOPING, AL_FALSE); + alSourcei(m_pAlSources[1], AL_LOOPING, AL_FALSE); + if (!imSureQueueIsEmpty) { + SetPlay(false); + ClearBuffers(); + } + m_pSoundFile->Seek(0); + //SetPosition(0.0f, 0.0f, 0.0f); + SetPitch(1.0f); + //SetPan(m_nPan); + //SetVolume(100); + } + + return IsOpened(); +} + +void CStream::SetLoopCount(int32 count) +{ + if ( !HasSource() ) return; + + m_nLoopCount = count; +} + +void CStream::SetPlay(bool state) +{ + if ( !HasSource() ) return; + if ( state ) + { + ALint sourceState = AL_PLAYING; + alGetSourcei(m_pAlSources[0], AL_SOURCE_STATE, &sourceState); + if (sourceState != AL_PLAYING ) + alSourcePlay(m_pAlSources[0]); + + sourceState = AL_PLAYING; + alGetSourcei(m_pAlSources[1], AL_SOURCE_STATE, &sourceState); + if (sourceState != AL_PLAYING) + alSourcePlay(m_pAlSources[1]); + + m_bActive = true; + } + else + { + ALint sourceState = AL_STOPPED; + alGetSourcei(m_pAlSources[0], AL_SOURCE_STATE, &sourceState); + if (sourceState != AL_STOPPED ) + alSourceStop(m_pAlSources[0]); + + sourceState = AL_STOPPED; + alGetSourcei(m_pAlSources[1], AL_SOURCE_STATE, &sourceState); + if (sourceState != AL_STOPPED) + alSourceStop(m_pAlSources[1]); + + m_bActive = false; + } +} + +void CStream::Start() +{ + if ( !HasSource() ) return; + if ( FillBuffers() != 0 ) + SetPlay(true); +} + +void CStream::Stop() +{ + if ( !HasSource() ) return; + SetPlay(false); +} + +void CStream::Update() +{ + if ( !IsOpened() ) + return; + + if ( !HasSource() ) + return; + + if ( m_bReset ) + return; + + if ( !m_bPaused ) + { + ALint totalBuffers[2] = { 0, 0 }; + ALint buffersProcessed[2] = { 0, 0 }; + + // Relying a lot on left buffer states in here + + do + { + //alSourcef(m_pAlSources[0], AL_ROLLOFF_FACTOR, 0.0f); + alGetSourcei(m_pAlSources[0], AL_BUFFERS_QUEUED, &totalBuffers[0]); + alGetSourcei(m_pAlSources[0], AL_BUFFERS_PROCESSED, &buffersProcessed[0]); + //alSourcef(m_pAlSources[1], AL_ROLLOFF_FACTOR, 0.0f); + alGetSourcei(m_pAlSources[1], AL_BUFFERS_QUEUED, &totalBuffers[1]); + alGetSourcei(m_pAlSources[1], AL_BUFFERS_PROCESSED, &buffersProcessed[1]); + } while (buffersProcessed[0] != buffersProcessed[1]); + + assert(buffersProcessed[0] == buffersProcessed[1]); + + // Correcting OpenAL concepts here: + // AL_BUFFERS_QUEUED = Number of *all* buffers in queue, including processed, processing and pending + // AL_BUFFERS_PROCESSED = Index of the buffer being processing right now. Buffers coming after that(have greater index) are pending buffers. + // which means: totalBuffers[0] - buffersProcessed[0] = pending buffers + + bool buffersRefilled = false; + + // We should wait queue to be cleared to loop track, because position calculation relies on queue. + if (m_nLoopCount != 1 && m_bActive && totalBuffers[0] == 0) + { + Setup(true); + buffersRefilled = FillBuffers() != 0; + if (m_nLoopCount != 0) + m_nLoopCount--; + } + else + { + while( buffersProcessed[0]-- ) + { + ALuint buffer[2]; + + alSourceUnqueueBuffers(m_pAlSources[0], 1, &buffer[0]); + alSourceUnqueueBuffers(m_pAlSources[1], 1, &buffer[1]); + + if (m_bActive && FillBuffer(buffer)) + { + buffersRefilled = true; + alSourceQueueBuffers(m_pAlSources[0], 1, &buffer[0]); + alSourceQueueBuffers(m_pAlSources[1], 1, &buffer[1]); + } + } + } + + // Two reasons: 1-Source may be starved to audio and stopped itself, 2- We're already waiting it to starve and die for looping track! + if (m_bActive && (buffersRefilled || (totalBuffers[1] - buffersProcessed[1] != 0))) + SetPlay(true); + } +} + +void CStream::ProviderInit() +{ + if ( m_bReset ) + { + if ( Setup(true) ) + { + SetPan(m_nPan); + SetVolume(m_nVolume); + SetLoopCount(m_nLoopCount); + SetPosMS(m_nPosBeforeReset); + if (m_bActive) + FillBuffers(); + SetPlay(m_bActive); + if ( m_bPaused ) + Pause(); + } + + m_bReset = false; + } +} + +void CStream::ProviderTerm() +{ + m_bReset = true; + m_nPosBeforeReset = GetPosMS(); + + ClearBuffers(); +} + +#endif diff --git a/src/audio/oal/stream.h b/src/audio/oal/stream.h new file mode 100644 index 0000000..9a2a2fb --- /dev/null +++ b/src/audio/oal/stream.h @@ -0,0 +1,114 @@ +#pragma once + +#ifdef AUDIO_OAL +#include <AL/al.h> + +#define NUM_STREAMBUFFERS 8 + +class IDecoder +{ +public: + virtual ~IDecoder() { } + + virtual bool IsOpened() = 0; + + virtual uint32 GetSampleSize() = 0; + virtual uint32 GetSampleCount() = 0; + virtual uint32 GetSampleRate() = 0; + virtual uint32 GetChannels() = 0; + + uint32 GetAvgSamplesPerSec() + { + return GetChannels() * GetSampleRate(); + } + + uint32 ms2samples(uint32 ms) + { + return float(ms) / 1000.0f * float(GetSampleRate()); + } + + uint32 samples2ms(uint32 sm) + { + return float(sm) * 1000.0f / float(GetSampleRate()); + } + + uint32 GetBufferSamples() + { + //return (GetAvgSamplesPerSec() >> 2) - (GetSampleCount() % GetChannels()); + return (GetAvgSamplesPerSec() / 4); // 250ms + } + + uint32 GetBufferSize() + { + return GetBufferSamples() * GetSampleSize(); + } + + virtual void Seek(uint32 milliseconds) = 0; + virtual uint32 Tell() = 0; + + uint32 GetLength() + { + return float(GetSampleCount()) * 1000.0f / float(GetSampleRate()); + } + + virtual uint32 Decode(void *buffer) = 0; +}; + +class CStream +{ + char m_aFilename[128]; + ALuint *m_pAlSources; + ALuint (&m_alBuffers)[NUM_STREAMBUFFERS]; + + bool m_bPaused; + bool m_bActive; + + void *m_pBuffer; + + bool m_bReset; + uint32 m_nVolume; + uint8 m_nPan; + uint32 m_nPosBeforeReset; + int32 m_nLoopCount; + + IDecoder *m_pSoundFile; + + bool HasSource(); + void SetPosition(int i, float x, float y, float z); + void SetPitch(float pitch); + void SetGain(float gain); + void Pause(); + void SetPlay(bool state); + + bool FillBuffer(ALuint *alBuffer); + int32 FillBuffers(); + void ClearBuffers(); +public: + static void Initialise(); + static void Terminate(); + + CStream(char *filename, ALuint *sources, ALuint (&buffers)[NUM_STREAMBUFFERS], uint32 overrideSampleRate = 32000); + ~CStream(); + void Delete(); + + bool IsOpened(); + bool IsPlaying(); + void SetPause (bool bPause); + void SetVolume(uint32 nVol); + void SetPan (uint8 nPan); + void SetPosMS (uint32 nPos); + uint32 GetPosMS(); + uint32 GetLengthMS(); + + bool Setup(bool imSureQueueIsEmpty = false); + void Start(); + void Stop(); + void Update(void); + void SetLoopCount(int32); + + + void ProviderInit(); + void ProviderTerm(); +}; + +#endif diff --git a/src/audio/sampman.h b/src/audio/sampman.h new file mode 100644 index 0000000..5d7d39a --- /dev/null +++ b/src/audio/sampman.h @@ -0,0 +1,1611 @@ +#pragma once +#include "AudioSamples.h" + +#define MAX_VOLUME 127 +#define MAX_FREQ DIGITALRATE + +struct tSample { + int32 nOffset; + uint32 nSize; + int32 nFrequency; + int32 nLoopStart; + int32 nLoopEnd; +}; + +#ifdef GTA_PS2 +#define PS2BANK(e) e +#else +#define PS2BANK(e) e = SFX_BANK_0 +#endif // GTA_PS2 + + +enum +{ + SFX_BANK_0, +#ifdef GTA_PS2 + SFX_BANK_GENERIC_EXTRA, + SFX_BANK_PED_COMMENTS, + SFX_BANK_FRONT_END_MENU, +#else + SFX_BANK_GENERIC_EXTRA = SFX_BANK_0, + SFX_BANK_FRONT_END_MENU = SFX_BANK_0, + + SFX_BANK_PED_COMMENTS, + MAX_SFX_BANKS, + INVALID_SFX_BANK, +#endif + + CAR_SFX_BANKS_OFFSET, + SFX_BANK_PONTIAC = CAR_SFX_BANKS_OFFSET, + SFX_BANK_PORSCHE, + SFX_BANK_SPIDER, + SFX_BANK_MERC, + SFX_BANK_TRUCK, + SFX_BANK_HOTROD, + SFX_BANK_COBRA, + SFX_BANK_PONTIAC_SLOW, + SFX_BANK_CADILLAC, + SFX_BANK_PATHFINDER, + SFX_BANK_PACARD, + SFX_BANK_GOLF_CART, + SFX_BANK_CAR_CHAINSAW, + SFX_BANK_RC, + SFX_BANK_RC_HELI, + SFX_BANK_CAR_UNUSED_4, + + // bikes + SFX_BANK_VTWIN, + SFX_BANK_MOPED, + SFX_BANK_HONDA250, + SFX_BANK_SPORTS_BIKE, + SFX_BANK_BIKE_UNUSED_1, + SFX_BANK_BIKE_UNUSED_2, + SFX_BANK_BIKE_UNUSED_3, + SFX_BANK_BIKE_UNUSED_4, + SFX_BANK_BIKE_UNUSED_5, + SFX_BANK_BIKE_UNUSED_6, + + // heli + SFX_BANK_HELI_APACHE, + SFX_BANK_HELI_UNUSED_1, + SFX_BANK_HELI_UNUSED_2, + SFX_BANK_HELI_UNUSED_3, + SFX_BANK_HELI_UNUSED_4, + + // plane + SFX_BANK_PLANE_SEAPLANE, + SFX_BANK_PLANE_UNUSED_1, + SFX_BANK_PLANE_UNUSED_2, + SFX_BANK_PLANE_UNUSED_3, + SFX_BANK_PLANE_UNUSED_4, + PS2BANK(SFX_BANK_BUILDING_BANK_ALARM), + PS2BANK(SFX_BANK_BUILDING_SNORING), + PS2BANK(SFX_BANK_BUILDING_BAR_1), + PS2BANK(SFX_BANK_BUILDING_BAR_2), + PS2BANK(SFX_BANK_BUILDING_BAR_3), + PS2BANK(SFX_BANK_BUILDING_BAR_4), + PS2BANK(SFX_BANK_BUILDING_MALIBU_1), + PS2BANK(SFX_BANK_BUILDING_MALIBU_2), + PS2BANK(SFX_BANK_BUILDING_MALIBU_3), + PS2BANK(SFX_BANK_BUILDING_STRIP_1), + PS2BANK(SFX_BANK_BUILDING_STRIP_2), + PS2BANK(SFX_BANK_BUILDING_STRIP_3), + PS2BANK(SFX_BANK_BUILDING_CHURCH), + PS2BANK(SFX_BANK_BUILDING_FAN_1), + PS2BANK(SFX_BANK_BUILDING_FAN_2), + PS2BANK(SFX_BANK_BUILDING_INSECT_1), + PS2BANK(SFX_BANK_BUILDING_INSECT_2), + PS2BANK(SFX_BANK_BUILDING_18), + PS2BANK(SFX_BANK_BUILDING_19), + PS2BANK(SFX_BANK_BUILDING_20), + PS2BANK(SFX_BANK_BUILDING_21), + PS2BANK(SFX_BANK_FOOTSTEPS_GRASS), + PS2BANK(SFX_BANK_FOOTSTEPS_GRAVEL), + PS2BANK(SFX_BANK_FOOTSTEPS_WOOD), + PS2BANK(SFX_BANK_FOOTSTEPS_METAL), + PS2BANK(SFX_BANK_FOOTSTEPS_WATER), + PS2BANK(SFX_BANK_FOOTSTEPS_SAND), +#ifdef GTA_PS2 + MAX_SFX_BANKS, + INVALID_SFX_BANK +#endif +}; +#define MAX_PEDSFX 7 +#define PED_BLOCKSIZE 79000 + +#define MAXPROVIDERS 64 + +#define MAXCHANNELS 28 +#define MAXCHANNELS_SURROUND 24 +#define MAX2DCHANNELS 1 +#define CHANNEL2D MAXCHANNELS + +#define MAX_STREAMS 3 + +#define DIGITALRATE 32000 +#define DIGITALBITS 16 +#define DIGITALCHANNELS 2 + +#define MAX_DIGITAL_MIXER_CHANNELS 32 + +class cSampleManager +{ + uint8 m_nEffectsVolume; + uint8 m_nMusicVolume; + uint8 m_nMP3BoostVolume; + uint8 m_nEffectsFadeVolume; + uint8 m_nMusicFadeVolume; + uint8 m_nMonoMode; + char m_szCDRomRootPath[80]; + bool m_bInitialised; + uint8 m_nNumberOfProviders; + char *m_aAudioProviders[MAXPROVIDERS]; + tSample m_aSamples[TOTAL_AUDIO_SAMPLES]; + char m_MiscomPath[260]; + char m_WavFilesPath[260]; + char m_MP3FilesPath[188]; + void *m_aChannels[18]; + +public: + + + + cSampleManager(void); + ~cSampleManager(void); + + void SetSpeakerConfig(int32 nConfig); + uint32 GetMaximumSupportedChannels(void); + + uint32 GetNum3DProvidersAvailable(void); + void SetNum3DProvidersAvailable(uint32 num); + + char *Get3DProviderName(uint8 id); + void Set3DProviderName(uint8 id, char *name); + + int8 GetCurrent3DProviderIndex(void); + int8 SetCurrent3DProvider(uint8 which); + + int8 AutoDetect3DProviders(); + + bool IsMP3RadioChannelAvailable(void); + + void ReleaseDigitalHandle (void); + void ReacquireDigitalHandle(void); + + bool Initialise(void); + void Terminate (void); + + bool CheckForAnAudioFileOnCD(void); + char GetCDAudioDriveLetter (void); + + void UpdateEffectsVolume(void); + + void SetEffectsMasterVolume(uint8 nVolume); + void SetMusicMasterVolume (uint8 nVolume); + void SetMP3BoostVolume (uint8 nVolume); + void SetEffectsFadeVolume (uint8 nVolume); + void SetMusicFadeVolume (uint8 nVolume); + void SetMonoMode (uint8 nMode); + + bool LoadSampleBank (uint8 nBank); + void UnloadSampleBank (uint8 nBank); + bool IsSampleBankLoaded(uint8 nBank); + + bool IsPedCommentLoaded(uint32 nComment); + bool LoadPedComment (uint32 nComment); + int32 GetBankContainingSound(uint32 offset); + + int32 _GetPedCommentSlot(uint32 nComment); + + int32 GetSampleBaseFrequency (uint32 nSample); + int32 GetSampleLoopStartOffset(uint32 nSample); + int32 GetSampleLoopEndOffset (uint32 nSample); + uint32 GetSampleLength (uint32 nSample); + + bool UpdateReverb(void); + + void SetChannelReverbFlag (uint32 nChannel, uint8 nReverbFlag); + bool InitialiseChannel (uint32 nChannel, uint32 nSfx, uint8 nBank); + void SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume); + void SetChannel3DPosition (uint32 nChannel, float fX, float fY, float fZ); + void SetChannel3DDistances (uint32 nChannel, float fMax, float fMin); + void SetChannelVolume (uint32 nChannel, uint32 nVolume); + void SetChannelPan (uint32 nChannel, uint32 nPan); + void SetChannelFrequency (uint32 nChannel, uint32 nFreq); + void SetChannelLoopPoints (uint32 nChannel, uint32 nLoopStart, int32 nLoopEnd); + void SetChannelLoopCount (uint32 nChannel, uint32 nLoopCount); + bool GetChannelUsedFlag (uint32 nChannel); + void StartChannel (uint32 nChannel); + void StopChannel (uint32 nChannel); + + void PreloadStreamedFile (uint32 nFile, uint8 nStream); + void PauseStream (uint8 nPauseFlag, uint8 nStream); + void StartPreloadedStreamedFile (uint8 nStream); + bool StartStreamedFile (uint32 nFile, uint32 nPos, uint8 nStream); + void StopStreamedFile (uint8 nStream); + int32 GetStreamedFilePosition (uint8 nStream); + void SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream); + int32 GetStreamedFileLength (uint8 nStream); + bool IsStreamPlaying (uint8 nStream); +#ifdef AUDIO_OAL + void Service(void); +#endif + bool InitialiseSampleBanks(void); + + uint8 GetMusicVolume() const { return m_nMusicVolume; } + void SetStreamedFileLoopFlag(uint8 nLoopFlag, uint8 nStream); +}; + +extern cSampleManager SampleManager; +extern uint32 BankStartOffset[MAX_SFX_BANKS]; + +#if defined(OPUS_AUDIO_PATHS) +static char StreamedNameTable[][25] = { + "AUDIO\\HEAD.OPUS", "AUDIO\\CLASS.OPUS", "AUDIO\\KJAH.OPUS", "AUDIO\\RISE.OPUS", "AUDIO\\LIPS.OPUS", "AUDIO\\GAME.OPUS", + "AUDIO\\MSX.OPUS", "AUDIO\\FLASH.OPUS", "AUDIO\\CHAT.OPUS", "AUDIO\\HEAD.OPUS", "AUDIO\\POLICE.OPUS", "AUDIO\\CITY.OPUS", + "AUDIO\\WATER.OPUS", "AUDIO\\COMOPEN.OPUS", "AUDIO\\SUBOPEN.OPUS", "AUDIO\\JB.OPUS", "AUDIO\\BET.OPUS", "AUDIO\\L1_LG.OPUS", + "AUDIO\\L2_DSB.OPUS", "AUDIO\\L3_DM.OPUS", "AUDIO\\L4_PAP.OPUS", "AUDIO\\L5_TFB.OPUS", "AUDIO\\J0_DM2.OPUS", "AUDIO\\J1_LFL.OPUS", + "AUDIO\\J2_KCL.OPUS", "AUDIO\\J3_VH.OPUS", "AUDIO\\J4_ETH.OPUS", "AUDIO\\J5_DST.OPUS", "AUDIO\\J6_TBJ.OPUS", "AUDIO\\T1_TOL.OPUS", + "AUDIO\\T2_TPU.OPUS", "AUDIO\\T3_MAS.OPUS", "AUDIO\\T4_TAT.OPUS", "AUDIO\\T5_BF.OPUS", "AUDIO\\S0_MAS.OPUS", "AUDIO\\S1_PF.OPUS", + "AUDIO\\S2_CTG.OPUS", "AUDIO\\S3_RTC.OPUS", "AUDIO\\S5_LRQ.OPUS", "AUDIO\\S4_BDBA.OPUS", "AUDIO\\S4_BDBB.OPUS", "AUDIO\\S2_CTG2.OPUS", + "AUDIO\\S4_BDBD.OPUS", "AUDIO\\S5_LRQB.OPUS", "AUDIO\\S5_LRQC.OPUS", "AUDIO\\A1_SSO.OPUS", "AUDIO\\A2_PP.OPUS", "AUDIO\\A3_SS.OPUS", + "AUDIO\\A4_PDR.OPUS", "AUDIO\\A5_K2FT.OPUS", "AUDIO\\K1_KBO.OPUS", "AUDIO\\K2_GIS.OPUS", "AUDIO\\K3_DS.OPUS", "AUDIO\\K4_SHI.OPUS", + "AUDIO\\K5_SD.OPUS", "AUDIO\\R0_PDR2.OPUS", "AUDIO\\R1_SW.OPUS", "AUDIO\\R2_AP.OPUS", "AUDIO\\R3_ED.OPUS", "AUDIO\\R4_GF.OPUS", + "AUDIO\\R5_PB.OPUS", "AUDIO\\R6_MM.OPUS", "AUDIO\\D1_STOG.OPUS", "AUDIO\\D2_KK.OPUS", "AUDIO\\D3_ADO.OPUS", "AUDIO\\D5_ES.OPUS", + "AUDIO\\D7_MLD.OPUS", "AUDIO\\D4_GTA.OPUS", "AUDIO\\D4_GTA2.OPUS", "AUDIO\\D6_STS.OPUS", "AUDIO\\A6_BAIT.OPUS", "AUDIO\\A7_ETG.OPUS", + "AUDIO\\A8_PS.OPUS", "AUDIO\\A9_ASD.OPUS", "AUDIO\\K4_SHI2.OPUS", "AUDIO\\C1_TEX.OPUS", "AUDIO\\EL_PH1.OPUS", "AUDIO\\EL_PH2.OPUS", + "AUDIO\\EL_PH3.OPUS", "AUDIO\\EL_PH4.OPUS", "AUDIO\\YD_PH1.OPUS", "AUDIO\\YD_PH2.OPUS", "AUDIO\\YD_PH3.OPUS", "AUDIO\\YD_PH4.OPUS", + "AUDIO\\HD_PH1.OPUS", "AUDIO\\HD_PH2.OPUS", "AUDIO\\HD_PH3.OPUS", "AUDIO\\HD_PH4.OPUS", "AUDIO\\HD_PH5.OPUS", "AUDIO\\MT_PH1.OPUS", + "AUDIO\\MT_PH2.OPUS", "AUDIO\\MT_PH3.OPUS", "AUDIO\\MT_PH4.OPUS", "AUDIO\\MISCOM.OPUS", "AUDIO\\END.OPUS", "AUDIO\\lib_a1.OPUS", + "AUDIO\\lib_a2.OPUS", "AUDIO\\lib_a.OPUS", "AUDIO\\lib_b.OPUS", "AUDIO\\lib_c.OPUS", "AUDIO\\lib_d.OPUS", "AUDIO\\l2_a.OPUS", + "AUDIO\\j4t_1.OPUS", "AUDIO\\j4t_2.OPUS", "AUDIO\\j4t_3.OPUS", "AUDIO\\j4t_4.OPUS", "AUDIO\\j4_a.OPUS", "AUDIO\\j4_b.OPUS", + "AUDIO\\j4_c.OPUS", "AUDIO\\j4_d.OPUS", "AUDIO\\j4_e.OPUS", "AUDIO\\j4_f.OPUS", "AUDIO\\j6_1.OPUS", "AUDIO\\j6_a.OPUS", + "AUDIO\\j6_b.OPUS", "AUDIO\\j6_c.OPUS", "AUDIO\\j6_d.OPUS", "AUDIO\\t4_a.OPUS", "AUDIO\\s1_a.OPUS", "AUDIO\\s1_a1.OPUS", + "AUDIO\\s1_b.OPUS", "AUDIO\\s1_c.OPUS", "AUDIO\\s1_c1.OPUS", "AUDIO\\s1_d.OPUS", "AUDIO\\s1_e.OPUS", "AUDIO\\s1_f.OPUS", + "AUDIO\\s1_g.OPUS", "AUDIO\\s1_h.OPUS", "AUDIO\\s1_i.OPUS", "AUDIO\\s1_j.OPUS", "AUDIO\\s1_k.OPUS", "AUDIO\\s1_l.OPUS", + "AUDIO\\s3_a.OPUS", "AUDIO\\s3_b.OPUS", "AUDIO\\el3_a.OPUS", "AUDIO\\mf1_a.OPUS", "AUDIO\\mf2_a.OPUS", "AUDIO\\mf3_a.OPUS", + "AUDIO\\mf3_b.OPUS", "AUDIO\\mf3_b1.OPUS", "AUDIO\\mf3_c.OPUS", "AUDIO\\mf4_a.OPUS", "AUDIO\\mf4_b.OPUS", "AUDIO\\mf4_c.OPUS", + "AUDIO\\a1_a.OPUS", "AUDIO\\a3_a.OPUS", "AUDIO\\a5_a.OPUS", "AUDIO\\a4_a.OPUS", "AUDIO\\a4_b.OPUS", "AUDIO\\a4_c.OPUS", + "AUDIO\\a4_d.OPUS", "AUDIO\\k1_a.OPUS", "AUDIO\\k3_a.OPUS", "AUDIO\\r1_a.OPUS", "AUDIO\\r2_a.OPUS", "AUDIO\\r2_b.OPUS", + "AUDIO\\r2_c.OPUS", "AUDIO\\r2_d.OPUS", "AUDIO\\r2_e.OPUS", "AUDIO\\r2_f.OPUS", "AUDIO\\r2_g.OPUS", "AUDIO\\r2_h.OPUS", + "AUDIO\\r5_a.OPUS", "AUDIO\\r6_a.OPUS", "AUDIO\\r6_a1.OPUS", "AUDIO\\r6_b.OPUS", "AUDIO\\lo2_a.OPUS", "AUDIO\\lo6_a.OPUS", + "AUDIO\\yd2_a.OPUS", "AUDIO\\yd2_b.OPUS", "AUDIO\\yd2_c.OPUS", "AUDIO\\yd2_c1.OPUS", "AUDIO\\yd2_d.OPUS", "AUDIO\\yd2_e.OPUS", + "AUDIO\\yd2_f.OPUS", "AUDIO\\yd2_g.OPUS", "AUDIO\\yd2_h.OPUS", "AUDIO\\yd2_ass.OPUS", "AUDIO\\yd2_ok.OPUS", "AUDIO\\h5_a.OPUS", + "AUDIO\\h5_b.OPUS", "AUDIO\\h5_c.OPUS", "AUDIO\\ammu_a.OPUS", "AUDIO\\ammu_b.OPUS", "AUDIO\\ammu_c.OPUS", "AUDIO\\door_1.OPUS", + "AUDIO\\door_2.OPUS", "AUDIO\\door_3.OPUS", "AUDIO\\door_4.OPUS", "AUDIO\\door_5.OPUS", "AUDIO\\door_6.OPUS", "AUDIO\\t3_a.OPUS", + "AUDIO\\t3_b.OPUS", "AUDIO\\t3_c.OPUS", "AUDIO\\k1_b.OPUS", "AUDIO\\cat1.OPUS"}; +#elif defined(PS2_AUDIO_PATHS) +static char StreamedNameTable[][40] = +{ + "AUDIO\\MUSIC\\WILD.VB", + "AUDIO\\MUSIC\\FLASH.VB", + "AUDIO\\MUSIC\\KCHAT.VB", // 16 khz + "AUDIO\\MUSIC\\FEVER.VB", + "AUDIO\\MUSIC\\VROCK.VB", + "AUDIO\\MUSIC\\VCPR.VB", // 16 khz + "AUDIO\\MUSIC\\ESPANT.VB", + "AUDIO\\MUSIC\\EMOTION.VB", + "AUDIO\\MUSIC\\WAVE.VB", + "AUDIO\\MUSIC\\MISCOM.VB", + "AUDIO\\MUSIC\\CITY.VB", + "AUDIO\\MUSIC\\WATER.VB", + "AUDIO\\MUSIC\\BEACHAMB.VB", + "AUDIO\\MUSIC\\HCITY.VB", + "AUDIO\\MUSIC\\HWATER.VB", + "AUDIO\\MUSIC\\HBEACH.VB", + "AUDIO\\MUSIC\\MALLAMB.VB", + "AUDIO\\MUSIC\\STRIP.VB", + "AUDIO\\MUSIC\\MALIBU.VB", + "AUDIO\\MUSIC\\HOTEL.VB", + "AUDIO\\MUSIC\\DIRTRING.VB", + "AUDIO\\MUSIC\\LAW4RIOT.VB", + "AUDIO\\MUSIC\\AMBSIL.VB", + "AUDIO\\MUSIC\\POLICE.VB", // 16 khz + "AUDIO\\MUSIC\\TAXI.VB", + "AUDIO\\MUSIC\\BCLOSED.VB", + "AUDIO\\MUSIC\\BOPEN.VB", + "AUDIO\\CUTSCENE\\ASS\\ASS_1.VB", + "AUDIO\\CUTSCENE\\ASS\\ASS_2.VB", + "AUDIO\\CUTSCENE\\BANK\\BANK_1.VB", + "AUDIO\\CUTSCENE\\BANK\\BANK_2A.VB", + "AUDIO\\CUTSCENE\\BANK\\BANK_2B.VB", + "AUDIO\\CUTSCENE\\BANK\\BANK_3A.VB", + "AUDIO\\CUTSCENE\\BANK\\BANK_3B.VB", + "AUDIO\\CUTSCENE\\BANK\\BANK_4.VB", + "AUDIO\\CUTSCENE\\BIKE\\BIKE_1.VB", + "AUDIO\\CUTSCENE\\BIKE\\BIKE_2.VB", + "AUDIO\\CUTSCENE\\BIKE\\BIKE_3.VB", + "AUDIO\\CUTSCENE\\BUD\\BUD_1.VB", + "AUDIO\\CUTSCENE\\BUD\\BUD_2.VB", + "AUDIO\\CUTSCENE\\BUD\\BUD_3.VB", + "AUDIO\\CUTSCENE\\CAP\\CAP_1.VB", + "AUDIO\\CUTSCENE\\CAR\\CAR_1.VB", + "AUDIO\\CUTSCENE\\CNT\\CNT_1A.VB", + "AUDIO\\CUTSCENE\\CNT\\CNT_1B.VB", + "AUDIO\\CUTSCENE\\CNT\\CNT_2.VB", + "AUDIO\\CUTSCENE\\COK\\COK_1.VB", + "AUDIO\\CUTSCENE\\COK\\COK_2A.VB", + "AUDIO\\CUTSCENE\\COK\\COK_2B.VB", + "AUDIO\\CUTSCENE\\COK\\COK_3.VB", + "AUDIO\\CUTSCENE\\COK\\COK_4A.VB", + "AUDIO\\CUTSCENE\\COK\\COK_4A2.VB", + "AUDIO\\CUTSCENE\\COK\\COK_4B.VB", + "AUDIO\\CUTSCENE\\COL\\COL_1.VB", + "AUDIO\\CUTSCENE\\COL\\COL_2.VB", + "AUDIO\\CUTSCENE\\COL\\COL_3A.VB", + "AUDIO\\CUTSCENE\\COL\\COL_4A.VB", + "AUDIO\\CUTSCENE\\COL\\COL_5A.VB", + "AUDIO\\CUTSCENE\\COL\\COL_5B.VB", + "AUDIO\\CUTSCENE\\CUB\\CUB_1.VB", + "AUDIO\\CUTSCENE\\CUB\\CUB_2.VB", + "AUDIO\\CUTSCENE\\CUB\\CUB_3.VB", + "AUDIO\\CUTSCENE\\CUB\\CUB_4.VB", + "AUDIO\\CUTSCENE\\DRUG\\DRUG_1.VB", + "AUDIO\\CUTSCENE\\FIN\\FIN.VB", + "AUDIO\\CUTSCENE\\FIN\\FIN2.VB", + "AUDIO\\CUTSCENE\\FINALE\\FINALE.VB", + "AUDIO\\CUTSCENE\\HAT\\HAT_1.VB", + "AUDIO\\CUTSCENE\\HAT\\HAT_2.VB", + "AUDIO\\CUTSCENE\\HAT\\HAT_3.VB", + "AUDIO\\CUTSCENE\\ICE\\ICE_1.VB", + "AUDIO\\CUTSCENE\\INT\\INT_A.VB", + "AUDIO\\CUTSCENE\\INT\\INT_B.VB", + "AUDIO\\CUTSCENE\\INT\\INT_D.VB", + "AUDIO\\CUTSCENE\\INT\\INT_M.VB", + "AUDIO\\CUTSCENE\\LAW\\LAW_1A.VB", + "AUDIO\\CUTSCENE\\LAW\\LAW_1B.VB", + "AUDIO\\CUTSCENE\\LAW\\LAW_2A.VB", + "AUDIO\\CUTSCENE\\LAW\\LAW_2B.VB", + "AUDIO\\CUTSCENE\\LAW\\LAW_2C.VB", + "AUDIO\\CUTSCENE\\LAW\\LAW_3.VB", + "AUDIO\\CUTSCENE\\LAW\\LAW_4.VB", + "AUDIO\\CUTSCENE\\PHIL\\PHIL_1.VB", + "AUDIO\\CUTSCENE\\PHIL\\PHIL_2.VB", + "AUDIO\\CUTSCENE\\PORN\\PORN_1.VB", + "AUDIO\\CUTSCENE\\PORN\\PORN_2.VB", + "AUDIO\\CUTSCENE\\PORN\\PORN_3.VB", + "AUDIO\\CUTSCENE\\PORN\\PORN_4.VB", + "AUDIO\\CUTSCENE\\RESC\\RESC_1A.VB", + "AUDIO\\CUTSCENE\\ROK\\ROK_1.VB", + "AUDIO\\CUTSCENE\\ROK\\ROK_2.VB", + "AUDIO\\CUTSCENE\\ROK\\ROK_3A.VB", + "AUDIO\\CUTSCENE\\STRIPA\\STRIPA.VB", + "AUDIO\\CUTSCENE\\TAX\\TAX_1.VB", + "AUDIO\\CUTSCENE\\TEX\\TEX_1.VB", + "AUDIO\\CUTSCENE\\TEX\\TEX_2.VB", + "AUDIO\\CUTSCENE\\TEX\\TEX_3.VB", + "AUDIO\\MUSIC\\GLIGHT.VB", + "AUDIO\\MUSIC\\FIST.VB", + "AUDIO\\MUSIC\\MISCOM.VB", + "AUDIO\\MUSIC\\MISCOM.VB", + "AUDIO\\MUSIC\\MISCOM.VB", + "AUDIO\\MUSIC\\MISCOM.VB", +#else +static char StreamedNameTable[][25] = +{ + "AUDIO\\WILD.ADF", + "AUDIO\\FLASH.ADF", + "AUDIO\\KCHAT.ADF", + "AUDIO\\FEVER.ADF", + "AUDIO\\VROCK.ADF", + "AUDIO\\VCPR.ADF", + "AUDIO\\ESPANT.ADF", + "AUDIO\\EMOTION.ADF", + "AUDIO\\WAVE.ADF", + "AUDIO\\MISCOM.MP3", + "AUDIO\\CITY.MP3", + "AUDIO\\WATER.MP3", + "AUDIO\\BEACHAMB.MP3", + "AUDIO\\HCITY.MP3", + "AUDIO\\HWATER.MP3", + "AUDIO\\HBEACH.MP3", + "AUDIO\\MALLAMB.MP3", + "AUDIO\\STRIP.MP3", + "AUDIO\\MALIBU.MP3", + "AUDIO\\HOTEL.MP3", + "AUDIO\\DIRTRING.MP3", + "AUDIO\\LAW4RIOT.MP3", + "AUDIO\\AMBSIL.MP3", + "AUDIO\\POLICE.MP3", + "AUDIO\\TAXI.MP3", + "AUDIO\\BCLOSED.MP3", + "AUDIO\\BOPEN.MP3", + "AUDIO\\ASS_1.MP3", + "AUDIO\\ASS_2.MP3", + "AUDIO\\BANK_1.MP3", + "AUDIO\\BANK_2A.MP3", + "AUDIO\\BANK_2B.MP3", + "AUDIO\\BANK_3A.MP3", + "AUDIO\\BANK_3B.MP3", + "AUDIO\\BANK_4.MP3", + "AUDIO\\BIKE_1.MP3", + "AUDIO\\BIKE_2.MP3", + "AUDIO\\BIKE_3.MP3", + "AUDIO\\BUD_1.MP3", + "AUDIO\\BUD_2.MP3", + "AUDIO\\BUD_3.MP3", + "AUDIO\\CAP_1.MP3", + "AUDIO\\CAR_1.MP3", + "AUDIO\\CNT_1A.MP3", + "AUDIO\\CNT_1B.MP3", + "AUDIO\\CNT_2.MP3", + "AUDIO\\COK_1.MP3", + "AUDIO\\COK_2A.MP3", + "AUDIO\\COK_2B.MP3", + "AUDIO\\COK_3.MP3", + "AUDIO\\COK_4A.MP3", + "AUDIO\\COK_4A2.MP3", + "AUDIO\\COK_4B.MP3", + "AUDIO\\COL_1.MP3", + "AUDIO\\COL_2.MP3", + "AUDIO\\COL_3A.MP3", + "AUDIO\\COL_4A.MP3", + "AUDIO\\COL_5A.MP3", + "AUDIO\\COL_5B.MP3", + "AUDIO\\CUB_1.MP3", + "AUDIO\\CUB_2.MP3", + "AUDIO\\CUB_3.MP3", + "AUDIO\\CUB_4.MP3", + "AUDIO\\DRUG_1.MP3", + "AUDIO\\FIN.MP3", + "AUDIO\\FIN2.MP3", + "AUDIO\\FINALE.MP3", + "AUDIO\\HAT_1.MP3", + "AUDIO\\HAT_2.MP3", + "AUDIO\\HAT_3.MP3", + "AUDIO\\ICE_1.MP3", + "AUDIO\\INT_A.MP3", + "AUDIO\\INT_B.MP3", + "AUDIO\\INT_D.MP3", + "AUDIO\\INT_M.MP3", + "AUDIO\\LAW_1A.MP3", + "AUDIO\\LAW_1B.MP3", + "AUDIO\\LAW_2A.MP3", + "AUDIO\\LAW_2B.MP3", + "AUDIO\\LAW_2C.MP3", + "AUDIO\\LAW_3.MP3", + "AUDIO\\LAW_4.MP3", + "AUDIO\\PHIL_1.MP3", + "AUDIO\\PHIL_2.MP3", + "AUDIO\\PORN_1.MP3", + "AUDIO\\PORN_2.MP3", + "AUDIO\\PORN_3.MP3", + "AUDIO\\PORN_4.MP3", + "AUDIO\\RESC_1A.MP3", + "AUDIO\\ROK_1.MP3", + "AUDIO\\ROK_2.MP3", + "AUDIO\\ROK_3A.MP3", + "AUDIO\\STRIPA.MP3", + "AUDIO\\TAX_1.MP3", + "AUDIO\\TEX_1.MP3", + "AUDIO\\TEX_2.MP3", + "AUDIO\\TEX_3.MP3", + "AUDIO\\GLIGHT.MP3", + "AUDIO\\FIST.MP3", + "AUDIO\\MISCOM.MP3", + "AUDIO\\MISCOM.MP3", + "AUDIO\\MISCOM.MP3", + "AUDIO\\MISCOM.MP3", +#endif + "AUDIO\\MOBR1.WAV", + "AUDIO\\PAGER.WAV", + "AUDIO\\CARREV.WAV", + "AUDIO\\BIKEREV.WAV", + "AUDIO\\LIFTOP.WAV", + "AUDIO\\LIFTCL.WAV", + "AUDIO\\LIFTRUN.WAV", + "AUDIO\\LIFTBEL.WAV", + "AUDIO\\INLIFT.WAV", + "AUDIO\\SFX_01.WAV", + "AUDIO\\SFX_02.WAV", + "AUDIO\\CAMERAL.WAV", + "AUDIO\\CAMERAR.WAV", + "AUDIO\\CHEER1.WAV", + "AUDIO\\CHEER2.WAV", + "AUDIO\\CHEER3.WAV", + "AUDIO\\CHEER4.WAV", + "AUDIO\\OOH1.WAV", + "AUDIO\\OOH2.WAV", + "AUDIO\\RACE1.WAV", + "AUDIO\\RACE2.WAV", + "AUDIO\\RACE3.WAV", + "AUDIO\\RACE4.WAV", + "AUDIO\\RACE5.WAV", + "AUDIO\\RACE6.WAV", + "AUDIO\\RACE7.WAV", + "AUDIO\\RACE8.WAV", + "AUDIO\\RACE9.WAV", + "AUDIO\\RACE10.WAV", + "AUDIO\\RACE11.WAV", + "AUDIO\\RACE12.WAV", + "AUDIO\\RACE13.WAV", + "AUDIO\\RACE14.WAV", + "AUDIO\\RACE15.WAV", + "AUDIO\\HOT1.WAV", + "AUDIO\\HOT2.WAV", + "AUDIO\\HOT3.WAV", + "AUDIO\\HOT4.WAV", + "AUDIO\\HOT5.WAV", + "AUDIO\\HOT6.WAV", + "AUDIO\\HOT7.WAV", + "AUDIO\\HOT8.WAV", + "AUDIO\\HOT9.WAV", + "AUDIO\\HOT10.WAV", + "AUDIO\\HOT11.WAV", + "AUDIO\\HOT12.WAV", + "AUDIO\\HOT13.WAV", + "AUDIO\\HOT14.WAV", + "AUDIO\\HOT15.WAV", + "AUDIO\\LANSTP1.WAV", + "AUDIO\\LANSTP2.WAV", + "AUDIO\\LANAMU1.WAV", + "AUDIO\\LANAMU2.WAV", + "AUDIO\\AIRHORNL.WAV", + "AUDIO\\AIRHORNR.WAV", + "AUDIO\\SNIPSCRL.WAV", + "AUDIO\\SNIPSHORT.WAV", + "AUDIO\\BLOWROOF.WAV", + "AUDIO\\ASS_1.WAV", + "AUDIO\\ASS_2.WAV", + "AUDIO\\ASS_3.WAV", + "AUDIO\\ASS_4.WAV", + "AUDIO\\ASS_5.WAV", + "AUDIO\\ASS_6.WAV", + "AUDIO\\ASS_7.WAV", + "AUDIO\\ASS_8.WAV", + "AUDIO\\ASS_9.WAV", + "AUDIO\\ASS_10.WAV", + "AUDIO\\ASS_11.WAV", + "AUDIO\\ASS_12.WAV", + "AUDIO\\ASS_13.WAV", + "AUDIO\\ASS_14.WAV", + "AUDIO\\BIKE1_1.WAV", + "AUDIO\\BIKE1_2.WAV", + "AUDIO\\BIKE1_3.WAV", + "AUDIO\\BNK1_1.WAV", + "AUDIO\\BNK1_2.WAV", + "AUDIO\\BNK1_3.WAV", + "AUDIO\\BNK1_4.WAV", + "AUDIO\\BNK1_5.WAV", + "AUDIO\\BNK1_6.WAV", + "AUDIO\\BNK1_7.WAV", + "AUDIO\\BNK1_8.WAV", + "AUDIO\\BNK1_10.WAV", + "AUDIO\\BNK1_11.WAV", + "AUDIO\\BNK1_12.WAV", + "AUDIO\\BNK1_13.WAV", + "AUDIO\\BNK1_14.WAV", + "AUDIO\\BNK2_1.WAV", + "AUDIO\\BNK2_2.WAV", + "AUDIO\\BNK2_3.WAV", + "AUDIO\\BNK2_4.WAV", + "AUDIO\\BNK2_5.WAV", + "AUDIO\\BNK2_6.WAV", + "AUDIO\\BNK2_7.WAV", + "AUDIO\\BNK2_8.WAV", + "AUDIO\\BNK2_9.WAV", + "AUDIO\\BNK3_1.WAV", + "AUDIO\\BNK3_2.WAV", + "AUDIO\\BNK3_3A.WAV", + "AUDIO\\BNK3_3B.WAV", + "AUDIO\\BNK3_3C.WAV", + "AUDIO\\BNK3_4A.WAV", + "AUDIO\\BNK3_4B.WAV", + "AUDIO\\BNK3_4C.WAV", + "AUDIO\\BNK4_1.WAV", + "AUDIO\\BNK4_2.WAV", + "AUDIO\\BNK4_3A.WAV", + "AUDIO\\BNK4_3B.WAV", + "AUDIO\\BNK4_3C.WAV", + "AUDIO\\BNK4_3D.WAV", + "AUDIO\\BNK4_3E.WAV", + "AUDIO\\BNK4_3F.WAV", + "AUDIO\\BNK4_3G.WAV", + "AUDIO\\BNK4_3H.WAV", + "AUDIO\\BNK4_3I.WAV", + "AUDIO\\BNK4_3J.WAV", + "AUDIO\\BNK4_3K.WAV", + "AUDIO\\BNK4_3M.WAV", + "AUDIO\\BNK4_3O.WAV", + "AUDIO\\BNK4_3P.WAV", + "AUDIO\\BNK4_3Q.WAV", + "AUDIO\\BNK4_3R.WAV", + "AUDIO\\BNK4_3S.WAV", + "AUDIO\\BNK4_3T.WAV", + "AUDIO\\BNK4_3U.WAV", + "AUDIO\\BNK4_3V.WAV", + "AUDIO\\BNK4_4A.WAV", + "AUDIO\\BNK4_4B.WAV", + "AUDIO\\BNK4_5.WAV", + "AUDIO\\BNK4_6.WAV", + "AUDIO\\BNK4_7.WAV", + "AUDIO\\BNK4_8.WAV", + "AUDIO\\BNK4_9.WAV", + "AUDIO\\BNK4_10.WAV", + "AUDIO\\BNK4_11.WAV", + "AUDIO\\BK4_12A.WAV", + "AUDIO\\BK4_12B.WAV", + "AUDIO\\BK4_12C.WAV", + "AUDIO\\BNK4_13.WAV", + "AUDIO\\BK4_14A.WAV", + "AUDIO\\BK4_14B.WAV", + "AUDIO\\BNK4_15.WAV", + "AUDIO\\BNK4_16.WAV", + "AUDIO\\BNK4_17.WAV", + "AUDIO\\BNK4_18.WAV", + "AUDIO\\BK4_19A.WAV", + "AUDIO\\BK4_19B.WAV", + "AUDIO\\BK4_20A.WAV", + "AUDIO\\BK4_20B.WAV", + "AUDIO\\BNK4_21.WAV", + "AUDIO\\BNK422A.WAV", + "AUDIO\\BNK422B.WAV", + "AUDIO\\BK4_23A.WAV", + "AUDIO\\BK4_23B.WAV", + "AUDIO\\BK4_23C.WAV", + "AUDIO\\BK4_23D.WAV", + "AUDIO\\BK4_24A.WAV", + "AUDIO\\BK4_24B.WAV", + "AUDIO\\BNK4_25.WAV", + "AUDIO\\BNK4_26.WAV", + "AUDIO\\BNK4_27.WAV", + "AUDIO\\BNK4_28.WAV", + "AUDIO\\BNK4_29.WAV", + "AUDIO\\BNK4_30.WAV", + "AUDIO\\BK4_31A.WAV", + "AUDIO\\BK4_31B.WAV", + "AUDIO\\BNK4_32.WAV", + "AUDIO\\BK4_34A.WAV", + "AUDIO\\BK4_34B.WAV", + "AUDIO\\BK4_35A.WAV", + "AUDIO\\BK4_35B.WAV", + "AUDIO\\BNK4_36.WAV", + "AUDIO\\BNK4_37.WAV", + "AUDIO\\BNK4_38.WAV", + "AUDIO\\BNK4_39.WAV", + "AUDIO\\BK4_40A.WAV", + "AUDIO\\BK4_40B.WAV", + "AUDIO\\BNK4_41.WAV", + "AUDIO\\BNK4_42.WAV", + "AUDIO\\BNK4_43.WAV", + "AUDIO\\BNK4_44.WAV", + "AUDIO\\BNK4_45.WAV", + "AUDIO\\BNK4_46.WAV", + "AUDIO\\BNK4_47.WAV", + "AUDIO\\BNK4_48.WAV", + "AUDIO\\BNK4_49.WAV", + "AUDIO\\BNK450A.WAV", + "AUDIO\\BNK450B.WAV", + "AUDIO\\BNK4_51.WAV", + "AUDIO\\BNK4_94.WAV", + "AUDIO\\BNK4_95.WAV", + "AUDIO\\BNK4_96.WAV", + "AUDIO\\BNK4_97.WAV", + "AUDIO\\BNK4_98.WAV", + "AUDIO\\BNK4_99.WAV", + "AUDIO\\BUD1_1.WAV", + "AUDIO\\BUD1_2.WAV", + "AUDIO\\BUD1_3.WAV", + "AUDIO\\BUD1_4.WAV", + "AUDIO\\BUD1_5.WAV", + "AUDIO\\BUD1_9.WAV", + "AUDIO\\BUD1_10.WAV", + "AUDIO\\BUD2_1.WAV", + "AUDIO\\BUD2_2.WAV", + "AUDIO\\BUD2_3.WAV", + "AUDIO\\BUD2_4.WAV", + "AUDIO\\BUD2_5.WAV", + "AUDIO\\BUD2_6.WAV", + "AUDIO\\BUD2_7.WAV", + "AUDIO\\BUD3_1.WAV", + "AUDIO\\BUD3_1A.WAV", + "AUDIO\\BUD3_1B.WAV", + "AUDIO\\BUD3_1C.WAV", + "AUDIO\\BUD3_2.WAV", + "AUDIO\\BUD3_3.WAV", + "AUDIO\\BUD3_4.WAV", + "AUDIO\\BUD3_5.WAV", + "AUDIO\\BUD3_6.WAV", + "AUDIO\\BUD3_7.WAV", + "AUDIO\\BUD3_8A.WAV", + "AUDIO\\BUD3_8B.WAV", + "AUDIO\\BUD3_8C.WAV", + "AUDIO\\BUD3_9A.WAV", + "AUDIO\\BUD3_9B.WAV", + "AUDIO\\BUD3_9C.WAV", + "AUDIO\\CAP1_2.WAV", + "AUDIO\\CAP1_3.WAV", + "AUDIO\\CAP1_4.WAV", + "AUDIO\\CAP1_5.WAV", + "AUDIO\\CAP1_6.WAV", + "AUDIO\\CAP1_7.WAV", + "AUDIO\\CAP1_8.WAV", + "AUDIO\\CAP1_9.WAV", + "AUDIO\\CAP1_10.WAV", + "AUDIO\\CAP1_11.WAV", + "AUDIO\\CAP1_12.WAV", + "AUDIO\\CNT1_1.WAV", + "AUDIO\\CNT1_2.WAV", + "AUDIO\\CNT1_3.WAV", + "AUDIO\\CNT1_4.WAV", + "AUDIO\\CNT1_5.WAV", + "AUDIO\\CNT2_1.WAV", + "AUDIO\\CNT2_2.WAV", + "AUDIO\\CNT2_3.WAV", + "AUDIO\\CNT2_4.WAV", + "AUDIO\\COK1_1.WAV", + "AUDIO\\COK1_2.WAV", + "AUDIO\\COK1_3.WAV", + "AUDIO\\COK1_4.WAV", + "AUDIO\\COK1_5.WAV", + "AUDIO\\COK1_6.WAV", + "AUDIO\\COK2_1.WAV", + "AUDIO\\COK2_2.WAV", + "AUDIO\\COK2_3.WAV", + "AUDIO\\COK2_4.WAV", + "AUDIO\\COK2_5.WAV", + "AUDIO\\COK2_6.WAV", + "AUDIO\\COK2_7A.WAV", + "AUDIO\\COK2_7B.WAV", + "AUDIO\\COK2_7C.WAV", + "AUDIO\\COK2_8A.WAV", + "AUDIO\\COK2_8B.WAV", + "AUDIO\\COK2_8C.WAV", + "AUDIO\\COK2_8D.WAV", + "AUDIO\\COK2_9.WAV", + "AUDIO\\COK210A.WAV", + "AUDIO\\COK210B.WAV", + "AUDIO\\COK210C.WAV", + "AUDIO\\COK212A.WAV", + "AUDIO\\COK212B.WAV", + "AUDIO\\COK2_13.WAV", + "AUDIO\\COK2_14.WAV", + "AUDIO\\COK2_15.WAV", + "AUDIO\\COK2_16.WAV", + "AUDIO\\COK2_20.WAV", + "AUDIO\\COK2_21.WAV", + "AUDIO\\COK2_2.WAV", // this is probably a typo of COK2_22 + "AUDIO\\COK3_1.WAV", + "AUDIO\\COK3_2.WAV", + "AUDIO\\COK3_3.WAV", + "AUDIO\\COK3_4.WAV", + "AUDIO\\COK4_1.WAV", + "AUDIO\\COK4_2.WAV", + "AUDIO\\COK4_3.WAV", + "AUDIO\\COK4_4.WAV", + "AUDIO\\COK4_5.WAV", + "AUDIO\\COK4_6.WAV", + "AUDIO\\COK4_7.WAV", + "AUDIO\\COK4_8.WAV", + "AUDIO\\COK4_9.WAV", + "AUDIO\\COK4_9A.WAV", + "AUDIO\\COK4_10.WAV", + "AUDIO\\COK4_11.WAV", + "AUDIO\\COK4_12.WAV", + "AUDIO\\COK4_13.WAV", + "AUDIO\\COK4_14.WAV", + "AUDIO\\COK4_15.WAV", + "AUDIO\\COK4_16.WAV", + "AUDIO\\COK4_17.WAV", + "AUDIO\\COK4_18.WAV", + "AUDIO\\COK4_19.WAV", + "AUDIO\\COK4_20.WAV", + "AUDIO\\COK4_21.WAV", + "AUDIO\\COK4_22.WAV", + "AUDIO\\COK4_23.WAV", + "AUDIO\\COK4_24.WAV", + "AUDIO\\COK4_25.WAV", + "AUDIO\\COK4_26.WAV", + "AUDIO\\COK4_27.WAV", + "AUDIO\\COL1_1.WAV", + "AUDIO\\COL1_2.WAV", + "AUDIO\\COL1_3.WAV", + "AUDIO\\COL1_4.WAV", + "AUDIO\\COL1_5.WAV", + "AUDIO\\COL1_6.WAV", + "AUDIO\\COL1_7.WAV", + "AUDIO\\COL1_8.WAV", + "AUDIO\\COL2_1.WAV", + "AUDIO\\COL2_2.WAV", + "AUDIO\\COL2_3.WAV", + "AUDIO\\COL2_4.WAV", + "AUDIO\\COL2_5.WAV", + "AUDIO\\COL2_6A.WAV", + "AUDIO\\COL2_7.WAV", + "AUDIO\\COL2_8.WAV", + "AUDIO\\COL2_9.WAV", + "AUDIO\\COL2_10.WAV", + "AUDIO\\COL2_11.WAV", + "AUDIO\\COL2_12.WAV", + "AUDIO\\COL2_13.WAV", + "AUDIO\\COL2_14.WAV", + "AUDIO\\COL2_15.WAV", + "AUDIO\\COL2_16.WAV", + "AUDIO\\COL3_1.WAV", + "AUDIO\\COL3_2.WAV", + "AUDIO\\COL3_2A.WAV", + "AUDIO\\COL3_2B.WAV", + "AUDIO\\COL3_3.WAV", + "AUDIO\\COL3_4.WAV", + "AUDIO\\COL3_5.WAV", + "AUDIO\\COL3_6.WAV", + "AUDIO\\COL3_7.WAV", + "AUDIO\\COL3_8.WAV", + "AUDIO\\COL3_9.WAV", + "AUDIO\\COL3_10.WAV", + "AUDIO\\COL3_11.WAV", + "AUDIO\\COL3_12.WAV", + "AUDIO\\COL3_13.WAV", + "AUDIO\\COL3_14.WAV", + "AUDIO\\COL3_15.WAV", + "AUDIO\\COL3_16.WAV", + "AUDIO\\COL3_17.WAV", + "AUDIO\\COL3_18.WAV", + "AUDIO\\COL3_19.WAV", + "AUDIO\\COL3_20.WAV", + "AUDIO\\COL3_21.WAV", + "AUDIO\\COL3_23.WAV", + "AUDIO\\COL3_24.WAV", + "AUDIO\\COL3_25.WAV", + "AUDIO\\COL4_1.WAV", + "AUDIO\\COL4_2.WAV", + "AUDIO\\COL4_3.WAV", + "AUDIO\\COL4_4.WAV", + "AUDIO\\COL4_5.WAV", + "AUDIO\\COL4_6.WAV", + "AUDIO\\COL4_7.WAV", + "AUDIO\\COL4_8.WAV", + "AUDIO\\COL4_9.WAV", + "AUDIO\\COL4_10.WAV", + "AUDIO\\COL4_11.WAV", + "AUDIO\\COL4_12.WAV", + "AUDIO\\COL4_13.WAV", + "AUDIO\\COL4_14.WAV", + "AUDIO\\COL4_15.WAV", + "AUDIO\\COL4_16.WAV", + "AUDIO\\COL4_17.WAV", + "AUDIO\\COL4_18.WAV", + "AUDIO\\COL4_19.WAV", + "AUDIO\\COL4_20.WAV", + "AUDIO\\COL4_21.WAV", + "AUDIO\\COL4_22.WAV", + "AUDIO\\COL4_23.WAV", + "AUDIO\\COL4_24.WAV", + "AUDIO\\COL4_25.WAV", + "AUDIO\\COL4_26.WAV", + "AUDIO\\COL5_1.WAV", + "AUDIO\\COL5_2.WAV", + "AUDIO\\COL5_3.WAV", + "AUDIO\\COL5_4.WAV", + "AUDIO\\COL5_5.WAV", + "AUDIO\\COL5_6.WAV", + "AUDIO\\COL5_7.WAV", + "AUDIO\\COL5_8.WAV", + "AUDIO\\COL5_9.WAV", + "AUDIO\\COL5_10.WAV", + "AUDIO\\COL5_11.WAV", + "AUDIO\\COL5_12.WAV", + "AUDIO\\COL5_13.WAV", + "AUDIO\\COL5_14.WAV", + "AUDIO\\COL5_15.WAV", + "AUDIO\\COL5_16.WAV", + "AUDIO\\COL5_17.WAV", + "AUDIO\\COL5_18.WAV", + "AUDIO\\COL5_19.WAV", + "AUDIO\\COL5_20.WAV", + "AUDIO\\COL5_21.WAV", + "AUDIO\\COL5_22.WAV", + "AUDIO\\CUB1_1.WAV", + "AUDIO\\CUB1_2.WAV", + "AUDIO\\CUB1_3.WAV", + "AUDIO\\CUB1_4.WAV", + "AUDIO\\CUB1_5.WAV", + "AUDIO\\CUB1_6.WAV", + "AUDIO\\CUB1_7.WAV", + "AUDIO\\CUB1_8.WAV", + "AUDIO\\CUB1_9.WAV", + "AUDIO\\CUB1_10.WAV", + "AUDIO\\CUB2_1.WAV", + "AUDIO\\CUB2_2.WAV", + "AUDIO\\CUB2_3A.WAV", + "AUDIO\\CUB2_3B.WAV", + "AUDIO\\CUB2_3C.WAV", + "AUDIO\\CUB2_4A.WAV", + "AUDIO\\CUB2_5.WAV", + "AUDIO\\CUB2_6.WAV", + "AUDIO\\CUB2_7.WAV", + "AUDIO\\CUB2_8.WAV", + "AUDIO\\CUB2_9.WAV", + "AUDIO\\CUB2_10.WAV", + "AUDIO\\CUB2_11.WAV", + "AUDIO\\CUB3_1.WAV", + "AUDIO\\CUB3_2.WAV", + "AUDIO\\CUB3_3.WAV", + "AUDIO\\CUB3_4.WAV", + "AUDIO\\CUB4_1.WAV", + "AUDIO\\CUB4_2.WAV", + "AUDIO\\CUB4_3.WAV", + "AUDIO\\CUB4_4.WAV", + "AUDIO\\CUB4_5.WAV", + "AUDIO\\CUB4_5A.WAV", + "AUDIO\\CUB4_6.WAV", + "AUDIO\\CUB4_7.WAV", + "AUDIO\\CUB4_8.WAV", + "AUDIO\\CUB4_9.WAV", + "AUDIO\\CUB4_10.WAV", + "AUDIO\\CUB4_11.WAV", + "AUDIO\\CUB4_12.WAV", + "AUDIO\\CUB4_13.WAV", + "AUDIO\\CUB4_14.WAV", + "AUDIO\\CUB4_15.WAV", + "AUDIO\\CUB4_16.WAV", + "AUDIO\\GOLF_1.WAV", + "AUDIO\\GOLF_2.WAV", + "AUDIO\\GOLF_3.WAV", + "AUDIO\\BAR_1.WAV", + "AUDIO\\BAR_2.WAV", + "AUDIO\\BAR_3.WAV", + "AUDIO\\BAR_4.WAV", + "AUDIO\\BAR_5.WAV", + "AUDIO\\BAR_6.WAV", + "AUDIO\\BAR_7.WAV", + "AUDIO\\BAR_8.WAV", + "AUDIO\\STRIP_1.WAV", + "AUDIO\\STRIP_2.WAV", + "AUDIO\\STRIP_3.WAV", + "AUDIO\\STRIP_4.WAV", + "AUDIO\\STRIP_5.WAV", + "AUDIO\\STRIP_6.WAV", + "AUDIO\\STRIP_7.WAV", + "AUDIO\\STRIP_8.WAV", + "AUDIO\\STRIP_9.WAV", + "AUDIO\\STAR_1.WAV", + "AUDIO\\STAR_2.WAV", + "AUDIO\\STAR_3.WAV", + "AUDIO\\STAR_4.WAV", + "AUDIO\\FIN_1A.WAV", + "AUDIO\\FIN_1B.WAV", + "AUDIO\\FIN_1C.WAV", + "AUDIO\\FIN_2B.WAV", + "AUDIO\\FIN_2C.WAV", + "AUDIO\\FIN_3.WAV", + "AUDIO\\FIN_4.WAV", + "AUDIO\\FIN_5.WAV", + "AUDIO\\FIN_6.WAV", + "AUDIO\\FIN_10.WAV", + "AUDIO\\FIN_11A.WAV", + "AUDIO\\FIN_11B.WAV", + "AUDIO\\FIN_12A.WAV", + "AUDIO\\FIN_12B.WAV", + "AUDIO\\FIN_12C.WAV", + "AUDIO\\FIN_13.WAV", + "AUDIO\\FINKILL.WAV", + "AUDIO\\LAW1_1.WAV", + "AUDIO\\LAW1_2.WAV", + "AUDIO\\LAW1_3.WAV", + "AUDIO\\LAW1_4.WAV", + "AUDIO\\LAW1_5.WAV", + "AUDIO\\LAW1_6.WAV", + "AUDIO\\LAW1_7.WAV", + "AUDIO\\LAW1_8.WAV", + "AUDIO\\LAW1_9.WAV", + "AUDIO\\LAW1_10.WAV", + "AUDIO\\LAW2_1.WAV", + "AUDIO\\LAW2_2.WAV", + "AUDIO\\LAW2_3.WAV", + "AUDIO\\LAW2_4.WAV", + "AUDIO\\LAW2_5.WAV", + "AUDIO\\LAW2_6.WAV", + "AUDIO\\LAW2_7.WAV", + "AUDIO\\LAW2_8.WAV", + "AUDIO\\LAW2_9.WAV", + "AUDIO\\LAW2_10.WAV", + "AUDIO\\LAW3_1.WAV", + "AUDIO\\LAW3_2.WAV", + "AUDIO\\LAW3_3.WAV", + "AUDIO\\LAW3_4.WAV", + "AUDIO\\LAW3_5.WAV", + "AUDIO\\LAW3_6.WAV", + "AUDIO\\LAW3_10.WAV", + "AUDIO\\LAW3_11.WAV", + "AUDIO\\LAW3_12.WAV", + "AUDIO\\LAW3_13.WAV", + "AUDIO\\LAW3_14.WAV", + "AUDIO\\LAW3_16.WAV", + "AUDIO\\LAW3_17.WAV", + "AUDIO\\LAW3_18.WAV", + "AUDIO\\LAW3_19.WAV", + "AUDIO\\LAW3_20.WAV", + "AUDIO\\LAW3_21.WAV", + "AUDIO\\LAW3_22.WAV", + "AUDIO\\LAW3_23.WAV", + "AUDIO\\LAW3_24.WAV", + "AUDIO\\LAW3_25.WAV", + "AUDIO\\LAW4_1A.WAV", + "AUDIO\\LAW4_1B.WAV", + "AUDIO\\LAW4_1C.WAV", + "AUDIO\\LAW4_1D.WAV", + "AUDIO\\LAW4_10.WAV", + "AUDIO\\LAW4_3.WAV", + "AUDIO\\LAW4_4.WAV", + "AUDIO\\LAW4_5.WAV", + "AUDIO\\LAW4_6.WAV", + "AUDIO\\LAW4_7.WAV", + "AUDIO\\LAW4_8.WAV", + "AUDIO\\LAW4_9.WAV", + "AUDIO\\PHIL1_2.WAV", + "AUDIO\\PHIL1_3.WAV", + "AUDIO\\PHIL2_1.WAV", + "AUDIO\\PHIL2_2.WAV", + "AUDIO\\PHIL2_3.WAV", + "AUDIO\\PHIL2_4.WAV", + "AUDIO\\PHIL2_5.WAV", + "AUDIO\\PHIL2_6.WAV", + "AUDIO\\PHIL2_7.WAV", + "AUDIO\\PHIL2_8.WAV", + "AUDIO\\PHIL2_9.WAV", + "AUDIO\\PHIL210.WAV", + "AUDIO\\PHIL211.WAV", + "AUDIO\\PORN1_1.WAV", + "AUDIO\\PORN1_2.WAV", + "AUDIO\\PORN1_3.WAV", + "AUDIO\\PRN1_3A.WAV", + "AUDIO\\PORN1_4.WAV", + "AUDIO\\PORN1_5.WAV", + "AUDIO\\PORN1_6.WAV", + "AUDIO\\PORN1_7.WAV", + "AUDIO\\PORN1_8.WAV", + "AUDIO\\PORN1_9.WAV", + "AUDIO\\PRN1_10.WAV", + "AUDIO\\PRN1_11.WAV", + "AUDIO\\PRN1_12.WAV", + "AUDIO\\PRN1_13.WAV", + "AUDIO\\PRN1_14.WAV", + "AUDIO\\PRN1_15.WAV", + "AUDIO\\PRN1_16.WAV", + "AUDIO\\PRN1_17.WAV", + "AUDIO\\PRN1_18.WAV", + "AUDIO\\PRN1_19.WAV", + "AUDIO\\PRN1_20.WAV", + "AUDIO\\PRN1_21.WAV", + "AUDIO\\PORN3_1.WAV", + "AUDIO\\PORN3_2.WAV", + "AUDIO\\PORN3_3.WAV", + "AUDIO\\PORN3_4.WAV", + "AUDIO\\PSYCH_1.WAV", + "AUDIO\\PSYCH_2.WAV", + "AUDIO\\ROK2_01.WAV", + "AUDIO\\ROK3_1.WAV", + "AUDIO\\ROK3_2.WAV", + "AUDIO\\ROK3_3.WAV", + "AUDIO\\ROK3_4.WAV", + "AUDIO\\ROK3_5.WAV", + "AUDIO\\ROK3_6.WAV", + "AUDIO\\ROK3_7.WAV", + "AUDIO\\ROK3_8.WAV", + "AUDIO\\ROK3_9.WAV", + "AUDIO\\ROK3_10.WAV", + "AUDIO\\ROK3_11.WAV", + "AUDIO\\ROK3_12.WAV", + "AUDIO\\ROK3_13.WAV", + "AUDIO\\ROK3_14.WAV", + "AUDIO\\ROK3_15.WAV", + "AUDIO\\ROK3_16.WAV", + "AUDIO\\ROK3_17.WAV", + "AUDIO\\ROK3_18.WAV", + "AUDIO\\ROK3_19.WAV", + "AUDIO\\ROK3_20.WAV", + "AUDIO\\ROK3_21.WAV", + "AUDIO\\ROK3_22.WAV", + "AUDIO\\ROK3_23.WAV", + "AUDIO\\ROK3_24.WAV", + "AUDIO\\ROK3_25.WAV", + "AUDIO\\ROK3_26.WAV", + "AUDIO\\ROK3_27.WAV", + "AUDIO\\ROK3_62.WAV", + "AUDIO\\ROK3_63.WAV", + "AUDIO\\ROK3_64.WAV", + "AUDIO\\ROK3_65.WAV", + "AUDIO\\ROK3_66.WAV", + "AUDIO\\ROK3_67.WAV", + "AUDIO\\ROK3_68.WAV", + "AUDIO\\ROK3_69.WAV", + "AUDIO\\ROK3_70.WAV", + "AUDIO\\ROK3_71.WAV", + "AUDIO\\ROK3_73.WAV", + "AUDIO\\RESC_1.WAV", + "AUDIO\\RESC_2.WAV", + "AUDIO\\RESC_3.WAV", + "AUDIO\\RESC_4.WAV", + "AUDIO\\RESC_5.WAV", + "AUDIO\\RESC_6.WAV", + "AUDIO\\RESC_7.WAV", + "AUDIO\\RESC_8.WAV", + "AUDIO\\RESC_9.WAV", + "AUDIO\\RESC_10.WAV", + "AUDIO\\ROK1_1A.WAV", + "AUDIO\\ROK1_1B.WAV", + "AUDIO\\ROK1_5.WAV", + "AUDIO\\ROK1_6.WAV", + "AUDIO\\ROK1_7.WAV", + "AUDIO\\ROK1_8.WAV", + "AUDIO\\ROK1_9.WAV", + "AUDIO\\TAX1_1.WAV", + "AUDIO\\TAX1_2.WAV", + "AUDIO\\TAX1_3.WAV", + "AUDIO\\TAX1_4.WAV", + "AUDIO\\TAX1_5.WAV", + "AUDIO\\TAX2_1.WAV", + "AUDIO\\TAX2_2.WAV", + "AUDIO\\TAX2_3.WAV", + "AUDIO\\TAX2_4.WAV", + "AUDIO\\TAX2_5.WAV", + "AUDIO\\TAX2_6.WAV", + "AUDIO\\TAX2_7.WAV", + "AUDIO\\TAX3_1.WAV", + "AUDIO\\TAX3_2.WAV", + "AUDIO\\TAX3_3.WAV", + "AUDIO\\TAX3_4.WAV", + "AUDIO\\TAX3_5.WAV", + "AUDIO\\TEX1_1.WAV", + "AUDIO\\TEX1_2.WAV", + "AUDIO\\TEX1_3.WAV", + "AUDIO\\TEX1_4.WAV", + "AUDIO\\TEX1_5.WAV", + "AUDIO\\TEX1_6.WAV", + "AUDIO\\TEX2_1.WAV", + "AUDIO\\TEX3_1.WAV", + "AUDIO\\TEX3_2.WAV", + "AUDIO\\TEX3_3.WAV", + "AUDIO\\TEX3_4.WAV", + "AUDIO\\TEX3_5.WAV", + "AUDIO\\TEX3_6.WAV", + "AUDIO\\TEX3_7.WAV", + "AUDIO\\TEX3_8.WAV", + "AUDIO\\HAT_1A.WAV", + "AUDIO\\INTRO1.WAV", + "AUDIO\\INTRO2.WAV", + "AUDIO\\INTRO3.WAV", + "AUDIO\\INTRO4.WAV", + "AUDIO\\MOB_01A.WAV", + "AUDIO\\MOB_01B.WAV", + "AUDIO\\MOB_01C.WAV", + "AUDIO\\MOB_02A.WAV", + "AUDIO\\MOB_02B.WAV", + "AUDIO\\MOB_02C.WAV", + "AUDIO\\MOB_03A.WAV", + "AUDIO\\MOB_03B.WAV", + "AUDIO\\MOB_03C.WAV", + "AUDIO\\MOB_03D.WAV", + "AUDIO\\MOB_03E.WAV", + "AUDIO\\SHARK_1.WAV", + "AUDIO\\SHARK_2.WAV", + "AUDIO\\SHARK_3.WAV", + "AUDIO\\SHARK_4.WAV", + "AUDIO\\SHARK_5.WAV", + "AUDIO\\MOB_04A.WAV", + "AUDIO\\MOB_04B.WAV", + "AUDIO\\MOB_04C.WAV", + "AUDIO\\MOB_04D.WAV", + "AUDIO\\MOB_05A.WAV", + "AUDIO\\MOB_05B.WAV", + "AUDIO\\MOB_05C.WAV", + "AUDIO\\MOB_05D.WAV", + "AUDIO\\MOB_06A.WAV", + "AUDIO\\MOB_06B.WAV", + "AUDIO\\MOB_06C.WAV", + "AUDIO\\MOB_07A.WAV", + "AUDIO\\MOB_07B.WAV", + "AUDIO\\MOB_08A.WAV", + "AUDIO\\MOB_08B.WAV", + "AUDIO\\MOB_08C.WAV", + "AUDIO\\MOB_08D.WAV", + "AUDIO\\MOB_08E.WAV", + "AUDIO\\MOB_08F.WAV", + "AUDIO\\MOB_08G.WAV", + "AUDIO\\MOB_09A.WAV", + "AUDIO\\MOB_09B.WAV", + "AUDIO\\MOB_09C.WAV", + "AUDIO\\MOB_09D.WAV", + "AUDIO\\MOB_09E.WAV", + "AUDIO\\MOB_09F.WAV", + "AUDIO\\MOB_10A.WAV", + "AUDIO\\MOB_10B.WAV", + "AUDIO\\MOB_10C.WAV", + "AUDIO\\MOB_10D.WAV", + "AUDIO\\MOB_10E.WAV", + "AUDIO\\MOB_11A.WAV", + "AUDIO\\MOB_11B.WAV", + "AUDIO\\MOB_11C.WAV", + "AUDIO\\MOB_11D.WAV", + "AUDIO\\MOB_11E.WAV", + "AUDIO\\MOB_11F.WAV", + "AUDIO\\MOB_14A.WAV", + "AUDIO\\MOB_14B.WAV", + "AUDIO\\MOB_14C.WAV", + "AUDIO\\MOB_14D.WAV", + "AUDIO\\MOB_14E.WAV", + "AUDIO\\MOB_14F.WAV", + "AUDIO\\MOB_14G.WAV", + "AUDIO\\MOB_14H.WAV", + "AUDIO\\MOB_16A.WAV", + "AUDIO\\MOB_16B.WAV", + "AUDIO\\MOB_16C.WAV", + "AUDIO\\MOB_16D.WAV", + "AUDIO\\MOB_16E.WAV", + "AUDIO\\MOB_16F.WAV", + "AUDIO\\MOB_16G.WAV", + "AUDIO\\MOB_17A.WAV", + "AUDIO\\MOB_17B.WAV", + "AUDIO\\MOB_17C.WAV", + "AUDIO\\MOB_17D.WAV", + "AUDIO\\MOB_17E.WAV", + "AUDIO\\MOB_17G.WAV", + "AUDIO\\MOB_17H.WAV", + "AUDIO\\MOB_17I.WAV", + "AUDIO\\MOB_17J.WAV", + "AUDIO\\MOB_17K.WAV", + "AUDIO\\MOB_17L.WAV", + "AUDIO\\MOB_18A.WAV", + "AUDIO\\MOB_18B.WAV", + "AUDIO\\MOB_18C.WAV", + "AUDIO\\MOB_18D.WAV", + "AUDIO\\MOB_18E.WAV", + "AUDIO\\MOB_18F.WAV", + "AUDIO\\MOB_18G.WAV", + "AUDIO\\MOB_20A.WAV", + "AUDIO\\MOB_20B.WAV", + "AUDIO\\MOB_20C.WAV", + "AUDIO\\MOB_20D.WAV", + "AUDIO\\MOB_20E.WAV", + "AUDIO\\MOB_24A.WAV", + "AUDIO\\MOB_24B.WAV", + "AUDIO\\MOB_24C.WAV", + "AUDIO\\MOB_24D.WAV", + "AUDIO\\MOB_24E.WAV", + "AUDIO\\MOB_24F.WAV", + "AUDIO\\MOB_24G.WAV", + "AUDIO\\MOB_24H.WAV", + "AUDIO\\MOB_25A.WAV", + "AUDIO\\MOB_25B.WAV", + "AUDIO\\MOB_25C.WAV", + "AUDIO\\MOB_25D.WAV", + "AUDIO\\MOB_26A.WAV", + "AUDIO\\MOB_26B.WAV", + "AUDIO\\MOB_26C.WAV", + "AUDIO\\MOB_26D.WAV", + "AUDIO\\MOB_26E.WAV", + "AUDIO\\MOB_29A.WAV", + "AUDIO\\MOB_29B.WAV", + "AUDIO\\MOB_29C.WAV", + "AUDIO\\MOB_29D.WAV", + "AUDIO\\MOB_29E.WAV", + "AUDIO\\MOB_29F.WAV", + "AUDIO\\MOB_29G.WAV", + "AUDIO\\MOB_30A.WAV", + "AUDIO\\MOB_30B.WAV", + "AUDIO\\MOB_30C.WAV", + "AUDIO\\MOB_30D.WAV", + "AUDIO\\MOB_30E.WAV", + "AUDIO\\MOB_30F.WAV", + "AUDIO\\MOB_33A.WAV", + "AUDIO\\MOB_33B.WAV", + "AUDIO\\MOB_33C.WAV", + "AUDIO\\MOB_33D.WAV", + "AUDIO\\MOB_34A.WAV", + "AUDIO\\MOB_34B.WAV", + "AUDIO\\MOB_34C.WAV", + "AUDIO\\MOB_34D.WAV", + "AUDIO\\MOB_35A.WAV", + "AUDIO\\MOB_35B.WAV", + "AUDIO\\MOB_35C.WAV", + "AUDIO\\MOB_35D.WAV", + "AUDIO\\MOB_36A.WAV", + "AUDIO\\MOB_36B.WAV", + "AUDIO\\MOB_36C.WAV", + "AUDIO\\MOB_40A.WAV", + "AUDIO\\MOB_40B.WAV", + "AUDIO\\MOB_40C.WAV", + "AUDIO\\MOB_40D.WAV", + "AUDIO\\MOB_40E.WAV", + "AUDIO\\MOB_40F.WAV", + "AUDIO\\MOB_40G.WAV", + "AUDIO\\MOB_40H.WAV", + "AUDIO\\MOB_40I.WAV", + "AUDIO\\MOB_41A.WAV", + "AUDIO\\MOB_41B.WAV", + "AUDIO\\MOB_41C.WAV", + "AUDIO\\MOB_41D.WAV", + "AUDIO\\MOB_41E.WAV", + "AUDIO\\MOB_41F.WAV", + "AUDIO\\MOB_41G.WAV", + "AUDIO\\MOB_41H.WAV", + "AUDIO\\MOB_42A.WAV", + "AUDIO\\MOB_42B.WAV", + "AUDIO\\MOB_42C.WAV", + "AUDIO\\MOB_42D.WAV", + "AUDIO\\MOB_42E.WAV", + "AUDIO\\MOB_43A.WAV", + "AUDIO\\MOB_43B.WAV", + "AUDIO\\MOB_43C.WAV", + "AUDIO\\MOB_43D.WAV", + "AUDIO\\MOB_43E.WAV", + "AUDIO\\MOB_43F.WAV", + "AUDIO\\MOB_43G.WAV", + "AUDIO\\MOB_43H.WAV", + "AUDIO\\MOB_45A.WAV", + "AUDIO\\MOB_45B.WAV", + "AUDIO\\MOB_45C.WAV", + "AUDIO\\MOB_45D.WAV", + "AUDIO\\MOB_45E.WAV", + "AUDIO\\MOB_45F.WAV", + "AUDIO\\MOB_45G.WAV", + "AUDIO\\MOB_45H.WAV", + "AUDIO\\MOB_45I.WAV", + "AUDIO\\MOB_45J.WAV", + "AUDIO\\MOB_45K.WAV", + "AUDIO\\MOB_45L.WAV", + "AUDIO\\MOB_45M.WAV", + "AUDIO\\MOB_45N.WAV", + "AUDIO\\MOB_46A.WAV", + "AUDIO\\MOB_46B.WAV", + "AUDIO\\MOB_46C.WAV", + "AUDIO\\MOB_46D.WAV", + "AUDIO\\MOB_46E.WAV", + "AUDIO\\MOB_46F.WAV", + "AUDIO\\MOB_46G.WAV", + "AUDIO\\MOB_46H.WAV", + "AUDIO\\MOB_47A.WAV", + "AUDIO\\MOB_52A.WAV", + "AUDIO\\MOB_52B.WAV", + "AUDIO\\MOB_52C.WAV", + "AUDIO\\MOB_52D.WAV", + "AUDIO\\MOB_52E.WAV", + "AUDIO\\MOB_52F.WAV", + "AUDIO\\MOB_52G.WAV", + "AUDIO\\MOB_52H.WAV", + "AUDIO\\MOB_54A.WAV", + "AUDIO\\MOB_54B.WAV", + "AUDIO\\MOB_54C.WAV", + "AUDIO\\MOB_54D.WAV", + "AUDIO\\MOB_54E.WAV", + "AUDIO\\MOB_55A.WAV", + "AUDIO\\MOB_55B.WAV", + "AUDIO\\MOB_55C.WAV", + "AUDIO\\MOB_55D.WAV", + "AUDIO\\MOB_55E.WAV", + "AUDIO\\MOB_55F.WAV", + "AUDIO\\MOB_56A.WAV", + "AUDIO\\MOB_56B.WAV", + "AUDIO\\MOB_56C.WAV", + "AUDIO\\MOB_56D.WAV", + "AUDIO\\MOB_56E.WAV", + "AUDIO\\MOB_56F.WAV", + "AUDIO\\MOB_57A.WAV", + "AUDIO\\MOB_57B.WAV", + "AUDIO\\MOB_57C.WAV", + "AUDIO\\MOB_57D.WAV", + "AUDIO\\MOB_57E.WAV", + "AUDIO\\MOB_58A.WAV", + "AUDIO\\MOB_58B.WAV", + "AUDIO\\MOB_58C.WAV", + "AUDIO\\MOB_58D.WAV", + "AUDIO\\MOB_58E.WAV", + "AUDIO\\MOB_58F.WAV", + "AUDIO\\MOB_58G.WAV", + "AUDIO\\MOB_61A.WAV", + "AUDIO\\MOB_61B.WAV", + "AUDIO\\MOB_62A.WAV", + "AUDIO\\MOB_62B.WAV", + "AUDIO\\MOB_62C.WAV", + "AUDIO\\MOB_62D.WAV", + "AUDIO\\MOB_63A.WAV", + "AUDIO\\MOB_63B.WAV", + "AUDIO\\MOB_63C.WAV", + "AUDIO\\MOB_63D.WAV", + "AUDIO\\MOB_63E.WAV", + "AUDIO\\MOB_63F.WAV", + "AUDIO\\MOB_63G.WAV", + "AUDIO\\MOB_63H.WAV", + "AUDIO\\MOB_63I.WAV", + "AUDIO\\MOB_63J.WAV", + "AUDIO\\MOB_66A.WAV", + "AUDIO\\MOB_66B.WAV", + "AUDIO\\MOB_68A.WAV", + "AUDIO\\MOB_68B.WAV", + "AUDIO\\MOB_68C.WAV", + "AUDIO\\MOB_68D.WAV", + "AUDIO\\MOB_70A.WAV", + "AUDIO\\MOB_70B.WAV", + "AUDIO\\MOB_71A.WAV", + "AUDIO\\MOB_71B.WAV", + "AUDIO\\MOB_71C.WAV", + "AUDIO\\MOB_71D.WAV", + "AUDIO\\MOB_71E.WAV", + "AUDIO\\MOB_71F.WAV", + "AUDIO\\MOB_71G.WAV", + "AUDIO\\MOB_71H.WAV", + "AUDIO\\MOB_71I.WAV", + "AUDIO\\MOB_71J.WAV", + "AUDIO\\MOB_71K.WAV", + "AUDIO\\MOB_71L.WAV", + "AUDIO\\MOB_71M.WAV", + "AUDIO\\MOB_71N.WAV", + "AUDIO\\MOB_72A.WAV", + "AUDIO\\MOB_72B.WAV", + "AUDIO\\MOB_72C.WAV", + "AUDIO\\MOB_72D.WAV", + "AUDIO\\MOB_72E.WAV", + "AUDIO\\MOB_72F.WAV", + "AUDIO\\MOB_72G.WAV", + "AUDIO\\MOB_73A.WAV", + "AUDIO\\MOB_73C.WAV", + "AUDIO\\MOB_73D.WAV", + "AUDIO\\MOB_73F.WAV", + "AUDIO\\MOB_73G.WAV", + "AUDIO\\MOB_73I.WAV", + "AUDIO\\MOB_95A.WAV", + "AUDIO\\MOB_96A.WAV", + "AUDIO\\MOB_98A.WAV", + "AUDIO\\MOB_99A.WAV", + "AUDIO\\JOB1_1B.WAV", + "AUDIO\\JOB1_1C.WAV", + "AUDIO\\JOB1_1D.WAV", + "AUDIO\\JOB2_1B.WAV", + "AUDIO\\JOB2_2.WAV", + "AUDIO\\JOB2_3.WAV", + "AUDIO\\JOB2_4.WAV", + "AUDIO\\JOB2_5.WAV", + "AUDIO\\JOB2_6.WAV", + "AUDIO\\JOB2_7.WAV", + "AUDIO\\JOB2_8.WAV", + "AUDIO\\JOB2_9.WAV", + "AUDIO\\JOB3_1.WAV", + "AUDIO\\JOB3_2.WAV", + "AUDIO\\JOB3_3.WAV", + "AUDIO\\JOB4_1.WAV", + "AUDIO\\JOB4_2.WAV", + "AUDIO\\JOB4_3.WAV", + "AUDIO\\JOB5_1.WAV", + "AUDIO\\JOB5_2.WAV", + "AUDIO\\JOB5_3.WAV", + "AUDIO\\BJM1_20.WAV", + "AUDIO\\BJM1_4.WAV", + "AUDIO\\BJM1_5.WAV", + "AUDIO\\MERC_39.WAV", + "AUDIO\\MONO_1.WAV", + "AUDIO\\MONO_2.WAV", + "AUDIO\\MONO_3.WAV", + "AUDIO\\MONO_4.WAV", + "AUDIO\\MONO_5.WAV", + "AUDIO\\MONO_6.WAV", + "AUDIO\\MONO_7.WAV", + "AUDIO\\MONO_8.WAV", + "AUDIO\\MONO_9.WAV", + "AUDIO\\MONO10.WAV", + "AUDIO\\MONO11.WAV", + "AUDIO\\MONO12.WAV", + "AUDIO\\MONO13.WAV", + "AUDIO\\MONO14.WAV", + "AUDIO\\MONO15.WAV", + "AUDIO\\MONO16.WAV", + "AUDIO\\FUD_01.WAV", + "AUDIO\\FUD_02.WAV", + "AUDIO\\FUD_03.WAV", + "AUDIO\\FUD_04.WAV", + "AUDIO\\FUD_05.WAV", + "AUDIO\\FUD_06.WAV", + "AUDIO\\FUD_07.WAV", + "AUDIO\\FUD_08.WAV", + "AUDIO\\FUD_09.WAV", + "AUDIO\\FUD_10.WAV", + "AUDIO\\FUD_11.WAV", + "AUDIO\\FUD_12.WAV", + "AUDIO\\FUD_13.WAV", + "AUDIO\\FUD_14.WAV", + "AUDIO\\FUD_15.WAV", + "AUDIO\\FUD_16.WAV", + "AUDIO\\FUD_17.WAV", + "AUDIO\\FUD_18.WAV", + "AUDIO\\FUD_19.WAV", + "AUDIO\\FUD_20.WAV", + "AUDIO\\BURG_01.WAV", + "AUDIO\\BURG_02.WAV", + "AUDIO\\BURG_03.WAV", + "AUDIO\\BURG_04.WAV", + "AUDIO\\BURG_05.WAV", + "AUDIO\\BURG_06.WAV", + "AUDIO\\BURG_07.WAV", + "AUDIO\\BURG_08.WAV", + "AUDIO\\BURG_09.WAV", + "AUDIO\\BURG_10.WAV", + "AUDIO\\BURG_11.WAV", + "AUDIO\\BURG_12.WAV", + "AUDIO\\CRUST01.WAV", + "AUDIO\\CRUST02.WAV", + "AUDIO\\CRUST03.WAV", + "AUDIO\\CRUST04.WAV", + "AUDIO\\CRUST05.WAV", + "AUDIO\\CRUST06.WAV", + "AUDIO\\CRUST07.WAV", + "AUDIO\\CRUST08.WAV", + "AUDIO\\CRUST09.WAV", + "AUDIO\\BAND_01.WAV", + "AUDIO\\BAND_02.WAV", + "AUDIO\\BAND_03.WAV", + "AUDIO\\BAND_04.WAV", + "AUDIO\\BAND_05.WAV", + "AUDIO\\BAND_06.WAV", + "AUDIO\\BAND_07.WAV", + "AUDIO\\BAND_08.WAV", + "AUDIO\\SHAFT01.WAV", + "AUDIO\\SHAFT02.WAV", + "AUDIO\\SHAFT03.WAV", + "AUDIO\\SHAFT04.WAV", + "AUDIO\\SHAFT05.WAV", + "AUDIO\\SHAFT06.WAV", + "AUDIO\\SHAFT07.WAV", + "AUDIO\\SHAFT08.WAV", + "AUDIO\\PISS_01.WAV", + "AUDIO\\PISS_02.WAV", + "AUDIO\\PISS_03.WAV", + "AUDIO\\PISS_04.WAV", + "AUDIO\\PISS_05.WAV", + "AUDIO\\PISS_06.WAV", + "AUDIO\\PISS_07.WAV", + "AUDIO\\PISS_08.WAV", + "AUDIO\\PISS_09.WAV", + "AUDIO\\PISS_10.WAV", + "AUDIO\\PISS_11.WAV", + "AUDIO\\PISS_12.WAV", + "AUDIO\\PISS_13.WAV", + "AUDIO\\PISS_14.WAV", + "AUDIO\\PISS_15.WAV", + "AUDIO\\PISS_16.WAV", + "AUDIO\\PISS_17.WAV", + "AUDIO\\PISS_18.WAV", + "AUDIO\\PISS_19.WAV", + "AUDIO\\GIMME01.WAV", + "AUDIO\\GIMME02.WAV", + "AUDIO\\GIMME03.WAV", + "AUDIO\\GIMME04.WAV", + "AUDIO\\GIMME05.WAV", + "AUDIO\\GIMME06.WAV", + "AUDIO\\GIMME07.WAV", + "AUDIO\\GIMME08.WAV", + "AUDIO\\GIMME09.WAV", + "AUDIO\\GIMME10.WAV", + "AUDIO\\GIMME11.WAV", + "AUDIO\\GIMME12.WAV", + "AUDIO\\GIMME13.WAV", + "AUDIO\\GIMME14.WAV", + "AUDIO\\GIMME15.WAV", + "AUDIO\\BUST_01.WAV", + "AUDIO\\BUST_02.WAV", + "AUDIO\\BUST_03.WAV", + "AUDIO\\BUST_04.WAV", + "AUDIO\\BUST_05.WAV", + "AUDIO\\BUST_06.WAV", + "AUDIO\\BUST_07.WAV", + "AUDIO\\BUST_08.WAV", + "AUDIO\\BUST_09.WAV", + "AUDIO\\BUST_10.WAV", + "AUDIO\\BUST_11.WAV", + "AUDIO\\BUST_12.WAV", + "AUDIO\\BUST_13.WAV", + "AUDIO\\BUST_14.WAV", + "AUDIO\\BUST_15.WAV", + "AUDIO\\BUST_16.WAV", + "AUDIO\\BUST_17.WAV", + "AUDIO\\BUST_18.WAV", + "AUDIO\\BUST_19.WAV", + "AUDIO\\BUST_20.WAV", + "AUDIO\\BUST_21.WAV", + "AUDIO\\BUST_22.WAV", + "AUDIO\\BUST_23.WAV", + "AUDIO\\BUST_24.WAV", + "AUDIO\\BUST_25.WAV", + "AUDIO\\BUST_26.WAV", + "AUDIO\\BUST_27.WAV", + "AUDIO\\BUST_28.WAV", +};
\ No newline at end of file diff --git a/src/audio/sampman_miles.cpp b/src/audio/sampman_miles.cpp new file mode 100644 index 0000000..3eee78a --- /dev/null +++ b/src/audio/sampman_miles.cpp @@ -0,0 +1,2380 @@ +#include "common.h" + +#ifdef AUDIO_MSS +#include <shlobj.h> +#include <shlguid.h> + +#include <time.h> + +#include "eax.h" +#include "eax-util.h" +#include "mss.h" + +#include "sampman.h" +#include "AudioManager.h" +#include "MusicManager.h" +#include "Frontend.h" +#include "Timer.h" +#include "crossplatform.h" + +#pragma comment( lib, "mss32.lib" ) + +cSampleManager SampleManager; +uint32 BankStartOffset[MAX_SFX_BANKS]; +/////////////////////////////////////////////////////////////// + +char SampleBankDescFilename[] = "AUDIO\\SFX.SDT"; +char SampleBankDataFilename[] = "AUDIO\\SFX.RAW"; + +FILE *fpSampleDescHandle; +FILE *fpSampleDataHandle; +bool bSampleBankLoaded [MAX_SFX_BANKS]; +int32 nSampleBankDiscStartOffset [MAX_SFX_BANKS]; +int32 nSampleBankSize [MAX_SFX_BANKS]; +int32 nSampleBankMemoryStartAddress[MAX_SFX_BANKS]; +int32 _nSampleDataEndOffset; + +int32 nPedSlotSfx [MAX_PEDSFX]; +int32 nPedSlotSfxAddr[MAX_PEDSFX]; +uint8 nCurrentPedSlot; + +uint8 nChannelVolume[MAXCHANNELS+MAX2DCHANNELS]; + +uint32 nStreamLength[TOTAL_STREAMED_SOUNDS]; + +/////////////////////////////////////////////////////////////// +struct tMP3Entry +{ + char aFilename[MAX_PATH]; + + uint32 nTrackLength; + uint32 nTrackStreamPos; + + tMP3Entry *pNext; + char *pLinkPath; +}; + +uint32 nNumMP3s; +tMP3Entry *_pMP3List; +char _mp3DirectoryPath[MAX_PATH]; +HSTREAM mp3Stream [MAX_STREAMS]; +int8 nStreamPan [MAX_STREAMS]; +int8 nStreamVolume[MAX_STREAMS]; +uint8 nStreamLoopedFlag[MAX_STREAMS]; +uint32 _CurMP3Index; +int32 _CurMP3Pos; +bool _bIsMp3Active; +/////////////////////////////////////////////////////////////// + + +bool _bSampmanInitialised = false; + +// +// Miscellaneous globals / defines + +// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS + +EAXLISTENERPROPERTIES StartEAX3 = + {26, 1.7f, 0.8f, -1000, -1000, -100, 4.42f, 0.14f, 1.00f, 429, 0.014f, 0.00f,0.00f,0.00f, 1023, 0.021f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 2727.1f, 250.0f, 0.00f, 0x3f }; + +EAXLISTENERPROPERTIES FinishEAX3 = + {26, 100.0f, 1.0f, 0, -1000, -2200, 20.0f, 1.39f, 1.00f, 1000, 0.069f, 0.00f,0.00f,0.00f, 400, 0.100f, 0.00f,0.00f,0.00f, 0.250f, 1.000f, 3.982f, 0.000f, -18.0f, 3530.8f, 417.9f, 6.70f, 0x3f }; + +EAXLISTENERPROPERTIES EAX3Params; + +S32 prevprovider=-1; +S32 curprovider=-1; +S32 usingEAX=0; +S32 usingEAX3=0; +HPROVIDER opened_provider=0; +H3DSAMPLE opened_samples[MAXCHANNELS] = {0}; +HSAMPLE opened_2dsamples[MAX2DCHANNELS] = {0}; +HDIGDRIVER DIG; +S32 speaker_type=0; + +U32 _maxSamples; +float _fPrevEaxRatioDestination; +bool _usingMilesFast2D; +float _fEffectsLevel; + + +struct +{ + HPROVIDER id; + char name[80]; +}providers[MAXPROVIDERS]; + +typedef struct provider_stuff +{ + char* name; + HPROVIDER id; +} provider_stuff; + + +static int __cdecl comp(const provider_stuff*s1,const provider_stuff*s2) +{ + return( _stricmp(s1->name,s2->name) ); +} + +static void +add_providers() +{ + provider_stuff pi[MAXPROVIDERS]; + U32 n,i,j; + + SampleManager.SetNum3DProvidersAvailable(0); + + HPROENUM next = HPROENUM_FIRST; + + n=0; + while (AIL_enumerate_3D_providers(&next, &pi[n].id, &pi[n].name) && (n<MAXPROVIDERS)) + { + ++n; + } + + qsort(pi,n,sizeof(pi[0]), (int(__cdecl*)(void const*, void const*))comp); + + for(i=0;i<n;i++) + { + providers[i].id=pi[i].id; + strcpy(providers[i].name, pi[i].name); + SampleManager.Set3DProviderName(i, providers[i].name); + } + + SampleManager.SetNum3DProvidersAvailable(n); + + for(j=n;j<MAXPROVIDERS;j++) + SampleManager.Set3DProviderName(j, NULL); +} + +static void +release_existing() +{ + for ( U32 i = 0; i < _maxSamples; i++ ) + { + if ( opened_samples[i] ) + { + AIL_release_3D_sample_handle(opened_samples[i]); + opened_samples[i] = NULL; + } + } + + if ( opened_provider ) + { + AIL_close_3D_provider(opened_provider); + opened_provider = NULL; + } + + _fPrevEaxRatioDestination = 0.0f; + _usingMilesFast2D = false; + _fEffectsLevel = 0.0f; +} + +static bool +set_new_provider(S32 index) +{ + DWORD result; + + if ( curprovider == index ) + return true; + + //close the already opened provider + curprovider = index; + + release_existing(); + + if ( curprovider != -1 ) + { + if ( !strcmp(providers[index].name, "Dolby Surround") ) + _maxSamples = MAXCHANNELS_SURROUND; + else + _maxSamples = MAXCHANNELS; + + AIL_set_3D_provider_preference(providers[index].id, "Maximum supported samples", &_maxSamples); + + //load the new provider + result = AIL_open_3D_provider(providers[index].id); + + if (result != M3D_NOERR) + { + curprovider=-1; + + OutputDebugStringA(AIL_last_error()); + + release_existing(); + + return false; + } + else + { + opened_provider=providers[index].id; + + //see if we're running under an EAX compatible provider + + if ( !strcmp(providers[index].name, "Creative Labs EAX 3 (TM)") ) + { + usingEAX = 1; + usingEAX3 = 1; + } + else + { + usingEAX3 = 0; + + result=AIL_3D_room_type(opened_provider); + usingEAX=(((S32)result)!=-1)?1:0; // will be something other than -1 on EAX + } + + if ( usingEAX3 ) + { + OutputDebugString("DOING SPECIAL EAX 3 STUFF!"); + AIL_set_3D_provider_preference(opened_provider, "EAX all parameters", &FinishEAX3); + } + else if ( usingEAX ) + { + AIL_set_3D_room_type(opened_provider, ENVIRONMENT_CAVE); + + if ( !strcmp(providers[index].name, "Miles Fast 2D Positional Audio") ) + _usingMilesFast2D = true; + } + + AIL_3D_provider_attribute(opened_provider, "Maximum supported samples", &_maxSamples); + + if ( _maxSamples > MAXCHANNELS ) + _maxSamples = MAXCHANNELS; + + SampleManager.SetSpeakerConfig(speaker_type); + + //obtain a 3D sample handles + for ( U32 i = 0; i < _maxSamples; ++i ) + { + opened_samples[i] = AIL_allocate_3D_sample_handle(opened_provider); + if ( opened_samples[i] != NULL ) + AIL_set_3D_sample_effects_level(opened_samples[i], 0.0f); + } + + return true; + } + } + + return false; +} + +U32 RadioHandlers[9]; + +U32 WINAPI vfs_open_callback(char const* Filename, U32* FileHandle) +{ + *FileHandle = (U32)fopen(Filename, "rb"); + + // couldn't they just use stricmp once? and strlen? this is very inefficient + if ((strcmp(Filename + strlen(Filename) - 4, ".adf") == 0) || (strcmp(Filename + strlen(Filename) - 4, ".ADF") == 0)) { + for (int i = 0; i < ARRAY_SIZE(RadioHandlers); i++) { + if (RadioHandlers[i] == NULL) { + RadioHandlers[i] = *FileHandle; + break; + } + } + strcpy((char*)Filename + strlen(Filename) - 4, ".mp3"); + } + return *FileHandle; +} + +void WINAPI vfs_close_callback(U32 FileHandle) +{ + for (int i = 0; i < ARRAY_SIZE(RadioHandlers); i++) { + if (RadioHandlers[i] == FileHandle) { + RadioHandlers[i] = NULL; + break; + } + } + fclose((FILE*)FileHandle); +} + +S32 WINAPI vfs_seek_callback(U32 FileHandle, S32 Offset, U32 Type) +{ + fseek((FILE*)FileHandle, Offset, Type); + return ftell((FILE*)FileHandle); +} + +U32 WINAPI vfs_read_callback(U32 FileHandle, void* Buffer, U32 Bytes) +{ + fread(Buffer, Bytes, 1, (FILE*)FileHandle); + uint8* _Buffer = (uint8*)Buffer; + + for (int i = 0; i < ARRAY_SIZE(RadioHandlers); i++) { + if (FileHandle == RadioHandlers[i]) { + for (U32 k = 0; k < Bytes; k++) + _Buffer[k] ^= 0x22; + break; + } + } + return Bytes; +} + +cSampleManager::cSampleManager(void) : + m_nNumberOfProviders(0) +{ + ; + + AIL_set_file_callbacks(vfs_open_callback, vfs_close_callback, vfs_seek_callback, vfs_read_callback); +} + +cSampleManager::~cSampleManager(void) +{ + +} + +void +cSampleManager::SetSpeakerConfig(int32 which) +{ + switch ( which ) + { + case 1: + speaker_type=AIL_3D_2_SPEAKER; + break; + + case 2: + speaker_type=AIL_3D_HEADPHONE; + break; + + case 3: + speaker_type=AIL_3D_4_SPEAKER; + break; + + default: + return; + break; + } + + if (opened_provider) + AIL_set_3D_speaker_type(opened_provider, speaker_type); +} + +uint32 +cSampleManager::GetMaximumSupportedChannels(void) +{ + if ( _maxSamples > MAXCHANNELS ) + return MAXCHANNELS; + + return _maxSamples; +} + +uint32 cSampleManager::GetNum3DProvidersAvailable() +{ + return m_nNumberOfProviders; +} + +void cSampleManager::SetNum3DProvidersAvailable(uint32 num) +{ + m_nNumberOfProviders = num; +} + +char *cSampleManager::Get3DProviderName(uint8 id) +{ + return m_aAudioProviders[id]; +} + +void cSampleManager::Set3DProviderName(uint8 id, char *name) +{ + m_aAudioProviders[id] = name; +} + +int8 +cSampleManager::GetCurrent3DProviderIndex(void) +{ + return curprovider; +} + +int8 +cSampleManager::SetCurrent3DProvider(uint8 nProvider) +{ + S32 savedprovider = curprovider; + + if ( nProvider < m_nNumberOfProviders ) + { + if ( set_new_provider(nProvider) ) + return curprovider; + else if ( savedprovider != -1 && savedprovider < m_nNumberOfProviders && set_new_provider(savedprovider) ) + return curprovider; + else + return -1; + } + else + return curprovider; +} + +int8 +cSampleManager::AutoDetect3DProviders() +{ + if (!AudioManager.IsAudioInitialised()) + return -1; + + int eax = -1, eax2 = -1, eax3 = -1, ds3dh = -1, ds3ds = -1; + + for (uint32 i = 0; i < GetNum3DProvidersAvailable(); i++) + { + char* providername = Get3DProviderName(i); + + if (!strcasecmp(providername, "CREATIVE LABS EAX (TM)")) { + AudioManager.SetCurrent3DProvider(i); + if (GetCurrent3DProviderIndex() == i) + eax = i; + } + + if (!strcasecmp(providername, "CREATIVE LABS EAX 2 (TM)")) { + AudioManager.SetCurrent3DProvider(i); + if (GetCurrent3DProviderIndex() == i) + eax2 = i; + } + + if (!strcasecmp(providername, "CREATIVE LABS EAX 3 (TM)")) { + AudioManager.SetCurrent3DProvider(i); + if (GetCurrent3DProviderIndex() == i) { + eax3 = i; + } + } + + if (!strcasecmp(providername, "DIRECTSOUND3D HARDWARE SUPPORT")) { + AudioManager.SetCurrent3DProvider(i); + if (GetCurrent3DProviderIndex() == i) + ds3dh = i; + } + + if (!strcasecmp(providername, "DIRECTSOUND3D SOFTWARE EMULATION")) { + AudioManager.SetCurrent3DProvider(i); + if (GetCurrent3DProviderIndex() == i) + ds3ds = i; + } + } + + if (eax3 != -1) + return eax3; + if (eax2 != -1) + return eax2; + if (eax != -1) + return eax; + if (ds3dh != -1) + return ds3dh; + if (ds3ds != -1) + return ds3ds; + return -1; +} + +static bool +_ResolveLink(char const *path, char *out) +{ + IShellLink* psl; + WIN32_FIND_DATA fd; + char filepath[MAX_PATH]; + + CoInitialize(NULL); + + if (SUCCEEDED( CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl ) )) + { + IPersistFile *ppf; + + if (SUCCEEDED(psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf))) + { + WCHAR wpath[MAX_PATH]; + + MultiByteToWideChar(CP_ACP, 0, path, -1, wpath, MAX_PATH); + + if (SUCCEEDED(ppf->Load(wpath, STGM_READ))) + { + /* Resolve the link */ + if (SUCCEEDED(psl->Resolve(NULL, SLR_ANY_MATCH|SLR_NO_UI|SLR_NOSEARCH))) + { + strcpy(filepath, path); + + if (SUCCEEDED(psl->GetPath(filepath, MAX_PATH, &fd, SLGP_UNCPRIORITY))) + { + OutputDebugString(fd.cFileName); + + strcpy(out, filepath); + // FIX: Release the objects. Taken from SA. +#ifdef FIX_BUGS + ppf->Release(); + psl->Release(); +#endif + return true; + } + } + } + + ppf->Release(); + } + psl->Release(); + } + + return false; +} + +static void +_FindMP3s(void) +{ + tMP3Entry *pList; + bool bShortcut; + bool bInitFirstEntry; + HANDLE hFind; + char path[MAX_PATH]; + char filepath[MAX_PATH*2]; + S32 total_ms; + WIN32_FIND_DATA fd; + + + if ( GetCurrentDirectory(MAX_PATH, _mp3DirectoryPath) == 0 ) + { + GetLastError(); + return; + } + + OutputDebugString("Finding MP3s..."); + strcpy(path, _mp3DirectoryPath); + strcat(path, "\\MP3\\"); + + strcpy(_mp3DirectoryPath, path); + OutputDebugString(_mp3DirectoryPath); + + strcat(path, "*"); + + hFind = FindFirstFile(path, &fd); + + if ( hFind == INVALID_HANDLE_VALUE ) + { + GetLastError(); + return; + } + + strcpy(filepath, _mp3DirectoryPath); + strcat(filepath, fd.cFileName); + + int32 filepathlen = strlen(filepath); + + if ( filepathlen <= 0) + { + FindClose(hFind); + return; + } + + if ( filepathlen > 4 ) + { + if ( !strcmp(&filepath[filepathlen - 4], ".lnk") ) + { + if ( _ResolveLink(filepath, filepath) ) + { + OutputDebugString("Resolving Link"); + OutputDebugString(filepath); + } + + bShortcut = true; + } + else + bShortcut = false; + } + + mp3Stream[0] = AIL_open_stream(DIG, filepath, 0); + if ( mp3Stream[0] ) + { + AIL_stream_ms_position(mp3Stream[0], &total_ms, NULL); + + AIL_close_stream(mp3Stream[0]); + mp3Stream[0] = NULL; + + OutputDebugString(fd.cFileName); + + _pMP3List = new tMP3Entry; + + if ( _pMP3List == NULL ) + { + FindClose(hFind); + return; + } + + nNumMP3s = 1; + + strcpy(_pMP3List->aFilename, fd.cFileName); + + _pMP3List->nTrackLength = total_ms; + + _pMP3List->pNext = NULL; + + pList = _pMP3List; + + if ( bShortcut ) + { + _pMP3List->pLinkPath = new char[MAX_PATH*2]; + strcpy(_pMP3List->pLinkPath, filepath); + } + else + { + _pMP3List->pLinkPath = NULL; + } + bInitFirstEntry = false; + } + else + { + strcat(filepath, " - NOT A VALID MP3"); + + OutputDebugString(filepath); + + bInitFirstEntry = true; + } + + while ( true ) + { + if ( !FindNextFile(hFind, &fd) ) + break; + + if ( bInitFirstEntry ) + { + strcpy(filepath, _mp3DirectoryPath); + strcat(filepath, fd.cFileName); + + int32 filepathlen = strlen(filepath); + + if ( filepathlen > 0 ) + { + if ( filepathlen > 4 ) + { + if ( !strcmp(&filepath[filepathlen - 4], ".lnk") ) + { + if ( _ResolveLink(filepath, filepath) ) + { + OutputDebugString("Resolving Link"); + OutputDebugString(filepath); + } + + bShortcut = true; + } + else + { + bShortcut = false; + + if ( filepathlen > MAX_PATH ) + { + continue; + } + } + } + + mp3Stream[0] = AIL_open_stream(DIG, filepath, 0); + if ( mp3Stream[0] ) + { + AIL_stream_ms_position(mp3Stream[0], &total_ms, NULL); + + AIL_close_stream(mp3Stream[0]); + mp3Stream[0] = NULL; + + OutputDebugString(fd.cFileName); + + _pMP3List = new tMP3Entry; + + if ( _pMP3List == NULL) + break; + + nNumMP3s = 1; + + strcpy(_pMP3List->aFilename, fd.cFileName); + + _pMP3List->nTrackLength = total_ms; + _pMP3List->pNext = NULL; + + if ( bShortcut ) + { + _pMP3List->pLinkPath = new char [MAX_PATH*2]; + strcpy(_pMP3List->pLinkPath, filepath); + } + else + { + _pMP3List->pLinkPath = NULL; + } + + pList = _pMP3List; + + bInitFirstEntry = false; + } + else + { + strcat(filepath, " - NOT A VALID MP3"); + OutputDebugString(filepath); + } + } + } + else + { + strcpy(filepath, _mp3DirectoryPath); + strcat(filepath, fd.cFileName); + + int32 filepathlen = strlen(filepath); + + if ( filepathlen > 0 ) + { + if ( filepathlen > 4 ) + { + if ( !strcmp(&filepath[filepathlen - 4], ".lnk") ) + { + if ( _ResolveLink(filepath, filepath) ) + { + OutputDebugString("Resolving Link"); + OutputDebugString(filepath); + } + + bShortcut = true; + } + else + { + bShortcut = false; + } + } + + mp3Stream[0] = AIL_open_stream(DIG, filepath, 0); + if ( mp3Stream[0] ) + { + AIL_stream_ms_position(mp3Stream[0], &total_ms, NULL); + + AIL_close_stream(mp3Stream[0]); + mp3Stream[0] = NULL; + + pList->pNext = new tMP3Entry; + + tMP3Entry *e = pList->pNext; + + if ( e == NULL ) + break; + + pList = pList->pNext; + + strcpy(e->aFilename, fd.cFileName); + e->nTrackLength = total_ms; + e->pNext = NULL; + + if ( bShortcut ) + { + e->pLinkPath = new char [MAX_PATH*2]; + strcpy(e->pLinkPath, filepath); + } + else + { + e->pLinkPath = NULL; + } + + nNumMP3s++; + + OutputDebugString(fd.cFileName); + } + else + { + strcat(filepath, " - NOT A VALID MP3"); + OutputDebugString(filepath); + } + } + } + } + + FindClose(hFind); +} + +static void +_DeleteMP3Entries(void) +{ + tMP3Entry *e = _pMP3List; + + while ( e != NULL ) + { + tMP3Entry *next = e->pNext; + + if ( next == NULL ) + next = NULL; + + if ( e->pLinkPath != NULL ) + { +#ifndef FIX_BUGS + delete e->pLinkPath; // BUG: should be delete [] +#else + delete[] e->pLinkPath; +#endif + e->pLinkPath = NULL; + } + + delete e; + + if ( next ) + e = next; + else + e = NULL; + + nNumMP3s--; + } + + + if ( nNumMP3s != 0 ) + { + OutputDebugString("Not all MP3 entries were deleted"); + nNumMP3s = 0; + } + + _pMP3List = NULL; +} + +static tMP3Entry * +_GetMP3EntryByIndex(uint32 idx) +{ + uint32 n = ( idx < nNumMP3s ) ? idx : 0; + + if ( _pMP3List != NULL ) + { + tMP3Entry *e = _pMP3List; + + for ( uint32 i = 0; i < n; i++ ) + e = e->pNext; + + return e; + + } + + return NULL; +} + +static inline bool +_GetMP3PosFromStreamPos(uint32 *pPosition, tMP3Entry **pEntry) +{ + _CurMP3Index = 0; + + for ( *pEntry = _pMP3List; *pEntry != NULL; *pEntry = (*pEntry)->pNext ) + { + if ( *pPosition >= (*pEntry)->nTrackStreamPos + && *pPosition < (*pEntry)->nTrackLength + (*pEntry)->nTrackStreamPos ) + { + *pPosition -= (*pEntry)->nTrackStreamPos; + _CurMP3Pos = *pPosition; + + return true; + } + + _CurMP3Index++; + } + + *pPosition = 0; + *pEntry = _pMP3List; + _CurMP3Pos = 0; + _CurMP3Index = 0; + + return false; +} + +bool +cSampleManager::IsMP3RadioChannelAvailable(void) +{ + return nNumMP3s != 0; +} + +void +cSampleManager::ReleaseDigitalHandle(void) +{ + if ( DIG ) + { + prevprovider = curprovider; + release_existing(); + curprovider = -1; + AIL_digital_handle_release(DIG); + } +} + +void +cSampleManager::ReacquireDigitalHandle(void) +{ + if ( DIG ) + { + AIL_digital_handle_reacquire(DIG); + if ( prevprovider != -1 ) + set_new_provider(prevprovider); + } +} + +bool +cSampleManager::Initialise(void) +{ + TRACE("start"); + + if ( _bSampmanInitialised ) + return true; + + { + for ( int32 i = 0; i < TOTAL_AUDIO_SAMPLES; i++ ) + { + m_aSamples[i].nOffset = 0; + m_aSamples[i].nSize = 0; + m_aSamples[i].nFrequency = 22050; + m_aSamples[i].nLoopStart = 0; + m_aSamples[i].nLoopEnd = -1; + } + + m_nEffectsVolume = MAX_VOLUME; + m_nMusicVolume = MAX_VOLUME; + m_nEffectsFadeVolume = MAX_VOLUME; + m_nMusicFadeVolume = MAX_VOLUME; + + m_nMonoMode = 0; + } + + // miles + TRACE("MILES"); + { + curprovider = -1; + prevprovider = -1; + + _usingMilesFast2D = false; + usingEAX=0; + usingEAX3=0; + + _fEffectsLevel = 0.0f; + + _maxSamples = 0; + + opened_provider = NULL; + DIG = NULL; + + for ( int32 i = 0; i < MAXCHANNELS; i++ ) + opened_samples[i] = NULL; + } + + // banks + TRACE("banks"); + { + fpSampleDescHandle = NULL; + fpSampleDataHandle = NULL; + + _nSampleDataEndOffset = 0; + + for ( int32 i = 0; i < MAX_SFX_BANKS; i++ ) + { + bSampleBankLoaded[i] = false; + nSampleBankDiscStartOffset[i] = 0; + nSampleBankSize[i] = 0; + nSampleBankMemoryStartAddress[i] = 0; + } + } + + // pedsfx + TRACE("pedsfx"); + { + for ( int32 i = 0; i < MAX_PEDSFX; i++ ) + { + nPedSlotSfx[i] = NO_SAMPLE; + nPedSlotSfxAddr[i] = 0; + } + + nCurrentPedSlot = 0; + } + + // channel volume + TRACE("vol"); + { + for ( int32 i = 0; i < MAXCHANNELS+MAX2DCHANNELS; i++ ) + nChannelVolume[i] = 0; + } + + TRACE("mss"); + { + AIL_set_redist_directory( "mss" ); + + AIL_startup(); + + AIL_set_preference(DIG_MIXER_CHANNELS, MAX_DIGITAL_MIXER_CHANNELS); + + DIG = AIL_open_digital_driver(DIGITALRATE, DIGITALBITS, DIGITALCHANNELS, 0); + + } + +#ifdef AUDIO_CACHE + TRACE("cache"); + FILE *cacheFile = fcaseopen("audio\\sound.cache", "rb"); + bool CreateCache = false; + if (cacheFile) { + fread(nStreamLength, sizeof(uint32), TOTAL_STREAMED_SOUNDS, cacheFile); + fclose(cacheFile); + }else + CreateCache = true; +#endif + + char filepath[MAX_PATH]; + bool bFileNotFound; + S32 tatalms; + + TRACE("cdrom"); + { + m_bInitialised = false; + + + while (true) + { + + // Find path of WAVs (originally in HDD) + int32 drive = 'C'; + +#ifndef NO_CDCHECK + do + { + char latter[2]; + + latter[0] = drive; + latter[1] = '\0'; + + strcpy(m_szCDRomRootPath, latter); + strcat(m_szCDRomRootPath, ":\\"); + + if ( GetDriveType(m_szCDRomRootPath) == DRIVE_CDROM ) + { + strcpy(filepath, m_szCDRomRootPath); + strcat(filepath, StreamedNameTable[0]); + + FILE *f = fopen(filepath, "rb"); + + if ( f ) + { + fclose(f); + strcpy(m_MiscomPath, m_szCDRomRootPath); + break; + } + } + + } while ( ++drive <= 'Z' ); +#else + m_MiscomPath[0] = '\0'; +#endif + + if ( DIG == NULL ) + { + OutputDebugString(AIL_last_error()); + Terminate(); + return false; + } + + add_providers(); + + m_szCDRomRootPath[0] = '\0'; + + strcpy(m_WavFilesPath, m_szCDRomRootPath); + +#ifdef AUDIO_CACHE + if ( CreateCache ) +#endif + for ( int32 i = STREAMED_SOUND_MISSION_MOBR1; i < TOTAL_STREAMED_SOUNDS; i++ ) + { + strcpy(filepath, m_szCDRomRootPath); + strcat(filepath, StreamedNameTable[i]); + + mp3Stream[0] = AIL_open_stream(DIG, filepath, 0); + + if ( mp3Stream[0] ) + { + AIL_stream_ms_position(mp3Stream[0], &tatalms, NULL); + + AIL_close_stream(mp3Stream[0]); + mp3Stream[0] = NULL; + + nStreamLength[i] = tatalms; + } + else + { + m_bInitialised = false; + Terminate(); + return false; + } + } + + // Find path of MP3s (originally in CD-Rom) + // if NO_CDCHECK is NOT defined but AUDIO_CACHE is defined, we still need to find MP3s' path, but will exit after the first file +#ifndef NO_CDCHECK + int32 drive = 'C'; + do + { + latter[0] = drive; + latter[1] = '\0'; + + strcpy(m_szCDRomRootPath, latter); + strcat(m_szCDRomRootPath, ":"); + strcat(m_MP3FilesPath, m_szCDRomRootPath); +#else + m_MP3FilesPath[0] = '\0'; + { +#endif + + for (int32 i = 0; i < STREAMED_SOUND_MISSION_MOBR1; i++) + { + strcpy(filepath, m_MP3FilesPath); + strcat(filepath, StreamedNameTable[i]); + + mp3Stream[0] = AIL_open_stream(DIG, filepath, 0); + + if (mp3Stream[0]) + { + AIL_stream_ms_position(mp3Stream[0], &tatalms, NULL); + + AIL_close_stream(mp3Stream[0]); + mp3Stream[0] = NULL; + + bFileNotFound = false; +#ifdef AUDIO_CACHE + if (!CreateCache) + break; + else +#endif + nStreamLength[i] = tatalms; + + } + else + { + bFileNotFound = true; + break; + } + } + +#ifndef NO_CDCHECK + if (!bFileNotFound) // otherwise try next drive + break; + + } + while (++drive <= 'Z'); +#else + } +#endif + + if ( !bFileNotFound ) { + +#ifdef AUDIO_CACHE + if ( CreateCache ) +#endif + for ( int32 i = STREAMED_SOUND_MISSION_COMPLETED4; i < STREAMED_SOUND_MISSION_PAGER; i++ ) + { + strcpy(filepath, m_MiscomPath); + strcat(filepath, StreamedNameTable[i]); + + mp3Stream[0] = AIL_open_stream(DIG, filepath, 0); + + if ( mp3Stream[0] ) + { + AIL_stream_ms_position(mp3Stream[0], &tatalms, NULL); + + AIL_close_stream(mp3Stream[0]); + mp3Stream[0] = NULL; + + nStreamLength[i] = tatalms; + bFileNotFound = false; + } + else + { + bFileNotFound = true; + break; + } + } + } + + m_bInitialised = !bFileNotFound; + + if ( !m_bInitialised ) + { +#if !defined(GTA3_STEAM_PATCH) && !defined(NO_CDCHECK) + FrontEndMenuManager.WaitForUserCD(); + if ( FrontEndMenuManager.m_bQuitGameNoCD ) + { + Terminate(); + return false; + } + continue; +#else + m_bInitialised = true; +#endif + } + + break; + } + } + +#ifdef AUDIO_CACHE + if (CreateCache) { + cacheFile = fcaseopen("audio\\sound.cache", "wb"); + fwrite(nStreamLength, sizeof(uint32), TOTAL_STREAMED_SOUNDS, cacheFile); + fclose(cacheFile); + } +#endif + + if ( !InitialiseSampleBanks() ) + { + Terminate(); + return false; + } + + nSampleBankMemoryStartAddress[SFX_BANK_0] = (int32)AIL_mem_alloc_lock(nSampleBankSize[SFX_BANK_0]); + if ( !nSampleBankMemoryStartAddress[SFX_BANK_0] ) + { + Terminate(); + return false; + } + + nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS] = (int32)AIL_mem_alloc_lock(PED_BLOCKSIZE*MAX_PEDSFX); + + LoadSampleBank(SFX_BANK_0); + + TRACE("stream"); + { + for ( int32 i = 0; i < MAX_STREAMS; i++ ) + { + mp3Stream [i] = NULL; + nStreamPan [i] = 63; + nStreamVolume[i] = 100; + } + } + + for ( int32 i = 0; i < MAX2DCHANNELS; i++ ) + { + opened_2dsamples[i] = AIL_allocate_sample_handle(DIG); + if ( opened_2dsamples[i] ) + { + AIL_init_sample(opened_2dsamples[i]); + AIL_set_sample_type(opened_2dsamples[i], DIG_F_MONO_16, DIG_PCM_SIGN); + } + } + + TRACE("providerset"); + { + _bSampmanInitialised = true; + + U32 n = 0; + + while ( n < m_nNumberOfProviders ) + { + if ( !strcmp(strupr(providers[n].name), "DIRECTSOUND3D SOFTWARE EMULATION") ) + { + set_new_provider(n); + break; + } + n++; + } + + if ( n == m_nNumberOfProviders ) + { + Terminate(); + return false; + } + } + + // mp3 + TRACE("mp3"); + { + nNumMP3s = 0; + + _pMP3List = NULL; + + _FindMP3s(); + + if ( nNumMP3s != 0 ) + { + nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER] = 0; + + for ( tMP3Entry *e = _pMP3List; e != NULL; e = e->pNext ) + { + e->nTrackStreamPos = nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER]; + nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER] += e->nTrackLength; + } + + time_t t = time(NULL); + tm *localtm; + bool bUseRandomTable; + + if ( t == -1 ) + bUseRandomTable = true; + else + { + bUseRandomTable = false; + localtm = localtime(&t); + } + + int32 randval; + if ( bUseRandomTable ) + randval = AudioManager.GetRandomNumber(1); + else + randval = localtm->tm_sec * localtm->tm_min; + + _CurMP3Index = randval % nNumMP3s; + + tMP3Entry *randmp3 = _pMP3List; + for ( int32 i = randval % nNumMP3s; i > 0; --i) + randmp3 = randmp3->pNext; + + if ( bUseRandomTable ) + _CurMP3Pos = AudioManager.GetRandomNumber(0) % randmp3->nTrackLength; + else + { + if ( localtm->tm_sec > 0 ) + { + int32 s = localtm->tm_sec; + _CurMP3Pos = s*s*s*s*s*s*s*s % randmp3->nTrackLength; + } + else + _CurMP3Pos = AudioManager.GetRandomNumber(0) % randmp3->nTrackLength; + } + } + else + _CurMP3Pos = 0; + + _bIsMp3Active = false; + } + + TRACE("end"); + + return true; +} + +void +cSampleManager::Terminate(void) +{ + for ( int32 i = 0; i < MAX_STREAMS; i++ ) + { + if ( mp3Stream[i] ) + { + AIL_pause_stream(mp3Stream[i], 1); + AIL_close_stream(mp3Stream[i]); + mp3Stream[i] = NULL; + } + } + + for ( int32 i = 0; i < MAX2DCHANNELS; i++ ) + { + if ( opened_2dsamples[i] ) + { + AIL_release_sample_handle(opened_2dsamples[i]); + opened_2dsamples[i] = NULL; + } + } + + release_existing(); + + _DeleteMP3Entries(); + + if ( nSampleBankMemoryStartAddress[SFX_BANK_0] != 0 ) + { + AIL_mem_free_lock((void *)nSampleBankMemoryStartAddress[SFX_BANK_0]); + nSampleBankMemoryStartAddress[SFX_BANK_0] = 0; + } + + if ( nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS] != 0 ) + { + AIL_mem_free_lock((void *)nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS]); + nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS] = 0; + } + + if ( DIG ) + { + AIL_close_digital_driver(DIG); + DIG = NULL; + } + + AIL_shutdown(); + + _bSampmanInitialised = false; +} + +bool +cSampleManager::CheckForAnAudioFileOnCD(void) +{ +#if !defined(NO_CDCHECK) // TODO: check steam, probably GTAVC_STEAM_PATCH needs to be added + char filepath[MAX_PATH]; + + strcpy(filepath, m_MiscomPath); + strcat(filepath, StreamedNameTable[STREAMED_SOUND_MISSION_COMPLETED4]); + + FILE *f = fopen(filepath, "rb"); + + if ( f ) + { + fclose(f); + DMAudio.SetMusicMasterVolume(FrontEndMenuManager.m_PrefsMusicVolume); + DMAudio.SetEffectsMasterVolume(FrontEndMenuManager.m_PrefsSfxVolume); + DMAudio.Service(); + + return true; + } + + DMAudio.SetMusicMasterVolume(0); + DMAudio.SetEffectsMasterVolume(0); + DMAudio.Service(); + + return false; + +#else + return true; +#endif // #if !defined(NO_CDCHECK) +} + +char +cSampleManager::GetCDAudioDriveLetter(void) +{ + if ( strlen(m_MiscomPath) != 0 ) + return m_MiscomPath[0]; + else + return '\0'; +} + +void +cSampleManager::UpdateEffectsVolume(void) //[Y], cSampleManager::UpdateSoundBuffers ? +{ + if ( _bSampmanInitialised ) + { + for ( int32 i = 0; i < MAXCHANNELS+MAX2DCHANNELS; i++ ) + { + if ( i < MAXCHANNELS ) + { + if ( opened_samples[i] && GetChannelUsedFlag(i) ) + { + if ( nChannelVolume[i] ) + { + AIL_set_3D_sample_volume(opened_samples[i], + m_nEffectsFadeVolume * nChannelVolume[i] * m_nEffectsVolume >> 14); + } + } + } + else + { + if ( opened_2dsamples[i - MAXCHANNELS] ) + { + if ( GetChannelUsedFlag(i - MAXCHANNELS) ) + { + if ( nChannelVolume[i - MAXCHANNELS] ) + { + AIL_set_sample_volume(opened_2dsamples[i - MAXCHANNELS], + m_nEffectsFadeVolume * nChannelVolume[i - MAXCHANNELS] * m_nEffectsVolume >> 14); + } + } + } + } + } + } +} + +void +cSampleManager::SetEffectsMasterVolume(uint8 nVolume) +{ + m_nEffectsVolume = nVolume; + UpdateEffectsVolume(); +} + +void +cSampleManager::SetMusicMasterVolume(uint8 nVolume) +{ + m_nMusicVolume = nVolume; +} + +void +cSampleManager::SetMP3BoostVolume(uint8 nVolume) +{ + m_nMP3BoostVolume = nVolume; +} + +void +cSampleManager::SetEffectsFadeVolume(uint8 nVolume) +{ + m_nEffectsFadeVolume = nVolume; + UpdateEffectsVolume(); +} + +void +cSampleManager::SetMusicFadeVolume(uint8 nVolume) +{ + m_nMusicFadeVolume = nVolume; +} + +void +cSampleManager::SetMonoMode(uint8 nMode) +{ + m_nMonoMode = nMode; +} + +bool +cSampleManager::LoadSampleBank(uint8 nBank) +{ + if ( CTimer::GetIsCodePaused() ) + return false; + + if ( MusicManager.IsInitialised() + && MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE + && nBank != SFX_BANK_0 ) + { + return false; + } + + if ( fseek(fpSampleDataHandle, nSampleBankDiscStartOffset[nBank], SEEK_SET) != 0 ) + return false; + + if ( fread((void *)nSampleBankMemoryStartAddress[nBank], 1, nSampleBankSize[nBank],fpSampleDataHandle) != nSampleBankSize[nBank] ) + return false; + + bSampleBankLoaded[nBank] = true; + + return true; +} + +void +cSampleManager::UnloadSampleBank(uint8 nBank) +{ + bSampleBankLoaded[nBank] = false; +} + +bool +cSampleManager::IsSampleBankLoaded(uint8 nBank) +{ + return bSampleBankLoaded[nBank]; +} + +bool +cSampleManager::IsPedCommentLoaded(uint32 nComment) +{ + int8 slot; + + for ( int32 i = 0; i < _TODOCONST(3); i++ ) + { + slot = nCurrentPedSlot - i - 1; +#ifdef FIX_BUGS + if (slot < 0) + slot += ARRAY_SIZE(nPedSlotSfx); +#endif + if ( nComment == nPedSlotSfx[slot] ) + return true; + } + + return false; +} + +int32 +cSampleManager::_GetPedCommentSlot(uint32 nComment) +{ + int8 slot; + + for ( int32 i = 0; i < _TODOCONST(3); i++ ) + { + slot = nCurrentPedSlot - i - 1; +#ifdef FIX_BUGS + if (slot < 0) + slot += ARRAY_SIZE(nPedSlotSfx); +#endif + if ( nComment == nPedSlotSfx[slot] ) + return slot; + } + + return -1; +} + +bool +cSampleManager::LoadPedComment(uint32 nComment) +{ + if ( CTimer::GetIsCodePaused() ) + return false; + + // no talking peds during cutsenes or the game end + if ( MusicManager.IsInitialised() ) + { + switch ( MusicManager.GetMusicMode() ) + { + case MUSICMODE_CUTSCENE: + { + return false; + + break; + } + } + } + + if ( fseek(fpSampleDataHandle, m_aSamples[nComment].nOffset, SEEK_SET) != 0 ) + return false; + + if ( fread((void *)(nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS] + PED_BLOCKSIZE*nCurrentPedSlot), 1, m_aSamples[nComment].nSize, fpSampleDataHandle) != m_aSamples[nComment].nSize ) + return false; + + nPedSlotSfxAddr[nCurrentPedSlot] = nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS] + PED_BLOCKSIZE*nCurrentPedSlot; + nPedSlotSfx [nCurrentPedSlot] = nComment; + + if ( ++nCurrentPedSlot >= MAX_PEDSFX ) + nCurrentPedSlot = 0; + + return true; +} + +int32 +cSampleManager::GetBankContainingSound(uint32 offset) +{ + if ( offset >= BankStartOffset[SFX_BANK_PED_COMMENTS] ) + return SFX_BANK_PED_COMMENTS; + + if ( offset >= BankStartOffset[SFX_BANK_0] ) + return SFX_BANK_0; + + return INVALID_SFX_BANK; +} + +int32 +cSampleManager::GetSampleBaseFrequency(uint32 nSample) +{ + return m_aSamples[nSample].nFrequency; +} + +int32 +cSampleManager::GetSampleLoopStartOffset(uint32 nSample) +{ + return m_aSamples[nSample].nLoopStart; +} + +int32 +cSampleManager::GetSampleLoopEndOffset(uint32 nSample) +{ + return m_aSamples[nSample].nLoopEnd; +} + +uint32 +cSampleManager::GetSampleLength(uint32 nSample) +{ + return m_aSamples[nSample].nSize >> 1; +} + +bool +cSampleManager::UpdateReverb(void) +{ + if ( !usingEAX ) + return false; + + if ( AudioManager.GetFrameCounter() & 15 ) + return false; + + float fRatio = 0.0f; + +#define MIN_DIST 0.5f +#define CALCULATE_RATIO(value, maxDist, maxRatio) (value > MIN_DIST && value < maxDist ? value / maxDist * maxRatio : 0) + + fRatio += CALCULATE_RATIO(AudioManager.GetReflectionsDistance(REFLECTION_CEIL_NORTH), 10.0f, 1/2.f); + fRatio += CALCULATE_RATIO(AudioManager.GetReflectionsDistance(REFLECTION_CEIL_SOUTH), 10.0f, 1/2.f); + fRatio += CALCULATE_RATIO(AudioManager.GetReflectionsDistance(REFLECTION_CEIL_WEST), 10.0f, 1/2.f); + fRatio += CALCULATE_RATIO(AudioManager.GetReflectionsDistance(REFLECTION_CEIL_EAST), 10.0f, 1/2.f); + + fRatio += CALCULATE_RATIO((AudioManager.GetReflectionsDistance(REFLECTION_NORTH) + AudioManager.GetReflectionsDistance(REFLECTION_SOUTH)) / 2.f, 4.0f, 1/3.f); + fRatio += CALCULATE_RATIO((AudioManager.GetReflectionsDistance(REFLECTION_WEST) + AudioManager.GetReflectionsDistance(REFLECTION_EAST)) / 2.f, 4.0f, 1/3.f); + +#undef CALCULATE_RATIO +#undef MIN_DIST + + fRatio = clamp(fRatio, 0.0f, 0.6f); + + if ( fRatio == _fPrevEaxRatioDestination ) + return false; + + if ( usingEAX3 ) + { + fRatio = Min(fRatio * 1.67f, 1.0f); + if ( EAX3ListenerInterpolate(&StartEAX3, &FinishEAX3, fRatio, &EAX3Params, false) ) + { + AIL_set_3D_provider_preference(opened_provider, "EAX all parameters", &EAX3Params); + _fEffectsLevel = fRatio * 0.75f; + } + } + else + { + if ( _usingMilesFast2D ) + _fEffectsLevel = fRatio * 0.8f; + else + _fEffectsLevel = fRatio * 0.22f; + } + _fEffectsLevel = Min(_fEffectsLevel, 1.0f); + + _fPrevEaxRatioDestination = fRatio; + + return true; +} + +void +cSampleManager::SetChannelReverbFlag(uint32 nChannel, uint8 nReverbFlag) +{ + bool b2d = false; + + switch ( nChannel ) + { + case CHANNEL2D: + { + b2d = true; + break; + } + } + + if ( usingEAX ) + { + if ( nReverbFlag != 0 ) + { + if ( !b2d ) + AIL_set_3D_sample_effects_level(opened_samples[nChannel], _fEffectsLevel); + } + else + { + if ( !b2d ) + AIL_set_3D_sample_effects_level(opened_samples[nChannel], 0.0f); + } + } +} + +bool +cSampleManager::InitialiseChannel(uint32 nChannel, uint32 nSfx, uint8 nBank) +{ + bool b2d = false; + + switch ( nChannel ) + { + case CHANNEL2D: + { + b2d = true; + break; + } + } + + int32 addr; + + if ( nSfx < SAMPLEBANK_MAX ) + { + if ( !IsSampleBankLoaded(nBank) ) + return false; + + addr = nSampleBankMemoryStartAddress[nBank] + m_aSamples[nSfx].nOffset - m_aSamples[BankStartOffset[nBank]].nOffset; + } + else + { + if ( !IsPedCommentLoaded(nSfx) ) + return false; + + int32 slot = _GetPedCommentSlot(nSfx); + + addr = nPedSlotSfxAddr[slot]; + } + + if ( b2d ) + { + if ( opened_2dsamples[nChannel - MAXCHANNELS] ) + { + AIL_set_sample_address(opened_2dsamples[nChannel - MAXCHANNELS], (void *)addr, m_aSamples[nSfx].nSize); + return true; + } + else + return false; + } + else + { + AILSOUNDINFO info; + + info.format = WAVE_FORMAT_PCM; + info.data_ptr = (void *)addr; + info.channels = 1; + info.data_len = m_aSamples[nSfx].nSize; + info.rate = m_aSamples[nSfx].nFrequency; + info.bits = 16; + + if ( AIL_set_3D_sample_info(opened_samples[nChannel], &info) == 0 ) + { + OutputDebugString(AIL_last_error()); + return false; + } + + return true; + } +} + +void +cSampleManager::SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume) +{ + uint32 vol = nVolume; + if ( vol > MAX_VOLUME ) vol = MAX_VOLUME; + + nChannelVolume[nChannel] = vol; + + // increase the volume for JB.MP3 and S4_BDBD.MP3 + if (MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE ) { + if (MusicManager.GetCurrentTrack() == STREAMED_SOUND_CUTSCENE_FINALE) + nChannelVolume[nChannel] = 0; + else + nChannelVolume[nChannel] >>= 2; + } + + if ( opened_samples[nChannel] ) + AIL_set_3D_sample_volume(opened_samples[nChannel], m_nEffectsFadeVolume*nChannelVolume[nChannel]*m_nEffectsVolume >> 14); + +} + +void +cSampleManager::SetChannel3DPosition(uint32 nChannel, float fX, float fY, float fZ) +{ + if ( opened_samples[nChannel] ) + AIL_set_3D_position(opened_samples[nChannel], -fX, fY, fZ); +} + +void +cSampleManager::SetChannel3DDistances(uint32 nChannel, float fMax, float fMin) +{ + if ( opened_samples[nChannel] ) + AIL_set_3D_sample_distances(opened_samples[nChannel], fMax, fMin); +} + +void +cSampleManager::SetChannelVolume(uint32 nChannel, uint32 nVolume) +{ + uint32 vol = nVolume; + if ( vol > MAX_VOLUME ) vol = MAX_VOLUME; + + switch ( nChannel ) + { + case CHANNEL2D: + { + nChannelVolume[nChannel] = vol; + + // increase the volume for JB.MP3 and S4_BDBD.MP3 + if ( MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE + && MusicManager.GetCurrentTrack() != STREAMED_SOUND_CUTSCENE_FINALE ) + { + nChannelVolume[nChannel] >>= 2; + } + + if ( opened_2dsamples[nChannel - MAXCHANNELS] ) + { + AIL_set_sample_volume(opened_2dsamples[nChannel - MAXCHANNELS], + m_nEffectsFadeVolume*vol*m_nEffectsVolume >> 14); + } + + break; + } + } +} + +void +cSampleManager::SetChannelPan(uint32 nChannel, uint32 nPan) +{ + switch ( nChannel ) + { + case CHANNEL2D: + { +#ifndef FIX_BUGS + if ( opened_samples[nChannel - MAXCHANNELS] ) // BUG +#else + if ( opened_2dsamples[nChannel - MAXCHANNELS] ) +#endif + AIL_set_sample_pan(opened_2dsamples[nChannel - MAXCHANNELS], nPan); + + break; + } + } +} + +void +cSampleManager::SetChannelFrequency(uint32 nChannel, uint32 nFreq) +{ + bool b2d = false; + + switch ( nChannel ) + { + case CHANNEL2D: + { + b2d = true; + break; + } + } + + if ( b2d ) + { + if ( opened_2dsamples[nChannel - MAXCHANNELS] ) + AIL_set_sample_playback_rate(opened_2dsamples[nChannel - MAXCHANNELS], nFreq); + } + else + { + if ( opened_samples[nChannel] ) + AIL_set_3D_sample_playback_rate(opened_samples[nChannel], nFreq); + } +} + +void +cSampleManager::SetChannelLoopPoints(uint32 nChannel, uint32 nLoopStart, int32 nLoopEnd) +{ + bool b2d = false; + + switch ( nChannel ) + { + case CHANNEL2D: + { + b2d = true; + break; + } + } + + if ( b2d ) + { + if ( opened_2dsamples[nChannel - MAXCHANNELS] ) + AIL_set_sample_loop_block(opened_2dsamples[nChannel - MAXCHANNELS], nLoopStart, nLoopEnd); + } + else + { + if ( opened_samples[nChannel] ) + AIL_set_3D_sample_loop_block(opened_samples[nChannel], nLoopStart, nLoopEnd); + } +} + +void +cSampleManager::SetChannelLoopCount(uint32 nChannel, uint32 nLoopCount) +{ + bool b2d = false; + + switch ( nChannel ) + { + case CHANNEL2D: + { + b2d = true; + break; + } + } + + if ( b2d ) + { + if ( opened_2dsamples[nChannel - MAXCHANNELS] ) + AIL_set_sample_loop_count(opened_2dsamples[nChannel - MAXCHANNELS], nLoopCount); + } + else + { + if ( opened_samples[nChannel] ) + AIL_set_3D_sample_loop_count(opened_samples[nChannel], nLoopCount); + } +} + +bool +cSampleManager::GetChannelUsedFlag(uint32 nChannel) +{ + bool b2d = false; + + switch ( nChannel ) + { + case CHANNEL2D: + { + b2d = true; + break; + } + } + + if ( b2d ) + { + if ( opened_2dsamples[nChannel - MAXCHANNELS] ) + return AIL_sample_status(opened_2dsamples[nChannel - MAXCHANNELS]) == SMP_PLAYING; + else + return false; + } + else + { + if ( opened_samples[nChannel] ) + return AIL_3D_sample_status(opened_samples[nChannel]) == SMP_PLAYING; + else + return false; + } + +} + +void +cSampleManager::StartChannel(uint32 nChannel) +{ + bool b2d = false; + + switch ( nChannel ) + { + case CHANNEL2D: + { + b2d = true; + break; + } + } + + if ( b2d ) + { + if ( opened_2dsamples[nChannel - MAXCHANNELS] ) + AIL_start_sample(opened_2dsamples[nChannel - MAXCHANNELS]); + } + else + { + if ( opened_samples[nChannel] ) + AIL_start_3D_sample(opened_samples[nChannel]); + } +} + +void +cSampleManager::StopChannel(uint32 nChannel) +{ + bool b2d = false; + + switch ( nChannel ) + { + case CHANNEL2D: + { + b2d = true; + break; + } + } + + if ( b2d ) + { + if ( opened_2dsamples[nChannel - MAXCHANNELS] ) + AIL_end_sample(opened_2dsamples[nChannel - MAXCHANNELS]); + } + else + { + if ( opened_samples[nChannel] ) + { + if ( AIL_3D_sample_status(opened_samples[nChannel]) == SMP_PLAYING ) + AIL_end_3D_sample(opened_samples[nChannel]); + } + } +} + +void +cSampleManager::PreloadStreamedFile(uint32 nFile, uint8 nStream) +{ + if ( m_bInitialised ) + { + if ( nFile < TOTAL_STREAMED_SOUNDS ) + { + if ( mp3Stream[nStream] ) + { + AIL_pause_stream(mp3Stream[nStream], 1); + AIL_close_stream(mp3Stream[nStream]); + } + + char filepath[MAX_PATH]; + + strcpy(filepath, nFile < STREAMED_SOUND_MISSION_COMPLETED4 ? m_MP3FilesPath : (nFile < STREAMED_SOUND_MISSION_MOBR1 ? m_MiscomPath : m_WavFilesPath)); + strcat(filepath, StreamedNameTable[nFile]); + + mp3Stream[nStream] = AIL_open_stream(DIG, filepath, 0); + + if ( mp3Stream[nStream] ) + { + AIL_set_stream_loop_count(mp3Stream[nStream], 1); + AIL_service_stream(mp3Stream[nStream], 1); + } + else + OutputDebugString(AIL_last_error()); + } + } +} + +void +cSampleManager::PauseStream(uint8 nPauseFlag, uint8 nStream) +{ + if ( m_bInitialised ) + { + if ( mp3Stream[nStream] ) + AIL_pause_stream(mp3Stream[nStream], nPauseFlag != 0); + } +} + +void +cSampleManager::StartPreloadedStreamedFile(uint8 nStream) +{ + if ( m_bInitialised ) + { + if ( mp3Stream[nStream] ) + AIL_start_stream(mp3Stream[nStream]); + } +} + +bool +cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream) +{ + int i = 0; + uint32 position = nPos; + char filename[MAX_PATH]; + + if ( !m_bInitialised || nFile >= TOTAL_STREAMED_SOUNDS ) + return false; + + if ( mp3Stream[nStream] ) + { + AIL_pause_stream(mp3Stream[nStream], 1); + AIL_close_stream(mp3Stream[nStream]); + } + if ( nFile == STREAMED_SOUND_RADIO_MP3_PLAYER ) + { + do + { + // Just switched to MP3 player + if ( !_bIsMp3Active && i == 0 ) + { + if ( nPos > nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER] ) + position = 0; + tMP3Entry *e = _pMP3List; + + // Try to continue from previous song, if already started + if(!_GetMP3PosFromStreamPos(&position, &e) && !e) { + nFile = 0; + strcpy(filename, m_MiscomPath); + strcat(filename, StreamedNameTable[nFile]); + mp3Stream[nStream] = + AIL_open_stream(DIG, filename, 0); + if(mp3Stream[nStream]) { + AIL_set_stream_loop_count(mp3Stream[nStream], nStreamLoopedFlag[nStream] ? 0 : 1); + nStreamLoopedFlag[nStream] = true; + AIL_set_stream_ms_position(mp3Stream[nStream], position); + AIL_pause_stream(mp3Stream[nStream], 0); + return true; + } + return false; + + } else { + if ( e->pLinkPath != NULL ) + mp3Stream[nStream] = AIL_open_stream(DIG, e->pLinkPath, 0); + else { + strcpy(filename, _mp3DirectoryPath); + strcat(filename, e->aFilename); + + mp3Stream[nStream] = AIL_open_stream(DIG, filename, 0); + } + + if ( mp3Stream[nStream] ) { + AIL_set_stream_loop_count(mp3Stream[nStream], 1); + AIL_set_stream_ms_position(mp3Stream[nStream], position); + AIL_pause_stream(mp3Stream[nStream], 0); + + _bIsMp3Active = true; + + return true; + } + // fall through, start playing from another song + } + } else { + if(++_CurMP3Index >= nNumMP3s) _CurMP3Index = 0; + + _CurMP3Pos = 0; + + tMP3Entry *mp3 = _GetMP3EntryByIndex(_CurMP3Index); + if ( !mp3 ) + { + mp3 = _pMP3List; + if ( !_pMP3List ) + { + nFile = 0; + _bIsMp3Active = 0; + strcpy(filename, m_MiscomPath); + strcat(filename, StreamedNameTable[nFile]); + + mp3Stream[nStream] = + AIL_open_stream(DIG, filename, 0); + if(mp3Stream[nStream]) { + AIL_set_stream_loop_count( + mp3Stream[nStream], nStreamLoopedFlag[nStream] ? 0 : 1); + nStreamLoopedFlag[nStream] = true; + AIL_set_stream_ms_position( + mp3Stream[nStream], position); + AIL_pause_stream(mp3Stream[nStream], + 0); + return true; + } + return false; + } + } + if(mp3->pLinkPath != NULL) + mp3Stream[nStream] = AIL_open_stream(DIG, mp3->pLinkPath, 0); + else { + strcpy(filename, _mp3DirectoryPath); + strcat(filename, mp3->aFilename); + + mp3Stream[nStream] = + AIL_open_stream(DIG, filename, 0); + } + + if(mp3Stream[nStream]) { + AIL_set_stream_loop_count(mp3Stream[nStream], 1); + AIL_set_stream_ms_position(mp3Stream[nStream], 0); + AIL_pause_stream(mp3Stream[nStream], 0); +#ifdef FIX_BUGS + _bIsMp3Active = true; +#endif + return true; + } + + } + _bIsMp3Active = 0; + } + while ( ++i < nNumMP3s ); + position = 0; + nFile = 0; + } + strcpy(filename, m_MiscomPath); + strcat(filename, StreamedNameTable[nFile]); + + mp3Stream[nStream] = AIL_open_stream(DIG, filename, 0); + if ( mp3Stream[nStream] ) + { + AIL_set_stream_loop_count(mp3Stream[nStream], nStreamLoopedFlag[nStream] ? 0 : 1); + nStreamLoopedFlag[nStream] = true; + AIL_set_stream_ms_position(mp3Stream[nStream], position); + AIL_pause_stream(mp3Stream[nStream], 0); + return true; + } + return false; +} + +void +cSampleManager::StopStreamedFile(uint8 nStream) +{ + if ( m_bInitialised ) + { + if ( mp3Stream[nStream] ) + { + AIL_pause_stream(mp3Stream[nStream], 1); + + AIL_close_stream(mp3Stream[nStream]); + mp3Stream[nStream] = NULL; + + if ( nStream == 0 ) + _bIsMp3Active = false; + } + } +} + +int32 +cSampleManager::GetStreamedFilePosition(uint8 nStream) +{ + S32 currentms; + + if ( m_bInitialised ) + { + if ( mp3Stream[nStream] ) + { + if ( _bIsMp3Active ) + { + tMP3Entry *mp3 = _GetMP3EntryByIndex(_CurMP3Index); + + if ( mp3 != NULL ) + { + AIL_stream_ms_position(mp3Stream[nStream], NULL, ¤tms); + return currentms + mp3->nTrackStreamPos; + } + else + return 0; + } + else + { + AIL_stream_ms_position(mp3Stream[nStream], NULL, ¤tms); + return currentms; + } + } + } + + return 0; +} + +void +cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream) +{ + uint8 vol = nVolume; + float boostMult = 0.0f; + + if ( m_bInitialised ) + { + if ( vol > MAX_VOLUME ) vol = MAX_VOLUME; + + if ( MusicManager.GetRadioInCar() == USERTRACK && !MusicManager.CheckForMusicInterruptions() ) + boostMult = m_nMP3BoostVolume / 64.f; + + nStreamVolume[nStream] = vol; + nStreamPan[nStream] = nPan; + + if ( mp3Stream[nStream] ) + { + if ( nEffectFlag ) + { + if ( nStream == 1 || nStream == 2 ) + AIL_set_stream_volume(mp3Stream[nStream], 128*vol*m_nEffectsVolume >> 14); + else + AIL_set_stream_volume(mp3Stream[nStream], m_nEffectsFadeVolume*vol*m_nEffectsVolume >> 14); + } + else + AIL_set_stream_volume(mp3Stream[nStream], (m_nMusicFadeVolume*vol*(uint32)(m_nMusicVolume * boostMult + m_nMusicVolume)) >> 14); + + AIL_set_stream_pan(mp3Stream[nStream], nPan); + } + } +} + +int32 +cSampleManager::GetStreamedFileLength(uint8 nStream) +{ + if ( m_bInitialised ) + return nStreamLength[nStream]; + + return 0; +} + +bool +cSampleManager::IsStreamPlaying(uint8 nStream) +{ + if ( m_bInitialised ) + { + if ( mp3Stream[nStream] ) + { + if ( AIL_stream_status(mp3Stream[nStream]) == SMP_PLAYING ) + return true; + else + return false; + } + } + + return false; +} + +bool +cSampleManager::InitialiseSampleBanks(void) +{ + int32 nBank = SFX_BANK_0; + + fpSampleDescHandle = fopen(SampleBankDescFilename, "rb"); + if ( fpSampleDescHandle == NULL ) + return false; + + fpSampleDataHandle = fopen(SampleBankDataFilename, "rb"); + if ( fpSampleDataHandle == NULL ) + { + fclose(fpSampleDescHandle); + fpSampleDescHandle = NULL; + + return false; + } + + fseek(fpSampleDataHandle, 0, SEEK_END); + _nSampleDataEndOffset = ftell(fpSampleDataHandle); + rewind(fpSampleDataHandle); + + fread(m_aSamples, sizeof(tSample), TOTAL_AUDIO_SAMPLES, fpSampleDescHandle); + + fclose(fpSampleDescHandle); + fpSampleDescHandle = NULL; + + for ( int32 i = 0; i < TOTAL_AUDIO_SAMPLES; i++ ) + { +#ifdef FIX_BUGS + if (nBank >= MAX_SFX_BANKS) break; +#endif + if ( BankStartOffset[nBank] == BankStartOffset[SFX_BANK_0] + i ) + { + nSampleBankDiscStartOffset[nBank] = m_aSamples[i].nOffset; + nBank++; + } + } + + nSampleBankSize[SFX_BANK_0] = nSampleBankDiscStartOffset[SFX_BANK_PED_COMMENTS] - nSampleBankDiscStartOffset[SFX_BANK_0]; + nSampleBankSize[SFX_BANK_PED_COMMENTS] = _nSampleDataEndOffset - nSampleBankDiscStartOffset[SFX_BANK_PED_COMMENTS]; + + return true; +} + + +void +cSampleManager::SetStreamedFileLoopFlag(uint8 nLoopFlag, uint8 nChannel) +{ + if (m_bInitialised) + nStreamLoopedFlag[nChannel] = nLoopFlag; +} + +#endif diff --git a/src/audio/sampman_null.cpp b/src/audio/sampman_null.cpp new file mode 100644 index 0000000..e9a9eaa --- /dev/null +++ b/src/audio/sampman_null.cpp @@ -0,0 +1,383 @@ +#include "common.h" +#if !defined(AUDIO_OAL) && !defined(AUDIO_MSS) +#include "sampman.h" +#include "AudioManager.h" + +cSampleManager SampleManager; +bool _bSampmanInitialised = false; + +uint32 BankStartOffset[MAX_SFX_BANKS]; +uint32 nNumMP3s; + +cSampleManager::cSampleManager(void) +{ + ; +} + +cSampleManager::~cSampleManager(void) +{ + +} + +void cSampleManager::SetSpeakerConfig(int32 nConfig) +{ + +} + +uint32 cSampleManager::GetMaximumSupportedChannels(void) +{ + return MAXCHANNELS; +} + +uint32 cSampleManager::GetNum3DProvidersAvailable() +{ + return 1; +} + +void cSampleManager::SetNum3DProvidersAvailable(uint32 num) +{ + +} + +char *cSampleManager::Get3DProviderName(uint8 id) +{ + static char name[64] = "NULL"; + return name; +} + +void cSampleManager::Set3DProviderName(uint8 id, char *name) +{ + +} + +int8 cSampleManager::GetCurrent3DProviderIndex(void) +{ + return 0; +} + +int8 cSampleManager::SetCurrent3DProvider(uint8 nProvider) +{ + return 0; +} + +bool +cSampleManager::IsMP3RadioChannelAvailable(void) +{ + return nNumMP3s != 0; +} + + +void cSampleManager::ReleaseDigitalHandle(void) +{ +} + +void cSampleManager::ReacquireDigitalHandle(void) +{ +} + +bool +cSampleManager::Initialise(void) +{ + return true; +} + +void +cSampleManager::Terminate(void) +{ + +} + +bool cSampleManager::CheckForAnAudioFileOnCD(void) +{ + return true; +} + +char cSampleManager::GetCDAudioDriveLetter(void) +{ + return '\0'; +} + +void +cSampleManager::UpdateEffectsVolume(void) +{ + +} + +void +cSampleManager::SetEffectsMasterVolume(uint8 nVolume) +{ +} + +void +cSampleManager::SetMusicMasterVolume(uint8 nVolume) +{ +} + +void +cSampleManager::SetMusicMasterVolume(uint8 nVolume) +{ +} + +void +cSampleManager::SetEffectsFadeVolume(uint8 nVolume) +{ +} + +void +cSampleManager::SetMusicFadeVolume(uint8 nVolume) +{ +} + +void +cSampleManager::SetMonoMode(uint8 nMode) +{ +} + +bool +cSampleManager::LoadSampleBank(uint8 nBank) +{ + ASSERT( nBank < MAX_SFX_BANKS ); + return false; +} + +void +cSampleManager::UnloadSampleBank(uint8 nBank) +{ + ASSERT( nBank < MAX_SFX_BANKS ); +} + +bool +cSampleManager::IsSampleBankLoaded(uint8 nBank) +{ + ASSERT( nBank < MAX_SFX_BANKS ); + + return false; +} + +bool +cSampleManager::IsPedCommentLoaded(uint32 nComment) +{ + ASSERT( nComment < TOTAL_AUDIO_SAMPLES ); + + return false; +} + + +int32 +cSampleManager::_GetPedCommentSlot(uint32 nComment) +{ + return -1; +} + +bool +cSampleManager::LoadPedComment(uint32 nComment) +{ + ASSERT( nComment < TOTAL_AUDIO_SAMPLES ); + return false; +} + +int32 +cSampleManager::GetBankContainingSound(uint32 offset) +{ + return INVALID_SFX_BANK; +} + +int32 +cSampleManager::GetSampleBaseFrequency(uint32 nSample) +{ + ASSERT( nSample < TOTAL_AUDIO_SAMPLES ); + return 0; +} + +int32 +cSampleManager::GetSampleLoopStartOffset(uint32 nSample) +{ + ASSERT( nSample < TOTAL_AUDIO_SAMPLES ); + return 0; +} + +int32 +cSampleManager::GetSampleLoopEndOffset(uint32 nSample) +{ + ASSERT( nSample < TOTAL_AUDIO_SAMPLES ); + return 0; +} + +uint32 +cSampleManager::GetSampleLength(uint32 nSample) +{ + ASSERT( nSample < TOTAL_AUDIO_SAMPLES ); + return 0; +} + +bool cSampleManager::UpdateReverb(void) +{ + return false; +} + +void +cSampleManager::SetChannelReverbFlag(uint32 nChannel, uint8 nReverbFlag) +{ + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); +} + +bool +cSampleManager::InitialiseChannel(uint32 nChannel, uint32 nSfx, uint8 nBank) +{ + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); + return false; +} + +void +cSampleManager::SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume) +{ + ASSERT( nChannel != CHANNEL2D ); + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); +} + +void +cSampleManager::SetChannel3DPosition(uint32 nChannel, float fX, float fY, float fZ) +{ + ASSERT( nChannel != CHANNEL2D ); + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); +} + +void +cSampleManager::SetChannel3DDistances(uint32 nChannel, float fMax, float fMin) +{ + ASSERT( nChannel != CHANNEL2D ); + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); +} + +void +cSampleManager::SetChannelVolume(uint32 nChannel, uint32 nVolume) +{ + ASSERT( nChannel == CHANNEL2D ); + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); +} + +void +cSampleManager::SetChannelPan(uint32 nChannel, uint32 nPan) +{ + ASSERT(nChannel == CHANNEL2D); + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); +} + +void +cSampleManager::SetChannelFrequency(uint32 nChannel, uint32 nFreq) +{ + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); +} + +void +cSampleManager::SetChannelLoopPoints(uint32 nChannel, uint32 nLoopStart, int32 nLoopEnd) +{ + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); +} + +void +cSampleManager::SetChannelLoopCount(uint32 nChannel, uint32 nLoopCount) +{ + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); +} + +bool +cSampleManager::GetChannelUsedFlag(uint32 nChannel) +{ + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); + + return false; +} + +void +cSampleManager::StartChannel(uint32 nChannel) +{ + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); +} + +void +cSampleManager::StopChannel(uint32 nChannel) +{ + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); +} + +void +cSampleManager::PreloadStreamedFile(uint32 nFile, uint8 nStream) +{ + ASSERT( nStream < MAX_STREAMS ); +} + +void +cSampleManager::PauseStream(uint8 nPauseFlag, uint8 nStream) +{ + ASSERT( nStream < MAX_STREAMS ); +} + +void +cSampleManager::StartPreloadedStreamedFile(uint8 nStream) +{ + ASSERT( nStream < MAX_STREAMS ); +} + +bool +cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream) +{ + ASSERT( nStream < MAX_STREAMS ); + + return false; +} + +void +cSampleManager::StopStreamedFile(uint8 nStream) +{ + ASSERT( nStream < MAX_STREAMS ); +} + +int32 +cSampleManager::GetStreamedFilePosition(uint8 nStream) +{ + ASSERT( nStream < MAX_STREAMS ); + + return 0; +} + +void +cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream) +{ + ASSERT( nStream < MAX_STREAMS ); +} + +int32 +cSampleManager::GetStreamedFileLength(uint8 nStream) +{ + ASSERT( nStream < TOTAL_STREAMED_SOUNDS ); + + return 1; +} + +bool +cSampleManager::IsStreamPlaying(uint8 nStream) +{ + ASSERT( nStream < MAX_STREAMS ); + + return false; +} + +bool +cSampleManager::InitialiseSampleBanks(void) +{ + + return true; +} + +void +cSampleManager::SetStreamedFileLoopFlag(uint8 nLoopFlag, uint8 nChannel) +{ +} + +int8 cSampleManager::AutoDetect3DProviders() +{ + return -1; +} + +#endif diff --git a/src/audio/sampman_oal.cpp b/src/audio/sampman_oal.cpp new file mode 100644 index 0000000..5a300cf --- /dev/null +++ b/src/audio/sampman_oal.cpp @@ -0,0 +1,2073 @@ +//#define JUICY_OAL + +#ifdef AUDIO_OAL +#include <time.h> + +#include "eax.h" +#include "eax-util.h" + +#ifdef _WIN32 +#include <io.h> +#include <AL/al.h> +#include <AL/alc.h> +#include <AL/alext.h> +#include <AL/efx.h> +#include <AL/efx-presets.h> + +// for user MP3s +#include <direct.h> +#include <shlobj.h> +#include <shlguid.h> +#else +#define _getcwd getcwd +#endif + +#if defined _MSC_VER && !defined CMAKE_NO_AUTOLINK +#pragma comment( lib, "OpenAL32.lib" ) +#endif + +#include "common.h" +#include "crossplatform.h" + +#include "sampman.h" + +#include "oal/oal_utils.h" +#include "oal/aldlist.h" +#include "oal/channel.h" +#include "oal/stream.h" + +#include "AudioManager.h" +#include "MusicManager.h" +#include "Frontend.h" +#include "Timer.h" +#ifdef AUDIO_OAL_USE_OPUS +#include <opusfile.h> +#endif + +//TODO: fix eax3 reverb +//TODO: max channels + +cSampleManager SampleManager; +bool _bSampmanInitialised = false; + +uint32 BankStartOffset[MAX_SFX_BANKS]; + +int prevprovider=-1; +int curprovider=-1; +int usingEAX=0; +int usingEAX3=0; +//int speaker_type=0; +ALCdevice *ALDevice = NULL; +ALCcontext *ALContext = NULL; +unsigned int _maxSamples; +float _fPrevEaxRatioDestination; +bool _usingEFX; +float _fEffectsLevel; +ALuint ALEffect = AL_EFFECT_NULL; +ALuint ALEffectSlot = AL_EFFECTSLOT_NULL; +struct +{ + char id[256]; + char name[256]; + int sources; +}providers[MAXPROVIDERS]; + +int defaultProvider; + + +char SampleBankDescFilename[] = "audio/sfx.SDT"; +char SampleBankDataFilename[] = "audio/sfx.RAW"; + +FILE *fpSampleDescHandle; +#ifdef OPUS_SFX +OggOpusFile *fpSampleDataHandle; +#else +FILE *fpSampleDataHandle; +#endif +bool bSampleBankLoaded [MAX_SFX_BANKS]; +int32 nSampleBankDiscStartOffset [MAX_SFX_BANKS]; +int32 nSampleBankSize [MAX_SFX_BANKS]; +uintptr nSampleBankMemoryStartAddress[MAX_SFX_BANKS]; +int32 _nSampleDataEndOffset; + +int32 nPedSlotSfx [MAX_PEDSFX]; +int32 nPedSlotSfxAddr[MAX_PEDSFX]; +uint8 nCurrentPedSlot; + +CChannel aChannel[MAXCHANNELS+MAX2DCHANNELS]; +uint8 nChannelVolume[MAXCHANNELS+MAX2DCHANNELS]; + +uint32 nStreamLength[TOTAL_STREAMED_SOUNDS]; +ALuint ALStreamSources[MAX_STREAMS][2]; +ALuint ALStreamBuffers[MAX_STREAMS][NUM_STREAMBUFFERS]; + +struct tMP3Entry +{ + char aFilename[MAX_PATH]; + + uint32 nTrackLength; + uint32 nTrackStreamPos; + + tMP3Entry* pNext; + char* pLinkPath; +}; + +uint32 nNumMP3s; +tMP3Entry* _pMP3List; +char _mp3DirectoryPath[MAX_PATH]; +CStream *aStream[MAX_STREAMS]; +uint8 nStreamPan [MAX_STREAMS]; +uint8 nStreamVolume[MAX_STREAMS]; +uint8 nStreamLoopedFlag[MAX_STREAMS]; +uint32 _CurMP3Index; +int32 _CurMP3Pos; +bool _bIsMp3Active; +/////////////////////////////////////////////////////////////// +// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS +EAXLISTENERPROPERTIES StartEAX3 = + {26, 1.7f, 0.8f, -1000, -1000, -100, 4.42f, 0.14f, 1.00f, 429, 0.014f, 0.00f,0.00f,0.00f, 1023, 0.021f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 2727.1f, 250.0f, 0.00f, 0x3f }; + +EAXLISTENERPROPERTIES FinishEAX3 = + {26, 100.0f, 1.0f, 0, -1000, -2200, 20.0f, 1.39f, 1.00f, 1000, 0.069f, 0.00f,0.00f,0.00f, 400, 0.100f, 0.00f,0.00f,0.00f, 0.250f, 1.000f, 3.982f, 0.000f, -18.0f, 3530.8f, 417.9f, 6.70f, 0x3f }; + +EAXLISTENERPROPERTIES EAX3Params; + + +bool IsFXSupported() +{ + return usingEAX || usingEAX3 || _usingEFX; +} + +void EAX_SetAll(const EAXLISTENERPROPERTIES *allparameters) +{ + if ( usingEAX || usingEAX3 ) + EAX3_Set(ALEffect, allparameters); + else + EFX_Set(ALEffect, allparameters); +} + +static void +add_providers() +{ + SampleManager.SetNum3DProvidersAvailable(0); + + ALDeviceList *pDeviceList = NULL; + pDeviceList = new ALDeviceList(); + + if ((pDeviceList) && (pDeviceList->GetNumDevices())) + { + const int devNumber = Min(pDeviceList->GetNumDevices(), MAXPROVIDERS); + int n = 0; + + for (int i = 0; i < devNumber; i++) + { + if ( n < MAXPROVIDERS ) + { + strcpy(providers[n].id, pDeviceList->GetDeviceName(i)); + strncpy(providers[n].name, pDeviceList->GetDeviceName(i), sizeof(providers[n].name)); + providers[n].sources = pDeviceList->GetMaxNumSources(i); + SampleManager.Set3DProviderName(n, providers[n].name); + n++; + } + + if ( alGetEnumValue("AL_EFFECT_EAXREVERB") != 0 + || pDeviceList->IsExtensionSupported(i, ADEXT_EAX2) + || pDeviceList->IsExtensionSupported(i, ADEXT_EAX3) + || pDeviceList->IsExtensionSupported(i, ADEXT_EAX4) + || pDeviceList->IsExtensionSupported(i, ADEXT_EAX5) ) + { + if ( n < MAXPROVIDERS ) + { + strcpy(providers[n].id, pDeviceList->GetDeviceName(i)); + strncpy(providers[n].name, pDeviceList->GetDeviceName(i), sizeof(providers[n].name)); + strcat(providers[n].name, " EAX"); + providers[n].sources = pDeviceList->GetMaxNumSources(i); + SampleManager.Set3DProviderName(n, providers[n].name); + n++; + } + + if ( n < MAXPROVIDERS ) + { + strcpy(providers[n].id, pDeviceList->GetDeviceName(i)); + strncpy(providers[n].name, pDeviceList->GetDeviceName(i), sizeof(providers[n].name)); + strcat(providers[n].name, " EAX3"); + providers[n].sources = pDeviceList->GetMaxNumSources(i); + SampleManager.Set3DProviderName(n, providers[n].name); + n++; + } + } + } + SampleManager.SetNum3DProvidersAvailable(n); + + for(int j=n;j<MAXPROVIDERS;j++) + SampleManager.Set3DProviderName(j, NULL); + + defaultProvider = pDeviceList->GetDefaultDevice(); + if ( defaultProvider > MAXPROVIDERS ) + defaultProvider = 0; + } + + delete pDeviceList; +} + +static void +release_existing() +{ + for ( int32 i = 0; i < MAXCHANNELS; i++ ) + aChannel[i].Term(); + aChannel[CHANNEL2D].Term(); + + if ( IsFXSupported() ) + { + if ( alIsEffect(ALEffect) ) + { + alEffecti(ALEffect, AL_EFFECT_TYPE, AL_EFFECT_NULL); + alDeleteEffects(1, &ALEffect); + ALEffect = AL_EFFECT_NULL; + } + + if (alIsAuxiliaryEffectSlot(ALEffectSlot)) + { + alAuxiliaryEffectSloti(ALEffectSlot, AL_EFFECTSLOT_EFFECT, AL_EFFECT_NULL); + + alDeleteAuxiliaryEffectSlots(1, &ALEffectSlot); + ALEffectSlot = AL_EFFECTSLOT_NULL; + } + } + + for ( int32 i = 0; i < MAX_STREAMS; i++ ) + { + CStream *stream = aStream[i]; + if (stream) + stream->ProviderTerm(); + + alDeleteBuffers(NUM_STREAMBUFFERS, ALStreamBuffers[i]); + } + alDeleteSources(MAX_STREAMS*2, ALStreamSources[0]); + + CChannel::DestroyChannels(); + + if ( ALContext ) + { + alcMakeContextCurrent(NULL); + alcSuspendContext(ALContext); + alcDestroyContext(ALContext); + } + if ( ALDevice ) + alcCloseDevice(ALDevice); + + ALDevice = NULL; + ALContext = NULL; + + _fPrevEaxRatioDestination = 0.0f; + _usingEFX = false; + _fEffectsLevel = 0.0f; + + DEV("release_existing()\n"); +} + +static bool +set_new_provider(int index) +{ + if ( curprovider == index ) + return true; + + curprovider = index; + + release_existing(); + + if ( curprovider != -1 ) + { + DEV("set_new_provider()\n"); + + //TODO: + _maxSamples = MAXCHANNELS; + + ALCint attr[] = {ALC_FREQUENCY,MAX_FREQ, + ALC_MONO_SOURCES, MAX_STREAMS * 2 + MAXCHANNELS, + 0, + }; + + ALDevice = alcOpenDevice(providers[index].id); + ASSERT(ALDevice != NULL); + + ALContext = alcCreateContext(ALDevice, attr); + ASSERT(ALContext != NULL); + + alcMakeContextCurrent(ALContext); + + const char* ext=(const char*)alGetString(AL_EXTENSIONS); + ASSERT(strstr(ext,"AL_SOFT_loop_points")!=NULL); + if ( strstr(ext,"AL_SOFT_loop_points")==NULL ) + { + curprovider=-1; + release_existing(); + return false; + } + + alListenerf (AL_GAIN, 1.0f); + alListener3f(AL_POSITION, 0.0f, 0.0f, 0.0f); + alListener3f(AL_VELOCITY, 0.0f, 0.0f, 0.0f); + ALfloat orientation[6] = { 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f }; + alListenerfv(AL_ORIENTATION, orientation); + + alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED); + + if ( alcIsExtensionPresent(ALDevice, (ALCchar*)ALC_EXT_EFX_NAME) ) + { + alGenAuxiliaryEffectSlots(1, &ALEffectSlot); + alGenEffects(1, &ALEffect); + } + + alGenSources(MAX_STREAMS*2, ALStreamSources[0]); + for ( int32 i = 0; i < MAX_STREAMS; i++ ) + { + alGenBuffers(NUM_STREAMBUFFERS, ALStreamBuffers[i]); + alSourcei(ALStreamSources[i][0], AL_SOURCE_RELATIVE, AL_TRUE); + alSource3f(ALStreamSources[i][0], AL_POSITION, 0.0f, 0.0f, 0.0f); + alSourcef(ALStreamSources[i][0], AL_GAIN, 1.0f); + alSourcei(ALStreamSources[i][1], AL_SOURCE_RELATIVE, AL_TRUE); + alSource3f(ALStreamSources[i][1], AL_POSITION, 0.0f, 0.0f, 0.0f); + alSourcef(ALStreamSources[i][1], AL_GAIN, 1.0f); + + CStream *stream = aStream[i]; + if (stream) + stream->ProviderInit(); + } + + usingEAX = 0; + usingEAX3 = 0; + _usingEFX = false; + + if ( !strcmp(&providers[index].name[strlen(providers[index].name) - strlen(" EAX3")], " EAX3") + && alcIsExtensionPresent(ALDevice, (ALCchar*)ALC_EXT_EFX_NAME) ) + { + EAX_SetAll(&FinishEAX3); + + usingEAX = 1; + usingEAX3 = 1; + + DEV("EAX3\n"); + } + else if ( alcIsExtensionPresent(ALDevice, (ALCchar*)ALC_EXT_EFX_NAME) ) + { + EAX_SetAll(&EAX30_ORIGINAL_PRESETS[EAX_ENVIRONMENT_CAVE]); + + if ( !strcmp(&providers[index].name[strlen(providers[index].name) - strlen(" EAX")], " EAX")) + { + usingEAX = 1; + DEV("EAX1\n"); + } + else + { + _usingEFX = true; + DEV("EFX\n"); + } + } + + //SampleManager.SetSpeakerConfig(speaker_type); + + CChannel::InitChannels(); + + for ( int32 i = 0; i < MAXCHANNELS; i++ ) + aChannel[i].Init(i); + aChannel[CHANNEL2D].Init(CHANNEL2D, true); + + if ( IsFXSupported() ) + { + /**/ + alAuxiliaryEffectSloti(ALEffectSlot, AL_EFFECTSLOT_EFFECT, ALEffect); + /**/ + + for ( int32 i = 0; i < MAXCHANNELS; i++ ) + aChannel[i].SetReverbMix(ALEffectSlot, 0.0f); + } + + return true; + } + + return false; +} + +static bool +IsThisTrackAt16KHz(uint32 track) +{ + return track == STREAMED_SOUND_RADIO_KCHAT || track == STREAMED_SOUND_RADIO_VCPR || track == STREAMED_SOUND_RADIO_POLICE; +} + +cSampleManager::cSampleManager(void) +{ + ; +} + +cSampleManager::~cSampleManager(void) +{ + +} + +void cSampleManager::SetSpeakerConfig(int32 nConfig) +{ + +} + +uint32 cSampleManager::GetMaximumSupportedChannels(void) +{ + if ( _maxSamples > MAXCHANNELS ) + return MAXCHANNELS; + + return _maxSamples; +} + +uint32 cSampleManager::GetNum3DProvidersAvailable() +{ + return m_nNumberOfProviders; +} + +void cSampleManager::SetNum3DProvidersAvailable(uint32 num) +{ + m_nNumberOfProviders = num; +} + +char *cSampleManager::Get3DProviderName(uint8 id) +{ + return m_aAudioProviders[id]; +} + +void cSampleManager::Set3DProviderName(uint8 id, char *name) +{ + m_aAudioProviders[id] = name; +} + +int8 cSampleManager::GetCurrent3DProviderIndex(void) +{ + return curprovider; +} + +int8 cSampleManager::SetCurrent3DProvider(uint8 nProvider) +{ + int savedprovider = curprovider; + + nProvider = clamp(nProvider, 0, m_nNumberOfProviders - 1); + + if ( set_new_provider(nProvider) ) + return curprovider; + else if ( savedprovider != -1 && savedprovider < m_nNumberOfProviders && set_new_provider(savedprovider) ) + return curprovider; + else + return curprovider; +} + +int8 +cSampleManager::AutoDetect3DProviders() +{ + if (!AudioManager.IsAudioInitialised()) + return -1; + + if (defaultProvider >= 0 && defaultProvider < m_nNumberOfProviders) { + if (set_new_provider(defaultProvider)) + return defaultProvider; + } + + for (uint32 i = 0; i < GetNum3DProvidersAvailable(); i++) + { + char* providername = Get3DProviderName(i); + + if (!strcasecmp(providername, "OPENAL SOFT")) { + SetCurrent3DProvider(i); + if (GetCurrent3DProviderIndex() == i) + return i; + } + } + + return -1; +} + +static bool +_ResolveLink(char const *path, char *out) +{ +#ifdef _WIN32 + size_t len = strlen(path); + if (len < 4 || strcmp(&path[len - 4], ".lnk") != 0) + return false; + + IShellLink* psl; + WIN32_FIND_DATA fd; + char filepath[MAX_PATH]; + + CoInitialize(NULL); + + if (SUCCEEDED( CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl ) )) + { + IPersistFile *ppf; + + if (SUCCEEDED(psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf))) + { + WCHAR wpath[MAX_PATH]; + + MultiByteToWideChar(CP_ACP, 0, path, -1, wpath, MAX_PATH); + + if (SUCCEEDED(ppf->Load(wpath, STGM_READ))) + { + /* Resolve the link */ + if (SUCCEEDED(psl->Resolve(NULL, SLR_ANY_MATCH|SLR_NO_UI|SLR_NOSEARCH))) + { + strcpy(filepath, path); + + if (SUCCEEDED(psl->GetPath(filepath, MAX_PATH, &fd, SLGP_UNCPRIORITY))) + { + OutputDebugString(fd.cFileName); + + strcpy(out, filepath); + // FIX: Release the objects. Taken from SA. +#ifdef FIX_BUGS + ppf->Release(); + psl->Release(); +#endif + return true; + } + } + } + + ppf->Release(); + } + psl->Release(); + } + + return false; +#else + struct stat sb; + + if (lstat(path, &sb) == -1) { + perror("lstat: "); + return false; + } + + if (S_ISLNK(sb.st_mode)) { + char* linkname = (char*)alloca(sb.st_size + 1); + if (linkname == NULL) { + fprintf(stderr, "insufficient memory\n"); + return false; + } + + if (readlink(path, linkname, sb.st_size + 1) < 0) { + perror("readlink: "); + return false; + } + linkname[sb.st_size] = '\0'; + strcpy(out, linkname); + return true; + } else { + return false; + } +#endif +} + +static void +_FindMP3s(void) +{ + tMP3Entry *pList; + bool bShortcut; + bool bInitFirstEntry; + HANDLE hFind; + char path[MAX_PATH]; + char filepath[MAX_PATH*2]; + int total_ms; + WIN32_FIND_DATA fd; + + if (getcwd(_mp3DirectoryPath, MAX_PATH) == NULL) { + perror("getcwd: "); + return; + } + + OutputDebugString("Finding MP3s..."); + strcpy(path, _mp3DirectoryPath); + strcat(path, "\\MP3\\"); + + strcpy(_mp3DirectoryPath, path); + OutputDebugString(_mp3DirectoryPath); + + strcat(path, "*"); + + hFind = FindFirstFile(path, &fd); + + if ( hFind == INVALID_HANDLE_VALUE ) + { + return; + } + + strcpy(filepath, _mp3DirectoryPath); + strcat(filepath, fd.cFileName); + + size_t filepathlen = strlen(filepath); + + if ( filepathlen <= 0) + { + FindClose(hFind); + return; + } + + if ( _ResolveLink(filepath, filepath) ) + { + OutputDebugString("Resolving Link"); + OutputDebugString(filepath); + bShortcut = true; + } else + bShortcut = false; + + aStream[0] = new CStream(filepath, ALStreamSources[0], ALStreamBuffers[0]); + + if (aStream[0] && aStream[0]->IsOpened()) + { + total_ms = aStream[0]->GetLengthMS(); + delete aStream[0]; + aStream[0] = NULL; + + OutputDebugString(fd.cFileName); + + _pMP3List = new tMP3Entry; + + if ( _pMP3List == NULL ) + { + FindClose(hFind); + return; + } + + nNumMP3s = 1; + + strcpy(_pMP3List->aFilename, fd.cFileName); + + _pMP3List->nTrackLength = total_ms; + + _pMP3List->pNext = NULL; + + pList = _pMP3List; + + if ( bShortcut ) + { + _pMP3List->pLinkPath = new char[MAX_PATH*2]; + strcpy(_pMP3List->pLinkPath, filepath); + } + else + { + _pMP3List->pLinkPath = NULL; + } + + bInitFirstEntry = false; + } + else + { + strcat(filepath, " - NOT A VALID MP3"); + + OutputDebugString(filepath); + + bInitFirstEntry = true; + } + + while ( true ) + { + if ( !FindNextFile(hFind, &fd) ) + break; + + if ( bInitFirstEntry ) + { + strcpy(filepath, _mp3DirectoryPath); + strcat(filepath, fd.cFileName); + + size_t filepathlen = strlen(filepath); + + if ( filepathlen > 0 ) + { + if ( _ResolveLink(filepath, filepath) ) + { + OutputDebugString("Resolving Link"); + OutputDebugString(filepath); + bShortcut = true; + } else { + bShortcut = false; + if (filepathlen > MAX_PATH) { + continue; + } + } + aStream[0] = new CStream(filepath, ALStreamSources[0], ALStreamBuffers[0]); + + if (aStream[0] && aStream[0]->IsOpened()) + { + total_ms = aStream[0]->GetLengthMS(); + delete aStream[0]; + aStream[0] = NULL; + + OutputDebugString(fd.cFileName); + + _pMP3List = new tMP3Entry; + + if ( _pMP3List == NULL) + break; + + nNumMP3s = 1; + + strcpy(_pMP3List->aFilename, fd.cFileName); + + _pMP3List->nTrackLength = total_ms; + _pMP3List->pNext = NULL; + + if ( bShortcut ) + { + _pMP3List->pLinkPath = new char [MAX_PATH*2]; + strcpy(_pMP3List->pLinkPath, filepath); + } + else + { + _pMP3List->pLinkPath = NULL; + } + + pList = _pMP3List; + + bInitFirstEntry = false; + } + else + { + strcat(filepath, " - NOT A VALID MP3"); + OutputDebugString(filepath); + } + } + } + else + { + strcpy(filepath, _mp3DirectoryPath); + strcat(filepath, fd.cFileName); + + size_t filepathlen = strlen(filepath); + + if ( filepathlen > 0 ) + { + if ( _ResolveLink(filepath, filepath) ) + { + OutputDebugString("Resolving Link"); + OutputDebugString(filepath); + bShortcut = true; + } else + bShortcut = false; + + aStream[0] = new CStream(filepath, ALStreamSources[0], ALStreamBuffers[0]); + + if (aStream[0] && aStream[0]->IsOpened()) + { + total_ms = aStream[0]->GetLengthMS(); + delete aStream[0]; + aStream[0] = NULL; + + OutputDebugString(fd.cFileName); + + pList->pNext = new tMP3Entry; + + tMP3Entry *e = pList->pNext; + + if ( e == NULL ) + break; + + pList = pList->pNext; + + strcpy(e->aFilename, fd.cFileName); + e->nTrackLength = total_ms; + e->pNext = NULL; + + if ( bShortcut ) + { + e->pLinkPath = new char [MAX_PATH*2]; + strcpy(e->pLinkPath, filepath); + } + else + { + e->pLinkPath = NULL; + } + + nNumMP3s++; + + OutputDebugString(fd.cFileName); + } + else + { + strcat(filepath, " - NOT A VALID MP3"); + OutputDebugString(filepath); + } + } + } + } + + FindClose(hFind); +} + +static void +_DeleteMP3Entries(void) +{ + tMP3Entry *e = _pMP3List; + + while ( e != NULL ) + { + tMP3Entry *next = e->pNext; + + if ( next == NULL ) + next = NULL; + + if ( e->pLinkPath != NULL ) + { +#ifndef FIX_BUGS + delete e->pLinkPath; // BUG: should be delete [] +#else + delete[] e->pLinkPath; +#endif + e->pLinkPath = NULL; + } + + delete e; + + if ( next ) + e = next; + else + e = NULL; + + nNumMP3s--; + } + + + if ( nNumMP3s != 0 ) + { + OutputDebugString("Not all MP3 entries were deleted"); + nNumMP3s = 0; + } + + _pMP3List = NULL; +} + +static tMP3Entry * +_GetMP3EntryByIndex(uint32 idx) +{ + uint32 n = ( idx < nNumMP3s ) ? idx : 0; + + if ( _pMP3List != NULL ) + { + tMP3Entry *e = _pMP3List; + + for ( uint32 i = 0; i < n; i++ ) + e = e->pNext; + + return e; + + } + + return NULL; +} + +static inline bool +_GetMP3PosFromStreamPos(uint32 *pPosition, tMP3Entry **pEntry) +{ + _CurMP3Index = 0; + + for ( *pEntry = _pMP3List; *pEntry != NULL; *pEntry = (*pEntry)->pNext ) + { + if ( *pPosition >= (*pEntry)->nTrackStreamPos + && *pPosition < (*pEntry)->nTrackLength + (*pEntry)->nTrackStreamPos ) + { + *pPosition -= (*pEntry)->nTrackStreamPos; + _CurMP3Pos = *pPosition; + + return true; + } + + _CurMP3Index++; + } + + *pPosition = 0; + *pEntry = _pMP3List; + _CurMP3Pos = 0; + _CurMP3Index = 0; + + return false; +} + +bool +cSampleManager::IsMP3RadioChannelAvailable(void) +{ + return nNumMP3s != 0; +} + + +void cSampleManager::ReleaseDigitalHandle(void) +{ + if ( ALDevice ) + { + prevprovider = curprovider; + release_existing(); + curprovider = -1; + } +} + +void cSampleManager::ReacquireDigitalHandle(void) +{ + if ( ALDevice ) + { + if ( prevprovider != -1 ) + set_new_provider(prevprovider); + } +} + +bool +cSampleManager::Initialise(void) +{ + if ( _bSampmanInitialised ) + return true; + + EFXInit(); + CStream::Initialise(); + + { + for ( int32 i = 0; i < TOTAL_AUDIO_SAMPLES; i++ ) + { + m_aSamples[i].nOffset = 0; + m_aSamples[i].nSize = 0; + m_aSamples[i].nFrequency = MAX_FREQ; + m_aSamples[i].nLoopStart = 0; + m_aSamples[i].nLoopEnd = -1; + } + + m_nEffectsVolume = MAX_VOLUME; + m_nMusicVolume = MAX_VOLUME; + m_nEffectsFadeVolume = MAX_VOLUME; + m_nMusicFadeVolume = MAX_VOLUME; + + m_nMonoMode = 0; + } + + { + curprovider = -1; + prevprovider = -1; + + _usingEFX = false; + usingEAX =0; + usingEAX3=0; + + _fEffectsLevel = 0.0f; + + _maxSamples = 0; + + ALDevice = NULL; + ALContext = NULL; + } + + { + fpSampleDescHandle = NULL; + fpSampleDataHandle = NULL; + + for ( int32 i = 0; i < MAX_SFX_BANKS; i++ ) + { + bSampleBankLoaded[i] = false; + nSampleBankDiscStartOffset[i] = 0; + nSampleBankSize[i] = 0; + nSampleBankMemoryStartAddress[i] = 0; + } + } + + { + for ( int32 i = 0; i < MAX_PEDSFX; i++ ) + { + nPedSlotSfx[i] = NO_SAMPLE; + nPedSlotSfxAddr[i] = 0; + } + + nCurrentPedSlot = 0; + } + + { + for ( int32 i = 0; i < MAXCHANNELS+MAX2DCHANNELS; i++ ) + nChannelVolume[i] = 0; + } + + { + for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ ) + nStreamLength[i] = 0; + } + + add_providers(); + +#ifdef AUDIO_CACHE + FILE *cacheFile = fcaseopen("audio\\sound.cache", "rb"); + if (cacheFile) { + debug("Loadind audio cache (If game crashes around here, then your cache is corrupted, remove audio/sound.cache)\n"); + fread(nStreamLength, sizeof(uint32), TOTAL_STREAMED_SOUNDS, cacheFile); + fclose(cacheFile); + } else + { + debug("Cannot load audio cache\n"); +#endif + + for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ ) + { + aStream[0] = new CStream(StreamedNameTable[i], ALStreamSources[0], ALStreamBuffers[0], IsThisTrackAt16KHz(i) ? 16000 : 32000); + + if ( aStream[0] && aStream[0]->IsOpened() ) + { + uint32 tatalms = aStream[0]->GetLengthMS(); + delete aStream[0]; + aStream[0] = NULL; + + nStreamLength[i] = tatalms; + } + else + USERERROR("Can't open '%s'\n", StreamedNameTable[i]); + } +#ifdef AUDIO_CACHE + cacheFile = fcaseopen("audio\\sound.cache", "wb"); + if(cacheFile) { + debug("Saving audio cache\n"); + fwrite(nStreamLength, sizeof(uint32), TOTAL_STREAMED_SOUNDS, cacheFile); + fclose(cacheFile); + } else { + debug("Cannot save audio cache\n"); + } + } +#endif + + { + if ( !InitialiseSampleBanks() ) + { + Terminate(); + return false; + } + + nSampleBankMemoryStartAddress[SFX_BANK_0] = (uintptr)malloc(nSampleBankSize[SFX_BANK_0]); + ASSERT(nSampleBankMemoryStartAddress[SFX_BANK_0] != 0); + + if ( nSampleBankMemoryStartAddress[SFX_BANK_0] == 0 ) + { + Terminate(); + return false; + } + + nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS] = (uintptr)malloc(PED_BLOCKSIZE*MAX_PEDSFX); + ASSERT(nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS] != 0); + + LoadSampleBank(SFX_BANK_0); + } + + { + for ( int32 i = 0; i < MAX_STREAMS; i++ ) + { + aStream[i] = NULL; + nStreamVolume[i] = 100; + nStreamPan[i] = 63; + } + } + + { + _bSampmanInitialised = true; + + if ( defaultProvider >= 0 && defaultProvider < m_nNumberOfProviders ) + { + set_new_provider(defaultProvider); + } + else + { + Terminate(); + return false; + } + } + + { + nNumMP3s = 0; + + _pMP3List = NULL; + + _FindMP3s(); + + if ( nNumMP3s != 0 ) + { + nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER] = 0; + + for ( tMP3Entry *e = _pMP3List; e != NULL; e = e->pNext ) + { + e->nTrackStreamPos = nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER]; + nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER] += e->nTrackLength; + } + + time_t t = time(NULL); + tm *localtm; + bool bUseRandomTable; + + if ( t == -1 ) + bUseRandomTable = true; + else + { + bUseRandomTable = false; + localtm = localtime(&t); + } + + int32 randval; + if ( bUseRandomTable ) + randval = AudioManager.GetRandomNumber(1); + else + randval = localtm->tm_sec * localtm->tm_min; + + _CurMP3Index = randval % nNumMP3s; + + tMP3Entry *randmp3 = _pMP3List; + for ( int32 i = randval % nNumMP3s; i > 0; --i) + randmp3 = randmp3->pNext; + + if ( bUseRandomTable ) + _CurMP3Pos = AudioManager.GetRandomNumber(0) % randmp3->nTrackLength; + else + { + if ( localtm->tm_sec > 0 ) + { + int32 s = localtm->tm_sec; + _CurMP3Pos = s*s*s*s*s*s*s*s % randmp3->nTrackLength; + } + else + _CurMP3Pos = AudioManager.GetRandomNumber(0) % randmp3->nTrackLength; + } + } + else + _CurMP3Pos = 0; + + _bIsMp3Active = false; + } + + return true; +} + +void +cSampleManager::Terminate(void) +{ + for (int32 i = 0; i < MAX_STREAMS; i++) + { + CStream *stream = aStream[i]; + if (stream) + { + delete stream; + aStream[i] = NULL; + } + } + + release_existing(); + + _DeleteMP3Entries(); + + CStream::Terminate(); + + if ( nSampleBankMemoryStartAddress[SFX_BANK_0] != 0 ) + { + free((void *)nSampleBankMemoryStartAddress[SFX_BANK_0]); + nSampleBankMemoryStartAddress[SFX_BANK_0] = 0; + } + + if ( nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS] != 0 ) + { + free((void *)nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS]); + nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS] = 0; + } + + _bSampmanInitialised = false; +} + +bool cSampleManager::CheckForAnAudioFileOnCD(void) +{ + return true; +} + +char cSampleManager::GetCDAudioDriveLetter(void) +{ + return '\0'; +} + +void +cSampleManager::UpdateEffectsVolume(void) +{ + if ( _bSampmanInitialised ) + { + for ( int32 i = 0; i < MAXCHANNELS+MAX2DCHANNELS; i++ ) + { + if ( GetChannelUsedFlag(i) ) + { + if ( nChannelVolume[i] != 0 ) + aChannel[i].SetVolume(m_nEffectsFadeVolume*nChannelVolume[i]*m_nEffectsVolume >> 14); + } + } + } +} + +void +cSampleManager::SetEffectsMasterVolume(uint8 nVolume) +{ + m_nEffectsVolume = nVolume; + UpdateEffectsVolume(); +} + +void +cSampleManager::SetMusicMasterVolume(uint8 nVolume) +{ + m_nMusicVolume = nVolume; +} + +void +cSampleManager::SetMP3BoostVolume(uint8 nVolume) +{ + m_nMP3BoostVolume = nVolume; +} + +void +cSampleManager::SetEffectsFadeVolume(uint8 nVolume) +{ + m_nEffectsFadeVolume = nVolume; + UpdateEffectsVolume(); +} + +void +cSampleManager::SetMusicFadeVolume(uint8 nVolume) +{ + m_nMusicFadeVolume = nVolume; +} + +void +cSampleManager::SetMonoMode(uint8 nMode) +{ + m_nMonoMode = nMode; +} + +bool +cSampleManager::LoadSampleBank(uint8 nBank) +{ + ASSERT( nBank < MAX_SFX_BANKS); + + if ( CTimer::GetIsCodePaused() ) + return false; + + if ( MusicManager.IsInitialised() + && MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE + && nBank != SFX_BANK_0 ) + { + return false; + } + +#ifdef OPUS_SFX + int samplesRead = 0; + int samplesSize = nSampleBankSize[nBank] / 2; + op_pcm_seek(fpSampleDataHandle, 0); + while (samplesSize > 0) { + int size = op_read(fpSampleDataHandle, (opus_int16 *)(nSampleBankMemoryStartAddress[nBank] + samplesRead), samplesSize, NULL); + if (size <= 0) { + // huh? + //assert(0); + break; + } + samplesRead += size*2; + samplesSize -= size; + } +#else + if ( fseek(fpSampleDataHandle, nSampleBankDiscStartOffset[nBank], SEEK_SET) != 0 ) + return false; + + if ( fread((void *)nSampleBankMemoryStartAddress[nBank], 1, nSampleBankSize[nBank], fpSampleDataHandle) != nSampleBankSize[nBank] ) + return false; +#endif + bSampleBankLoaded[nBank] = true; + + return true; +} + +void +cSampleManager::UnloadSampleBank(uint8 nBank) +{ + ASSERT( nBank < MAX_SFX_BANKS); + + bSampleBankLoaded[nBank] = false; +} + +bool +cSampleManager::IsSampleBankLoaded(uint8 nBank) +{ + ASSERT( nBank < MAX_SFX_BANKS); + + return bSampleBankLoaded[nBank]; +} + +bool +cSampleManager::IsPedCommentLoaded(uint32 nComment) +{ + ASSERT( nComment < TOTAL_AUDIO_SAMPLES ); + + int8 slot; + + for ( int32 i = 0; i < _TODOCONST(3); i++ ) + { + slot = nCurrentPedSlot - i - 1; +#ifdef FIX_BUGS + if (slot < 0) + slot += ARRAY_SIZE(nPedSlotSfx); +#endif + if ( nComment == nPedSlotSfx[slot] ) + return true; + } + + return false; +} + + +int32 +cSampleManager::_GetPedCommentSlot(uint32 nComment) +{ + int8 slot; + + for (int32 i = 0; i < _TODOCONST(3); i++) + { + slot = nCurrentPedSlot - i - 1; +#ifdef FIX_BUGS + if (slot < 0) + slot += ARRAY_SIZE(nPedSlotSfx); +#endif + if (nComment == nPedSlotSfx[slot]) + return slot; + } + + return -1; +} + +bool +cSampleManager::LoadPedComment(uint32 nComment) +{ + ASSERT( nComment < TOTAL_AUDIO_SAMPLES ); + + if ( CTimer::GetIsCodePaused() ) + return false; + + // no talking peds during cutsenes or the game end + if ( MusicManager.IsInitialised() ) + { + switch ( MusicManager.GetMusicMode() ) + { + case MUSICMODE_CUTSCENE: + { + return false; + + break; + } + } + } + +#ifdef OPUS_SFX + int samplesRead = 0; + int samplesSize = m_aSamples[nComment].nSize / 2; + op_pcm_seek(fpSampleDataHandle, m_aSamples[nComment].nOffset / 2); + while (samplesSize > 0) { + int size = op_read(fpSampleDataHandle, (opus_int16 *)(nSampleBankMemoryStartAddress[SAMPLEBANK_PED] + PED_BLOCKSIZE * nCurrentPedSlot + samplesRead), + samplesSize, NULL); + if (size <= 0) { + return false; + } + samplesRead += size * 2; + samplesSize -= size; + } +#else + if ( fseek(fpSampleDataHandle, m_aSamples[nComment].nOffset, SEEK_SET) != 0 ) + return false; + + if ( fread((void *)(nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS] + PED_BLOCKSIZE*nCurrentPedSlot), 1, m_aSamples[nComment].nSize, fpSampleDataHandle) != m_aSamples[nComment].nSize ) + return false; + +#endif + nPedSlotSfx[nCurrentPedSlot] = nComment; + + if ( ++nCurrentPedSlot >= MAX_PEDSFX ) + nCurrentPedSlot = 0; + + return true; +} + +int32 +cSampleManager::GetBankContainingSound(uint32 offset) +{ + if ( offset >= BankStartOffset[SFX_BANK_PED_COMMENTS] ) + return SFX_BANK_PED_COMMENTS; + + if ( offset >= BankStartOffset[SFX_BANK_0] ) + return SFX_BANK_0; + + return INVALID_SFX_BANK; +} + +int32 +cSampleManager::GetSampleBaseFrequency(uint32 nSample) +{ + ASSERT( nSample < TOTAL_AUDIO_SAMPLES ); + return m_aSamples[nSample].nFrequency; +} + +int32 +cSampleManager::GetSampleLoopStartOffset(uint32 nSample) +{ + ASSERT( nSample < TOTAL_AUDIO_SAMPLES ); + return m_aSamples[nSample].nLoopStart; +} + +int32 +cSampleManager::GetSampleLoopEndOffset(uint32 nSample) +{ + ASSERT( nSample < TOTAL_AUDIO_SAMPLES ); + return m_aSamples[nSample].nLoopEnd; +} + +uint32 +cSampleManager::GetSampleLength(uint32 nSample) +{ + ASSERT( nSample < TOTAL_AUDIO_SAMPLES ); + return m_aSamples[nSample].nSize / sizeof(uint16); +} + +bool cSampleManager::UpdateReverb(void) +{ + if ( !usingEAX && !_usingEFX ) + return false; + + if ( AudioManager.GetFrameCounter() & 15 ) + return false; + + float fRatio = 0.0f; + +#define MIN_DIST 0.5f +#define CALCULATE_RATIO(value, maxDist, maxRatio) (value > MIN_DIST && value < maxDist ? value / maxDist * maxRatio : 0) + + fRatio += CALCULATE_RATIO(AudioManager.GetReflectionsDistance(REFLECTION_CEIL_NORTH), 10.0f, 1/2.f); + fRatio += CALCULATE_RATIO(AudioManager.GetReflectionsDistance(REFLECTION_CEIL_SOUTH), 10.0f, 1/2.f); + fRatio += CALCULATE_RATIO(AudioManager.GetReflectionsDistance(REFLECTION_CEIL_WEST), 10.0f, 1/2.f); + fRatio += CALCULATE_RATIO(AudioManager.GetReflectionsDistance(REFLECTION_CEIL_EAST), 10.0f, 1/2.f); + + fRatio += CALCULATE_RATIO((AudioManager.GetReflectionsDistance(REFLECTION_NORTH) + AudioManager.GetReflectionsDistance(REFLECTION_SOUTH)) / 2.f, 4.0f, 1/3.f); + fRatio += CALCULATE_RATIO((AudioManager.GetReflectionsDistance(REFLECTION_WEST) + AudioManager.GetReflectionsDistance(REFLECTION_EAST)) / 2.f, 4.0f, 1/3.f); + +#undef CALCULATE_RATIO +#undef MIN_DIST + + fRatio = clamp(fRatio, 0.0f, 0.6f); + + if ( fRatio == _fPrevEaxRatioDestination ) + return false; + +#ifdef JUICY_OAL + if ( usingEAX3 || _usingEFX ) +#else + if ( usingEAX3 ) +#endif + { + fRatio = Min(fRatio * 1.67f, 1.0f); + if ( EAX3ListenerInterpolate(&StartEAX3, &FinishEAX3, fRatio, &EAX3Params, false) ) + { + EAX_SetAll(&EAX3Params); + + /* + if ( IsFXSupported() ) + { + alAuxiliaryEffectSloti(ALEffectSlot, AL_EFFECTSLOT_EFFECT, ALEffect); + + for ( int32 i = 0; i < MAXCHANNELS; i++ ) + aChannel[i].UpdateReverb(ALEffectSlot); + } + */ + + _fEffectsLevel = fRatio * 0.75f; + } + } + else + { + if ( _usingEFX ) + _fEffectsLevel = fRatio * 0.8f; + else + _fEffectsLevel = fRatio * 0.22f; + } + _fEffectsLevel = Min(_fEffectsLevel, 1.0f); + + _fPrevEaxRatioDestination = fRatio; + + return true; +} + +void +cSampleManager::SetChannelReverbFlag(uint32 nChannel, uint8 nReverbFlag) +{ + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); + + if ( usingEAX || _usingEFX ) + { + if ( IsFXSupported() ) + { + alAuxiliaryEffectSloti(ALEffectSlot, AL_EFFECTSLOT_EFFECT, ALEffect); + + if ( nReverbFlag != 0 ) + aChannel[nChannel].SetReverbMix(ALEffectSlot, _fEffectsLevel); + else + aChannel[nChannel].SetReverbMix(ALEffectSlot, 0.0f); + } + } +} + +bool +cSampleManager::InitialiseChannel(uint32 nChannel, uint32 nSfx, uint8 nBank) +{ + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); + + uintptr addr; + + if ( nSfx < SAMPLEBANK_MAX ) + { + if ( !IsSampleBankLoaded(nBank) ) + return false; + + addr = nSampleBankMemoryStartAddress[nBank] + m_aSamples[nSfx].nOffset - m_aSamples[BankStartOffset[nBank]].nOffset; + } + else + { + if ( !IsPedCommentLoaded(nSfx) ) + return false; + + int32 slot = _GetPedCommentSlot(nSfx); + addr = (nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS] + PED_BLOCKSIZE * slot); + } + + if ( GetChannelUsedFlag(nChannel) ) + { + TRACE("Stopping channel %d - really!!!", nChannel); + StopChannel(nChannel); + } + + aChannel[nChannel].Reset(); + if ( aChannel[nChannel].HasSource() ) + { + aChannel[nChannel].SetSampleData ((void*)addr, m_aSamples[nSfx].nSize, m_aSamples[nSfx].nFrequency); + aChannel[nChannel].SetLoopPoints (0, -1); + aChannel[nChannel].SetPitch (1.0f); + return true; + } + + return false; +} + +void +cSampleManager::SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume) +{ + ASSERT( nChannel != CHANNEL2D ); + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); + + uint32 vol = nVolume; + if ( vol > MAX_VOLUME ) vol = MAX_VOLUME; + + nChannelVolume[nChannel] = vol; + + if (MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE ) { + if (MusicManager.GetCurrentTrack() == STREAMED_SOUND_CUTSCENE_FINALE) + nChannelVolume[nChannel] = 0; + else + nChannelVolume[nChannel] >>= 2; + } + + // no idea, does this one looks like a bug or it's SetChannelVolume ? + aChannel[nChannel].SetVolume(m_nEffectsFadeVolume*nChannelVolume[nChannel]*m_nEffectsVolume >> 14); +} + +void +cSampleManager::SetChannel3DPosition(uint32 nChannel, float fX, float fY, float fZ) +{ + ASSERT( nChannel != CHANNEL2D ); + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); + + aChannel[nChannel].SetPosition(-fX, fY, fZ); +} + +void +cSampleManager::SetChannel3DDistances(uint32 nChannel, float fMax, float fMin) +{ + ASSERT( nChannel != CHANNEL2D ); + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); + aChannel[nChannel].SetDistances(fMax, fMin); +} + +void +cSampleManager::SetChannelVolume(uint32 nChannel, uint32 nVolume) +{ + ASSERT( nChannel == CHANNEL2D ); + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); + + if ( nChannel == CHANNEL2D ) + { + uint32 vol = nVolume; + if ( vol > MAX_VOLUME ) vol = MAX_VOLUME; + + nChannelVolume[nChannel] = vol; + + // increase the volume for JB.MP3 and S4_BDBD.MP3 + if (MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE ) { + if (MusicManager.GetCurrentTrack() == STREAMED_SOUND_CUTSCENE_FINALE) + nChannelVolume[nChannel] = 0; + else + nChannelVolume[nChannel] >>= 2; + } + + aChannel[nChannel].SetVolume(m_nEffectsFadeVolume*vol*m_nEffectsVolume >> 14); + } +} + +void +cSampleManager::SetChannelPan(uint32 nChannel, uint32 nPan) +{ + ASSERT(nChannel == CHANNEL2D); + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); + + if ( nChannel == CHANNEL2D ) + { + aChannel[nChannel].SetPan(nPan); + } +} + +void +cSampleManager::SetChannelFrequency(uint32 nChannel, uint32 nFreq) +{ + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); + + aChannel[nChannel].SetCurrentFreq(nFreq); +} + +void +cSampleManager::SetChannelLoopPoints(uint32 nChannel, uint32 nLoopStart, int32 nLoopEnd) +{ + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); + + aChannel[nChannel].SetLoopPoints(nLoopStart / (DIGITALBITS / 8), nLoopEnd / (DIGITALBITS / 8)); +} + +void +cSampleManager::SetChannelLoopCount(uint32 nChannel, uint32 nLoopCount) +{ + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); + + aChannel[nChannel].SetLoopCount(nLoopCount); +} + +bool +cSampleManager::GetChannelUsedFlag(uint32 nChannel) +{ + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); + + return aChannel[nChannel].IsUsed(); +} + +void +cSampleManager::StartChannel(uint32 nChannel) +{ + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); + + aChannel[nChannel].Start(); +} + +void +cSampleManager::StopChannel(uint32 nChannel) +{ + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); + + aChannel[nChannel].Stop(); +} + +void +cSampleManager::PreloadStreamedFile(uint32 nFile, uint8 nStream) +{ + char filename[MAX_PATH]; + + ASSERT( nStream < MAX_STREAMS ); + + if ( nFile < TOTAL_STREAMED_SOUNDS ) + { + if ( aStream[nStream] ) + { + delete aStream[nStream]; + aStream[nStream] = NULL; + } + + strcpy(filename, StreamedNameTable[nFile]); + + CStream *stream = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream], IsThisTrackAt16KHz(nFile) ? 16000 : 32000); + ASSERT(stream != NULL); + + aStream[nStream] = stream; + if ( !stream->Setup() ) + { + delete stream; + aStream[nStream] = NULL; + } + } +} + +void +cSampleManager::PauseStream(uint8 nPauseFlag, uint8 nStream) +{ + ASSERT( nStream < MAX_STREAMS ); + + CStream *stream = aStream[nStream]; + + if ( stream ) + { + stream->SetPause(nPauseFlag != 0); + } +} + +void +cSampleManager::StartPreloadedStreamedFile(uint8 nStream) +{ + ASSERT( nStream < MAX_STREAMS ); + + CStream *stream = aStream[nStream]; + + if ( stream ) + { + if ( stream->IsOpened() ) + { + stream->Start(); + } + } +} + +bool +cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream) +{ + int i = 0; + uint32 position = nPos; + char filename[MAX_PATH]; + + if ( nFile >= TOTAL_STREAMED_SOUNDS ) + return false; + + if ( aStream[nStream] ) + { + delete aStream[nStream]; + aStream[nStream] = NULL; + } + if ( nFile == STREAMED_SOUND_RADIO_MP3_PLAYER ) + { + do + { + // Just switched to MP3 player + if ( !_bIsMp3Active && i == 0 ) + { + if ( nPos > nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER] ) + position = 0; + tMP3Entry *e = _pMP3List; + + // Try to continue from previous song, if already started + if(!_GetMP3PosFromStreamPos(&position, &e) && !e) { + nFile = 0; + + strcpy(filename, StreamedNameTable[nFile]); + CStream* stream = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream], IsThisTrackAt16KHz(nFile) ? 16000 : 32000); + + aStream[nStream] = stream; + + if (stream->Setup()) { + stream->SetLoopCount(nStreamLoopedFlag[nStream] ? 0 : 1); + nStreamLoopedFlag[nStream] = true; + if (position != 0) + stream->SetPosMS(position); + + stream->Start(); + + return true; + } else { + delete stream; + aStream[nStream] = NULL; + } + return false; + + } else { + + if (e->pLinkPath != NULL) + aStream[nStream] = new CStream(e->pLinkPath, ALStreamSources[nStream], ALStreamBuffers[nStream], IsThisTrackAt16KHz(nFile) ? 16000 : 32000); + else { + strcpy(filename, _mp3DirectoryPath); + strcat(filename, e->aFilename); + + aStream[nStream] = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]); + } + + if (aStream[nStream]->Setup()) { + if (position != 0) + aStream[nStream]->SetPosMS(position); + + aStream[nStream]->Start(); + + _bIsMp3Active = true; + return true; + } else { + delete aStream[nStream]; + aStream[nStream] = NULL; + } + // fall through, start playing from another song + } + } else { + if(++_CurMP3Index >= nNumMP3s) _CurMP3Index = 0; + + _CurMP3Pos = 0; + + tMP3Entry *mp3 = _GetMP3EntryByIndex(_CurMP3Index); + if ( !mp3 ) + { + mp3 = _pMP3List; + if ( !_pMP3List ) + { + nFile = 0; + _bIsMp3Active = 0; + strcpy(filename, StreamedNameTable[nFile]); + + CStream* stream = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream], IsThisTrackAt16KHz(nFile) ? 16000 : 32000); + + aStream[nStream] = stream; + + if (stream->Setup()) { + stream->SetLoopCount(nStreamLoopedFlag[nStream] ? 0 : 1); + nStreamLoopedFlag[nStream] = true; + if (position != 0) + stream->SetPosMS(position); + + stream->Start(); + + return true; + } else { + delete stream; + aStream[nStream] = NULL; + } + return false; + } + } + if (mp3->pLinkPath != NULL) + aStream[nStream] = new CStream(mp3->pLinkPath, ALStreamSources[nStream], ALStreamBuffers[nStream], IsThisTrackAt16KHz(nFile) ? 16000 : 32000); + else { + strcpy(filename, _mp3DirectoryPath); + strcat(filename, mp3->aFilename); + + aStream[nStream] = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream], IsThisTrackAt16KHz(nFile) ? 16000 : 32000); + } + + if (aStream[nStream]->Setup()) { + aStream[nStream]->Start(); +#ifdef FIX_BUGS + _bIsMp3Active = true; +#endif + return true; + } else { + delete aStream[nStream]; + aStream[nStream] = NULL; + } + + } + _bIsMp3Active = 0; + } + while ( ++i < nNumMP3s ); + position = 0; + nFile = 0; + } + strcpy(filename, StreamedNameTable[nFile]); + + CStream *stream = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream], IsThisTrackAt16KHz(nFile) ? 16000 : 32000); + + aStream[nStream] = stream; + + if ( stream->Setup() ) { + stream->SetLoopCount(nStreamLoopedFlag[nStream] ? 0 : 1); + nStreamLoopedFlag[nStream] = true; + if (position != 0) + stream->SetPosMS(position); + + stream->Start(); + + return true; + } else { + delete stream; + aStream[nStream] = NULL; + } + return false; +} + +void +cSampleManager::StopStreamedFile(uint8 nStream) +{ + ASSERT( nStream < MAX_STREAMS ); + + CStream *stream = aStream[nStream]; + + if ( stream ) + { + delete stream; + aStream[nStream] = NULL; + + if ( nStream == 0 ) + _bIsMp3Active = false; + } +} + +int32 +cSampleManager::GetStreamedFilePosition(uint8 nStream) +{ + ASSERT( nStream < MAX_STREAMS ); + + CStream *stream = aStream[nStream]; + + if ( stream ) + { + if ( _bIsMp3Active ) + { + tMP3Entry *mp3 = _GetMP3EntryByIndex(_CurMP3Index); + + if ( mp3 != NULL ) + { + return stream->GetPosMS() + mp3->nTrackStreamPos; + } + else + return 0; + } + else + { + return stream->GetPosMS(); + } + } + + return 0; +} + +void +cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream) +{ + ASSERT( nStream < MAX_STREAMS ); + + float boostMult = 0.0f; + + if ( nVolume > MAX_VOLUME ) + nVolume = MAX_VOLUME; + + if ( nPan > MAX_VOLUME ) + nPan = MAX_VOLUME; + + if ( MusicManager.GetRadioInCar() == USERTRACK && !MusicManager.CheckForMusicInterruptions() ) + boostMult = m_nMP3BoostVolume / 64.f; + + nStreamVolume[nStream] = nVolume; + nStreamPan [nStream] = nPan; + + CStream *stream = aStream[nStream]; + + if ( stream ) + { + if ( nEffectFlag ) { + if ( nStream == 1 || nStream == 2 ) + stream->SetVolume(128*nVolume*m_nEffectsVolume >> 14); + else + stream->SetVolume(m_nEffectsFadeVolume*nVolume*m_nEffectsVolume >> 14); + } + else + stream->SetVolume((m_nMusicFadeVolume*nVolume*(uint32)(m_nMusicVolume * boostMult + m_nMusicVolume)) >> 14); + + stream->SetPan(nPan); + } +} + +int32 +cSampleManager::GetStreamedFileLength(uint8 nStream) +{ + ASSERT( nStream < TOTAL_STREAMED_SOUNDS ); + + return nStreamLength[nStream]; +} + +bool +cSampleManager::IsStreamPlaying(uint8 nStream) +{ + ASSERT( nStream < MAX_STREAMS ); + + CStream *stream = aStream[nStream]; + + if ( stream ) + { + if ( stream->IsPlaying() ) + return true; + } + + return false; +} + +void +cSampleManager::Service(void) +{ + for ( int32 i = 0; i < MAX_STREAMS; i++ ) + { + CStream *stream = aStream[i]; + + if ( stream ) + stream->Update(); + } + int refCount = CChannel::channelsThatNeedService; + for ( int32 i = 0; refCount && i < MAXCHANNELS+MAX2DCHANNELS; i++ ) + { + if ( aChannel[i].Update() ) + refCount--; + } +} + +bool +cSampleManager::InitialiseSampleBanks(void) +{ + int32 nBank = SFX_BANK_0; + + fpSampleDescHandle = fcaseopen(SampleBankDescFilename, "rb"); + if ( fpSampleDescHandle == NULL ) + return false; +#ifndef OPUS_SFX + fpSampleDataHandle = fcaseopen(SampleBankDataFilename, "rb"); + if ( fpSampleDataHandle == NULL ) + { + fclose(fpSampleDescHandle); + fpSampleDescHandle = NULL; + + return false; + } + + fseek(fpSampleDataHandle, 0, SEEK_END); + int32 _nSampleDataEndOffset = ftell(fpSampleDataHandle); + rewind(fpSampleDataHandle); +#else + int e; + fpSampleDataHandle = op_open_file(SampleBankDataFilename, &e); +#endif + fread(m_aSamples, sizeof(tSample), TOTAL_AUDIO_SAMPLES, fpSampleDescHandle); +#ifdef OPUS_SFX + int32 _nSampleDataEndOffset = m_aSamples[TOTAL_AUDIO_SAMPLES - 1].nOffset + m_aSamples[TOTAL_AUDIO_SAMPLES - 1].nSize; +#endif + fclose(fpSampleDescHandle); + fpSampleDescHandle = NULL; + + for ( int32 i = 0; i < TOTAL_AUDIO_SAMPLES; i++ ) + { +#ifdef FIX_BUGS + if (nBank >= MAX_SFX_BANKS) break; +#endif + if ( BankStartOffset[nBank] == BankStartOffset[SFX_BANK_0] + i ) + { + nSampleBankDiscStartOffset[nBank] = m_aSamples[i].nOffset; + nBank++; + } + } + + nSampleBankSize[SFX_BANK_0] = nSampleBankDiscStartOffset[SFX_BANK_PED_COMMENTS] - nSampleBankDiscStartOffset[SFX_BANK_0]; + nSampleBankSize[SFX_BANK_PED_COMMENTS] = _nSampleDataEndOffset - nSampleBankDiscStartOffset[SFX_BANK_PED_COMMENTS]; + + return true; +} + +void +cSampleManager::SetStreamedFileLoopFlag(uint8 nLoopFlag, uint8 nChannel) +{ + nStreamLoopedFlag[nChannel] = nLoopFlag; +} + +#endif diff --git a/src/audio/soundlist.h b/src/audio/soundlist.h new file mode 100644 index 0000000..e86b13e --- /dev/null +++ b/src/audio/soundlist.h @@ -0,0 +1,282 @@ +#pragma once + +enum eSound +{ + SOUND_CAR_DOOR_CLOSE_BONNET = 0, + SOUND_CAR_DOOR_CLOSE_BUMPER, + SOUND_CAR_DOOR_CLOSE_FRONT_LEFT, + SOUND_CAR_DOOR_CLOSE_FRONT_RIGHT, + SOUND_CAR_DOOR_CLOSE_BACK_LEFT, + SOUND_CAR_DOOR_CLOSE_BACK_RIGHT, + SOUND_CAR_DOOR_OPEN_BONNET, + SOUND_CAR_DOOR_OPEN_BUMPER, + SOUND_CAR_DOOR_OPEN_FRONT_LEFT, + SOUND_CAR_DOOR_OPEN_FRONT_RIGHT, + SOUND_CAR_DOOR_OPEN_BACK_LEFT, + SOUND_CAR_DOOR_OPEN_BACK_RIGHT, + SOUND_CAR_WINDSHIELD_CRACK, + SOUND_CAR_JUMP, + SOUND_CAR_JUMP_2, + SOUND_CAR_TYRE_POP, + SOUND_16, + SOUND_17, + SOUND_CAR_ENGINE_START, + SOUND_CAR_LIGHT_BREAK, + SOUND_CAR_HYDRAULIC_1, + SOUND_CAR_HYDRAULIC_2, + SOUND_CAR_HYDRAULIC_3, + SOUND_CAR_JERK, + SOUND_CAR_SPLASH, + SOUND_BOAT_SLOWDOWN, + SOUND_TRAIN_DOOR_CLOSE, + SOUND_TRAIN_DOOR_OPEN, + SOUND_CAR_TANK_TURRET_ROTATE, + SOUND_CAR_BOMB_TICK, + SOUND_PLANE_ON_GROUND, + SOUND_HELI_BLADE, + SOUND_32, + SOUND_STEP_START, + SOUND_STEP_END, + SOUND_FALL_LAND, + SOUND_FALL_COLLAPSE, + SOUND_FIGHT_37, + SOUND_FIGHT_38, + SOUND_FIGHT_39, + SOUND_FIGHT_40, + SOUND_FIGHT_41, + SOUND_FIGHT_42, + SOUND_FIGHT_43, + SOUND_FIGHT_44, + SOUND_FIGHT_45, + SOUND_FIGHT_46, + SOUND_FIGHT_47, + SOUND_FIGHT_48, + SOUND_49, + SOUND_WEAPON_BAT_ATTACK, + SOUND_WEAPON_KNIFE_ATTACK, + SOUND_WEAPON_CHAINSAW_ATTACK, + SOUND_WEAPON_CHAINSAW_IDLE, + SOUND_WEAPON_CHAINSAW_MADECONTACT, + SOUND_WEAPON_SHOT_FIRED, + SOUND_WEAPON_RELOAD, + SOUND_WEAPON_AK47_BULLET_ECHO, + SOUND_WEAPON_FLAMETHROWER_FIRE, + SOUND_WEAPON_SNIPER_SHOT_NO_ZOOM, + SOUND_WEAPON_ROCKET_SHOT_NO_ZOOM, + SOUND_WEAPON_HIT_PED, + SOUND_WEAPON_HIT_VEHICLE, + SOUND_GARAGE_NO_MONEY, + SOUND_GARAGE_BAD_VEHICLE, + SOUND_GARAGE_OPENING, + SOUND_GARAGE_BOMB_ALREADY_SET, + SOUND_GARAGE_BOMB1_SET, + SOUND_GARAGE_BOMB2_SET, + SOUND_GARAGE_BOMB3_SET, + SOUND_70, + SOUND_71, + SOUND_GARAGE_VEHICLE_DECLINED, + SOUND_GARAGE_VEHICLE_ACCEPTED, + SOUND_GARAGE_DOOR_CLOSED, + SOUND_GARAGE_DOOR_OPENED, + SOUND_CRANE_PICKUP, + SOUND_PICKUP_WEAPON_BOUGHT, + SOUND_PICKUP_WEAPON, + SOUND_PICKUP_HEALTH, + SOUND_80, + SOUND_81, + SOUND_PICKUP_ADRENALINE, + SOUND_PICKUP_ARMOUR, + SOUND_PICKUP_BONUS, + SOUND_PICKUP_MONEY, + SOUND_PICKUP_HIDDEN_PACKAGE, + SOUND_PICKUP_PACMAN_PILL, + SOUND_PICKUP_PACMAN_PACKAGE, + SOUND_PICKUP_FLOAT_PACKAGE, + SOUND_BOMB_TIMED_ACTIVATED, + SOUND_91, + SOUND_BOMB_ONIGNITION_ACTIVATED, + SOUND_BOMB_TICK, + SOUND_RAMPAGE_START, + SOUND_RAMPAGE_ONGOING, + SOUND_RAMPAGE_PASSED, + SOUND_RAMPAGE_FAILED, + SOUND_RAMPAGE_KILL, + SOUND_RAMPAGE_CAR_BLOWN, + SOUND_EVIDENCE_PICKUP, + SOUND_UNLOAD_GOLD, + SOUND_PAGER, + SOUND_PED_DEATH, + SOUND_PED_DAMAGE, + SOUND_PED_HIT, + SOUND_PED_LAND, + SOUND_PED_BULLET_HIT, + SOUND_PED_BURNING, + SOUND_PED_PLAYER_REACTTOCOP, + SOUND_PED_ARREST_COP, + SOUND_PED_MIAMIVICE_EXITING_CAR, + SOUND_PED_COP_HELIPILOTPHRASE, + SOUND_PED_PULLOUTWEAPON, + SOUND_PED_HELI_PLAYER_FOUND = 114, + SOUND_PED_VCPA_PLAYER_FOUND = 115, + SOUND_PED_ON_FIRE, + SOUND_PED_AIMING, + SOUND_PED_HANDS_UP, + SOUND_PED_HANDS_COWER, + SOUND_PED_FLEE_SPRINT, + SOUND_PED_CAR_JACKING, + SOUND_PED_MUGGING, + SOUND_PED_CAR_JACKED, + SOUND_PED_ROBBED, + SOUND_PED_ACCIDENTREACTION1, + SOUND_PED_UNK_126, + SOUND_PED_PLAYER_AFTERSEX, + SOUND_PED_PLAYER_BEFORESEX, + SOUND_PED_COP_UNK_129, // also used for medics + SOUND_PED_COP_MANYCOPSAROUND, // also used for medics + SOUND_PED_GUNAIMEDAT2, + SOUND_PED_COP_ALONE, // also used for medics + SOUND_PED_GUNAIMEDAT3, + SOUND_PED_COP_REACTION, + SOUND_PED_COP_LITTLECOPSAROUND, // also used for medics + SOUND_PED_PLAYER_FARFROMCOPS, // also used for medics + SOUND_PED_TAXI_WAIT, + SOUND_PED_ATTACK, + SOUND_PED_DEFEND, + SOUND_PED_HEALING, + SOUND_PED_LEAVE_VEHICLE, + SOUND_PED_EVADE, + SOUND_PED_FLEE_RUN, + SOUND_PED_CRASH_VEHICLE, + SOUND_PED_CRASH_CAR, + SOUND_PED_ANNOYED_DRIVER, + SOUND_PED_147, + SOUND_PED_SOLICIT, + SOUND_PED_149, + SOUND_PED_150, + SOUND_PED_EXTINGUISHING_FIRE, + SOUND_PED_WAIT_DOUBLEBACK, + SOUND_153, + SOUND_PED_CHAT_SEXY, + SOUND_PED_CHAT_EVENT, + SOUND_PED_PED_COLLISION, + SOUND_PED_CHAT, + SOUND_PED_TAXI_CALL, + SOUND_RACE_START_3, + SOUND_RACE_START_2, + SOUND_RACE_START_1, + SOUND_RACE_START_GO, + SOUND_SPLASH, + SOUND_WATER_FALL, + SOUND_SPLATTER, + SOUND_CAR_PED_COLLISION, + SOUND_CLOCK_TICK, + SOUND_PART_MISSION_COMPLETE, + SOUND_FRONTEND_MENU_STARTING, // same sound as SOUND_HUD + + // TODO(Miami): What are 170-175?? + + SOUND_FRONTEND_RADIO_TURN_OFF = 176, // those 2 are same sound + SOUND_FRONTEND_RADIO_TURN_ON, + SOUND_FRONTEND_HURRICANE, // yes, frontend + SOUND_HUD, + SOUND_180, + SOUND_181, + SOUND_182, + SOUND_LIGHTNING, + SOUND_BULLETTRACE_1, + SOUND_BULLETTRACE_2, + SOUND_186, // makes same sound as 40 + SOUND_187, // makes same sound as 46 + SOUND_MELEE_ATTACK_START, + SOUND_SKATING, + SOUND_WEAPON_MINIGUN_ATTACK, + SOUND_WEAPON_MINIGUN_2, + SOUND_WEAPON_MINIGUN_3, + SOUND_AMMUNATION_IMRAN_ARM_BOMB, + SOUND_RADIO_CHANGE, + SOUND_FRONTEND_HIGHLIGHT_OPTION, + SOUND_FRONTEND_ENTER_OR_ADJUST, + SOUND_FRONTEND_BACK, + SOUND_FRONTEND_FAIL, + SOUND_FRONTEND_AUDIO_TEST, + SOUND_INJURED_PED_MALE_OUCH, + SOUND_INJURED_PED_FEMALE, + SOUND_SHIRT_WIND_FLAP, + SOUND_SET_203, + SOUND_TOTAL_SOUNDS = 204, + SOUND_NO_SOUND = 205, +}; + + +enum eScriptSounds { + SCRIPT_SOUND_BANK_ALARM_LOOP = 0, + SCRIPT_SOUND_PART_MISSION_COMPLETE, + SCRIPT_SOUND_POLICE_CELL_DOOR_SLIDING_LOOP, + SCRIPT_SOUND_POLICE_CELL_DOOR_CLUNK, + SCRIPT_SOUND_GARAGE_DOOR_SLIDING_LOOP, + SCRIPT_SOUND_GARAGE_DOOR_CLUNK, + SCRIPT_SOUND_SNORING_LOOP, + SCRIPT_SOUND_RACE_START_3, + SCRIPT_SOUND_RACE_START_2, + SCRIPT_SOUND_RACE_START_1, + SCRIPT_SOUND_RACE_START_GO, + SCRIPT_SOUND_SHOOTING_RANGE_TARGET_MOVING_LOOP, + SCRIPT_SOUND_SHOOTING_RANGE_TARGET_HIT, + SCRIPT_SOUND_AMMUNATION_BUY_WEAPON, + SCRIPT_SOUND_AMMUNATION_BUY_WEAPON_DENIED, + SCRIPT_SOUND_WMYCW_TICKET_SPEECH, + SCRIPT_SOUND_IMRAN_ARM_BOMB, + SCRIPT_SOUND_ANDY_SNIPER_SHOT, + SCRIPT_SOUND_WILLIE_CARD_SWIPE, + SCRIPT_SOUND_MALE_AMBULANCE_OUCH, + SCRIPT_SOUND_FEMALE_AMBULANCE_OUCH, + SCRIPT_SOUND_BUILDING_BAR_1, + SCRIPT_SOUND_BUILDING_BAR_2, + SCRIPT_SOUND_BUILDING_BAR_3, + SCRIPT_SOUND_BUILDING_BAR_4, + SCRIPT_SOUND_BUILDING_BIKER_BAR, + SCRIPT_SOUND_BUILDING_CHURCH, + SCRIPT_SOUND_BUILDING_CLUB, + SCRIPT_SOUND_BUILDING_CUBA_1, + SCRIPT_SOUND_BUILDING_CUBA_2, + SCRIPT_SOUND_BUILDING_VOODOO, + SCRIPT_SOUND_BUILDING_MUSIC_SHOP, + SCRIPT_SOUND_BUILDING_STRIPCLUB_1, + SCRIPT_SOUND_BUILDING_STRIPCLUB_2, + SCRIPT_SOUND_BUILDING_SUPERSWEEP, + SCRIPT_SOUND_SEAPLANE_LOW_FUEL, + SCRIPT_SOUND_NEW_BUILDING_BAR_1, + SCRIPT_SOUND_NEW_BUILDING_BAR_2, + SCRIPT_SOUND_NEW_BUILDING_BAR_3, + SCRIPT_SOUND_NEW_BUILDING_BAR_4, + SCRIPT_SOUND_NEW_BUILDING_MALIBU_1, + SCRIPT_SOUND_NEW_BUILDING_MALIBU_2, + SCRIPT_SOUND_NEW_BUILDING_MALIBU_3, + SCRIPT_SOUND_NEW_BUILDING_STRIP_1, + SCRIPT_SOUND_NEW_BUILDING_STRIP_2, + SCRIPT_SOUND_NEW_BUILDING_STRIP_3, + SCRIPT_SOUND_NEW_BUILDING_CHURCH, + SCRIPT_SOUND_NEW_BUILDING_FAN_1, + SCRIPT_SOUND_NEW_BUILDING_FAN_2, + SCRIPT_SOUND_NEW_BUILDING_INSECT_1, + SCRIPT_SOUND_NEW_BUILDING_INSECT_2, + SCRIPT_SOUND_NEW_WATERFALL, + SCRIPT_SOUND_BULLET_HIT_GROUND_1, + SCRIPT_SOUND_BULLET_HIT_GROUND_2, + SCRIPT_SOUND_BULLET_HIT_GROUND_3, + SCRIPT_SOUND_BULLET_HIT_WATER, // no sound + SCRIPT_SOUND_PAYPHONE_RINGING, + SCRIPT_SOUND_GLASS_BREAK_L, + SCRIPT_SOUND_GLASS_BREAK_S, + SCRIPT_SOUND_GLASS_CRACK, + SCRIPT_SOUND_GLASS_LIGHT_BREAK, + SCRIPT_SOUND_BOX_DESTROYED_1, + SCRIPT_SOUND_BOX_DESTROYED_2, + SCRIPT_SOUND_METAL_COLLISION, + SCRIPT_SOUND_TIRE_COLLISION, + SCRIPT_SOUND_HIT_BALL, + SCRIPT_SOUND_GUNSHELL_DROP, + SCRIPT_SOUND_GUNSHELL_DROP_SOFT, + SCRIPT_SOUND_TOTAL, + SCRIPT_SOUND_INVALID, +}; |
