added apex audio system
[gbajam21] / libs / aas / AAS_SFX.c
1 /* Copyright (c) 2003-2021 James Daniels */
2 /* Distributed under the MIT License */
3 /* license terms: see LICENSE file in root or http://opensource.org/licenses/MIT */
4
5 #include "AAS_Shared.h"
6
7 int AAS_SFX_GetNumChannels()
8 {
9         if(AAS_initialised) {
10                 if(AAS_volscale == 9)
11                         return 16 - AAS_MOD_GetNumChannels();
12                 else if(AAS_volscale == 8)
13                         return 8 - AAS_MOD_GetNumChannels();
14                 else
15                         return 4 - AAS_MOD_GetNumChannels();
16         } else {
17                 return 0;
18         }
19 }
20
21 struct AAS_Channel *AAS_SFX_GetChannel(int channel)
22 {
23         if(AAS_volscale == 9)
24                 return &AAS_channels[AAS_chan_rearrange[15 - channel]];
25         else if(AAS_volscale == 8)
26                 return &AAS_channels[AAS_chan_rearrange[7 - channel]];
27         else
28                 return &AAS_channels[AAS_chan_rearrange[3 - channel]];
29 }
30
31 int AAS_SFX_GetOutput(int channel)
32 {
33         if(AAS_volscale == 9)
34                 return AAS_chan_rearrange[15 - channel] >> 3;
35         else if(AAS_volscale == 8)
36                 return AAS_chan_rearrange[7 - channel] >> 3;
37         else
38                 return AAS_chan_rearrange[3 - channel] >> 3;
39 }
40
41 AAS_BOOL AAS_SFX_ChannelExists(int channel)
42 {
43         if((channel >= 0) && (channel < AAS_SFX_GetNumChannels())) {
44                 return AAS_TRUE;
45         } else {
46                 return AAS_FALSE;
47         }
48 }
49
50 int AAS_SFX_Play(int channel, int sample_volume, int sample_frequency, const AAS_s8 * sample_start,
51                  const AAS_s8 * sample_end, const AAS_s8 * sample_restart)
52 {
53         if(AAS_initialised) {
54                 if(AAS_SFX_ChannelExists(channel)) {
55                         if((sample_frequency >= 1) && (sample_frequency <= 65535)) {
56                                 if((sample_volume >= 0) && (sample_volume <= 64)) {
57                                         if(sample_start && (sample_end > sample_start) &&
58                                            (sample_restart < sample_end)) {
59                                                 struct AAS_Channel *ch;
60
61                                                 ch = AAS_SFX_GetChannel(channel);
62                                                 ch->active = AAS_FALSE;
63                                                 ch->volume = (sample_volume << 8) >> AAS_volscale;
64                                                 ch->frequency = sample_frequency;
65                                                 ch->delta = AAS_Min(4095, ((sample_frequency * AAS_mix_scale) + 32768) >> 16);
66                                                 ch->pos = sample_start;
67                                                 ch->pos_fraction = 0;
68                                                 if(sample_restart)
69                                                         ch->loop_length = sample_end - sample_restart;
70                                                 else
71                                                         ch->loop_length = 0;
72                                                 ch->end = sample_end;
73                                                 ch->active = AAS_TRUE;
74
75                                                 AAS_changed[AAS_SFX_GetOutput(channel)] = AAS_TRUE;
76
77                                                 return AAS_OK;
78                                         } else {
79                                                 return AAS_ERROR_INVALID_SAMPLE_ADDRESS;
80                                         }
81                                 } else {
82                                         return AAS_ERROR_VOLUME_OUT_OF_RANGE;
83                                 }
84                         } else {
85                                 return AAS_ERROR_FREQUENCY_OUT_OF_RANGE;
86                         }
87                 } else {
88                         return AAS_ERROR_CHANNEL_NOT_AVAILABLE;
89                 }
90         } else {
91                 return AAS_ERROR_CALL_SET_CONFIG_FIRST;
92         }
93 }
94
95 AAS_BOOL AAS_SFX_IsActive(int channel)
96 {
97         if(AAS_SFX_ChannelExists(channel)) {
98                 return AAS_SFX_GetChannel(channel)->active;
99         } else {
100                 return AAS_FALSE;
101         }
102 }
103
104 int AAS_SFX_EndLoop(int channel)
105 {
106         if(AAS_initialised) {
107                 if(AAS_SFX_ChannelExists(channel)) {
108                         AAS_SFX_GetChannel(channel)->loop_length = 0;
109
110                         return AAS_OK;
111                 } else {
112                         return AAS_ERROR_CHANNEL_NOT_AVAILABLE;
113                 }
114         } else {
115                 return AAS_ERROR_CALL_SET_CONFIG_FIRST;
116         }
117 }
118
119 int AAS_SFX_SetFrequency(int channel, int sample_frequency)
120 {
121         if(AAS_initialised) {
122                 if(AAS_SFX_ChannelExists(channel)) {
123                         if((sample_frequency >= 1) && (sample_frequency <= 65535)) {
124                                 struct AAS_Channel *ch;
125
126                                 ch = AAS_SFX_GetChannel(channel);
127                                 ch->frequency = sample_frequency;
128                                 ch->delta = AAS_Min(4095, ((sample_frequency * AAS_mix_scale) + 32768) >> 16);
129
130                                 AAS_changed[AAS_SFX_GetOutput(channel)] = AAS_TRUE;
131
132                                 return AAS_OK;
133                         } else {
134                                 return AAS_ERROR_FREQUENCY_OUT_OF_RANGE;
135                         }
136                 } else {
137                         return AAS_ERROR_CHANNEL_NOT_AVAILABLE;
138                 }
139         } else {
140                 return AAS_ERROR_CALL_SET_CONFIG_FIRST;
141         }
142 }
143
144 int AAS_SFX_SetVolume(int channel, int sample_volume)
145 {
146         if(AAS_initialised) {
147                 if(AAS_SFX_ChannelExists(channel)) {
148                         if((sample_volume >= 0) && (sample_volume <= 64)) {
149                                 AAS_SFX_GetChannel(channel)->volume = (sample_volume << 8) >> AAS_volscale;
150
151                                 AAS_changed[AAS_SFX_GetOutput(channel)] = AAS_TRUE;
152
153                                 return AAS_OK;
154                         } else {
155                                 return AAS_ERROR_VOLUME_OUT_OF_RANGE;
156                         }
157                 } else {
158                         return AAS_ERROR_CHANNEL_NOT_AVAILABLE;
159                 }
160         } else {
161                 return AAS_ERROR_CALL_SET_CONFIG_FIRST;
162         }
163 }
164
165 int AAS_SFX_Stop(int channel)
166 {
167         if(AAS_initialised) {
168                 if(AAS_SFX_ChannelExists(channel)) {
169                         AAS_SFX_GetChannel(channel)->active = AAS_FALSE;
170
171                         AAS_changed[AAS_SFX_GetOutput(channel)] = AAS_TRUE;
172
173                         return AAS_OK;
174                 } else {
175                         return AAS_ERROR_CHANNEL_NOT_AVAILABLE;
176                 }
177         } else {
178                 return AAS_ERROR_CALL_SET_CONFIG_FIRST;
179         }
180 }
181
182 int AAS_SFX_Resume(int channel)
183 {
184         if(AAS_initialised) {
185                 if(AAS_SFX_ChannelExists(channel)) {
186                         struct AAS_Channel *ch;
187
188                         ch = AAS_SFX_GetChannel(channel);
189
190                         if(!ch->active) {
191                                 if(ch->loop_length) {
192                                         ch->active = AAS_TRUE;
193
194                                         AAS_changed[AAS_SFX_GetOutput(channel)] = AAS_TRUE;
195
196                                         return AAS_OK;
197                                 } else {
198                                         if(ch->pos < ((ch->end - (ch->delta >> 6)) - 1)) {
199                                                 ch->active = AAS_TRUE;
200
201                                                 AAS_changed[AAS_SFX_GetOutput(channel)] = AAS_TRUE;
202
203                                                 return AAS_OK;
204                                         } else {
205                                                 return AAS_ERROR_CHANNEL_UNRESUMEABLE;
206                                         }
207                                 }
208                         } else {
209                                 return AAS_ERROR_CHANNEL_ACTIVE;
210                         }
211                 } else {
212                         return AAS_ERROR_CHANNEL_NOT_AVAILABLE;
213                 }
214         } else {
215                 return AAS_ERROR_CALL_SET_CONFIG_FIRST;
216         }
217 }