comparison src/audio/baudio/SDL_beaudio.cc @ 2049:5f6550e5184f

Merged SDL-ryan-multiple-audio-device branch r2803:2871 into the trunk.
author Ryan C. Gordon <icculus@icculus.org>
date Tue, 17 Oct 2006 09:15:21 +0000
parents adf732f1f016
children 866052b01ee5
comparison
equal deleted inserted replaced
2048:6067c7f9a672 2049:5f6550e5184f
34 #include "../SDL_audio_c.h" 34 #include "../SDL_audio_c.h"
35 #include "../SDL_sysaudio.h" 35 #include "../SDL_sysaudio.h"
36 #include "../../thread/beos/SDL_systhread_c.h" 36 #include "../../thread/beos/SDL_systhread_c.h"
37 #include "SDL_beaudio.h" 37 #include "SDL_beaudio.h"
38 38
39 39 }
40 /* Audio driver functions */ 40
41 static int BE_OpenAudio(_THIS, SDL_AudioSpec * spec); 41
42 static void BE_WaitAudio(_THIS); 42 /* !!! FIXME: have the callback call the higher level to avoid code dupe. */
43 static void BE_PlayAudio(_THIS);
44 static Uint8 *BE_GetAudioBuf(_THIS);
45 static void BE_CloseAudio(_THIS);
46
47 /* Audio driver bootstrap functions */
48
49 static int Audio_Available(void)
50 {
51 return (1);
52 }
53
54 static void Audio_DeleteDevice(SDL_AudioDevice * device)
55 {
56 SDL_free(device->hidden);
57 SDL_free(device);
58 }
59
60 static SDL_AudioDevice *Audio_CreateDevice(int devindex)
61 {
62 SDL_AudioDevice *device;
63
64 /* Initialize all variables that we clean on shutdown */
65 device = (SDL_AudioDevice *) SDL_malloc(sizeof(SDL_AudioDevice));
66 if (device) {
67 SDL_memset(device, 0, (sizeof *device));
68 device->hidden = (struct SDL_PrivateAudioData *)
69 SDL_malloc((sizeof *device->hidden));
70 }
71 if ((device == NULL) || (device->hidden == NULL)) {
72 SDL_OutOfMemory();
73 if (device) {
74 SDL_free(device);
75 }
76 return (0);
77 }
78 SDL_memset(device->hidden, 0, (sizeof *device->hidden));
79
80 /* Set the function pointers */
81 device->OpenAudio = BE_OpenAudio;
82 device->WaitAudio = BE_WaitAudio;
83 device->PlayAudio = BE_PlayAudio;
84 device->GetAudioBuf = BE_GetAudioBuf;
85 device->CloseAudio = BE_CloseAudio;
86
87 device->free = Audio_DeleteDevice;
88
89 return device;
90 }
91
92 AudioBootStrap BAUDIO_bootstrap = {
93 "baudio", "BeOS BSoundPlayer",
94 Audio_Available, Audio_CreateDevice
95 };
96
97 /* The BeOS callback for handling the audio buffer */ 43 /* The BeOS callback for handling the audio buffer */
98 static void FillSound(void *device, void *stream, size_t len, 44 static void
99 const media_raw_audio_format & format) 45 FillSound(void *device, void *stream, size_t len,
100 { 46 const media_raw_audio_format & format)
101 SDL_AudioDevice *audio = (SDL_AudioDevice *) device; 47 {
102 48 SDL_AudioDevice *audio = (SDL_AudioDevice *) device;
103 /* Silence the buffer, since it's ours */ 49
104 SDL_memset(stream, audio->spec.silence, len); 50 /* Silence the buffer, since it's ours */
105 51 SDL_memset(stream, audio->spec.silence, len);
106 /* Only do soemthing if audio is enabled */ 52
107 if (!audio->enabled) 53 /* Only do soemthing if audio is enabled */
108 return; 54 if (!audio->enabled)
109 55 return;
110 if (!audio->paused) { 56
111 if (audio->convert.needed) { 57 if (!audio->paused) {
112 SDL_mutexP(audio->mixer_lock); 58 if (audio->convert.needed) {
113 (*audio->spec.callback) (audio->spec.userdata, 59 SDL_mutexP(audio->mixer_lock);
60 (*audio->spec.callback) (audio->spec.userdata,
114 (Uint8 *) audio->convert.buf, 61 (Uint8 *) audio->convert.buf,
115 audio->convert.len); 62 audio->convert.len);
116 SDL_mutexV(audio->mixer_lock); 63 SDL_mutexV(audio->mixer_lock);
117 SDL_ConvertAudio(&audio->convert); 64 SDL_ConvertAudio(&audio->convert);
118 SDL_memcpy(stream, audio->convert.buf, 65 SDL_memcpy(stream, audio->convert.buf, audio->convert.len_cvt);
119 audio->convert.len_cvt); 66 } else {
120 } else { 67 SDL_mutexP(audio->mixer_lock);
121 SDL_mutexP(audio->mixer_lock); 68 (*audio->spec.callback) (audio->spec.userdata,
122 (*audio->spec.callback) (audio->spec.userdata, 69 (Uint8 *) stream, len);
123 (Uint8 *) stream, len); 70 SDL_mutexV(audio->mixer_lock);
124 SDL_mutexV(audio->mixer_lock);
125 }
126 } 71 }
127 return; 72 }
128 } 73 }
129 74
130 /* Dummy functions -- we don't use thread-based audio */ 75 static void
131 void BE_WaitAudio(_THIS) 76 BEOSAUDIO_CloseDevice(_THIS)
132 { 77 {
133 return; 78 if (_this->hidden != NULL) {
134 } 79 if (_this->hidden->audio_obj) {
135 void BE_PlayAudio(_THIS) 80 _this->hidden->audio_obj->Stop();
136 { 81 delete _this->hidden->audio_obj;
137 return; 82 _this->hidden->audio_obj = NULL;
138 }
139 Uint8 *BE_GetAudioBuf(_THIS)
140 {
141 return (NULL);
142 }
143
144 void BE_CloseAudio(_THIS)
145 {
146 if (audio_obj) {
147 audio_obj->Stop();
148 delete audio_obj;
149 audio_obj = NULL;
150 } 83 }
151 84
152 /* Quit the Be Application, if there's nothing left to do */ 85 delete _this->hidden;
153 SDL_QuitBeApp(); 86 _this->hidden = NULL;
154 } 87 }
155 88 }
156 int BE_OpenAudio(_THIS, SDL_AudioSpec * spec) 89
157 { 90 static int
158 int valid_datatype = 0; 91 BEOSAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
159 media_raw_audio_format format; 92 {
160 SDL_AudioFormat test_format = SDL_FirstAudioFormat(spec->format); 93 int valid_datatype = 0;
161 94 media_raw_audio_format format;
162 /* Parse the audio format and fill the Be raw audio format */ 95 SDL_AudioFormat test_format = SDL_FirstAudioFormat(_this->spec.format);
163 memset(&format, '\0', sizeof(media_raw_audio_format)); 96
164 format.byte_order = B_MEDIA_LITTLE_ENDIAN; 97 /* Initialize all variables that we clean on shutdown */
165 format.frame_rate = (float) spec->freq; 98 _this->hidden = new SDL_PrivateAudioData;
166 format.channel_count = spec->channels; /* !!! FIXME: support > 2? */ 99 if (_this->hidden == NULL) {
167 while ((!valid_datatype) && (test_format)) { 100 SDL_OutOfMemory();
168 valid_datatype = 1; 101 return 0;
169 spec->format = test_format; 102 }
170 switch (test_format) { 103 SDL_memset(_this->hidden, 0, (sizeof *_this->hidden));
104
105 /* Parse the audio format and fill the Be raw audio format */
106 SDL_memset(&format, '\0', sizeof(media_raw_audio_format));
107 format.byte_order = B_MEDIA_LITTLE_ENDIAN;
108 format.frame_rate = (float) _this->spec.freq;
109 format.channel_count = _this->spec.channels; /* !!! FIXME: support > 2? */
110 while ((!valid_datatype) && (test_format)) {
111 valid_datatype = 1;
112 _this->spec.format = test_format;
113 switch (test_format) {
171 case AUDIO_S8: 114 case AUDIO_S8:
172 format.format = media_raw_audio_format::B_AUDIO_CHAR; 115 format.format = media_raw_audio_format::B_AUDIO_CHAR;
173 break; 116 break;
174 117
175 case AUDIO_U8: 118 case AUDIO_U8:
205 148
206 default: 149 default:
207 valid_datatype = 0; 150 valid_datatype = 0;
208 test_format = SDL_NextAudioFormat(); 151 test_format = SDL_NextAudioFormat();
209 break; 152 break;
210 }
211 } 153 }
212 154 }
213 format.buffer_size = spec->samples; 155
214 156 format.buffer_size = _this->spec.samples;
215 if (!valid_datatype) { /* shouldn't happen, but just in case... */ 157
216 SDL_SetError("Unsupported audio format"); 158 if (!valid_datatype) { /* shouldn't happen, but just in case... */
217 return (-1); 159 BEOSAUDIO_CloseDevice(_this);
218 } 160 SDL_SetError("Unsupported audio format");
219 161 return 0;
220 /* Initialize the Be Application, if it's not already started */ 162 }
221 if (SDL_InitBeApp() < 0) { 163
222 return (-1); 164 /* Calculate the final parameters for this audio specification */
223 } 165 SDL_CalculateAudioSpec(&_this->spec);
224 166
225 /* Calculate the final parameters for this audio specification */ 167 /* Subscribe to the audio stream (creates a new thread) */
226 SDL_CalculateAudioSpec(spec); 168 sigset_t omask;
227 169 SDL_MaskSignals(&omask);
228 /* Subscribe to the audio stream (creates a new thread) */ 170 _this->hidden->audio_obj = new BSoundPlayer(&format, "SDL Audio",
229 { 171 FillSound, NULL, _this);
230 sigset_t omask; 172 SDL_UnmaskSignals(&omask);
231 SDL_MaskSignals(&omask); 173
232 audio_obj = new BSoundPlayer(&format, "SDL Audio", FillSound, 174 if (_this->hidden->audio_obj->Start() == B_NO_ERROR) {
233 NULL, _this); 175 _this->hidden->audio_obj->SetHasData(true);
234 SDL_UnmaskSignals(&omask); 176 } else {
235 } 177 BEOSAUDIO_CloseDevice(_this);
236 if (audio_obj->Start() == B_NO_ERROR) { 178 SDL_SetError("Unable to start Be audio");
237 audio_obj->SetHasData(true); 179 return 0;
238 } else { 180 }
239 SDL_SetError("Unable to start Be audio"); 181
240 return (-1); 182 /* We're running! */
241 } 183 return 1;
242 184 }
243 /* We're running! */ 185
244 return (1); 186 static void
245 } 187 BEOSAUDIO_Deinitialize(void)
246 188 {
247 }; /* Extern C */ 189 SDL_QuitBeApp();
190 }
191
192 static int
193 BEOSAUDIO_Init(SDL_AudioDriverImpl *impl)
194 {
195 /* Initialize the Be Application, if it's not already started */
196 if (SDL_InitBeApp() < 0) {
197 return 0;
198 }
199
200 /* Set the function pointers */
201 impl->OpenDevice = BEOSAUDIO_OpenDevice;
202 impl->CloseDevice = BEOSAUDIO_CloseDevice;
203 impl->Deinitialize = BEOSAUDIO_Deinitialize;
204 impl->ProvidesOwnCallbackThread = 1;
205 impl->OnlyHasDefaultOutputDevice = 1;
206
207 return 1;
208 }
209
210 extern "C" { extern AudioBootStrap BEOSAUDIO_bootstrap; }
211 AudioBootStrap BEOSAUDIO_bootstrap = {
212 "baudio", "BeOS BSoundPlayer", BEOSAUDIO_Init, 0
213 };
248 214
249 /* vi: set ts=4 sw=4 expandtab: */ 215 /* vi: set ts=4 sw=4 expandtab: */
216