3
3
#include "s_buffers.h"
4
4
#include "pcm.h"
5
5
6
- #define S_PAINT_CHUNK 128 // the number of samples to paint in a single call of S_Src_Paint
6
+ #define S_PAINT_CHUNK CHBUF_SIZE // the number of samples to paint in a single call of S_Src_Paint
7
7
8
8
sfx_source_t s_sources [ S_MAX_SOURCES ] = { { 0 } };
9
9
10
10
void S_Src_Init (sfx_source_t * src )
11
11
{
12
12
src -> buf = NULL ;
13
13
src -> num_channels = 0 ;
14
- src -> channels [0 ] = src -> channels [1 ] = 0 ;
15
14
src -> rem = 0 ;
16
15
src -> eof = 0 ;
16
+ src -> backbuf = -1 ;
17
17
}
18
18
19
19
void S_Src_Stop (sfx_source_t * src )
20
20
{
21
21
int i ;
22
+
23
+ if (!src -> buf ) {
24
+ return ;
25
+ }
26
+
22
27
for (i = 0 ; i < src -> num_channels ; i ++ ) {
23
28
S_Chan_Clear ( & s_channels [ src -> channels [ i ] ] );
24
29
}
30
+
25
31
src -> buf = NULL ;
26
32
src -> freq = 0 ;
27
33
src -> painted = 0 ;
28
34
src -> num_channels = 0 ;
29
35
src -> rem = 0 ;
30
36
src -> eof = 1 ;
37
+ src -> backbuf = -1 ; // force data refresh on the next update
38
+
39
+ S_UpdateSourcesStatus ();
31
40
}
32
41
33
42
void S_Src_Rewind (sfx_source_t * src )
@@ -125,7 +134,7 @@ uint16_t S_Src_LoadSamples(sfx_source_t *src, uint16_t *pos, uint16_t len)
125
134
return painted ;
126
135
}
127
136
128
- int S_Src_Paint (sfx_source_t * src )
137
+ void S_Src_Paint (sfx_source_t * src )
129
138
{
130
139
int i ;
131
140
uint16_t painted , rem ;
@@ -135,21 +144,23 @@ int S_Src_Paint(sfx_source_t *src)
135
144
// stream data
136
145
if (!src -> buf || !src -> num_channels ) {
137
146
S_Src_Stop (src );
138
- return 1 ;
147
+ return ;
139
148
}
140
149
141
150
// use position of the primary channel to determine backbuffer id
142
151
prichan = & s_channels [ src -> channels [ 0 ] ];
143
152
144
153
int8_t backbuf = S_Chan_BackBuffer ( prichan );
145
154
if (src -> backbuf != backbuf ) {
146
- if (src -> eof ) {
155
+ if (src -> eof > 1 ) {
147
156
S_Src_Stop (src );
148
- return 1 ;
157
+ return ;
149
158
}
150
159
151
160
src -> backbuf = backbuf ;
152
161
src -> rem = CHBUF_SIZE ;
162
+ if (src -> eof )
163
+ src -> eof ++ ;
153
164
154
165
for (i = 0 ; i < src -> num_channels ; i ++ ) {
155
166
uint16_t startblock ;
@@ -161,7 +172,7 @@ int S_Src_Paint(sfx_source_t *src)
161
172
}
162
173
else {
163
174
if (src -> rem == 0 ) {
164
- return 1 ;
175
+ return ;
165
176
}
166
177
}
167
178
@@ -206,43 +217,44 @@ int S_Src_Paint(sfx_source_t *src)
206
217
src -> rem = 0 ;
207
218
}
208
219
209
- if (src -> rem == 0 ) {
210
- // copy channel parameters from source and update
211
- for (i = 0 ; i < src -> num_channels ; i ++ ) {
212
- chan = & s_channels [ src -> channels [ i ] ];
213
- chan -> freq = src -> freq ;
214
- chan -> env = src -> env ;
215
- chan -> pan = src -> pan [i ];
216
- S_Chan_Update (chan );
217
- }
218
-
219
- return 1 ;
220
+ if (src -> rem != 0 ) {
221
+ return ;
220
222
}
221
223
222
- return 0 ;
224
+ // copy channel parameters from source and update
225
+ for (i = 0 ; i < src -> num_channels ; i ++ ) {
226
+ chan = & s_channels [ src -> channels [ i ] ];
227
+ chan -> freq = src -> freq ;
228
+ chan -> env = src -> env ;
229
+ chan -> pan = src -> pan [i ];
230
+ S_Chan_Update (chan );
231
+ }
223
232
}
224
233
225
234
void S_Src_Play (sfx_source_t * src , sfx_buffer_t * buf , uint16_t freq , uint8_t pan , uint8_t vol , uint8_t autoloop )
226
235
{
227
236
int i ;
228
237
sfx_channel_t * chan ;
229
238
239
+ if (src -> num_channels > 0 && src -> num_channels != buf -> num_channels ) {
240
+ // we need to re-allocate channels for this source
241
+ S_Src_Stop (src );
242
+ }
243
+
230
244
src -> buf = buf ;
231
- src -> backbuf = -1 ; // force data refresh on the next update
232
245
src -> pan [0 ] = S_Chan_MidiPan (pan );
233
246
src -> env = vol ;
234
247
src -> autoloop = autoloop ;
235
- src -> channels [ 0 ] = 0 ;
236
- src -> channels [ 1 ] = 0 ;
237
248
src -> freq = freq ? freq : buf -> freq ;
238
249
src -> paused = 0 ;
239
250
src -> eof = 0 ;
251
+ src -> painted = 0 ;
252
+ //src->backbuf = -1;
240
253
241
254
if (!buf || !buf -> num_channels || !buf -> data || !src -> freq ) {
242
255
goto noplay ;
243
256
}
244
257
245
- src -> num_channels = buf -> num_channels ;
246
258
src -> adpcm .codec = buf -> adpcm_codec ;
247
259
src -> adpcm .block_size = buf -> adpcm_block_size ;
248
260
@@ -252,29 +264,40 @@ void S_Src_Play(sfx_source_t *src, sfx_buffer_t *buf, uint16_t freq, uint8_t pan
252
264
src -> pan [1 ] = 0b10000000 ; // right
253
265
}
254
266
255
- for (i = 0 ; i < buf -> num_channels ; i ++ ) {
256
- src -> channels [ i ] = S_AllocChannel ();
257
- if (!src -> channels [ i ]) {
258
- // out of free channels
259
- break ;
267
+ if (src -> num_channels != buf -> num_channels ) {
268
+ for (i = 0 ; i < buf -> num_channels ; i ++ ) {
269
+ src -> channels [ i ] = S_AllocChannel ();
270
+ if (!src -> channels [ i ]) {
271
+ // out of free channels
272
+ break ;
273
+ }
274
+ chan = & s_channels [ src -> channels [ i ] ];
275
+ chan -> freq = src -> freq ;
260
276
}
261
- chan = & s_channels [ src -> channels [ i ] ];
262
- chan -> freq = src -> freq ;
263
- }
264
277
265
- if (i < buf -> num_channels ) {
266
- // deallocate channels, exit
267
- while (i -- > 0 ) {
278
+ src -> num_channels = buf -> num_channels ;
279
+
280
+ if (i < buf -> num_channels ) {
281
+ // deallocate channels, exit
282
+ while (i -- > 0 ) {
283
+ chan = & s_channels [ src -> channels [ i ] ];
284
+ chan -> freq = 0 ;
285
+ }
286
+ noplay :
287
+ S_Src_Stop (src );
288
+ return ;
289
+ }
290
+ }
291
+ else {
292
+ for (i = 0 ; i < buf -> num_channels ; i ++ ) {
268
293
chan = & s_channels [ src -> channels [ i ] ];
269
- chan -> freq = 0 ;
294
+ chan -> freq = src -> freq ;
270
295
}
271
- noplay :
272
- src -> buf = NULL ;
273
- src -> num_channels = 0 ;
274
- return ;
275
296
}
276
297
277
298
S_Src_Rewind (src );
299
+
300
+ S_UpdateSourcesStatus ();
278
301
}
279
302
280
303
void S_Src_Update (sfx_source_t * src , uint16_t freq , uint8_t pan , uint8_t vol , uint8_t autoloop )
@@ -308,6 +331,7 @@ void S_InitSources(void)
308
331
for (i = 0 ; i < S_MAX_SOURCES ; i ++ ) {
309
332
S_Src_Init (& s_sources [ i ]);
310
333
}
334
+ S_UpdateSourcesStatus ();
311
335
}
312
336
313
337
void S_StopSources (void )
@@ -332,3 +356,22 @@ int S_AllocSource(void)
332
356
}
333
357
return 0 ;
334
358
}
359
+
360
+ void S_UpdateSourcesStatus (void )
361
+ {
362
+ int i ;
363
+ uint8_t status , bit ;
364
+
365
+ // update playback status register: for all active
366
+ // sources, the matching bit will be set to 1
367
+ bit = 1 ;
368
+ status = 0 ;
369
+ for (i = 0 ; i < S_MAX_SOURCES ; i ++ ) {
370
+ sfx_source_t * src = & s_sources [ i ];
371
+ if (src -> buf != NULL ) {
372
+ status |= bit ;
373
+ }
374
+ bit += bit ;
375
+ }
376
+ * (volatile uint8_t * )0xFF802F = status ;
377
+ }
0 commit comments