From 934109a35b895c4237001522a49c5e196ad0e200 Mon Sep 17 00:00:00 2001 From: wm4 Date: Tue, 5 May 2015 21:47:19 +0200 Subject: ao_coreaudio: move channel mapping code to a separate file Move all of the channel map retrieval/negotiation code to a separate file. This will (probably) be helpful when extending ao_coreaudio_exclusive.c. Nothing else changes, other than some minor cosmetics and renaming, and changing some details for decoupling it from the ao_coreaudio.c internals. --- audio/out/ao_coreaudio.c | 259 +-------------------------------------- audio/out/ao_coreaudio_chmap.c | 268 +++++++++++++++++++++++++++++++++++++++++ audio/out/ao_coreaudio_chmap.h | 25 ++++ wscript_build.py | 1 + 4 files changed, 298 insertions(+), 255 deletions(-) create mode 100644 audio/out/ao_coreaudio_chmap.c create mode 100644 audio/out/ao_coreaudio_chmap.h diff --git a/audio/out/ao_coreaudio.c b/audio/out/ao_coreaudio.c index a91ba95c2f..09ca4fa8cd 100644 --- a/audio/out/ao_coreaudio.c +++ b/audio/out/ao_coreaudio.c @@ -25,8 +25,9 @@ #include "options/m_option.h" #include "misc/ring.h" #include "common/msg.h" -#include "audio/out/ao_coreaudio_properties.h" -#include "audio/out/ao_coreaudio_utils.h" +#include "ao_coreaudio_chmap.h" +#include "ao_coreaudio_properties.h" +#include "ao_coreaudio_utils.h" struct priv { AudioDeviceID device; @@ -37,9 +38,6 @@ struct priv { int change_physical_format; }; -bool ca_layout_to_mp_chmap(struct ao *ao, AudioChannelLayout *layout, - struct mp_chmap *chmap); - static int64_t ca_get_hardware_latency(struct ao *ao) { struct priv *p = ao->priv; @@ -123,7 +121,6 @@ static int control(struct ao *ao, enum aocontrol cmd, void *arg) return CONTROL_UNKNOWN; } -static bool init_chmap(struct ao *ao); static bool init_audiounit(struct ao *ao, AudioStreamBasicDescription asbd); static void init_physical_format(struct ao *ao); @@ -160,7 +157,7 @@ static int init(struct ao *ao) if (p->change_physical_format) init_physical_format(ao); - if (!init_chmap(ao)) + if (!ca_init_chmap(ao, p->device)) goto coreaudio_error; ao->format = af_fmt_from_planar(ao->format); @@ -177,97 +174,6 @@ coreaudio_error: return CONTROL_ERROR; } -static AudioChannelLayout* ca_query_layout(struct ao *ao, void *talloc_ctx) -{ - struct priv *p = ao->priv; - OSStatus err; - uint32_t psize; - AudioChannelLayout *r = NULL; - - AudioObjectPropertyAddress p_addr = (AudioObjectPropertyAddress) { - .mSelector = kAudioDevicePropertyPreferredChannelLayout, - .mScope = kAudioDevicePropertyScopeOutput, - .mElement = kAudioObjectPropertyElementWildcard, - }; - - err = AudioObjectGetPropertyDataSize(p->device, &p_addr, 0, NULL, &psize); - CHECK_CA_ERROR("could not get device preferred layout (size)"); - - r = talloc_size(talloc_ctx, psize); - - err = AudioObjectGetPropertyData(p->device, &p_addr, 0, NULL, &psize, r); - CHECK_CA_ERROR("could not get device preferred layout (get)"); - -coreaudio_error: - return r; -} - -static AudioChannelLayout* ca_query_stereo_layout(struct ao *ao, void *talloc_ctx) -{ - struct priv *p = ao->priv; - OSStatus err; - const int nch = 2; - uint32_t channels[nch]; - AudioChannelLayout *r = NULL; - - AudioObjectPropertyAddress p_addr = (AudioObjectPropertyAddress) { - .mSelector = kAudioDevicePropertyPreferredChannelsForStereo, - .mScope = kAudioDevicePropertyScopeOutput, - .mElement = kAudioObjectPropertyElementWildcard, - }; - - uint32_t psize = sizeof(channels); - err = AudioObjectGetPropertyData(p->device, &p_addr, 0, NULL, &psize, channels); - CHECK_CA_ERROR("could not get device preferred stereo layout"); - - psize = sizeof(AudioChannelLayout) + nch * sizeof(AudioChannelDescription); - r = talloc_zero_size(talloc_ctx, psize); - r->mChannelLayoutTag = kAudioChannelLayoutTag_UseChannelDescriptions; - r->mNumberChannelDescriptions = nch; - - AudioChannelDescription desc = {0}; - desc.mChannelFlags = kAudioChannelFlags_AllOff; - - for(int i = 0; i < nch; i++) { - desc.mChannelLabel = channels[i]; - r->mChannelDescriptions[i] = desc; - } - -coreaudio_error: - return r; -} - -static bool init_chmap(struct ao *ao) -{ - struct priv *p = ao->priv; - void *ta_ctx = talloc_new(NULL); - - struct mp_chmap_sel chmap_sel = {.tmp = p}; - struct mp_chmap chmap = {0}; - - AudioChannelLayout *ml = ca_query_layout(ao, ta_ctx); - if (ml && ca_layout_to_mp_chmap(ao, ml, &chmap)) - mp_chmap_sel_add_map(&chmap_sel, &chmap); - - AudioChannelLayout *sl = ca_query_stereo_layout(ao, ta_ctx); - if (sl && ca_layout_to_mp_chmap(ao, sl, &chmap)) - mp_chmap_sel_add_map(&chmap_sel, &chmap); - - talloc_free(ta_ctx); - - if (!ao_chmap_sel_adjust(ao, &chmap_sel, &ao->channels)) { - MP_ERR(ao, "could not select a suitable channel map among the " - "hardware supported ones. Make sure to configure your " - "output device correctly in 'Audio MIDI Setup.app'\n"); - goto coreaudio_error; - } - - return true; - -coreaudio_error: - return false; -} - static void init_physical_format(struct ao *ao) { struct priv *p = ao->priv; @@ -469,163 +375,6 @@ static void hotplug_uninit(struct ao *ao) } } - -// Channel Mapping functions -static const int speaker_map[][2] = { - { kAudioChannelLabel_Left, MP_SPEAKER_ID_FL }, - { kAudioChannelLabel_Right, MP_SPEAKER_ID_FR }, - { kAudioChannelLabel_Center, MP_SPEAKER_ID_FC }, - { kAudioChannelLabel_LFEScreen, MP_SPEAKER_ID_LFE }, - { kAudioChannelLabel_LeftSurround, MP_SPEAKER_ID_BL }, - { kAudioChannelLabel_RightSurround, MP_SPEAKER_ID_BR }, - { kAudioChannelLabel_LeftCenter, MP_SPEAKER_ID_FLC }, - { kAudioChannelLabel_RightCenter, MP_SPEAKER_ID_FRC }, - { kAudioChannelLabel_CenterSurround, MP_SPEAKER_ID_BC }, - { kAudioChannelLabel_LeftSurroundDirect, MP_SPEAKER_ID_SL }, - { kAudioChannelLabel_RightSurroundDirect, MP_SPEAKER_ID_SR }, - { kAudioChannelLabel_TopCenterSurround, MP_SPEAKER_ID_TC }, - { kAudioChannelLabel_VerticalHeightLeft, MP_SPEAKER_ID_TFL }, - { kAudioChannelLabel_VerticalHeightCenter, MP_SPEAKER_ID_TFC }, - { kAudioChannelLabel_VerticalHeightRight, MP_SPEAKER_ID_TFR }, - { kAudioChannelLabel_TopBackLeft, MP_SPEAKER_ID_TBL }, - { kAudioChannelLabel_TopBackCenter, MP_SPEAKER_ID_TBC }, - { kAudioChannelLabel_TopBackRight, MP_SPEAKER_ID_TBR }, - - // unofficial extensions - { kAudioChannelLabel_RearSurroundLeft, MP_SPEAKER_ID_SDL }, - { kAudioChannelLabel_RearSurroundRight, MP_SPEAKER_ID_SDR }, - { kAudioChannelLabel_LeftWide, MP_SPEAKER_ID_WL }, - { kAudioChannelLabel_RightWide, MP_SPEAKER_ID_WR }, - { kAudioChannelLabel_LFE2, MP_SPEAKER_ID_LFE2 }, - - { kAudioChannelLabel_HeadphonesLeft, MP_SPEAKER_ID_DL }, - { kAudioChannelLabel_HeadphonesRight, MP_SPEAKER_ID_DR }, - - { kAudioChannelLabel_Unknown, MP_SPEAKER_ID_NA0 }, - - { 0, -1 }, -}; - -static int ca_label_to_mp_speaker_id(AudioChannelLabel label) -{ - for (int i = 0; speaker_map[i][1] >= 0; i++) - if (speaker_map[i][0] == label) - return speaker_map[i][1]; - return -1; -} - -static void ca_log_layout(struct ao *ao, int l, AudioChannelLayout *layout) -{ - if (!mp_msg_test(ao->log, l)) - return; - - AudioChannelDescription *descs = layout->mChannelDescriptions; - - mp_msg(ao->log, l, "layout: tag: <%u>, bitmap: <%u>, " - "descriptions <%u>\n", - (unsigned) layout->mChannelLayoutTag, - (unsigned) layout->mChannelBitmap, - (unsigned) layout->mNumberChannelDescriptions); - - for (int i = 0; i < layout->mNumberChannelDescriptions; i++) { - AudioChannelDescription d = descs[i]; - mp_msg(ao->log, l, " - description %d: label <%u, %u>, " - " flags: <%u>, coords: <%f, %f, %f>\n", i, - (unsigned) d.mChannelLabel, - (unsigned) ca_label_to_mp_speaker_id(d.mChannelLabel), - (unsigned) d.mChannelFlags, - d.mCoordinates[0], - d.mCoordinates[1], - d.mCoordinates[2]); - } -} - -static AudioChannelLayout *ca_layout_to_custom_layout( - struct ao *ao, void *talloc_ctx, AudioChannelLayout *l) -{ - AudioChannelLayoutTag tag = l->mChannelLayoutTag; - AudioChannelLayout *r; - OSStatus err; - - if (tag == kAudioChannelLayoutTag_UseChannelBitmap) { - uint32_t psize; - err = AudioFormatGetPropertyInfo( - kAudioFormatProperty_ChannelLayoutForBitmap, - sizeof(uint32_t), &l->mChannelBitmap, &psize); - CHECK_CA_ERROR("failed to convert channel bitmap to descriptions (info)"); - r = talloc_size(NULL, psize); - err = AudioFormatGetProperty( - kAudioFormatProperty_ChannelLayoutForBitmap, - sizeof(uint32_t), &l->mChannelBitmap, &psize, r); - CHECK_CA_ERROR("failed to convert channel bitmap to descriptions (get)"); - } else if (tag != kAudioChannelLayoutTag_UseChannelDescriptions) { - uint32_t psize; - err = AudioFormatGetPropertyInfo( - kAudioFormatProperty_ChannelLayoutForTag, - sizeof(AudioChannelLayoutTag), &l->mChannelLayoutTag, &psize); - r = talloc_size(NULL, psize); - CHECK_CA_ERROR("failed to convert channel tag to descriptions (info)"); - err = AudioFormatGetProperty( - kAudioFormatProperty_ChannelLayoutForTag, - sizeof(AudioChannelLayoutTag), &l->mChannelLayoutTag, &psize, r); - CHECK_CA_ERROR("failed to convert channel tag to descriptions (get)"); - } else { - r = l; - } - - return r; -coreaudio_error: - return NULL; -} - -bool ca_layout_to_mp_chmap(struct ao *ao, AudioChannelLayout *layout, - struct mp_chmap *chmap) -{ - void *talloc_ctx = talloc_new(NULL); - - MP_DBG(ao, "input channel layout:\n"); - ca_log_layout(ao, MSGL_DEBUG, layout); - - AudioChannelLayout *l = ca_layout_to_custom_layout(ao, talloc_ctx, layout); - if (!l) - goto coreaudio_error; - - MP_VERBOSE(ao, "converted input channel layout:\n"); - ca_log_layout(ao, MSGL_V, l); - - if (l->mNumberChannelDescriptions > MP_NUM_CHANNELS) { - MP_VERBOSE(ao, "layout has too many descriptions (%u, max: %d)\n", - (unsigned) l->mNumberChannelDescriptions, MP_NUM_CHANNELS); - return false; - } - - int next_na = MP_SPEAKER_ID_NA0; - for (int n = 0; n < l->mNumberChannelDescriptions; n++) { - AudioChannelLabel label = l->mChannelDescriptions[n].mChannelLabel; - uint8_t speaker = ca_label_to_mp_speaker_id(label); - if (speaker == MP_SPEAKER_ID_NA0 && next_na < MP_SPEAKER_ID_NA_LAST) - { - speaker = next_na++; - } - if (speaker < 0) { - MP_VERBOSE(ao, "channel label=%u unusable to build channel " - "bitmap, skipping layout\n", (unsigned) label); - goto coreaudio_error; - } else { - chmap->speaker[n] = speaker; - chmap->num = n + 1; - } - } - - talloc_free(talloc_ctx); - return chmap->num > 0; -coreaudio_error: - MP_VERBOSE(ao, "converted input channel layout (failed):\n"); - ca_log_layout(ao, MSGL_V, layout); - talloc_free(talloc_ctx); - return false; -} - #define OPT_BASE_STRUCT struct priv const struct ao_driver audio_out_coreaudio = { diff --git a/audio/out/ao_coreaudio_chmap.c b/audio/out/ao_coreaudio_chmap.c new file mode 100644 index 0000000000..f50bf4f3cc --- /dev/null +++ b/audio/out/ao_coreaudio_chmap.c @@ -0,0 +1,268 @@ +/* + * This file is part of mpv. + * + * mpv is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * mpv is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with mpv. If not, see . + */ + +#include "common/common.h" + +#include "ao_coreaudio_utils.h" + +#include "ao_coreaudio_chmap.h" + +static const int speaker_map[][2] = { + { kAudioChannelLabel_Left, MP_SPEAKER_ID_FL }, + { kAudioChannelLabel_Right, MP_SPEAKER_ID_FR }, + { kAudioChannelLabel_Center, MP_SPEAKER_ID_FC }, + { kAudioChannelLabel_LFEScreen, MP_SPEAKER_ID_LFE }, + { kAudioChannelLabel_LeftSurround, MP_SPEAKER_ID_BL }, + { kAudioChannelLabel_RightSurround, MP_SPEAKER_ID_BR }, + { kAudioChannelLabel_LeftCenter, MP_SPEAKER_ID_FLC }, + { kAudioChannelLabel_RightCenter, MP_SPEAKER_ID_FRC }, + { kAudioChannelLabel_CenterSurround, MP_SPEAKER_ID_BC }, + { kAudioChannelLabel_LeftSurroundDirect, MP_SPEAKER_ID_SL }, + { kAudioChannelLabel_RightSurroundDirect, MP_SPEAKER_ID_SR }, + { kAudioChannelLabel_TopCenterSurround, MP_SPEAKER_ID_TC }, + { kAudioChannelLabel_VerticalHeightLeft, MP_SPEAKER_ID_TFL }, + { kAudioChannelLabel_VerticalHeightCenter, MP_SPEAKER_ID_TFC }, + { kAudioChannelLabel_VerticalHeightRight, MP_SPEAKER_ID_TFR }, + { kAudioChannelLabel_TopBackLeft, MP_SPEAKER_ID_TBL }, + { kAudioChannelLabel_TopBackCenter, MP_SPEAKER_ID_TBC }, + { kAudioChannelLabel_TopBackRight, MP_SPEAKER_ID_TBR }, + + // unofficial extensions + { kAudioChannelLabel_RearSurroundLeft, MP_SPEAKER_ID_SDL }, + { kAudioChannelLabel_RearSurroundRight, MP_SPEAKER_ID_SDR }, + { kAudioChannelLabel_LeftWide, MP_SPEAKER_ID_WL }, + { kAudioChannelLabel_RightWide, MP_SPEAKER_ID_WR }, + { kAudioChannelLabel_LFE2, MP_SPEAKER_ID_LFE2 }, + + { kAudioChannelLabel_HeadphonesLeft, MP_SPEAKER_ID_DL }, + { kAudioChannelLabel_HeadphonesRight, MP_SPEAKER_ID_DR }, + + { kAudioChannelLabel_Unknown, MP_SPEAKER_ID_NA0 }, + + { 0, -1 }, +}; + +static int ca_label_to_mp_speaker_id(AudioChannelLabel label) +{ + for (int i = 0; speaker_map[i][1] >= 0; i++) + if (speaker_map[i][0] == label) + return speaker_map[i][1]; + return -1; +} + +static void ca_log_layout(struct ao *ao, int l, AudioChannelLayout *layout) +{ + if (!mp_msg_test(ao->log, l)) + return; + + AudioChannelDescription *descs = layout->mChannelDescriptions; + + mp_msg(ao->log, l, "layout: tag: <%u>, bitmap: <%u>, " + "descriptions <%u>\n", + (unsigned) layout->mChannelLayoutTag, + (unsigned) layout->mChannelBitmap, + (unsigned) layout->mNumberChannelDescriptions); + + for (int i = 0; i < layout->mNumberChannelDescriptions; i++) { + AudioChannelDescription d = descs[i]; + mp_msg(ao->log, l, " - description %d: label <%u, %u>, " + " flags: <%u>, coords: <%f, %f, %f>\n", i, + (unsigned) d.mChannelLabel, + (unsigned) ca_label_to_mp_speaker_id(d.mChannelLabel), + (unsigned) d.mChannelFlags, + d.mCoordinates[0], + d.mCoordinates[1], + d.mCoordinates[2]); + } +} + +static AudioChannelLayout *ca_layout_to_custom_layout(struct ao *ao, + void *talloc_ctx, + AudioChannelLayout *l) +{ + AudioChannelLayoutTag tag = l->mChannelLayoutTag; + AudioChannelLayout *r; + OSStatus err; + + if (tag == kAudioChannelLayoutTag_UseChannelBitmap) { + uint32_t psize; + err = AudioFormatGetPropertyInfo( + kAudioFormatProperty_ChannelLayoutForBitmap, + sizeof(uint32_t), &l->mChannelBitmap, &psize); + CHECK_CA_ERROR("failed to convert channel bitmap to descriptions (info)"); + r = talloc_size(NULL, psize); + err = AudioFormatGetProperty( + kAudioFormatProperty_ChannelLayoutForBitmap, + sizeof(uint32_t), &l->mChannelBitmap, &psize, r); + CHECK_CA_ERROR("failed to convert channel bitmap to descriptions (get)"); + } else if (tag != kAudioChannelLayoutTag_UseChannelDescriptions) { + uint32_t psize; + err = AudioFormatGetPropertyInfo( + kAudioFormatProperty_ChannelLayoutForTag, + sizeof(AudioChannelLayoutTag), &l->mChannelLayoutTag, &psize); + r = talloc_size(NULL, psize); + CHECK_CA_ERROR("failed to convert channel tag to descriptions (info)"); + err = AudioFormatGetProperty( + kAudioFormatProperty_ChannelLayoutForTag, + sizeof(AudioChannelLayoutTag), &l->mChannelLayoutTag, &psize, r); + CHECK_CA_ERROR("failed to convert channel tag to descriptions (get)"); + } else { + r = l; + } + + return r; +coreaudio_error: + return NULL; +} + +static bool ca_layout_to_mp_chmap(struct ao *ao, AudioChannelLayout *layout, + struct mp_chmap *chmap) +{ + void *talloc_ctx = talloc_new(NULL); + + MP_DBG(ao, "input channel layout:\n"); + ca_log_layout(ao, MSGL_DEBUG, layout); + + AudioChannelLayout *l = ca_layout_to_custom_layout(ao, talloc_ctx, layout); + if (!l) + goto coreaudio_error; + + MP_VERBOSE(ao, "converted input channel layout:\n"); + ca_log_layout(ao, MSGL_V, l); + + if (l->mNumberChannelDescriptions > MP_NUM_CHANNELS) { + MP_VERBOSE(ao, "layout has too many descriptions (%u, max: %d)\n", + (unsigned) l->mNumberChannelDescriptions, MP_NUM_CHANNELS); + return false; + } + + int next_na = MP_SPEAKER_ID_NA0; + for (int n = 0; n < l->mNumberChannelDescriptions; n++) { + AudioChannelLabel label = l->mChannelDescriptions[n].mChannelLabel; + uint8_t speaker = ca_label_to_mp_speaker_id(label); + if (speaker == MP_SPEAKER_ID_NA0 && next_na < MP_SPEAKER_ID_NA_LAST) + speaker = next_na++; + if (speaker < 0) { + MP_VERBOSE(ao, "channel label=%u unusable to build channel " + "bitmap, skipping layout\n", (unsigned) label); + goto coreaudio_error; + } else { + chmap->speaker[n] = speaker; + chmap->num = n + 1; + } + } + + talloc_free(talloc_ctx); + return chmap->num > 0; +coreaudio_error: + MP_VERBOSE(ao, "converted input channel layout (failed):\n"); + ca_log_layout(ao, MSGL_V, layout); + talloc_free(talloc_ctx); + return false; +} + +static AudioChannelLayout* ca_query_layout(struct ao *ao, + AudioDeviceID device, + void *talloc_ctx) +{ + OSStatus err; + uint32_t psize; + AudioChannelLayout *r = NULL; + + AudioObjectPropertyAddress p_addr = (AudioObjectPropertyAddress) { + .mSelector = kAudioDevicePropertyPreferredChannelLayout, + .mScope = kAudioDevicePropertyScopeOutput, + .mElement = kAudioObjectPropertyElementWildcard, + }; + + err = AudioObjectGetPropertyDataSize(device, &p_addr, 0, NULL, &psize); + CHECK_CA_ERROR("could not get device preferred layout (size)"); + + r = talloc_size(talloc_ctx, psize); + + err = AudioObjectGetPropertyData(device, &p_addr, 0, NULL, &psize, r); + CHECK_CA_ERROR("could not get device preferred layout (get)"); + +coreaudio_error: + return r; +} + +static AudioChannelLayout* ca_query_stereo_layout(struct ao *ao, + AudioDeviceID device, + void *talloc_ctx) +{ + OSStatus err; + const int nch = 2; + uint32_t channels[nch]; + AudioChannelLayout *r = NULL; + + AudioObjectPropertyAddress p_addr = (AudioObjectPropertyAddress) { + .mSelector = kAudioDevicePropertyPreferredChannelsForStereo, + .mScope = kAudioDevicePropertyScopeOutput, + .mElement = kAudioObjectPropertyElementWildcard, + }; + + uint32_t psize = sizeof(channels); + err = AudioObjectGetPropertyData(device, &p_addr, 0, NULL, &psize, channels); + CHECK_CA_ERROR("could not get device preferred stereo layout"); + + psize = sizeof(AudioChannelLayout) + nch * sizeof(AudioChannelDescription); + r = talloc_zero_size(talloc_ctx, psize); + r->mChannelLayoutTag = kAudioChannelLayoutTag_UseChannelDescriptions; + r->mNumberChannelDescriptions = nch; + + AudioChannelDescription desc = {0}; + desc.mChannelFlags = kAudioChannelFlags_AllOff; + + for(int i = 0; i < nch; i++) { + desc.mChannelLabel = channels[i]; + r->mChannelDescriptions[i] = desc; + } + +coreaudio_error: + return r; +} + +bool ca_init_chmap(struct ao *ao, AudioDeviceID device) +{ + void *ta_ctx = talloc_new(NULL); + + struct mp_chmap_sel chmap_sel = {.tmp = ta_ctx}; + struct mp_chmap chmap = {0}; + + AudioChannelLayout *ml = ca_query_layout(ao, device, ta_ctx); + if (ml && ca_layout_to_mp_chmap(ao, ml, &chmap)) + mp_chmap_sel_add_map(&chmap_sel, &chmap); + + AudioChannelLayout *sl = ca_query_stereo_layout(ao, device, ta_ctx); + if (sl && ca_layout_to_mp_chmap(ao, sl, &chmap)) + mp_chmap_sel_add_map(&chmap_sel, &chmap); + + if (!ao_chmap_sel_adjust(ao, &chmap_sel, &ao->channels)) { + MP_ERR(ao, "could not select a suitable channel map among the " + "hardware supported ones. Make sure to configure your " + "output device correctly in 'Audio MIDI Setup.app'\n"); + goto coreaudio_error; + } + + talloc_free(ta_ctx); + return true; + +coreaudio_error: + talloc_free(ta_ctx); + return false; +} diff --git a/audio/out/ao_coreaudio_chmap.h b/audio/out/ao_coreaudio_chmap.h new file mode 100644 index 0000000000..ce31975b6d --- /dev/null +++ b/audio/out/ao_coreaudio_chmap.h @@ -0,0 +1,25 @@ +/* + * This file is part of mpv. + * + * mpv is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * mpv is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with mpv. If not, see . + */ + +#ifndef MPV_COREAUDIO_CHMAP_H +#define MPV_COREAUDIO_CHMAP_H + +#include + +bool ca_init_chmap(struct ao *ao, AudioDeviceID device); + +#endif diff --git a/wscript_build.py b/wscript_build.py index 93642c4693..6961c938b7 100644 --- a/wscript_build.py +++ b/wscript_build.py @@ -132,6 +132,7 @@ def build(ctx): ( "audio/out/ao.c" ), ( "audio/out/ao_alsa.c", "alsa" ), ( "audio/out/ao_coreaudio.c", "coreaudio" ), + ( "audio/out/ao_coreaudio_chmap.c", "coreaudio" ), ( "audio/out/ao_coreaudio_exclusive.c", "coreaudio" ), ( "audio/out/ao_coreaudio_properties.c", "coreaudio" ), ( "audio/out/ao_coreaudio_utils.c", "coreaudio" ), -- cgit v1.2.3