1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
14 * The Initial Developer of the Original Code is
16 * Portions created by the Initial Developer are Copyright (C) 2007
17 * the Initial Developer. All Rights Reserved.
19 * Contributor(s): Michael Martin
21 * Alternatively, the contents of this file may be used under the terms of
22 * either the GNU General Public License Version 2 or later (the "GPL"), or
23 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
24 * in which case the provisions of the GPL or the LGPL are applicable instead
25 * of those above. If you wish to allow use of your version of this file only
26 * under the terms of either the GPL or the LGPL, and not to allow others to
27 * use your version of this file under the terms of the MPL, indicate your
28 * decision by deleting the provisions above and replace them with the notice
29 * and other provisions required by the GPL or the LGPL. If you do not delete
30 * the provisions above, a recipient may use your version of this file under
31 * the terms of any one of the MPL, the GPL or the LGPL.
33 * ***** END LICENSE BLOCK ***** *
36 #include <AudioUnit/AudioUnit.h>
37 #include "sydney_audio.h"
40 * The Mac's audio interface is based on a "pull" I/O model, which means you
41 * can't just provide a data buffer and tell the audio device to play; you must
42 * register a callback and provide data as the device asks for it. To support
43 * sydney audio's "write-to-play" style interface, we have to buffer up the
44 * data as it arrives and feed it to the callback as required.
46 * This is handled by a simple linked list of buffers; data is always written
47 * to the tail and read from the head. Each buffer tracks the start and end
48 * positions of its contained data. Buffers are allocated when the tail buffer
49 * fills, and freed when the head buffer empties. There is always at least one
52 * s e s e s e + data read
53 * +++##### -> ######## -> ####---- # data written
58 typedef struct sa_buf sa_buf
;
64 unsigned char data
[0];
68 AudioUnit output_unit
;
69 pthread_mutex_t mutex
;
73 /* audio format info */
75 unsigned int n_channels
;
76 unsigned int bytes_per_ch
;
86 * Use a default buffer size with enough room for one second of audio,
87 * assuming stereo data at 44.1kHz with 32 bits per channel, and impose
88 * a generous limit on the number of buffers.
90 #define BUF_SIZE (2 * 44100 * 4)
94 #error BUF_LIMIT must be at least 2!
98 static OSStatus
audio_callback(void *arg
, AudioUnitRenderActionFlags
*action_flags
,
99 const AudioTimeStamp
*time_stamp
, UInt32 bus_num
, UInt32 n_frames
, AudioBufferList
*data
);
101 static sa_buf
*new_buffer(void);
105 * -----------------------------------------------------------------------------
106 * Startup and shutdown functions
107 * -----------------------------------------------------------------------------
111 sa_stream_create_pcm(
113 const char * client_name
,
115 sa_pcm_format_t format
,
117 unsigned int n_channels
121 * Make sure we return a NULL stream pointer on failure.
124 return SA_ERROR_INVALID
;
128 if (mode
!= SA_MODE_WRONLY
) {
129 return SA_ERROR_NOT_SUPPORTED
;
131 if (format
!= SA_PCM_FORMAT_S16_LE
) {
132 return SA_ERROR_NOT_SUPPORTED
;
136 * Allocate the instance and required resources.
139 if ((s
= malloc(sizeof(sa_stream_t
))) == NULL
) {
142 if ((s
->bl_head
= new_buffer()) == NULL
) {
146 if (pthread_mutex_init(&s
->mutex
, NULL
) != 0) {
149 return SA_ERROR_SYSTEM
;
152 s
->output_unit
= NULL
;
156 s
->n_channels
= n_channels
;
158 s
->bl_tail
= s
->bl_head
;
167 sa_stream_open(sa_stream_t
*s
) {
170 return SA_ERROR_NO_INIT
;
172 if (s
->output_unit
!= NULL
) {
173 return SA_ERROR_INVALID
;
177 * Open the default audio output unit.
179 ComponentDescription desc
;
180 desc
.componentType
= kAudioUnitType_Output
;
181 desc
.componentSubType
= kAudioUnitSubType_DefaultOutput
;
182 desc
.componentManufacturer
= kAudioUnitManufacturer_Apple
;
183 desc
.componentFlags
= 0;
184 desc
.componentFlagsMask
= 0;
186 Component comp
= FindNextComponent(NULL
, &desc
);
188 return SA_ERROR_NO_DEVICE
;
191 if (OpenAComponent(comp
, &s
->output_unit
) != noErr
) {
192 return SA_ERROR_NO_DEVICE
;
196 * Set up the render callback used to feed audio data into the output unit.
198 AURenderCallbackStruct input
;
199 input
.inputProc
= audio_callback
;
200 input
.inputProcRefCon
= s
;
201 if (AudioUnitSetProperty(s
->output_unit
, kAudioUnitProperty_SetRenderCallback
,
202 kAudioUnitScope_Input
, 0, &input
, sizeof(input
)) != 0) {
203 return SA_ERROR_SYSTEM
;
207 * Set up the format description for our audio data. Apple uses the
208 * following terminology:
210 * sample = a single data value for one channel
211 * frame = a set of samples that includes one sample for each channel
212 * packet = the smallest indivisible block of audio data; for uncompressed
213 * audio (which is what we have), this is one frame
214 * rate = the number of complete frames per second
216 * Note that this definition of frame differs from, well, pretty much everyone
217 * else's. See this really long link for more info:
219 * http://developer.apple.com/documentation/MusicAudio/Reference/CoreAudioDataTypesRef/Reference/reference.html#//apple_ref/c/tdef/AudioStreamBasicDescription
221 AudioStreamBasicDescription fmt
;
222 fmt
.mFormatID
= kAudioFormatLinearPCM
;
223 fmt
.mFormatFlags
= kLinearPCMFormatFlagIsSignedInteger
|
224 #ifdef __BIG_ENDIAN__
225 kLinearPCMFormatFlagIsBigEndian
|
227 kLinearPCMFormatFlagIsPacked
;
228 fmt
.mSampleRate
= s
->rate
;
229 fmt
.mChannelsPerFrame
= s
->n_channels
;
230 fmt
.mBitsPerChannel
= s
->bytes_per_ch
* 8;
231 fmt
.mFramesPerPacket
= 1; /* uncompressed audio */
232 fmt
.mBytesPerFrame
= fmt
.mChannelsPerFrame
* fmt
.mBitsPerChannel
/ 8;
233 fmt
.mBytesPerPacket
= fmt
.mBytesPerFrame
* fmt
.mFramesPerPacket
;
236 * We're feeding data in to the output bus of the audio system, so we set
237 * the format description on the input scope of the device, using the very
238 * obvious element value of 0 to indicate the output bus.
240 * http://developer.apple.com/technotes/tn2002/tn2091.html
242 if (AudioUnitSetProperty(s
->output_unit
, kAudioUnitProperty_StreamFormat
,
243 kAudioUnitScope_Input
, 0, &fmt
, sizeof(AudioStreamBasicDescription
)) != 0) {
244 return SA_ERROR_NOT_SUPPORTED
;
247 if (AudioUnitInitialize(s
->output_unit
) != 0) {
248 return SA_ERROR_SYSTEM
;
256 sa_stream_destroy(sa_stream_t
*s
) {
262 pthread_mutex_lock(&s
->mutex
);
265 * Shut down the audio output device.
267 int result
= SA_SUCCESS
;
268 if (s
->output_unit
!= NULL
) {
269 if (s
->playing
&& AudioOutputUnitStop(s
->output_unit
) != 0) {
270 result
= SA_ERROR_SYSTEM
;
272 if (AudioUnitUninitialize(s
->output_unit
) != 0) {
273 result
= SA_ERROR_SYSTEM
;
275 if (CloseComponent(s
->output_unit
) != noErr
) {
276 result
= SA_ERROR_SYSTEM
;
280 pthread_mutex_unlock(&s
->mutex
);
285 if (pthread_mutex_destroy(&s
->mutex
) != 0) {
286 result
= SA_ERROR_SYSTEM
;
288 while (s
->bl_head
!= NULL
) {
289 sa_buf
* next
= s
->bl_head
->next
;
301 * -----------------------------------------------------------------------------
302 * Data read and write functions
303 * -----------------------------------------------------------------------------
307 sa_stream_write(sa_stream_t
*s
, const void *data
, size_t nbytes
) {
309 if (s
== NULL
|| s
->output_unit
== NULL
) {
310 return SA_ERROR_NO_INIT
;
316 pthread_mutex_lock(&s
->mutex
);
319 * Append the new data to the end of our buffer list.
321 int result
= SA_SUCCESS
;
323 unsigned int avail
= s
->bl_tail
->size
- s
->bl_tail
->end
;
325 if (nbytes
<= avail
) {
328 * The new data will fit into the current tail buffer, so
329 * just copy it in and we're done.
331 memcpy(s
->bl_tail
->data
+ s
->bl_tail
->end
, data
, nbytes
);
332 s
->bl_tail
->end
+= nbytes
;
338 * Copy what we can into the tail and allocate a new buffer
341 memcpy(s
->bl_tail
->data
+ s
->bl_tail
->end
, data
, avail
);
342 s
->bl_tail
->end
+= avail
;
343 data
= ((unsigned char *)data
) + avail
;
347 * If we still have data left to copy but we've hit the limit of
348 * allowable buffer allocations, we need to spin for a bit to allow
349 * the audio callback function to slurp some more data up.
351 if (nbytes
> 0 && s
->n_bufs
== BUF_LIMIT
) {
353 printf("#"); /* too much audio data */
357 * We haven't even started playing yet! That means the
358 * BUF_SIZE/BUF_LIMIT values are too low... Not much we can
359 * do here; spinning won't help because the audio callback
360 * hasn't been enabled yet. Oh well, error time.
362 printf("Too much audio data received before audio device enabled!\n");
363 result
= SA_ERROR_SYSTEM
;
366 while (s
->n_bufs
== BUF_LIMIT
) {
367 pthread_mutex_unlock(&s
->mutex
);
368 struct timespec ts
= {0, 1000000};
369 nanosleep(&ts
, NULL
);
370 pthread_mutex_lock(&s
->mutex
);
375 * Allocate a new tail buffer, and go 'round again to fill it up.
377 if ((s
->bl_tail
->next
= new_buffer()) == NULL
) {
378 result
= SA_ERROR_OOM
;
382 s
->bl_tail
= s
->bl_tail
->next
;
384 } /* if (nbytes <= avail), else */
388 pthread_mutex_unlock(&s
->mutex
);
391 * Once we have our first block of audio data, enable the audio callback
392 * function. This doesn't need to be protected by the mutex, because
393 * s->playing is not used in the audio callback thread, and it's probably
394 * better not to be inside the lock when we enable the audio callback.
398 if (AudioOutputUnitStart(s
->output_unit
) != 0) {
399 result
= SA_ERROR_SYSTEM
;
410 AudioUnitRenderActionFlags
* action_flags
,
411 const AudioTimeStamp
* time_stamp
,
414 AudioBufferList
* data
418 printf("."); /* audio read 'tick' */
422 * We're dealing with interleaved data, so the system should only
423 * have provided one buffer to be filled.
425 assert(data
->mNumberBuffers
== 1);
427 sa_stream_t
* s
= arg
;
429 pthread_mutex_lock(&s
->mutex
);
431 unsigned char * dst
= data
->mBuffers
[0].mData
;
432 unsigned int bytes_per_frame
= s
->n_channels
* s
->bytes_per_ch
;
433 unsigned int bytes_to_copy
= n_frames
* bytes_per_frame
;
436 * Keep track of the number of bytes we've consumed so far. mSampleTime
437 * is actually the number of *frames* that have been consumed by the
438 * audio output unit so far. I don't know why it's a float.
440 assert(time_stamp
->mFlags
& kAudioTimeStampSampleTimeValid
);
441 s
->bytes_played
= (int64_t)time_stamp
->mSampleTime
* bytes_per_frame
;
444 * Consume data from the start of the buffer list.
447 assert(s
->bl_head
->start
<= s
->bl_head
->end
);
448 unsigned int avail
= s
->bl_head
->end
- s
->bl_head
->start
;
450 if (avail
>= bytes_to_copy
) {
453 * We have all we need in the head buffer, so just grab it and go.
455 memcpy(dst
, s
->bl_head
->data
+ s
->bl_head
->start
, bytes_to_copy
);
456 s
->bl_head
->start
+= bytes_to_copy
;
462 * Copy what we can from the head and move on to the next buffer.
464 memcpy(dst
, s
->bl_head
->data
+ s
->bl_head
->start
, avail
);
465 s
->bl_head
->start
+= avail
;
467 bytes_to_copy
-= avail
;
470 * We want to free the now-empty buffer, but not if it's also the
471 * current tail. If it is the tail, we don't have enough data to fill
472 * the destination buffer, so we'll just zero it out and give up.
474 sa_buf
* next
= s
->bl_head
->next
;
477 printf("!"); /* not enough audio data */
479 memset(dst
, 0, bytes_to_copy
);
486 } /* if (avail >= bytes_to_copy), else */
490 pthread_mutex_unlock(&s
->mutex
);
497 * -----------------------------------------------------------------------------
498 * General query and support functions
499 * -----------------------------------------------------------------------------
503 sa_stream_get_write_size(sa_stream_t
*s
, size_t *size
) {
505 if (s
== NULL
|| s
->output_unit
== NULL
) {
506 return SA_ERROR_NO_INIT
;
509 pthread_mutex_lock(&s
->mutex
);
512 * Sum up the used portions of our buffers and subtract that from
513 * the pre-defined max allowed allocation.
517 for (b
= s
->bl_head
; b
!= NULL
; b
= b
->next
) {
518 used
+= b
->end
- b
->start
;
520 *size
= BUF_SIZE
* BUF_LIMIT
- used
;
522 pthread_mutex_unlock(&s
->mutex
);
528 sa_stream_get_position(sa_stream_t
*s
, sa_position_t position
, int64_t *pos
) {
530 if (s
== NULL
|| s
->output_unit
== NULL
) {
531 return SA_ERROR_NO_INIT
;
533 if (position
!= SA_POSITION_WRITE_SOFTWARE
) {
534 return SA_ERROR_NOT_SUPPORTED
;
537 pthread_mutex_lock(&s
->mutex
);
538 *pos
= s
->bytes_played
;
539 pthread_mutex_unlock(&s
->mutex
);
545 sa_stream_pause(sa_stream_t
*s
) {
547 if (s
== NULL
|| s
->output_unit
== NULL
) {
548 return SA_ERROR_NO_INIT
;
551 pthread_mutex_lock(&s
->mutex
);
552 AudioOutputUnitStop(s
->output_unit
);
553 pthread_mutex_unlock(&s
->mutex
);
559 sa_stream_resume(sa_stream_t
*s
) {
561 if (s
== NULL
|| s
->output_unit
== NULL
) {
562 return SA_ERROR_NO_INIT
;
565 pthread_mutex_lock(&s
->mutex
);
568 * The audio device resets its mSampleTime counter after pausing,
569 * so we need to clear our tracking value to keep that in sync.
572 AudioOutputUnitStart(s
->output_unit
);
574 pthread_mutex_unlock(&s
->mutex
);
581 sa_buf
* b
= malloc(sizeof(sa_buf
) + BUF_SIZE
);
594 * -----------------------------------------------------------------------------
595 * Extension functions
596 * -----------------------------------------------------------------------------
600 sa_stream_set_volume_abs(sa_stream_t
*s
, float vol
) {
602 if (s
== NULL
|| s
->output_unit
== NULL
) {
603 return SA_ERROR_NO_INIT
;
606 pthread_mutex_lock(&s
->mutex
);
607 AudioUnitSetParameter(s
->output_unit
, kHALOutputParam_Volume
,
608 kAudioUnitParameterFlag_Output
, 0, vol
, 0);
609 pthread_mutex_unlock(&s
->mutex
);
615 sa_stream_get_volume_abs(sa_stream_t
*s
, float *vol
) {
617 if (s
== NULL
|| s
->output_unit
== NULL
) {
618 return SA_ERROR_NO_INIT
;
621 pthread_mutex_lock(&s
->mutex
);
622 Float32 local_vol
= 0;
623 AudioUnitGetParameter(s
->output_unit
, kHALOutputParam_Volume
,
624 kAudioUnitParameterFlag_Output
, 0, &local_vol
);
626 pthread_mutex_unlock(&s
->mutex
);
633 * -----------------------------------------------------------------------------
634 * Unsupported functions
635 * -----------------------------------------------------------------------------
637 #define UNSUPPORTED(func) func { return SA_ERROR_NOT_SUPPORTED; }
639 UNSUPPORTED(int sa_stream_create_opaque(sa_stream_t
**s
, const char *client_name
, sa_mode_t mode
, const char *codec
))
640 UNSUPPORTED(int sa_stream_set_write_lower_watermark(sa_stream_t
*s
, size_t size
))
641 UNSUPPORTED(int sa_stream_set_read_lower_watermark(sa_stream_t
*s
, size_t size
))
642 UNSUPPORTED(int sa_stream_set_write_upper_watermark(sa_stream_t
*s
, size_t size
))
643 UNSUPPORTED(int sa_stream_set_read_upper_watermark(sa_stream_t
*s
, size_t size
))
644 UNSUPPORTED(int sa_stream_set_channel_map(sa_stream_t
*s
, const sa_channel_t map
[], unsigned int n
))
645 UNSUPPORTED(int sa_stream_set_xrun_mode(sa_stream_t
*s
, sa_xrun_mode_t mode
))
646 UNSUPPORTED(int sa_stream_set_non_interleaved(sa_stream_t
*s
, int enable
))
647 UNSUPPORTED(int sa_stream_set_dynamic_rate(sa_stream_t
*s
, int enable
))
648 UNSUPPORTED(int sa_stream_set_driver(sa_stream_t
*s
, const char *driver
))
649 UNSUPPORTED(int sa_stream_start_thread(sa_stream_t
*s
, sa_event_callback_t callback
))
650 UNSUPPORTED(int sa_stream_stop_thread(sa_stream_t
*s
))
651 UNSUPPORTED(int sa_stream_change_device(sa_stream_t
*s
, const char *device_name
))
652 UNSUPPORTED(int sa_stream_change_read_volume(sa_stream_t
*s
, const int32_t vol
[], unsigned int n
))
653 UNSUPPORTED(int sa_stream_change_write_volume(sa_stream_t
*s
, const int32_t vol
[], unsigned int n
))
654 UNSUPPORTED(int sa_stream_change_rate(sa_stream_t
*s
, unsigned int rate
))
655 UNSUPPORTED(int sa_stream_change_meta_data(sa_stream_t
*s
, const char *name
, const void *data
, size_t size
))
656 UNSUPPORTED(int sa_stream_change_user_data(sa_stream_t
*s
, const void *value
))
657 UNSUPPORTED(int sa_stream_set_adjust_rate(sa_stream_t
*s
, sa_adjust_t direction
))
658 UNSUPPORTED(int sa_stream_set_adjust_nchannels(sa_stream_t
*s
, sa_adjust_t direction
))
659 UNSUPPORTED(int sa_stream_set_adjust_pcm_format(sa_stream_t
*s
, sa_adjust_t direction
))
660 UNSUPPORTED(int sa_stream_set_adjust_watermarks(sa_stream_t
*s
, sa_adjust_t direction
))
661 UNSUPPORTED(int sa_stream_get_mode(sa_stream_t
*s
, sa_mode_t
*access_mode
))
662 UNSUPPORTED(int sa_stream_get_codec(sa_stream_t
*s
, char *codec
, size_t *size
))
663 UNSUPPORTED(int sa_stream_get_pcm_format(sa_stream_t
*s
, sa_pcm_format_t
*format
))
664 UNSUPPORTED(int sa_stream_get_rate(sa_stream_t
*s
, unsigned int *rate
))
665 UNSUPPORTED(int sa_stream_get_nchannels(sa_stream_t
*s
, int *nchannels
))
666 UNSUPPORTED(int sa_stream_get_user_data(sa_stream_t
*s
, void **value
))
667 UNSUPPORTED(int sa_stream_get_write_lower_watermark(sa_stream_t
*s
, size_t *size
))
668 UNSUPPORTED(int sa_stream_get_read_lower_watermark(sa_stream_t
*s
, size_t *size
))
669 UNSUPPORTED(int sa_stream_get_write_upper_watermark(sa_stream_t
*s
, size_t *size
))
670 UNSUPPORTED(int sa_stream_get_read_upper_watermark(sa_stream_t
*s
, size_t *size
))
671 UNSUPPORTED(int sa_stream_get_channel_map(sa_stream_t
*s
, sa_channel_t map
[], unsigned int *n
))
672 UNSUPPORTED(int sa_stream_get_xrun_mode(sa_stream_t
*s
, sa_xrun_mode_t
*mode
))
673 UNSUPPORTED(int sa_stream_get_non_interleaved(sa_stream_t
*s
, int *enabled
))
674 UNSUPPORTED(int sa_stream_get_dynamic_rate(sa_stream_t
*s
, int *enabled
))
675 UNSUPPORTED(int sa_stream_get_driver(sa_stream_t
*s
, char *driver_name
, size_t *size
))
676 UNSUPPORTED(int sa_stream_get_device(sa_stream_t
*s
, char *device_name
, size_t *size
))
677 UNSUPPORTED(int sa_stream_get_read_volume(sa_stream_t
*s
, int32_t vol
[], unsigned int *n
))
678 UNSUPPORTED(int sa_stream_get_write_volume(sa_stream_t
*s
, int32_t vol
[], unsigned int *n
))
679 UNSUPPORTED(int sa_stream_get_meta_data(sa_stream_t
*s
, const char *name
, void*data
, size_t *size
))
680 UNSUPPORTED(int sa_stream_get_adjust_rate(sa_stream_t
*s
, sa_adjust_t
*direction
))
681 UNSUPPORTED(int sa_stream_get_adjust_nchannels(sa_stream_t
*s
, sa_adjust_t
*direction
))
682 UNSUPPORTED(int sa_stream_get_adjust_pcm_format(sa_stream_t
*s
, sa_adjust_t
*direction
))
683 UNSUPPORTED(int sa_stream_get_adjust_watermarks(sa_stream_t
*s
, sa_adjust_t
*direction
))
684 UNSUPPORTED(int sa_stream_get_state(sa_stream_t
*s
, sa_state_t
*state
))
685 UNSUPPORTED(int sa_stream_get_event_error(sa_stream_t
*s
, sa_error_t
*error
))
686 UNSUPPORTED(int sa_stream_get_event_notify(sa_stream_t
*s
, sa_notify_t
*notify
))
687 UNSUPPORTED(int sa_stream_read(sa_stream_t
*s
, void *data
, size_t nbytes
))
688 UNSUPPORTED(int sa_stream_read_ni(sa_stream_t
*s
, unsigned int channel
, void *data
, size_t nbytes
))
689 UNSUPPORTED(int sa_stream_write_ni(sa_stream_t
*s
, unsigned int channel
, const void *data
, size_t nbytes
))
690 UNSUPPORTED(int sa_stream_pwrite(sa_stream_t
*s
, const void *data
, size_t nbytes
, int64_t offset
, sa_seek_t whence
))
691 UNSUPPORTED(int sa_stream_pwrite_ni(sa_stream_t
*s
, unsigned int channel
, const void *data
, size_t nbytes
, int64_t offset
, sa_seek_t whence
))
692 UNSUPPORTED(int sa_stream_get_read_size(sa_stream_t
*s
, size_t *size
))
693 UNSUPPORTED(int sa_stream_drain(sa_stream_t
*s
))
695 const char *sa_strerror(int code
) { return NULL
; }