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