1 //-----------------------------------------------------------------------------
2 // Copyright (c) 2015-2018 Marcelo Fernandez
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining a copy
5 // of this software and associated documentation files (the "Software"), to
6 // deal in the Software without restriction, including without limitation the
7 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 // sell copies of the Software, and to permit persons to whom the Software is
9 // furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20 // IN THE SOFTWARE.
21 //-----------------------------------------------------------------------------
22 
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 
27 #include "oamlCommon.h"
28 
29 
oamlMusicTrack(bool _verbose)30 oamlMusicTrack::oamlMusicTrack(bool _verbose) {
31 	verbose = _verbose;
32 	name = "Track";
33 	playing = false;
34 	filesSamples = 0;
35 
36 	playCondSamples = 0;
37 	playCondAudio = -1;
38 
39 	fadeIn = 0;
40 	fadeOut = 0;
41 	xfadeIn = 0;
42 	xfadeOut = 0;
43 	playingOrder = 0;
44 	maxPlayOrder = 0;
45 
46 	tailPos = 0;
47 
48 	curAudio = -1;
49 	tailAudio = -1;
50 	fadeAudio = -1;
51 }
52 
~oamlMusicTrack()53 oamlMusicTrack::~oamlMusicTrack() {
54 	ClearAudios(&introAudios);
55 	ClearAudios(&loopAudios);
56 	ClearAudios(&randAudios);
57 	ClearAudios(&condAudios);
58 }
59 
GetAudioByTypeId(int type,int id)60 oamlAudio *oamlMusicTrack::GetAudioByTypeId(int type, int id) {
61 	switch (type) {
62 		case 0:
63 			if (id >= 0 && (size_t)id < introAudios.size()) {
64 				return introAudios[id];
65 			}
66 			break;
67 		case 1:
68 			if (id >= 0 && (size_t)id < loopAudios.size()) {
69 				return loopAudios[id];
70 			}
71 			break;
72 		case 2:
73 			if (id >= 0 && (size_t)id < randAudios.size()) {
74 				return randAudios[id];
75 			}
76 			break;
77 		case 3:
78 			if (id >= 0 && (size_t)id < condAudios.size()) {
79 				return condAudios[id];
80 			}
81 			break;
82 	}
83 
84 	return NULL;
85 }
86 
GetCurAudio()87 oamlAudio *oamlMusicTrack::GetCurAudio() {
88 	return GetAudioByTypeId(curAudio >> 24, curAudio & 0xFFFFFF);
89 }
90 
GetFadeAudio()91 oamlAudio *oamlMusicTrack::GetFadeAudio() {
92 	return GetAudioByTypeId(fadeAudio >> 24, fadeAudio & 0xFFFFFF);
93 }
94 
GetTailAudio()95 oamlAudio *oamlMusicTrack::GetTailAudio() {
96 	return GetAudioByTypeId(tailAudio >> 24, tailAudio & 0xFFFFFF);
97 }
98 
SetCurAudio(int type,int id)99 void oamlMusicTrack::SetCurAudio(int type, int id) {
100 	curAudio = (type << 24) | (id & 0xFFFFFF);
101 }
102 
AddAudio(oamlAudio * audio)103 void oamlMusicTrack::AddAudio(oamlAudio *audio) {
104 	ASSERT(audio != NULL);
105 
106 	if (GetAudio(audio->GetName())) {
107 		fprintf(stderr, "oaml: Warning, duplicated audio name: %s\n", audio->GetName().c_str());
108 	}
109 
110 	if (audio->GetType() == 1) {
111 		introAudios.push_back(audio);
112 	} else if (audio->GetType() == 4) {
113 		condAudios.push_back(audio);
114 	} else if (audio->GetRandomChance() > 0) {
115 		randAudios.push_back(audio);
116 	} else {
117 		loopAudios.push_back(audio);
118 	}
119 }
120 
GetAudio(std::string filename)121 oamlAudio* oamlMusicTrack::GetAudio(std::string filename) {
122 	oamlAudio *audio;
123 
124 	audio = FindAudio(&introAudios, filename);
125 	if (audio) return audio;
126 	audio = FindAudio(&loopAudios, filename);
127 	if (audio) return audio;
128 	audio = FindAudio(&randAudios, filename);
129 	if (audio) return audio;
130 	audio = FindAudio(&condAudios, filename);
131 	if (audio) return audio;
132 
133 	return NULL;
134 }
135 
RemoveAudio(std::string filename)136 oamlRC oamlMusicTrack::RemoveAudio(std::string filename) {
137 	if (FindAudioAndRemove(&introAudios, filename) == OAML_OK)
138 		return OAML_OK;
139 	if (FindAudioAndRemove(&loopAudios, filename) == OAML_OK)
140 		return OAML_OK;
141 	if (FindAudioAndRemove(&randAudios, filename) == OAML_OK)
142 		return OAML_OK;
143 	if (FindAudioAndRemove(&condAudios, filename) == OAML_OK)
144 		return OAML_OK;
145 	return OAML_NOT_FOUND;
146 }
147 
SetCondition(int id,int value)148 void oamlMusicTrack::SetCondition(int id, int value) {
149 	bool stopCond = false;
150 	bool playCond = false;
151 
152 	if (playCondSamples > 0)
153 		return;
154 
155 	if (id == OAML_CONDID_MAIN_LOOP) {
156 		for (size_t i=0; i<loopAudios.size(); i++) {
157 			oamlAudio *audio = loopAudios[i];
158 			if (audio->HasCondition(id)) {
159 				audio->SetPickable(audio->TestCondition(id, value));
160 			}
161 		}
162 
163 		if (playing == true && curAudio == -1) {
164 			// If track is currently playing but no audio is actually playing this to play one
165 			PlayNext();
166 		}
167 		return;
168 	}
169 
170 	oamlAudio *pcurAudio = GetCurAudio();
171 	for (size_t i=0; i<condAudios.size(); i++) {
172 		oamlAudio *audio = condAudios[i];
173 		if (audio->GetCondId() != id)
174 			continue;
175 
176 		if (pcurAudio != audio) {
177 			// Audio isn't being played right now
178 			if (audio->TestCondition(id, value) == true) {
179 				// Condition is true, so let's play the audio
180 				if (pcurAudio == NULL || pcurAudio->GetMinMovementBars() == 0) {
181 					PlayCond((3 << 24) | i);
182 				} else {
183 					PlayCondWithMovement((3 << 24) | i);
184 				}
185 
186 				playCond = true;
187 			}
188 		} else {
189 			// Audio is being played right now
190 			if (audio->TestCondition(id, value) == false) {
191 				stopCond = true;
192 			}
193 		}
194 	}
195 
196 	if (stopCond == true && playCond == false) {
197 		// No condition is being played now, let's go back to the main loop
198 		if (pcurAudio == NULL || pcurAudio->GetMinMovementBars() == 0) {
199 			PlayCond(-1);
200 		} else {
201 			PlayCondWithMovement(-1);
202 		}
203 	}
204 }
205 
PlayCondWithMovement(int audio)206 void oamlMusicTrack::PlayCondWithMovement(int audio) {
207 	oamlAudio *pcurAudio = GetCurAudio();
208 	if (pcurAudio == NULL)
209 		return;
210 
211 	playCondAudio = audio;
212 	playCondSamples = pcurAudio->GetBarsSamples(pcurAudio->GetMinMovementBars());
213 	if (playCondSamples == 0)
214 		return;
215 
216 	playCondSamples = (playCondSamples + pcurAudio->GetBarsSamples(pcurAudio->GetSamplesCount() / playCondSamples) * pcurAudio->GetMinMovementBars()) - pcurAudio->GetSamplesCount();
217 //	printf("%s %d\n", __FUNCTION__, playCondSamples);
218 }
219 
PlayCond(int audio)220 void oamlMusicTrack::PlayCond(int audio) {
221 	fadeAudio = curAudio;
222 	curAudio = audio;
223 
224 	oamlAudio *pcurAudio = GetCurAudio();
225 	if (pcurAudio == NULL) {
226 		PlayNext();
227 	} else {
228 		pcurAudio->Open();
229 		XFadePlay();
230 	}
231 }
232 
Play(int mainCondValue)233 oamlRC oamlMusicTrack::Play(int mainCondValue) {
234 	int doFade = 0;
235 
236 	if (lock > 0) {
237 		return OAML_ERROR;
238 	}
239 
240 	if (verbose) __oamlLog("%s %s\n", __FUNCTION__, GetNameStr());
241 	fadeAudio = -1;
242 
243 	if (curAudio == -1) {
244 		doFade = 1;
245 	}
246 
247 	printf("mainCondValue=%d\n", mainCondValue);
248 	SetCondition(OAML_CONDID_MAIN_LOOP, mainCondValue);
249 
250 	playingOrder = 0;
251 	maxPlayOrder = 0;
252 
253 	// Check if we need to use the playOrder audio property
254 	size_t count = 0;
255 	for (std::vector<oamlAudio*>::iterator it=loopAudios.begin(); it<loopAudios.end(); ++it) {
256 		oamlAudio *audio = *it;
257 		int playOrder = audio->GetPlayOrder();
258 		if (playOrder != 0) {
259 			if (playOrder > maxPlayOrder) {
260 				maxPlayOrder = playOrder;
261 			}
262 			count++;
263 		}
264 	}
265 
266 	if (count == loopAudios.size()) {
267 		// All of our loop audios have the playOrder property assigned, enable its use
268 		playingOrder = 1;
269 	}
270 
271 	if (introAudios.size() >= 1) {
272 		if (introAudios.size() == 1) {
273 			SetCurAudio(0, 0);
274 		} else {
275 			int i = Random(0, introAudios.size()-1);
276 			SetCurAudio(0, i);
277 		}
278 
279 		oamlAudio *audio = GetCurAudio();
280 		if (audio) {
281 			audio->Open();
282 		}
283 	} else {
284 		PlayNext();
285 	}
286 
287 	oamlAudio *pcurAudio = GetCurAudio();
288 	if (doFade && pcurAudio != NULL) {
289 		// First check the fade in property for the audio and then the track fade in property
290 		if (pcurAudio->GetFadeIn()) {
291 			pcurAudio->DoFadeIn(pcurAudio->GetFadeIn());
292 		} else if (fadeIn) {
293 			pcurAudio->DoFadeIn(fadeIn);
294 		}
295 	}
296 
297 	playing = true;
298 
299 	return OAML_OK;
300 }
301 
PickNextAudio()302 int oamlMusicTrack::PickNextAudio() {
303 	if (verbose) __oamlLog("%s %s\n", __FUNCTION__, GetNameStr());
304 
305 	oamlAudio *pcurAudio = GetCurAudio();
306 	if (randAudios.size() > 0 && (pcurAudio == NULL || pcurAudio->GetRandomChance() == 0)) {
307 		for (size_t i=0; i<randAudios.size(); i++) {
308 			int chance = randAudios[i]->GetRandomChance();
309 			if (Random(0, 100) > chance) {
310 				continue;
311 			} else {
312 				return (3 << 24) | (i & 0xFFFFFF);
313 			}
314 		}
315 	}
316 
317 	if (loopAudios.size() == 1) {
318 		return (1 << 24) | (0 & 0xFFFFFF);
319 	} else if (loopAudios.size() >= 2) {
320 		std::vector<int> list;
321 
322 		for (size_t i=0; i<loopAudios.size(); i++) {
323 			oamlAudio *audio = loopAudios[i];
324 			if (audio->IsPickable()) {
325 				if (playingOrder != 0 && audio->GetPlayOrder() != playingOrder) {
326 					continue;
327 				}
328 				list.push_back((1 << 24) | (i & 0xFFFFFF));
329 			}
330 		}
331 
332 		if (playingOrder != 0) {
333 			playingOrder++;
334 			if (playingOrder > maxPlayOrder) {
335 				playingOrder = 1;
336 			}
337 		}
338 
339 		if (list.size() == 0) {
340 			return -1;
341 		} else if (list.size() == 1) {
342 			return list[0];
343 		} else {
344 			int r = Random(0, list.size()-1);
345 			while (curAudio == list[r]) {
346 				r = Random(0, list.size()-1);
347 			}
348 
349 			return list[r];
350 		}
351 	}
352 
353 	return -1;
354 }
355 
PlayNext()356 void oamlMusicTrack::PlayNext() {
357 	if (verbose) __oamlLog("%s %s\n", __FUNCTION__, GetNameStr());
358 
359 	oamlAudio *pcurAudio = GetCurAudio();
360 	if (pcurAudio) {
361 		if (pcurAudio->GetType() == 4) {
362 			tailAudio = curAudio;
363 			tailPos = pcurAudio->GetSamplesCount();
364 
365 			pcurAudio->Open();
366 			return;
367 		}
368 	}
369 
370 	if (fadeAudio == -1)
371 		fadeAudio = curAudio;
372 
373 	curAudio = PickNextAudio();
374 	pcurAudio = GetCurAudio();
375 	if (pcurAudio)
376 		pcurAudio->Open();
377 
378 	if (fadeAudio != curAudio) {
379 		XFadePlay();
380 	} else {
381 		fadeAudio = -1;
382 	}
383 }
384 
XFadePlay()385 void oamlMusicTrack::XFadePlay() {
386 	oamlAudio *pcurAudio = GetCurAudio();
387 	oamlAudio *pfadeAudio = GetFadeAudio();
388 	if (pcurAudio) {
389 		// First check the fade in property for the audio and then the track fade in property
390 		if (pcurAudio->GetXFadeIn()) {
391 			pcurAudio->DoFadeIn(pcurAudio->GetXFadeIn());
392 		} else if (pfadeAudio && pfadeAudio->GetXFadeIn()) {
393 			pcurAudio->DoFadeIn(pfadeAudio->GetXFadeIn());
394 		} else if (xfadeIn) {
395 			pcurAudio->DoFadeIn(xfadeIn);
396 		}
397 	}
398 
399 	if (pfadeAudio) {
400 		if (pcurAudio && pcurAudio->GetXFadeOut()) {
401 			pfadeAudio->DoFadeOut(pcurAudio->GetXFadeOut());
402 		} else if (pfadeAudio && pfadeAudio->GetXFadeOut()) {
403 			pfadeAudio->DoFadeOut(pfadeAudio->GetXFadeOut());
404 		} else if (xfadeOut) {
405 			pfadeAudio->DoFadeOut(xfadeOut);
406 		} else {
407 			fadeAudio = -1;
408 		}
409 	}
410 }
411 
Mix(float * samples,int channels,bool debugClipping)412 void oamlMusicTrack::Mix(float *samples, int channels, bool debugClipping) {
413 	if (curAudio == -1 && tailAudio == -1 && fadeAudio == -1)
414 		return;
415 
416 	lock++;
417 
418 	oamlAudio *pcurAudio = GetCurAudio();
419 	if (pcurAudio) {
420 		MixAudio(pcurAudio, samples, channels, debugClipping);
421 	}
422 
423 	oamlAudio *ptailAudio = GetTailAudio();
424 	if (ptailAudio) {
425 		tailPos = MixAudio(ptailAudio, samples, channels, debugClipping, tailPos);
426 		if (ptailAudio->HasFinishedTail(tailPos))
427 			tailAudio = -1;
428 	}
429 
430 	oamlAudio *pfadeAudio = GetFadeAudio();
431 	if (pfadeAudio) {
432 		MixAudio(pfadeAudio, samples, channels, debugClipping);
433 	}
434 
435 	if (pcurAudio && pcurAudio->HasFinished()) {
436 		tailAudio = curAudio;
437 		tailPos = pcurAudio->GetSamplesCount();
438 
439 		PlayNext();
440 	}
441 
442 	if (pfadeAudio && pfadeAudio->HasFinished()) {
443 		fadeAudio = -1;
444 	}
445 
446 	if (playCondSamples > 0) {
447 		playCondSamples--;
448 		if (playCondSamples == 0) {
449 			PlayCond(playCondAudio);
450 		}
451 	}
452 
453 	if (curAudio == -1 && tailAudio == -1 && fadeAudio == -1) {
454 		FreeMemory();
455 	}
456 
457 	lock--;
458 }
459 
IsPlaying()460 bool oamlMusicTrack::IsPlaying() {
461 	return playing;
462 }
463 
GetPlayingInfo()464 std::string oamlMusicTrack::GetPlayingInfo() {
465 	char str[1024];
466 	std::string info = "";
467 
468 	if (curAudio == -1 && tailAudio == -1 && fadeAudio == -1) {
469 		if (playing == true) {
470 			return "Playing track but no available audio, missing condition?";
471 		}
472 
473 		return info;
474 	}
475 
476 	info+= GetName() + ":";
477 
478 	oamlAudio *audio = GetCurAudio();
479 	if (audio) {
480 		snprintf(str, 1024, " curAudio = %s (pos=%d)", audio->GetName().c_str(), audio->GetSamplesCount());
481 		info+= str;
482 	}
483 
484 	audio = GetTailAudio();
485 	if (audio) {
486 		snprintf(str, 1024, " tailAudio = %s (pos=%d)", audio->GetName().c_str(), audio->GetSamplesCount());
487 		info+= str;
488 	}
489 
490 	audio = GetFadeAudio();
491 	if (audio) {
492 		snprintf(str, 1024, " fadeAudio = %s (pos=%d)", audio->GetName().c_str(), audio->GetSamplesCount());
493 		info+= str;
494 	}
495 
496 	return info;
497 }
498 
Stop()499 void oamlMusicTrack::Stop() {
500 	if (curAudio != -1) {
501 		if (fadeOut) {
502 			fadeAudio = curAudio;
503 			oamlAudio *audio = GetFadeAudio();
504 			if (audio) {
505 				audio->DoFadeOut(fadeOut);
506 			}
507 		}
508 		curAudio = -1;
509 	}
510 
511 	tailAudio = -1;
512 	playing = false;
513 
514 	if (curAudio == -1 && tailAudio == -1 && fadeAudio == -1) {
515 		FreeMemory();
516 	}
517 }
518 
Load()519 oamlRC oamlMusicTrack::Load() {
520 	for (std::vector<oamlAudio*>::iterator it=loopAudios.begin(); it<loopAudios.end(); ++it) {
521 		oamlAudio *audio = *it;
522 		oamlRC ret = audio->Load();
523 		if (ret != OAML_OK) return ret;
524 	}
525 
526 	return OAML_OK;
527 }
528 
LoadProgress()529 float oamlMusicTrack::LoadProgress() {
530 	int samples;
531 
532 	if (filesSamples == 0) {
533 		// Calculate the total size of the audio loops to read
534 
535 		samples = GetFilesSamplesFor(&introAudios);
536 		if (samples == -1)
537 			return -1.f;
538 		filesSamples+= samples;
539 
540 		samples = GetFilesSamplesFor(&loopAudios);
541 		if (samples == -1)
542 			return -1.f;
543 		filesSamples+= samples;
544 
545 		samples = GetFilesSamplesFor(&randAudios);
546 		if (samples == -1)
547 			return -1.f;
548 		filesSamples+= samples;
549 
550 		samples = GetFilesSamplesFor(&condAudios);
551 		if (samples == -1)
552 			return -1.f;
553 		filesSamples+= samples;
554 	}
555 
556 	if (filesSamples == 0) {
557 		return -1.f;
558 	}
559 
560 	int totalSamplesRead = 0;
561 
562 	samples = LoadProgressFor(&introAudios);
563 	if (samples == -1) {
564 		return -1.f;
565 	}
566 	totalSamplesRead+= samples;
567 
568 	samples = LoadProgressFor(&loopAudios);
569 	if (samples == -1) {
570 		return -1.f;
571 	}
572 	totalSamplesRead+= samples;
573 
574 	samples = LoadProgressFor(&randAudios);
575 	if (samples == -1) {
576 		return -1.f;
577 	}
578 	totalSamplesRead+= samples;
579 
580 	samples = LoadProgressFor(&condAudios);
581 	if (samples == -1) {
582 		return -1.f;
583 	}
584 	totalSamplesRead+= samples;
585 
586 	return float(double(totalSamplesRead) / double(filesSamples));
587 }
588 
ReadInfo(oamlTrackInfo * info)589 void oamlMusicTrack::ReadInfo(oamlTrackInfo *info) {
590 	oamlTrack::ReadInfo(info);
591 
592 	ReadAudiosInfo(&introAudios, info);
593 	ReadAudiosInfo(&loopAudios, info);
594 	ReadAudiosInfo(&randAudios, info);
595 	ReadAudiosInfo(&condAudios, info);
596 }
597 
SaveAudioState(tinyxml2::XMLDocument & doc,tinyxml2::XMLElement * node,const char * nodeName,std::vector<oamlAudio * > * audios)598 void oamlMusicTrack::SaveAudioState(tinyxml2::XMLDocument &doc, tinyxml2::XMLElement *node, const char *nodeName, std::vector<oamlAudio*> *audios) {
599 	for (std::vector<oamlAudio*>::iterator it=audios->begin(); it<audios->end(); ++it) {
600 		oamlAudio *audio = *it;
601 
602 		tinyxml2::XMLElement *elem = doc.NewElement(nodeName);
603 		audio->SaveState(elem);
604 		node->InsertEndChild(elem);
605 	}
606 }
607 
SaveState(tinyxml2::XMLDocument & doc,tinyxml2::XMLElement * node)608 void oamlMusicTrack::SaveState(tinyxml2::XMLDocument &doc, tinyxml2::XMLElement *node) {
609 	node->SetAttribute("name", GetNameStr());
610 	node->SetAttribute("playing", playing);
611 	node->SetAttribute("playingOrder", playingOrder);
612 	node->SetAttribute("tailPos", tailPos);
613 	node->SetAttribute("curAudio", curAudio);
614 	node->SetAttribute("fadeAudio", fadeAudio);
615 	node->SetAttribute("tailAudio", tailAudio);
616 	node->SetAttribute("playCondAudio", playCondAudio);
617 	node->SetAttribute("playCondSamples", playCondSamples);
618 
619 	if (introAudios.size() > 0) {
620 		SaveAudioState(doc, node, "introAudio", &introAudios);
621 	}
622 	if (loopAudios.size() > 0) {
623 		SaveAudioState(doc, node, "loopAudio", &loopAudios);
624 	}
625 	if (randAudios.size() > 0) {
626 		SaveAudioState(doc, node, "randAudio", &randAudios);
627 	}
628 	if (condAudios.size() > 0) {
629 		SaveAudioState(doc, node, "condAudio", &condAudios);
630 	}
631 }
632 
LoadAudioState(tinyxml2::XMLElement * node,std::vector<oamlAudio * > * audios)633 void oamlMusicTrack::LoadAudioState(tinyxml2::XMLElement *node, std::vector<oamlAudio*> *audios) {
634 	for (std::vector<oamlAudio*>::iterator it=audios->begin(); it<audios->end(); ++it) {
635 		oamlAudio *audio = *it;
636 		if (strcmp(node->Attribute("name"), audio->GetName().c_str()) == 0) {
637 			audio->LoadState(node);
638 			break;
639 		}
640 	}
641 }
642 
LoadState(tinyxml2::XMLElement * node)643 void oamlMusicTrack::LoadState(tinyxml2::XMLElement *node) {
644 	const char *attr = node->Attribute("playing");
645 	if (attr && strcmp(attr, "true") == 0) {
646 		playing = true;
647 	} else {
648 		playing = false;
649 	}
650 
651 	playingOrder = node->IntAttribute("playingOrder");
652 	tailPos = node->IntAttribute("tailPos");
653 	curAudio = node->IntAttribute("curAudio");
654 	fadeAudio = node->IntAttribute("fadeAudio");
655 	tailAudio = node->IntAttribute("tailAudio");
656 	playCondAudio = node->IntAttribute("playCondAudio");
657 	playCondSamples = node->IntAttribute("playCondSamples");
658 
659 	tinyxml2::XMLElement *el = node->FirstChildElement();
660 	while (el != NULL) {
661 		if (strcmp(el->Name(), "introAudio") == 0) {
662 			LoadAudioState(el, &introAudios);
663 		} else if (strcmp(el->Name(), "loopAudio") == 0) {
664 			LoadAudioState(el, &loopAudios);
665 		} else if (strcmp(el->Name(), "randAudio") == 0) {
666 			LoadAudioState(el, &randAudios);
667 		} else if (strcmp(el->Name(), "condAudio") == 0) {
668 			LoadAudioState(el, &condAudios);
669 		}
670 
671 		el = el->NextSiblingElement();
672 	}
673 }
674 
FreeMemory()675 void oamlMusicTrack::FreeMemory() {
676 	FreeAudiosMemory(&introAudios);
677 	FreeAudiosMemory(&loopAudios);
678 	FreeAudiosMemory(&randAudios);
679 	FreeAudiosMemory(&condAudios);
680 
681 	filesSamples = 0;
682 }
683 
GetAudioList(std::vector<std::string> & list)684 void oamlMusicTrack::GetAudioList(std::vector<std::string>& list) {
685 	FillAudiosList(&introAudios, list);
686 	FillAudiosList(&loopAudios, list);
687 	FillAudiosList(&randAudios, list);
688 	FillAudiosList(&condAudios, list);
689 }
690 
_SetLayerGain(std::vector<oamlAudio * > * audios,std::string layer,float gain)691 void oamlMusicTrack::_SetLayerGain(std::vector<oamlAudio*> *audios, std::string layer, float gain) {
692 	for (std::vector<oamlAudio*>::iterator it=audios->begin(); it<audios->end(); ++it) {
693 		oamlAudio *audio = *it;
694 		audio->SetLayerGain(layer, gain);
695 	}
696 }
697 
SetLayerGain(std::string layer,float gain)698 void oamlMusicTrack::SetLayerGain(std::string layer, float gain) {
699 	_SetLayerGain(&introAudios, layer, gain);
700 	_SetLayerGain(&loopAudios, layer, gain);
701 	_SetLayerGain(&randAudios, layer, gain);
702 	_SetLayerGain(&condAudios, layer, gain);
703 }
704