1717#include " common/pproc.h"
1818#include " lib/maapi.h"
1919#include " ui/utils.h"
20+ #include " ui/audio.h"
2021#include " platform/sdl/runtime.h"
2122#include " platform/sdl/syswm.h"
2223#include " platform/sdl/keymap.h"
2324#include " platform/sdl/main_bas.h"
2425
25- #include < SDL_audio.h>
2626#include < SDL_clipboard.h>
2727#include < SDL_events.h>
2828#include < SDL_messagebox.h>
29+ #include < SDL_mutex.h>
30+ #include < SDL_thread.h>
2931#include < SDL_timer.h>
3032#include < math.h>
3133#include < wchar.h>
@@ -53,51 +55,6 @@ strlib::List<int*> g_breakPoints;
5355socket_t g_debugee = -1 ;
5456extern int g_debugPort;
5557
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);
10158int debugThread (void *data);
10259
10360MAEvent *getMotionEvent (int type, SDL_Event *event) {
@@ -333,15 +290,8 @@ int Runtime::runShell(const char *startupBas, bool runWait, int fontScale, int d
333290 _output->setFontSize (fontSize);
334291 }
335292
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;
342293
343- SDL_AudioSpec obtainedSpec;
344- SDL_OpenAudio (&desiredSpec, &obtainedSpec);
294+ audio_open ();
345295 net_init ();
346296
347297 if (debugPort > 0 ) {
@@ -382,7 +332,7 @@ int Runtime::runShell(const char *startupBas, bool runWait, int fontScale, int d
382332
383333 debugStop ();
384334 net_close ();
385- SDL_CloseAudio ();
335+ audio_close ();
386336 _state = kDoneState ;
387337 logLeaving ();
388338 return _fontScale;
@@ -889,69 +839,6 @@ void maWait(int timeout) {
889839 runtime->pause (timeout);
890840}
891841
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-
955842//
956843// sbasic implementation
957844//
@@ -961,89 +848,10 @@ int osd_devinit(void) {
961848}
962849
963850int 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-
982851 runtime->setRunning (false );
983852 return 0 ;
984853}
985854
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-
1047855//
1048856// debugging
1049857//
0 commit comments