comparison src/cdrom/macosx/AudioFilePlayer.cpp @ 935:f8d5ddc7aef1

Audio improvements from Max Horn, including a new CoreAudio driver for MacOSX
author Sam Lantinga <slouken@libsdl.org>
date Sat, 21 Aug 2004 02:06:30 +0000
parents da0a2ad35bf4
children
comparison
equal deleted inserted replaced
934:af585d6efec8 935:f8d5ddc7aef1
65 return THIS->Render(*ioData); 65 return THIS->Render(*ioData);
66 } 66 }
67 67
68 OSStatus AudioFileManager::Render (AudioBuffer &ioData) 68 OSStatus AudioFileManager::Render (AudioBuffer &ioData)
69 { 69 {
70 OSStatus result = AudioConverterFillBuffer(mParentConverter, 70 OSStatus result = noErr;
71 AudioFileManager::ACInputProc, 71
72 this, 72 if (mBufferOffset >= mBufferSize) {
73 &ioData.mDataByteSize, 73 result = GetFileData(&mTmpBuffer, &mBufferSize);
74 ioData.mData); 74 if (result) {
75 if (result) { 75 SDL_SetError ("AudioConverterFillBuffer:%ld\n", result);
76 SDL_SetError ("AudioConverterFillBuffer:%ld\n", result); 76 mParent.DoNotification (result);
77 mParent.DoNotification (result); 77 return result;
78 } else { 78 }
79 mByteCounter += ioData.mDataByteSize / 2; 79
80 AfterRender(); 80 mBufferOffset = 0;
81 } 81 }
82
83 if (ioData.mDataByteSize > mBufferSize - mBufferOffset)
84 ioData.mDataByteSize = mBufferSize - mBufferOffset;
85 ioData.mData = (char *)mTmpBuffer + mBufferOffset;
86 mBufferOffset += ioData.mDataByteSize;
87
88 mByteCounter += ioData.mDataByteSize;
89 AfterRender();
82 return result; 90 return result;
83 }
84
85 OSStatus AudioFileManager::ACInputProc (AudioConverterRef inAudioConverter,
86 UInt32* outDataSize,
87 void** outData,
88 void* inUserData)
89 {
90 AudioFileManager* THIS = (AudioFileManager*)inUserData;
91 return THIS->GetFileData(outData, outDataSize);
92 } 91 }
93 92
94 AudioFileManager::~AudioFileManager () 93 AudioFileManager::~AudioFileManager ()
95 { 94 {
96 if (mFileBuffer) { 95 if (mFileBuffer) {
100 } 99 }
101 100
102 AudioFilePlayer::AudioFilePlayer (const FSRef *inFileRef) 101 AudioFilePlayer::AudioFilePlayer (const FSRef *inFileRef)
103 : mConnected (false), 102 : mConnected (false),
104 mAudioFileManager (0), 103 mAudioFileManager (0),
105 mConverter (0),
106 mNotifier (0), 104 mNotifier (0),
107 mStartFrame (0) 105 mStartFrame (0)
108 { 106 {
109 SInt64 fileDataSize = 0; 107 SInt64 fileDataSize = 0;
110 108
122 mForkRefNum, 120 mForkRefNum,
123 fileDataSize, 121 fileDataSize,
124 bytesPerSecond); 122 bytesPerSecond);
125 } 123 }
126 124
127 // you can put a rate scalar here to play the file faster or slower 125 void AudioFilePlayer::SetDestination (AudioUnit &inDestUnit)
128 // by multiplying the same rate by the desired factor
129 // eg fileSampleRate * 2 -> twice as fast
130 // before you create the AudioConverter
131 void AudioFilePlayer::SetDestination (AudioUnit &inDestUnit,
132 int inBusNumber)
133 { 126 {
134 if (mConnected) throw static_cast<OSStatus>(-1); //can't set dest if already engaged 127 if (mConnected) throw static_cast<OSStatus>(-1); //can't set dest if already engaged
135 128
136 mPlayUnit = inDestUnit; 129 mPlayUnit = inDestUnit;
137 mBusNumber = inBusNumber;
138 130
139 OSStatus result = noErr; 131 OSStatus result = noErr;
140 132
141 if (mConverter) {
142 result = AudioConverterDispose (mConverter);
143 THROW_RESULT("AudioConverterDispose")
144 }
145
146 AudioStreamBasicDescription destDesc;
147 UInt32 size = sizeof (destDesc);
148 result = AudioUnitGetProperty (inDestUnit,
149 kAudioUnitProperty_StreamFormat,
150 kAudioUnitScope_Input,
151 inBusNumber,
152 &destDesc,
153 &size);
154 THROW_RESULT("AudioUnitGetProperty")
155
156 #if DEBUG
157 printf("Destination format:\n");
158 PrintStreamDesc (&destDesc);
159 #endif
160 133
161 //we can "down" cast a component instance to a component 134 //we can "down" cast a component instance to a component
162 ComponentDescription desc; 135 ComponentDescription desc;
163 result = GetComponentInfo ((Component)inDestUnit, &desc, 0, 0, 0); 136 result = GetComponentInfo ((Component)inDestUnit, &desc, 0, 0, 0);
164 THROW_RESULT("GetComponentInfo") 137 THROW_RESULT("GetComponentInfo")
169 if (desc.componentType != kAudioUnitComponentType) { 142 if (desc.componentType != kAudioUnitComponentType) {
170 result = badComponentInstance; 143 result = badComponentInstance;
171 THROW_RESULT("BAD COMPONENT") 144 THROW_RESULT("BAD COMPONENT")
172 } 145 }
173 146
174 147 /* Set the input format of the audio unit. */
175 result = AudioConverterNew (&mFileDescription, &destDesc, &mConverter); 148 result = AudioUnitSetProperty (inDestUnit,
176 THROW_RESULT("AudioConverterNew") 149 kAudioUnitProperty_StreamFormat,
177 150 kAudioUnitScope_Input,
178 #if 0 151 0,
179 // this uses the better quality SRC 152 &mFileDescription,
180 UInt32 srcID = kAudioUnitSRCAlgorithm_Polyphase; 153 sizeof (mFileDescription));
181 result = AudioConverterSetProperty(mConverter, 154 THROW_RESULT("AudioUnitSetProperty")
182 kAudioConverterSampleRateConverterAlgorithm,
183 sizeof(srcID),
184 &srcID);
185 THROW_RESULT("AudioConverterSetProperty")
186 #endif
187 } 155 }
188 156
189 void AudioFilePlayer::SetStartFrame (int frame) 157 void AudioFilePlayer::SetStartFrame (int frame)
190 { 158 {
191 SInt64 position = frame * 2352; 159 SInt64 position = frame * 2352;
218 186
219 if (mForkRefNum) { 187 if (mForkRefNum) {
220 FSClose (mForkRefNum); 188 FSClose (mForkRefNum);
221 mForkRefNum = 0; 189 mForkRefNum = 0;
222 } 190 }
223
224 if (mConverter) {
225 AudioConverterDispose (mConverter);
226 mConverter = 0;
227 }
228 } 191 }
229 192
230 void AudioFilePlayer::Connect() 193 void AudioFilePlayer::Connect()
231 { 194 {
232 #if DEBUG 195 #if DEBUG
233 printf ("Connect:%x,%ld, engaged=%d\n", (int)mPlayUnit, mBusNumber, (mConnected ? 1 : 0)); 196 printf ("Connect:%x, engaged=%d\n", (int)mPlayUnit, (mConnected ? 1 : 0));
234 #endif 197 #endif
235 if (!mConnected) 198 if (!mConnected)
236 { 199 {
237 mAudioFileManager->Connect(mConverter); 200 mAudioFileManager->DoConnect();
238 201
202
239 // set the render callback for the file data to be supplied to the sound converter AU 203 // set the render callback for the file data to be supplied to the sound converter AU
240 mInputCallback.inputProc = AudioFileManager::FileInputProc; 204 mInputCallback.inputProc = AudioFileManager::FileInputProc;
241 mInputCallback.inputProcRefCon = mAudioFileManager; 205 mInputCallback.inputProcRefCon = mAudioFileManager;
242 206
243 OSStatus result = AudioUnitSetProperty (mPlayUnit, 207 OSStatus result = AudioUnitSetProperty (mPlayUnit,
244 kAudioUnitProperty_SetInputCallback, 208 kAudioUnitProperty_SetInputCallback,
245 kAudioUnitScope_Input, 209 kAudioUnitScope_Input,
246 mBusNumber, 210 0,
247 &mInputCallback, 211 &mInputCallback,
248 sizeof(mInputCallback)); 212 sizeof(mInputCallback));
249 THROW_RESULT("AudioUnitSetProperty") 213 THROW_RESULT("AudioUnitSetProperty")
250 mConnected = true; 214 mConnected = true;
251 } 215 }
270 } 234 }
271 235
272 void AudioFilePlayer::Disconnect () 236 void AudioFilePlayer::Disconnect ()
273 { 237 {
274 #if DEBUG 238 #if DEBUG
275 printf ("Disconnect:%x,%ld, engaged=%d\n", (int)mPlayUnit, mBusNumber, (mConnected ? 1 : 0)); 239 printf ("Disconnect:%x,%ld, engaged=%d\n", (int)mPlayUnit, 0, (mConnected ? 1 : 0));
276 #endif 240 #endif
277 if (mConnected) 241 if (mConnected)
278 { 242 {
279 mConnected = false; 243 mConnected = false;
280 244
281 mInputCallback.inputProc = 0; 245 mInputCallback.inputProc = 0;
282 mInputCallback.inputProcRefCon = 0; 246 mInputCallback.inputProcRefCon = 0;
283 OSStatus result = AudioUnitSetProperty (mPlayUnit, 247 OSStatus result = AudioUnitSetProperty (mPlayUnit,
284 kAudioUnitProperty_SetInputCallback, 248 kAudioUnitProperty_SetInputCallback,
285 kAudioUnitScope_Input, 249 kAudioUnitScope_Input,
286 mBusNumber, 250 0,
287 &mInputCallback, 251 &mInputCallback,
288 sizeof(mInputCallback)); 252 sizeof(mInputCallback));
289 if (result) 253 if (result)
290 SDL_SetError ("AudioUnitSetProperty:RemoveInputCallback:%ld", result); 254 SDL_SetError ("AudioUnitSetProperty:RemoveInputCallback:%ld", result);
291 255