Mercurial > sdl-ios-xcode
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: */ |