comparison src/cdrom/macosx/AudioFileReaderThread.c @ 1895:c121d94672cb

SDL 1.2 is moving to a branch, and SDL 1.3 is becoming the head.
author Sam Lantinga <slouken@libsdl.org>
date Mon, 10 Jul 2006 21:04:37 +0000
parents dc6b59e925a2
children e1da92da346c
comparison
equal deleted inserted replaced
1894:c69cee13dd76 1895:c121d94672cb
26 26
27 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 27 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
28 AudioFileManager.cpp 28 AudioFileManager.cpp
29 */ 29 */
30 #include "AudioFilePlayer.h" 30 #include "AudioFilePlayer.h"
31 #include <mach/mach.h> /* used for setting policy of thread */ 31 #include <mach/mach.h> /* used for setting policy of thread */
32 #include "SDLOSXCAGuard.h" 32 #include "SDLOSXCAGuard.h"
33 #include <pthread.h> 33 #include <pthread.h>
34 34
35 /*#include <list>*/ 35 /*#include <list>*/
36 36
40 AudioFileManager *obj; 40 AudioFileManager *obj;
41 struct S_FileData *next; 41 struct S_FileData *next;
42 } FileData; 42 } FileData;
43 43
44 44
45 typedef struct S_FileReaderThread { 45 typedef struct S_FileReaderThread
46 {
46 /*public:*/ 47 /*public:*/
47 SDLOSXCAGuard* (*GetGuard)(struct S_FileReaderThread *frt); 48 SDLOSXCAGuard *(*GetGuard) (struct S_FileReaderThread * frt);
48 void (*AddReader)(struct S_FileReaderThread *frt); 49 void (*AddReader) (struct S_FileReaderThread * frt);
49 void (*RemoveReader)(struct S_FileReaderThread *frt, AudioFileManager* inItem); 50 void (*RemoveReader) (struct S_FileReaderThread * frt,
50 int (*TryNextRead)(struct S_FileReaderThread *frt, AudioFileManager* inItem); 51 AudioFileManager * inItem);
51 52 int (*TryNextRead) (struct S_FileReaderThread * frt,
52 int mThreadShouldDie; 53 AudioFileManager * inItem);
53 54
55 int mThreadShouldDie;
56
54 /*private:*/ 57 /*private:*/
55 /*typedef std::list<AudioFileManager*> FileData;*/ 58 /*typedef std::list<AudioFileManager*> FileData; */
56 59
57 SDLOSXCAGuard *mGuard; 60 SDLOSXCAGuard *mGuard;
58 UInt32 mThreadPriority; 61 UInt32 mThreadPriority;
59 62
60 int mNumReaders; 63 int mNumReaders;
61 FileData *mFileData; 64 FileData *mFileData;
62 65
63 66
64 void (*ReadNextChunk)(struct S_FileReaderThread *frt); 67 void (*ReadNextChunk) (struct S_FileReaderThread * frt);
65 int (*StartFixedPriorityThread)(struct S_FileReaderThread *frt); 68 int (*StartFixedPriorityThread) (struct S_FileReaderThread * frt);
66 /*static*/ 69 /*static */
67 UInt32 (*GetThreadBasePriority)(pthread_t inThread); 70 UInt32(*GetThreadBasePriority) (pthread_t inThread);
68 /*static*/ 71 /*static */
69 void* (*DiskReaderEntry)(void *inRefCon); 72 void *(*DiskReaderEntry) (void *inRefCon);
70 } FileReaderThread; 73 } FileReaderThread;
71 74
72 75
73 static SDLOSXCAGuard* FileReaderThread_GetGuard(FileReaderThread *frt) 76 static SDLOSXCAGuard *
77 FileReaderThread_GetGuard(FileReaderThread * frt)
74 { 78 {
75 return frt->mGuard; 79 return frt->mGuard;
76 } 80 }
77 81
78 /* returns 1 if succeeded */ 82 /* returns 1 if succeeded */
79 static int FileReaderThread_TryNextRead (FileReaderThread *frt, AudioFileManager* inItem) 83 static int
84 FileReaderThread_TryNextRead(FileReaderThread * frt,
85 AudioFileManager * inItem)
80 { 86 {
81 int didLock = 0; 87 int didLock = 0;
82 int succeeded = 0; 88 int succeeded = 0;
83 if (frt->mGuard->Try(frt->mGuard, &didLock)) 89 if (frt->mGuard->Try(frt->mGuard, &didLock)) {
84 { 90 /*frt->mFileData.push_back (inItem); */
85 /*frt->mFileData.push_back (inItem);*/
86 /* !!! FIXME: this could be faster with a "tail" member. --ryan. */ 91 /* !!! FIXME: this could be faster with a "tail" member. --ryan. */
87 FileData *i = frt->mFileData; 92 FileData *i = frt->mFileData;
88 FileData *prev = NULL; 93 FileData *prev = NULL;
89 94
90 FileData *newfd = (FileData *) SDL_malloc(sizeof (FileData)); 95 FileData *newfd = (FileData *) SDL_malloc(sizeof(FileData));
91 newfd->obj = inItem; 96 newfd->obj = inItem;
92 newfd->next = NULL; 97 newfd->next = NULL;
93 98
94 while (i != NULL) { prev = i; i = i->next; } 99 while (i != NULL) {
100 prev = i;
101 i = i->next;
102 }
95 if (prev == NULL) 103 if (prev == NULL)
96 frt->mFileData = newfd; 104 frt->mFileData = newfd;
97 else 105 else
98 prev->next = newfd; 106 prev->next = newfd;
99 107
101 succeeded = 1; 109 succeeded = 1;
102 110
103 if (didLock) 111 if (didLock)
104 frt->mGuard->Unlock(frt->mGuard); 112 frt->mGuard->Unlock(frt->mGuard);
105 } 113 }
106 114
107 return succeeded; 115 return succeeded;
108 } 116 }
109 117
110 static void FileReaderThread_AddReader(FileReaderThread *frt) 118 static void
111 { 119 FileReaderThread_AddReader(FileReaderThread * frt)
112 if (frt->mNumReaders == 0) 120 {
113 { 121 if (frt->mNumReaders == 0) {
114 frt->mThreadShouldDie = 0; 122 frt->mThreadShouldDie = 0;
115 frt->StartFixedPriorityThread (frt); 123 frt->StartFixedPriorityThread(frt);
116 } 124 }
117 frt->mNumReaders++; 125 frt->mNumReaders++;
118 } 126 }
119 127
120 static void FileReaderThread_RemoveReader (FileReaderThread *frt, AudioFileManager* inItem) 128 static void
121 { 129 FileReaderThread_RemoveReader(FileReaderThread * frt,
122 if (frt->mNumReaders > 0) 130 AudioFileManager * inItem)
123 { 131 {
132 if (frt->mNumReaders > 0) {
124 int bNeedsRelease = frt->mGuard->Lock(frt->mGuard); 133 int bNeedsRelease = frt->mGuard->Lock(frt->mGuard);
125 134
126 /*frt->mFileData.remove (inItem);*/ 135 /*frt->mFileData.remove (inItem); */
127 FileData *i = frt->mFileData; 136 FileData *i = frt->mFileData;
128 FileData *prev = NULL; 137 FileData *prev = NULL;
129 while (i != NULL) 138 while (i != NULL) {
130 {
131 FileData *next = i->next; 139 FileData *next = i->next;
132 if (i->obj != inItem) 140 if (i->obj != inItem)
133 prev = i; 141 prev = i;
134 else 142 else {
135 {
136 if (prev == NULL) 143 if (prev == NULL)
137 frt->mFileData = next; 144 frt->mFileData = next;
138 else 145 else
139 prev->next = next; 146 prev->next = next;
140 SDL_free(i); 147 SDL_free(i);
142 i = next; 149 i = next;
143 } 150 }
144 151
145 if (--frt->mNumReaders == 0) { 152 if (--frt->mNumReaders == 0) {
146 frt->mThreadShouldDie = 1; 153 frt->mThreadShouldDie = 1;
147 frt->mGuard->Notify(frt->mGuard); /* wake up thread so it will quit */ 154 frt->mGuard->Notify(frt->mGuard); /* wake up thread so it will quit */
148 frt->mGuard->Wait(frt->mGuard); /* wait for thread to die */ 155 frt->mGuard->Wait(frt->mGuard); /* wait for thread to die */
149 } 156 }
150 157
151 if (bNeedsRelease) frt->mGuard->Unlock(frt->mGuard); 158 if (bNeedsRelease)
152 } 159 frt->mGuard->Unlock(frt->mGuard);
153 } 160 }
154 161 }
155 static int FileReaderThread_StartFixedPriorityThread (FileReaderThread *frt) 162
156 { 163 static int
157 pthread_attr_t theThreadAttrs; 164 FileReaderThread_StartFixedPriorityThread(FileReaderThread * frt)
158 pthread_t pThread; 165 {
166 pthread_attr_t theThreadAttrs;
167 pthread_t pThread;
159 168
160 OSStatus result = pthread_attr_init(&theThreadAttrs); 169 OSStatus result = pthread_attr_init(&theThreadAttrs);
161 if (result) return 0; /*THROW_RESULT("pthread_attr_init - Thread attributes could not be created.")*/ 170 if (result)
162 171 return 0; /*THROW_RESULT("pthread_attr_init - Thread attributes could not be created.") */
163 result = pthread_attr_setdetachstate(&theThreadAttrs, PTHREAD_CREATE_DETACHED); 172
164 if (result) return 0; /*THROW_RESULT("pthread_attr_setdetachstate - Thread attributes could not be detached.")*/ 173 result =
165 174 pthread_attr_setdetachstate(&theThreadAttrs, PTHREAD_CREATE_DETACHED);
166 result = pthread_create (&pThread, &theThreadAttrs, frt->DiskReaderEntry, frt); 175 if (result)
167 if (result) return 0; /*THROW_RESULT("pthread_create - Create and start the thread.")*/ 176 return 0; /*THROW_RESULT("pthread_attr_setdetachstate - Thread attributes could not be detached.") */
168 177
178 result =
179 pthread_create(&pThread, &theThreadAttrs, frt->DiskReaderEntry, frt);
180 if (result)
181 return 0; /*THROW_RESULT("pthread_create - Create and start the thread.") */
182
169 pthread_attr_destroy(&theThreadAttrs); 183 pthread_attr_destroy(&theThreadAttrs);
170 184
171 /* we've now created the thread and started it 185 /* we've now created the thread and started it
172 we'll now set the priority of the thread to the nominated priority 186 we'll now set the priority of the thread to the nominated priority
173 and we'll also make the thread fixed */ 187 and we'll also make the thread fixed */
174 thread_extended_policy_data_t theFixedPolicy; 188 thread_extended_policy_data_t theFixedPolicy;
175 thread_precedence_policy_data_t thePrecedencePolicy; 189 thread_precedence_policy_data_t thePrecedencePolicy;
176 SInt32 relativePriority; 190 SInt32 relativePriority;
177 191
178 /* make thread fixed */ 192 /* make thread fixed */
179 theFixedPolicy.timeshare = 0; /* set to 1 for a non-fixed thread */ 193 theFixedPolicy.timeshare = 0; /* set to 1 for a non-fixed thread */
180 result = thread_policy_set (pthread_mach_thread_np(pThread), THREAD_EXTENDED_POLICY, (thread_policy_t)&theFixedPolicy, THREAD_EXTENDED_POLICY_COUNT); 194 result =
181 if (result) return 0; /*THROW_RESULT("thread_policy - Couldn't set thread as fixed priority.")*/ 195 thread_policy_set(pthread_mach_thread_np(pThread),
196 THREAD_EXTENDED_POLICY,
197 (thread_policy_t) & theFixedPolicy,
198 THREAD_EXTENDED_POLICY_COUNT);
199 if (result)
200 return 0; /*THROW_RESULT("thread_policy - Couldn't set thread as fixed priority.") */
182 /* set priority */ 201 /* set priority */
183 /* precedency policy's "importance" value is relative to spawning thread's priority */ 202 /* precedency policy's "importance" value is relative to spawning thread's priority */
184 relativePriority = frt->mThreadPriority - frt->GetThreadBasePriority(pthread_self()); 203 relativePriority =
185 204 frt->mThreadPriority - frt->GetThreadBasePriority(pthread_self());
205
186 thePrecedencePolicy.importance = relativePriority; 206 thePrecedencePolicy.importance = relativePriority;
187 result = thread_policy_set (pthread_mach_thread_np(pThread), THREAD_PRECEDENCE_POLICY, (thread_policy_t)&thePrecedencePolicy, THREAD_PRECEDENCE_POLICY_COUNT); 207 result =
188 if (result) return 0; /*THROW_RESULT("thread_policy - Couldn't set thread priority.")*/ 208 thread_policy_set(pthread_mach_thread_np(pThread),
209 THREAD_PRECEDENCE_POLICY,
210 (thread_policy_t) & thePrecedencePolicy,
211 THREAD_PRECEDENCE_POLICY_COUNT);
212 if (result)
213 return 0; /*THROW_RESULT("thread_policy - Couldn't set thread priority.") */
189 214
190 return 1; 215 return 1;
191 } 216 }
192 217
193 static UInt32 FileReaderThread_GetThreadBasePriority (pthread_t inThread) 218 static UInt32
194 { 219 FileReaderThread_GetThreadBasePriority(pthread_t inThread)
195 thread_basic_info_data_t threadInfo; 220 {
196 policy_info_data_t thePolicyInfo; 221 thread_basic_info_data_t threadInfo;
197 unsigned int count; 222 policy_info_data_t thePolicyInfo;
198 223 unsigned int count;
224
199 /* get basic info */ 225 /* get basic info */
200 count = THREAD_BASIC_INFO_COUNT; 226 count = THREAD_BASIC_INFO_COUNT;
201 thread_info (pthread_mach_thread_np (inThread), THREAD_BASIC_INFO, (integer_t*)&threadInfo, &count); 227 thread_info(pthread_mach_thread_np(inThread), THREAD_BASIC_INFO,
202 228 (integer_t *) & threadInfo, &count);
229
203 switch (threadInfo.policy) { 230 switch (threadInfo.policy) {
204 case POLICY_TIMESHARE: 231 case POLICY_TIMESHARE:
205 count = POLICY_TIMESHARE_INFO_COUNT; 232 count = POLICY_TIMESHARE_INFO_COUNT;
206 thread_info(pthread_mach_thread_np (inThread), THREAD_SCHED_TIMESHARE_INFO, (integer_t*)&(thePolicyInfo.ts), &count); 233 thread_info(pthread_mach_thread_np(inThread),
207 return thePolicyInfo.ts.base_priority; 234 THREAD_SCHED_TIMESHARE_INFO,
208 break; 235 (integer_t *) & (thePolicyInfo.ts), &count);
209 236 return thePolicyInfo.ts.base_priority;
210 case POLICY_FIFO: 237 break;
211 count = POLICY_FIFO_INFO_COUNT; 238
212 thread_info(pthread_mach_thread_np (inThread), THREAD_SCHED_FIFO_INFO, (integer_t*)&(thePolicyInfo.fifo), &count); 239 case POLICY_FIFO:
213 if (thePolicyInfo.fifo.depressed) { 240 count = POLICY_FIFO_INFO_COUNT;
214 return thePolicyInfo.fifo.depress_priority; 241 thread_info(pthread_mach_thread_np(inThread),
215 } else { 242 THREAD_SCHED_FIFO_INFO,
216 return thePolicyInfo.fifo.base_priority; 243 (integer_t *) & (thePolicyInfo.fifo), &count);
217 } 244 if (thePolicyInfo.fifo.depressed) {
218 break; 245 return thePolicyInfo.fifo.depress_priority;
219 246 } else {
220 case POLICY_RR: 247 return thePolicyInfo.fifo.base_priority;
221 count = POLICY_RR_INFO_COUNT; 248 }
222 thread_info(pthread_mach_thread_np (inThread), THREAD_SCHED_RR_INFO, (integer_t*)&(thePolicyInfo.rr), &count); 249 break;
223 if (thePolicyInfo.rr.depressed) { 250
224 return thePolicyInfo.rr.depress_priority; 251 case POLICY_RR:
225 } else { 252 count = POLICY_RR_INFO_COUNT;
226 return thePolicyInfo.rr.base_priority; 253 thread_info(pthread_mach_thread_np(inThread),
227 } 254 THREAD_SCHED_RR_INFO,
228 break; 255 (integer_t *) & (thePolicyInfo.rr), &count);
229 } 256 if (thePolicyInfo.rr.depressed) {
230 257 return thePolicyInfo.rr.depress_priority;
258 } else {
259 return thePolicyInfo.rr.base_priority;
260 }
261 break;
262 }
263
231 return 0; 264 return 0;
232 } 265 }
233 266
234 static void *FileReaderThread_DiskReaderEntry (void *inRefCon) 267 static void *
235 { 268 FileReaderThread_DiskReaderEntry(void *inRefCon)
236 FileReaderThread *frt = (FileReaderThread *)inRefCon; 269 {
270 FileReaderThread *frt = (FileReaderThread *) inRefCon;
237 frt->ReadNextChunk(frt); 271 frt->ReadNextChunk(frt);
238 #if DEBUG 272 #if DEBUG
239 printf ("finished with reading file\n"); 273 printf("finished with reading file\n");
240 #endif 274 #endif
241 275
242 return 0; 276 return 0;
243 } 277 }
244 278
245 static void FileReaderThread_ReadNextChunk (FileReaderThread *frt) 279 static void
280 FileReaderThread_ReadNextChunk(FileReaderThread * frt)
246 { 281 {
247 OSStatus result; 282 OSStatus result;
248 UInt32 dataChunkSize; 283 UInt32 dataChunkSize;
249 AudioFileManager* theItem = 0; 284 AudioFileManager *theItem = 0;
250 285
251 for (;;) 286 for (;;) {
252 { 287 { /* this is a scoped based lock */
253 { /* this is a scoped based lock */
254 int bNeedsRelease = frt->mGuard->Lock(frt->mGuard); 288 int bNeedsRelease = frt->mGuard->Lock(frt->mGuard);
255 289
256 if (frt->mThreadShouldDie) { 290 if (frt->mThreadShouldDie) {
257 frt->mGuard->Notify(frt->mGuard); 291 frt->mGuard->Notify(frt->mGuard);
258 if (bNeedsRelease) frt->mGuard->Unlock(frt->mGuard); 292 if (bNeedsRelease)
293 frt->mGuard->Unlock(frt->mGuard);
259 return; 294 return;
260 } 295 }
261 296
262 /*if (frt->mFileData.empty())*/ 297 /*if (frt->mFileData.empty()) */
263 if (frt->mFileData == NULL) 298 if (frt->mFileData == NULL) {
264 {
265 frt->mGuard->Wait(frt->mGuard); 299 frt->mGuard->Wait(frt->mGuard);
266 } 300 }
267 301
268 /* kill thread */ 302 /* kill thread */
269 if (frt->mThreadShouldDie) { 303 if (frt->mThreadShouldDie) {
270 304
271 frt->mGuard->Notify(frt->mGuard); 305 frt->mGuard->Notify(frt->mGuard);
272 if (bNeedsRelease) frt->mGuard->Unlock(frt->mGuard); 306 if (bNeedsRelease)
307 frt->mGuard->Unlock(frt->mGuard);
273 return; 308 return;
274 } 309 }
275 310
276 /*theItem = frt->mFileData.front();*/ 311 /*theItem = frt->mFileData.front(); */
277 /*frt->mFileData.pop_front();*/ 312 /*frt->mFileData.pop_front(); */
278 theItem = NULL; 313 theItem = NULL;
279 if (frt->mFileData != NULL) 314 if (frt->mFileData != NULL) {
280 {
281 FileData *next = frt->mFileData->next; 315 FileData *next = frt->mFileData->next;
282 theItem = frt->mFileData->obj; 316 theItem = frt->mFileData->obj;
283 SDL_free(frt->mFileData); 317 SDL_free(frt->mFileData);
284 frt->mFileData = next; 318 frt->mFileData = next;
285 } 319 }
286 320
287 if (bNeedsRelease) frt->mGuard->Unlock(frt->mGuard); 321 if (bNeedsRelease)
288 } 322 frt->mGuard->Unlock(frt->mGuard);
289 323 }
290 if ((theItem->mFileLength - theItem->mReadFilePosition) < theItem->mChunkSize) 324
325 if ((theItem->mFileLength - theItem->mReadFilePosition) <
326 theItem->mChunkSize)
291 dataChunkSize = theItem->mFileLength - theItem->mReadFilePosition; 327 dataChunkSize = theItem->mFileLength - theItem->mReadFilePosition;
292 else 328 else
293 dataChunkSize = theItem->mChunkSize; 329 dataChunkSize = theItem->mChunkSize;
294 330
295 /* this is the exit condition for the thread */ 331 /* this is the exit condition for the thread */
296 if (dataChunkSize <= 0) { 332 if (dataChunkSize <= 0) {
297 theItem->mFinishedReadingData = 1; 333 theItem->mFinishedReadingData = 1;
298 continue; 334 continue;
299 } 335 }
300 /* construct pointer */ 336 /* construct pointer */
301 char* writePtr = (char *) (theItem->GetFileBuffer(theItem) + 337 char *writePtr = (char *) (theItem->GetFileBuffer(theItem) +
302 (theItem->mWriteToFirstBuffer ? 0 : theItem->mChunkSize)); 338 (theItem->
303 339 mWriteToFirstBuffer ? 0 : theItem->
304 /* read data */ 340 mChunkSize));
341
342 /* read data */
305 result = theItem->Read(theItem, writePtr, &dataChunkSize); 343 result = theItem->Read(theItem, writePtr, &dataChunkSize);
306 if (result != noErr && result != eofErr) { 344 if (result != noErr && result != eofErr) {
307 AudioFilePlayer *afp = (AudioFilePlayer *) theItem->GetParent(theItem); 345 AudioFilePlayer *afp =
346 (AudioFilePlayer *) theItem->GetParent(theItem);
308 afp->DoNotification(afp, result); 347 afp->DoNotification(afp, result);
309 continue; 348 continue;
310 } 349 }
311 350
312 if (dataChunkSize != theItem->mChunkSize) 351 if (dataChunkSize != theItem->mChunkSize) {
313 {
314 writePtr += dataChunkSize; 352 writePtr += dataChunkSize;
315 353
316 /* can't exit yet.. we still have to pass the partial buffer back */ 354 /* can't exit yet.. we still have to pass the partial buffer back */
317 SDL_memset(writePtr, 0, (theItem->mChunkSize - dataChunkSize)); 355 SDL_memset(writePtr, 0, (theItem->mChunkSize - dataChunkSize));
318 } 356 }
319 357
320 theItem->mWriteToFirstBuffer = !theItem->mWriteToFirstBuffer; /* switch buffers */ 358 theItem->mWriteToFirstBuffer = !theItem->mWriteToFirstBuffer; /* switch buffers */
321 359
322 if (result == eofErr) 360 if (result == eofErr)
323 theItem->mReadFilePosition = theItem->mFileLength; 361 theItem->mReadFilePosition = theItem->mFileLength;
324 else 362 else
325 theItem->mReadFilePosition += dataChunkSize; /* increment count */ 363 theItem->mReadFilePosition += dataChunkSize; /* increment count */
326 } 364 }
327 } 365 }
328 366
329 void delete_FileReaderThread(FileReaderThread *frt) 367 void
330 { 368 delete_FileReaderThread(FileReaderThread * frt)
331 if (frt != NULL) 369 {
332 { 370 if (frt != NULL) {
333 delete_SDLOSXCAGuard(frt->mGuard); 371 delete_SDLOSXCAGuard(frt->mGuard);
334 SDL_free(frt); 372 SDL_free(frt);
335 } 373 }
336 } 374 }
337 375
338 FileReaderThread *new_FileReaderThread () 376 FileReaderThread *
339 { 377 new_FileReaderThread()
340 FileReaderThread *frt = (FileReaderThread *) SDL_malloc(sizeof (FileReaderThread)); 378 {
379 FileReaderThread *frt =
380 (FileReaderThread *) SDL_malloc(sizeof(FileReaderThread));
341 if (frt == NULL) 381 if (frt == NULL)
342 return NULL; 382 return NULL;
343 SDL_memset(frt, '\0', sizeof (*frt)); 383 SDL_memset(frt, '\0', sizeof(*frt));
344 384
345 frt->mGuard = new_SDLOSXCAGuard(); 385 frt->mGuard = new_SDLOSXCAGuard();
346 if (frt->mGuard == NULL) 386 if (frt->mGuard == NULL) {
347 {
348 SDL_free(frt); 387 SDL_free(frt);
349 return NULL; 388 return NULL;
350 } 389 }
351 390 #define SET_FILEREADERTHREAD_METHOD(m) frt->m = FileReaderThread_##m
352 #define SET_FILEREADERTHREAD_METHOD(m) frt->m = FileReaderThread_##m
353 SET_FILEREADERTHREAD_METHOD(GetGuard); 391 SET_FILEREADERTHREAD_METHOD(GetGuard);
354 SET_FILEREADERTHREAD_METHOD(AddReader); 392 SET_FILEREADERTHREAD_METHOD(AddReader);
355 SET_FILEREADERTHREAD_METHOD(RemoveReader); 393 SET_FILEREADERTHREAD_METHOD(RemoveReader);
356 SET_FILEREADERTHREAD_METHOD(TryNextRead); 394 SET_FILEREADERTHREAD_METHOD(TryNextRead);
357 SET_FILEREADERTHREAD_METHOD(ReadNextChunk); 395 SET_FILEREADERTHREAD_METHOD(ReadNextChunk);
358 SET_FILEREADERTHREAD_METHOD(StartFixedPriorityThread); 396 SET_FILEREADERTHREAD_METHOD(StartFixedPriorityThread);
359 SET_FILEREADERTHREAD_METHOD(GetThreadBasePriority); 397 SET_FILEREADERTHREAD_METHOD(GetThreadBasePriority);
360 SET_FILEREADERTHREAD_METHOD(DiskReaderEntry); 398 SET_FILEREADERTHREAD_METHOD(DiskReaderEntry);
361 #undef SET_FILEREADERTHREAD_METHOD 399 #undef SET_FILEREADERTHREAD_METHOD
362 400
363 frt->mThreadPriority = 62; 401 frt->mThreadPriority = 62;
364 return frt; 402 return frt;
365 } 403 }
366 404
367 405
368 static FileReaderThread *sReaderThread; 406 static FileReaderThread *sReaderThread;
369 407
370 408
371 static int AudioFileManager_DoConnect (AudioFileManager *afm) 409 static int
372 { 410 AudioFileManager_DoConnect(AudioFileManager * afm)
373 if (!afm->mIsEngaged) 411 {
374 { 412 if (!afm->mIsEngaged) {
375 OSStatus result; 413 OSStatus result;
376 414
377 /*afm->mReadFilePosition = 0;*/ 415 /*afm->mReadFilePosition = 0; */
378 afm->mFinishedReadingData = 0; 416 afm->mFinishedReadingData = 0;
379 417
380 afm->mNumTimesAskedSinceFinished = 0; 418 afm->mNumTimesAskedSinceFinished = 0;
381 afm->mLockUnsuccessful = 0; 419 afm->mLockUnsuccessful = 0;
382 420
383 UInt32 dataChunkSize; 421 UInt32 dataChunkSize;
384 422
385 if ((afm->mFileLength - afm->mReadFilePosition) < afm->mChunkSize) 423 if ((afm->mFileLength - afm->mReadFilePosition) < afm->mChunkSize)
386 dataChunkSize = afm->mFileLength - afm->mReadFilePosition; 424 dataChunkSize = afm->mFileLength - afm->mReadFilePosition;
387 else 425 else
388 dataChunkSize = afm->mChunkSize; 426 dataChunkSize = afm->mChunkSize;
389 427
390 result = afm->Read(afm, afm->mFileBuffer, &dataChunkSize); 428 result = afm->Read(afm, afm->mFileBuffer, &dataChunkSize);
391 if (result) return 0; /*THROW_RESULT("AudioFileManager::DoConnect(): Read")*/ 429 if (result)
430 return 0; /*THROW_RESULT("AudioFileManager::DoConnect(): Read") */
392 431
393 afm->mReadFilePosition += dataChunkSize; 432 afm->mReadFilePosition += dataChunkSize;
394 433
395 afm->mWriteToFirstBuffer = 0; 434 afm->mWriteToFirstBuffer = 0;
396 afm->mReadFromFirstBuffer = 1; 435 afm->mReadFromFirstBuffer = 1;
397 436
398 sReaderThread->AddReader(sReaderThread); 437 sReaderThread->AddReader(sReaderThread);
399 438
400 afm->mIsEngaged = 1; 439 afm->mIsEngaged = 1;
401 } 440 }
402 /* 441 /*
403 else 442 else
404 throw static_cast<OSStatus>(-1); */ /* thread has already been started */ 443 throw static_cast<OSStatus>(-1); *//* thread has already been started */
405 444
406 return 1; 445 return 1;
407 } 446 }
408 447
409 static void AudioFileManager_Disconnect (AudioFileManager *afm) 448 static void
410 { 449 AudioFileManager_Disconnect(AudioFileManager * afm)
411 if (afm->mIsEngaged) 450 {
412 { 451 if (afm->mIsEngaged) {
413 sReaderThread->RemoveReader (sReaderThread, afm); 452 sReaderThread->RemoveReader(sReaderThread, afm);
414 afm->mIsEngaged = 0; 453 afm->mIsEngaged = 0;
415 } 454 }
416 } 455 }
417 456
418 static OSStatus AudioFileManager_Read(AudioFileManager *afm, char *buffer, UInt32 *len) 457 static OSStatus
419 { 458 AudioFileManager_Read(AudioFileManager * afm, char *buffer, UInt32 * len)
420 return FSReadFork (afm->mForkRefNum, 459 {
421 fsFromStart, 460 return FSReadFork(afm->mForkRefNum,
422 afm->mReadFilePosition + afm->mAudioDataOffset, 461 fsFromStart,
423 *len, 462 afm->mReadFilePosition + afm->mAudioDataOffset,
424 buffer, 463 *len, buffer, len);
425 len); 464 }
426 } 465
427 466 static OSStatus
428 static OSStatus AudioFileManager_GetFileData (AudioFileManager *afm, void** inOutData, UInt32 *inOutDataSize) 467 AudioFileManager_GetFileData(AudioFileManager * afm, void **inOutData,
429 { 468 UInt32 * inOutDataSize)
430 if (afm->mFinishedReadingData) 469 {
431 { 470 if (afm->mFinishedReadingData) {
432 ++afm->mNumTimesAskedSinceFinished; 471 ++afm->mNumTimesAskedSinceFinished;
433 *inOutDataSize = 0; 472 *inOutDataSize = 0;
434 *inOutData = 0; 473 *inOutData = 0;
435 return noErr; 474 return noErr;
436 } 475 }
437 476
438 if (afm->mReadFromFirstBuffer == afm->mWriteToFirstBuffer) { 477 if (afm->mReadFromFirstBuffer == afm->mWriteToFirstBuffer) {
439 #if DEBUG 478 #if DEBUG
440 printf ("* * * * * * * Can't keep up with reading file\n"); 479 printf("* * * * * * * Can't keep up with reading file\n");
441 #endif 480 #endif
442 481
443 afm->mParent->DoNotification (afm->mParent, kAudioFilePlayErr_FilePlayUnderrun); 482 afm->mParent->DoNotification(afm->mParent,
483 kAudioFilePlayErr_FilePlayUnderrun);
444 *inOutDataSize = 0; 484 *inOutDataSize = 0;
445 *inOutData = 0; 485 *inOutData = 0;
446 } else { 486 } else {
447 *inOutDataSize = afm->mChunkSize; 487 *inOutDataSize = afm->mChunkSize;
448 *inOutData = afm->mReadFromFirstBuffer ? afm->mFileBuffer : (afm->mFileBuffer + afm->mChunkSize); 488 *inOutData =
449 } 489 afm->mReadFromFirstBuffer ? afm->mFileBuffer : (afm->
450 490 mFileBuffer +
451 afm->mLockUnsuccessful = !sReaderThread->TryNextRead (sReaderThread, afm); 491 afm->mChunkSize);
452 492 }
493
494 afm->mLockUnsuccessful = !sReaderThread->TryNextRead(sReaderThread, afm);
495
453 afm->mReadFromFirstBuffer = !afm->mReadFromFirstBuffer; 496 afm->mReadFromFirstBuffer = !afm->mReadFromFirstBuffer;
454 497
455 return noErr; 498 return noErr;
456 } 499 }
457 500
458 static void AudioFileManager_AfterRender (AudioFileManager *afm) 501 static void
459 { 502 AudioFileManager_AfterRender(AudioFileManager * afm)
460 if (afm->mNumTimesAskedSinceFinished > 0) 503 {
461 { 504 if (afm->mNumTimesAskedSinceFinished > 0) {
462 int didLock = 0; 505 int didLock = 0;
463 SDLOSXCAGuard *guard = sReaderThread->GetGuard(sReaderThread); 506 SDLOSXCAGuard *guard = sReaderThread->GetGuard(sReaderThread);
464 if (guard->Try(guard, &didLock)) { 507 if (guard->Try(guard, &didLock)) {
465 afm->mParent->DoNotification (afm->mParent, kAudioFilePlay_FileIsFinished); 508 afm->mParent->DoNotification(afm->mParent,
509 kAudioFilePlay_FileIsFinished);
466 if (didLock) 510 if (didLock)
467 guard->Unlock(guard); 511 guard->Unlock(guard);
468 } 512 }
469 } 513 }
470 514
471 if (afm->mLockUnsuccessful) 515 if (afm->mLockUnsuccessful)
472 afm->mLockUnsuccessful = !sReaderThread->TryNextRead (sReaderThread, afm); 516 afm->mLockUnsuccessful =
473 } 517 !sReaderThread->TryNextRead(sReaderThread, afm);
474 518 }
475 static void AudioFileManager_SetPosition (AudioFileManager *afm, SInt64 pos) 519
520 static void
521 AudioFileManager_SetPosition(AudioFileManager * afm, SInt64 pos)
476 { 522 {
477 if (pos < 0 || pos >= afm->mFileLength) { 523 if (pos < 0 || pos >= afm->mFileLength) {
478 SDL_SetError ("AudioFileManager::SetPosition - position invalid: %d filelen=%d\n", 524 SDL_SetError
479 (unsigned int)pos, (unsigned int)afm->mFileLength); 525 ("AudioFileManager::SetPosition - position invalid: %d filelen=%d\n",
526 (unsigned int) pos, (unsigned int) afm->mFileLength);
480 pos = 0; 527 pos = 0;
481 } 528 }
482 529
483 afm->mReadFilePosition = pos; 530 afm->mReadFilePosition = pos;
484 } 531 }
485 532
486 static void AudioFileManager_SetEndOfFile (AudioFileManager *afm, SInt64 pos) 533 static void
534 AudioFileManager_SetEndOfFile(AudioFileManager * afm, SInt64 pos)
487 { 535 {
488 if (pos <= 0 || pos > afm->mFileLength) { 536 if (pos <= 0 || pos > afm->mFileLength) {
489 SDL_SetError ("AudioFileManager::SetEndOfFile - position beyond actual eof\n"); 537 SDL_SetError
538 ("AudioFileManager::SetEndOfFile - position beyond actual eof\n");
490 pos = afm->mFileLength; 539 pos = afm->mFileLength;
491 } 540 }
492 541
493 afm->mFileLength = pos; 542 afm->mFileLength = pos;
494 } 543 }
495 544
496 static const char *AudioFileManager_GetFileBuffer(AudioFileManager *afm) 545 static const char *
546 AudioFileManager_GetFileBuffer(AudioFileManager * afm)
497 { 547 {
498 return afm->mFileBuffer; 548 return afm->mFileBuffer;
499 } 549 }
500 550
501 const AudioFilePlayer *AudioFileManager_GetParent(AudioFileManager *afm) 551 const AudioFilePlayer *
552 AudioFileManager_GetParent(AudioFileManager * afm)
502 { 553 {
503 return afm->mParent; 554 return afm->mParent;
504 } 555 }
505 556
506 static int AudioFileManager_GetByteCounter(AudioFileManager *afm) 557 static int
558 AudioFileManager_GetByteCounter(AudioFileManager * afm)
507 { 559 {
508 return afm->mByteCounter; 560 return afm->mByteCounter;
509 } 561 }
510 562
511 563
512 static OSStatus AudioFileManager_FileInputProc (void *inRefCon, 564 static OSStatus
513 AudioUnitRenderActionFlags inActionFlags, 565 AudioFileManager_FileInputProc(void *inRefCon,
514 const AudioTimeStamp *inTimeStamp, 566 AudioUnitRenderActionFlags inActionFlags,
515 UInt32 inBusNumber, 567 const AudioTimeStamp * inTimeStamp,
516 AudioBuffer *ioData) 568 UInt32 inBusNumber, AudioBuffer * ioData)
517 { 569 {
518 AudioFileManager* afm = (AudioFileManager*)inRefCon; 570 AudioFileManager *afm = (AudioFileManager *) inRefCon;
519 return afm->Render(afm, ioData); 571 return afm->Render(afm, ioData);
520 } 572 }
521 573
522 static OSStatus AudioFileManager_Render (AudioFileManager *afm, AudioBuffer *ioData) 574 static OSStatus
575 AudioFileManager_Render(AudioFileManager * afm, AudioBuffer * ioData)
523 { 576 {
524 OSStatus result = noErr; 577 OSStatus result = noErr;
525 578
526 if (afm->mBufferOffset >= afm->mBufferSize) { 579 if (afm->mBufferOffset >= afm->mBufferSize) {
527 result = afm->GetFileData(afm, &afm->mTmpBuffer, &afm->mBufferSize); 580 result = afm->GetFileData(afm, &afm->mTmpBuffer, &afm->mBufferSize);
528 if (result) { 581 if (result) {
529 SDL_SetError ("AudioConverterFillBuffer:%ld\n", result); 582 SDL_SetError("AudioConverterFillBuffer:%ld\n", result);
530 afm->mParent->DoNotification(afm->mParent, result); 583 afm->mParent->DoNotification(afm->mParent, result);
531 return result; 584 return result;
532 } 585 }
533 586
534 afm->mBufferOffset = 0; 587 afm->mBufferOffset = 0;
535 } 588 }
536 589
537 if (ioData->mDataByteSize > afm->mBufferSize - afm->mBufferOffset) 590 if (ioData->mDataByteSize > afm->mBufferSize - afm->mBufferOffset)
538 ioData->mDataByteSize = afm->mBufferSize - afm->mBufferOffset; 591 ioData->mDataByteSize = afm->mBufferSize - afm->mBufferOffset;
539 ioData->mData = (char *)afm->mTmpBuffer + afm->mBufferOffset; 592 ioData->mData = (char *) afm->mTmpBuffer + afm->mBufferOffset;
540 afm->mBufferOffset += ioData->mDataByteSize; 593 afm->mBufferOffset += ioData->mDataByteSize;
541 594
542 afm->mByteCounter += ioData->mDataByteSize; 595 afm->mByteCounter += ioData->mDataByteSize;
543 afm->AfterRender(afm); 596 afm->AfterRender(afm);
544 return result; 597 return result;
545 } 598 }
546 599
547 600
548 void delete_AudioFileManager (AudioFileManager *afm) 601 void
602 delete_AudioFileManager(AudioFileManager * afm)
549 { 603 {
550 if (afm != NULL) { 604 if (afm != NULL) {
551 if (afm->mFileBuffer) { 605 if (afm->mFileBuffer) {
552 free(afm->mFileBuffer); 606 free(afm->mFileBuffer);
553 } 607 }
555 SDL_free(afm); 609 SDL_free(afm);
556 } 610 }
557 } 611 }
558 612
559 613
560 AudioFileManager *new_AudioFileManager(AudioFilePlayer *inParent, 614 AudioFileManager *
561 SInt16 inForkRefNum, 615 new_AudioFileManager(AudioFilePlayer * inParent,
562 SInt64 inFileLength, 616 SInt16 inForkRefNum,
563 UInt32 inChunkSize) 617 SInt64 inFileLength, UInt32 inChunkSize)
564 { 618 {
565 AudioFileManager *afm; 619 AudioFileManager *afm;
566 620
567 if (sReaderThread == NULL) 621 if (sReaderThread == NULL) {
568 {
569 sReaderThread = new_FileReaderThread(); 622 sReaderThread = new_FileReaderThread();
570 if (sReaderThread == NULL) 623 if (sReaderThread == NULL)
571 return NULL; 624 return NULL;
572 } 625 }
573 626
574 afm = (AudioFileManager *) SDL_malloc(sizeof (AudioFileManager)); 627 afm = (AudioFileManager *) SDL_malloc(sizeof(AudioFileManager));
575 if (afm == NULL) 628 if (afm == NULL)
576 return NULL; 629 return NULL;
577 SDL_memset(afm, '\0', sizeof (*afm)); 630 SDL_memset(afm, '\0', sizeof(*afm));
578 631
579 #define SET_AUDIOFILEMANAGER_METHOD(m) afm->m = AudioFileManager_##m 632 #define SET_AUDIOFILEMANAGER_METHOD(m) afm->m = AudioFileManager_##m
580 SET_AUDIOFILEMANAGER_METHOD(Disconnect); 633 SET_AUDIOFILEMANAGER_METHOD(Disconnect);
581 SET_AUDIOFILEMANAGER_METHOD(DoConnect); 634 SET_AUDIOFILEMANAGER_METHOD(DoConnect);
582 SET_AUDIOFILEMANAGER_METHOD(Read); 635 SET_AUDIOFILEMANAGER_METHOD(Read);
583 SET_AUDIOFILEMANAGER_METHOD(GetFileBuffer); 636 SET_AUDIOFILEMANAGER_METHOD(GetFileBuffer);
584 SET_AUDIOFILEMANAGER_METHOD(GetParent); 637 SET_AUDIOFILEMANAGER_METHOD(GetParent);
587 SET_AUDIOFILEMANAGER_METHOD(SetEndOfFile); 640 SET_AUDIOFILEMANAGER_METHOD(SetEndOfFile);
588 SET_AUDIOFILEMANAGER_METHOD(Render); 641 SET_AUDIOFILEMANAGER_METHOD(Render);
589 SET_AUDIOFILEMANAGER_METHOD(GetFileData); 642 SET_AUDIOFILEMANAGER_METHOD(GetFileData);
590 SET_AUDIOFILEMANAGER_METHOD(AfterRender); 643 SET_AUDIOFILEMANAGER_METHOD(AfterRender);
591 SET_AUDIOFILEMANAGER_METHOD(FileInputProc); 644 SET_AUDIOFILEMANAGER_METHOD(FileInputProc);
592 #undef SET_AUDIOFILEMANAGER_METHOD 645 #undef SET_AUDIOFILEMANAGER_METHOD
593 646
594 afm->mParent = inParent; 647 afm->mParent = inParent;
595 afm->mForkRefNum = inForkRefNum; 648 afm->mForkRefNum = inForkRefNum;
596 afm->mBufferSize = inChunkSize; 649 afm->mBufferSize = inChunkSize;
597 afm->mBufferOffset = inChunkSize; 650 afm->mBufferOffset = inChunkSize;
598 afm->mChunkSize = inChunkSize; 651 afm->mChunkSize = inChunkSize;
599 afm->mFileLength = inFileLength; 652 afm->mFileLength = inFileLength;
600 afm->mFileBuffer = (char*) SDL_malloc(afm->mChunkSize * 2); 653 afm->mFileBuffer = (char *) SDL_malloc(afm->mChunkSize * 2);
601 FSGetForkPosition(afm->mForkRefNum, &afm->mAudioDataOffset); 654 FSGetForkPosition(afm->mForkRefNum, &afm->mAudioDataOffset);
602 assert (afm->mFileBuffer != NULL); 655 assert(afm->mFileBuffer != NULL);
603 return afm; 656 return afm;
604 } 657 }
605 658
659 /* vi: set ts=4 sw=4 expandtab: */