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

Latest commit

 

History

History
659 lines (546 loc) · 19.3 KB

AudioFileReaderThread.c

File metadata and controls

659 lines (546 loc) · 19.3 KB
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
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
338
339
340
341
342
/* construct pointer */
char *writePtr = (char *) (theItem->GetFileBuffer(theItem) +
(theItem->
mWriteToFirstBuffer ? 0 : theItem->
mChunkSize));
/* read data */
343
344
result = theItem->Read(theItem, writePtr, &dataChunkSize);
if (result != noErr && result != eofErr) {
Jul 10, 2006
Jul 10, 2006
345
346
AudioFilePlayer *afp =
(AudioFilePlayer *) theItem->GetParent(theItem);
347
348
349
afp->DoNotification(afp, result);
continue;
}
Jul 10, 2006
Jul 10, 2006
350
351
if (dataChunkSize != theItem->mChunkSize) {
352
353
writePtr += dataChunkSize;
Mar 9, 2006
Mar 9, 2006
354
355
/* 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
357
Mar 9, 2006
Mar 9, 2006
358
theItem->mWriteToFirstBuffer = !theItem->mWriteToFirstBuffer; /* switch buffers */
Jul 10, 2006
Jul 10, 2006
359
360
361
362
if (result == eofErr)
theItem->mReadFilePosition = theItem->mFileLength;
else
Mar 9, 2006
Mar 9, 2006
363
theItem->mReadFilePosition += dataChunkSize; /* increment count */
Jul 10, 2006
Jul 10, 2006
367
368
void
delete_FileReaderThread(FileReaderThread * frt)
Jul 10, 2006
Jul 10, 2006
370
if (frt != NULL) {
371
delete_SDLOSXCAGuard(frt->mGuard);
Feb 7, 2006
Feb 7, 2006
372
SDL_free(frt);
Jul 10, 2006
Jul 10, 2006
376
377
FileReaderThread *
new_FileReaderThread()
Jul 10, 2006
Jul 10, 2006
379
380
FileReaderThread *frt =
(FileReaderThread *) SDL_malloc(sizeof(FileReaderThread));
381
382
if (frt == NULL)
return NULL;
Jul 10, 2006
Jul 10, 2006
383
SDL_memset(frt, '\0', sizeof(*frt));
384
385
frt->mGuard = new_SDLOSXCAGuard();
Jul 10, 2006
Jul 10, 2006
386
if (frt->mGuard == NULL) {
Feb 7, 2006
Feb 7, 2006
387
SDL_free(frt);
Jul 10, 2006
Jul 10, 2006
390
#define SET_FILEREADERTHREAD_METHOD(m) frt->m = FileReaderThread_##m
391
392
393
394
395
396
397
398
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
399
#undef SET_FILEREADERTHREAD_METHOD
400
401
402
403
404
405
406
407
408
frt->mThreadPriority = 62;
return frt;
}
static FileReaderThread *sReaderThread;
Jul 10, 2006
Jul 10, 2006
409
410
static int
AudioFileManager_DoConnect(AudioFileManager * afm)
Jul 10, 2006
Jul 10, 2006
412
if (!afm->mIsEngaged) {
Mar 9, 2006
Mar 9, 2006
413
414
OSStatus result;
Jul 10, 2006
Jul 10, 2006
415
/*afm->mReadFilePosition = 0; */
416
417
418
419
afm->mFinishedReadingData = 0;
afm->mNumTimesAskedSinceFinished = 0;
afm->mLockUnsuccessful = 0;
Jul 10, 2006
Jul 10, 2006
420
421
UInt32 dataChunkSize;
Jul 10, 2006
Jul 10, 2006
422
423
424
425
426
if ((afm->mFileLength - afm->mReadFilePosition) < afm->mChunkSize)
dataChunkSize = afm->mFileLength - afm->mReadFilePosition;
else
dataChunkSize = afm->mChunkSize;
Jul 10, 2006
Jul 10, 2006
427
428
result = afm->Read(afm, afm->mFileBuffer, &dataChunkSize);
Jul 10, 2006
Jul 10, 2006
429
430
if (result)
return 0; /*THROW_RESULT("AudioFileManager::DoConnect(): Read") */
431
432
afm->mReadFilePosition += dataChunkSize;
Jul 10, 2006
Jul 10, 2006
433
434
435
436
437
afm->mWriteToFirstBuffer = 0;
afm->mReadFromFirstBuffer = 1;
sReaderThread->AddReader(sReaderThread);
Jul 10, 2006
Jul 10, 2006
438
439
440
afm->mIsEngaged = 1;
}
Mar 9, 2006
Mar 9, 2006
441
/*
Jul 10, 2006
Jul 10, 2006
442
443
else
throw static_cast<OSStatus>(-1); *//* thread has already been started */
444
445
446
447
return 1;
}
Jul 10, 2006
Jul 10, 2006
448
449
static void
AudioFileManager_Disconnect(AudioFileManager * afm)
Jul 10, 2006
Jul 10, 2006
451
452
if (afm->mIsEngaged) {
sReaderThread->RemoveReader(sReaderThread, afm);
453
454
455
456
afm->mIsEngaged = 0;
}
}
Jul 10, 2006
Jul 10, 2006
457
458
static OSStatus
AudioFileManager_Read(AudioFileManager * afm, char *buffer, UInt32 * len)
Jul 10, 2006
Jul 10, 2006
460
461
462
463
return FSReadFork(afm->mForkRefNum,
fsFromStart,
afm->mReadFilePosition + afm->mAudioDataOffset,
*len, buffer, len);
Jul 10, 2006
Jul 10, 2006
466
467
468
static OSStatus
AudioFileManager_GetFileData(AudioFileManager * afm, void **inOutData,
UInt32 * inOutDataSize)
Jul 10, 2006
Jul 10, 2006
470
if (afm->mFinishedReadingData) {
471
472
473
474
475
++afm->mNumTimesAskedSinceFinished;
*inOutDataSize = 0;
*inOutData = 0;
return noErr;
}
Jul 10, 2006
Jul 10, 2006
476
477
if (afm->mReadFromFirstBuffer == afm->mWriteToFirstBuffer) {
Jul 10, 2006
Jul 10, 2006
478
479
480
481
482
483
#if DEBUG
printf("* * * * * * * Can't keep up with reading file\n");
#endif
afm->mParent->DoNotification(afm->mParent,
kAudioFilePlayErr_FilePlayUnderrun);
484
485
486
487
*inOutDataSize = 0;
*inOutData = 0;
} else {
*inOutDataSize = afm->mChunkSize;
Jul 10, 2006
Jul 10, 2006
488
489
490
491
*inOutData =
afm->mReadFromFirstBuffer ? afm->mFileBuffer : (afm->
mFileBuffer +
afm->mChunkSize);
Jul 10, 2006
Jul 10, 2006
494
495
afm->mLockUnsuccessful = !sReaderThread->TryNextRead(sReaderThread, afm);
496
497
498
499
500
afm->mReadFromFirstBuffer = !afm->mReadFromFirstBuffer;
return noErr;
}
Jul 10, 2006
Jul 10, 2006
501
502
static void
AudioFileManager_AfterRender(AudioFileManager * afm)
Jul 10, 2006
Jul 10, 2006
504
if (afm->mNumTimesAskedSinceFinished > 0) {
505
506
507
int didLock = 0;
SDLOSXCAGuard *guard = sReaderThread->GetGuard(sReaderThread);
if (guard->Try(guard, &didLock)) {
Jul 10, 2006
Jul 10, 2006
508
509
afm->mParent->DoNotification(afm->mParent,
kAudioFilePlay_FileIsFinished);
510
511
512
513
514
515
if (didLock)
guard->Unlock(guard);
}
}
if (afm->mLockUnsuccessful)
Jul 10, 2006
Jul 10, 2006
516
517
afm->mLockUnsuccessful =
!sReaderThread->TryNextRead(sReaderThread, afm);
Jul 10, 2006
Jul 10, 2006
520
521
static void
AudioFileManager_SetPosition(AudioFileManager * afm, SInt64 pos)
522
523
{
if (pos < 0 || pos >= afm->mFileLength) {
Jul 10, 2006
Jul 10, 2006
524
525
526
SDL_SetError
("AudioFileManager::SetPosition - position invalid: %d filelen=%d\n",
(unsigned int) pos, (unsigned int) afm->mFileLength);
Jul 10, 2006
Jul 10, 2006
529
530
531
afm->mReadFilePosition = pos;
}
Jul 10, 2006
Jul 10, 2006
532
533
534
static void
AudioFileManager_SetEndOfFile(AudioFileManager * afm, SInt64 pos)
535
536
{
if (pos <= 0 || pos > afm->mFileLength) {
Jul 10, 2006
Jul 10, 2006
537
538
SDL_SetError
("AudioFileManager::SetEndOfFile - position beyond actual eof\n");
539
540
pos = afm->mFileLength;
}
Jul 10, 2006
Jul 10, 2006
541
542
543
544
afm->mFileLength = pos;
}
Jul 10, 2006
Jul 10, 2006
545
546
static const char *
AudioFileManager_GetFileBuffer(AudioFileManager * afm)
547
548
549
550
{
return afm->mFileBuffer;
}
Jul 10, 2006
Jul 10, 2006
551
552
const AudioFilePlayer *
AudioFileManager_GetParent(AudioFileManager * afm)
553
554
555
556
{
return afm->mParent;
}
Jul 10, 2006
Jul 10, 2006
557
558
static int
AudioFileManager_GetByteCounter(AudioFileManager * afm)
559
560
561
562
563
{
return afm->mByteCounter;
}
Jul 10, 2006
Jul 10, 2006
564
565
566
567
568
static OSStatus
AudioFileManager_FileInputProc(void *inRefCon,
AudioUnitRenderActionFlags inActionFlags,
const AudioTimeStamp * inTimeStamp,
UInt32 inBusNumber, AudioBuffer * ioData)
Jul 10, 2006
Jul 10, 2006
570
AudioFileManager *afm = (AudioFileManager *) inRefCon;
571
572
573
return afm->Render(afm, ioData);
}
Jul 10, 2006
Jul 10, 2006
574
575
static OSStatus
AudioFileManager_Render(AudioFileManager * afm, AudioBuffer * ioData)
576
577
{
OSStatus result = noErr;
Jul 10, 2006
Jul 10, 2006
578
579
580
581
582
583
584
585
586
587
588
589
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;
}
590
if (ioData->mDataByteSize > afm->mBufferSize - afm->mBufferOffset)
Jul 10, 2006
Jul 10, 2006
591
592
ioData->mDataByteSize = afm->mBufferSize - afm->mBufferOffset;
ioData->mData = (char *) afm->mTmpBuffer + afm->mBufferOffset;
593
afm->mBufferOffset += ioData->mDataByteSize;
Jul 10, 2006
Jul 10, 2006
594
595
596
afm->mByteCounter += ioData->mDataByteSize;
afm->AfterRender(afm);
597
598
599
600
return result;
}
Jul 10, 2006
Jul 10, 2006
601
602
void
delete_AudioFileManager(AudioFileManager * afm)
603
604
605
{
if (afm != NULL) {
if (afm->mFileBuffer) {
Feb 7, 2006
Feb 7, 2006
606
free(afm->mFileBuffer);
Feb 7, 2006
Feb 7, 2006
609
SDL_free(afm);
Jul 10, 2006
Jul 10, 2006
614
615
616
617
AudioFileManager *
new_AudioFileManager(AudioFilePlayer * inParent,
SInt16 inForkRefNum,
SInt64 inFileLength, UInt32 inChunkSize)
618
619
620
{
AudioFileManager *afm;
Jul 10, 2006
Jul 10, 2006
621
if (sReaderThread == NULL) {
622
623
624
625
626
sReaderThread = new_FileReaderThread();
if (sReaderThread == NULL)
return NULL;
}
Jul 10, 2006
Jul 10, 2006
627
afm = (AudioFileManager *) SDL_malloc(sizeof(AudioFileManager));
628
629
if (afm == NULL)
return NULL;
Jul 10, 2006
Jul 10, 2006
630
SDL_memset(afm, '\0', sizeof(*afm));
Jul 10, 2006
Jul 10, 2006
632
#define SET_AUDIOFILEMANAGER_METHOD(m) afm->m = AudioFileManager_##m
633
634
635
636
637
638
639
640
641
642
643
644
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
645
#undef SET_AUDIOFILEMANAGER_METHOD
646
647
648
649
650
651
652
afm->mParent = inParent;
afm->mForkRefNum = inForkRefNum;
afm->mBufferSize = inChunkSize;
afm->mBufferOffset = inChunkSize;
afm->mChunkSize = inChunkSize;
afm->mFileLength = inFileLength;
Jul 10, 2006
Jul 10, 2006
653
afm->mFileBuffer = (char *) SDL_malloc(afm->mChunkSize * 2);
654
FSGetForkPosition(afm->mForkRefNum, &afm->mAudioDataOffset);
Jul 10, 2006
Jul 10, 2006
655
assert(afm->mFileBuffer != NULL);
Jul 10, 2006
Jul 10, 2006
659
/* vi: set ts=4 sw=4 expandtab: */