comparison src/audio/macosx/SDL_coreaudio.c @ 1662:782fd950bd46 SDL-1.3

Revamp of the video system in progress - adding support for multiple displays, multiple windows, and a full video mode selection API. WARNING: None of the video drivers have been updated for the new API yet! The API is still under design and very fluid. The code is now run through a consistent indent format: indent -i4 -nut -nsc -br -ce The headers are being converted to automatically generate doxygen documentation.
author Sam Lantinga <slouken@libsdl.org>
date Sun, 28 May 2006 13:04:16 +0000
parents dc6b59e925a2
children 4da1ee79c9af
comparison
equal deleted inserted replaced
1661:281d3f4870e5 1662:782fd950bd46
29 #include "SDL_coreaudio.h" 29 #include "SDL_coreaudio.h"
30 30
31 31
32 /* Audio driver functions */ 32 /* Audio driver functions */
33 33
34 static int Core_OpenAudio(_THIS, SDL_AudioSpec *spec); 34 static int Core_OpenAudio (_THIS, SDL_AudioSpec * spec);
35 static void Core_WaitAudio(_THIS); 35 static void Core_WaitAudio (_THIS);
36 static void Core_PlayAudio(_THIS); 36 static void Core_PlayAudio (_THIS);
37 static Uint8 *Core_GetAudioBuf(_THIS); 37 static Uint8 *Core_GetAudioBuf (_THIS);
38 static void Core_CloseAudio(_THIS); 38 static void Core_CloseAudio (_THIS);
39 39
40 /* Audio driver bootstrap functions */ 40 /* Audio driver bootstrap functions */
41 41
42 static int Audio_Available(void) 42 static int
43 { 43 Audio_Available (void)
44 return(1); 44 {
45 } 45 return (1);
46 46 }
47 static void Audio_DeleteDevice(SDL_AudioDevice *device) 47
48 { 48 static void
49 SDL_free(device->hidden); 49 Audio_DeleteDevice (SDL_AudioDevice * device)
50 SDL_free(device); 50 {
51 } 51 SDL_free (device->hidden);
52 52 SDL_free (device);
53 static SDL_AudioDevice *Audio_CreateDevice(int devindex) 53 }
54
55 static SDL_AudioDevice *
56 Audio_CreateDevice (int devindex)
54 { 57 {
55 SDL_AudioDevice *this; 58 SDL_AudioDevice *this;
56 59
57 /* Initialize all variables that we clean on shutdown */ 60 /* Initialize all variables that we clean on shutdown */
58 this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); 61 this = (SDL_AudioDevice *) SDL_malloc (sizeof (SDL_AudioDevice));
59 if ( this ) { 62 if (this) {
60 SDL_memset(this, 0, (sizeof *this)); 63 SDL_memset (this, 0, (sizeof *this));
61 this->hidden = (struct SDL_PrivateAudioData *) 64 this->hidden = (struct SDL_PrivateAudioData *)
62 SDL_malloc((sizeof *this->hidden)); 65 SDL_malloc ((sizeof *this->hidden));
63 } 66 }
64 if ( (this == NULL) || (this->hidden == NULL) ) { 67 if ((this == NULL) || (this->hidden == NULL)) {
65 SDL_OutOfMemory(); 68 SDL_OutOfMemory ();
66 if ( this ) { 69 if (this) {
67 SDL_free(this); 70 SDL_free (this);
68 } 71 }
69 return(0); 72 return (0);
70 } 73 }
71 SDL_memset(this->hidden, 0, (sizeof *this->hidden)); 74 SDL_memset (this->hidden, 0, (sizeof *this->hidden));
72 75
73 /* Set the function pointers */ 76 /* Set the function pointers */
74 this->OpenAudio = Core_OpenAudio; 77 this->OpenAudio = Core_OpenAudio;
75 this->WaitAudio = Core_WaitAudio; 78 this->WaitAudio = Core_WaitAudio;
76 this->PlayAudio = Core_PlayAudio; 79 this->PlayAudio = Core_PlayAudio;
86 "coreaudio", "Mac OS X CoreAudio", 89 "coreaudio", "Mac OS X CoreAudio",
87 Audio_Available, Audio_CreateDevice 90 Audio_Available, Audio_CreateDevice
88 }; 91 };
89 92
90 /* The CoreAudio callback */ 93 /* The CoreAudio callback */
91 static OSStatus audioCallback (void *inRefCon, 94 static OSStatus
92 AudioUnitRenderActionFlags inActionFlags, 95 audioCallback (void *inRefCon,
93 const AudioTimeStamp *inTimeStamp, 96 AudioUnitRenderActionFlags inActionFlags,
94 UInt32 inBusNumber, 97 const AudioTimeStamp * inTimeStamp,
95 AudioBuffer *ioData) 98 UInt32 inBusNumber, AudioBuffer * ioData)
96 { 99 {
97 SDL_AudioDevice *this = (SDL_AudioDevice *)inRefCon; 100 SDL_AudioDevice *this = (SDL_AudioDevice *) inRefCon;
98 UInt32 remaining, len; 101 UInt32 remaining, len;
99 void *ptr; 102 void *ptr;
100 103
101 /* Only do anything if audio is enabled and not paused */ 104 /* Only do anything if audio is enabled and not paused */
102 if ( ! this->enabled || this->paused ) { 105 if (!this->enabled || this->paused) {
103 SDL_memset(ioData->mData, this->spec.silence, ioData->mDataByteSize); 106 SDL_memset (ioData->mData, this->spec.silence, ioData->mDataByteSize);
104 return 0; 107 return 0;
105 } 108 }
106 109
107 /* No SDL conversion should be needed here, ever, since we accept 110 /* No SDL conversion should be needed here, ever, since we accept
108 any input format in OpenAudio, and leave the conversion to CoreAudio. 111 any input format in OpenAudio, and leave the conversion to CoreAudio.
109 */ 112 */
110 /* 113 /*
111 assert(!this->convert.needed); 114 assert(!this->convert.needed);
112 assert(this->spec.channels == ioData->mNumberChannels); 115 assert(this->spec.channels == ioData->mNumberChannels);
113 */ 116 */
114 117
115 remaining = ioData->mDataByteSize; 118 remaining = ioData->mDataByteSize;
116 ptr = ioData->mData; 119 ptr = ioData->mData;
117 while (remaining > 0) { 120 while (remaining > 0) {
118 if (bufferOffset >= bufferSize) { 121 if (bufferOffset >= bufferSize) {
119 /* Generate the data */ 122 /* Generate the data */
120 SDL_memset(buffer, this->spec.silence, bufferSize); 123 SDL_memset (buffer, this->spec.silence, bufferSize);
121 SDL_mutexP(this->mixer_lock); 124 SDL_mutexP (this->mixer_lock);
122 (*this->spec.callback)(this->spec.userdata, 125 (*this->spec.callback) (this->spec.userdata, buffer, bufferSize);
123 buffer, bufferSize); 126 SDL_mutexV (this->mixer_lock);
124 SDL_mutexV(this->mixer_lock);
125 bufferOffset = 0; 127 bufferOffset = 0;
126 } 128 }
127 129
128 len = bufferSize - bufferOffset; 130 len = bufferSize - bufferOffset;
129 if (len > remaining) 131 if (len > remaining)
130 len = remaining; 132 len = remaining;
131 SDL_memcpy(ptr, (char *)buffer + bufferOffset, len); 133 SDL_memcpy (ptr, (char *) buffer + bufferOffset, len);
132 ptr = (char *)ptr + len; 134 ptr = (char *) ptr + len;
133 remaining -= len; 135 remaining -= len;
134 bufferOffset += len; 136 bufferOffset += len;
135 } 137 }
136 138
137 return 0; 139 return 0;
138 } 140 }
139 141
140 /* Dummy functions -- we don't use thread-based audio */ 142 /* Dummy functions -- we don't use thread-based audio */
141 void Core_WaitAudio(_THIS) 143 void
144 Core_WaitAudio (_THIS)
142 { 145 {
143 return; 146 return;
144 } 147 }
145 148
146 void Core_PlayAudio(_THIS) 149 void
150 Core_PlayAudio (_THIS)
147 { 151 {
148 return; 152 return;
149 } 153 }
150 154
151 Uint8 *Core_GetAudioBuf(_THIS) 155 Uint8 *
152 { 156 Core_GetAudioBuf (_THIS)
153 return(NULL); 157 {
154 } 158 return (NULL);
155 159 }
156 void Core_CloseAudio(_THIS) 160
161 void
162 Core_CloseAudio (_THIS)
157 { 163 {
158 OSStatus result; 164 OSStatus result;
159 struct AudioUnitInputCallback callback; 165 struct AudioUnitInputCallback callback;
160 166
161 /* stop processing the audio unit */ 167 /* stop processing the audio unit */
162 result = AudioOutputUnitStop (outputAudioUnit); 168 result = AudioOutputUnitStop (outputAudioUnit);
163 if (result != noErr) { 169 if (result != noErr) {
164 SDL_SetError("Core_CloseAudio: AudioOutputUnitStop"); 170 SDL_SetError ("Core_CloseAudio: AudioOutputUnitStop");
165 return; 171 return;
166 } 172 }
167 173
168 /* Remove the input callback */ 174 /* Remove the input callback */
169 callback.inputProc = 0; 175 callback.inputProc = 0;
170 callback.inputProcRefCon = 0; 176 callback.inputProcRefCon = 0;
171 result = AudioUnitSetProperty (outputAudioUnit, 177 result = AudioUnitSetProperty (outputAudioUnit,
172 kAudioUnitProperty_SetInputCallback, 178 kAudioUnitProperty_SetInputCallback,
173 kAudioUnitScope_Input, 179 kAudioUnitScope_Input,
174 0, 180 0, &callback, sizeof (callback));
175 &callback,
176 sizeof(callback));
177 if (result != noErr) { 181 if (result != noErr) {
178 SDL_SetError("Core_CloseAudio: AudioUnitSetProperty (kAudioUnitProperty_SetInputCallback)"); 182 SDL_SetError
183 ("Core_CloseAudio: AudioUnitSetProperty (kAudioUnitProperty_SetInputCallback)");
179 return; 184 return;
180 } 185 }
181 186
182 result = CloseComponent(outputAudioUnit); 187 result = CloseComponent (outputAudioUnit);
183 if (result != noErr) { 188 if (result != noErr) {
184 SDL_SetError("Core_CloseAudio: CloseComponent"); 189 SDL_SetError ("Core_CloseAudio: CloseComponent");
185 return; 190 return;
186 } 191 }
187 192
188 SDL_free(buffer); 193 SDL_free (buffer);
189 } 194 }
190 195
191 #define CHECK_RESULT(msg) \ 196 #define CHECK_RESULT(msg) \
192 if (result != noErr) { \ 197 if (result != noErr) { \
193 SDL_SetError("Failed to start CoreAudio: " msg); \ 198 SDL_SetError("Failed to start CoreAudio: " msg); \
194 return -1; \ 199 return -1; \
195 } 200 }
196 201
197 202
198 int Core_OpenAudio(_THIS, SDL_AudioSpec *spec) 203 int
204 Core_OpenAudio (_THIS, SDL_AudioSpec * spec)
199 { 205 {
200 OSStatus result = noErr; 206 OSStatus result = noErr;
201 Component comp; 207 Component comp;
202 ComponentDescription desc; 208 ComponentDescription desc;
203 struct AudioUnitInputCallback callback; 209 struct AudioUnitInputCallback callback;
206 /* Setup a AudioStreamBasicDescription with the requested format */ 212 /* Setup a AudioStreamBasicDescription with the requested format */
207 requestedDesc.mFormatID = kAudioFormatLinearPCM; 213 requestedDesc.mFormatID = kAudioFormatLinearPCM;
208 requestedDesc.mFormatFlags = kLinearPCMFormatFlagIsPacked; 214 requestedDesc.mFormatFlags = kLinearPCMFormatFlagIsPacked;
209 requestedDesc.mChannelsPerFrame = spec->channels; 215 requestedDesc.mChannelsPerFrame = spec->channels;
210 requestedDesc.mSampleRate = spec->freq; 216 requestedDesc.mSampleRate = spec->freq;
211 217
212 requestedDesc.mBitsPerChannel = spec->format & 0xFF; 218 requestedDesc.mBitsPerChannel = spec->format & 0xFF;
213 if (spec->format & 0x8000) 219 if (spec->format & 0x8000)
214 requestedDesc.mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger; 220 requestedDesc.mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger;
215 if (spec->format & 0x1000) 221 if (spec->format & 0x1000)
216 requestedDesc.mFormatFlags |= kLinearPCMFormatFlagIsBigEndian; 222 requestedDesc.mFormatFlags |= kLinearPCMFormatFlagIsBigEndian;
217 223
218 requestedDesc.mFramesPerPacket = 1; 224 requestedDesc.mFramesPerPacket = 1;
219 requestedDesc.mBytesPerFrame = requestedDesc.mBitsPerChannel * requestedDesc.mChannelsPerFrame / 8; 225 requestedDesc.mBytesPerFrame =
220 requestedDesc.mBytesPerPacket = requestedDesc.mBytesPerFrame * requestedDesc.mFramesPerPacket; 226 requestedDesc.mBitsPerChannel * requestedDesc.mChannelsPerFrame / 8;
227 requestedDesc.mBytesPerPacket =
228 requestedDesc.mBytesPerFrame * requestedDesc.mFramesPerPacket;
221 229
222 230
223 /* Locate the default output audio unit */ 231 /* Locate the default output audio unit */
224 desc.componentType = kAudioUnitComponentType; 232 desc.componentType = kAudioUnitComponentType;
225 desc.componentSubType = kAudioUnitSubType_Output; 233 desc.componentSubType = kAudioUnitSubType_Output;
226 desc.componentManufacturer = kAudioUnitID_DefaultOutput; 234 desc.componentManufacturer = kAudioUnitID_DefaultOutput;
227 desc.componentFlags = 0; 235 desc.componentFlags = 0;
228 desc.componentFlagsMask = 0; 236 desc.componentFlagsMask = 0;
229 237
230 comp = FindNextComponent (NULL, &desc); 238 comp = FindNextComponent (NULL, &desc);
231 if (comp == NULL) { 239 if (comp == NULL) {
232 SDL_SetError ("Failed to start CoreAudio: FindNextComponent returned NULL"); 240 SDL_SetError
241 ("Failed to start CoreAudio: FindNextComponent returned NULL");
233 return -1; 242 return -1;
234 } 243 }
235 244
236 /* Open & initialize the default output audio unit */ 245 /* Open & initialize the default output audio unit */
237 result = OpenAComponent (comp, &outputAudioUnit); 246 result = OpenAComponent (comp, &outputAudioUnit);
238 CHECK_RESULT("OpenAComponent") 247 CHECK_RESULT ("OpenAComponent")
239 248 result = AudioUnitInitialize (outputAudioUnit);
240 result = AudioUnitInitialize (outputAudioUnit); 249 CHECK_RESULT ("AudioUnitInitialize")
241 CHECK_RESULT("AudioUnitInitialize") 250 /* Set the input format of the audio unit. */
242 251 result = AudioUnitSetProperty (outputAudioUnit,
243 /* Set the input format of the audio unit. */ 252 kAudioUnitProperty_StreamFormat,
253 kAudioUnitScope_Input,
254 0,
255 &requestedDesc,
256 sizeof (requestedDesc));
257 CHECK_RESULT ("AudioUnitSetProperty (kAudioUnitProperty_StreamFormat)")
258 /* Set the audio callback */
259 callback.inputProc = audioCallback;
260 callback.inputProcRefCon = this;
244 result = AudioUnitSetProperty (outputAudioUnit, 261 result = AudioUnitSetProperty (outputAudioUnit,
245 kAudioUnitProperty_StreamFormat, 262 kAudioUnitProperty_SetInputCallback,
246 kAudioUnitScope_Input, 263 kAudioUnitScope_Input,
247 0, 264 0, &callback, sizeof (callback));
248 &requestedDesc, 265 CHECK_RESULT
249 sizeof (requestedDesc)); 266 ("AudioUnitSetProperty (kAudioUnitProperty_SetInputCallback)")
250 CHECK_RESULT("AudioUnitSetProperty (kAudioUnitProperty_StreamFormat)") 267 /* Calculate the final parameters for this audio specification */
251 268 SDL_CalculateAudioSpec (spec);
252 /* Set the audio callback */ 269
253 callback.inputProc = audioCallback;
254 callback.inputProcRefCon = this;
255 result = AudioUnitSetProperty (outputAudioUnit,
256 kAudioUnitProperty_SetInputCallback,
257 kAudioUnitScope_Input,
258 0,
259 &callback,
260 sizeof(callback));
261 CHECK_RESULT("AudioUnitSetProperty (kAudioUnitProperty_SetInputCallback)")
262
263 /* Calculate the final parameters for this audio specification */
264 SDL_CalculateAudioSpec(spec);
265
266 /* Allocate a sample buffer */ 270 /* Allocate a sample buffer */
267 bufferOffset = bufferSize = this->spec.size; 271 bufferOffset = bufferSize = this->spec.size;
268 buffer = SDL_malloc(bufferSize); 272 buffer = SDL_malloc (bufferSize);
269 273
270 /* Finally, start processing of the audio unit */ 274 /* Finally, start processing of the audio unit */
271 result = AudioOutputUnitStart (outputAudioUnit); 275 result = AudioOutputUnitStart (outputAudioUnit);
272 CHECK_RESULT("AudioOutputUnitStart") 276 CHECK_RESULT ("AudioOutputUnitStart")
273 277 /* We're running! */
274 278 return (1);
275 /* We're running! */ 279 }
276 return(1); 280
277 } 281 /* vi: set ts=4 sw=4 expandtab: */