diff options
author | Franklin Wei <git@fwei.tk> | 2018-02-07 20:04:46 -0500 |
---|---|---|
committer | Franklin Wei <git@fwei.tk> | 2018-03-12 20:52:01 -0400 |
commit | 6039eb05ba6d82ef56f2868c96654c552d117bf9 (patch) | |
tree | 9db7016bcbf66cfdf7b9bc998d84c6eaff9c8378 /apps/plugins/sdl/src/cdrom/macosx/AudioFileReaderThread.c | |
parent | ef373c03b96b0be08babca581d9f10bccfd4931f (diff) | |
download | rockbox-6039eb05ba6d82ef56f2868c96654c552d117bf9.tar.gz rockbox-6039eb05ba6d82ef56f2868c96654c552d117bf9.zip |
sdl: remove non-rockbox drivers
We never use any of these other drivers, so having them around just takes
up space.
Change-Id: Iced812162df1fef3fd55522b7e700acb6c3bcd41
Diffstat (limited to 'apps/plugins/sdl/src/cdrom/macosx/AudioFileReaderThread.c')
-rw-r--r-- | apps/plugins/sdl/src/cdrom/macosx/AudioFileReaderThread.c | 610 |
1 files changed, 0 insertions, 610 deletions
diff --git a/apps/plugins/sdl/src/cdrom/macosx/AudioFileReaderThread.c b/apps/plugins/sdl/src/cdrom/macosx/AudioFileReaderThread.c deleted file mode 100644 index 0007c07f61..0000000000 --- a/apps/plugins/sdl/src/cdrom/macosx/AudioFileReaderThread.c +++ /dev/null | |||
@@ -1,610 +0,0 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 Sam Lantinga | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Library General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2 of the License, or (at your option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Library General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Library General Public | ||
16 | License along with this library; if not, write to the Free | ||
17 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | |||
22 | This file based on Apple sample code. We haven't changed the file name, | ||
23 | so if you want to see the original search for it on apple.com/developer | ||
24 | */ | ||
25 | #include "SDL_config.h" | ||
26 | |||
27 | /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
28 | AudioFileManager.cpp | ||
29 | */ | ||
30 | #include "AudioFilePlayer.h" | ||
31 | #include <mach/mach.h> /* used for setting policy of thread */ | ||
32 | #include "SDLOSXCAGuard.h" | ||
33 | #include <pthread.h> | ||
34 | |||
35 | /*#include <list>*/ | ||
36 | |||
37 | /*typedef void *FileData;*/ | ||
38 | typedef struct S_FileData | ||
39 | { | ||
40 | AudioFileManager *obj; | ||
41 | struct S_FileData *next; | ||
42 | } FileData; | ||
43 | |||
44 | |||
45 | typedef struct S_FileReaderThread { | ||
46 | /*public:*/ | ||
47 | SDLOSXCAGuard* (*GetGuard)(struct S_FileReaderThread *frt); | ||
48 | void (*AddReader)(struct S_FileReaderThread *frt); | ||
49 | void (*RemoveReader)(struct S_FileReaderThread *frt, AudioFileManager* inItem); | ||
50 | int (*TryNextRead)(struct S_FileReaderThread *frt, AudioFileManager* inItem); | ||
51 | |||
52 | int mThreadShouldDie; | ||
53 | |||
54 | /*private:*/ | ||
55 | /*typedef std::list<AudioFileManager*> FileData;*/ | ||
56 | |||
57 | SDLOSXCAGuard *mGuard; | ||
58 | UInt32 mThreadPriority; | ||
59 | |||
60 | int mNumReaders; | ||
61 | FileData *mFileData; | ||
62 | |||
63 | |||
64 | void (*ReadNextChunk)(struct S_FileReaderThread *frt); | ||
65 | int (*StartFixedPriorityThread)(struct S_FileReaderThread *frt); | ||
66 | /*static*/ | ||
67 | UInt32 (*GetThreadBasePriority)(pthread_t inThread); | ||
68 | /*static*/ | ||
69 | void* (*DiskReaderEntry)(void *inRefCon); | ||
70 | } FileReaderThread; | ||
71 | |||
72 | |||
73 | static SDLOSXCAGuard* FileReaderThread_GetGuard(FileReaderThread *frt) | ||
74 | { | ||
75 | return frt->mGuard; | ||
76 | } | ||
77 | |||
78 | /* returns 1 if succeeded */ | ||
79 | static int FileReaderThread_TryNextRead (FileReaderThread *frt, AudioFileManager* inItem) | ||
80 | { | ||
81 | int didLock = 0; | ||
82 | int succeeded = 0; | ||
83 | if (frt->mGuard->Try(frt->mGuard, &didLock)) | ||
84 | { | ||
85 | /*frt->mFileData.push_back (inItem);*/ | ||
86 | /* !!! FIXME: this could be faster with a "tail" member. --ryan. */ | ||
87 | FileData *i = frt->mFileData; | ||
88 | FileData *prev = NULL; | ||
89 | |||
90 | FileData *newfd = (FileData *) SDL_malloc(sizeof (FileData)); | ||
91 | newfd->obj = inItem; | ||
92 | newfd->next = NULL; | ||
93 | |||
94 | while (i != NULL) { prev = i; i = i->next; } | ||
95 | if (prev == NULL) | ||
96 | frt->mFileData = newfd; | ||
97 | else | ||
98 | prev->next = newfd; | ||
99 | |||
100 | frt->mGuard->Notify(frt->mGuard); | ||
101 | succeeded = 1; | ||
102 | |||
103 | if (didLock) | ||
104 | frt->mGuard->Unlock(frt->mGuard); | ||
105 | } | ||
106 | |||
107 | return succeeded; | ||
108 | } | ||
109 | |||
110 | static void FileReaderThread_AddReader(FileReaderThread *frt) | ||
111 | { | ||
112 | if (frt->mNumReaders == 0) | ||
113 | { | ||
114 | frt->mThreadShouldDie = 0; | ||
115 | frt->StartFixedPriorityThread (frt); | ||
116 | } | ||
117 | frt->mNumReaders++; | ||
118 | } | ||
119 | |||
120 | static void FileReaderThread_RemoveReader (FileReaderThread *frt, AudioFileManager* inItem) | ||
121 | { | ||
122 | if (frt->mNumReaders > 0) | ||
123 | { | ||
124 | int bNeedsRelease = frt->mGuard->Lock(frt->mGuard); | ||
125 | |||
126 | /*frt->mFileData.remove (inItem);*/ | ||
127 | FileData *i = frt->mFileData; | ||
128 | FileData *prev = NULL; | ||
129 | while (i != NULL) | ||
130 | { | ||
131 | FileData *next = i->next; | ||
132 | if (i->obj != inItem) | ||
133 | prev = i; | ||
134 | else | ||
135 | { | ||
136 | if (prev == NULL) | ||
137 | frt->mFileData = next; | ||
138 | else | ||
139 | prev->next = next; | ||
140 | SDL_free(i); | ||
141 | } | ||
142 | i = next; | ||
143 | } | ||
144 | |||
145 | if (--frt->mNumReaders == 0) { | ||
146 | frt->mThreadShouldDie = 1; | ||
147 | frt->mGuard->Notify(frt->mGuard); /* wake up thread so it will quit */ | ||
148 | frt->mGuard->Wait(frt->mGuard); /* wait for thread to die */ | ||
149 | } | ||
150 | |||
151 | if (bNeedsRelease) frt->mGuard->Unlock(frt->mGuard); | ||
152 | } | ||
153 | } | ||
154 | |||
155 | static int FileReaderThread_StartFixedPriorityThread (FileReaderThread *frt) | ||
156 | { | ||
157 | pthread_attr_t theThreadAttrs; | ||
158 | pthread_t pThread; | ||
159 | |||
160 | OSStatus result = pthread_attr_init(&theThreadAttrs); | ||
161 | if (result) return 0; /*THROW_RESULT("pthread_attr_init - Thread attributes could not be created.")*/ | ||
162 | |||
163 | result = pthread_attr_setdetachstate(&theThreadAttrs, PTHREAD_CREATE_DETACHED); | ||
164 | if (result) return 0; /*THROW_RESULT("pthread_attr_setdetachstate - Thread attributes could not be detached.")*/ | ||
165 | |||
166 | result = pthread_create (&pThread, &theThreadAttrs, frt->DiskReaderEntry, frt); | ||
167 | if (result) return 0; /*THROW_RESULT("pthread_create - Create and start the thread.")*/ | ||
168 | |||
169 | pthread_attr_destroy(&theThreadAttrs); | ||
170 | |||
171 | /* we've now created the thread and started it | ||
172 | we'll now set the priority of the thread to the nominated priority | ||
173 | and we'll also make the thread fixed */ | ||
174 | thread_extended_policy_data_t theFixedPolicy; | ||
175 | thread_precedence_policy_data_t thePrecedencePolicy; | ||
176 | SInt32 relativePriority; | ||
177 | |||
178 | /* make thread fixed */ | ||
179 | 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); | ||
181 | if (result) return 0; /*THROW_RESULT("thread_policy - Couldn't set thread as fixed priority.")*/ | ||
182 | /* set priority */ | ||
183 | /* precedency policy's "importance" value is relative to spawning thread's priority */ | ||
184 | relativePriority = frt->mThreadPriority - frt->GetThreadBasePriority(pthread_self()); | ||
185 | |||
186 | thePrecedencePolicy.importance = relativePriority; | ||
187 | result = thread_policy_set (pthread_mach_thread_np(pThread), THREAD_PRECEDENCE_POLICY, (thread_policy_t)&thePrecedencePolicy, THREAD_PRECEDENCE_POLICY_COUNT); | ||
188 | if (result) return 0; /*THROW_RESULT("thread_policy - Couldn't set thread priority.")*/ | ||
189 | |||
190 | return 1; | ||
191 | } | ||
192 | |||
193 | static UInt32 FileReaderThread_GetThreadBasePriority (pthread_t inThread) | ||
194 | { | ||
195 | thread_basic_info_data_t threadInfo; | ||
196 | policy_info_data_t thePolicyInfo; | ||
197 | unsigned int count; | ||
198 | |||
199 | /* get basic info */ | ||
200 | count = THREAD_BASIC_INFO_COUNT; | ||
201 | thread_info (pthread_mach_thread_np (inThread), THREAD_BASIC_INFO, (integer_t*)&threadInfo, &count); | ||
202 | |||
203 | switch (threadInfo.policy) { | ||
204 | case POLICY_TIMESHARE: | ||
205 | count = POLICY_TIMESHARE_INFO_COUNT; | ||
206 | thread_info(pthread_mach_thread_np (inThread), THREAD_SCHED_TIMESHARE_INFO, (integer_t*)&(thePolicyInfo.ts), &count); | ||
207 | return thePolicyInfo.ts.base_priority; | ||
208 | break; | ||
209 | |||
210 | case POLICY_FIFO: | ||
211 | count = POLICY_FIFO_INFO_COUNT; | ||
212 | thread_info(pthread_mach_thread_np (inThread), THREAD_SCHED_FIFO_INFO, (integer_t*)&(thePolicyInfo.fifo), &count); | ||
213 | if (thePolicyInfo.fifo.depressed) { | ||
214 | return thePolicyInfo.fifo.depress_priority; | ||
215 | } else { | ||
216 | return thePolicyInfo.fifo.base_priority; | ||
217 | } | ||
218 | break; | ||
219 | |||
220 | case POLICY_RR: | ||
221 | count = POLICY_RR_INFO_COUNT; | ||
222 | thread_info(pthread_mach_thread_np (inThread), THREAD_SCHED_RR_INFO, (integer_t*)&(thePolicyInfo.rr), &count); | ||
223 | if (thePolicyInfo.rr.depressed) { | ||
224 | return thePolicyInfo.rr.depress_priority; | ||
225 | } else { | ||
226 | return thePolicyInfo.rr.base_priority; | ||
227 | } | ||
228 | break; | ||
229 | } | ||
230 | |||
231 | return 0; | ||
232 | } | ||
233 | |||
234 | static void *FileReaderThread_DiskReaderEntry (void *inRefCon) | ||
235 | { | ||
236 | FileReaderThread *frt = (FileReaderThread *)inRefCon; | ||
237 | frt->ReadNextChunk(frt); | ||
238 | #if DEBUG | ||
239 | printf ("finished with reading file\n"); | ||
240 | #endif | ||
241 | |||
242 | return 0; | ||
243 | } | ||
244 | |||
245 | static void FileReaderThread_ReadNextChunk (FileReaderThread *frt) | ||
246 | { | ||
247 | OSStatus result; | ||
248 | ByteCount dataChunkSize; | ||
249 | AudioFileManager* theItem = 0; | ||
250 | |||
251 | for (;;) | ||
252 | { | ||
253 | { /* this is a scoped based lock */ | ||
254 | int bNeedsRelease = frt->mGuard->Lock(frt->mGuard); | ||
255 | |||
256 | if (frt->mThreadShouldDie) { | ||
257 | frt->mGuard->Notify(frt->mGuard); | ||
258 | if (bNeedsRelease) frt->mGuard->Unlock(frt->mGuard); | ||
259 | return; | ||
260 | } | ||
261 | |||
262 | /*if (frt->mFileData.empty())*/ | ||
263 | if (frt->mFileData == NULL) | ||
264 | { | ||
265 | frt->mGuard->Wait(frt->mGuard); | ||
266 | } | ||
267 | |||
268 | /* kill thread */ | ||
269 | if (frt->mThreadShouldDie) { | ||
270 | |||
271 | frt->mGuard->Notify(frt->mGuard); | ||
272 | if (bNeedsRelease) frt->mGuard->Unlock(frt->mGuard); | ||
273 | return; | ||
274 | } | ||
275 | |||
276 | /*theItem = frt->mFileData.front();*/ | ||
277 | /*frt->mFileData.pop_front();*/ | ||
278 | theItem = NULL; | ||
279 | if (frt->mFileData != NULL) | ||
280 | { | ||
281 | FileData *next = frt->mFileData->next; | ||
282 | theItem = frt->mFileData->obj; | ||
283 | SDL_free(frt->mFileData); | ||
284 | frt->mFileData = next; | ||
285 | } | ||
286 | |||
287 | if (bNeedsRelease) frt->mGuard->Unlock(frt->mGuard); | ||
288 | } | ||
289 | |||
290 | if ((theItem->mFileLength - theItem->mReadFilePosition) < theItem->mChunkSize) | ||
291 | dataChunkSize = theItem->mFileLength - theItem->mReadFilePosition; | ||
292 | else | ||
293 | dataChunkSize = theItem->mChunkSize; | ||
294 | |||
295 | /* this is the exit condition for the thread */ | ||
296 | if (dataChunkSize <= 0) { | ||
297 | theItem->mFinishedReadingData = 1; | ||
298 | continue; | ||
299 | } | ||
300 | /* construct pointer */ | ||
301 | char* writePtr = (char *) (theItem->GetFileBuffer(theItem) + | ||
302 | (theItem->mWriteToFirstBuffer ? 0 : theItem->mChunkSize)); | ||
303 | |||
304 | /* read data */ | ||
305 | result = theItem->Read(theItem, writePtr, &dataChunkSize); | ||
306 | if (result != noErr && result != eofErr) { | ||
307 | AudioFilePlayer *afp = (AudioFilePlayer *) theItem->GetParent(theItem); | ||
308 | afp->DoNotification(afp, result); | ||
309 | continue; | ||
310 | } | ||
311 | |||
312 | if (dataChunkSize != theItem->mChunkSize) | ||
313 | { | ||
314 | writePtr += dataChunkSize; | ||
315 | |||
316 | /* can't exit yet.. we still have to pass the partial buffer back */ | ||
317 | SDL_memset(writePtr, 0, (theItem->mChunkSize - dataChunkSize)); | ||
318 | } | ||
319 | |||
320 | theItem->mWriteToFirstBuffer = !theItem->mWriteToFirstBuffer; /* switch buffers */ | ||
321 | |||
322 | if (result == eofErr) | ||
323 | theItem->mReadFilePosition = theItem->mFileLength; | ||
324 | else | ||
325 | theItem->mReadFilePosition += dataChunkSize; /* increment count */ | ||
326 | } | ||
327 | } | ||
328 | |||
329 | void delete_FileReaderThread(FileReaderThread *frt) | ||
330 | { | ||
331 | if (frt != NULL) | ||
332 | { | ||
333 | delete_SDLOSXCAGuard(frt->mGuard); | ||
334 | SDL_free(frt); | ||
335 | } | ||
336 | } | ||
337 | |||
338 | FileReaderThread *new_FileReaderThread () | ||
339 | { | ||
340 | FileReaderThread *frt = (FileReaderThread *) SDL_malloc(sizeof (FileReaderThread)); | ||
341 | if (frt == NULL) | ||
342 | return NULL; | ||
343 | SDL_memset(frt, '\0', sizeof (*frt)); | ||
344 | |||
345 | frt->mGuard = new_SDLOSXCAGuard(); | ||
346 | if (frt->mGuard == NULL) | ||
347 | { | ||
348 | SDL_free(frt); | ||
349 | return NULL; | ||
350 | } | ||
351 | |||
352 | #define SET_FILEREADERTHREAD_METHOD(m) frt->m = FileReaderThread_##m | ||
353 | SET_FILEREADERTHREAD_METHOD(GetGuard); | ||
354 | SET_FILEREADERTHREAD_METHOD(AddReader); | ||
355 | SET_FILEREADERTHREAD_METHOD(RemoveReader); | ||
356 | SET_FILEREADERTHREAD_METHOD(TryNextRead); | ||
357 | SET_FILEREADERTHREAD_METHOD(ReadNextChunk); | ||
358 | SET_FILEREADERTHREAD_METHOD(StartFixedPriorityThread); | ||
359 | SET_FILEREADERTHREAD_METHOD(GetThreadBasePriority); | ||
360 | SET_FILEREADERTHREAD_METHOD(DiskReaderEntry); | ||
361 | #undef SET_FILEREADERTHREAD_METHOD | ||
362 | |||
363 | frt->mThreadPriority = 62; | ||
364 | return frt; | ||
365 | } | ||
366 | |||
367 | |||
368 | static FileReaderThread *sReaderThread; | ||
369 | |||
370 | |||
371 | static int AudioFileManager_DoConnect (AudioFileManager *afm) | ||
372 | { | ||
373 | if (!afm->mIsEngaged) | ||
374 | { | ||
375 | OSStatus result; | ||
376 | |||
377 | /*afm->mReadFilePosition = 0;*/ | ||
378 | afm->mFinishedReadingData = 0; | ||
379 | |||
380 | afm->mNumTimesAskedSinceFinished = 0; | ||
381 | afm->mLockUnsuccessful = 0; | ||
382 | |||
383 | ByteCount dataChunkSize; | ||
384 | |||
385 | if ((afm->mFileLength - afm->mReadFilePosition) < afm->mChunkSize) | ||
386 | dataChunkSize = afm->mFileLength - afm->mReadFilePosition; | ||
387 | else | ||
388 | dataChunkSize = afm->mChunkSize; | ||
389 | |||
390 | result = afm->Read(afm, afm->mFileBuffer, &dataChunkSize); | ||
391 | if (result) return 0; /*THROW_RESULT("AudioFileManager::DoConnect(): Read")*/ | ||
392 | |||
393 | afm->mReadFilePosition += dataChunkSize; | ||
394 | |||
395 | afm->mWriteToFirstBuffer = 0; | ||
396 | afm->mReadFromFirstBuffer = 1; | ||
397 | |||
398 | sReaderThread->AddReader(sReaderThread); | ||
399 | |||
400 | afm->mIsEngaged = 1; | ||
401 | } | ||
402 | /* | ||
403 | else | ||
404 | throw static_cast<OSStatus>(-1); */ /* thread has already been started */ | ||
405 | |||
406 | return 1; | ||
407 | } | ||
408 | |||
409 | static void AudioFileManager_Disconnect (AudioFileManager *afm) | ||
410 | { | ||
411 | if (afm->mIsEngaged) | ||
412 | { | ||
413 | sReaderThread->RemoveReader (sReaderThread, afm); | ||
414 | afm->mIsEngaged = 0; | ||
415 | } | ||
416 | } | ||
417 | |||
418 | static OSStatus AudioFileManager_Read(AudioFileManager *afm, char *buffer, ByteCount *len) | ||
419 | { | ||
420 | return FSReadFork (afm->mForkRefNum, | ||
421 | fsFromStart, | ||
422 | afm->mReadFilePosition + afm->mAudioDataOffset, | ||
423 | *len, | ||
424 | buffer, | ||
425 | len); | ||
426 | } | ||
427 | |||
428 | static OSStatus AudioFileManager_GetFileData (AudioFileManager *afm, void** inOutData, UInt32 *inOutDataSize) | ||
429 | { | ||
430 | if (afm->mFinishedReadingData) | ||
431 | { | ||
432 | ++afm->mNumTimesAskedSinceFinished; | ||
433 | *inOutDataSize = 0; | ||
434 | *inOutData = 0; | ||
435 | return noErr; | ||
436 | } | ||
437 | |||
438 | if (afm->mReadFromFirstBuffer == afm->mWriteToFirstBuffer) { | ||
439 | #if DEBUG | ||
440 | printf ("* * * * * * * Can't keep up with reading file\n"); | ||
441 | #endif | ||
442 | |||
443 | afm->mParent->DoNotification (afm->mParent, kAudioFilePlayErr_FilePlayUnderrun); | ||
444 | *inOutDataSize = 0; | ||
445 | *inOutData = 0; | ||
446 | } else { | ||
447 | *inOutDataSize = afm->mChunkSize; | ||
448 | *inOutData = afm->mReadFromFirstBuffer ? afm->mFileBuffer : (afm->mFileBuffer + afm->mChunkSize); | ||
449 | } | ||
450 | |||
451 | afm->mLockUnsuccessful = !sReaderThread->TryNextRead (sReaderThread, afm); | ||
452 | |||
453 | afm->mReadFromFirstBuffer = !afm->mReadFromFirstBuffer; | ||
454 | |||
455 | return noErr; | ||
456 | } | ||
457 | |||
458 | static void AudioFileManager_AfterRender (AudioFileManager *afm) | ||
459 | { | ||
460 | if (afm->mNumTimesAskedSinceFinished > 0) | ||
461 | { | ||
462 | int didLock = 0; | ||
463 | SDLOSXCAGuard *guard = sReaderThread->GetGuard(sReaderThread); | ||
464 | if (guard->Try(guard, &didLock)) { | ||
465 | afm->mParent->DoNotification (afm->mParent, kAudioFilePlay_FileIsFinished); | ||
466 | if (didLock) | ||
467 | guard->Unlock(guard); | ||
468 | } | ||
469 | } | ||
470 | |||
471 | if (afm->mLockUnsuccessful) | ||
472 | afm->mLockUnsuccessful = !sReaderThread->TryNextRead (sReaderThread, afm); | ||
473 | } | ||
474 | |||
475 | static void AudioFileManager_SetPosition (AudioFileManager *afm, SInt64 pos) | ||
476 | { | ||
477 | if (pos < 0 || pos >= afm->mFileLength) { | ||
478 | SDL_SetError ("AudioFileManager::SetPosition - position invalid: %d filelen=%d\n", | ||
479 | (unsigned int)pos, (unsigned int)afm->mFileLength); | ||
480 | pos = 0; | ||
481 | } | ||
482 | |||
483 | afm->mReadFilePosition = pos; | ||
484 | } | ||
485 | |||
486 | static void AudioFileManager_SetEndOfFile (AudioFileManager *afm, SInt64 pos) | ||
487 | { | ||
488 | if (pos <= 0 || pos > afm->mFileLength) { | ||
489 | SDL_SetError ("AudioFileManager::SetEndOfFile - position beyond actual eof\n"); | ||
490 | pos = afm->mFileLength; | ||
491 | } | ||
492 | |||
493 | afm->mFileLength = pos; | ||
494 | } | ||
495 | |||
496 | static const char *AudioFileManager_GetFileBuffer(AudioFileManager *afm) | ||
497 | { | ||
498 | return afm->mFileBuffer; | ||
499 | } | ||
500 | |||
501 | const AudioFilePlayer *AudioFileManager_GetParent(AudioFileManager *afm) | ||
502 | { | ||
503 | return afm->mParent; | ||
504 | } | ||
505 | |||
506 | static int AudioFileManager_GetByteCounter(AudioFileManager *afm) | ||
507 | { | ||
508 | return afm->mByteCounter; | ||
509 | } | ||
510 | |||
511 | static OSStatus AudioFileManager_FileInputProc (void *inRefCon, | ||
512 | AudioUnitRenderActionFlags *ioActionFlags, | ||
513 | const AudioTimeStamp *inTimeStamp, | ||
514 | UInt32 inBusNumber, | ||
515 | UInt32 inNumberFrames, | ||
516 | AudioBufferList *ioData) | ||
517 | { | ||
518 | AudioFileManager* afm = (AudioFileManager*)inRefCon; | ||
519 | return afm->Render(afm, ioData); | ||
520 | } | ||
521 | |||
522 | static OSStatus AudioFileManager_Render (AudioFileManager *afm, AudioBufferList *ioData) | ||
523 | { | ||
524 | OSStatus result = noErr; | ||
525 | AudioBuffer *abuf; | ||
526 | UInt32 i; | ||
527 | |||
528 | for (i = 0; i < ioData->mNumberBuffers; i++) { | ||
529 | abuf = &ioData->mBuffers[i]; | ||
530 | if (afm->mBufferOffset >= afm->mBufferSize) { | ||
531 | result = afm->GetFileData(afm, &afm->mTmpBuffer, &afm->mBufferSize); | ||
532 | if (result) { | ||
533 | SDL_SetError ("AudioConverterFillBuffer:%ld\n", result); | ||
534 | afm->mParent->DoNotification(afm->mParent, result); | ||
535 | return result; | ||
536 | } | ||
537 | |||
538 | afm->mBufferOffset = 0; | ||
539 | } | ||
540 | |||
541 | if (abuf->mDataByteSize > afm->mBufferSize - afm->mBufferOffset) | ||
542 | abuf->mDataByteSize = afm->mBufferSize - afm->mBufferOffset; | ||
543 | abuf->mData = (char *)afm->mTmpBuffer + afm->mBufferOffset; | ||
544 | afm->mBufferOffset += abuf->mDataByteSize; | ||
545 | |||
546 | afm->mByteCounter += abuf->mDataByteSize; | ||
547 | afm->AfterRender(afm); | ||
548 | } | ||
549 | return result; | ||
550 | } | ||
551 | |||
552 | |||
553 | void delete_AudioFileManager (AudioFileManager *afm) | ||
554 | { | ||
555 | if (afm != NULL) { | ||
556 | if (afm->mFileBuffer) { | ||
557 | free(afm->mFileBuffer); | ||
558 | } | ||
559 | |||
560 | SDL_free(afm); | ||
561 | } | ||
562 | } | ||
563 | |||
564 | |||
565 | AudioFileManager *new_AudioFileManager(AudioFilePlayer *inParent, | ||
566 | SInt16 inForkRefNum, | ||
567 | SInt64 inFileLength, | ||
568 | UInt32 inChunkSize) | ||
569 | { | ||
570 | AudioFileManager *afm; | ||
571 | |||
572 | if (sReaderThread == NULL) | ||
573 | { | ||
574 | sReaderThread = new_FileReaderThread(); | ||
575 | if (sReaderThread == NULL) | ||
576 | return NULL; | ||
577 | } | ||
578 | |||
579 | afm = (AudioFileManager *) SDL_malloc(sizeof (AudioFileManager)); | ||
580 | if (afm == NULL) | ||
581 | return NULL; | ||
582 | SDL_memset(afm, '\0', sizeof (*afm)); | ||
583 | |||
584 | #define SET_AUDIOFILEMANAGER_METHOD(m) afm->m = AudioFileManager_##m | ||
585 | SET_AUDIOFILEMANAGER_METHOD(Disconnect); | ||
586 | SET_AUDIOFILEMANAGER_METHOD(DoConnect); | ||
587 | SET_AUDIOFILEMANAGER_METHOD(Read); | ||
588 | SET_AUDIOFILEMANAGER_METHOD(GetFileBuffer); | ||
589 | SET_AUDIOFILEMANAGER_METHOD(GetParent); | ||
590 | SET_AUDIOFILEMANAGER_METHOD(SetPosition); | ||
591 | SET_AUDIOFILEMANAGER_METHOD(GetByteCounter); | ||
592 | SET_AUDIOFILEMANAGER_METHOD(SetEndOfFile); | ||
593 | SET_AUDIOFILEMANAGER_METHOD(Render); | ||
594 | SET_AUDIOFILEMANAGER_METHOD(GetFileData); | ||
595 | SET_AUDIOFILEMANAGER_METHOD(AfterRender); | ||
596 | SET_AUDIOFILEMANAGER_METHOD(FileInputProc); | ||
597 | #undef SET_AUDIOFILEMANAGER_METHOD | ||
598 | |||
599 | afm->mParent = inParent; | ||
600 | afm->mForkRefNum = inForkRefNum; | ||
601 | afm->mBufferSize = inChunkSize; | ||
602 | afm->mBufferOffset = inChunkSize; | ||
603 | afm->mChunkSize = inChunkSize; | ||
604 | afm->mFileLength = inFileLength; | ||
605 | afm->mFileBuffer = (char*) SDL_malloc(afm->mChunkSize * 2); | ||
606 | FSGetForkPosition(afm->mForkRefNum, &afm->mAudioDataOffset); | ||
607 | assert (afm->mFileBuffer != NULL); | ||
608 | return afm; | ||
609 | } | ||
610 | |||