|
|
@@ -420,10 +420,7 @@ cAudioManager::CheckForAnAudioFileOnCD() const |
|
|
uint8 |
|
|
cAudioManager::GetCDAudioDriveLetter() const |
|
|
{ |
|
|
if (m_bIsInitialised) |
|
|
return SampleManager.GetCDAudioDriveLetter(); |
|
|
|
|
|
return 0; |
|
|
return SampleManager.GetCDAudioDriveLetter(); |
|
|
} |
|
|
|
|
|
bool |
|
|
@@ -483,12 +480,18 @@ 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) |
|
|
emittingVolume = sq((soundIntensity - newSoundIntensity - (distance - newSoundIntensity)) / (soundIntensity - newSoundIntensity)) * emittingVolume; |
|
|
return emittingVolume; |
|
|
if (newSoundIntensity > distance) |
|
|
return emittingVolume; |
|
|
|
|
|
newEmittingVolume = emittingVolume * SQR((soundIntensity - newSoundIntensity - (distance - newSoundIntensity)) |
|
|
/ (soundIntensity - newSoundIntensity)); |
|
|
return Min(127u, newEmittingVolume); |
|
|
} |
|
|
|
|
|
void |
|
|
@@ -500,17 +503,16 @@ cAudioManager::TranslateEntity(Const CVector *in, CVector *out) const |
|
|
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(vec->x / (dist / 64.f))); |
|
|
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); |
|
|
} |
|
|
|
|
|
int32 |
|
|
uint32 |
|
|
cAudioManager::ComputeDopplerEffectedFrequency(uint32 oldFreq, float position1, float position2, float speedMultiplier) const |
|
|
{ |
|
|
uint32 newFreq = oldFreq; |
|
|
@@ -519,11 +521,7 @@ cAudioManager::ComputeDopplerEffectedFrequency(uint32 oldFreq, float position1, |
|
|
if (dist != 0.0f) { |
|
|
float speedOfSource = (dist / m_nTimeSpent) * speedMultiplier; |
|
|
if (m_fSpeedOfSound > Abs(speedOfSource)) { |
|
|
if (speedOfSource < 0.0f) { |
|
|
speedOfSource = Max(speedOfSource, -1.5f); |
|
|
} else { |
|
|
speedOfSource = Min(speedOfSource, 1.5f); |
|
|
} |
|
|
speedOfSource = clamp2(speedOfSource, 0.0f, 1.5f); |
|
|
newFreq = (oldFreq * m_fSpeedOfSound) / (speedOfSource + m_fSpeedOfSound); |
|
|
} |
|
|
} |
|
|
@@ -750,46 +748,50 @@ cAudioManager::AddReleasingSounds() |
|
|
void |
|
|
cAudioManager::ProcessActiveQueues() |
|
|
{ |
|
|
bool flag; |
|
|
float position2; |
|
|
float position1; |
|
|
|
|
|
uint32 v28; |
|
|
uint32 v29; |
|
|
|
|
|
float x; |
|
|
float usedX; |
|
|
float usedY; |
|
|
float usedZ; |
|
|
|
|
|
uint8 vol; |
|
|
uint8 emittingVol; |
|
|
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]]; |
|
|
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) { |
|
|
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) { |
|
|
flag = !!(j & 1); |
|
|
|
|
|
if (field_5554 & 1) { |
|
|
if (!(j & 1)) { |
|
|
flag = false; |
|
|
} else { |
|
|
flag = true; |
|
|
} |
|
|
} else if (j & 1) { |
|
|
flag = false; |
|
|
} else { |
|
|
flag = !(j & 1); |
|
|
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; |
|
|
@@ -805,37 +807,39 @@ cAudioManager::ProcessActiveQueues() |
|
|
SampleManager.SetChannelEmittingVolume(j, emittingVol); |
|
|
} else { |
|
|
m_asActiveSamples[j].m_fDistance = sample.m_fDistance; |
|
|
position2 = sample.m_fDistance; |
|
|
position1 = m_asActiveSamples[j].m_fDistance; |
|
|
sample.m_nFrequency = ComputeDopplerEffectedFrequency(sample.m_nFrequency, position1, position2, sample.m_fSpeedMultiplier); |
|
|
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) { |
|
|
int32 freq; |
|
|
if (sample.m_nFrequency <= m_asActiveSamples[j].m_nFrequency) { |
|
|
#ifdef FIX_BUGS |
|
|
freq = Max((int32)sample.m_nFrequency, (int32)m_asActiveSamples[j].m_nFrequency - 6000); |
|
|
#else |
|
|
freq = Max((int32)sample.m_nFrequency, int32(m_asActiveSamples[j].m_nFrequency - 6000)); |
|
|
#endif |
|
|
} else { |
|
|
freq = Min(sample.m_nFrequency, m_asActiveSamples[j].m_nFrequency + 6000); |
|
|
} |
|
|
m_asActiveSamples[j].m_nFrequency = freq; |
|
|
SampleManager.SetChannelFrequency(j, freq); |
|
|
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) { |
|
|
if (sample.m_nEmittingVolume <= m_asActiveSamples[j].m_nEmittingVolume) { |
|
|
vol = Max(m_asActiveSamples[j].m_nEmittingVolume - 10, sample.m_nEmittingVolume); |
|
|
} else { |
|
|
vol = Min(m_asActiveSamples[j].m_nEmittingVolume + 10, sample.m_nEmittingVolume); |
|
|
} |
|
|
vol = clamp2((int8)sample.m_nEmittingVolume, (int8)m_asActiveSamples[j].m_nEmittingVolume, 10); |
|
|
|
|
|
uint8 emittingVol; |
|
|
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; |
|
|
} |
|
|
@@ -844,10 +848,11 @@ cAudioManager::ProcessActiveQueues() |
|
|
SampleManager.SetChannel3DDistances(j, sample.m_fSoundIntensity, 0.25f * sample.m_fSoundIntensity); |
|
|
} |
|
|
SampleManager.SetChannelReverbFlag(j, sample.m_bReverbFlag); |
|
|
break; |
|
|
break; //continue for i |
|
|
} |
|
|
sample.m_bIsProcessed = false; |
|
|
m_asActiveSamples[j].m_bIsProcessed = false; |
|
|
//continue for j |
|
|
} |
|
|
} |
|
|
} |
|
|
@@ -859,59 +864,69 @@ cAudioManager::ProcessActiveQueues() |
|
|
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) { |
|
|
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_nLoopsRemaining--; |
|
|
sample.m_nReleasingVolumeDivider = 1; |
|
|
} else { |
|
|
for (uint8 j = 0; j < m_nActiveSamples; ++j) { |
|
|
if (!m_asActiveSamples[j].m_bIsProcessed) { |
|
|
if (sample.m_nLoopCount) { |
|
|
v28 = sample.m_nFrequency / m_nTimeSpent; |
|
|
v29 = sample.m_nLoopCount * SampleManager.GetSampleLength(sample.m_nSampleIndex); |
|
|
if (v28 == 0) |
|
|
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 = v29 / v28 + 1; |
|
|
sample.m_nReleasingVolumeDivider = loopCount / freqDivided + 1; |
|
|
} |
|
|
memcpy(&m_asActiveSamples[j], &sample, sizeof(tSound)); |
|
|
if (!m_asActiveSamples[j].m_bIs2D) |
|
|
TranslateEntity(&m_asActiveSamples[j].m_vecPos, &position); |
|
|
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[j].m_nEmittingVolume); |
|
|
emittingVol = 2 * Min(63, m_asActiveSamples[k].m_nEmittingVolume); |
|
|
} else { |
|
|
emittingVol = m_asActiveSamples[j].m_nEmittingVolume; |
|
|
emittingVol = m_asActiveSamples[k].m_nEmittingVolume; |
|
|
} |
|
|
if (SampleManager.InitialiseChannel(j, m_asActiveSamples[j].m_nSampleIndex, m_asActiveSamples[j].m_nBankIndex)) { |
|
|
SampleManager.SetChannelFrequency(j, m_asActiveSamples[j].m_nFrequency); |
|
|
SampleManager.SetChannelEmittingVolume(j, emittingVol); |
|
|
SampleManager.SetChannelLoopPoints(j, m_asActiveSamples[j].m_nLoopStart, m_asActiveSamples[j].m_nLoopEnd); |
|
|
SampleManager.SetChannelLoopCount(j, m_asActiveSamples[j].m_nLoopCount); |
|
|
SampleManager.SetChannelReverbFlag(j, m_asActiveSamples[j].m_bReverbFlag); |
|
|
if (m_asActiveSamples[j].m_bIs2D) { |
|
|
uint8 offset = m_asActiveSamples[j].m_nOffset; |
|
|
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.f; |
|
|
x = 0.0f; |
|
|
} else if (offset >= 63) { |
|
|
x = (offset - 63) * 1000.f / 63; |
|
|
x = (offset - 63) * 1000.0f / 63; |
|
|
} else { |
|
|
x = -(63 - offset) * 1000.f / 63; |
|
|
x = -(63 - offset) * 1000.0f / 63; //same like line below |
|
|
} |
|
|
usedX = x; |
|
|
usedY = 0.f; |
|
|
usedZ = 0.f; |
|
|
m_asActiveSamples[j].m_fSoundIntensity = 100000.0f; |
|
|
} else { |
|
|
usedX = position.x; |
|
|
usedY = position.y; |
|
|
usedZ = position.z; |
|
|
position = CVector(x, 0.0f, 0.0f); |
|
|
m_asActiveSamples[k].m_fSoundIntensity = 100000.0f; |
|
|
} |
|
|
SampleManager.SetChannel3DPosition(j, usedX, usedY, usedZ); |
|
|
SampleManager.SetChannel3DDistances(j, m_asActiveSamples[j].m_fSoundIntensity, 0.25f * m_asActiveSamples[j].m_fSoundIntensity); |
|
|
SampleManager.StartChannel(j); |
|
|
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[j].m_bIsProcessed = true; |
|
|
m_asActiveSamples[k].m_bIsProcessed = true; |
|
|
sample.m_bIsProcessed = true; |
|
|
sample.m_nVolumeChange = -1; |
|
|
break; |
|
|
@@ -920,6 +935,7 @@ cAudioManager::ProcessActiveQueues() |
|
|
} |
|
|
} |
|
|
} |
|
|
field_6 %= m_nActiveSamples; |
|
|
} |
|
|
|
|
|
void |
|
|
@@ -934,7 +950,7 @@ cAudioManager::ClearRequestedQueue() |
|
|
void |
|
|
cAudioManager::ClearActiveSamples() |
|
|
{ |
|
|
for (int32 i = 0; i < m_nActiveSamples; i++) { |
|
|
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; |
|
|
@@ -957,7 +973,7 @@ cAudioManager::ClearActiveSamples() |
|
|
m_asActiveSamples[i].m_nCalculatedVolume = 0; |
|
|
m_asActiveSamples[i].m_nReleasingVolumeDivider = 0; |
|
|
m_asActiveSamples[i].m_nVolumeChange = -1; |
|
|
m_asActiveSamples[i].m_vecPos = {0.0f, 0.0f, 0.0f}; |
|
|
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; |
|
|
|