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