Mercurial > mplayer.hg
annotate libao2/ao_coreaudio.c @ 35418:cedb0ba2b5c6
Move the code to set guiInfo's Track, Chapter and Angle start values.
Set them before checking whether there is any media opened, because
with no media opened we clear the counters.
author | ib |
---|---|
date | Thu, 29 Nov 2012 14:11:03 +0000 |
parents | a42d4bc441d7 |
children | efb9481610d2 |
rev | line source |
---|---|
29209 | 1 /* |
2 * CoreAudio audio output driver for Mac OS X | |
3 * | |
4 * original copyright (C) Timothy J. Wood - Aug 2000 | |
5 * ported to MPlayer libao2 by Dan Christiansen | |
6 * | |
7 * The S/PDIF part of the code is based on the auhal audio output | |
8 * module from VideoLAN: | |
9 * Copyright (c) 2006 Derk-Jan Hartman <hartman at videolan dot org> | |
10 * | |
11 * This file is part of MPlayer. | |
12 * | |
13 * MPlayer is free software; you can redistribute it and/or modify | |
14 * it under the terms of the GNU General Public License as published by | |
15 * the Free Software Foundation; either version 2 of the License, or | |
16 * (at your option) any later version. | |
17 * | |
18 * MPlayer is distributed in the hope that it will be useful, | |
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
21 * GNU General Public License for more details. | |
22 * | |
23 * You should have received a copy of the GNU General Public License along | |
24 * along with MPlayer; if not, write to the Free Software | |
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
26 */ | |
27 | |
28 /* | |
29 * The MacOS X CoreAudio framework doesn't mesh as simply as some | |
30 * simpler frameworks do. This is due to the fact that CoreAudio pulls | |
31 * audio samples rather than having them pushed at it (which is nice | |
32 * when you are wanting to do good buffering of audio). | |
33 * | |
34 * AC-3 and MPEG audio passthrough is possible, but has never been tested | |
35 * due to lack of a soundcard that supports it. | |
36 */ | |
37 | |
38 #include <CoreServices/CoreServices.h> | |
39 #include <AudioUnit/AudioUnit.h> | |
40 #include <AudioToolbox/AudioToolbox.h> | |
41 #include <stdio.h> | |
42 #include <string.h> | |
43 #include <stdlib.h> | |
44 #include <inttypes.h> | |
45 #include <sys/types.h> | |
46 #include <unistd.h> | |
47 | |
48 #include "config.h" | |
49 #include "mp_msg.h" | |
50 | |
51 #include "audio_out.h" | |
52 #include "audio_out_internal.h" | |
53 #include "libaf/af_format.h" | |
54 #include "osdep/timer.h" | |
55 #include "libavutil/fifo.h" | |
31649
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
56 #include "subopt-helper.h" |
29209 | 57 |
58 static const ao_info_t info = | |
59 { | |
60 "Darwin/Mac OS X native audio output", | |
61 "coreaudio", | |
62 "Timothy J. Wood & Dan Christiansen & Chris Roccati", | |
63 "" | |
64 }; | |
65 | |
66 LIBAO_EXTERN(coreaudio) | |
67 | |
68 /* Prefix for all mp_msg() calls */ | |
69 #define ao_msg(a, b, c...) mp_msg(a, b, "AO: [coreaudio] " c) | |
70 | |
32683 | 71 #if MAC_OS_X_VERSION_MAX_ALLOWED <= 1040 |
72 /* AudioDeviceIOProcID does not exist in Mac OS X 10.4. We can emulate | |
73 * this by using AudioDeviceAddIOProc() and AudioDeviceRemoveIOProc(). */ | |
74 #define AudioDeviceIOProcID AudioDeviceIOProc | |
75 #define AudioDeviceDestroyIOProcID AudioDeviceRemoveIOProc | |
76 static OSStatus AudioDeviceCreateIOProcID(AudioDeviceID dev, | |
77 AudioDeviceIOProc proc, | |
78 void *data, | |
79 AudioDeviceIOProcID *procid) | |
80 { | |
81 *procid = proc; | |
82 return AudioDeviceAddIOProc(dev, proc, data); | |
83 } | |
84 #endif | |
85 | |
29209 | 86 typedef struct ao_coreaudio_s |
87 { | |
88 AudioDeviceID i_selected_dev; /* Keeps DeviceID of the selected device. */ | |
89 int b_supports_digital; /* Does the currently selected device support digital mode? */ | |
90 int b_digital; /* Are we running in digital mode? */ | |
91 int b_muted; /* Are we muted in digital mode? */ | |
92 | |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
93 AudioDeviceIOProcID renderCallback; /* Render callback used for SPDIF */ |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
94 |
29209 | 95 /* AudioUnit */ |
96 AudioUnit theOutputUnit; | |
97 | |
98 /* CoreAudio SPDIF mode specific */ | |
99 pid_t i_hog_pid; /* Keeps the pid of our hog status. */ | |
100 AudioStreamID i_stream_id; /* The StreamID that has a cac3 streamformat */ | |
101 int i_stream_index; /* The index of i_stream_id in an AudioBufferList */ | |
102 AudioStreamBasicDescription stream_format;/* The format we changed the stream to */ | |
103 AudioStreamBasicDescription sfmt_revert; /* The original format of the stream */ | |
104 int b_revert; /* Whether we need to revert the stream format */ | |
105 int b_changed_mixing; /* Whether we need to set the mixing mode back */ | |
106 int b_stream_format_changed; /* Flag for main thread to reset stream's format to digital and reset buffer */ | |
107 | |
108 /* Original common part */ | |
109 int packetSize; | |
110 int paused; | |
111 | |
112 /* Ring-buffer */ | |
113 AVFifoBuffer *buffer; | |
114 unsigned int buffer_len; ///< must always be num_chunks * chunk_size | |
115 unsigned int num_chunks; | |
116 unsigned int chunk_size; | |
117 } ao_coreaudio_t; | |
118 | |
119 static ao_coreaudio_t *ao = NULL; | |
120 | |
121 /** | |
122 * \brief add data to ringbuffer | |
123 */ | |
124 static int write_buffer(unsigned char* data, int len){ | |
125 int free = ao->buffer_len - av_fifo_size(ao->buffer); | |
126 if (len > free) len = free; | |
127 return av_fifo_generic_write(ao->buffer, data, len, NULL); | |
128 } | |
129 | |
130 /** | |
131 * \brief remove data from ringbuffer | |
132 */ | |
133 static int read_buffer(unsigned char* data,int len){ | |
134 int buffered = av_fifo_size(ao->buffer); | |
135 if (len > buffered) len = buffered; | |
34153
54f502c57425
Fix possible crash since RenderCallbackSPDIF might call read_buffer with NULL data.
reimar
parents:
34059
diff
changeset
|
136 if (data) |
34154 | 137 av_fifo_generic_read(ao->buffer, data, len, NULL); |
34153
54f502c57425
Fix possible crash since RenderCallbackSPDIF might call read_buffer with NULL data.
reimar
parents:
34059
diff
changeset
|
138 else |
54f502c57425
Fix possible crash since RenderCallbackSPDIF might call read_buffer with NULL data.
reimar
parents:
34059
diff
changeset
|
139 av_fifo_drain(ao->buffer, len); |
29439
02dec439f717
100l, av_fifo_generic_read does not return anything useful, so ignore its
reimar
parents:
29401
diff
changeset
|
140 return len; |
29209 | 141 } |
142 | |
30676
13b7aa964af6
Mark theRenderProc() as static, it is only used within the file.
diego
parents:
30242
diff
changeset
|
143 static OSStatus theRenderProc(void *inRefCon, |
13b7aa964af6
Mark theRenderProc() as static, it is only used within the file.
diego
parents:
30242
diff
changeset
|
144 AudioUnitRenderActionFlags *inActionFlags, |
13b7aa964af6
Mark theRenderProc() as static, it is only used within the file.
diego
parents:
30242
diff
changeset
|
145 const AudioTimeStamp *inTimeStamp, |
13b7aa964af6
Mark theRenderProc() as static, it is only used within the file.
diego
parents:
30242
diff
changeset
|
146 UInt32 inBusNumber, UInt32 inNumFrames, |
13b7aa964af6
Mark theRenderProc() as static, it is only used within the file.
diego
parents:
30242
diff
changeset
|
147 AudioBufferList *ioData) |
29209 | 148 { |
149 int amt=av_fifo_size(ao->buffer); | |
150 int req=(inNumFrames)*ao->packetSize; | |
151 | |
152 if(amt>req) | |
153 amt=req; | |
154 | |
155 if(amt) | |
156 read_buffer((unsigned char *)ioData->mBuffers[0].mData, amt); | |
157 else audio_pause(); | |
158 ioData->mBuffers[0].mDataByteSize = amt; | |
159 | |
160 return noErr; | |
161 } | |
162 | |
163 static int control(int cmd,void *arg){ | |
164 ao_control_vol_t *control_vol; | |
165 OSStatus err; | |
166 Float32 vol; | |
167 switch (cmd) { | |
168 case AOCONTROL_GET_VOLUME: | |
169 control_vol = (ao_control_vol_t*)arg; | |
170 if (ao->b_digital) { | |
171 // Digital output has no volume adjust. | |
172 return CONTROL_FALSE; | |
173 } | |
174 err = AudioUnitGetParameter(ao->theOutputUnit, kHALOutputParam_Volume, kAudioUnitScope_Global, 0, &vol); | |
175 | |
176 if(err==0) { | |
177 // printf("GET VOL=%f\n", vol); | |
178 control_vol->left=control_vol->right=vol*100.0/4.0; | |
179 return CONTROL_TRUE; | |
180 } | |
181 else { | |
182 ao_msg(MSGT_AO, MSGL_WARN, "could not get HAL output volume: [%4.4s]\n", (char *)&err); | |
183 return CONTROL_FALSE; | |
184 } | |
185 | |
186 case AOCONTROL_SET_VOLUME: | |
187 control_vol = (ao_control_vol_t*)arg; | |
188 | |
189 if (ao->b_digital) { | |
190 // Digital output can not set volume. Here we have to return true | |
191 // to make mixer forget it. Else mixer will add a soft filter, | |
192 // that's not we expected and the filter not support ac3 stream | |
193 // will cause mplayer die. | |
194 | |
195 // Although not support set volume, but at least we support mute. | |
196 // MPlayer set mute by set volume to zero, we handle it. | |
197 if (control_vol->left == 0 && control_vol->right == 0) | |
198 ao->b_muted = 1; | |
199 else | |
200 ao->b_muted = 0; | |
201 return CONTROL_TRUE; | |
202 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29212
diff
changeset
|
203 |
29209 | 204 vol=(control_vol->left+control_vol->right)*4.0/200.0; |
205 err = AudioUnitSetParameter(ao->theOutputUnit, kHALOutputParam_Volume, kAudioUnitScope_Global, 0, vol, 0); | |
206 if(err==0) { | |
207 // printf("SET VOL=%f\n", vol); | |
208 return CONTROL_TRUE; | |
209 } | |
210 else { | |
211 ao_msg(MSGT_AO, MSGL_WARN, "could not set HAL output volume: [%4.4s]\n", (char *)&err); | |
212 return CONTROL_FALSE; | |
213 } | |
214 /* Everything is currently unimplemented */ | |
215 default: | |
216 return CONTROL_FALSE; | |
217 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29212
diff
changeset
|
218 |
29209 | 219 } |
220 | |
221 | |
222 static void print_format(int lev, const char* str, const AudioStreamBasicDescription *f){ | |
223 uint32_t flags=(uint32_t) f->mFormatFlags; | |
31646
b0da003fadf2
Fix printf specifiers used in ao_coreaudio. Fixes warnings:
adrian
parents:
30702
diff
changeset
|
224 ao_msg(MSGT_AO,lev, "%s %7.1fHz %"PRIu32"bit [%c%c%c%c][%"PRIu32"][%"PRIu32"][%"PRIu32"][%"PRIu32"][%"PRIu32"] %s %s %s%s%s%s\n", |
29209 | 225 str, f->mSampleRate, f->mBitsPerChannel, |
226 (int)(f->mFormatID & 0xff000000) >> 24, | |
227 (int)(f->mFormatID & 0x00ff0000) >> 16, | |
228 (int)(f->mFormatID & 0x0000ff00) >> 8, | |
229 (int)(f->mFormatID & 0x000000ff) >> 0, | |
230 f->mFormatFlags, f->mBytesPerPacket, | |
231 f->mFramesPerPacket, f->mBytesPerFrame, | |
232 f->mChannelsPerFrame, | |
233 (flags&kAudioFormatFlagIsFloat) ? "float" : "int", | |
234 (flags&kAudioFormatFlagIsBigEndian) ? "BE" : "LE", | |
235 (flags&kAudioFormatFlagIsSignedInteger) ? "S" : "U", | |
236 (flags&kAudioFormatFlagIsPacked) ? " packed" : "", | |
237 (flags&kAudioFormatFlagIsAlignedHigh) ? " aligned" : "", | |
238 (flags&kAudioFormatFlagIsNonInterleaved) ? " ni" : "" ); | |
239 } | |
240 | |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
241 static OSStatus GetAudioProperty(AudioObjectID id, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
242 AudioObjectPropertySelector selector, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
243 UInt32 outSize, void *outData) |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
244 { |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
245 AudioObjectPropertyAddress property_address; |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
246 |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
247 property_address.mSelector = selector; |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
248 property_address.mScope = kAudioObjectPropertyScopeGlobal; |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
249 property_address.mElement = kAudioObjectPropertyElementMaster; |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
250 |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
251 return AudioObjectGetPropertyData(id, &property_address, 0, NULL, &outSize, outData); |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
252 } |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
253 |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
254 static UInt32 GetAudioPropertyArray(AudioObjectID id, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
255 AudioObjectPropertySelector selector, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
256 AudioObjectPropertyScope scope, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
257 void **outData) |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
258 { |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
259 OSStatus err; |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
260 AudioObjectPropertyAddress property_address; |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
261 UInt32 i_param_size; |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
262 |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
263 property_address.mSelector = selector; |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
264 property_address.mScope = scope; |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
265 property_address.mElement = kAudioObjectPropertyElementMaster; |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
266 |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
267 err = AudioObjectGetPropertyDataSize(id, &property_address, 0, NULL, &i_param_size); |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
268 |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
269 if (err != noErr) |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
270 return 0; |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
271 |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
272 *outData = malloc(i_param_size); |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
273 |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
274 |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
275 err = AudioObjectGetPropertyData(id, &property_address, 0, NULL, &i_param_size, *outData); |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
276 |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
277 if (err != noErr) { |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
278 free(*outData); |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
279 return 0; |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
280 } |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
281 |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
282 return i_param_size; |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
283 } |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
284 |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
285 static UInt32 GetGlobalAudioPropertyArray(AudioObjectID id, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
286 AudioObjectPropertySelector selector, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
287 void **outData) |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
288 { |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
289 return GetAudioPropertyArray(id, selector, kAudioObjectPropertyScopeGlobal, outData); |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
290 } |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
291 |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
292 static OSStatus GetAudioPropertyString(AudioObjectID id, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
293 AudioObjectPropertySelector selector, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
294 char **outData) |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
295 { |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
296 OSStatus err; |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
297 AudioObjectPropertyAddress property_address; |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
298 UInt32 i_param_size; |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
299 CFStringRef string; |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
300 CFIndex string_length; |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
301 |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
302 property_address.mSelector = selector; |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
303 property_address.mScope = kAudioObjectPropertyScopeGlobal; |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
304 property_address.mElement = kAudioObjectPropertyElementMaster; |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
305 |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
306 i_param_size = sizeof(CFStringRef); |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
307 err = AudioObjectGetPropertyData(id, &property_address, 0, NULL, &i_param_size, &string); |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
308 if (err != noErr) |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
309 return err; |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
310 |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
311 string_length = CFStringGetMaximumSizeForEncoding(CFStringGetLength(string), |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
312 kCFStringEncodingASCII); |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
313 *outData = malloc(string_length + 1); |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
314 CFStringGetCString(string, *outData, string_length + 1, kCFStringEncodingASCII); |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
315 |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
316 CFRelease(string); |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
317 |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
318 return err; |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
319 } |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
320 |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
321 static OSStatus SetAudioProperty(AudioObjectID id, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
322 AudioObjectPropertySelector selector, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
323 UInt32 inDataSize, void *inData) |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
324 { |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
325 AudioObjectPropertyAddress property_address; |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
326 |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
327 property_address.mSelector = selector; |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
328 property_address.mScope = kAudioObjectPropertyScopeGlobal; |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
329 property_address.mElement = kAudioObjectPropertyElementMaster; |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
330 |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
331 return AudioObjectSetPropertyData(id, &property_address, 0, NULL, inDataSize, inData); |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
332 } |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
333 |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
334 static Boolean IsAudioPropertySettable(AudioObjectID id, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
335 AudioObjectPropertySelector selector, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
336 Boolean *outData) |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
337 { |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
338 AudioObjectPropertyAddress property_address; |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
339 |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
340 property_address.mSelector = selector; |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
341 property_address.mScope = kAudioObjectPropertyScopeGlobal; |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
342 property_address.mElement = kAudioObjectPropertyElementMaster; |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
343 |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
344 return AudioObjectIsPropertySettable(id, &property_address, outData); |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
345 } |
29209 | 346 |
347 static int AudioDeviceSupportsDigital( AudioDeviceID i_dev_id ); | |
348 static int AudioStreamSupportsDigital( AudioStreamID i_stream_id ); | |
29212
eda346733b8c
Add missing 'void' to parameterless function declarations.
diego
parents:
29209
diff
changeset
|
349 static int OpenSPDIF(void); |
29209 | 350 static int AudioStreamChangeFormat( AudioStreamID i_stream_id, AudioStreamBasicDescription change_format ); |
351 static OSStatus RenderCallbackSPDIF( AudioDeviceID inDevice, | |
352 const AudioTimeStamp * inNow, | |
353 const void * inInputData, | |
354 const AudioTimeStamp * inInputTime, | |
355 AudioBufferList * outOutputData, | |
356 const AudioTimeStamp * inOutputTime, | |
357 void * threadGlobals ); | |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
358 static OSStatus StreamListener( AudioObjectID inObjectID, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
359 UInt32 inNumberAddresses, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
360 const AudioObjectPropertyAddress inAddresses[], |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
361 void *inClientData ); |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
362 static OSStatus DeviceListener( AudioObjectID inObjectID, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
363 UInt32 inNumberAddresses, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
364 const AudioObjectPropertyAddress inAddresses[], |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
365 void *inClientData ); |
29209 | 366 |
31649
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
367 static void print_help(void) |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
368 { |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
369 OSStatus err; |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
370 UInt32 i_param_size; |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
371 int num_devices; |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
372 AudioDeviceID *devids; |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
373 char *device_name; |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
374 |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
375 mp_msg(MSGT_AO, MSGL_FATAL, |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
376 "\n-ao coreaudio commandline help:\n" |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
377 "Example: mplayer -ao coreaudio:device_id=266\n" |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
378 " open Core Audio with output device ID 266.\n" |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
379 "\nOptions:\n" |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
380 " device_id\n" |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
381 " ID of output device to use (0 = default device)\n" |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
382 " help\n" |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
383 " This help including list of available devices.\n" |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
384 "\n" |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
385 "Available output devices:\n"); |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
386 |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
387 i_param_size = GetGlobalAudioPropertyArray(kAudioObjectSystemObject, kAudioHardwarePropertyDevices, (void **)&devids); |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
388 |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
389 if (!i_param_size) { |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
390 mp_msg(MSGT_AO, MSGL_FATAL, "Failed to get list of output devices.\n"); |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
391 return; |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
392 } |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
393 |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
394 num_devices = i_param_size / sizeof(AudioDeviceID); |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
395 |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
396 for (int i = 0; i < num_devices; ++i) { |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
397 err = GetAudioPropertyString(devids[i], kAudioObjectPropertyName, &device_name); |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
398 |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
399 if (err == noErr) { |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
400 mp_msg(MSGT_AO, MSGL_FATAL, "%s (id: %"PRIu32")\n", device_name, devids[i]); |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
401 free(device_name); |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
402 } else |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
403 mp_msg(MSGT_AO, MSGL_FATAL, "Unknown (id: %"PRIu32")\n", devids[i]); |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
404 } |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
405 |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
406 mp_msg(MSGT_AO, MSGL_FATAL, "\n"); |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
407 |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
408 free(devids); |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
409 } |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
410 |
29209 | 411 static int init(int rate,int channels,int format,int flags) |
412 { | |
413 AudioStreamBasicDescription inDesc; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29212
diff
changeset
|
414 ComponentDescription desc; |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29212
diff
changeset
|
415 Component comp; |
29209 | 416 AURenderCallbackStruct renderCallback; |
417 OSStatus err; | |
31657
fa6671a1b8dc
Remove some unused variables along with the corresponding warnings.
diego
parents:
31651
diff
changeset
|
418 UInt32 size, maxFrames, b_alive; |
29209 | 419 char *psz_name; |
420 AudioDeviceID devid_def = 0; | |
31659
a05f97bad2a9
Improve handling of the "help" suboption in coreaudio:
adrian
parents:
31657
diff
changeset
|
421 int device_id, display_help = 0; |
31649
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
422 |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
423 const opt_t subopts[] = { |
31660 | 424 {"device_id", OPT_ARG_INT, &device_id, NULL}, |
425 {"help", OPT_ARG_BOOL, &display_help, NULL}, | |
31649
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
426 {NULL} |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
427 }; |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
428 |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
429 // set defaults |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
430 device_id = 0; |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
431 |
31659
a05f97bad2a9
Improve handling of the "help" suboption in coreaudio:
adrian
parents:
31657
diff
changeset
|
432 if (subopt_parse(ao_subdevice, subopts) != 0 || display_help) { |
31649
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
433 print_help(); |
31659
a05f97bad2a9
Improve handling of the "help" suboption in coreaudio:
adrian
parents:
31657
diff
changeset
|
434 if (!display_help) |
31660 | 435 return 0; |
31649
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
436 } |
29209 | 437 |
438 ao_msg(MSGT_AO,MSGL_V, "init([%dHz][%dch][%s][%d])\n", rate, channels, af_fmt2str_short(format), flags); | |
439 | |
440 ao = calloc(1, sizeof(ao_coreaudio_t)); | |
441 | |
442 ao->i_selected_dev = 0; | |
443 ao->b_supports_digital = 0; | |
444 ao->b_digital = 0; | |
445 ao->b_muted = 0; | |
446 ao->b_stream_format_changed = 0; | |
447 ao->i_hog_pid = -1; | |
448 ao->i_stream_id = 0; | |
449 ao->i_stream_index = -1; | |
450 ao->b_revert = 0; | |
451 ao->b_changed_mixing = 0; | |
452 | |
31649
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
453 if (device_id == 0) { |
29209 | 454 /* Find the ID of the default Device. */ |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
455 err = GetAudioProperty(kAudioObjectSystemObject, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
456 kAudioHardwarePropertyDefaultOutputDevice, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
457 sizeof(UInt32), &devid_def); |
29209 | 458 if (err != noErr) |
459 { | |
460 ao_msg(MSGT_AO, MSGL_WARN, "could not get default audio device: [%4.4s]\n", (char *)&err); | |
461 goto err_out; | |
462 } | |
31649
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
463 } else { |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
464 devid_def = device_id; |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
465 } |
29209 | 466 |
31650 | 467 /* Retrieve the name of the device. */ |
468 err = GetAudioPropertyString(devid_def, | |
469 kAudioObjectPropertyName, | |
470 &psz_name); | |
471 if (err != noErr) | |
472 { | |
473 ao_msg(MSGT_AO, MSGL_WARN, "could not get default audio device name: [%4.4s]\n", (char *)&err); | |
474 goto err_out; | |
475 } | |
29209 | 476 |
31649
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
477 ao_msg(MSGT_AO,MSGL_V, "got audio output device ID: %"PRIu32" Name: %s\n", devid_def, psz_name ); |
29209 | 478 |
31649
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
479 /* Probe whether device support S/PDIF stream output if input is AC3 stream. */ |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
480 if (AF_FORMAT_IS_AC3(format)) { |
29209 | 481 if (AudioDeviceSupportsDigital(devid_def)) |
482 { | |
483 ao->b_supports_digital = 1; | |
484 } | |
31891
4f17ff5b3cbc
Fix a bunch of grammar and spelling errors in mp_msg calls.
diego
parents:
31660
diff
changeset
|
485 ao_msg(MSGT_AO, MSGL_V, |
4f17ff5b3cbc
Fix a bunch of grammar and spelling errors in mp_msg calls.
diego
parents:
31660
diff
changeset
|
486 "probe default audio output device about support for digital s/pdif output: %d\n", |
4f17ff5b3cbc
Fix a bunch of grammar and spelling errors in mp_msg calls.
diego
parents:
31660
diff
changeset
|
487 ao->b_supports_digital ); |
31649
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
488 } |
29209 | 489 |
31649
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
490 free(psz_name); |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
491 |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
492 // Save selected device id |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
493 ao->i_selected_dev = devid_def; |
29209 | 494 |
495 // Build Description for the input format | |
496 inDesc.mSampleRate=rate; | |
497 inDesc.mFormatID=ao->b_supports_digital ? kAudioFormat60958AC3 : kAudioFormatLinearPCM; | |
498 inDesc.mChannelsPerFrame=channels; | |
30235 | 499 inDesc.mBitsPerChannel=af_fmt2bits(format); |
29209 | 500 |
501 if((format&AF_FORMAT_POINT_MASK)==AF_FORMAT_F) { | |
502 // float | |
503 inDesc.mFormatFlags = kAudioFormatFlagIsFloat|kAudioFormatFlagIsPacked; | |
504 } | |
505 else if((format&AF_FORMAT_SIGN_MASK)==AF_FORMAT_SI) { | |
506 // signed int | |
507 inDesc.mFormatFlags = kAudioFormatFlagIsSignedInteger|kAudioFormatFlagIsPacked; | |
508 } | |
509 else { | |
510 // unsigned int | |
511 inDesc.mFormatFlags = kAudioFormatFlagIsPacked; | |
512 } | |
30242
03c1ad03f29d
MPlayer's format now correctly identifies AC3 as either little- or big-endian,
reimar
parents:
30235
diff
changeset
|
513 if ((format & AF_FORMAT_END_MASK) == AF_FORMAT_BE) |
29209 | 514 inDesc.mFormatFlags |= kAudioFormatFlagIsBigEndian; |
515 | |
516 inDesc.mFramesPerPacket = 1; | |
517 ao->packetSize = inDesc.mBytesPerPacket = inDesc.mBytesPerFrame = inDesc.mFramesPerPacket*channels*(inDesc.mBitsPerChannel/8); | |
518 print_format(MSGL_V, "source:",&inDesc); | |
519 | |
520 if (ao->b_supports_digital) | |
521 { | |
522 b_alive = 1; | |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
523 err = GetAudioProperty(ao->i_selected_dev, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
524 kAudioDevicePropertyDeviceIsAlive, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
525 sizeof(UInt32), &b_alive); |
29209 | 526 if (err != noErr) |
527 ao_msg(MSGT_AO, MSGL_WARN, "could not check whether device is alive: [%4.4s]\n", (char *)&err); | |
528 if (!b_alive) | |
529 ao_msg(MSGT_AO, MSGL_WARN, "device is not alive\n" ); | |
31650 | 530 |
29209 | 531 /* S/PDIF output need device in HogMode. */ |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
532 err = GetAudioProperty(ao->i_selected_dev, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
533 kAudioDevicePropertyHogMode, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
534 sizeof(pid_t), &ao->i_hog_pid); |
29209 | 535 if (err != noErr) |
536 { | |
537 /* This is not a fatal error. Some drivers simply don't support this property. */ | |
538 ao_msg(MSGT_AO, MSGL_WARN, "could not check whether device is hogged: [%4.4s]\n", | |
539 (char *)&err); | |
540 ao->i_hog_pid = -1; | |
541 } | |
542 | |
543 if (ao->i_hog_pid != -1 && ao->i_hog_pid != getpid()) | |
544 { | |
545 ao_msg(MSGT_AO, MSGL_WARN, "Selected audio device is exclusively in use by another program.\n" ); | |
546 goto err_out; | |
547 } | |
548 ao->stream_format = inDesc; | |
549 return OpenSPDIF(); | |
550 } | |
551 | |
552 /* original analog output code */ | |
553 desc.componentType = kAudioUnitType_Output; | |
31649
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
554 desc.componentSubType = (device_id == 0) ? kAudioUnitSubType_DefaultOutput : kAudioUnitSubType_HALOutput; |
29209 | 555 desc.componentManufacturer = kAudioUnitManufacturer_Apple; |
556 desc.componentFlags = 0; | |
557 desc.componentFlagsMask = 0; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29212
diff
changeset
|
558 |
29209 | 559 comp = FindNextComponent(NULL, &desc); //Finds an component that meets the desc spec's |
560 if (comp == NULL) { | |
561 ao_msg(MSGT_AO, MSGL_WARN, "Unable to find Output Unit component\n"); | |
562 goto err_out; | |
563 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29212
diff
changeset
|
564 |
29209 | 565 err = OpenAComponent(comp, &(ao->theOutputUnit)); //gains access to the services provided by the component |
566 if (err) { | |
567 ao_msg(MSGT_AO, MSGL_WARN, "Unable to open Output Unit component: [%4.4s]\n", (char *)&err); | |
568 goto err_out; | |
569 } | |
570 | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29212
diff
changeset
|
571 // Initialize AudioUnit |
29209 | 572 err = AudioUnitInitialize(ao->theOutputUnit); |
573 if (err) { | |
574 ao_msg(MSGT_AO, MSGL_WARN, "Unable to initialize Output Unit component: [%4.4s]\n", (char *)&err); | |
575 goto err_out1; | |
576 } | |
577 | |
578 size = sizeof(AudioStreamBasicDescription); | |
579 err = AudioUnitSetProperty(ao->theOutputUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &inDesc, size); | |
580 | |
581 if (err) { | |
582 ao_msg(MSGT_AO, MSGL_WARN, "Unable to set the input format: [%4.4s]\n", (char *)&err); | |
583 goto err_out2; | |
584 } | |
585 | |
586 size = sizeof(UInt32); | |
587 err = AudioUnitGetProperty(ao->theOutputUnit, kAudioDevicePropertyBufferSize, kAudioUnitScope_Input, 0, &maxFrames, &size); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29212
diff
changeset
|
588 |
29209 | 589 if (err) |
590 { | |
591 ao_msg(MSGT_AO,MSGL_WARN, "AudioUnitGetProperty returned [%4.4s] when getting kAudioDevicePropertyBufferSize\n", (char *)&err); | |
592 goto err_out2; | |
593 } | |
594 | |
31649
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
595 //Set the Current Device to the Default Output Unit. |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
596 err = AudioUnitSetProperty(ao->theOutputUnit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &ao->i_selected_dev, sizeof(ao->i_selected_dev)); |
e55ce930e6ae
Refactor device selection in ao_coreaudio: Add output device selection and correctly set the default device if it's selected.
adrian
parents:
31648
diff
changeset
|
597 |
29209 | 598 ao->chunk_size = maxFrames;//*inDesc.mBytesPerFrame; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29212
diff
changeset
|
599 |
29209 | 600 ao_data.samplerate = inDesc.mSampleRate; |
601 ao_data.channels = inDesc.mChannelsPerFrame; | |
602 ao_data.bps = ao_data.samplerate * inDesc.mBytesPerFrame; | |
603 ao_data.outburst = ao->chunk_size; | |
604 ao_data.buffersize = ao_data.bps; | |
605 | |
606 ao->num_chunks = (ao_data.bps+ao->chunk_size-1)/ao->chunk_size; | |
607 ao->buffer_len = ao->num_chunks * ao->chunk_size; | |
608 ao->buffer = av_fifo_alloc(ao->buffer_len); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29212
diff
changeset
|
609 |
29209 | 610 ao_msg(MSGT_AO,MSGL_V, "using %5d chunks of %d bytes (buffer len %d bytes)\n", (int)ao->num_chunks, (int)ao->chunk_size, (int)ao->buffer_len); |
611 | |
612 renderCallback.inputProc = theRenderProc; | |
613 renderCallback.inputProcRefCon = 0; | |
614 err = AudioUnitSetProperty(ao->theOutputUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &renderCallback, sizeof(AURenderCallbackStruct)); | |
615 if (err) { | |
616 ao_msg(MSGT_AO, MSGL_WARN, "Unable to set the render callback: [%4.4s]\n", (char *)&err); | |
617 goto err_out2; | |
618 } | |
619 | |
620 reset(); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29212
diff
changeset
|
621 |
29209 | 622 return CONTROL_OK; |
623 | |
624 err_out2: | |
625 AudioUnitUninitialize(ao->theOutputUnit); | |
626 err_out1: | |
627 CloseComponent(ao->theOutputUnit); | |
628 err_out: | |
629 av_fifo_free(ao->buffer); | |
630 free(ao); | |
631 ao = NULL; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29212
diff
changeset
|
632 return CONTROL_FALSE; |
29209 | 633 } |
634 | |
635 /***************************************************************************** | |
636 * Setup a encoded digital stream (SPDIF) | |
637 *****************************************************************************/ | |
29212
eda346733b8c
Add missing 'void' to parameterless function declarations.
diego
parents:
29209
diff
changeset
|
638 static int OpenSPDIF(void) |
29209 | 639 { |
31650 | 640 OSStatus err = noErr; |
641 UInt32 i_param_size, b_mix = 0; | |
642 Boolean b_writeable = 0; | |
643 AudioStreamID *p_streams = NULL; | |
644 int i, i_streams = 0; | |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
645 AudioObjectPropertyAddress property_address; |
29209 | 646 |
647 /* Start doing the SPDIF setup process. */ | |
648 ao->b_digital = 1; | |
649 | |
650 /* Hog the device. */ | |
651 ao->i_hog_pid = getpid() ; | |
652 | |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
653 err = SetAudioProperty(ao->i_selected_dev, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
654 kAudioDevicePropertyHogMode, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
655 sizeof(ao->i_hog_pid), &ao->i_hog_pid); |
29209 | 656 if (err != noErr) |
657 { | |
658 ao_msg(MSGT_AO, MSGL_WARN, "failed to set hogmode: [%4.4s]\n", (char *)&err); | |
659 ao->i_hog_pid = -1; | |
660 goto err_out; | |
661 } | |
662 | |
34059 | 663 property_address.mSelector = kAudioDevicePropertySupportsMixing; |
664 property_address.mScope = kAudioObjectPropertyScopeGlobal; | |
665 property_address.mElement = kAudioObjectPropertyElementMaster; | |
666 | |
29209 | 667 /* Set mixable to false if we are allowed to. */ |
34059 | 668 if (AudioObjectHasProperty(ao->i_selected_dev, &property_address)) { |
669 /* Set mixable to false if we are allowed to. */ | |
670 err = IsAudioPropertySettable(ao->i_selected_dev, | |
671 kAudioDevicePropertySupportsMixing, | |
672 &b_writeable); | |
673 err = GetAudioProperty(ao->i_selected_dev, | |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
674 kAudioDevicePropertySupportsMixing, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
675 sizeof(UInt32), &b_mix); |
34059 | 676 if (err == noErr && b_writeable) |
677 { | |
678 b_mix = 0; | |
679 err = SetAudioProperty(ao->i_selected_dev, | |
680 kAudioDevicePropertySupportsMixing, | |
681 sizeof(UInt32), &b_mix); | |
682 ao->b_changed_mixing = 1; | |
683 } | |
684 if (err != noErr) | |
685 { | |
686 ao_msg(MSGT_AO, MSGL_WARN, "failed to set mixmode: [%4.4s]\n", (char *)&err); | |
687 goto err_out; | |
688 } | |
29209 | 689 } |
690 | |
691 /* Get a list of all the streams on this device. */ | |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
692 i_param_size = GetAudioPropertyArray(ao->i_selected_dev, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
693 kAudioDevicePropertyStreams, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
694 kAudioDevicePropertyScopeOutput, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
695 (void **)&p_streams); |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
696 |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
697 if (!i_param_size) { |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
698 ao_msg(MSGT_AO, MSGL_WARN, "could not get number of streams.\n"); |
29209 | 699 goto err_out; |
700 } | |
701 | |
702 i_streams = i_param_size / sizeof(AudioStreamID); | |
703 | |
704 ao_msg(MSGT_AO, MSGL_V, "current device stream number: %d\n", i_streams); | |
705 | |
706 for (i = 0; i < i_streams && ao->i_stream_index < 0; ++i) | |
707 { | |
708 /* Find a stream with a cac3 stream. */ | |
34059 | 709 AudioStreamRangedDescription *p_format_list = NULL; |
29209 | 710 int i_formats = 0, j = 0, b_digital = 0; |
711 | |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
712 i_param_size = GetGlobalAudioPropertyArray(p_streams[i], |
34059 | 713 kAudioStreamPropertyAvailablePhysicalFormats, |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
714 (void **)&p_format_list); |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
715 |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
716 if (!i_param_size) { |
31891
4f17ff5b3cbc
Fix a bunch of grammar and spelling errors in mp_msg calls.
diego
parents:
31660
diff
changeset
|
717 ao_msg(MSGT_AO, MSGL_WARN, |
4f17ff5b3cbc
Fix a bunch of grammar and spelling errors in mp_msg calls.
diego
parents:
31660
diff
changeset
|
718 "Could not get number of stream formats.\n"); |
29209 | 719 continue; |
720 } | |
721 | |
34059 | 722 i_formats = i_param_size / sizeof(AudioStreamRangedDescription); |
29209 | 723 |
724 /* Check if one of the supported formats is a digital format. */ | |
725 for (j = 0; j < i_formats; ++j) | |
726 { | |
34059 | 727 if (p_format_list[j].mFormat.mFormatID == 'IAC3' || |
728 p_format_list[j].mFormat.mFormatID == 'iac3' || | |
729 p_format_list[j].mFormat.mFormatID == kAudioFormat60958AC3 || | |
730 p_format_list[j].mFormat.mFormatID == kAudioFormatAC3) | |
29209 | 731 { |
732 b_digital = 1; | |
733 break; | |
734 } | |
735 } | |
736 | |
737 if (b_digital) | |
738 { | |
739 /* If this stream supports a digital (cac3) format, then set it. */ | |
740 int i_requested_rate_format = -1; | |
741 int i_current_rate_format = -1; | |
742 int i_backup_rate_format = -1; | |
743 | |
744 ao->i_stream_id = p_streams[i]; | |
745 ao->i_stream_index = i; | |
746 | |
747 if (ao->b_revert == 0) | |
748 { | |
749 /* Retrieve the original format of this stream first if not done so already. */ | |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
750 err = GetAudioProperty(ao->i_stream_id, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
751 kAudioStreamPropertyPhysicalFormat, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
752 sizeof(ao->sfmt_revert), &ao->sfmt_revert); |
29209 | 753 if (err != noErr) |
754 { | |
31891
4f17ff5b3cbc
Fix a bunch of grammar and spelling errors in mp_msg calls.
diego
parents:
31660
diff
changeset
|
755 ao_msg(MSGT_AO, MSGL_WARN, |
4f17ff5b3cbc
Fix a bunch of grammar and spelling errors in mp_msg calls.
diego
parents:
31660
diff
changeset
|
756 "Could not retrieve the original stream format: [%4.4s]\n", |
4f17ff5b3cbc
Fix a bunch of grammar and spelling errors in mp_msg calls.
diego
parents:
31660
diff
changeset
|
757 (char *)&err); |
32537
8fa2f43cb760
Remove most of the NULL pointer check before free all over the code
cboesch
parents:
32364
diff
changeset
|
758 free(p_format_list); |
29209 | 759 continue; |
760 } | |
761 ao->b_revert = 1; | |
762 } | |
763 | |
764 for (j = 0; j < i_formats; ++j) | |
34059 | 765 if (p_format_list[j].mFormat.mFormatID == 'IAC3' || |
766 p_format_list[j].mFormat.mFormatID == 'iac3' || | |
767 p_format_list[j].mFormat.mFormatID == kAudioFormat60958AC3 || | |
768 p_format_list[j].mFormat.mFormatID == kAudioFormatAC3) | |
29209 | 769 { |
34059 | 770 if (p_format_list[j].mFormat.mSampleRate == ao->stream_format.mSampleRate) |
29209 | 771 { |
772 i_requested_rate_format = j; | |
773 break; | |
774 } | |
34059 | 775 if (p_format_list[j].mFormat.mSampleRate == ao->sfmt_revert.mSampleRate) |
29209 | 776 i_current_rate_format = j; |
34059 | 777 else if (i_backup_rate_format < 0 || p_format_list[j].mFormat.mSampleRate > p_format_list[i_backup_rate_format].mFormat.mSampleRate) |
29209 | 778 i_backup_rate_format = j; |
779 } | |
780 | |
781 if (i_requested_rate_format >= 0) /* We prefer to output at the samplerate of the original audio. */ | |
34059 | 782 ao->stream_format = p_format_list[i_requested_rate_format].mFormat; |
29209 | 783 else if (i_current_rate_format >= 0) /* If not possible, we will try to use the current samplerate of the device. */ |
34059 | 784 ao->stream_format = p_format_list[i_current_rate_format].mFormat; |
785 else ao->stream_format = p_format_list[i_backup_rate_format].mFormat; /* And if we have to, any digital format will be just fine (highest rate possible). */ | |
29209 | 786 } |
32537
8fa2f43cb760
Remove most of the NULL pointer check before free all over the code
cboesch
parents:
32364
diff
changeset
|
787 free(p_format_list); |
29209 | 788 } |
32537
8fa2f43cb760
Remove most of the NULL pointer check before free all over the code
cboesch
parents:
32364
diff
changeset
|
789 free(p_streams); |
29209 | 790 |
791 if (ao->i_stream_index < 0) | |
792 { | |
31891
4f17ff5b3cbc
Fix a bunch of grammar and spelling errors in mp_msg calls.
diego
parents:
31660
diff
changeset
|
793 ao_msg(MSGT_AO, MSGL_WARN, |
4f17ff5b3cbc
Fix a bunch of grammar and spelling errors in mp_msg calls.
diego
parents:
31660
diff
changeset
|
794 "Cannot find any digital output stream format when OpenSPDIF().\n"); |
29209 | 795 goto err_out; |
796 } | |
797 | |
798 print_format(MSGL_V, "original stream format:", &ao->sfmt_revert); | |
799 | |
800 if (!AudioStreamChangeFormat(ao->i_stream_id, ao->stream_format)) | |
801 goto err_out; | |
802 | |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
803 property_address.mSelector = kAudioDevicePropertyDeviceHasChanged; |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
804 property_address.mScope = kAudioObjectPropertyScopeGlobal; |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
805 property_address.mElement = kAudioObjectPropertyElementMaster; |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
806 |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
807 err = AudioObjectAddPropertyListener(ao->i_selected_dev, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
808 &property_address, |
29209 | 809 DeviceListener, |
810 NULL); | |
811 if (err != noErr) | |
812 ao_msg(MSGT_AO, MSGL_WARN, "AudioDeviceAddPropertyListener for kAudioDevicePropertyDeviceHasChanged failed: [%4.4s]\n", (char *)&err); | |
813 | |
814 | |
815 /* FIXME: If output stream is not native byte-order, we need change endian somewhere. */ | |
816 /* Although there's no such case reported. */ | |
29401
f01023c524c3
Replace WORDS_BIGENDIAN by HAVE_BIGENDIAN in all internal code.
diego
parents:
29263
diff
changeset
|
817 #if HAVE_BIGENDIAN |
29209 | 818 if (!(ao->stream_format.mFormatFlags & kAudioFormatFlagIsBigEndian)) |
819 #else | |
32364
d9c8f66f77e1
AC-3 streams need to be byteswapped on little-endian machines.
diego
parents:
31891
diff
changeset
|
820 /* tell mplayer that we need a byteswap on AC3 streams, */ |
d9c8f66f77e1
AC-3 streams need to be byteswapped on little-endian machines.
diego
parents:
31891
diff
changeset
|
821 if (ao->stream_format.mFormatID & kAudioFormat60958AC3) |
d9c8f66f77e1
AC-3 streams need to be byteswapped on little-endian machines.
diego
parents:
31891
diff
changeset
|
822 ao_data.format = AF_FORMAT_AC3_LE; |
d9c8f66f77e1
AC-3 streams need to be byteswapped on little-endian machines.
diego
parents:
31891
diff
changeset
|
823 |
29209 | 824 if (ao->stream_format.mFormatFlags & kAudioFormatFlagIsBigEndian) |
825 #endif | |
31891
4f17ff5b3cbc
Fix a bunch of grammar and spelling errors in mp_msg calls.
diego
parents:
31660
diff
changeset
|
826 ao_msg(MSGT_AO, MSGL_WARN, |
4f17ff5b3cbc
Fix a bunch of grammar and spelling errors in mp_msg calls.
diego
parents:
31660
diff
changeset
|
827 "Output stream has non-native byte order, digital output may fail.\n"); |
29209 | 828 |
829 /* For ac3/dts, just use packet size 6144 bytes as chunk size. */ | |
830 ao->chunk_size = ao->stream_format.mBytesPerPacket; | |
831 | |
832 ao_data.samplerate = ao->stream_format.mSampleRate; | |
833 ao_data.channels = ao->stream_format.mChannelsPerFrame; | |
834 ao_data.bps = ao_data.samplerate * (ao->stream_format.mBytesPerPacket/ao->stream_format.mFramesPerPacket); | |
835 ao_data.outburst = ao->chunk_size; | |
836 ao_data.buffersize = ao_data.bps; | |
837 | |
838 ao->num_chunks = (ao_data.bps+ao->chunk_size-1)/ao->chunk_size; | |
839 ao->buffer_len = ao->num_chunks * ao->chunk_size; | |
840 ao->buffer = av_fifo_alloc(ao->buffer_len); | |
841 | |
842 ao_msg(MSGT_AO,MSGL_V, "using %5d chunks of %d bytes (buffer len %d bytes)\n", (int)ao->num_chunks, (int)ao->chunk_size, (int)ao->buffer_len); | |
843 | |
844 | |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
845 /* Create IOProc callback. */ |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
846 err = AudioDeviceCreateIOProcID(ao->i_selected_dev, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
847 (AudioDeviceIOProc)RenderCallbackSPDIF, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
848 (void *)ao, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
849 &ao->renderCallback); |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
850 |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
851 if (err != noErr || ao->renderCallback == NULL) |
29209 | 852 { |
853 ao_msg(MSGT_AO, MSGL_WARN, "AudioDeviceAddIOProc failed: [%4.4s]\n", (char *)&err); | |
854 goto err_out1; | |
855 } | |
856 | |
857 reset(); | |
858 | |
859 return CONTROL_TRUE; | |
860 | |
861 err_out1: | |
862 if (ao->b_revert) | |
863 AudioStreamChangeFormat(ao->i_stream_id, ao->sfmt_revert); | |
864 err_out: | |
865 if (ao->b_changed_mixing && ao->sfmt_revert.mFormatID != kAudioFormat60958AC3) | |
866 { | |
867 int b_mix = 1; | |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
868 err = SetAudioProperty(ao->i_selected_dev, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
869 kAudioDevicePropertySupportsMixing, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
870 sizeof(int), &b_mix); |
29209 | 871 if (err != noErr) |
872 ao_msg(MSGT_AO, MSGL_WARN, "failed to set mixmode: [%4.4s]\n", | |
873 (char *)&err); | |
874 } | |
875 if (ao->i_hog_pid == getpid()) | |
876 { | |
877 ao->i_hog_pid = -1; | |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
878 err = SetAudioProperty(ao->i_selected_dev, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
879 kAudioDevicePropertyHogMode, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
880 sizeof(ao->i_hog_pid), &ao->i_hog_pid); |
29209 | 881 if (err != noErr) |
882 ao_msg(MSGT_AO, MSGL_WARN, "Could not release hogmode: [%4.4s]\n", | |
883 (char *)&err); | |
884 } | |
885 av_fifo_free(ao->buffer); | |
886 free(ao); | |
887 ao = NULL; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29212
diff
changeset
|
888 return CONTROL_FALSE; |
29209 | 889 } |
890 | |
891 /***************************************************************************** | |
892 * AudioDeviceSupportsDigital: Check i_dev_id for digital stream support. | |
893 *****************************************************************************/ | |
894 static int AudioDeviceSupportsDigital( AudioDeviceID i_dev_id ) | |
895 { | |
896 UInt32 i_param_size = 0; | |
897 AudioStreamID *p_streams = NULL; | |
898 int i = 0, i_streams = 0; | |
899 int b_return = CONTROL_FALSE; | |
900 | |
901 /* Retrieve all the output streams. */ | |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
902 i_param_size = GetAudioPropertyArray(i_dev_id, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
903 kAudioDevicePropertyStreams, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
904 kAudioDevicePropertyScopeOutput, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
905 (void **)&p_streams); |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
906 |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
907 if (!i_param_size) { |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
908 ao_msg(MSGT_AO, MSGL_WARN, "could not get number of streams.\n"); |
29209 | 909 return CONTROL_FALSE; |
910 } | |
911 | |
912 i_streams = i_param_size / sizeof(AudioStreamID); | |
913 | |
914 for (i = 0; i < i_streams; ++i) | |
915 { | |
916 if (AudioStreamSupportsDigital(p_streams[i])) | |
917 b_return = CONTROL_OK; | |
918 } | |
919 | |
920 free(p_streams); | |
921 return b_return; | |
922 } | |
923 | |
924 /***************************************************************************** | |
925 * AudioStreamSupportsDigital: Check i_stream_id for digital stream support. | |
926 *****************************************************************************/ | |
927 static int AudioStreamSupportsDigital( AudioStreamID i_stream_id ) | |
928 { | |
929 UInt32 i_param_size; | |
34059 | 930 AudioStreamRangedDescription *p_format_list = NULL; |
29209 | 931 int i, i_formats, b_return = CONTROL_FALSE; |
932 | |
933 /* Retrieve all the stream formats supported by each output stream. */ | |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
934 i_param_size = GetGlobalAudioPropertyArray(i_stream_id, |
34059 | 935 kAudioStreamPropertyAvailablePhysicalFormats, |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
936 (void **)&p_format_list); |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
937 |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
938 if (!i_param_size) { |
31891
4f17ff5b3cbc
Fix a bunch of grammar and spelling errors in mp_msg calls.
diego
parents:
31660
diff
changeset
|
939 ao_msg(MSGT_AO, MSGL_WARN, "Could not get number of stream formats.\n"); |
29209 | 940 return CONTROL_FALSE; |
941 } | |
942 | |
34059 | 943 i_formats = i_param_size / sizeof(AudioStreamRangedDescription); |
29209 | 944 |
945 for (i = 0; i < i_formats; ++i) | |
946 { | |
34059 | 947 print_format(MSGL_V, "supported format:", &(p_format_list[i].mFormat)); |
29209 | 948 |
34059 | 949 if (p_format_list[i].mFormat.mFormatID == 'IAC3' || |
950 p_format_list[i].mFormat.mFormatID == 'iac3' || | |
951 p_format_list[i].mFormat.mFormatID == kAudioFormat60958AC3 || | |
952 p_format_list[i].mFormat.mFormatID == kAudioFormatAC3) | |
29209 | 953 b_return = CONTROL_OK; |
954 } | |
955 | |
956 free(p_format_list); | |
957 return b_return; | |
958 } | |
959 | |
960 /***************************************************************************** | |
961 * AudioStreamChangeFormat: Change i_stream_id to change_format | |
962 *****************************************************************************/ | |
963 static int AudioStreamChangeFormat( AudioStreamID i_stream_id, AudioStreamBasicDescription change_format ) | |
964 { | |
965 OSStatus err = noErr; | |
966 int i; | |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
967 AudioObjectPropertyAddress property_address; |
29209 | 968 |
969 static volatile int stream_format_changed; | |
970 stream_format_changed = 0; | |
971 | |
972 print_format(MSGL_V, "setting stream format:", &change_format); | |
973 | |
974 /* Install the callback. */ | |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
975 property_address.mSelector = kAudioStreamPropertyPhysicalFormat; |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
976 property_address.mScope = kAudioObjectPropertyScopeGlobal; |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
977 property_address.mElement = kAudioObjectPropertyElementMaster; |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
978 |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
979 err = AudioObjectAddPropertyListener(i_stream_id, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
980 &property_address, |
29209 | 981 StreamListener, |
982 (void *)&stream_format_changed); | |
983 if (err != noErr) | |
984 { | |
985 ao_msg(MSGT_AO, MSGL_WARN, "AudioStreamAddPropertyListener failed: [%4.4s]\n", (char *)&err); | |
986 return CONTROL_FALSE; | |
987 } | |
988 | |
989 /* Change the format. */ | |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
990 err = SetAudioProperty(i_stream_id, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
991 kAudioStreamPropertyPhysicalFormat, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
992 sizeof(AudioStreamBasicDescription), &change_format); |
29209 | 993 if (err != noErr) |
994 { | |
995 ao_msg(MSGT_AO, MSGL_WARN, "could not set the stream format: [%4.4s]\n", (char *)&err); | |
996 return CONTROL_FALSE; | |
997 } | |
998 | |
999 /* The AudioStreamSetProperty is not only asynchronious, | |
1000 * it is also not Atomic, in its behaviour. | |
1001 * Therefore we check 5 times before we really give up. | |
1002 * FIXME: failing isn't actually implemented yet. */ | |
1003 for (i = 0; i < 5; ++i) | |
1004 { | |
1005 AudioStreamBasicDescription actual_format; | |
1006 int j; | |
1007 for (j = 0; !stream_format_changed && j < 50; ++j) | |
1008 usec_sleep(10000); | |
1009 if (stream_format_changed) | |
1010 stream_format_changed = 0; | |
1011 else | |
1012 ao_msg(MSGT_AO, MSGL_V, "reached timeout\n" ); | |
1013 | |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1014 err = GetAudioProperty(i_stream_id, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1015 kAudioStreamPropertyPhysicalFormat, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1016 sizeof(AudioStreamBasicDescription), &actual_format); |
29209 | 1017 |
1018 print_format(MSGL_V, "actual format in use:", &actual_format); | |
1019 if (actual_format.mSampleRate == change_format.mSampleRate && | |
1020 actual_format.mFormatID == change_format.mFormatID && | |
1021 actual_format.mFramesPerPacket == change_format.mFramesPerPacket) | |
1022 { | |
1023 /* The right format is now active. */ | |
1024 break; | |
1025 } | |
1026 /* We need to check again. */ | |
1027 } | |
1028 | |
1029 /* Removing the property listener. */ | |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1030 err = AudioObjectRemovePropertyListener(i_stream_id, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1031 &property_address, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1032 StreamListener, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1033 (void *)&stream_format_changed); |
29209 | 1034 if (err != noErr) |
1035 { | |
1036 ao_msg(MSGT_AO, MSGL_WARN, "AudioStreamRemovePropertyListener failed: [%4.4s]\n", (char *)&err); | |
1037 return CONTROL_FALSE; | |
1038 } | |
1039 | |
1040 return CONTROL_TRUE; | |
1041 } | |
1042 | |
1043 /***************************************************************************** | |
1044 * RenderCallbackSPDIF: callback for SPDIF audio output | |
1045 *****************************************************************************/ | |
1046 static OSStatus RenderCallbackSPDIF( AudioDeviceID inDevice, | |
1047 const AudioTimeStamp * inNow, | |
1048 const void * inInputData, | |
1049 const AudioTimeStamp * inInputTime, | |
1050 AudioBufferList * outOutputData, | |
1051 const AudioTimeStamp * inOutputTime, | |
1052 void * threadGlobals ) | |
1053 { | |
1054 int amt = av_fifo_size(ao->buffer); | |
1055 int req = outOutputData->mBuffers[ao->i_stream_index].mDataByteSize; | |
1056 | |
1057 if (amt > req) | |
1058 amt = req; | |
1059 if (amt) | |
1060 read_buffer(ao->b_muted ? NULL : (unsigned char *)outOutputData->mBuffers[ao->i_stream_index].mData, amt); | |
1061 | |
1062 return noErr; | |
1063 } | |
1064 | |
1065 | |
1066 static int play(void* output_samples,int num_bytes,int flags) | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29212
diff
changeset
|
1067 { |
29209 | 1068 int wrote, b_digital; |
31651
1b5102a113e0
Process the CoreFoundation runloop in ao_coreaudio in case it's not being processed in the vo, e.g. when vo_corevideo is used with shared_buffer.
adrian
parents:
31650
diff
changeset
|
1069 SInt32 exit_reason; |
29209 | 1070 |
1071 // Check whether we need to reset the digital output stream. | |
1072 if (ao->b_digital && ao->b_stream_format_changed) | |
1073 { | |
1074 ao->b_stream_format_changed = 0; | |
1075 b_digital = AudioStreamSupportsDigital(ao->i_stream_id); | |
1076 if (b_digital) | |
1077 { | |
31891
4f17ff5b3cbc
Fix a bunch of grammar and spelling errors in mp_msg calls.
diego
parents:
31660
diff
changeset
|
1078 /* Current stream supports digital format output, let's set it. */ |
4f17ff5b3cbc
Fix a bunch of grammar and spelling errors in mp_msg calls.
diego
parents:
31660
diff
changeset
|
1079 ao_msg(MSGT_AO, MSGL_V, |
4f17ff5b3cbc
Fix a bunch of grammar and spelling errors in mp_msg calls.
diego
parents:
31660
diff
changeset
|
1080 "Detected current stream supports digital, try to restore digital output...\n"); |
29209 | 1081 |
1082 if (!AudioStreamChangeFormat(ao->i_stream_id, ao->stream_format)) | |
1083 { | |
31891
4f17ff5b3cbc
Fix a bunch of grammar and spelling errors in mp_msg calls.
diego
parents:
31660
diff
changeset
|
1084 ao_msg(MSGT_AO, MSGL_WARN, "Restoring digital output failed.\n"); |
29209 | 1085 } |
1086 else | |
1087 { | |
31891
4f17ff5b3cbc
Fix a bunch of grammar and spelling errors in mp_msg calls.
diego
parents:
31660
diff
changeset
|
1088 ao_msg(MSGT_AO, MSGL_WARN, "Restoring digital output succeeded.\n"); |
29209 | 1089 reset(); |
1090 } | |
1091 } | |
1092 else | |
31891
4f17ff5b3cbc
Fix a bunch of grammar and spelling errors in mp_msg calls.
diego
parents:
31660
diff
changeset
|
1093 ao_msg(MSGT_AO, MSGL_V, "Detected current stream does not support digital.\n"); |
29209 | 1094 } |
1095 | |
1096 wrote=write_buffer(output_samples, num_bytes); | |
1097 audio_resume(); | |
31651
1b5102a113e0
Process the CoreFoundation runloop in ao_coreaudio in case it's not being processed in the vo, e.g. when vo_corevideo is used with shared_buffer.
adrian
parents:
31650
diff
changeset
|
1098 |
1b5102a113e0
Process the CoreFoundation runloop in ao_coreaudio in case it's not being processed in the vo, e.g. when vo_corevideo is used with shared_buffer.
adrian
parents:
31650
diff
changeset
|
1099 do { |
1b5102a113e0
Process the CoreFoundation runloop in ao_coreaudio in case it's not being processed in the vo, e.g. when vo_corevideo is used with shared_buffer.
adrian
parents:
31650
diff
changeset
|
1100 exit_reason = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.01, true); |
1b5102a113e0
Process the CoreFoundation runloop in ao_coreaudio in case it's not being processed in the vo, e.g. when vo_corevideo is used with shared_buffer.
adrian
parents:
31650
diff
changeset
|
1101 } while (exit_reason == kCFRunLoopRunHandledSource); |
1b5102a113e0
Process the CoreFoundation runloop in ao_coreaudio in case it's not being processed in the vo, e.g. when vo_corevideo is used with shared_buffer.
adrian
parents:
31650
diff
changeset
|
1102 |
29209 | 1103 return wrote; |
1104 } | |
1105 | |
1106 /* set variables and buffer to initial state */ | |
1107 static void reset(void) | |
1108 { | |
1109 audio_pause(); | |
1110 av_fifo_reset(ao->buffer); | |
1111 } | |
1112 | |
1113 | |
1114 /* return available space */ | |
1115 static int get_space(void) | |
1116 { | |
1117 return ao->buffer_len - av_fifo_size(ao->buffer); | |
1118 } | |
1119 | |
1120 | |
1121 /* return delay until audio is played */ | |
1122 static float get_delay(void) | |
1123 { | |
1124 // inaccurate, should also contain the data buffered e.g. by the OS | |
1125 return (float)av_fifo_size(ao->buffer)/(float)ao_data.bps; | |
1126 } | |
1127 | |
1128 | |
1129 /* unload plugin and deregister from coreaudio */ | |
1130 static void uninit(int immed) | |
1131 { | |
1132 OSStatus err = noErr; | |
1133 | |
1134 if (!immed) { | |
1135 long long timeleft=(1000000LL*av_fifo_size(ao->buffer))/ao_data.bps; | |
1136 ao_msg(MSGT_AO,MSGL_DBG2, "%d bytes left @%d bps (%d usec)\n", av_fifo_size(ao->buffer), ao_data.bps, (int)timeleft); | |
1137 usec_sleep((int)timeleft); | |
1138 } | |
1139 | |
1140 if (!ao->b_digital) { | |
1141 AudioOutputUnitStop(ao->theOutputUnit); | |
1142 AudioUnitUninitialize(ao->theOutputUnit); | |
1143 CloseComponent(ao->theOutputUnit); | |
1144 } | |
1145 else { | |
1146 /* Stop device. */ | |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1147 err = AudioDeviceStop(ao->i_selected_dev, ao->renderCallback); |
29209 | 1148 if (err != noErr) |
1149 ao_msg(MSGT_AO, MSGL_WARN, "AudioDeviceStop failed: [%4.4s]\n", (char *)&err); | |
1150 | |
1151 /* Remove IOProc callback. */ | |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1152 err = AudioDeviceDestroyIOProcID(ao->i_selected_dev, ao->renderCallback); |
29209 | 1153 if (err != noErr) |
1154 ao_msg(MSGT_AO, MSGL_WARN, "AudioDeviceRemoveIOProc failed: [%4.4s]\n", (char *)&err); | |
1155 | |
1156 if (ao->b_revert) | |
1157 AudioStreamChangeFormat(ao->i_stream_id, ao->sfmt_revert); | |
1158 | |
1159 if (ao->b_changed_mixing && ao->sfmt_revert.mFormatID != kAudioFormat60958AC3) | |
1160 { | |
31648
a09f02987594
Consistently use types as they are used by the API in ao_coreaudio.
adrian
parents:
31647
diff
changeset
|
1161 UInt32 b_mix; |
34059 | 1162 Boolean b_writeable = 0; |
29209 | 1163 /* Revert mixable to true if we are allowed to. */ |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1164 err = IsAudioPropertySettable(ao->i_selected_dev, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1165 kAudioDevicePropertySupportsMixing, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1166 &b_writeable); |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1167 err = GetAudioProperty(ao->i_selected_dev, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1168 kAudioDevicePropertySupportsMixing, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1169 sizeof(UInt32), &b_mix); |
34059 | 1170 if (err == noErr && b_writeable) |
29209 | 1171 { |
1172 b_mix = 1; | |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1173 err = SetAudioProperty(ao->i_selected_dev, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1174 kAudioDevicePropertySupportsMixing, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1175 sizeof(UInt32), &b_mix); |
29209 | 1176 } |
1177 if (err != noErr) | |
1178 ao_msg(MSGT_AO, MSGL_WARN, "failed to set mixmode: [%4.4s]\n", (char *)&err); | |
1179 } | |
1180 if (ao->i_hog_pid == getpid()) | |
1181 { | |
1182 ao->i_hog_pid = -1; | |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1183 err = SetAudioProperty(ao->i_selected_dev, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1184 kAudioDevicePropertyHogMode, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1185 sizeof(ao->i_hog_pid), &ao->i_hog_pid); |
29209 | 1186 if (err != noErr) ao_msg(MSGT_AO, MSGL_WARN, "Could not release hogmode: [%4.4s]\n", (char *)&err); |
1187 } | |
1188 } | |
1189 | |
1190 av_fifo_free(ao->buffer); | |
1191 free(ao); | |
1192 ao = NULL; | |
1193 } | |
1194 | |
1195 | |
1196 /* stop playing, keep buffers (for pause) */ | |
1197 static void audio_pause(void) | |
1198 { | |
1199 OSErr err=noErr; | |
1200 | |
1201 /* Stop callback. */ | |
1202 if (!ao->b_digital) | |
1203 { | |
1204 err=AudioOutputUnitStop(ao->theOutputUnit); | |
1205 if (err != noErr) | |
1206 ao_msg(MSGT_AO,MSGL_WARN, "AudioOutputUnitStop returned [%4.4s]\n", (char *)&err); | |
1207 } | |
1208 else | |
1209 { | |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1210 err = AudioDeviceStop(ao->i_selected_dev, ao->renderCallback); |
29209 | 1211 if (err != noErr) |
1212 ao_msg(MSGT_AO, MSGL_WARN, "AudioDeviceStop failed: [%4.4s]\n", (char *)&err); | |
1213 } | |
1214 ao->paused = 1; | |
1215 } | |
1216 | |
1217 | |
1218 /* resume playing, after audio_pause() */ | |
1219 static void audio_resume(void) | |
1220 { | |
1221 OSErr err=noErr; | |
1222 | |
1223 if (!ao->paused) | |
1224 return; | |
1225 | |
1226 /* Start callback. */ | |
1227 if (!ao->b_digital) | |
1228 { | |
1229 err = AudioOutputUnitStart(ao->theOutputUnit); | |
1230 if (err != noErr) | |
1231 ao_msg(MSGT_AO,MSGL_WARN, "AudioOutputUnitStart returned [%4.4s]\n", (char *)&err); | |
1232 } | |
1233 else | |
1234 { | |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1235 err = AudioDeviceStart(ao->i_selected_dev, ao->renderCallback); |
29209 | 1236 if (err != noErr) |
1237 ao_msg(MSGT_AO, MSGL_WARN, "AudioDeviceStart failed: [%4.4s]\n", (char *)&err); | |
1238 } | |
1239 ao->paused = 0; | |
1240 } | |
1241 | |
1242 /***************************************************************************** | |
1243 * StreamListener | |
1244 *****************************************************************************/ | |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1245 static OSStatus StreamListener( AudioObjectID inObjectID, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1246 UInt32 inNumberAddresses, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1247 const AudioObjectPropertyAddress inAddresses[], |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1248 void *inClientData ) |
29209 | 1249 { |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1250 for (int i=0; i < inNumberAddresses; ++i) |
29209 | 1251 { |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1252 if (inAddresses[i].mSelector == kAudioStreamPropertyPhysicalFormat) { |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1253 ao_msg(MSGT_AO, MSGL_WARN, "got notify kAudioStreamPropertyPhysicalFormat changed.\n"); |
29209 | 1254 if (inClientData) |
1255 *(volatile int *)inClientData = 1; | |
1256 break; | |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1257 } |
29209 | 1258 } |
1259 return noErr; | |
1260 } | |
1261 | |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1262 static OSStatus DeviceListener( AudioObjectID inObjectID, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1263 UInt32 inNumberAddresses, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1264 const AudioObjectPropertyAddress inAddresses[], |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1265 void *inClientData ) |
29209 | 1266 { |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1267 for (int i=0; i < inNumberAddresses; ++i) |
29209 | 1268 { |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1269 if (inAddresses[i].mSelector == kAudioDevicePropertyDeviceHasChanged) { |
29209 | 1270 ao_msg(MSGT_AO, MSGL_WARN, "got notify kAudioDevicePropertyDeviceHasChanged.\n"); |
1271 ao->b_stream_format_changed = 1; | |
1272 break; | |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1273 } |
29209 | 1274 } |
1275 return noErr; | |
1276 } |