Mercurial > mplayer.hg
annotate libao2/ao_coreaudio.c @ 36815:4c44fdd14655
Fix issue with Win32 GUI default preferences.
Don't (mis)use option variables to set defaults (and then don't use
them when actually setting the defaults in the preferences dialog).
Set them directly (and correctly) instead, and use proper symbolic
constants.
author | ib |
---|---|
date | Sun, 23 Feb 2014 19:33:46 +0000 |
parents | efb9481610d2 |
children |
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; |
36006 | 372 int i; |
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
|
373 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
|
374 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
|
375 |
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 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
|
377 "\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
|
378 "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
|
379 " 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
|
380 "\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
|
381 " 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
|
382 " 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
|
383 " 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
|
384 " 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
|
385 "\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 "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
|
387 |
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 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
|
389 |
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 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
|
391 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
|
392 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
|
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 |
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 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
|
396 |
36006 | 397 for (i = 0; i < num_devices; ++i) { |
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
|
398 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
|
399 |
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 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
|
401 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
|
402 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
|
403 } 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
|
404 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
|
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 |
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 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
|
408 |
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 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
|
410 } |
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
|
411 |
29209 | 412 static int init(int rate,int channels,int format,int flags) |
413 { | |
414 AudioStreamBasicDescription inDesc; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29212
diff
changeset
|
415 ComponentDescription desc; |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29212
diff
changeset
|
416 Component comp; |
29209 | 417 AURenderCallbackStruct renderCallback; |
418 OSStatus err; | |
31657
fa6671a1b8dc
Remove some unused variables along with the corresponding warnings.
diego
parents:
31651
diff
changeset
|
419 UInt32 size, maxFrames, b_alive; |
29209 | 420 char *psz_name; |
421 AudioDeviceID devid_def = 0; | |
31659
a05f97bad2a9
Improve handling of the "help" suboption in coreaudio:
adrian
parents:
31657
diff
changeset
|
422 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
|
423 |
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
|
424 const opt_t subopts[] = { |
31660 | 425 {"device_id", OPT_ARG_INT, &device_id, NULL}, |
426 {"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
|
427 {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
|
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 |
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 // 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
|
431 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
|
432 |
31659
a05f97bad2a9
Improve handling of the "help" suboption in coreaudio:
adrian
parents:
31657
diff
changeset
|
433 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
|
434 print_help(); |
31659
a05f97bad2a9
Improve handling of the "help" suboption in coreaudio:
adrian
parents:
31657
diff
changeset
|
435 if (!display_help) |
31660 | 436 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
|
437 } |
29209 | 438 |
439 ao_msg(MSGT_AO,MSGL_V, "init([%dHz][%dch][%s][%d])\n", rate, channels, af_fmt2str_short(format), flags); | |
440 | |
441 ao = calloc(1, sizeof(ao_coreaudio_t)); | |
442 | |
443 ao->i_selected_dev = 0; | |
444 ao->b_supports_digital = 0; | |
445 ao->b_digital = 0; | |
446 ao->b_muted = 0; | |
447 ao->b_stream_format_changed = 0; | |
448 ao->i_hog_pid = -1; | |
449 ao->i_stream_id = 0; | |
450 ao->i_stream_index = -1; | |
451 ao->b_revert = 0; | |
452 ao->b_changed_mixing = 0; | |
453 | |
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
|
454 if (device_id == 0) { |
29209 | 455 /* 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
|
456 err = GetAudioProperty(kAudioObjectSystemObject, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
457 kAudioHardwarePropertyDefaultOutputDevice, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
458 sizeof(UInt32), &devid_def); |
29209 | 459 if (err != noErr) |
460 { | |
461 ao_msg(MSGT_AO, MSGL_WARN, "could not get default audio device: [%4.4s]\n", (char *)&err); | |
462 goto err_out; | |
463 } | |
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
|
464 } 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
|
465 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
|
466 } |
29209 | 467 |
31650 | 468 /* Retrieve the name of the device. */ |
469 err = GetAudioPropertyString(devid_def, | |
470 kAudioObjectPropertyName, | |
471 &psz_name); | |
472 if (err != noErr) | |
473 { | |
474 ao_msg(MSGT_AO, MSGL_WARN, "could not get default audio device name: [%4.4s]\n", (char *)&err); | |
475 goto err_out; | |
476 } | |
29209 | 477 |
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
|
478 ao_msg(MSGT_AO,MSGL_V, "got audio output device ID: %"PRIu32" Name: %s\n", devid_def, psz_name ); |
29209 | 479 |
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
|
480 /* 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
|
481 if (AF_FORMAT_IS_AC3(format)) { |
29209 | 482 if (AudioDeviceSupportsDigital(devid_def)) |
483 { | |
484 ao->b_supports_digital = 1; | |
485 } | |
31891
4f17ff5b3cbc
Fix a bunch of grammar and spelling errors in mp_msg calls.
diego
parents:
31660
diff
changeset
|
486 ao_msg(MSGT_AO, MSGL_V, |
4f17ff5b3cbc
Fix a bunch of grammar and spelling errors in mp_msg calls.
diego
parents:
31660
diff
changeset
|
487 "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
|
488 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
|
489 } |
29209 | 490 |
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
|
491 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
|
492 |
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 // 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
|
494 ao->i_selected_dev = devid_def; |
29209 | 495 |
496 // Build Description for the input format | |
497 inDesc.mSampleRate=rate; | |
498 inDesc.mFormatID=ao->b_supports_digital ? kAudioFormat60958AC3 : kAudioFormatLinearPCM; | |
499 inDesc.mChannelsPerFrame=channels; | |
30235 | 500 inDesc.mBitsPerChannel=af_fmt2bits(format); |
29209 | 501 |
502 if((format&AF_FORMAT_POINT_MASK)==AF_FORMAT_F) { | |
503 // float | |
504 inDesc.mFormatFlags = kAudioFormatFlagIsFloat|kAudioFormatFlagIsPacked; | |
505 } | |
506 else if((format&AF_FORMAT_SIGN_MASK)==AF_FORMAT_SI) { | |
507 // signed int | |
508 inDesc.mFormatFlags = kAudioFormatFlagIsSignedInteger|kAudioFormatFlagIsPacked; | |
509 } | |
510 else { | |
511 // unsigned int | |
512 inDesc.mFormatFlags = kAudioFormatFlagIsPacked; | |
513 } | |
30242
03c1ad03f29d
MPlayer's format now correctly identifies AC3 as either little- or big-endian,
reimar
parents:
30235
diff
changeset
|
514 if ((format & AF_FORMAT_END_MASK) == AF_FORMAT_BE) |
29209 | 515 inDesc.mFormatFlags |= kAudioFormatFlagIsBigEndian; |
516 | |
517 inDesc.mFramesPerPacket = 1; | |
518 ao->packetSize = inDesc.mBytesPerPacket = inDesc.mBytesPerFrame = inDesc.mFramesPerPacket*channels*(inDesc.mBitsPerChannel/8); | |
519 print_format(MSGL_V, "source:",&inDesc); | |
520 | |
521 if (ao->b_supports_digital) | |
522 { | |
523 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
|
524 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
|
525 kAudioDevicePropertyDeviceIsAlive, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
526 sizeof(UInt32), &b_alive); |
29209 | 527 if (err != noErr) |
528 ao_msg(MSGT_AO, MSGL_WARN, "could not check whether device is alive: [%4.4s]\n", (char *)&err); | |
529 if (!b_alive) | |
530 ao_msg(MSGT_AO, MSGL_WARN, "device is not alive\n" ); | |
31650 | 531 |
29209 | 532 /* 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
|
533 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
|
534 kAudioDevicePropertyHogMode, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
535 sizeof(pid_t), &ao->i_hog_pid); |
29209 | 536 if (err != noErr) |
537 { | |
538 /* This is not a fatal error. Some drivers simply don't support this property. */ | |
539 ao_msg(MSGT_AO, MSGL_WARN, "could not check whether device is hogged: [%4.4s]\n", | |
540 (char *)&err); | |
541 ao->i_hog_pid = -1; | |
542 } | |
543 | |
544 if (ao->i_hog_pid != -1 && ao->i_hog_pid != getpid()) | |
545 { | |
546 ao_msg(MSGT_AO, MSGL_WARN, "Selected audio device is exclusively in use by another program.\n" ); | |
547 goto err_out; | |
548 } | |
549 ao->stream_format = inDesc; | |
550 return OpenSPDIF(); | |
551 } | |
552 | |
553 /* original analog output code */ | |
554 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
|
555 desc.componentSubType = (device_id == 0) ? kAudioUnitSubType_DefaultOutput : kAudioUnitSubType_HALOutput; |
29209 | 556 desc.componentManufacturer = kAudioUnitManufacturer_Apple; |
557 desc.componentFlags = 0; | |
558 desc.componentFlagsMask = 0; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29212
diff
changeset
|
559 |
29209 | 560 comp = FindNextComponent(NULL, &desc); //Finds an component that meets the desc spec's |
561 if (comp == NULL) { | |
562 ao_msg(MSGT_AO, MSGL_WARN, "Unable to find Output Unit component\n"); | |
563 goto err_out; | |
564 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29212
diff
changeset
|
565 |
29209 | 566 err = OpenAComponent(comp, &(ao->theOutputUnit)); //gains access to the services provided by the component |
567 if (err) { | |
568 ao_msg(MSGT_AO, MSGL_WARN, "Unable to open Output Unit component: [%4.4s]\n", (char *)&err); | |
569 goto err_out; | |
570 } | |
571 | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29212
diff
changeset
|
572 // Initialize AudioUnit |
29209 | 573 err = AudioUnitInitialize(ao->theOutputUnit); |
574 if (err) { | |
575 ao_msg(MSGT_AO, MSGL_WARN, "Unable to initialize Output Unit component: [%4.4s]\n", (char *)&err); | |
576 goto err_out1; | |
577 } | |
578 | |
579 size = sizeof(AudioStreamBasicDescription); | |
580 err = AudioUnitSetProperty(ao->theOutputUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &inDesc, size); | |
581 | |
582 if (err) { | |
583 ao_msg(MSGT_AO, MSGL_WARN, "Unable to set the input format: [%4.4s]\n", (char *)&err); | |
584 goto err_out2; | |
585 } | |
586 | |
587 size = sizeof(UInt32); | |
588 err = AudioUnitGetProperty(ao->theOutputUnit, kAudioDevicePropertyBufferSize, kAudioUnitScope_Input, 0, &maxFrames, &size); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29212
diff
changeset
|
589 |
29209 | 590 if (err) |
591 { | |
592 ao_msg(MSGT_AO,MSGL_WARN, "AudioUnitGetProperty returned [%4.4s] when getting kAudioDevicePropertyBufferSize\n", (char *)&err); | |
593 goto err_out2; | |
594 } | |
595 | |
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
|
596 //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
|
597 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
|
598 |
29209 | 599 ao->chunk_size = maxFrames;//*inDesc.mBytesPerFrame; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29212
diff
changeset
|
600 |
29209 | 601 ao_data.samplerate = inDesc.mSampleRate; |
602 ao_data.channels = inDesc.mChannelsPerFrame; | |
603 ao_data.bps = ao_data.samplerate * inDesc.mBytesPerFrame; | |
604 ao_data.outburst = ao->chunk_size; | |
605 ao_data.buffersize = ao_data.bps; | |
606 | |
607 ao->num_chunks = (ao_data.bps+ao->chunk_size-1)/ao->chunk_size; | |
608 ao->buffer_len = ao->num_chunks * ao->chunk_size; | |
609 ao->buffer = av_fifo_alloc(ao->buffer_len); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29212
diff
changeset
|
610 |
29209 | 611 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); |
612 | |
613 renderCallback.inputProc = theRenderProc; | |
614 renderCallback.inputProcRefCon = 0; | |
615 err = AudioUnitSetProperty(ao->theOutputUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &renderCallback, sizeof(AURenderCallbackStruct)); | |
616 if (err) { | |
617 ao_msg(MSGT_AO, MSGL_WARN, "Unable to set the render callback: [%4.4s]\n", (char *)&err); | |
618 goto err_out2; | |
619 } | |
620 | |
621 reset(); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29212
diff
changeset
|
622 |
29209 | 623 return CONTROL_OK; |
624 | |
625 err_out2: | |
626 AudioUnitUninitialize(ao->theOutputUnit); | |
627 err_out1: | |
628 CloseComponent(ao->theOutputUnit); | |
629 err_out: | |
630 av_fifo_free(ao->buffer); | |
631 free(ao); | |
632 ao = NULL; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29212
diff
changeset
|
633 return CONTROL_FALSE; |
29209 | 634 } |
635 | |
636 /***************************************************************************** | |
637 * Setup a encoded digital stream (SPDIF) | |
638 *****************************************************************************/ | |
29212
eda346733b8c
Add missing 'void' to parameterless function declarations.
diego
parents:
29209
diff
changeset
|
639 static int OpenSPDIF(void) |
29209 | 640 { |
31650 | 641 OSStatus err = noErr; |
642 UInt32 i_param_size, b_mix = 0; | |
643 Boolean b_writeable = 0; | |
644 AudioStreamID *p_streams = NULL; | |
645 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
|
646 AudioObjectPropertyAddress property_address; |
29209 | 647 |
648 /* Start doing the SPDIF setup process. */ | |
649 ao->b_digital = 1; | |
650 | |
651 /* Hog the device. */ | |
652 ao->i_hog_pid = getpid() ; | |
653 | |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
654 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
|
655 kAudioDevicePropertyHogMode, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
656 sizeof(ao->i_hog_pid), &ao->i_hog_pid); |
29209 | 657 if (err != noErr) |
658 { | |
659 ao_msg(MSGT_AO, MSGL_WARN, "failed to set hogmode: [%4.4s]\n", (char *)&err); | |
660 ao->i_hog_pid = -1; | |
661 goto err_out; | |
662 } | |
663 | |
34059 | 664 property_address.mSelector = kAudioDevicePropertySupportsMixing; |
665 property_address.mScope = kAudioObjectPropertyScopeGlobal; | |
666 property_address.mElement = kAudioObjectPropertyElementMaster; | |
667 | |
29209 | 668 /* Set mixable to false if we are allowed to. */ |
34059 | 669 if (AudioObjectHasProperty(ao->i_selected_dev, &property_address)) { |
670 /* Set mixable to false if we are allowed to. */ | |
671 err = IsAudioPropertySettable(ao->i_selected_dev, | |
672 kAudioDevicePropertySupportsMixing, | |
673 &b_writeable); | |
674 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
|
675 kAudioDevicePropertySupportsMixing, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
676 sizeof(UInt32), &b_mix); |
34059 | 677 if (err == noErr && b_writeable) |
678 { | |
679 b_mix = 0; | |
680 err = SetAudioProperty(ao->i_selected_dev, | |
681 kAudioDevicePropertySupportsMixing, | |
682 sizeof(UInt32), &b_mix); | |
683 ao->b_changed_mixing = 1; | |
684 } | |
685 if (err != noErr) | |
686 { | |
687 ao_msg(MSGT_AO, MSGL_WARN, "failed to set mixmode: [%4.4s]\n", (char *)&err); | |
688 goto err_out; | |
689 } | |
29209 | 690 } |
691 | |
692 /* 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
|
693 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
|
694 kAudioDevicePropertyStreams, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
695 kAudioDevicePropertyScopeOutput, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
696 (void **)&p_streams); |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
697 |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
698 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
|
699 ao_msg(MSGT_AO, MSGL_WARN, "could not get number of streams.\n"); |
29209 | 700 goto err_out; |
701 } | |
702 | |
703 i_streams = i_param_size / sizeof(AudioStreamID); | |
704 | |
705 ao_msg(MSGT_AO, MSGL_V, "current device stream number: %d\n", i_streams); | |
706 | |
707 for (i = 0; i < i_streams && ao->i_stream_index < 0; ++i) | |
708 { | |
709 /* Find a stream with a cac3 stream. */ | |
34059 | 710 AudioStreamRangedDescription *p_format_list = NULL; |
29209 | 711 int i_formats = 0, j = 0, b_digital = 0; |
712 | |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
713 i_param_size = GetGlobalAudioPropertyArray(p_streams[i], |
34059 | 714 kAudioStreamPropertyAvailablePhysicalFormats, |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
715 (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
|
716 |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
717 if (!i_param_size) { |
31891
4f17ff5b3cbc
Fix a bunch of grammar and spelling errors in mp_msg calls.
diego
parents:
31660
diff
changeset
|
718 ao_msg(MSGT_AO, MSGL_WARN, |
4f17ff5b3cbc
Fix a bunch of grammar and spelling errors in mp_msg calls.
diego
parents:
31660
diff
changeset
|
719 "Could not get number of stream formats.\n"); |
29209 | 720 continue; |
721 } | |
722 | |
34059 | 723 i_formats = i_param_size / sizeof(AudioStreamRangedDescription); |
29209 | 724 |
725 /* Check if one of the supported formats is a digital format. */ | |
726 for (j = 0; j < i_formats; ++j) | |
727 { | |
34059 | 728 if (p_format_list[j].mFormat.mFormatID == 'IAC3' || |
729 p_format_list[j].mFormat.mFormatID == 'iac3' || | |
730 p_format_list[j].mFormat.mFormatID == kAudioFormat60958AC3 || | |
731 p_format_list[j].mFormat.mFormatID == kAudioFormatAC3) | |
29209 | 732 { |
733 b_digital = 1; | |
734 break; | |
735 } | |
736 } | |
737 | |
738 if (b_digital) | |
739 { | |
740 /* If this stream supports a digital (cac3) format, then set it. */ | |
741 int i_requested_rate_format = -1; | |
742 int i_current_rate_format = -1; | |
743 int i_backup_rate_format = -1; | |
744 | |
745 ao->i_stream_id = p_streams[i]; | |
746 ao->i_stream_index = i; | |
747 | |
748 if (ao->b_revert == 0) | |
749 { | |
750 /* 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
|
751 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
|
752 kAudioStreamPropertyPhysicalFormat, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
753 sizeof(ao->sfmt_revert), &ao->sfmt_revert); |
29209 | 754 if (err != noErr) |
755 { | |
31891
4f17ff5b3cbc
Fix a bunch of grammar and spelling errors in mp_msg calls.
diego
parents:
31660
diff
changeset
|
756 ao_msg(MSGT_AO, MSGL_WARN, |
4f17ff5b3cbc
Fix a bunch of grammar and spelling errors in mp_msg calls.
diego
parents:
31660
diff
changeset
|
757 "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
|
758 (char *)&err); |
32537
8fa2f43cb760
Remove most of the NULL pointer check before free all over the code
cboesch
parents:
32364
diff
changeset
|
759 free(p_format_list); |
29209 | 760 continue; |
761 } | |
762 ao->b_revert = 1; | |
763 } | |
764 | |
765 for (j = 0; j < i_formats; ++j) | |
34059 | 766 if (p_format_list[j].mFormat.mFormatID == 'IAC3' || |
767 p_format_list[j].mFormat.mFormatID == 'iac3' || | |
768 p_format_list[j].mFormat.mFormatID == kAudioFormat60958AC3 || | |
769 p_format_list[j].mFormat.mFormatID == kAudioFormatAC3) | |
29209 | 770 { |
34059 | 771 if (p_format_list[j].mFormat.mSampleRate == ao->stream_format.mSampleRate) |
29209 | 772 { |
773 i_requested_rate_format = j; | |
774 break; | |
775 } | |
34059 | 776 if (p_format_list[j].mFormat.mSampleRate == ao->sfmt_revert.mSampleRate) |
29209 | 777 i_current_rate_format = j; |
34059 | 778 else if (i_backup_rate_format < 0 || p_format_list[j].mFormat.mSampleRate > p_format_list[i_backup_rate_format].mFormat.mSampleRate) |
29209 | 779 i_backup_rate_format = j; |
780 } | |
781 | |
782 if (i_requested_rate_format >= 0) /* We prefer to output at the samplerate of the original audio. */ | |
34059 | 783 ao->stream_format = p_format_list[i_requested_rate_format].mFormat; |
29209 | 784 else if (i_current_rate_format >= 0) /* If not possible, we will try to use the current samplerate of the device. */ |
34059 | 785 ao->stream_format = p_format_list[i_current_rate_format].mFormat; |
786 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 | 787 } |
32537
8fa2f43cb760
Remove most of the NULL pointer check before free all over the code
cboesch
parents:
32364
diff
changeset
|
788 free(p_format_list); |
29209 | 789 } |
32537
8fa2f43cb760
Remove most of the NULL pointer check before free all over the code
cboesch
parents:
32364
diff
changeset
|
790 free(p_streams); |
29209 | 791 |
792 if (ao->i_stream_index < 0) | |
793 { | |
31891
4f17ff5b3cbc
Fix a bunch of grammar and spelling errors in mp_msg calls.
diego
parents:
31660
diff
changeset
|
794 ao_msg(MSGT_AO, MSGL_WARN, |
4f17ff5b3cbc
Fix a bunch of grammar and spelling errors in mp_msg calls.
diego
parents:
31660
diff
changeset
|
795 "Cannot find any digital output stream format when OpenSPDIF().\n"); |
29209 | 796 goto err_out; |
797 } | |
798 | |
799 print_format(MSGL_V, "original stream format:", &ao->sfmt_revert); | |
800 | |
801 if (!AudioStreamChangeFormat(ao->i_stream_id, ao->stream_format)) | |
802 goto err_out; | |
803 | |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
804 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
|
805 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
|
806 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
|
807 |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
808 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
|
809 &property_address, |
29209 | 810 DeviceListener, |
811 NULL); | |
812 if (err != noErr) | |
813 ao_msg(MSGT_AO, MSGL_WARN, "AudioDeviceAddPropertyListener for kAudioDevicePropertyDeviceHasChanged failed: [%4.4s]\n", (char *)&err); | |
814 | |
815 | |
816 /* FIXME: If output stream is not native byte-order, we need change endian somewhere. */ | |
817 /* Although there's no such case reported. */ | |
29401
f01023c524c3
Replace WORDS_BIGENDIAN by HAVE_BIGENDIAN in all internal code.
diego
parents:
29263
diff
changeset
|
818 #if HAVE_BIGENDIAN |
29209 | 819 if (!(ao->stream_format.mFormatFlags & kAudioFormatFlagIsBigEndian)) |
820 #else | |
32364
d9c8f66f77e1
AC-3 streams need to be byteswapped on little-endian machines.
diego
parents:
31891
diff
changeset
|
821 /* 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
|
822 if (ao->stream_format.mFormatID & kAudioFormat60958AC3) |
d9c8f66f77e1
AC-3 streams need to be byteswapped on little-endian machines.
diego
parents:
31891
diff
changeset
|
823 ao_data.format = AF_FORMAT_AC3_LE; |
d9c8f66f77e1
AC-3 streams need to be byteswapped on little-endian machines.
diego
parents:
31891
diff
changeset
|
824 |
29209 | 825 if (ao->stream_format.mFormatFlags & kAudioFormatFlagIsBigEndian) |
826 #endif | |
31891
4f17ff5b3cbc
Fix a bunch of grammar and spelling errors in mp_msg calls.
diego
parents:
31660
diff
changeset
|
827 ao_msg(MSGT_AO, MSGL_WARN, |
4f17ff5b3cbc
Fix a bunch of grammar and spelling errors in mp_msg calls.
diego
parents:
31660
diff
changeset
|
828 "Output stream has non-native byte order, digital output may fail.\n"); |
29209 | 829 |
830 /* For ac3/dts, just use packet size 6144 bytes as chunk size. */ | |
831 ao->chunk_size = ao->stream_format.mBytesPerPacket; | |
832 | |
833 ao_data.samplerate = ao->stream_format.mSampleRate; | |
834 ao_data.channels = ao->stream_format.mChannelsPerFrame; | |
835 ao_data.bps = ao_data.samplerate * (ao->stream_format.mBytesPerPacket/ao->stream_format.mFramesPerPacket); | |
836 ao_data.outburst = ao->chunk_size; | |
837 ao_data.buffersize = ao_data.bps; | |
838 | |
839 ao->num_chunks = (ao_data.bps+ao->chunk_size-1)/ao->chunk_size; | |
840 ao->buffer_len = ao->num_chunks * ao->chunk_size; | |
841 ao->buffer = av_fifo_alloc(ao->buffer_len); | |
842 | |
843 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); | |
844 | |
845 | |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
846 /* Create IOProc callback. */ |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
847 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
|
848 (AudioDeviceIOProc)RenderCallbackSPDIF, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
849 (void *)ao, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
850 &ao->renderCallback); |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
851 |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
852 if (err != noErr || ao->renderCallback == NULL) |
29209 | 853 { |
854 ao_msg(MSGT_AO, MSGL_WARN, "AudioDeviceAddIOProc failed: [%4.4s]\n", (char *)&err); | |
855 goto err_out1; | |
856 } | |
857 | |
858 reset(); | |
859 | |
860 return CONTROL_TRUE; | |
861 | |
862 err_out1: | |
863 if (ao->b_revert) | |
864 AudioStreamChangeFormat(ao->i_stream_id, ao->sfmt_revert); | |
865 err_out: | |
866 if (ao->b_changed_mixing && ao->sfmt_revert.mFormatID != kAudioFormat60958AC3) | |
867 { | |
868 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
|
869 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
|
870 kAudioDevicePropertySupportsMixing, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
871 sizeof(int), &b_mix); |
29209 | 872 if (err != noErr) |
873 ao_msg(MSGT_AO, MSGL_WARN, "failed to set mixmode: [%4.4s]\n", | |
874 (char *)&err); | |
875 } | |
876 if (ao->i_hog_pid == getpid()) | |
877 { | |
878 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
|
879 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
|
880 kAudioDevicePropertyHogMode, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
881 sizeof(ao->i_hog_pid), &ao->i_hog_pid); |
29209 | 882 if (err != noErr) |
883 ao_msg(MSGT_AO, MSGL_WARN, "Could not release hogmode: [%4.4s]\n", | |
884 (char *)&err); | |
885 } | |
886 av_fifo_free(ao->buffer); | |
887 free(ao); | |
888 ao = NULL; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29212
diff
changeset
|
889 return CONTROL_FALSE; |
29209 | 890 } |
891 | |
892 /***************************************************************************** | |
893 * AudioDeviceSupportsDigital: Check i_dev_id for digital stream support. | |
894 *****************************************************************************/ | |
895 static int AudioDeviceSupportsDigital( AudioDeviceID i_dev_id ) | |
896 { | |
897 UInt32 i_param_size = 0; | |
898 AudioStreamID *p_streams = NULL; | |
899 int i = 0, i_streams = 0; | |
900 int b_return = CONTROL_FALSE; | |
901 | |
902 /* 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
|
903 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
|
904 kAudioDevicePropertyStreams, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
905 kAudioDevicePropertyScopeOutput, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
906 (void **)&p_streams); |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
907 |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
908 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
|
909 ao_msg(MSGT_AO, MSGL_WARN, "could not get number of streams.\n"); |
29209 | 910 return CONTROL_FALSE; |
911 } | |
912 | |
913 i_streams = i_param_size / sizeof(AudioStreamID); | |
914 | |
915 for (i = 0; i < i_streams; ++i) | |
916 { | |
917 if (AudioStreamSupportsDigital(p_streams[i])) | |
918 b_return = CONTROL_OK; | |
919 } | |
920 | |
921 free(p_streams); | |
922 return b_return; | |
923 } | |
924 | |
925 /***************************************************************************** | |
926 * AudioStreamSupportsDigital: Check i_stream_id for digital stream support. | |
927 *****************************************************************************/ | |
928 static int AudioStreamSupportsDigital( AudioStreamID i_stream_id ) | |
929 { | |
930 UInt32 i_param_size; | |
34059 | 931 AudioStreamRangedDescription *p_format_list = NULL; |
29209 | 932 int i, i_formats, b_return = CONTROL_FALSE; |
933 | |
934 /* 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
|
935 i_param_size = GetGlobalAudioPropertyArray(i_stream_id, |
34059 | 936 kAudioStreamPropertyAvailablePhysicalFormats, |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
937 (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
|
938 |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
939 if (!i_param_size) { |
31891
4f17ff5b3cbc
Fix a bunch of grammar and spelling errors in mp_msg calls.
diego
parents:
31660
diff
changeset
|
940 ao_msg(MSGT_AO, MSGL_WARN, "Could not get number of stream formats.\n"); |
29209 | 941 return CONTROL_FALSE; |
942 } | |
943 | |
34059 | 944 i_formats = i_param_size / sizeof(AudioStreamRangedDescription); |
29209 | 945 |
946 for (i = 0; i < i_formats; ++i) | |
947 { | |
34059 | 948 print_format(MSGL_V, "supported format:", &(p_format_list[i].mFormat)); |
29209 | 949 |
34059 | 950 if (p_format_list[i].mFormat.mFormatID == 'IAC3' || |
951 p_format_list[i].mFormat.mFormatID == 'iac3' || | |
952 p_format_list[i].mFormat.mFormatID == kAudioFormat60958AC3 || | |
953 p_format_list[i].mFormat.mFormatID == kAudioFormatAC3) | |
29209 | 954 b_return = CONTROL_OK; |
955 } | |
956 | |
957 free(p_format_list); | |
958 return b_return; | |
959 } | |
960 | |
961 /***************************************************************************** | |
962 * AudioStreamChangeFormat: Change i_stream_id to change_format | |
963 *****************************************************************************/ | |
964 static int AudioStreamChangeFormat( AudioStreamID i_stream_id, AudioStreamBasicDescription change_format ) | |
965 { | |
966 OSStatus err = noErr; | |
967 int i; | |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
968 AudioObjectPropertyAddress property_address; |
29209 | 969 |
970 static volatile int stream_format_changed; | |
971 stream_format_changed = 0; | |
972 | |
973 print_format(MSGL_V, "setting stream format:", &change_format); | |
974 | |
975 /* 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
|
976 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
|
977 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
|
978 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
|
979 |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
980 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
|
981 &property_address, |
29209 | 982 StreamListener, |
983 (void *)&stream_format_changed); | |
984 if (err != noErr) | |
985 { | |
986 ao_msg(MSGT_AO, MSGL_WARN, "AudioStreamAddPropertyListener failed: [%4.4s]\n", (char *)&err); | |
987 return CONTROL_FALSE; | |
988 } | |
989 | |
990 /* 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
|
991 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
|
992 kAudioStreamPropertyPhysicalFormat, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
993 sizeof(AudioStreamBasicDescription), &change_format); |
29209 | 994 if (err != noErr) |
995 { | |
996 ao_msg(MSGT_AO, MSGL_WARN, "could not set the stream format: [%4.4s]\n", (char *)&err); | |
997 return CONTROL_FALSE; | |
998 } | |
999 | |
1000 /* The AudioStreamSetProperty is not only asynchronious, | |
1001 * it is also not Atomic, in its behaviour. | |
1002 * Therefore we check 5 times before we really give up. | |
1003 * FIXME: failing isn't actually implemented yet. */ | |
1004 for (i = 0; i < 5; ++i) | |
1005 { | |
1006 AudioStreamBasicDescription actual_format; | |
1007 int j; | |
1008 for (j = 0; !stream_format_changed && j < 50; ++j) | |
1009 usec_sleep(10000); | |
1010 if (stream_format_changed) | |
1011 stream_format_changed = 0; | |
1012 else | |
1013 ao_msg(MSGT_AO, MSGL_V, "reached timeout\n" ); | |
1014 | |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1015 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
|
1016 kAudioStreamPropertyPhysicalFormat, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1017 sizeof(AudioStreamBasicDescription), &actual_format); |
29209 | 1018 |
1019 print_format(MSGL_V, "actual format in use:", &actual_format); | |
1020 if (actual_format.mSampleRate == change_format.mSampleRate && | |
1021 actual_format.mFormatID == change_format.mFormatID && | |
1022 actual_format.mFramesPerPacket == change_format.mFramesPerPacket) | |
1023 { | |
1024 /* The right format is now active. */ | |
1025 break; | |
1026 } | |
1027 /* We need to check again. */ | |
1028 } | |
1029 | |
1030 /* 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
|
1031 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
|
1032 &property_address, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1033 StreamListener, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1034 (void *)&stream_format_changed); |
29209 | 1035 if (err != noErr) |
1036 { | |
1037 ao_msg(MSGT_AO, MSGL_WARN, "AudioStreamRemovePropertyListener failed: [%4.4s]\n", (char *)&err); | |
1038 return CONTROL_FALSE; | |
1039 } | |
1040 | |
1041 return CONTROL_TRUE; | |
1042 } | |
1043 | |
1044 /***************************************************************************** | |
1045 * RenderCallbackSPDIF: callback for SPDIF audio output | |
1046 *****************************************************************************/ | |
1047 static OSStatus RenderCallbackSPDIF( AudioDeviceID inDevice, | |
1048 const AudioTimeStamp * inNow, | |
1049 const void * inInputData, | |
1050 const AudioTimeStamp * inInputTime, | |
1051 AudioBufferList * outOutputData, | |
1052 const AudioTimeStamp * inOutputTime, | |
1053 void * threadGlobals ) | |
1054 { | |
1055 int amt = av_fifo_size(ao->buffer); | |
1056 int req = outOutputData->mBuffers[ao->i_stream_index].mDataByteSize; | |
1057 | |
1058 if (amt > req) | |
1059 amt = req; | |
1060 if (amt) | |
1061 read_buffer(ao->b_muted ? NULL : (unsigned char *)outOutputData->mBuffers[ao->i_stream_index].mData, amt); | |
1062 | |
1063 return noErr; | |
1064 } | |
1065 | |
1066 | |
1067 static int play(void* output_samples,int num_bytes,int flags) | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29212
diff
changeset
|
1068 { |
29209 | 1069 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
|
1070 SInt32 exit_reason; |
29209 | 1071 |
1072 // Check whether we need to reset the digital output stream. | |
1073 if (ao->b_digital && ao->b_stream_format_changed) | |
1074 { | |
1075 ao->b_stream_format_changed = 0; | |
1076 b_digital = AudioStreamSupportsDigital(ao->i_stream_id); | |
1077 if (b_digital) | |
1078 { | |
31891
4f17ff5b3cbc
Fix a bunch of grammar and spelling errors in mp_msg calls.
diego
parents:
31660
diff
changeset
|
1079 /* 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
|
1080 ao_msg(MSGT_AO, MSGL_V, |
4f17ff5b3cbc
Fix a bunch of grammar and spelling errors in mp_msg calls.
diego
parents:
31660
diff
changeset
|
1081 "Detected current stream supports digital, try to restore digital output...\n"); |
29209 | 1082 |
1083 if (!AudioStreamChangeFormat(ao->i_stream_id, ao->stream_format)) | |
1084 { | |
31891
4f17ff5b3cbc
Fix a bunch of grammar and spelling errors in mp_msg calls.
diego
parents:
31660
diff
changeset
|
1085 ao_msg(MSGT_AO, MSGL_WARN, "Restoring digital output failed.\n"); |
29209 | 1086 } |
1087 else | |
1088 { | |
31891
4f17ff5b3cbc
Fix a bunch of grammar and spelling errors in mp_msg calls.
diego
parents:
31660
diff
changeset
|
1089 ao_msg(MSGT_AO, MSGL_WARN, "Restoring digital output succeeded.\n"); |
29209 | 1090 reset(); |
1091 } | |
1092 } | |
1093 else | |
31891
4f17ff5b3cbc
Fix a bunch of grammar and spelling errors in mp_msg calls.
diego
parents:
31660
diff
changeset
|
1094 ao_msg(MSGT_AO, MSGL_V, "Detected current stream does not support digital.\n"); |
29209 | 1095 } |
1096 | |
1097 wrote=write_buffer(output_samples, num_bytes); | |
1098 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
|
1099 |
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 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
|
1101 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
|
1102 } 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
|
1103 |
29209 | 1104 return wrote; |
1105 } | |
1106 | |
1107 /* set variables and buffer to initial state */ | |
1108 static void reset(void) | |
1109 { | |
1110 audio_pause(); | |
1111 av_fifo_reset(ao->buffer); | |
1112 } | |
1113 | |
1114 | |
1115 /* return available space */ | |
1116 static int get_space(void) | |
1117 { | |
1118 return ao->buffer_len - av_fifo_size(ao->buffer); | |
1119 } | |
1120 | |
1121 | |
1122 /* return delay until audio is played */ | |
1123 static float get_delay(void) | |
1124 { | |
1125 // inaccurate, should also contain the data buffered e.g. by the OS | |
1126 return (float)av_fifo_size(ao->buffer)/(float)ao_data.bps; | |
1127 } | |
1128 | |
1129 | |
1130 /* unload plugin and deregister from coreaudio */ | |
1131 static void uninit(int immed) | |
1132 { | |
1133 OSStatus err = noErr; | |
1134 | |
1135 if (!immed) { | |
1136 long long timeleft=(1000000LL*av_fifo_size(ao->buffer))/ao_data.bps; | |
1137 ao_msg(MSGT_AO,MSGL_DBG2, "%d bytes left @%d bps (%d usec)\n", av_fifo_size(ao->buffer), ao_data.bps, (int)timeleft); | |
1138 usec_sleep((int)timeleft); | |
1139 } | |
1140 | |
1141 if (!ao->b_digital) { | |
1142 AudioOutputUnitStop(ao->theOutputUnit); | |
1143 AudioUnitUninitialize(ao->theOutputUnit); | |
1144 CloseComponent(ao->theOutputUnit); | |
1145 } | |
1146 else { | |
1147 /* Stop device. */ | |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1148 err = AudioDeviceStop(ao->i_selected_dev, ao->renderCallback); |
29209 | 1149 if (err != noErr) |
1150 ao_msg(MSGT_AO, MSGL_WARN, "AudioDeviceStop failed: [%4.4s]\n", (char *)&err); | |
1151 | |
1152 /* 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
|
1153 err = AudioDeviceDestroyIOProcID(ao->i_selected_dev, ao->renderCallback); |
29209 | 1154 if (err != noErr) |
1155 ao_msg(MSGT_AO, MSGL_WARN, "AudioDeviceRemoveIOProc failed: [%4.4s]\n", (char *)&err); | |
1156 | |
1157 if (ao->b_revert) | |
1158 AudioStreamChangeFormat(ao->i_stream_id, ao->sfmt_revert); | |
1159 | |
1160 if (ao->b_changed_mixing && ao->sfmt_revert.mFormatID != kAudioFormat60958AC3) | |
1161 { | |
31648
a09f02987594
Consistently use types as they are used by the API in ao_coreaudio.
adrian
parents:
31647
diff
changeset
|
1162 UInt32 b_mix; |
34059 | 1163 Boolean b_writeable = 0; |
29209 | 1164 /* 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
|
1165 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
|
1166 kAudioDevicePropertySupportsMixing, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1167 &b_writeable); |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1168 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
|
1169 kAudioDevicePropertySupportsMixing, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1170 sizeof(UInt32), &b_mix); |
34059 | 1171 if (err == noErr && b_writeable) |
29209 | 1172 { |
1173 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
|
1174 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
|
1175 kAudioDevicePropertySupportsMixing, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1176 sizeof(UInt32), &b_mix); |
29209 | 1177 } |
1178 if (err != noErr) | |
1179 ao_msg(MSGT_AO, MSGL_WARN, "failed to set mixmode: [%4.4s]\n", (char *)&err); | |
1180 } | |
1181 if (ao->i_hog_pid == getpid()) | |
1182 { | |
1183 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
|
1184 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
|
1185 kAudioDevicePropertyHogMode, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1186 sizeof(ao->i_hog_pid), &ao->i_hog_pid); |
29209 | 1187 if (err != noErr) ao_msg(MSGT_AO, MSGL_WARN, "Could not release hogmode: [%4.4s]\n", (char *)&err); |
1188 } | |
1189 } | |
1190 | |
1191 av_fifo_free(ao->buffer); | |
1192 free(ao); | |
1193 ao = NULL; | |
1194 } | |
1195 | |
1196 | |
1197 /* stop playing, keep buffers (for pause) */ | |
1198 static void audio_pause(void) | |
1199 { | |
1200 OSErr err=noErr; | |
1201 | |
1202 /* Stop callback. */ | |
1203 if (!ao->b_digital) | |
1204 { | |
1205 err=AudioOutputUnitStop(ao->theOutputUnit); | |
1206 if (err != noErr) | |
1207 ao_msg(MSGT_AO,MSGL_WARN, "AudioOutputUnitStop returned [%4.4s]\n", (char *)&err); | |
1208 } | |
1209 else | |
1210 { | |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1211 err = AudioDeviceStop(ao->i_selected_dev, ao->renderCallback); |
29209 | 1212 if (err != noErr) |
1213 ao_msg(MSGT_AO, MSGL_WARN, "AudioDeviceStop failed: [%4.4s]\n", (char *)&err); | |
1214 } | |
1215 ao->paused = 1; | |
1216 } | |
1217 | |
1218 | |
1219 /* resume playing, after audio_pause() */ | |
1220 static void audio_resume(void) | |
1221 { | |
1222 OSErr err=noErr; | |
1223 | |
1224 if (!ao->paused) | |
1225 return; | |
1226 | |
1227 /* Start callback. */ | |
1228 if (!ao->b_digital) | |
1229 { | |
1230 err = AudioOutputUnitStart(ao->theOutputUnit); | |
1231 if (err != noErr) | |
1232 ao_msg(MSGT_AO,MSGL_WARN, "AudioOutputUnitStart returned [%4.4s]\n", (char *)&err); | |
1233 } | |
1234 else | |
1235 { | |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1236 err = AudioDeviceStart(ao->i_selected_dev, ao->renderCallback); |
29209 | 1237 if (err != noErr) |
1238 ao_msg(MSGT_AO, MSGL_WARN, "AudioDeviceStart failed: [%4.4s]\n", (char *)&err); | |
1239 } | |
1240 ao->paused = 0; | |
1241 } | |
1242 | |
1243 /***************************************************************************** | |
1244 * StreamListener | |
1245 *****************************************************************************/ | |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1246 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
|
1247 UInt32 inNumberAddresses, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1248 const AudioObjectPropertyAddress inAddresses[], |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1249 void *inClientData ) |
29209 | 1250 { |
36006 | 1251 int i; |
1252 for (i=0; i < inNumberAddresses; ++i) | |
29209 | 1253 { |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1254 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
|
1255 ao_msg(MSGT_AO, MSGL_WARN, "got notify kAudioStreamPropertyPhysicalFormat changed.\n"); |
29209 | 1256 if (inClientData) |
1257 *(volatile int *)inClientData = 1; | |
1258 break; | |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1259 } |
29209 | 1260 } |
1261 return noErr; | |
1262 } | |
1263 | |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1264 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
|
1265 UInt32 inNumberAddresses, |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1266 const AudioObjectPropertyAddress inAddresses[], |
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1267 void *inClientData ) |
29209 | 1268 { |
36006 | 1269 int i; |
1270 for (i=0; i < inNumberAddresses; ++i) | |
29209 | 1271 { |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1272 if (inAddresses[i].mSelector == kAudioDevicePropertyDeviceHasChanged) { |
29209 | 1273 ao_msg(MSGT_AO, MSGL_WARN, "got notify kAudioDevicePropertyDeviceHasChanged.\n"); |
1274 ao->b_stream_format_changed = 1; | |
1275 break; | |
31647
976c9554f284
Replace deprecated functions in ao_coreaudio with their new ones introduced in OSX 10.4.
adrian
parents:
31646
diff
changeset
|
1276 } |
29209 | 1277 } |
1278 return noErr; | |
1279 } |