Skip to content
This repository was archived by the owner on Jan 5, 2024. It is now read-only.

Commit 5864e1f

Browse files
committed
Added SoundSet standalone object to allow SoundSets to have sub SoundSets and clean things up
Moved sound cycle mode, sound adding, soundset ini handling and sound selection stuff from SoundContainer to SoundSet Made SoundContainer properties private, them being protected was an accident Renamed SoundSelectionCycleMode and SoundOverlapMode values so they don't have MODE_ at the front Cleaned up GUISound, HDFirearm, AudioMan, NetworkClient to match changes
1 parent 74902ec commit 5864e1f

File tree

9 files changed

+531
-349
lines changed

9 files changed

+531
-349
lines changed

Entities/HDFirearm.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -178,17 +178,17 @@ int HDFirearm::ReadProperty(std::string propName, Reader &reader)
178178
}
179179
} else if (propName == "PreFireSound") {
180180
reader >> m_PreFireSound;
181-
m_DeactivationSound.SetSoundOverlapMode(SoundContainer::SoundOverlapMode::MODE_IGNORE_PLAY);
181+
m_DeactivationSound.SetSoundOverlapMode(SoundContainer::SoundOverlapMode::IGNORE_PLAY);
182182
} else if (propName == "FireSound")
183183
reader >> m_FireSound;
184184
else if (propName == "FireEchoSound") {
185185
reader >> m_FireEchoSound;
186-
m_FireEchoSound.SetSoundOverlapMode(SoundContainer::SoundOverlapMode::MODE_RESTART);
186+
m_FireEchoSound.SetSoundOverlapMode(SoundContainer::SoundOverlapMode::RESTART);
187187
} else if (propName == "ActiveSound") {
188188
reader >> m_ActiveSound;
189189
} else if (propName == "DeactivationSound") {
190190
reader >> m_DeactivationSound;
191-
m_DeactivationSound.SetSoundOverlapMode(SoundContainer::SoundOverlapMode::MODE_IGNORE_PLAY);
191+
m_DeactivationSound.SetSoundOverlapMode(SoundContainer::SoundOverlapMode::IGNORE_PLAY);
192192
} else if (propName == "EmptySound")
193193
reader >> m_EmptySound;
194194
else if (propName == "ReloadStartSound")

Entities/SoundContainer.cpp

Lines changed: 45 additions & 204 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,19 @@ namespace RTE {
44

55
ConcreteClassInfo(SoundContainer, Entity, 50);
66

7-
const std::unordered_map<std::string, SoundContainer::SoundCycleMode> SoundContainer::c_SoundCycleModeMap = {
8-
{"Random", SoundContainer::SoundCycleMode::MODE_RANDOM},
9-
{"Forwards", SoundContainer::SoundCycleMode::MODE_FORWARDS}
10-
};
117
const std::unordered_map<std::string, SoundContainer::SoundOverlapMode> SoundContainer::c_SoundOverlapModeMap = {
12-
{"Overlap", SoundContainer::SoundOverlapMode::MODE_OVERLAP},
13-
{"Restart", SoundContainer::SoundOverlapMode::MODE_RESTART},
14-
{"Ignore Play", SoundContainer::SoundOverlapMode::MODE_IGNORE_PLAY}
8+
{"Overlap", SoundContainer::SoundOverlapMode::OVERLAP},
9+
{"Restart", SoundContainer::SoundOverlapMode::RESTART},
10+
{"Ignore Play", SoundContainer::SoundOverlapMode::IGNORE_PLAY}
1511
};
1612

1713
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1814

1915
void SoundContainer::Clear() {
20-
m_SoundSets.clear();
21-
m_SelectedSoundSet = 0;
22-
m_SoundSelectionCycleMode = MODE_RANDOM;
16+
m_TopLevelSoundSet.Destroy();
2317

2418
m_PlayingChannels.clear();
25-
m_SoundOverlapMode = MODE_OVERLAP;
19+
m_SoundOverlapMode = SoundOverlapMode::OVERLAP;
2620

2721
m_Immobile = false;
2822
m_AttenuationStartDistance = c_DefaultAttenuationStartDistance;
@@ -42,15 +36,7 @@ namespace RTE {
4236
int SoundContainer::Create(const SoundContainer &reference) {
4337
Entity::Create(reference);
4438

45-
for (const std::vector<SoundData> &referenceSoundSet : reference.m_SoundSets) {
46-
std::vector<SoundData> soundSet;
47-
for (const SoundData &referenceData : referenceSoundSet) {
48-
soundSet.push_back(SoundData {referenceData.SoundFile, referenceData.SoundObject, referenceData.Offset, referenceData.MinimumAudibleDistance, referenceData.AttenuationStartDistance});
49-
}
50-
m_SoundSets.push_back(soundSet);
51-
}
52-
m_SelectedSoundSet = reference.m_SelectedSoundSet;
53-
m_SoundSelectionCycleMode = reference.m_SoundSelectionCycleMode;
39+
m_TopLevelSoundSet.Create(reference.m_TopLevelSoundSet);
5440

5541
m_PlayingChannels.clear();
5642
m_SoundOverlapMode = reference.m_SoundOverlapMode;
@@ -72,15 +58,14 @@ namespace RTE {
7258
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7359

7460
int SoundContainer::ReadProperty(std::string propName, Reader &reader) {
75-
if (propName == "AddSound" || propName == "AddSoundSet") {
76-
return ReadSoundOrSoundSet(propName, reader);
77-
} else if (propName == "CycleMode") {
78-
std::string cycleModeString = reader.ReadPropValue();
79-
if (c_SoundCycleModeMap.find(cycleModeString) != c_SoundCycleModeMap.end()) {
80-
m_SoundSelectionCycleMode = c_SoundCycleModeMap.find(cycleModeString)->second;
81-
} else {
82-
reader.ReportError("Cycle mode " + cycleModeString + " is invalid.");
83-
}
61+
if (propName == "AddSound") {
62+
m_TopLevelSoundSet.AddSoundData(SoundSet::ReadAndGetSound(reader));
63+
} else if (propName == "AddSoundSet") {
64+
SoundSet subSoundSet;
65+
reader >> subSoundSet;
66+
m_TopLevelSoundSet.AddSubSoundSet(subSoundSet);
67+
} else if (propName == "SoundSelectionCycleMode" || propName == "CycleMode") {
68+
m_TopLevelSoundSet.SetSoundSelectionCycleMode(SoundSet::ReadSoundSelectionCycleMode(reader));
8469
} else if (propName == "OverlapMode") {
8570
std::string overlapModeString = reader.ReadPropValue();
8671
if (c_SoundOverlapModeMap.find(overlapModeString) != c_SoundOverlapModeMap.end()) {
@@ -112,110 +97,22 @@ namespace RTE {
11297
return 0;
11398
}
11499

115-
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
116-
117-
int SoundContainer::ReadSoundOrSoundSet(const std::string &propName, Reader &reader) {
118-
vector<SoundData> soundSet;
119-
if (propName == "AddSound") {
120-
soundSet.push_back(ReadAndGetSound(reader));
121-
} else if (propName == "AddSoundSet") {
122-
reader.ReadPropValue();
123-
while (reader.NextProperty()) {
124-
std::string soundSetSubPropertyName = reader.ReadPropName();
125-
if (soundSetSubPropertyName == "AddSound") {
126-
soundSet.push_back(ReadAndGetSound(reader));
127-
} else {
128-
reader.ReportError(soundSetSubPropertyName + " is not a valid property of SoundSets.");
129-
}
130-
}
131-
}
132-
133-
m_SoundSets.push_back(soundSet);
134-
return 0;
135-
}
136-
137-
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
138-
139-
SoundContainer::SoundData SoundContainer::ReadAndGetSound(Reader &reader) const {
140-
std::string propValue = reader.ReadPropValue();
141-
SoundData soundData;
142-
143-
/// <summary>
144-
/// Internal lambda function to load an audio file by path in as a ContentFile, which in turn loads it into FMOD, then returns SoundData for it in the outParam outSoundData.
145-
/// </summary>
146-
/// <param name="soundPath">The path to the sound file.</param>
147-
auto readSound = [&soundData, &reader](const std::string &soundPath) {
148-
ContentFile soundFile(soundPath.c_str());
149-
soundFile.SetFormattedReaderPosition("in file " + reader.GetCurrentFilePath() + " on line " + std::to_string(reader.GetCurrentFileLine()));
150-
FMOD::Sound *soundObject = soundFile.GetAsSound();
151-
if (g_AudioMan.IsAudioEnabled() && !soundObject) { reader.ReportError(std::string("Failed to load the sound from the file")); }
152-
153-
soundData.SoundFile = soundFile;
154-
soundData.SoundObject = soundObject;
155-
};
156-
157-
if (propValue != "Sound" && propValue != "ContentFile") {
158-
readSound(propValue);
159-
return soundData;
160-
}
161-
162-
while (reader.NextProperty()) {
163-
std::string soundSubPropertyName = reader.ReadPropName();
164-
if (soundSubPropertyName == "FilePath" || soundSubPropertyName == "Path") {
165-
readSound(reader.ReadPropValue());
166-
} else if (soundSubPropertyName == "Offset") {
167-
reader >> soundData.Offset;
168-
} else if (soundSubPropertyName == "MinimumAudibleDistance") {
169-
reader >> soundData.MinimumAudibleDistance;
170-
} else if (soundSubPropertyName == "AttenuationStartDistance") {
171-
reader >> soundData.AttenuationStartDistance;
172-
}
173-
}
174-
175-
return soundData;
176-
}
177-
178100
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
179101

180102
int SoundContainer::Save(Writer &writer) const {
181103
Entity::Save(writer);
182104

183-
for (const std::vector<SoundData> &soundSet : m_SoundSets) {
184-
writer.NewProperty("AddSoundSet");
185-
writer.ObjectStart("SoundSet");
105+
writer << m_TopLevelSoundSet;
186106

187-
for (const SoundData &soundData : soundSet) {
188-
writer.NewProperty("AddSound");
189-
writer.ObjectStart("ContentFile");
190-
191-
writer.NewProperty("FilePath");
192-
writer << soundData.SoundFile.GetDataPath();
193-
writer.NewProperty("Offset");
194-
writer << soundData.Offset;
195-
writer.NewProperty("MinimumAudibleDistance");
196-
writer << soundData.MinimumAudibleDistance;
197-
writer.NewProperty("AttenuationStartDistance");
198-
writer << soundData.AttenuationStartDistance;
199-
200-
writer.ObjectEnd();
201-
}
202-
writer.ObjectEnd();
203-
}
204-
205-
writer.NewProperty("CycleMode");
206-
std::list<std::pair<const std::string, SoundCycleMode>>::const_iterator cycleModeMapEntry = std::find_if(c_SoundCycleModeMap.begin(), c_SoundCycleModeMap.end(), [&soundSelectionCycleMode = m_SoundSelectionCycleMode](auto element) { return element.second == soundSelectionCycleMode; });
207-
if (cycleModeMapEntry != c_SoundCycleModeMap.end()) {
208-
writer << cycleModeMapEntry->first;
209-
} else {
210-
writer << m_SoundSelectionCycleMode;
211-
}
107+
writer.NewProperty("SoundSelectionCycleMode");
108+
SoundSet::SaveSoundSelectionCycleMode(writer, m_TopLevelSoundSet.GetSoundSelectionCycleMode());
212109

213110
writer.NewProperty("OverlapMode");
214111
std::list<std::pair<const std::string, SoundOverlapMode>>::const_iterator overlapModeMapEntry = std::find_if(c_SoundOverlapModeMap.begin(), c_SoundOverlapModeMap.end(), [&soundOverlapMode = m_SoundOverlapMode](auto element) { return element.second == soundOverlapMode; });
215112
if (overlapModeMapEntry != c_SoundOverlapModeMap.end()) {
216113
writer << overlapModeMapEntry->first;
217114
} else {
218-
writer << m_SoundOverlapMode;
115+
RTEAbort("Tried to write invalid SoundOverlapMode when saving SoundContainer.");
219116
}
220117

221118
writer.NewProperty("Immobile");
@@ -242,53 +139,37 @@ namespace RTE {
242139

243140
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
244141

245-
void SoundContainer::AddSound(const std::string &soundFilePath, unsigned int soundSetIndex, const Vector &offset, float minimumAudibleDistance, float attenuationStartDistance, bool abortGameForInvalidSound) {
246-
std::vector<SoundData> soundSet;
247-
if (soundSetIndex < m_SoundSets.size()) { soundSet = m_SoundSets[soundSetIndex]; }
248-
249-
ContentFile soundFile(soundFilePath.c_str());
250-
FMOD::Sound *soundObject = soundFile.GetAsSound(abortGameForInvalidSound, false);
251-
if (!soundObject) {
252-
return;
253-
}
254-
255-
soundSet.push_back({soundFile, soundObject, offset, minimumAudibleDistance, attenuationStartDistance});
256-
if (soundSetIndex >= m_SoundSets.size()) { m_SoundSets.push_back(soundSet); }
257-
258-
m_SoundPropertiesUpToDate = false;
259-
}
260-
261-
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
262-
263-
std::vector<size_t> SoundContainer::GetSelectedSoundHashes() const {
142+
std::vector<std::size_t> SoundContainer::GetSelectedSoundHashes() const {
264143
std::vector<size_t> soundHashes;
265-
for (const SoundData &selectedSoundData : m_SoundSets[m_SelectedSoundSet]) {
266-
soundHashes.push_back(selectedSoundData.SoundFile.GetHash());
144+
std::vector<SoundSet::SoundData *> flattenedSoundData;
145+
m_TopLevelSoundSet.GetFlattenedSoundData(flattenedSoundData, false);
146+
for (const SoundSet::SoundData *selectedSoundData : flattenedSoundData) {
147+
soundHashes.push_back(selectedSoundData->SoundFile.GetHash());
267148
}
268149
return soundHashes;
269150
}
270151

271152
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
272153

273-
const SoundContainer::SoundData *SoundContainer::GetSoundDataForSound(const FMOD::Sound *sound) const {
274-
for (const std::vector<SoundData> &soundSet : m_SoundSets) {
275-
for (const SoundData &soundData : soundSet) {
276-
if (sound == soundData.SoundObject) {
277-
return &soundData;
278-
}
154+
const SoundSet::SoundData * SoundContainer::GetSoundDataForSound(const FMOD::Sound *sound) const {
155+
std::vector<SoundSet::SoundData *> flattenedSoundData;
156+
m_TopLevelSoundSet.GetFlattenedSoundData(flattenedSoundData, false);
157+
for (const SoundSet::SoundData *soundData : flattenedSoundData) {
158+
if (sound == soundData->SoundObject) {
159+
return soundData;
279160
}
280161
}
281-
return NULL;
162+
return nullptr;
282163
}
283164

284165
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
285166

286167
bool SoundContainer::Play(int player) {
287168
if (HasAnySounds()) {
288169
if (IsBeingPlayed()) {
289-
if (m_SoundOverlapMode == MODE_RESTART) {
170+
if (m_SoundOverlapMode == SoundOverlapMode::RESTART) {
290171
Restart(player);
291-
} else if (m_SoundOverlapMode == MODE_IGNORE_PLAY) {
172+
} else if (m_SoundOverlapMode == SoundOverlapMode::IGNORE_PLAY) {
292173
return false;
293174
}
294175
}
@@ -298,65 +179,25 @@ namespace RTE {
298179
return false;
299180
}
300181

301-
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
302-
303-
bool SoundContainer::SelectNextSoundSet() {
304-
int soundSetCount = m_SoundSets.size();
305-
switch (soundSetCount) {
306-
case 0:
307-
return false;
308-
case 1:
309-
return true;
310-
case 2:
311-
m_SelectedSoundSet = (m_SelectedSoundSet + 1) % 2;
312-
break;
313-
default:
314-
/// <summary>
315-
/// Internal lambda function to pick a random sound that's not the previously played sound. Done to avoid scoping issues inside the switch below.
316-
/// </summary>
317-
auto selectRandomSound = [&soundSetCount, this]() {
318-
size_t soundToSelect = RandomNum(0, soundSetCount - 1);
319-
while (soundToSelect == m_SelectedSoundSet) {
320-
soundToSelect = RandomNum(0, soundSetCount - 1);
321-
}
322-
m_SelectedSoundSet = soundToSelect;
323-
};
324-
325-
switch (m_SoundSelectionCycleMode) {
326-
case MODE_RANDOM:
327-
selectRandomSound();
328-
break;
329-
case MODE_FORWARDS:
330-
m_SelectedSoundSet = (m_SelectedSoundSet + 1) % soundSetCount;
331-
break;
332-
default:
333-
RTEAbort("Invalid sound cycle mode " + m_SoundSelectionCycleMode);
334-
break;
335-
}
336-
RTEAssert(m_SelectedSoundSet >= 0 && m_SelectedSoundSet < soundSetCount, "Failed to select next sound, either none was selected or the selected sound was invalid.");
337-
}
338-
return true;
339-
}
340-
341182
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
342183

343184
FMOD_RESULT SoundContainer::UpdateSoundProperties() {
344185
FMOD_RESULT result = FMOD_OK;
345186

346-
for (std::vector<SoundData> &soundSet : m_SoundSets) {
347-
for (SoundData &soundData : soundSet) {
348-
FMOD_MODE soundMode = (m_Loops == 0) ? FMOD_LOOP_OFF : FMOD_LOOP_NORMAL;
349-
if (m_Immobile) {
350-
soundMode |= FMOD_3D_HEADRELATIVE;
351-
m_AttenuationStartDistance = c_SoundMaxAudibleDistance;
352-
} else {
353-
soundMode |= FMOD_3D_INVERSEROLLOFF;
354-
}
355-
356-
result = (result == FMOD_OK) ? soundData.SoundObject->setMode(soundMode) : result;
357-
result = (result == FMOD_OK) ? soundData.SoundObject->setLoopCount(m_Loops) : result;
358-
result = (result == FMOD_OK) ? soundData.SoundObject->set3DMinMaxDistance(soundData.MinimumAudibleDistance + std::max(0.0F, m_AttenuationStartDistance), c_SoundMaxAudibleDistance) : result;
187+
std::vector<SoundSet::SoundData *> flattenedSoundData;
188+
m_TopLevelSoundSet.GetFlattenedSoundData(flattenedSoundData, false);
189+
for (SoundSet::SoundData *soundData : flattenedSoundData) {
190+
FMOD_MODE soundMode = (m_Loops == 0) ? FMOD_LOOP_OFF : FMOD_LOOP_NORMAL;
191+
if (m_Immobile) {
192+
soundMode |= FMOD_3D_HEADRELATIVE;
193+
m_AttenuationStartDistance = c_SoundMaxAudibleDistance;
194+
} else {
195+
soundMode |= FMOD_3D_INVERSEROLLOFF;
359196
}
197+
198+
result = (result == FMOD_OK) ? soundData->SoundObject->setMode(soundMode) : result;
199+
result = (result == FMOD_OK) ? soundData->SoundObject->setLoopCount(m_Loops) : result;
200+
result = (result == FMOD_OK) ? soundData->SoundObject->set3DMinMaxDistance(soundData->MinimumAudibleDistance + std::max(0.0F, m_AttenuationStartDistance), c_SoundMaxAudibleDistance) : result;
360201
}
361202
m_SoundPropertiesUpToDate = result == FMOD_OK;
362203

0 commit comments

Comments
 (0)