1/*
2    SDL - Simple DirectMedia Layer
3    Copyright (C) 1997-2004 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    AudioFilePlayer.h
29*/
30#ifndef __AudioFilePlayer_H__
31#define __AudioFilePlayer_H__
32
33#include <CoreServices/CoreServices.h>
34
35#include <AudioUnit/AudioUnit.h>
36
37#include "SDL_error.h"
38
39const char* AudioFilePlayerErrorStr (OSStatus error);
40
41/*
42void ThrowResult (OSStatus result, const char *str);
43
44#define THROW_RESULT(str)                                       \
45    if (result) {                                               \
46        ThrowResult (result, str);                              \
47    }
48*/
49
50typedef void (*AudioFilePlayNotifier)(void          *inRefCon,
51                                    OSStatus        inStatus);
52
53enum {
54    kAudioFilePlayErr_FilePlayUnderrun = -10000,
55    kAudioFilePlay_FileIsFinished = -10001,
56    kAudioFilePlay_PlayerIsUninitialized = -10002
57};
58
59
60struct S_AudioFileManager;
61
62#pragma mark __________ AudioFilePlayer
63typedef struct S_AudioFilePlayer
64{
65/*public:*/
66    int             (*SetDestination)(struct S_AudioFilePlayer *afp, AudioUnit *inDestUnit);
67    void            (*SetNotifier)(struct S_AudioFilePlayer *afp, AudioFilePlayNotifier inNotifier, void *inRefCon);
68    void            (*SetStartFrame)(struct S_AudioFilePlayer *afp, int frame); /* seek in the file */
69    int             (*GetCurrentFrame)(struct S_AudioFilePlayer *afp); /* get the current frame position */
70    void            (*SetStopFrame)(struct S_AudioFilePlayer *afp, int frame);   /* set limit in the file */
71    int             (*Connect)(struct S_AudioFilePlayer *afp);
72    void            (*Disconnect)(struct S_AudioFilePlayer *afp);
73    void            (*DoNotification)(struct S_AudioFilePlayer *afp, OSStatus inError);
74    int             (*IsConnected)(struct S_AudioFilePlayer *afp);
75    AudioUnit       (*GetDestUnit)(struct S_AudioFilePlayer *afp);
76    void            (*Print)(struct S_AudioFilePlayer *afp);
77
78/*private:*/
79    AudioUnit                       mPlayUnit;
80    SInt16                          mForkRefNum;
81
82    AudioUnitInputCallback          mInputCallback;
83
84    AudioStreamBasicDescription     mFileDescription;
85
86    int                             mConnected;
87
88    struct S_AudioFileManager*      mAudioFileManager;
89
90    AudioFilePlayNotifier           mNotifier;
91    void*                           mRefCon;
92
93    int                             mStartFrame;
94
95#pragma mark __________ Private_Methods
96
97    int          (*OpenFile)(struct S_AudioFilePlayer *afp, const FSRef *inRef, SInt64 *outFileSize);
98} AudioFilePlayer;
99
100
101AudioFilePlayer *new_AudioFilePlayer(const FSRef    *inFileRef);
102void delete_AudioFilePlayer(AudioFilePlayer *afp);
103
104
105
106#pragma mark __________ AudioFileManager
107typedef struct S_AudioFileManager
108{
109/*public:*/
110        /* this method should NOT be called by an object of this class
111           as it is called by the parent's Disconnect() method */
112    void                (*Disconnect)(struct S_AudioFileManager *afm);
113    int                 (*DoConnect)(struct S_AudioFileManager *afm);
114    OSStatus            (*Read)(struct S_AudioFileManager *afm, char *buffer, UInt32 *len);
115    const char*         (*GetFileBuffer)(struct S_AudioFileManager *afm);
116    const AudioFilePlayer *(*GetParent)(struct S_AudioFileManager *afm);
117    void                (*SetPosition)(struct S_AudioFileManager *afm, SInt64 pos);  /* seek/rewind in the file */
118    int                 (*GetByteCounter)(struct S_AudioFileManager *afm);  /* return actual bytes streamed to audio hardware */
119    void                (*SetEndOfFile)(struct S_AudioFileManager *afm, SInt64 pos);  /* set the "EOF" (will behave just like it reached eof) */
120
121/*protected:*/
122    AudioFilePlayer*    mParent;
123    SInt16              mForkRefNum;
124    SInt64              mAudioDataOffset;
125
126    char*               mFileBuffer;
127
128    int                 mByteCounter;
129
130    int                mReadFromFirstBuffer;
131    int                mLockUnsuccessful;
132    int                mIsEngaged;
133
134    int                 mNumTimesAskedSinceFinished;
135
136
137	void*               mTmpBuffer;
138	UInt32              mBufferSize;
139	UInt32              mBufferOffset;
140/*public:*/
141    UInt32              mChunkSize;
142    SInt64              mFileLength;
143    SInt64              mReadFilePosition;
144    int                 mWriteToFirstBuffer;
145    int                 mFinishedReadingData;
146
147/*protected:*/
148    OSStatus            (*Render)(struct S_AudioFileManager *afm, AudioBuffer *ioData);
149    OSStatus            (*GetFileData)(struct S_AudioFileManager *afm, void** inOutData, UInt32 *inOutDataSize);
150    void                (*AfterRender)(struct S_AudioFileManager *afm);
151
152/*public:*/
153    /*static*/
154    OSStatus            (*FileInputProc)(void                             *inRefCon,
155                                         AudioUnitRenderActionFlags      inActionFlags,
156                                         const AudioTimeStamp            *inTimeStamp,
157                                         UInt32                          inBusNumber,
158                                         AudioBuffer                     *ioData);
159} AudioFileManager;
160
161
162AudioFileManager *new_AudioFileManager (AudioFilePlayer *inParent,
163                      SInt16          inForkRefNum,
164                      SInt64          inFileLength,
165                      UInt32          inChunkSize);
166
167void delete_AudioFileManager(AudioFileManager *afm);
168
169#endif
170
171