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 
30 oamlSfxTrack::oamlSfxTrack(bool _verbose) {
31 	name = "Sfx";
32 	verbose = _verbose;
33 }
34 
35 oamlSfxTrack::~oamlSfxTrack() {
36 	ClearAudios(&sfxAudios);
37 }
38 
39 void oamlSfxTrack::AddAudio(oamlAudio *audio) {
40 	ASSERT(audio != NULL);
41 
42 	sfxAudios.push_back(audio);
43 }
44 
45 oamlAudio* oamlSfxTrack::GetAudio(std::string filename) {
46 	return FindAudio(&sfxAudios, filename);
47 }
48 
49 oamlRC oamlSfxTrack::Play(const char *name, float vol, float pan) {
50 	if (lock > 0) {
51 		// Play function can't be called while Mix is being run
52 		return OAML_ERROR;
53 	}
54 
55 	for (size_t i=0; i<sfxAudios.size(); i++) {
56 		oamlAudio *audio = sfxAudios[i];
57 		if (audio->GetName().compare(name) == 0) {
58 			// We found our match, open and push it to playingAudios
59 			audio->Open();
60 
61 			sfxPlayInfo info = { audio, 0, vol, pan };
62 			playingAudios.push_back(info);
63 			return OAML_OK;
64 		}
65 	}
66 
67 	return OAML_NOT_FOUND;
68 }
69 
70 void oamlSfxTrack::Mix(float *samples, int channels, bool debugClipping) {
71 	if (playingAudios.size() == 0)
72 		return;
73 
74 	// Prevent Play being called while this function is running
75 	lock++;
76 
77 	for (std::vector<sfxPlayInfo>::iterator it=playingAudios.begin(); it!=playingAudios.end(); ++it) {
78 		float buf[8];
79 
80 		// Read samples from our sfx to buf
81 		it->pos = it->audio->ReadSamples(buf, channels, it->pos);
82 
83 		// Apply the desired volume/panning
84 		ApplyVolPanTo(buf, channels, it->vol, it->pan);
85 
86 		// Now finally mix the buf samples into the output samples array
87 		for (int j=0; j<channels; j++) {
88 			samples[j] = SafeAdd(samples[j], buf[j], debugClipping);
89 		}
90 	}
91 
92 	for (std::vector<sfxPlayInfo>::iterator it=playingAudios.begin(); it!=playingAudios.end();) {
93 		// Check if the sfx has finished playing and remove it if so
94 		if (it->audio->HasFinishedTail(it->pos)) {
95 			it = playingAudios.erase(it);
96 		} else {
97 			++it;
98 		}
99 	}
100 
101 	lock--;
102 }
103 
104 bool oamlSfxTrack::IsPlaying() {
105 	return false;
106 }
107 
108 std::string oamlSfxTrack::GetPlayingInfo() {
109 	std::string info = "";
110 
111 	return info;
112 }
113 
114 void oamlSfxTrack::Stop() {
115 }
116 
117 void oamlSfxTrack::ReadInfo(oamlTrackInfo *info) {
118 	oamlTrack::ReadInfo(info);
119 
120 	ReadAudiosInfo(&sfxAudios, info);
121 }
122 
123 void oamlSfxTrack::FreeMemory() {
124 	FreeAudiosMemory(&sfxAudios);
125 }
126 
127 void oamlSfxTrack::GetAudioList(std::vector<std::string>& list) {
128 	FillAudiosList(&sfxAudios, list);
129 }
130 
131