using SDL for timekeeping
[drnoksnes] / platform / sdla.cpp
1 #include <SDL.h>
2
3 #include "platform.h"
4 #include "snes9x.h"
5 #include "soundux.h"
6
7 #define DIE(format, ...) do { \
8                 fprintf(stderr, "Died at %s:%d: ", __FILE__, __LINE__ ); \
9                 fprintf(stderr, format "\n", ## __VA_ARGS__); \
10                 abort(); \
11         } while (0);
12
13
14 static SDL_AudioSpec spec;
15
16 static void audioCallback(void *userdata, Uint8 *stream, int len)
17 {
18         int samplecount = len / 2;
19         S9xMixSamples((short*)stream, samplecount);
20 }
21
22 void S9xInitAudioOutput()
23 {
24         if (!Config.enableAudio) goto no_audio;
25
26         if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) 
27                 DIE("SDL_InitSubSystem(AUDIO): %s", SDL_GetError());
28                 
29         SDL_AudioSpec desired;
30         desired.freq = Settings.SoundPlaybackRate;
31         desired.format = AUDIO_S16LSB;
32         desired.channels = Settings.Stereo ? 2 : 1;
33         desired.samples = MAX_BUFFER_SIZE;
34         desired.callback = audioCallback;
35         desired.userdata = 0;
36         
37         if (SDL_OpenAudio(&desired, &spec) < 0) {
38                 fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError());
39                 goto no_audio_free;
40         }
41         
42         Settings.APUEnabled = TRUE;
43         Settings.SoundPlaybackRate = spec.freq;
44         if (spec.format == AUDIO_S16LSB)
45                 Settings.SixteenBitSound = TRUE;
46         else if (spec.format == AUDIO_S8) 
47                 Settings.SixteenBitSound = FALSE;
48         else {
49                 fprintf(stderr, "Invalid audio format\n");
50                 goto no_audio_free;
51         }
52         Settings.Stereo = spec.channels == 2 ? TRUE : FALSE;
53         
54         printf("Audio: %d Hz, %d %s, %s\n", spec.freq, 
55                 spec.channels, Settings.Stereo ? "channels" : "channel",
56                 Settings.SixteenBitSound ? "16 bits" : "8 bits");
57                 
58         return;
59
60 no_audio_free:
61         SDL_QuitSubSystem(SDL_INIT_AUDIO);
62         /* Fall through */
63 no_audio:
64         Config.enableAudio = false;
65         Settings.APUEnabled = FALSE;
66         printf("Audio: no audio\n");
67         
68         return;
69 }
70
71 void S9xDeinitAudioOutput()
72 {
73         if (!Config.enableAudio) return;
74         SDL_CloseAudio();
75         SDL_QuitSubSystem(SDL_INIT_AUDIO);
76 }
77
78 void S9xAudioOutputEnable(bool enable)
79 {
80         if (!Config.enableAudio) return;
81         if (enable)     {
82                 CPU.APU_APUExecuting = Settings.APUEnabled = TRUE;
83                 so.stereo = Settings.Stereo;
84                 so.playback_rate = Settings.SoundPlaybackRate;
85                 S9xSetPlaybackRate(so.playback_rate);
86                 S9xSetSoundMute(FALSE);
87                 SDL_PauseAudio(FALSE);
88         } else {
89                 S9xSetSoundMute(TRUE);
90                 SDL_PauseAudio(TRUE);
91         }
92 }
93