Mercurial > mplayer.hg
annotate libao2/ao_macosx.c @ 15101:04a5b6407cb6
Add releaseclean target to remove generated files but keep the HTML.
author | diego |
---|---|
date | Sun, 10 Apr 2005 16:26:51 +0000 |
parents | 21f44596f356 |
children | 324046793f7c |
rev | line source |
---|---|
10147
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
1 /* |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
2 * |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
3 * ao_macosx.c |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
4 * |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
5 * Original Copyright (C) Timothy J. Wood - Aug 2000 |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
6 * |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
7 * This file is part of libao, a cross-platform library. See |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
8 * README for a history of this source code. |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
9 * |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
10 * libao is free software; you can redistribute it and/or modify |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
11 * it under the terms of the GNU General Public License as published by |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
12 * the Free Software Foundation; either version 2, or (at your option) |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
13 * any later version. |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
14 * |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
15 * libao is distributed in the hope that it will be useful, |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
18 * GNU General Public License for more details. |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
19 * |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
20 * You should have received a copy of the GNU General Public License |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
21 * along with GNU Make; see the file COPYING. If not, write to |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
22 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
23 */ |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
24 |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
25 /* |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
26 * The MacOS X CoreAudio framework doesn't mesh as simply as some |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
27 * simpler frameworks do. This is due to the fact that CoreAudio pulls |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
28 * audio samples rather than having them pushed at it (which is nice |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
29 * when you are wanting to do good buffering of audio). |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
30 */ |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
31 |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
32 /* Change log: |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
33 * |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
34 * 14/5-2003: Ported to MPlayer libao2 by Dan Christiansen |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
35 * |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
36 * AC-3 and MPEG audio passthrough is possible, but I don't have |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
37 * access to a sound card that supports it. |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
38 */ |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
39 |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
40 #include <CoreAudio/AudioHardware.h> |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
41 #include <stdio.h> |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
42 #include <string.h> |
14903
21f44596f356
do not always request little-endian despite the actual sound format. by Alexander Strange - astrange@ithinksw.com
nplourde
parents:
14769
diff
changeset
|
43 #include <stdlib.h> |
10147
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
44 #include <inttypes.h> |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
45 #include <pthread.h> |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
46 |
14479 | 47 #include "config.h" |
14123 | 48 #include "mp_msg.h" |
10147
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
49 |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
50 #include "audio_out.h" |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
51 #include "audio_out_internal.h" |
14245 | 52 #include "libaf/af_format.h" |
10147
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
53 |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
54 static ao_info_t info = |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
55 { |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
56 "Darwin/Mac OS X native audio output", |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
57 "macosx", |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
58 "Timothy J. Wood & Dan Christiansen", |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
59 "" |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
60 }; |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
61 |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
62 LIBAO_EXTERN(macosx) |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
63 |
10152 | 64 /* Prefix for all mp_msg() calls */ |
65 #define ao_msg(a, b, c...) mp_msg(a, b, "AO: [macosx] " c) | |
66 | |
10147
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
67 /* This is large, but best (maybe it should be even larger). |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
68 * CoreAudio supposedly has an internal latency in the order of 2ms */ |
14290 | 69 #define NUM_BUFS 32 |
10147
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
70 |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
71 typedef struct ao_macosx_s |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
72 { |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
73 /* CoreAudio */ |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
74 AudioDeviceID outputDeviceID; |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
75 AudioStreamBasicDescription outputStreamBasicDescription; |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
76 |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
77 /* Ring-buffer */ |
14769
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
78 /* does not need explicit synchronization, but needs to allocate |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
79 * (num_chunks + 1) * chunk_size memory to store num_chunks * chunk_size |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
80 * data */ |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
81 unsigned char *buffer; |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
82 unsigned int buffer_len; ///< must always be (num_chunks + 1) * chunk_size |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
83 unsigned int num_chunks; |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
84 unsigned int chunk_size; |
10147
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
85 |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
86 unsigned int buf_read_pos; |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
87 unsigned int buf_write_pos; |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
88 } ao_macosx_t; |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
89 |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
90 static ao_macosx_t *ao; |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
91 |
14769
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
92 /** |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
93 * \brief return number of free bytes in the buffer |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
94 * may only be called by mplayer's thread |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
95 * \return minimum number of free bytes in buffer, value may change between |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
96 * two immediately following calls, and the real number of free bytes |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
97 * might actually be larger! |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
98 */ |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
99 static int buf_free() { |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
100 int free = ao->buf_read_pos - ao->buf_write_pos - ao->chunk_size; |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
101 if (free < 0) free += ao->buffer_len; |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
102 return free; |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
103 } |
10147
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
104 |
14769
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
105 /** |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
106 * \brief return number of buffered bytes |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
107 * may only be called by playback thread |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
108 * \return minimum number of buffered bytes, value may change between |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
109 * two immediately following calls, and the real number of buffered bytes |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
110 * might actually be larger! |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
111 */ |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
112 static int buf_used() { |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
113 int used = ao->buf_write_pos - ao->buf_read_pos; |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
114 if (used < 0) used += ao->buffer_len; |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
115 return used; |
10147
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
116 } |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
117 |
14769
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
118 /** |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
119 * \brief add data to ringbuffer |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
120 */ |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
121 static int write_buffer(unsigned char* data, int len){ |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
122 int first_len = ao->buffer_len - ao->buf_write_pos; |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
123 int free = buf_free(); |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
124 if (len > free) len = free; |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
125 if (first_len > len) first_len = len; |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
126 // till end of buffer |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
127 memcpy (&ao->buffer[ao->buf_write_pos], data, first_len); |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
128 if (len > first_len) { // we have to wrap around |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
129 // remaining part from beginning of buffer |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
130 memcpy (ao->buffer, &data[first_len], len - first_len); |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
131 } |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
132 ao->buf_write_pos = (ao->buf_write_pos + len) % ao->buffer_len; |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
133 return len; |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
134 } |
10147
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
135 |
14769
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
136 /** |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
137 * \brief remove data from ringbuffer |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
138 */ |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
139 static int read_buffer(unsigned char* data,int len){ |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
140 int first_len = ao->buffer_len - ao->buf_read_pos; |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
141 int buffered = buf_used(); |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
142 if (len > buffered) len = buffered; |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
143 if (first_len > len) first_len = len; |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
144 // till end of buffer |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
145 memcpy (data, &ao->buffer[ao->buf_read_pos], first_len); |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
146 if (len > first_len) { // we have to wrap around |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
147 // remaining part from beginning of buffer |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
148 memcpy (&data[first_len], ao->buffer, len - first_len); |
10147
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
149 } |
14769
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
150 ao->buf_read_pos = (ao->buf_read_pos + len) % ao->buffer_len; |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
151 return len; |
10147
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
152 } |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
153 |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
154 /* end ring buffer stuff */ |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
155 |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
156 /* The function that the CoreAudio thread calls when it wants more data */ |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
157 static OSStatus audioDeviceIOProc(AudioDeviceID inDevice, const AudioTimeStamp *inNow, const AudioBufferList *inInputData, const AudioTimeStamp *inInputTime, AudioBufferList *outOutputData, const AudioTimeStamp *inOutputTime, void *inClientData) |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
158 { |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
159 outOutputData->mBuffers[0].mDataByteSize = |
14769
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
160 read_buffer((char *)outOutputData->mBuffers[0].mData, ao->chunk_size); |
10147
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
161 |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
162 return 0; |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
163 } |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
164 |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
165 |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
166 static int control(int cmd,void *arg){ |
14290 | 167 OSStatus status; |
168 UInt32 propertySize; | |
169 ao_control_vol_t* vol = (ao_control_vol_t*)arg; | |
170 UInt32 stereoChannels[2]; | |
171 static float volume=0.5; | |
10147
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
172 switch (cmd) { |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
173 case AOCONTROL_SET_DEVICE: |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
174 case AOCONTROL_GET_DEVICE: |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
175 /* unimplemented/meaningless */ |
10152 | 176 return CONTROL_FALSE; |
14290 | 177 case AOCONTROL_GET_VOLUME: |
178 propertySize=sizeof(stereoChannels); | |
179 status = AudioDeviceGetProperty(ao->outputDeviceID, NULL, 0, | |
180 kAudioDevicePropertyPreferredChannelsForStereo, &propertySize, | |
181 &stereoChannels); | |
182 // printf("OSX: stereochannels %d ; %d \n",stereoChannels[0],stereoChannels[1]); | |
183 propertySize=sizeof(volume); | |
184 status = AudioDeviceGetProperty(ao->outputDeviceID, stereoChannels[0], false, kAudioDevicePropertyVolumeScalar, &propertySize, &volume); | |
185 // printf("OSX: get volume=%5.3f status=%d \n",volume,status); | |
186 vol->left=(int)(volume*100.0); | |
187 status = AudioDeviceGetProperty(ao->outputDeviceID, stereoChannels[1], false, kAudioDevicePropertyVolumeScalar, &propertySize, &volume); | |
188 vol->right=(int)(volume*100.0); | |
189 return CONTROL_TRUE; | |
190 case AOCONTROL_SET_VOLUME: | |
191 propertySize=sizeof(stereoChannels); | |
192 status = AudioDeviceGetProperty(ao->outputDeviceID, NULL, 0, | |
193 kAudioDevicePropertyPreferredChannelsForStereo, &propertySize, | |
194 &stereoChannels); | |
195 // printf("OSX: stereochannels %d ; %d \n",stereoChannels[0],stereoChannels[1]); | |
196 propertySize=sizeof(volume); | |
197 volume=vol->left/100.0; | |
198 status = AudioDeviceSetProperty(ao->outputDeviceID, 0, stereoChannels[0], 0, kAudioDevicePropertyVolumeScalar, propertySize, &volume); | |
199 // printf("OSX: set volume=%5.3f status=%d\n",volume,status); | |
200 volume=vol->right/100.0; | |
201 status = AudioDeviceSetProperty(ao->outputDeviceID, 0, stereoChannels[1], 0, kAudioDevicePropertyVolumeScalar, propertySize, &volume); | |
202 return CONTROL_TRUE; | |
10147
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
203 case AOCONTROL_QUERY_FORMAT: |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
204 /* stick with what CoreAudio requests */ |
10152 | 205 return CONTROL_FALSE; |
10147
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
206 default: |
10152 | 207 return CONTROL_FALSE; |
10147
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
208 } |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
209 |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
210 } |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
211 |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
212 |
14317 | 213 static void print_format(const char* str,AudioStreamBasicDescription *f){ |
14290 | 214 uint32_t flags=(uint32_t) f->mFormatFlags; |
14317 | 215 ao_msg(MSGT_AO,MSGL_V, "%s %7.1fHz %dbit [%c%c%c%c] %s %s %s%s%s%s\n", |
216 str, f->mSampleRate, f->mBitsPerChannel, | |
14290 | 217 (int)(f->mFormatID & 0xff000000) >> 24, |
218 (int)(f->mFormatID & 0x00ff0000) >> 16, | |
219 (int)(f->mFormatID & 0x0000ff00) >> 8, | |
220 (int)(f->mFormatID & 0x000000ff) >> 0, | |
221 (flags&kAudioFormatFlagIsFloat) ? "float" : "int", | |
222 (flags&kAudioFormatFlagIsBigEndian) ? "BE" : "LE", | |
223 (flags&kAudioFormatFlagIsSignedInteger) ? "S" : "U", | |
224 (flags&kAudioFormatFlagIsPacked) ? " packed" : "", | |
225 (flags&kAudioFormatFlagIsAlignedHigh) ? " aligned" : "", | |
226 (flags&kAudioFormatFlagIsNonInterleaved) ? " ni" : "" ); | |
227 | |
14317 | 228 ao_msg(MSGT_AO,MSGL_DBG2, "%5d mBytesPerPacket\n", |
14290 | 229 (int)f->mBytesPerPacket); |
14317 | 230 ao_msg(MSGT_AO,MSGL_DBG2, "%5d mFramesPerPacket\n", |
14290 | 231 (int)f->mFramesPerPacket); |
14317 | 232 ao_msg(MSGT_AO,MSGL_DBG2, "%5d mBytesPerFrame\n", |
14290 | 233 (int)f->mBytesPerFrame); |
14317 | 234 ao_msg(MSGT_AO,MSGL_DBG2, "%5d mChannelsPerFrame\n", |
14290 | 235 (int)f->mChannelsPerFrame); |
236 | |
237 } | |
238 | |
239 | |
10147
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
240 static int init(int rate,int channels,int format,int flags) |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
241 { |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
242 OSStatus status; |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
243 UInt32 propertySize; |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
244 int rc; |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
245 int i; |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
246 |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
247 ao = (ao_macosx_t *)malloc(sizeof(ao_macosx_t)); |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
248 |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
249 /* get default output device */ |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
250 propertySize = sizeof(ao->outputDeviceID); |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
251 status = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &propertySize, &(ao->outputDeviceID)); |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
252 if (status) { |
10152 | 253 ao_msg(MSGT_AO,MSGL_WARN, |
254 "AudioHardwareGetProperty returned %d\n", | |
10147
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
255 (int)status); |
10152 | 256 return CONTROL_FALSE; |
10147
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
257 } |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
258 |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
259 if (ao->outputDeviceID == kAudioDeviceUnknown) { |
10152 | 260 ao_msg(MSGT_AO,MSGL_WARN, "AudioHardwareGetProperty: ao->outputDeviceID is kAudioDeviceUnknown\n"); |
261 return CONTROL_FALSE; | |
10147
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
262 } |
14290 | 263 |
264 | |
14317 | 265 propertySize = sizeof(ao->outputStreamBasicDescription); |
266 status = AudioDeviceGetProperty(ao->outputDeviceID, 0, false, kAudioDevicePropertyStreamFormat, &propertySize, &ao->outputStreamBasicDescription); | |
267 if(!status) print_format("default:",&ao->outputStreamBasicDescription); | |
268 | |
269 | |
270 #if 1 | |
14290 | 271 // dump supported format list: |
272 { AudioStreamBasicDescription* p; | |
273 Boolean ow; | |
274 int i; | |
275 propertySize=0; //sizeof(p); | |
14317 | 276 // status = AudioDeviceGetPropertyInfo(ao->outputDeviceID, 0, false, kAudioStreamPropertyPhysicalFormats, &propertySize, &ow); |
277 status = AudioDeviceGetPropertyInfo(ao->outputDeviceID, 0, false, kAudioDevicePropertyStreamFormats, &propertySize, &ow); | |
14290 | 278 if (status) { |
279 ao_msg(MSGT_AO,MSGL_WARN, "AudioDeviceGetPropertyInfo returned 0x%X when getting kAudioDevicePropertyStreamFormats\n", (int)status); | |
280 } | |
281 p=malloc(propertySize); | |
14317 | 282 // status = AudioDeviceGetProperty(ao->outputDeviceID, 0, false, kAudioStreamPropertyPhysicalFormats, &propertySize, p); |
283 status = AudioDeviceGetProperty(ao->outputDeviceID, 0, false, kAudioDevicePropertyStreamFormats, &propertySize, p); | |
14290 | 284 if (status) { |
285 ao_msg(MSGT_AO,MSGL_WARN, "AudioDeviceGetProperty returned 0x%X when getting kAudioDevicePropertyStreamFormats\n", (int)status); | |
286 // return CONTROL_FALSE; | |
287 } | |
288 for(i=0;i<propertySize/sizeof(AudioStreamBasicDescription);i++) | |
14317 | 289 print_format("support:",&p[i]); |
14290 | 290 // printf("FORMATS: (%d) %p %p %p %p\n",propertySize,p[0],p[1],p[2],p[3]); |
291 free(p); | |
292 } | |
293 #endif | |
294 | |
295 // fill in our wanted format, and let's see if the driver accepts it or | |
296 // offers some similar alternative: | |
14317 | 297 propertySize = sizeof(ao->outputStreamBasicDescription); |
14290 | 298 memset(&ao->outputStreamBasicDescription,0,propertySize); |
299 ao->outputStreamBasicDescription.mSampleRate=rate; | |
300 ao->outputStreamBasicDescription.mFormatID=kAudioFormatLinearPCM; | |
301 ao->outputStreamBasicDescription.mChannelsPerFrame=channels; | |
302 switch(format&AF_FORMAT_BITS_MASK){ | |
303 case AF_FORMAT_8BIT: ao->outputStreamBasicDescription.mBitsPerChannel=8; break; | |
304 case AF_FORMAT_16BIT: ao->outputStreamBasicDescription.mBitsPerChannel=16; break; | |
305 case AF_FORMAT_24BIT: ao->outputStreamBasicDescription.mBitsPerChannel=24; break; | |
306 case AF_FORMAT_32BIT: ao->outputStreamBasicDescription.mBitsPerChannel=32; break; | |
307 } | |
14317 | 308 if((format&AF_FORMAT_POINT_MASK)==AF_FORMAT_F){ |
14290 | 309 // float |
310 ao->outputStreamBasicDescription.mFormatFlags=kAudioFormatFlagIsFloat|kAudioFormatFlagIsPacked; | |
14317 | 311 } else if((format&AF_FORMAT_SIGN_MASK)==AF_FORMAT_SI){ |
14290 | 312 // signed int |
313 ao->outputStreamBasicDescription.mFormatFlags=kAudioFormatFlagIsSignedInteger|kAudioFormatFlagIsPacked; | |
314 } else { | |
315 // unsigned int | |
316 ao->outputStreamBasicDescription.mFormatFlags=kAudioFormatFlagIsPacked; | |
317 } | |
14903
21f44596f356
do not always request little-endian despite the actual sound format. by Alexander Strange - astrange@ithinksw.com
nplourde
parents:
14769
diff
changeset
|
318 if((format&AF_FORMAT_END_MASK)==AF_FORMAT_BE) |
14290 | 319 ao->outputStreamBasicDescription.mFormatFlags|=kAudioFormatFlagIsBigEndian; |
320 | |
321 ao->outputStreamBasicDescription.mBytesPerPacket= | |
322 ao->outputStreamBasicDescription.mBytesPerFrame=channels*(ao->outputStreamBasicDescription.mBitsPerChannel/8); | |
323 ao->outputStreamBasicDescription.mFramesPerPacket=1; | |
324 | |
14317 | 325 print_format("wanted: ",&ao->outputStreamBasicDescription); |
14290 | 326 |
14317 | 327 // try 1: ask if it accepts our specific requirements? |
10147
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
328 propertySize = sizeof(ao->outputStreamBasicDescription); |
14317 | 329 // status = AudioDeviceGetProperty(ao->outputDeviceID, 0, false, kAudioStreamPropertyPhysicalFormatMatch, &propertySize, &ao->outputStreamBasicDescription); |
330 status = AudioDeviceGetProperty(ao->outputDeviceID, 0, false, kAudioDevicePropertyStreamFormatMatch, &propertySize, &ao->outputStreamBasicDescription); | |
14290 | 331 if (status || ao->outputStreamBasicDescription.mSampleRate!=rate |
332 || ao->outputStreamBasicDescription.mFormatID!=kAudioFormatLinearPCM) { | |
333 ao_msg(MSGT_AO,MSGL_V, "AudioDeviceGetProperty returned 0x%X when getting kAudioDevicePropertyStreamFormatMatch\n", (int)status); | |
334 // failed (error, bad rate or bad type) | |
335 // try 2: set only rate & type, no format details (bits, channels etc) | |
336 propertySize = sizeof(ao->outputStreamBasicDescription); | |
337 memset(&ao->outputStreamBasicDescription,0,propertySize); | |
338 ao->outputStreamBasicDescription.mSampleRate=rate; | |
339 ao->outputStreamBasicDescription.mFormatID=kAudioFormatLinearPCM; | |
14317 | 340 // status = AudioDeviceGetProperty(ao->outputDeviceID, 0, false, kAudioStreamPropertyPhysicalFormatMatch, &propertySize, &ao->outputStreamBasicDescription); |
341 status = AudioDeviceGetProperty(ao->outputDeviceID, 0, false, kAudioDevicePropertyStreamFormatMatch, &propertySize, &ao->outputStreamBasicDescription); | |
14290 | 342 if (status || ao->outputStreamBasicDescription.mFormatID!=kAudioFormatLinearPCM) { |
343 ao_msg(MSGT_AO,MSGL_V, "AudioDeviceGetProperty returned 0x%X when getting kAudioDevicePropertyStreamFormatMatch\n", (int)status); | |
344 // failed again. (error or bad type) | |
345 // giving up... just read the default. | |
346 propertySize = sizeof(ao->outputStreamBasicDescription); | |
14317 | 347 // status = AudioDeviceGetProperty(ao->outputDeviceID, 0, false, kAudioStreamPropertyPhysicalFormat, &propertySize, &ao->outputStreamBasicDescription); |
14290 | 348 status = AudioDeviceGetProperty(ao->outputDeviceID, 0, false, kAudioDevicePropertyStreamFormat, &propertySize, &ao->outputStreamBasicDescription); |
349 if (status) { | |
350 // failed to read the default format - WTF? | |
351 ao_msg(MSGT_AO,MSGL_WARN, "AudioDeviceGetProperty returned 0x%X when getting kAudioDevicePropertyStreamFormat\n", (int)status); | |
352 return CONTROL_FALSE; | |
353 } | |
354 } | |
10147
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
355 } |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
356 |
14317 | 357 // propertySize = sizeof(ao->outputStreamBasicDescription); |
358 // status = AudioDeviceGetProperty(ao->outputDeviceID, 0, false, kAudioDevicePropertyStreamFormatSupported, &propertySize, &ao->outputStreamBasicDescription); | |
359 // if (status) { | |
360 // ao_msg(MSGT_AO,MSGL_V, "AudioDeviceGetProperty returned 0x%X when getting kAudioDevicePropertyStreamFormatSupported\n", (int)status); | |
361 // } | |
362 | |
363 // ok, now try to set the new (default or matched) audio format: | |
364 print_format("best: ",&ao->outputStreamBasicDescription); | |
365 propertySize = sizeof(ao->outputStreamBasicDescription); | |
366 status = AudioDeviceSetProperty(ao->outputDeviceID, 0, 0, false, kAudioDevicePropertyStreamFormat, propertySize, &ao->outputStreamBasicDescription); | |
367 if(status) | |
368 ao_msg(MSGT_AO,MSGL_WARN, "AudioDeviceSetProperty returned 0x%X when getting kAudioDevicePropertyStreamFormat\n", (int)status); | |
369 | |
370 // see what did we get finally... we'll be forced to use this anyway :( | |
371 propertySize = sizeof(ao->outputStreamBasicDescription); | |
372 status = AudioDeviceGetProperty(ao->outputDeviceID, 0, false, kAudioDevicePropertyStreamFormat, &propertySize, &ao->outputStreamBasicDescription); | |
373 print_format("final: ",&ao->outputStreamBasicDescription); | |
10147
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
374 |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
375 /* get requested buffer length */ |
14290 | 376 // TODO: set NUM_BUFS dinamically, based on buffer size! |
14769
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
377 propertySize = sizeof(ao->chunk_size); |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
378 status = AudioDeviceGetProperty(ao->outputDeviceID, 0, false, kAudioDevicePropertyBufferSize, &propertySize, &ao->chunk_size); |
10147
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
379 if (status) { |
10152 | 380 ao_msg(MSGT_AO,MSGL_WARN, "AudioDeviceGetProperty returned %d when getting kAudioDevicePropertyBufferSize\n", (int)status); |
381 return CONTROL_FALSE; | |
10147
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
382 } |
14769
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
383 ao_msg(MSGT_AO,MSGL_V, "%5d chunk size\n", (int)ao->chunk_size); |
10147
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
384 |
12788
a6ff4398e4e6
enables resampling of audio in ao_macosx by Dan Christiansen
nplourde
parents:
12145
diff
changeset
|
385 ao_data.samplerate = ao->outputStreamBasicDescription.mSampleRate; |
13651
997adf3656e2
Fix incompatibility with audio devices with more then 2 channels
nplourde
parents:
12788
diff
changeset
|
386 ao_data.channels = channels; |
14769
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
387 ao_data.outburst = ao_data.buffersize = ao->chunk_size; |
10147
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
388 ao_data.bps = |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
389 ao_data.samplerate * ao->outputStreamBasicDescription.mBytesPerFrame; |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
390 |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
391 if (ao->outputStreamBasicDescription.mFormatID == kAudioFormatLinearPCM) { |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
392 uint32_t flags = ao->outputStreamBasicDescription.mFormatFlags; |
10152 | 393 if (flags & kAudioFormatFlagIsFloat) { |
14290 | 394 ao_data.format = (flags&kAudioFormatFlagIsBigEndian) ? AF_FORMAT_FLOAT_BE : AF_FORMAT_FLOAT_LE; |
10152 | 395 } else { |
396 ao_msg(MSGT_AO,MSGL_WARN, "Unsupported audio output " | |
14290 | 397 "format 0x%X. Please report this to the developer\n", format); |
10152 | 398 return CONTROL_FALSE; |
399 } | |
400 | |
10147
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
401 } else { |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
402 /* TODO: handle AFMT_AC3, AFMT_MPEG & friends */ |
10152 | 403 ao_msg(MSGT_AO,MSGL_WARN, "Default Audio Device doesn't " |
10147
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
404 "support Linear PCM!\n"); |
10152 | 405 return CONTROL_FALSE; |
10147
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
406 } |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
407 |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
408 /* Allocate ring-buffer memory */ |
14769
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
409 ao->num_chunks = NUM_BUFS; |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
410 ao->buffer_len = (ao->num_chunks + 1) * ao->chunk_size; |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
411 ao->buffer = (unsigned char *)malloc(ao->buffer_len); |
10147
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
412 |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
413 |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
414 /* Prepare for playback */ |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
415 |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
416 /* Set the IO proc that CoreAudio will call when it needs data */ |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
417 status = AudioDeviceAddIOProc(ao->outputDeviceID, audioDeviceIOProc, NULL); |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
418 if (status) { |
10152 | 419 ao_msg(MSGT_AO,MSGL_WARN, "AudioDeviceAddIOProc returned %d\n", (int)status); |
420 return CONTROL_FALSE; | |
10147
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
421 } |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
422 |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
423 /* Start callback */ |
14769
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
424 reset(); |
10147
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
425 |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
426 return CONTROL_OK; |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
427 } |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
428 |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
429 |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
430 static int play(void* output_samples,int num_bytes,int flags) |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
431 { |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
432 return write_buffer(output_samples, num_bytes); |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
433 } |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
434 |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
435 /* set variables and buffer to initial state */ |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
436 static void reset() |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
437 { |
14769
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
438 audio_pause(); |
10147
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
439 /* reset ring-buffer state */ |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
440 ao->buf_read_pos=0; |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
441 ao->buf_write_pos=0; |
14769
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
442 audio_resume(); |
10147
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
443 |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
444 return; |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
445 } |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
446 |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
447 |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
448 /* return available space */ |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
449 static int get_space() |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
450 { |
14769
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
451 return buf_free(); |
10147
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
452 } |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
453 |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
454 |
10152 | 455 /* return delay until audio is played */ |
10147
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
456 static float get_delay() |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
457 { |
14769
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
458 int buffered = ao->buffer_len - ao->chunk_size - buf_free(); // could be less |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
459 // inaccurate, should also contain the data buffered e.g. by the OS |
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
460 return (float)(buffered)/(float)ao_data.bps; |
10147
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
461 } |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
462 |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
463 |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
464 /* unload plugin and deregister from coreaudio */ |
12145 | 465 static void uninit(int immed) |
10147
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
466 { |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
467 int i; |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
468 OSErr status; |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
469 |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
470 reset(); |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
471 |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
472 status = AudioDeviceRemoveIOProc(ao->outputDeviceID, audioDeviceIOProc); |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
473 if (status) |
10152 | 474 ao_msg(MSGT_AO,MSGL_WARN, "AudioDeviceRemoveIOProc " |
10147
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
475 "returned %d\n", (int)status); |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
476 |
14769
e701873aa8ca
rids ao_macosx of the buffer mutex by using the same buffering scheme as ao_sdl - Patch by Reimar Doffinger
nplourde
parents:
14642
diff
changeset
|
477 free(ao->buffer); |
10147
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
478 free(ao); |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
479 } |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
480 |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
481 |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
482 /* stop playing, keep buffers (for pause) */ |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
483 static void audio_pause() |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
484 { |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
485 OSErr status; |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
486 |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
487 /* stop callback */ |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
488 status = AudioDeviceStop(ao->outputDeviceID, audioDeviceIOProc); |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
489 if (status) |
10152 | 490 ao_msg(MSGT_AO,MSGL_WARN, "AudioDeviceStop returned %d\n", |
10147
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
491 (int)status); |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
492 } |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
493 |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
494 |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
495 /* resume playing, after audio_pause() */ |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
496 static void audio_resume() |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
497 { |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
498 OSErr status = AudioDeviceStart(ao->outputDeviceID, audioDeviceIOProc); |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
499 if (status) |
10152 | 500 ao_msg(MSGT_AO,MSGL_WARN, "AudioDeviceStart returned %d\n", |
10147
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
501 (int)status); |
f2725d6717bd
Native MacOSX audio output by Dan Christiansen <danchr@daimi.au.dk>
alex
parents:
diff
changeset
|
502 } |