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