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"
May 28, 2006
May 28, 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;
May 28, 2006
May 28, 2006
45
46
typedef struct S_FileReaderThread
{
Mar 9, 2006
Mar 9, 2006
47
/*public:*/
May 28, 2006
May 28, 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:*/
May 28, 2006
May 28, 2006
58
/*typedef std::list<AudioFileManager*> FileData; */
May 28, 2006
May 28, 2006
60
61
SDLOSXCAGuard *mGuard;
UInt32 mThreadPriority;
May 28, 2006
May 28, 2006
63
64
int mNumReaders;
FileData *mFileData;
May 28, 2006
May 28, 2006
66
67
68
69
void (*ReadNextChunk) (struct S_FileReaderThread * frt);
int (*StartFixedPriorityThread) (struct S_FileReaderThread * frt);
/*static */
May 29, 2006
May 29, 2006
70
UInt32(*GetThreadBasePriority) (pthread_t inThread);
May 28, 2006
May 28, 2006
71
72
/*static */
void *(*DiskReaderEntry) (void *inRefCon);
73
74
75
} FileReaderThread;
May 28, 2006
May 28, 2006
76
static SDLOSXCAGuard *
May 29, 2006
May 29, 2006
77
FileReaderThread_GetGuard(FileReaderThread * frt)
78
79
80
81
{
return frt->mGuard;
}
Mar 9, 2006
Mar 9, 2006
82
/* returns 1 if succeeded */
May 28, 2006
May 28, 2006
83
static int
May 29, 2006
May 29, 2006
84
85
FileReaderThread_TryNextRead(FileReaderThread * frt,
AudioFileManager * inItem)
86
87
88
{
int didLock = 0;
int succeeded = 0;
May 29, 2006
May 29, 2006
89
if (frt->mGuard->Try(frt->mGuard, &didLock)) {
May 28, 2006
May 28, 2006
90
/*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;
May 29, 2006
May 29, 2006
95
FileData *newfd = (FileData *) SDL_malloc(sizeof(FileData));
96
97
98
newfd->obj = inItem;
newfd->next = NULL;
May 28, 2006
May 28, 2006
99
100
101
102
while (i != NULL) {
prev = i;
i = i->next;
}
103
104
105
106
107
if (prev == NULL)
frt->mFileData = newfd;
else
prev->next = newfd;
May 29, 2006
May 29, 2006
108
frt->mGuard->Notify(frt->mGuard);
109
110
111
succeeded = 1;
if (didLock)
May 29, 2006
May 29, 2006
112
frt->mGuard->Unlock(frt->mGuard);
May 28, 2006
May 28, 2006
114
115
116
117
return succeeded;
}
May 28, 2006
May 28, 2006
118
static void
May 29, 2006
May 29, 2006
119
FileReaderThread_AddReader(FileReaderThread * frt)
May 28, 2006
May 28, 2006
121
if (frt->mNumReaders == 0) {
122
frt->mThreadShouldDie = 0;
May 29, 2006
May 29, 2006
123
frt->StartFixedPriorityThread(frt);
124
125
126
127
}
frt->mNumReaders++;
}
May 28, 2006
May 28, 2006
128
static void
May 29, 2006
May 29, 2006
129
130
FileReaderThread_RemoveReader(FileReaderThread * frt,
AudioFileManager * inItem)
May 28, 2006
May 28, 2006
132
if (frt->mNumReaders > 0) {
May 29, 2006
May 29, 2006
133
int bNeedsRelease = frt->mGuard->Lock(frt->mGuard);
May 28, 2006
May 28, 2006
134
135
/*frt->mFileData.remove (inItem); */
136
137
FileData *i = frt->mFileData;
FileData *prev = NULL;
May 28, 2006
May 28, 2006
138
while (i != NULL) {
139
140
141
FileData *next = i->next;
if (i->obj != inItem)
prev = i;
May 28, 2006
May 28, 2006
142
else {
143
144
145
146
if (prev == NULL)
frt->mFileData = next;
else
prev->next = next;
May 29, 2006
May 29, 2006
147
SDL_free(i);
148
149
150
151
152
153
}
i = next;
}
if (--frt->mNumReaders == 0) {
frt->mThreadShouldDie = 1;
May 29, 2006
May 29, 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 */
May 28, 2006
May 28, 2006
158
if (bNeedsRelease)
May 29, 2006
May 29, 2006
159
frt->mGuard->Unlock(frt->mGuard);
May 28, 2006
May 28, 2006
160
}
May 28, 2006
May 28, 2006
163
static int
May 29, 2006
May 29, 2006
164
FileReaderThread_StartFixedPriorityThread(FileReaderThread * frt)
May 28, 2006
May 28, 2006
166
167
168
pthread_attr_t theThreadAttrs;
pthread_t pThread;
May 29, 2006
May 29, 2006
169
OSStatus result = pthread_attr_init(&theThreadAttrs);
May 28, 2006
May 28, 2006
170
171
172
173
if (result)
return 0; /*THROW_RESULT("pthread_attr_init - Thread attributes could not be created.") */
result =
May 29, 2006
May 29, 2006
174
pthread_attr_setdetachstate(&theThreadAttrs, PTHREAD_CREATE_DETACHED);
May 28, 2006
May 28, 2006
175
176
177
178
if (result)
return 0; /*THROW_RESULT("pthread_attr_setdetachstate - Thread attributes could not be detached.") */
result =
May 29, 2006
May 29, 2006
179
pthread_create(&pThread, &theThreadAttrs, frt->DiskReaderEntry, frt);
May 28, 2006
May 28, 2006
180
181
182
if (result)
return 0; /*THROW_RESULT("pthread_create - Create and start the thread.") */
May 29, 2006
May 29, 2006
183
pthread_attr_destroy(&theThreadAttrs);
May 28, 2006
May 28, 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 */
May 28, 2006
May 28, 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 */
May 28, 2006
May 28, 2006
193
194
theFixedPolicy.timeshare = 0; /* set to 1 for a non-fixed thread */
result =
May 29, 2006
May 29, 2006
195
196
197
198
thread_policy_set(pthread_mach_thread_np(pThread),
THREAD_EXTENDED_POLICY,
(thread_policy_t) & theFixedPolicy,
THREAD_EXTENDED_POLICY_COUNT);
May 28, 2006
May 28, 2006
199
200
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 */
May 28, 2006
May 28, 2006
203
relativePriority =
May 29, 2006
May 29, 2006
204
frt->mThreadPriority - frt->GetThreadBasePriority(pthread_self());
May 28, 2006
May 28, 2006
205
206
thePrecedencePolicy.importance = relativePriority;
May 28, 2006
May 28, 2006
207
result =
May 29, 2006
May 29, 2006
208
209
210
211
thread_policy_set(pthread_mach_thread_np(pThread),
THREAD_PRECEDENCE_POLICY,
(thread_policy_t) & thePrecedencePolicy,
THREAD_PRECEDENCE_POLICY_COUNT);
May 28, 2006
May 28, 2006
212
213
if (result)
return 0; /*THROW_RESULT("thread_policy - Couldn't set thread priority.") */
214
215
216
217
return 1;
}
May 28, 2006
May 28, 2006
218
static UInt32
May 29, 2006
May 29, 2006
219
FileReaderThread_GetThreadBasePriority(pthread_t inThread)
May 28, 2006
May 28, 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;
May 29, 2006
May 29, 2006
227
228
thread_info(pthread_mach_thread_np(inThread), THREAD_BASIC_INFO,
(integer_t *) & threadInfo, &count);
May 28, 2006
May 28, 2006
229
230
switch (threadInfo.policy) {
May 28, 2006
May 28, 2006
231
232
case POLICY_TIMESHARE:
count = POLICY_TIMESHARE_INFO_COUNT;
May 29, 2006
May 29, 2006
233
234
235
thread_info(pthread_mach_thread_np(inThread),
THREAD_SCHED_TIMESHARE_INFO,
(integer_t *) & (thePolicyInfo.ts), &count);
May 28, 2006
May 28, 2006
236
237
238
239
240
return thePolicyInfo.ts.base_priority;
break;
case POLICY_FIFO:
count = POLICY_FIFO_INFO_COUNT;
May 29, 2006
May 29, 2006
241
242
243
thread_info(pthread_mach_thread_np(inThread),
THREAD_SCHED_FIFO_INFO,
(integer_t *) & (thePolicyInfo.fifo), &count);
May 28, 2006
May 28, 2006
244
245
246
247
248
249
250
251
252
if (thePolicyInfo.fifo.depressed) {
return thePolicyInfo.fifo.depress_priority;
} else {
return thePolicyInfo.fifo.base_priority;
}
break;
case POLICY_RR:
count = POLICY_RR_INFO_COUNT;
May 29, 2006
May 29, 2006
253
254
255
thread_info(pthread_mach_thread_np(inThread),
THREAD_SCHED_RR_INFO,
(integer_t *) & (thePolicyInfo.rr), &count);
May 28, 2006
May 28, 2006
256
257
258
259
260
261
if (thePolicyInfo.rr.depressed) {
return thePolicyInfo.rr.depress_priority;
} else {
return thePolicyInfo.rr.base_priority;
}
break;
May 28, 2006
May 28, 2006
263
May 28, 2006
May 28, 2006
267
static void *
May 29, 2006
May 29, 2006
268
FileReaderThread_DiskReaderEntry(void *inRefCon)
May 28, 2006
May 28, 2006
270
FileReaderThread *frt = (FileReaderThread *) inRefCon;
May 29, 2006
May 29, 2006
271
frt->ReadNextChunk(frt);
May 28, 2006
May 28, 2006
272
#if DEBUG
May 29, 2006
May 29, 2006
273
printf("finished with reading file\n");
May 28, 2006
May 28, 2006
274
275
#endif
May 28, 2006
May 28, 2006
279
static void
May 29, 2006
May 29, 2006
280
FileReaderThread_ReadNextChunk(FileReaderThread * frt)
281
282
{
OSStatus result;
May 28, 2006
May 28, 2006
283
284
285
286
287
UInt32 dataChunkSize;
AudioFileManager *theItem = 0;
for (;;) {
{ /* this is a scoped based lock */
May 29, 2006
May 29, 2006
288
int bNeedsRelease = frt->mGuard->Lock(frt->mGuard);
May 28, 2006
May 28, 2006
289
290
if (frt->mThreadShouldDie) {
May 29, 2006
May 29, 2006
291
frt->mGuard->Notify(frt->mGuard);
May 28, 2006
May 28, 2006
292
if (bNeedsRelease)
May 29, 2006
May 29, 2006
293
frt->mGuard->Unlock(frt->mGuard);
May 28, 2006
May 28, 2006
296
297
298
/*if (frt->mFileData.empty()) */
if (frt->mFileData == NULL) {
May 29, 2006
May 29, 2006
299
frt->mGuard->Wait(frt->mGuard);
May 28, 2006
May 28, 2006
301
Mar 9, 2006
Mar 9, 2006
302
/* kill thread */
303
if (frt->mThreadShouldDie) {
May 28, 2006
May 28, 2006
304
May 29, 2006
May 29, 2006
305
frt->mGuard->Notify(frt->mGuard);
May 28, 2006
May 28, 2006
306
if (bNeedsRelease)
May 29, 2006
May 29, 2006
307
frt->mGuard->Unlock(frt->mGuard);
May 28, 2006
May 28, 2006
311
312
/*theItem = frt->mFileData.front(); */
/*frt->mFileData.pop_front(); */
May 28, 2006
May 28, 2006
314
if (frt->mFileData != NULL) {
315
316
FileData *next = frt->mFileData->next;
theItem = frt->mFileData->obj;
May 29, 2006
May 29, 2006
317
SDL_free(frt->mFileData);
318
319
320
frt->mFileData = next;
}
May 28, 2006
May 28, 2006
321
if (bNeedsRelease)
May 29, 2006
May 29, 2006
322
frt->mGuard->Unlock(frt->mGuard);
May 28, 2006
May 28, 2006
324
325
326
if ((theItem->mFileLength - theItem->mReadFilePosition) <
theItem->mChunkSize)
327
328
329
dataChunkSize = theItem->mFileLength - theItem->mReadFilePosition;
else
dataChunkSize = theItem->mChunkSize;
May 28, 2006
May 28, 2006
330
331
/* this is the exit condition for the thread */
332
333
334
335
if (dataChunkSize <= 0) {
theItem->mFinishedReadingData = 1;
continue;
}
May 28, 2006
May 28, 2006
336
/* construct pointer */
May 29, 2006
May 29, 2006
337
char *writePtr = (char *) (theItem->GetFileBuffer(theItem) +
May 28, 2006
May 28, 2006
338
339
340
341
342
(theItem->
mWriteToFirstBuffer ? 0 : theItem->
mChunkSize));
/* read data */
May 29, 2006
May 29, 2006
343
result = theItem->Read(theItem, writePtr, &dataChunkSize);
344
if (result != noErr && result != eofErr) {
May 28, 2006
May 28, 2006
345
AudioFilePlayer *afp =
May 29, 2006
May 29, 2006
346
347
(AudioFilePlayer *) theItem->GetParent(theItem);
afp->DoNotification(afp, result);
May 28, 2006
May 28, 2006
350
351
if (dataChunkSize != theItem->mChunkSize) {
352
353
writePtr += dataChunkSize;
Mar 9, 2006
Mar 9, 2006
354
/* can't exit yet.. we still have to pass the partial buffer back */
May 29, 2006
May 29, 2006
355
SDL_memset(writePtr, 0, (theItem->mChunkSize - dataChunkSize));
May 28, 2006
May 28, 2006
357
Mar 9, 2006
Mar 9, 2006
358
theItem->mWriteToFirstBuffer = !theItem->mWriteToFirstBuffer; /* switch buffers */
May 28, 2006
May 28, 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 */
May 28, 2006
May 28, 2006
367
void
May 29, 2006
May 29, 2006
368
delete_FileReaderThread(FileReaderThread * frt)
May 28, 2006
May 28, 2006
370
if (frt != NULL) {
May 29, 2006
May 29, 2006
371
372
delete_SDLOSXCAGuard(frt->mGuard);
SDL_free(frt);
May 28, 2006
May 28, 2006
376
FileReaderThread *
May 29, 2006
May 29, 2006
377
new_FileReaderThread()
May 28, 2006
May 28, 2006
379
FileReaderThread *frt =
May 29, 2006
May 29, 2006
380
(FileReaderThread *) SDL_malloc(sizeof(FileReaderThread));
381
382
if (frt == NULL)
return NULL;
May 29, 2006
May 29, 2006
383
SDL_memset(frt, '\0', sizeof(*frt));
May 29, 2006
May 29, 2006
385
frt->mGuard = new_SDLOSXCAGuard();
May 28, 2006
May 28, 2006
386
if (frt->mGuard == NULL) {
May 29, 2006
May 29, 2006
387
SDL_free(frt);
May 28, 2006
May 28, 2006
390
#define SET_FILEREADERTHREAD_METHOD(m) frt->m = FileReaderThread_##m
May 29, 2006
May 29, 2006
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);
May 28, 2006
May 28, 2006
399
#undef SET_FILEREADERTHREAD_METHOD
400
401
402
403
404
405
406
407
408
frt->mThreadPriority = 62;
return frt;
}
static FileReaderThread *sReaderThread;
May 28, 2006
May 28, 2006
409
static int
May 29, 2006
May 29, 2006
410
AudioFileManager_DoConnect(AudioFileManager * afm)
May 28, 2006
May 28, 2006
412
if (!afm->mIsEngaged) {
Mar 9, 2006
Mar 9, 2006
413
414
OSStatus result;
May 28, 2006
May 28, 2006
415
/*afm->mReadFilePosition = 0; */
416
417
418
419
afm->mFinishedReadingData = 0;
afm->mNumTimesAskedSinceFinished = 0;
afm->mLockUnsuccessful = 0;
May 28, 2006
May 28, 2006
420
421
UInt32 dataChunkSize;
May 28, 2006
May 28, 2006
422
423
424
425
426
if ((afm->mFileLength - afm->mReadFilePosition) < afm->mChunkSize)
dataChunkSize = afm->mFileLength - afm->mReadFilePosition;
else
dataChunkSize = afm->mChunkSize;
May 28, 2006
May 28, 2006
427
May 29, 2006
May 29, 2006
428
result = afm->Read(afm, afm->mFileBuffer, &dataChunkSize);
May 28, 2006
May 28, 2006
429
430
if (result)
return 0; /*THROW_RESULT("AudioFileManager::DoConnect(): Read") */
431
432
afm->mReadFilePosition += dataChunkSize;
May 28, 2006
May 28, 2006
433
434
435
436
afm->mWriteToFirstBuffer = 0;
afm->mReadFromFirstBuffer = 1;
May 29, 2006
May 29, 2006
437
sReaderThread->AddReader(sReaderThread);
May 28, 2006
May 28, 2006
438
439
440
afm->mIsEngaged = 1;
}
Mar 9, 2006
Mar 9, 2006
441
/*
May 28, 2006
May 28, 2006
442
443
else
throw static_cast<OSStatus>(-1); *//* thread has already been started */
444
445
446
447
return 1;
}
May 28, 2006
May 28, 2006
448
static void
May 29, 2006
May 29, 2006
449
AudioFileManager_Disconnect(AudioFileManager * afm)
May 28, 2006
May 28, 2006
451
if (afm->mIsEngaged) {
May 29, 2006
May 29, 2006
452
sReaderThread->RemoveReader(sReaderThread, afm);
453
454
455
456
afm->mIsEngaged = 0;
}
}
May 28, 2006
May 28, 2006
457
static OSStatus
May 29, 2006
May 29, 2006
458
AudioFileManager_Read(AudioFileManager * afm, char *buffer, UInt32 * len)
May 29, 2006
May 29, 2006
460
461
462
463
return FSReadFork(afm->mForkRefNum,
fsFromStart,
afm->mReadFilePosition + afm->mAudioDataOffset,
*len, buffer, len);
May 28, 2006
May 28, 2006
466
static OSStatus
May 29, 2006
May 29, 2006
467
468
AudioFileManager_GetFileData(AudioFileManager * afm, void **inOutData,
UInt32 * inOutDataSize)
May 28, 2006
May 28, 2006
470
if (afm->mFinishedReadingData) {
471
472
473
474
475
++afm->mNumTimesAskedSinceFinished;
*inOutDataSize = 0;
*inOutData = 0;
return noErr;
}
May 28, 2006
May 28, 2006
476
477
if (afm->mReadFromFirstBuffer == afm->mWriteToFirstBuffer) {
May 28, 2006
May 28, 2006
478
#if DEBUG
May 29, 2006
May 29, 2006
479
printf("* * * * * * * Can't keep up with reading file\n");
May 28, 2006
May 28, 2006
480
481
#endif
May 29, 2006
May 29, 2006
482
483
afm->mParent->DoNotification(afm->mParent,
kAudioFilePlayErr_FilePlayUnderrun);
484
485
486
487
*inOutDataSize = 0;
*inOutData = 0;
} else {
*inOutDataSize = afm->mChunkSize;
May 28, 2006
May 28, 2006
488
489
490
491
*inOutData =
afm->mReadFromFirstBuffer ? afm->mFileBuffer : (afm->
mFileBuffer +
afm->mChunkSize);
May 29, 2006
May 29, 2006
494
afm->mLockUnsuccessful = !sReaderThread->TryNextRead(sReaderThread, afm);
May 28, 2006
May 28, 2006
495
496
497
498
499
500
afm->mReadFromFirstBuffer = !afm->mReadFromFirstBuffer;
return noErr;
}
May 28, 2006
May 28, 2006
501
static void
May 29, 2006
May 29, 2006
502
AudioFileManager_AfterRender(AudioFileManager * afm)
May 28, 2006
May 28, 2006
504
if (afm->mNumTimesAskedSinceFinished > 0) {
May 29, 2006
May 29, 2006
506
507
508
509
SDLOSXCAGuard *guard = sReaderThread->GetGuard(sReaderThread);
if (guard->Try(guard, &didLock)) {
afm->mParent->DoNotification(afm->mParent,
kAudioFilePlay_FileIsFinished);
May 29, 2006
May 29, 2006
511
guard->Unlock(guard);
512
513
514
515
}
}
if (afm->mLockUnsuccessful)
May 28, 2006
May 28, 2006
516
afm->mLockUnsuccessful =
May 29, 2006
May 29, 2006
517
!sReaderThread->TryNextRead(sReaderThread, afm);
May 28, 2006
May 28, 2006
520
static void
May 29, 2006
May 29, 2006
521
AudioFileManager_SetPosition(AudioFileManager * afm, SInt64 pos)
522
523
{
if (pos < 0 || pos >= afm->mFileLength) {
May 28, 2006
May 28, 2006
524
525
526
SDL_SetError
("AudioFileManager::SetPosition - position invalid: %d filelen=%d\n",
(unsigned int) pos, (unsigned int) afm->mFileLength);
May 28, 2006
May 28, 2006
529
530
531
afm->mReadFilePosition = pos;
}
May 28, 2006
May 28, 2006
532
533
static void
May 29, 2006
May 29, 2006
534
AudioFileManager_SetEndOfFile(AudioFileManager * afm, SInt64 pos)
535
536
{
if (pos <= 0 || pos > afm->mFileLength) {
May 28, 2006
May 28, 2006
537
538
SDL_SetError
("AudioFileManager::SetEndOfFile - position beyond actual eof\n");
539
540
pos = afm->mFileLength;
}
May 28, 2006
May 28, 2006
541
542
543
544
afm->mFileLength = pos;
}
May 28, 2006
May 28, 2006
545
static const char *
May 29, 2006
May 29, 2006
546
AudioFileManager_GetFileBuffer(AudioFileManager * afm)
547
548
549
550
{
return afm->mFileBuffer;
}
May 28, 2006
May 28, 2006
551
const AudioFilePlayer *
May 29, 2006
May 29, 2006
552
AudioFileManager_GetParent(AudioFileManager * afm)
553
554
555
556
{
return afm->mParent;
}
May 28, 2006
May 28, 2006
557
static int
May 29, 2006
May 29, 2006
558
AudioFileManager_GetByteCounter(AudioFileManager * afm)
559
560
561
562
563
{
return afm->mByteCounter;
}
May 28, 2006
May 28, 2006
564
static OSStatus
May 29, 2006
May 29, 2006
565
566
567
568
AudioFileManager_FileInputProc(void *inRefCon,
AudioUnitRenderActionFlags inActionFlags,
const AudioTimeStamp * inTimeStamp,
UInt32 inBusNumber, AudioBuffer * ioData)
May 28, 2006
May 28, 2006
570
AudioFileManager *afm = (AudioFileManager *) inRefCon;
May 29, 2006
May 29, 2006
571
return afm->Render(afm, ioData);
May 28, 2006
May 28, 2006
574
static OSStatus
May 29, 2006
May 29, 2006
575
AudioFileManager_Render(AudioFileManager * afm, AudioBuffer * ioData)
576
577
{
OSStatus result = noErr;
May 28, 2006
May 28, 2006
578
579
if (afm->mBufferOffset >= afm->mBufferSize) {
May 29, 2006
May 29, 2006
580
result = afm->GetFileData(afm, &afm->mTmpBuffer, &afm->mBufferSize);
May 28, 2006
May 28, 2006
581
if (result) {
May 29, 2006
May 29, 2006
582
583
SDL_SetError("AudioConverterFillBuffer:%ld\n", result);
afm->mParent->DoNotification(afm->mParent, result);
May 28, 2006
May 28, 2006
584
585
586
587
588
589
return result;
}
afm->mBufferOffset = 0;
}
590
if (ioData->mDataByteSize > afm->mBufferSize - afm->mBufferOffset)
May 28, 2006
May 28, 2006
591
592
ioData->mDataByteSize = afm->mBufferSize - afm->mBufferOffset;
ioData->mData = (char *) afm->mTmpBuffer + afm->mBufferOffset;
593
afm->mBufferOffset += ioData->mDataByteSize;
May 28, 2006
May 28, 2006
594
595
afm->mByteCounter += ioData->mDataByteSize;
May 29, 2006
May 29, 2006
596
afm->AfterRender(afm);
597
598
599
600
return result;
}
May 28, 2006
May 28, 2006
601
void
May 29, 2006
May 29, 2006
602
delete_AudioFileManager(AudioFileManager * afm)
603
604
605
{
if (afm != NULL) {
if (afm->mFileBuffer) {
May 29, 2006
May 29, 2006
606
free(afm->mFileBuffer);
May 29, 2006
May 29, 2006
609
SDL_free(afm);
May 28, 2006
May 28, 2006
614
AudioFileManager *
May 29, 2006
May 29, 2006
615
616
617
new_AudioFileManager(AudioFilePlayer * inParent,
SInt16 inForkRefNum,
SInt64 inFileLength, UInt32 inChunkSize)
618
619
620
{
AudioFileManager *afm;
May 28, 2006
May 28, 2006
621
if (sReaderThread == NULL) {
May 29, 2006
May 29, 2006
622
sReaderThread = new_FileReaderThread();
623
624
625
626
if (sReaderThread == NULL)
return NULL;
}
May 29, 2006
May 29, 2006
627
afm = (AudioFileManager *) SDL_malloc(sizeof(AudioFileManager));
628
629
if (afm == NULL)
return NULL;
May 29, 2006
May 29, 2006
630
SDL_memset(afm, '\0', sizeof(*afm));
May 28, 2006
May 28, 2006
631
632
#define SET_AUDIOFILEMANAGER_METHOD(m) afm->m = AudioFileManager_##m
May 29, 2006
May 29, 2006
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);
May 28, 2006
May 28, 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;
May 29, 2006
May 29, 2006
653
654
655
afm->mFileBuffer = (char *) SDL_malloc(afm->mChunkSize * 2);
FSGetForkPosition(afm->mForkRefNum, &afm->mAudioDataOffset);
assert(afm->mFileBuffer != NULL);
May 28, 2006
May 28, 2006
659
/* vi: set ts=4 sw=4 expandtab: */