Mercurial > sdl-ios-xcode
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 |