Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Latest commit

 

History

History
657 lines (544 loc) · 19.2 KB

AudioFileReaderThread.c

File metadata and controls

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