1 /*
2 Copyright 2004-2011 Tom Rothamel <pytom@bishoujo.us>
3
4 Permission is hereby granted, free of charge, to any person
5 obtaining a copy of this software and associated documentation files
6 (the "Software"), to deal in the Software without restriction,
7 including without limitation the rights to use, copy, modify, merge,
8 publish, distribute, sublicense, and/or sell copies of the Software,
9 and to permit persons to whom the Software is furnished to do so,
10 subject to the following conditions:
11
12 The above copyright notice and this permission notice shall be
13 included in all copies or substantial portions of the Software.
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23
24 #include "renpysound_core.h"
25 #include <Python.h>
26 #include <SDL.h>
27 #include <SDL_thread.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include <pygame_sdl2/pygame_sdl2.h>
31
32 #define MAXVOLUME 16384
33
34
35 SDL_mutex *name_mutex;
36
37 #ifdef __EMSCRIPTEN__
38
39 #define LOCK_AUDIO() { }
40 #define UNLOCK_AUDIO() { }
41
42 #define LOCK_NAME() { }
43 #define UNLOCK_NAME() { }
44
45 #else
46
47 /* These prevent the audio callback from running when held. Use this to
48 prevent the audio callback from running while the state of the audio
49 system is being changed. */
50 #define LOCK_AUDIO() { SDL_LockAudio(); }
51 #define UNLOCK_AUDIO() { SDL_UnlockAudio(); }
52
53 /* This is held while the current track is being changed by the audio callback,
54 and can also be held to the current track doesn't change while things are
55 being processed. */
56 #define LOCK_NAME() { SDL_LockMutex(name_mutex); }
57 #define UNLOCK_NAME() { SDL_UnlockMutex(name_mutex); }
58
59 #endif
60
61 /* Declarations of ffdecode functions. */
62 struct MediaState;
63 typedef struct MediaState MediaState;
64
65 void media_init(int rate, int status, int equal_mono);
66
67 void media_advance_time(void);
68 void media_sample_surfaces(SDL_Surface *rgb, SDL_Surface *rgba);
69 MediaState *media_open(SDL_RWops *, const char *);
70 void media_want_video(MediaState *, int);
71 void media_start_end(MediaState *, double, double);
72 void media_start(MediaState *);
73 void media_pause(MediaState *, int);
74 void media_close(MediaState *);
75
76 int media_read_audio(struct MediaState *is, Uint8 *stream, int len);
77
78 int media_video_ready(struct MediaState *ms);
79 SDL_Surface *media_read_video(struct MediaState *ms);
80
81 double media_duration(struct MediaState *ms);
82 void media_wait_ready(struct MediaState *ms);
83
84 /* Min and Max */
85 #define min(a, b) (((a) < (b)) ? (a) : (b))
86 #define max(a, b) (((a) > (b)) ? (a) : (b))
87
88 /* Various error codes. */
89 #define SUCCESS 0
90 #define SDL_ERROR -1
91 #define SOUND_ERROR -2
92 #define RPS_ERROR -3
93
94 /* This is called with the appropriate error code at the end of a
95 * function. */
96 #define error(err) RPS_error = err
97 int RPS_error = SUCCESS;
98 static const char *error_msg = NULL;
99
100 /* Have we been initialized? */
101 static int initialized = 0;
102
103 /*
104 * This structure represents a channel the system knows about
105 * and can play from.
106 */
107 struct Channel {
108
109 /* The currently playing sample, NULL if this sample isn't playing
110 anything. */
111 struct MediaState *playing;
112
113 /* The name of the playing music. */
114 char *playing_name;
115
116 /* The number of ms to take to fade in the playing sample. */
117 int playing_fadein;
118
119 /* Is the playing sample tight? */
120 int playing_tight;
121
122 /* The start time of the playing sample, in ms. */
123 int playing_start_ms;
124
125 /* The queued up sample. */
126 struct MediaState *queued;
127
128 /* The name of the queued up sample. */
129 char *queued_name;
130
131 /* The number of ms to take to fade in the queued sample. */
132 int queued_fadein;
133
134 /* Is the queued sample tight? */
135 int queued_tight;
136
137 /* The start time of the queued sample, in ms. */
138 int queued_start_ms;
139
140 /* Is this channel paused? */
141 int paused;
142
143 /* The volume of the channel. */
144 int volume;
145
146 /* The position (in bytes) that this channel has queued to. */
147 int pos;
148
149 /*
150 * The number of bytes for each step of fade.
151 * 0 when no fade is in progress.
152 */
153 int fade_step_len;
154
155 /* How many bytes we are into the current fade step. */
156 int fade_off;
157
158 /* The current fade volume. */
159 int fade_vol;
160
161 /* The change in fade_vol for each step. */
162 int fade_delta;
163
164 /* The number of bytes in which we'll stop. */
165 int stop_bytes;
166
167 /* The event posted to the queue when we finish a track. */
168 int event;
169
170 /* The pan being applied to the current channel. */
171 float pan_start;
172 float pan_end;
173
174 /* The length of the current pan, in samples. */
175 unsigned int pan_length;
176
177 /* The number of samples we've finished in the current pan. */
178 unsigned int pan_done;
179
180
181 /* These are used like in pan, above. Unlike the volume parameter,
182 the voulme set here is persisted between sessions. */
183 float vol2_start;
184 float vol2_end;
185 unsigned int vol2_length;
186 unsigned int vol2_done;
187
188 /* This is set to 1 if this is a movie channel with dropping, 2 if it's a
189 * video channel without dropping. */
190 int video;
191
192 };
193
194 struct Dying {
195 struct MediaState *stream;
196 struct Dying *next;
197 };
198
199 static struct Dying *dying = NULL;
200
201 /*
202 * The number of channels the system knows about.
203 */
204 int num_channels = 0;
205
206 /*
207 * All of the channels that the system knows about.
208 */
209 struct Channel *channels = NULL;
210
211 /*
212 * The spec of the audio that is playing.
213 */
214 SDL_AudioSpec audio_spec;
215
216
interpolate_pan(struct Channel * c)217 static float interpolate_pan(struct Channel *c) {
218 float done;
219
220 if (c->pan_done > c->pan_length) {
221 c->pan_length = 0;
222 }
223
224 if (c->pan_length == 0) {
225 return c->pan_end;
226 }
227
228 done = 1.0 * c->pan_done / c->pan_length;
229
230 return c->pan_start + done * (c->pan_end - c->pan_start);
231
232 }
233
interpolate_vol2(struct Channel * c)234 static float interpolate_vol2(struct Channel *c) {
235 float done;
236
237 if (c->vol2_done > c->vol2_length) {
238 c->vol2_length = 0;
239 }
240
241 if (c->vol2_length == 0) {
242 return c->vol2_end;
243 }
244
245 done = 1.0 * c->vol2_done / c->vol2_length;
246
247 return c->vol2_start + done * (c->vol2_end - c->vol2_start);
248 }
249
ms_to_bytes(int ms)250 static int ms_to_bytes(int ms) {
251 return ((long long) ms) * audio_spec.freq * audio_spec.channels * 2 / 1000;
252 }
253
bytes_to_ms(int bytes)254 static int bytes_to_ms(int bytes) {
255 return ((long long) bytes) * 1000 / (audio_spec.freq * audio_spec.channels * 2);
256 }
257
start_sample(struct Channel * c,int reset_fade)258 static void start_sample(struct Channel* c, int reset_fade) {
259 int fade_steps;
260
261 if (!c) return;
262
263 c->pos = 0;
264
265 if (reset_fade) {
266
267 if (c->playing_fadein == 0) {
268 c->fade_step_len = 0;
269 } else {
270 fade_steps = c->volume;
271 c->fade_delta = 1;
272 c->fade_off = 0;
273 c->fade_vol = 0;
274
275 if (fade_steps) {
276 c->fade_step_len = ms_to_bytes(c->playing_fadein) / fade_steps;
277 c->fade_step_len &= ~0x7; // Even sample.
278 } else {
279 c->fade_step_len = 0;
280 }
281 }
282
283 c->stop_bytes = -1;
284 }
285 }
286
free_sample(struct MediaState * ss)287 static void free_sample(struct MediaState *ss) {
288 media_close(ss);
289 }
290
291 #define MAX_SHORT (32767)
292 #define MIN_SHORT (-32768)
293
294 // Actually mixes the audio.
mixaudio(Uint8 * dst,Uint8 * src,int length,int volume)295 static void mixaudio(Uint8 *dst, Uint8 *src, int length, int volume) {
296 int i;
297 short *sdst = (short *) dst;
298 short *ssrc = (short *) src;
299
300 for (i = 0; i < length / 2; i++) {
301 int sound = *sdst + (volume * *ssrc) / MAXVOLUME;
302 if (sound > MAX_SHORT) {
303 sound = MAX_SHORT;
304 }
305 if (sound < MIN_SHORT) {
306 sound = MIN_SHORT;
307 }
308
309 *sdst++ = (short) sound;
310 ssrc++;
311 }
312 }
313
314
315 // Mixes the audio, while performing fading.
fade_mixaudio(struct Channel * c,Uint8 * dst,Uint8 * src,int length)316 static void fade_mixaudio(struct Channel *c,
317 Uint8 *dst, Uint8 *src, int length) {
318
319 while (length) {
320
321 // No fade case.
322 if (c->fade_step_len == 0) {
323 mixaudio(dst, src, length, c->volume);
324 return;
325 }
326
327 // Fading, but we have some space left in the current step.
328 if (c->fade_off < c->fade_step_len) {
329 int l = min(c->fade_step_len - c->fade_off, length);
330
331 mixaudio(dst, src, l, c->fade_vol);
332
333 length -= l;
334 dst += l;
335 src += l;
336 c->fade_off += l;
337 continue;
338 }
339
340 // Otherwise, we have no space left in the current fade step.
341 // Go to the next step.
342 c->fade_off = 0;
343 c->fade_vol += c->fade_delta;
344
345 // Don't stop on a fadeout.
346 if (c->fade_vol <= 0) {
347 c->fade_vol = 0;
348 }
349
350 // Stop on a fadein.
351 if (c->fade_vol >= c->volume) {
352 c->fade_vol = c->volume;
353 c->fade_step_len = 0;
354 }
355 }
356
357 return;
358 }
359
post_event(struct Channel * c)360 static void post_event(struct Channel *c) {
361 if (! c->event) {
362 return;
363 }
364
365 SDL_Event e;
366 memset(&e, 0, sizeof(e));
367 e.type = c->event;
368 SDL_PushEvent(&e);
369 }
370
371 /* This handels panning and vol2 manipulations. */
pan_audio(struct Channel * c,Uint8 * stream,int length)372 static void pan_audio(struct Channel *c, Uint8 *stream, int length) {
373 int i;
374 short *sample = (short *) stream;
375 length /= 4;
376
377 float pan;
378 float vol2;
379 int left = 256;
380 int right = 256;
381
382
383 for (i = 0; i < length; i++) {
384
385 if ((i & 0x1f) == 0) {
386 pan = interpolate_pan(c);
387 vol2 = interpolate_vol2(c);
388
389 // If nothing to do, skip 32 samples.
390 if (pan == 0.0 && vol2 == 1.0) {
391 i += 31;
392 c->pan_done += 32;
393 c->vol2_done += 32;
394 sample += 32 * 2;
395 continue;
396 }
397
398 vol2 *= 256.0;
399
400 if (pan < 0) {
401 left = (int) vol2;
402 right = (int) (vol2 * (1.0 + pan));
403 } else {
404 left = (int) (vol2 * (1.0 - pan));
405 right = (int) vol2;
406 }
407 }
408
409
410 *sample = (short) ((*sample * left) >> 8);
411 sample++;
412 *sample = (short) ((*sample * right) >> 8);
413 sample++;
414
415 c->pan_done += 1;
416 c->vol2_done += 1;
417 }
418
419 }
420
callback(void * userdata,Uint8 * stream,int length)421 static void callback(void *userdata, Uint8 *stream, int length) {
422
423 int channel = 0;
424
425 memset(stream, 0, length);
426
427 for (channel = 0; channel < num_channels; channel++) {
428
429 int mixed = 0;
430 struct Channel *c = &channels[channel];
431
432 if (! c->playing) {
433 continue;
434 }
435
436 if (c->paused) {
437 continue;
438 }
439
440 while (mixed < length && c->playing) {
441 int mixleft = length - mixed;
442 Uint8 buffer[mixleft];
443 int bytes;
444
445 // Decode some amount of data.
446
447 bytes = media_read_audio(c->playing, buffer, mixleft);
448
449 // We have some data in the buffer.
450 if (c->stop_bytes && bytes) {
451
452 if (c->stop_bytes != -1)
453 bytes = min(c->stop_bytes, bytes);
454
455 pan_audio(c, buffer, bytes);
456 fade_mixaudio(c, &stream[mixed], buffer, bytes);
457
458 mixed += bytes;
459
460 if (c->stop_bytes != -1)
461 c->stop_bytes -= bytes;
462
463 c->pos += bytes;
464
465 continue;
466 }
467
468 // Otherwise, no data is left in the buffer. Check why,
469 // and act accordingly.
470
471 // Skip to the next sample.
472 if (c->stop_bytes == 0 || bytes == 0) {
473
474 int old_tight = c->playing_tight;
475 struct Dying *d;
476
477 post_event(c);
478
479 LOCK_NAME()
480
481 d = malloc(sizeof(struct Dying));
482 d->next = dying;
483 d->stream = c->playing;
484 dying = d;
485
486 free(c->playing_name);
487
488 c->playing = c->queued;
489 c->playing_name = c->queued_name;
490 c->playing_fadein = c->queued_fadein;
491 c->playing_tight = c->queued_tight;
492 c->playing_start_ms = c->queued_start_ms;
493
494 c->queued = NULL;
495 c->queued_name = NULL;
496 c->queued_fadein = 0;
497 c->queued_tight = 0;
498 c->queued_start_ms = 0;
499
500 if (c->playing_fadein) {
501 old_tight = 0;
502 }
503
504 UNLOCK_NAME()
505
506 start_sample(c, ! old_tight);
507
508 continue;
509 }
510 }
511
512 }
513
514 }
515
516 /*
517 * Checks that the given channel is in range. Returns 0 if it is,
518 * sets an error and returns -1 if it is not. Allocates channels
519 * that don't already exist.
520 */
check_channel(int c)521 static int check_channel(int c) {
522 int i;
523
524 if (c < 0) {
525 error(RPS_ERROR);
526 error_msg = "Channel number out of range.";
527 return -1;
528 }
529
530 if (c >= num_channels) {
531 struct Channel *extended_channels = realloc(channels, sizeof(struct Channel) * (c + 1));
532 if (extended_channels == NULL) {
533 error(RPS_ERROR);
534 error_msg = "Unable to allocate additional channels.";
535 return -1;
536 }
537 channels = extended_channels;
538
539 for (i = num_channels; i <= c; i++) {
540
541 memset(&channels[i], 0, sizeof(struct Channel));
542
543 channels[i].volume = MAXVOLUME;
544 channels[i].paused = 1;
545 channels[i].event = 0;
546 channels[i].vol2_start = 1.0;
547 channels[i].vol2_end = 1.0;
548 }
549
550 num_channels = c + 1;
551 }
552
553 return 0;
554 }
555
556
557 /*
558 * Loads the provided sample. Returns the sample on success, NULL on
559 * failure.
560 */
load_sample(SDL_RWops * rw,const char * ext,double start,double end,int video)561 struct MediaState *load_sample(SDL_RWops *rw, const char *ext, double start, double end, int video) {
562 struct MediaState *rv;
563 rv = media_open(rw, ext);
564 if (rv == NULL)
565 {
566 return NULL;
567 }
568 media_start_end(rv, start, end);
569
570 if (video) {
571 media_want_video(rv, video);
572 }
573
574 media_start(rv);
575 return rv;
576 }
577
578
RPS_play(int channel,SDL_RWops * rw,const char * ext,const char * name,int fadein,int tight,int paused,double start,double end)579 void RPS_play(int channel, SDL_RWops *rw, const char *ext, const char *name, int fadein, int tight, int paused, double start, double end) {
580
581 struct Channel *c;
582
583 if (check_channel(channel)) {
584 return;
585 }
586
587 c = &channels[channel];
588
589 LOCK_AUDIO();
590
591 /* Free playing and queued samples. */
592 if (c->playing) {
593 free_sample(c->playing);
594 c->playing = NULL;
595 free(c->playing_name);
596 c->playing_name = NULL;
597 c->playing_tight = 0;
598 c->playing_start_ms = 0;
599 }
600
601 if (c->queued) {
602 free_sample(c->queued);
603 c->queued = NULL;
604 free(c->queued_name);
605 c->queued_name = NULL;
606 c->queued_tight = 0;
607 c->queued_start_ms = 0;
608 }
609
610 /* Allocate playing sample. */
611
612 c->playing = load_sample(rw, ext, start, end, c->video);
613
614 if (! c->playing) {
615 UNLOCK_AUDIO();
616 error(SOUND_ERROR);
617 return;
618 }
619
620 c->playing_name = strdup(name);
621 c->playing_fadein = fadein;
622 c->playing_tight = tight;
623 c->playing_start_ms = (int) (start * 1000);
624
625 c->paused = paused;
626
627 start_sample(c, 1);
628
629 UNLOCK_AUDIO();
630
631 error(SUCCESS);
632 }
633
RPS_queue(int channel,SDL_RWops * rw,const char * ext,const char * name,int fadein,int tight,double start,double end)634 void RPS_queue(int channel, SDL_RWops *rw, const char *ext, const char *name, int fadein, int tight, double start, double end) {
635
636 struct Channel *c;
637
638 if (check_channel(channel)) {
639 return;
640 }
641
642 c = &channels[channel];
643
644 /* If we're not playing, then we should play instead of queue. */
645 if (!c->playing) {
646 RPS_play(channel, rw, ext, name, fadein, tight, 0, start, end);
647 return;
648 }
649
650 LOCK_AUDIO();
651
652 /* Free queued sample. */
653
654 if (c->queued) {
655 free_sample(c->queued);
656 c->queued = NULL;
657 free(c->queued_name);
658 c->queued_name = NULL;
659 c->queued_tight = 0;
660 }
661
662 /* Allocate queued sample. */
663 c->queued = load_sample(rw, ext, start, end, c->video);
664
665 if (! c->queued) {
666 UNLOCK_AUDIO();
667
668 error(SOUND_ERROR);
669 return;
670 }
671
672 c->queued_name = strdup(name);
673 c->queued_fadein = fadein;
674 c->queued_tight = tight;
675
676 c->queued_start_ms = (int) (start * 1000);
677
678 UNLOCK_AUDIO();
679
680 error(SUCCESS);
681 }
682
683
684 /*
685 * Stops all music from playing, freeing the data used by the
686 * music.
687 */
RPS_stop(int channel)688 void RPS_stop(int channel) {
689
690 struct Channel *c;
691
692 if (check_channel(channel)) {
693 return;
694 }
695
696 c = &channels[channel];
697
698 LOCK_AUDIO();
699
700 if (c->playing) {
701 post_event(c);
702 }
703
704 /* Free playing and queued samples. */
705 if (c->playing) {
706 free_sample(c->playing);
707 c->playing = NULL;
708 free(c->playing_name);
709 c->playing_name = NULL;
710 c->playing_start_ms = 0;
711 }
712
713 if (c->queued) {
714 free_sample(c->queued);
715 c->queued = NULL;
716 free(c->queued_name);
717 c->queued_name = NULL;
718 c->queued_start_ms = 0;
719 }
720
721 UNLOCK_AUDIO();
722
723 error(SUCCESS);
724 }
725
726 /*
727 * This dequeues the queued sound from the supplied channel, if
728 * such a sound is queued. This does nothing to the playing
729 * sound.
730 *
731 * This does nothing if the playing sound is tight, ever_tight is
732 * false.
733 */
RPS_dequeue(int channel,int even_tight)734 void RPS_dequeue(int channel, int even_tight) {
735
736 struct Channel *c;
737
738 if (check_channel(channel)) {
739 return;
740 }
741
742 c = &channels[channel];
743
744 LOCK_AUDIO();
745
746 if (c->queued && (! c->playing_tight || even_tight)) {
747 free_sample(c->queued);
748 c->queued = NULL;
749 free(c->queued_name);
750 c->queued_name = NULL;
751 } else {
752 c->queued_tight = 0;
753 }
754
755 c->queued_start_ms = 0;
756
757 UNLOCK_AUDIO();
758
759 error(SUCCESS);
760 }
761
762 /*
763 * Returns the queue depth of the current channel. This is 0 if we're
764 * stopped, 1 if there's something playing but nothing queued, and 2
765 * if there's both something playing and something queued.
766 */
RPS_queue_depth(int channel)767 int RPS_queue_depth(int channel) {
768 int rv = 0;
769
770 struct Channel *c;
771
772 if (check_channel(channel)) {
773 return 0;
774 }
775
776 c = &channels[channel];
777
778 LOCK_NAME();
779
780 if (c->playing) rv++;
781 if (c->queued) rv++;
782
783 UNLOCK_NAME();
784
785 error(SUCCESS);
786
787 return rv;
788 }
789
RPS_playing_name(int channel)790 PyObject *RPS_playing_name(int channel) {
791 PyObject *rv;
792 struct Channel *c;
793
794 if (check_channel(channel)) {
795 Py_INCREF(Py_None);
796 return Py_None;
797 }
798
799 c = &channels[channel];
800
801 LOCK_NAME();
802
803 if (c->playing_name) {
804 rv = PyBytes_FromString(c->playing_name);
805 } else {
806 Py_INCREF(Py_None);
807 rv = Py_None;
808 }
809
810 UNLOCK_NAME();
811
812 error(SUCCESS);
813
814 return rv;
815 }
816
817 /*
818 * Causes the given channel to fadeout playing after a specified
819 * number of milliseconds. The playing sound stops once the
820 * fadeout finishes (a queued sound may then start at full volume).
821 */
RPS_fadeout(int channel,int ms)822 void RPS_fadeout(int channel, int ms) {
823
824 int fade_steps;
825 struct Channel *c;
826
827 if (check_channel(channel)) {
828 return;
829 }
830
831 c = &channels[channel];
832
833 LOCK_AUDIO();
834
835 if (ms == 0) {
836 c->stop_bytes = 0;
837 UNLOCK_AUDIO();
838
839 error(SUCCESS);
840 return;
841 }
842
843 fade_steps = c->volume;
844 c->fade_delta = -1;
845 c->fade_off = 0;
846 c->fade_vol = c->volume;
847
848 if (fade_steps) {
849 c->fade_step_len = ms_to_bytes(ms) / fade_steps;
850 c->fade_step_len &= ~0x7; // Even sample.
851 } else {
852 c->fade_step_len = 0;
853 }
854
855 c->stop_bytes = ms_to_bytes(ms);
856 c->queued_tight = 0;
857
858 if (!c->queued) {
859 c->playing_tight = 0;
860 }
861
862 UNLOCK_AUDIO();
863
864 error(SUCCESS);
865 }
866
867 /*
868 * Sets the pause flag on the given channel 0 = unpaused, 1 = paused.
869 */
RPS_pause(int channel,int pause)870 void RPS_pause(int channel, int pause) {
871
872 struct Channel *c;
873
874 if (check_channel(channel)) {
875 return;
876 }
877
878 c = &channels[channel];
879
880 c->paused = pause;
881
882 if (c->playing) {
883 media_pause(c->playing, pause);
884 }
885
886 error(SUCCESS);
887
888 }
889
RPS_unpause_all_at_start(void)890 void RPS_unpause_all_at_start(void) {
891
892 int i;
893
894 /* Since media_wait_ready can block, we need to release the GIL. */
895 Py_BEGIN_ALLOW_THREADS
896
897 for (i = 0; i < num_channels; i++) {
898 if (channels[i].playing && channels[i].paused && channels[i].pos == 0) {
899 media_wait_ready(channels[i].playing);
900 }
901 }
902
903 Py_END_ALLOW_THREADS
904
905 for (i = 0; i < num_channels; i++) {
906 if (channels[i].playing && channels[i].pos == 0) {
907 channels[i].paused = 0;
908 media_pause(channels[i].playing, 0);
909 }
910 }
911
912 error(SUCCESS);
913
914 }
915
916 /*
917 * Returns the position of the given channel, in ms.
918 */
RPS_get_pos(int channel)919 int RPS_get_pos(int channel) {
920 int rv;
921 struct Channel *c;
922
923 if (check_channel(channel)) {
924 return -1;
925 }
926
927 c = &channels[channel];
928
929 LOCK_NAME();
930
931 if (c->playing) {
932 rv = bytes_to_ms(c->pos) + c->playing_start_ms;
933 } else {
934 rv = -1;
935 }
936
937 UNLOCK_NAME();
938
939 error(SUCCESS);
940 return rv;
941 }
942
943 /*
944 * Returns the duration of the file playing on the given channel, in
945 * seconds.
946 */
RPS_get_duration(int channel)947 double RPS_get_duration(int channel) {
948 double rv;
949 struct Channel *c;
950
951 if (check_channel(channel)) {
952 return 0.0;
953 }
954
955 c = &channels[channel];
956
957 LOCK_NAME();
958
959 if (c->playing) {
960 rv = media_duration(c->playing);
961 } else {
962 rv = 0.0;
963 }
964
965 UNLOCK_NAME();
966
967 error(SUCCESS);
968 return rv;
969 }
970
971 /*
972 * Sets an event that is queued up when the track on the given channel
973 * ends due to natural termination or a forced stop.
974 */
RPS_set_endevent(int channel,int event)975 void RPS_set_endevent(int channel, int event) {
976 struct Channel *c;
977
978 if (check_channel(channel)) {
979 return;
980 }
981
982 c = &channels[channel];
983
984 c->event = event;
985
986 error(SUCCESS);
987 }
988
989 /*
990 * This sets the natural volume of the channel. (This may not take
991 * effect immediately if a fade is going on.)
992 */
RPS_set_volume(int channel,float volume)993 void RPS_set_volume(int channel, float volume) {
994 struct Channel *c;
995
996 if (check_channel(channel)) {
997 return;
998 }
999
1000 c = &channels[channel];
1001 c->volume = (int) (volume * MAXVOLUME);
1002
1003 error(SUCCESS);
1004 }
1005
1006
1007
RPS_get_volume(int channel)1008 float RPS_get_volume(int channel) {
1009
1010 float rv;
1011
1012 struct Channel *c;
1013
1014 if (check_channel(channel)) {
1015 return 0.0;
1016 }
1017
1018 c = &channels[channel];
1019
1020 rv = 1.0 * c->volume / MAXVOLUME;
1021
1022 error(SUCCESS);
1023 return rv;
1024 }
1025
1026 /*
1027 * This sets the pan of the channel... independent volumes for the
1028 * left and right channels.
1029 */
RPS_set_pan(int channel,float pan,float delay)1030 void RPS_set_pan(int channel, float pan, float delay) {
1031 struct Channel *c;
1032
1033 if (check_channel(channel)) {
1034 return;
1035 }
1036
1037 c = &channels[channel];
1038
1039 LOCK_AUDIO();
1040
1041 c->pan_start = interpolate_pan(c);
1042 c->pan_end = pan;
1043 c->pan_length = (int) (audio_spec.freq * delay);
1044 c->pan_done = 0;
1045
1046 UNLOCK_AUDIO();
1047
1048 error(SUCCESS);
1049 }
1050
1051 /*
1052 * This sets the secondary volume of the channel.
1053 */
RPS_set_secondary_volume(int channel,float vol2,float delay)1054 void RPS_set_secondary_volume(int channel, float vol2, float delay) {
1055 struct Channel *c;
1056
1057 if (check_channel(channel)) {
1058 return;
1059 }
1060
1061 c = &channels[channel];
1062
1063 LOCK_AUDIO();
1064
1065 c->vol2_start = interpolate_vol2(c);
1066 c->vol2_end = vol2;
1067 c->vol2_length = (int) (audio_spec.freq * delay);
1068 c->vol2_done = 0;
1069
1070 UNLOCK_AUDIO();
1071
1072 error(SUCCESS);
1073 }
1074
RPS_read_video(int channel)1075 PyObject *RPS_read_video(int channel) {
1076 struct Channel *c;
1077 SDL_Surface *surf = NULL;
1078
1079 if (check_channel(channel)) {
1080 Py_INCREF(Py_None);
1081 return Py_None;
1082 }
1083
1084 c = &channels[channel];
1085
1086 if (c->playing) {
1087 surf = media_read_video(c->playing);
1088 }
1089
1090 error(SUCCESS);
1091
1092 if (surf) {
1093 return PySurface_New(surf);
1094 } else {
1095 Py_INCREF(Py_None);
1096 return Py_None;
1097 }
1098
1099 }
1100
RPS_video_ready(int channel)1101 int RPS_video_ready(int channel) {
1102 struct Channel *c;
1103 int rv;
1104
1105 if (check_channel(channel)) {
1106 return 1;
1107 }
1108
1109 c = &channels[channel];
1110
1111 if (c->playing) {
1112 rv = media_video_ready(c->playing);
1113 } else {
1114 rv = 1;
1115 }
1116
1117 error(SUCCESS);
1118
1119 return rv;
1120 }
1121
1122 /**
1123 * Marks channel as a video channel.
1124 */
RPS_set_video(int channel,int video)1125 void RPS_set_video(int channel, int video) {
1126 struct Channel *c;
1127
1128 if (check_channel(channel)) {
1129 return;
1130 }
1131
1132 c = &channels[channel];
1133
1134 c->video = video;
1135 }
1136
1137
1138 /*
1139 * Initializes the sound to the given frequencies, channels, and
1140 * sample buffer size.
1141 */
RPS_init(int freq,int stereo,int samples,int status,int equal_mono)1142 void RPS_init(int freq, int stereo, int samples, int status, int equal_mono) {
1143
1144 if (initialized) {
1145 return;
1146 }
1147
1148 name_mutex = SDL_CreateMutex();
1149
1150 #ifndef __EMSCRIPTEN__
1151 PyEval_InitThreads();
1152 #endif
1153
1154 import_pygame_sdl2();
1155
1156 if (SDL_Init(SDL_INIT_AUDIO)) {
1157 error(SDL_ERROR);
1158 return;
1159 }
1160
1161 audio_spec.freq = freq;
1162 audio_spec.format = AUDIO_S16SYS;
1163 audio_spec.channels = stereo;
1164 audio_spec.samples = samples;
1165 audio_spec.callback = callback;
1166 audio_spec.userdata = NULL;
1167
1168 if (SDL_OpenAudio(&audio_spec, NULL)) {
1169 error(SDL_ERROR);
1170 return;
1171 }
1172
1173 media_init(audio_spec.freq, status, equal_mono);
1174
1175 SDL_PauseAudio(0);
1176
1177 initialized = 1;
1178
1179 error(SUCCESS);
1180 }
1181
RPS_quit()1182 void RPS_quit() {
1183
1184 if (! initialized) {
1185 return;
1186 }
1187
1188 int i;
1189
1190 LOCK_AUDIO();
1191 SDL_PauseAudio(1);
1192 UNLOCK_AUDIO();
1193
1194 for (i = 0; i < num_channels; i++) {
1195 RPS_stop(i);
1196 }
1197
1198 SDL_CloseAudio();
1199
1200 num_channels = 0;
1201 initialized = 0;
1202 error(SUCCESS);
1203 }
1204
1205 /* This must be called frequently, to take care of deallocating dead
1206 * streams. */
RPS_periodic()1207 void RPS_periodic() {
1208
1209 LOCK_NAME();
1210 struct Dying *d = dying;
1211 dying = NULL;
1212 UNLOCK_NAME();
1213
1214 while (d) {
1215 media_close(d->stream);
1216 struct Dying *next_d = d->next;
1217 free(d);
1218 d = next_d;
1219 }
1220
1221 }
1222
RPS_advance_time(void)1223 void RPS_advance_time(void) {
1224 media_advance_time();
1225 }
1226
RPS_sample_surfaces(PyObject * rgb,PyObject * rgba)1227 void RPS_sample_surfaces(PyObject *rgb, PyObject *rgba) {
1228 import_pygame_sdl2();
1229
1230 media_sample_surfaces(
1231 PySurface_AsSurface(rgb),
1232 PySurface_AsSurface(rgba)
1233 );
1234
1235 }
1236
1237 /*
1238 * Returns the error message string if an error has occured, or
1239 * NULL if no error has happened.
1240 */
RPS_get_error()1241 char *RPS_get_error() {
1242 switch(RPS_error) {
1243 case 0:
1244 return (char *) "";
1245 case SDL_ERROR:
1246 return (char *) SDL_GetError();
1247 case SOUND_ERROR:
1248 return (char *) "Some sort of codec error.";
1249 case RPS_ERROR:
1250 return (char *) error_msg;
1251 default:
1252 return (char *) "Error getting error.";
1253 }
1254 }
1255