17
17
#include " common/pproc.h"
18
18
#include " lib/maapi.h"
19
19
#include " ui/utils.h"
20
+ #include " ui/audio.h"
20
21
#include " platform/sdl/runtime.h"
21
22
#include " platform/sdl/syswm.h"
22
23
#include " platform/sdl/keymap.h"
23
24
#include " platform/sdl/main_bas.h"
24
25
25
- #include < SDL_audio.h>
26
26
#include < SDL_clipboard.h>
27
27
#include < SDL_events.h>
28
28
#include < SDL_messagebox.h>
29
+ #include < SDL_mutex.h>
30
+ #include < SDL_thread.h>
29
31
#include < SDL_timer.h>
30
32
#include < math.h>
31
33
#include < wchar.h>
@@ -53,51 +55,6 @@ strlib::List<int*> g_breakPoints;
53
55
socket_t g_debugee = -1 ;
54
56
extern int g_debugPort;
55
57
56
- struct SoundObject {
57
- SoundObject (double freq, int duration) :
58
- _v (0 ),
59
- _freq (freq),
60
- _samplesLeft (0 ),
61
- _buffer (NULL ),
62
- _index (0 ),
63
- _cached (false ) {
64
- _samplesLeft = _samples = duration * FREQUENCY / 1000 ;
65
- }
66
-
67
- SoundObject (Uint8 *buffer, Uint32 length) :
68
- _v (0 ),
69
- _freq (0 ),
70
- _samplesLeft (length),
71
- _samples (length),
72
- _buffer (buffer),
73
- _index (0 ),
74
- _cached (true ) {
75
- }
76
-
77
- virtual ~SoundObject () {
78
- if (_buffer) {
79
- SDL_FreeWAV (_buffer);
80
- _buffer = NULL ;
81
- }
82
- }
83
-
84
- void reset () {
85
- _index = 0 ;
86
- _samplesLeft = _samples;
87
- }
88
-
89
- double _v;
90
- double _freq;
91
- Uint32 _samplesLeft;
92
- Uint32 _samples;
93
- Uint8 *_buffer;
94
- Uint32 _index;
95
- bool _cached;
96
- };
97
-
98
- strlib::Queue<SoundObject *> g_sounds;
99
- strlib::Properties<SoundObject *> g_soundCache;
100
- void audio_callback (void *data, Uint8 *stream8, int length);
101
58
int debugThread (void *data);
102
59
103
60
MAEvent *getMotionEvent (int type, SDL_Event *event) {
@@ -333,15 +290,8 @@ int Runtime::runShell(const char *startupBas, bool runWait, int fontScale, int d
333
290
_output->setFontSize (fontSize);
334
291
}
335
292
336
- SDL_AudioSpec desiredSpec;
337
- desiredSpec.freq = FREQUENCY;
338
- desiredSpec.format = AUDIO_S16SYS;
339
- desiredSpec.channels = 1 ;
340
- desiredSpec.samples = 2048 ;
341
- desiredSpec.callback = audio_callback;
342
293
343
- SDL_AudioSpec obtainedSpec;
344
- SDL_OpenAudio (&desiredSpec, &obtainedSpec);
294
+ audio_open ();
345
295
net_init ();
346
296
347
297
if (debugPort > 0 ) {
@@ -382,7 +332,7 @@ int Runtime::runShell(const char *startupBas, bool runWait, int fontScale, int d
382
332
383
333
debugStop ();
384
334
net_close ();
385
- SDL_CloseAudio ();
335
+ audio_close ();
386
336
_state = kDoneState ;
387
337
logLeaving ();
388
338
return _fontScale;
@@ -889,69 +839,6 @@ void maWait(int timeout) {
889
839
runtime->pause (timeout);
890
840
}
891
841
892
- //
893
- // audio
894
- //
895
- void audio_callback (void *data, Uint8 *stream8, int length) {
896
- Sint16 *stream = (Sint16 *)stream8;
897
- // two bytes per sample
898
- Uint32 samples = length / 2 ;
899
- Uint32 i = 0 ;
900
- while (i < samples) {
901
- if (g_sounds.empty ()) {
902
- while (i < samples) {
903
- stream[i] = 0 ;
904
- i++;
905
- }
906
- SDL_PauseAudio (1 );
907
- return ;
908
- }
909
- SoundObject *sound = g_sounds.front ();
910
- if (sound->_buffer != NULL ) {
911
- Uint32 len = MIN (sound->_samplesLeft , (Uint32)length);
912
- sound->_samplesLeft -= len;
913
- memcpy (stream8, sound->_buffer + sound->_index , len);
914
- sound->_index += len;
915
- i += len;
916
- } else {
917
- // copy a generated tone onto the stream
918
- Uint32 samplesToDo = MIN (i + sound->_samplesLeft , samples);
919
- sound->_samplesLeft -= samplesToDo - i;
920
- while (i < samplesToDo) {
921
- stream[i++] = AMPLITUDE * sin (sound->_v * 2 * M_PI / FREQUENCY);
922
- sound->_v += sound->_freq ;
923
- }
924
- }
925
- if (!sound->_samplesLeft ) {
926
- g_sounds.pop (!sound->_cached );
927
- }
928
- }
929
- }
930
-
931
- void create_sound (double freq, int duration) {
932
- SDL_LockAudio ();
933
- g_sounds.push (new SoundObject (freq, duration));
934
- SDL_UnlockAudio ();
935
- }
936
-
937
- void flush_queue () {
938
- int size;
939
- int last_size = 0 ;
940
- int unplayed = 0 ;
941
-
942
- do {
943
- SDL_Delay (20 );
944
- SDL_LockAudio ();
945
- size = g_sounds.size ();
946
- if (size != last_size) {
947
- unplayed++;
948
- } else {
949
- last_size = size;
950
- }
951
- SDL_UnlockAudio ();
952
- } while (size > 0 && unplayed < 50 );
953
- }
954
-
955
842
//
956
843
// sbasic implementation
957
844
//
@@ -961,89 +848,10 @@ int osd_devinit(void) {
961
848
}
962
849
963
850
int osd_devrestore (void ) {
964
- SDL_PauseAudio (1 );
965
- SDL_LockAudio ();
966
-
967
- // remove any cached sounds from the queue
968
- List_each (SoundObject *, it, g_sounds) {
969
- SoundObject *next = *it;
970
- if (next != NULL && next->_cached ) {
971
- g_sounds.remove (it);
972
- it--;
973
- }
974
- }
975
-
976
- // delete the sounds
977
- g_soundCache.removeAll ();
978
- g_sounds.removeAll ();
979
-
980
- SDL_UnlockAudio ();
981
-
982
851
runtime->setRunning (false );
983
852
return 0 ;
984
853
}
985
854
986
- void osd_beep () {
987
- create_sound (1000 , 30 );
988
- create_sound (500 , 30 );
989
- SDL_PauseAudio (0 );
990
- flush_queue ();
991
- }
992
-
993
- void osd_audio (const char *path) {
994
- SDL_AudioSpec desiredSpec;
995
- desiredSpec.freq = FREQUENCY;
996
- desiredSpec.format = AUDIO_S16SYS;
997
- desiredSpec.channels = 1 ;
998
- desiredSpec.samples = 2048 ;
999
- Uint8 *buffer;
1000
- Uint32 length;
1001
-
1002
- SoundObject *cachedSound = g_soundCache.get (path);
1003
- if (cachedSound) {
1004
- SDL_LockAudio ();
1005
- cachedSound->reset ();
1006
- g_sounds.push (cachedSound);
1007
- SDL_UnlockAudio ();
1008
- SDL_PauseAudio (0 );
1009
- } else {
1010
- SDL_AudioSpec *obtainedSpec = SDL_LoadWAV (path, &desiredSpec, &buffer, &length);
1011
- if (obtainedSpec != NULL ) {
1012
- if (obtainedSpec->freq != FREQUENCY) {
1013
- err_throw (" Failed to open wav file: invalid frequency %d" , obtainedSpec->freq );
1014
- } else if (obtainedSpec->channels != 1 ) {
1015
- err_throw (" Failed to open wav file: invalid channels %d" , obtainedSpec->channels );
1016
- } else if (obtainedSpec->format != AUDIO_S16SYS) {
1017
- err_throw (" Failed to open wav file: invalid format %d" , obtainedSpec->format );
1018
- } else {
1019
- SDL_LockAudio ();
1020
- SoundObject *cachedSound = new SoundObject (buffer, length);
1021
- g_sounds.push (cachedSound);
1022
- g_soundCache.put (path, cachedSound);
1023
- SDL_UnlockAudio ();
1024
- SDL_PauseAudio (0 );
1025
- }
1026
- } else {
1027
- err_throw (" Failed to open wav file: %s" , SDL_GetError ());
1028
- }
1029
- }
1030
- }
1031
-
1032
- void osd_sound (int frq, int ms, int vol, int bgplay) {
1033
- create_sound (frq, ms);
1034
- SDL_PauseAudio (0 );
1035
- if (!bgplay) {
1036
- flush_queue ();
1037
- }
1038
- }
1039
-
1040
- void osd_clear_sound_queue () {
1041
- SDL_PauseAudio (1 );
1042
- SDL_LockAudio ();
1043
- g_sounds.removeAll ();
1044
- SDL_UnlockAudio ();
1045
- }
1046
-
1047
855
//
1048
856
// debugging
1049
857
//
0 commit comments