Audio enhancements:

* redo high fps fix
* make releasing vehicle sounds attach to entities
* fix bug with reusing audio entity that is still being used
* use time scale to modify sound speed
This commit is contained in:
Sergeanur 2021-08-24 14:58:41 +03:00
parent ef0ba763b9
commit abbfb09a64
5 changed files with 166 additions and 49 deletions

View file

@ -2321,7 +2321,11 @@ cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams& params, CVehicle* veh
freq = GearFreqAdj[CurrentPretendGear] + freqModifier + 22050; freq = GearFreqAdj[CurrentPretendGear] + freqModifier + 22050;
if (engineSoundType == SFX_BANK_TRUCK) if (engineSoundType == SFX_BANK_TRUCK)
freq /= 2; freq /= 2;
#ifdef USE_TIME_SCALE_FOR_AUDIO
SampleManager.SetChannelFrequency(nChannel, freq * CTimer::GetTimeScale());
#else
SampleManager.SetChannelFrequency(nChannel, freq); SampleManager.SetChannelFrequency(nChannel, freq);
#endif
if (!channelUsed) { if (!channelUsed) {
#ifdef AUDIO_REVERB #ifdef AUDIO_REVERB
SampleManager.SetChannelReverbFlag(nChannel, m_bDynamicAcousticModelingStatus != FALSE); SampleManager.SetChannelReverbFlag(nChannel, m_bDynamicAcousticModelingStatus != FALSE);
@ -7870,7 +7874,7 @@ cPedComments::Process()
AudioManager.m_sQueueSample.m_nEmittingVolume = MAX_VOLUME; AudioManager.m_sQueueSample.m_nEmittingVolume = MAX_VOLUME;
#endif // FIX_BUGS #endif // FIX_BUGS
#endif // EXTERNAL_3D_SOUND #endif // EXTERNAL_3D_SOUND
#ifdef ATTACH_PED_COMMENTS_TO_ENTITIES #ifdef ATTACH_RELEASING_SOUNDS_TO_ENTITIES
// let's disable doppler because if sounds funny as the sound moves // let's disable doppler because if sounds funny as the sound moves
// originally position of ped comment doesn't change so this has no effect anyway // originally position of ped comment doesn't change so this has no effect anyway
AudioManager.m_sQueueSample.m_fSpeedMultiplier = 0.0f; AudioManager.m_sQueueSample.m_fSpeedMultiplier = 0.0f;
@ -7891,16 +7895,19 @@ cPedComments::Process()
if((sampleIndex >= SFX_POLICE_BOAT_1 && sampleIndex <= SFX_POLICE_BOAT_23) || if((sampleIndex >= SFX_POLICE_BOAT_1 && sampleIndex <= SFX_POLICE_BOAT_23) ||
(sampleIndex >= SFX_POLICE_HELI_1 && sampleIndex <= SFX_POLICE_HELI_20)) (sampleIndex >= SFX_POLICE_HELI_1 && sampleIndex <= SFX_POLICE_HELI_20))
AudioManager.m_sQueueSample.m_MaxDistance = 400.0f; AudioManager.m_sQueueSample.m_MaxDistance = 400.0f;
#ifndef ATTACH_PED_COMMENTS_TO_ENTITIES #ifndef ATTACH_RELEASING_SOUNDS_TO_ENTITIES
else if (sampleIndex >= SFX_PLAYER_ANGRY_BUSTED_1 && sampleIndex <= SFX_PLAYER_ON_FIRE_16) { // check if player sfx else if (sampleIndex >= SFX_PLAYER_ANGRY_BUSTED_1 && sampleIndex <= SFX_PLAYER_ON_FIRE_16) { // check if player sfx
AudioManager.m_sQueueSample.m_bIs2D = TRUE; AudioManager.m_sQueueSample.m_bIs2D = TRUE;
AudioManager.m_sQueueSample.m_nPan = 63; AudioManager.m_sQueueSample.m_nPan = 63;
} }
#endif // ATTACH_PED_COMMENTS_TO_ENTITIES #endif // ATTACH_RELEASING_SOUNDS_TO_ENTITIES
#endif // FIX_BUGS #endif // FIX_BUGS
AudioManager.m_sQueueSample.m_nFrequency = AudioManager.m_sQueueSample.m_nFrequency =
SampleManager.GetSampleBaseFrequency(AudioManager.m_sQueueSample.m_nSampleIndex) + AudioManager.RandomDisplacement(750); SampleManager.GetSampleBaseFrequency(AudioManager.m_sQueueSample.m_nSampleIndex) + AudioManager.RandomDisplacement(750);
if(CTimer::GetIsSlowMotionActive()) AudioManager.m_sQueueSample.m_nFrequency /= 2; #ifndef USE_TIME_SCALE_FOR_AUDIO
if (CTimer::GetIsSlowMotionActive())
AudioManager.m_sQueueSample.m_nFrequency >>= 1;
#endif
m_asPedComments[m_nActiveBank][m_nIndexMap[m_nActiveBank][0]].m_nProcess = -1; m_asPedComments[m_nActiveBank][m_nIndexMap[m_nActiveBank][0]].m_nProcess = -1;
prevSamples[counter++] = sampleIndex; prevSamples[counter++] = sampleIndex;
if(counter == 10) counter = 0; if(counter == 10) counter = 0;

View file

@ -135,8 +135,47 @@ cAudioManager::CreateEntity(eAudioType type, void *entity)
return AEHANDLE_ERROR_NOENTITY; return AEHANDLE_ERROR_NOENTITY;
if (type >= TOTAL_AUDIO_TYPES) if (type >= TOTAL_AUDIO_TYPES)
return AEHANDLE_ERROR_BADAUDIOTYPE; return AEHANDLE_ERROR_BADAUDIOTYPE;
#ifdef FIX_BUGS
// since sound could still play after entity deletion let's make sure we don't override one that is in use
// find all the free entity IDs that are being used by queued samples
int32 stillUsedEntities[NUM_CHANNELS_GENERIC * NUM_SOUNDS_SAMPLES_BANKS];
uint32 stillUsedEntitiesCount = 0;
for (uint8 i = 0; i < NUM_SOUNDS_SAMPLES_BANKS; i++)
for (uint8 j = 0; j < m_SampleRequestQueuesStatus[i]; j++) {
tSound &sound = m_asSamples[i][m_abSampleQueueIndexTable[i][j]];
if (sound.m_nEntityIndex < 0) continue;
if (!m_asAudioEntities[sound.m_nEntityIndex].m_bIsUsed) {
bool found = false;
for (uint8 k = 0; k < stillUsedEntitiesCount; k++) {
if (stillUsedEntities[k] == sound.m_nEntityIndex) {
found = true;
break;
}
}
if (!found)
stillUsedEntities[stillUsedEntitiesCount++] = sound.m_nEntityIndex;
}
}
#endif
for (uint32 i = 0; i < ARRAY_SIZE(m_asAudioEntities); i++) { for (uint32 i = 0; i < ARRAY_SIZE(m_asAudioEntities); i++) {
if (!m_asAudioEntities[i].m_bIsUsed) { if (!m_asAudioEntities[i].m_bIsUsed) {
#ifdef FIX_BUGS
// skip if ID is still used by queued sample
bool skip = false;
for (uint8 j = 0; j < stillUsedEntitiesCount; j++) {
if (stillUsedEntities[j] == i) {
//debug("audio entity %i still used, skipping\n", i);
skip = true;
break;
}
}
if (skip)
continue;
#endif
m_asAudioEntities[i].m_bIsUsed = TRUE; m_asAudioEntities[i].m_bIsUsed = TRUE;
m_asAudioEntities[i].m_bStatus = FALSE; m_asAudioEntities[i].m_bStatus = FALSE;
m_asAudioEntities[i].m_nType = type; m_asAudioEntities[i].m_nType = type;
@ -936,39 +975,92 @@ cAudioManager::AddReleasingSounds()
if(sample.m_nCounter <= 255 || sample.m_nReflectionDelay == 0) // check if not delayed reflection if(sample.m_nCounter <= 255 || sample.m_nReflectionDelay == 0) // check if not delayed reflection
#endif #endif
{ {
if (sample.m_nFramesToPlay == 0) #ifdef ATTACH_RELEASING_SOUNDS_TO_ENTITIES
if (sample.m_nCounter <= 255 && !sample.m_bIs2D) { // check if not reflection and is a 3D sound
CEntity* entity = (CEntity*)GetEntityPointer(sample.m_nEntityIndex);
if (entity && m_asAudioEntities[sample.m_nEntityIndex].m_nType == AUDIOTYPE_PHYSICAL) {
sample.m_vecPos = entity->GetPosition();
float oldDistance = sample.m_fDistance;
sample.m_fDistance = Sqrt(GetDistanceSquared(sample.m_vecPos));
if (sample.m_nSampleIndex >= SAMPLEBANK_PED_START && sample.m_nSampleIndex <= SAMPLEBANK_PED_END) { // check if it's ped comment
uint8 vol;
if (CWorld::GetIsLineOfSightClear(TheCamera.GetPosition(), sample.m_vecPos, true, false, false, false, false, false))
vol = MAX_VOLUME;
else
vol = 31;
#ifdef EXTERNAL_3D_SOUND
sample.m_nEmittingVolume = vol;
#endif
sample.m_nVolume = ComputeVolume(vol, sample.m_MaxDistance, sample.m_fDistance);
} else {
// calculate new volume with changed distance
float volumeDiff = sq((sample.m_MaxDistance - sample.m_fDistance) / (sample.m_MaxDistance - oldDistance));
if (volumeDiff > 0.0f) {
uint8 newVolume = volumeDiff * sample.m_nVolume;
if (sample.m_nVolumeChange > 0)
sample.m_nVolumeChange = volumeDiff * sample.m_nVolumeChange;
#if defined(FIX_BUGS) && defined(EXTERNAL_3D_SOUND)
if (sample.m_nEmittingVolumeChange > 0)
sample.m_nEmittingVolumeChange = volumeDiff * sample.m_nEmittingVolumeChange;
#endif
sample.m_nVolume = Min(127, newVolume);
}
}
if (sample.m_nVolume == 0)
sample.m_nFramesToPlay = 0;
}
}
#endif
#ifdef FIX_BUGS
if (sample.m_nFramesToPlay <= 0)
continue; continue;
if (sample.m_nLoopCount == 0) { if (sample.m_nLoopCount == 0) {
if (sample.m_nVolumeChange == -1) { if (sample.m_nVolumeChange == -1) {
#if defined(FIX_BUGS) && defined(EXTERNAL_3D_SOUND)
sample.m_nVolumeChange = sample.m_nEmittingVolume / sample.m_nFramesToPlay;
#else
sample.m_nVolumeChange = sample.m_nVolume / sample.m_nFramesToPlay; sample.m_nVolumeChange = sample.m_nVolume / sample.m_nFramesToPlay;
#endif
if (sample.m_nVolumeChange <= 0) if (sample.m_nVolumeChange <= 0)
sample.m_nVolumeChange = 1; sample.m_nVolumeChange = 1;
#ifdef EXTERNAL_3D_SOUND
sample.m_nEmittingVolumeChange = sample.m_nEmittingVolume / sample.m_nFramesToPlay;
if (sample.m_nEmittingVolumeChange <= 0)
sample.m_nEmittingVolumeChange = 1;
#endif
} }
#if defined(FIX_BUGS) && defined(EXTERNAL_3D_SOUND) if (sample.m_nVolume <= sample.m_nVolumeChange * CTimer::GetTimeStepFix()) {
if (sample.m_nEmittingVolume <= sample.m_nVolumeChange) { sample.m_nFramesToPlay = 0;
continue;
}
sample.m_nVolume -= sample.m_nVolumeChange * CTimer::GetTimeStepFix();
#ifdef EXTERNAL_3D_SOUND
if (sample.m_nEmittingVolume <= sample.m_nEmittingVolumeChange * CTimer::GetTimeStepFix()) {
sample.m_nFramesToPlay = 0;
continue;
}
sample.m_nEmittingVolume -= sample.m_nEmittingVolumeChange * CTimer::GetTimeStepFix();
#endif
}
sample.m_nFramesToPlay -= CTimer::GetTimeStepFix();
if (sample.m_nFramesToPlay < 0)
sample.m_nFramesToPlay = 0;
#else #else
if (sample.m_nFramesToPlay == 0)
continue;
if (sample.m_nLoopCount == 0) {
if (sample.m_nVolumeChange == -1) {
sample.m_nVolumeChange = sample.m_nVolume / sample.m_nFramesToPlay;
if (sample.m_nVolumeChange <= 0)
sample.m_nVolumeChange = 1;
}
if (sample.m_nVolume <= sample.m_nVolumeChange) { if (sample.m_nVolume <= sample.m_nVolumeChange) {
#endif
sample.m_nFramesToPlay = 0; sample.m_nFramesToPlay = 0;
continue; continue;
} }
#if defined(FIX_BUGS) && defined(EXTERNAL_3D_SOUND)
sample.m_nEmittingVolume -= sample.m_nVolumeChange;
#else
sample.m_nVolume -= sample.m_nVolumeChange; sample.m_nVolume -= sample.m_nVolumeChange;
#endif
} }
#ifdef FIX_BUGS sample.m_nFramesToPlay--;
if(CTimer::GetLogicalFramesPassed() != 0)
#endif #endif
--sample.m_nFramesToPlay;
if (m_bReduceReleasingPriority) { if (m_bReduceReleasingPriority) {
if (sample.m_nPriority < 20) if (sample.m_nPriority < 20)
++sample.m_nPriority; sample.m_nPriority++;
} }
sample.m_bStatic = FALSE; sample.m_bStatic = FALSE;
} }
@ -1002,6 +1094,16 @@ cAudioManager::ProcessActiveQueues()
bool8 isPhoneCall; bool8 isPhoneCall;
uint8 channelOffset = 0; uint8 channelOffset = 0;
#ifdef EXTERNAL_3D_SOUND
#define WORKING_VOLUME_FIELD m_nEmittingVolume
#else
#define WORKING_VOLUME_FIELD m_nVolume
#endif
#ifdef USE_TIME_SCALE_FOR_AUDIO
float timeScale = m_nUserPause ? 1.0f : CTimer::GetTimeScale();
#endif
for (int32 i = 0; i < m_nActiveSamples; i++) { for (int32 i = 0; i < m_nActiveSamples; i++) {
m_asSamples[m_nActiveSampleQueue][i].m_bIsBeingPlayed = FALSE; m_asSamples[m_nActiveSampleQueue][i].m_bIsBeingPlayed = FALSE;
m_asActiveSamples[i].m_bIsBeingPlayed = FALSE; m_asActiveSamples[i].m_bIsBeingPlayed = FALSE;
@ -1034,12 +1136,12 @@ cAudioManager::ProcessActiveQueues()
sample.m_nVolumeChange = -1; sample.m_nVolumeChange = -1;
if (!sample.m_bStatic) { if (!sample.m_bStatic) {
if (sample.m_bIs2D) { if (sample.m_bIs2D) {
#ifdef EXTERNAL_3D_SOUND emittingVol = m_bDoubleVolume ? 2 * Min(63, sample.WORKING_VOLUME_FIELD) : sample.WORKING_VOLUME_FIELD;
emittingVol = m_bDoubleVolume ? 2 * Min(63, sample.m_nEmittingVolume) : sample.m_nEmittingVolume; #ifdef USE_TIME_SCALE_FOR_AUDIO
SampleManager.SetChannelFrequency(j, sample.m_nFrequency * timeScale);
#else #else
emittingVol = m_bDoubleVolume ? 2 * Min(63, sample.m_nVolume) : sample.m_nVolume;
#endif
SampleManager.SetChannelFrequency(j, sample.m_nFrequency); SampleManager.SetChannelFrequency(j, sample.m_nFrequency);
#endif
#ifdef EXTERNAL_3D_SOUND #ifdef EXTERNAL_3D_SOUND
SampleManager.SetChannelEmittingVolume(j, emittingVol); SampleManager.SetChannelEmittingVolume(j, emittingVol);
#else #else
@ -1047,24 +1149,6 @@ cAudioManager::ProcessActiveQueues()
SampleManager.SetChannelVolume(j, emittingVol); SampleManager.SetChannelVolume(j, emittingVol);
#endif #endif
} else { } else {
#ifdef ATTACH_PED_COMMENTS_TO_ENTITIES
if (sample.m_nCounter <= 255 && sample.m_nSampleIndex >= SAMPLEBANK_PED_START && sample.m_nSampleIndex <= SAMPLEBANK_PED_END) {
CEntity* entity = (CEntity*)GetEntityPointer(sample.m_nEntityIndex);
if (entity && m_asAudioEntities[sample.m_nEntityIndex].m_nType == AUDIOTYPE_PHYSICAL) {
sample.m_vecPos = entity->GetPosition();
sample.m_fDistance = Sqrt(GetDistanceSquared(sample.m_vecPos));
uint8 vol;
if (CWorld::GetIsLineOfSightClear(TheCamera.GetPosition(), sample.m_vecPos, true, false, false, false, false, false))
vol = MAX_VOLUME;
else
vol = 31;
#ifdef EXTERNAL_3D_SOUND
sample.m_nEmittingVolume = vol;
#endif
sample.m_nVolume = ComputeVolume(vol, sample.m_MaxDistance, sample.m_fDistance);
}
}
#endif
position2 = sample.m_fDistance; position2 = sample.m_fDistance;
position1 = m_asActiveSamples[j].m_fDistance; position1 = m_asActiveSamples[j].m_fDistance;
m_asActiveSamples[j].m_fDistance = sample.m_fDistance; m_asActiveSamples[j].m_fDistance = sample.m_fDistance;
@ -1072,7 +1156,11 @@ cAudioManager::ProcessActiveQueues()
if (sample.m_nFrequency != m_asActiveSamples[j].m_nFrequency) { if (sample.m_nFrequency != m_asActiveSamples[j].m_nFrequency) {
uint32 freq = Clamp2((int32)sample.m_nFrequency, (int32)m_asActiveSamples[j].m_nFrequency, 6000); uint32 freq = Clamp2((int32)sample.m_nFrequency, (int32)m_asActiveSamples[j].m_nFrequency, 6000);
m_asActiveSamples[j].m_nFrequency = freq; m_asActiveSamples[j].m_nFrequency = freq;
#ifdef USE_TIME_SCALE_FOR_AUDIO
SampleManager.SetChannelFrequency(j, freq * timeScale);
#else
SampleManager.SetChannelFrequency(j, freq); SampleManager.SetChannelFrequency(j, freq);
#endif
} }
#ifdef EXTERNAL_3D_SOUND #ifdef EXTERNAL_3D_SOUND
if (sample.m_nEmittingVolume != m_asActiveSamples[j].m_nEmittingVolume) { if (sample.m_nEmittingVolume != m_asActiveSamples[j].m_nEmittingVolume) {
@ -1160,18 +1248,18 @@ cAudioManager::ProcessActiveQueues()
m_asActiveSamples[j].m_nPan = ComputePan(m_asActiveSamples[j].m_fDistance, &position); m_asActiveSamples[j].m_nPan = ComputePan(m_asActiveSamples[j].m_fDistance, &position);
#endif #endif
} }
#ifdef EXTERNAL_3D_SOUND emittingVol = m_bDoubleVolume ? 2 * Min(63, m_asActiveSamples[j].WORKING_VOLUME_FIELD) : m_asActiveSamples[j].WORKING_VOLUME_FIELD;
emittingVol = m_bDoubleVolume ? 2 * Min(63, m_asActiveSamples[j].m_nEmittingVolume) : m_asActiveSamples[j].m_nEmittingVolume;
#else
emittingVol = m_bDoubleVolume ? 2 * Min(63, m_asActiveSamples[j].m_nVolume) : m_asActiveSamples[j].m_nVolume;
#endif
#ifdef GTA_PS2 #ifdef GTA_PS2
{ {
SampleManager.InitialiseChannel(k, m_asActiveSamples[k].m_nSampleIndex, m_asActiveSamples[k].m_nBankIndex); SampleManager.InitialiseChannel(k, m_asActiveSamples[k].m_nSampleIndex, m_asActiveSamples[k].m_nBankIndex);
#else #else
if (SampleManager.InitialiseChannel(k, m_asActiveSamples[k].m_nSampleIndex, m_asActiveSamples[k].m_nBankIndex)) { if (SampleManager.InitialiseChannel(k, m_asActiveSamples[k].m_nSampleIndex, m_asActiveSamples[k].m_nBankIndex)) {
#endif #endif
#ifdef USE_TIME_SCALE_FOR_AUDIO
SampleManager.SetChannelFrequency(k, m_asActiveSamples[k].m_nFrequency * timeScale);
#else
SampleManager.SetChannelFrequency(k, m_asActiveSamples[k].m_nFrequency); SampleManager.SetChannelFrequency(k, m_asActiveSamples[k].m_nFrequency);
#endif
isPhoneCall = FALSE; isPhoneCall = FALSE;
for (int32 l = 0; l < MISSION_AUDIO_SLOTS; l++) { for (int32 l = 0; l < MISSION_AUDIO_SLOTS; l++) {
if (m_bIsMissionAudioPhoneCall[l]) { if (m_bIsMissionAudioPhoneCall[l]) {
@ -1194,8 +1282,8 @@ cAudioManager::ProcessActiveQueues()
#endif #endif
#ifndef GTA_PS2 #ifndef GTA_PS2
SampleManager.SetChannelLoopPoints(k, m_asActiveSamples[k].m_nLoopStart, m_asActiveSamples[k].m_nLoopEnd); SampleManager.SetChannelLoopPoints(k, m_asActiveSamples[k].m_nLoopStart, m_asActiveSamples[k].m_nLoopEnd);
SampleManager.SetChannelLoopCount(k, m_asActiveSamples[k].m_nLoopCount);
#endif #endif
SampleManager.SetChannelLoopCount(k, m_asActiveSamples[k].m_nLoopCount);
#if !defined(GTA_PS2) || defined(AUDIO_REVERB) #if !defined(GTA_PS2) || defined(AUDIO_REVERB)
SampleManager.SetChannelReverbFlag(k, m_asActiveSamples[k].m_bReverb); SampleManager.SetChannelReverbFlag(k, m_asActiveSamples[k].m_bReverb);
#endif #endif
@ -1232,10 +1320,20 @@ cAudioManager::ProcessActiveQueues()
} }
} }
} }
#ifdef GTA_PS2 #ifdef GTA_PS2
m_nChannelOffset += channelOffset; m_nChannelOffset += channelOffset;
#endif #endif
m_nChannelOffset %= m_nActiveSamples; m_nChannelOffset %= m_nActiveSamples;
#ifdef USE_TIME_SCALE_FOR_AUDIO
for (uint8 i = 0; i < m_nActiveSamples; i++) {
if (m_asActiveSamples[i].m_nSampleIndex != NO_SAMPLE && m_asActiveSamples[i].m_bIsBeingPlayed)
SampleManager.SetChannelFrequency(i, m_asActiveSamples[i].m_nFrequency * timeScale);
}
#endif
#undef WORKING_VOLUME_FIELD
} }
void void

View file

@ -44,14 +44,21 @@ public:
// 63 = L 100% R 100% // 63 = L 100% R 100%
// 127 = L 0% R 100% // 127 = L 0% R 100%
uint8 m_nFrontRearPan; // Used on PS2 for surround panning uint8 m_nFrontRearPan; // Used on PS2 for surround panning
#ifndef FIX_BUGS
uint32 m_nFramesToPlay; // Number of frames the sound would be played (if it stops being queued). uint32 m_nFramesToPlay; // Number of frames the sound would be played (if it stops being queued).
// This one is being set by queued sample for looping sounds, otherwise calculated inside AudioManager // This one is being set by queued sample for looping sounds, otherwise calculated inside AudioManager
#else
float m_nFramesToPlay; // Made into float for high fps fix
#endif
// all fields below are internal to AudioManager calculations and aren't set by queued sample // all fields below are internal to AudioManager calculations and aren't set by queued sample
bool8 m_bIsBeingPlayed; // Set to TRUE when the sound was added or changed on current frame to avoid it being overwritten bool8 m_bIsBeingPlayed; // Set to TRUE when the sound was added or changed on current frame to avoid it being overwritten
bool8 m_bIsPlayingFinished; // Not sure about the name. Set to TRUE when sampman channel becomes free bool8 m_bIsPlayingFinished; // Not sure about the name. Set to TRUE when sampman channel becomes free
uint32 m_nFinalPriority; // Actual value used to compare priority, calculated using volume and m_nPriority. Lesser value means higher priority uint32 m_nFinalPriority; // Actual value used to compare priority, calculated using volume and m_nPriority. Lesser value means higher priority
int8 m_nVolumeChange; // How much m_nVolume should reduce per each frame. int8 m_nVolumeChange; // How much m_nVolume should reduce per each frame.
#if defined(FIX_BUGS) && defined(EXTERNAL_3D_SOUND)
int8 m_nEmittingVolumeChange; // same as above but for m_nEmittingVolume
#endif
}; };
VALIDATE_SIZE(tSound, 96); VALIDATE_SIZE(tSound, 96);

View file

@ -236,7 +236,11 @@ cAudioManager::ServicePoliceRadioChannel(uint8 wantedLevel)
default: freq = SampleManager.GetSampleBaseFrequency(sample); break; default: freq = SampleManager.GetSampleBaseFrequency(sample); break;
} }
PoliceChannelFreq = freq; PoliceChannelFreq = freq;
#ifdef USE_TIME_SCALE_FOR_AUDIO
SampleManager.SetChannelFrequency(CHANNEL_POLICE_RADIO, freq * CTimer::GetTimeScale());
#else
SampleManager.SetChannelFrequency(CHANNEL_POLICE_RADIO, freq); SampleManager.SetChannelFrequency(CHANNEL_POLICE_RADIO, freq);
#endif
SampleManager.SetChannelVolume(CHANNEL_POLICE_RADIO, 100); SampleManager.SetChannelVolume(CHANNEL_POLICE_RADIO, 100);
SampleManager.SetChannelPan(CHANNEL_POLICE_RADIO, 63); SampleManager.SetChannelPan(CHANNEL_POLICE_RADIO, 63);
#ifndef GTA_PS2 #ifndef GTA_PS2

View file

@ -449,7 +449,8 @@ static_assert(false, "SUPPORT_XBOX_SCRIPT and SUPPORT_MOBILE_SCRIPT are mutually
//#define AUDIO_OAL_USE_SNDFILE // use libsndfile to decode WAVs instead of our internal decoder //#define AUDIO_OAL_USE_SNDFILE // use libsndfile to decode WAVs instead of our internal decoder
#define AUDIO_OAL_USE_MPG123 // use mpg123 to support mp3 files #define AUDIO_OAL_USE_MPG123 // use mpg123 to support mp3 files
#define PAUSE_RADIO_IN_FRONTEND // pause radio when game is paused #define PAUSE_RADIO_IN_FRONTEND // pause radio when game is paused
#define ATTACH_PED_COMMENTS_TO_ENTITIES // ped comments coordinates would update following ped entity #define ATTACH_RELEASING_SOUNDS_TO_ENTITIES // ped comments coordinates would update following ped entity
#define USE_TIME_SCALE_FOR_AUDIO // slow down/speed up sounds according to the speed of the game
#define MULTITHREADED_AUDIO // for streams. requires C++11 or later #define MULTITHREADED_AUDIO // for streams. requires C++11 or later
#ifdef AUDIO_OPUS #ifdef AUDIO_OPUS