Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
mpd
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Иван Мажукин
mpd
Commits
4cd9abe6
Commit
4cd9abe6
authored
Jul 09, 2016
by
Jacob Vosmaer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
output/osx channel_map feature
parent
b67e7df3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
163 additions
and
0 deletions
+163
-0
mpd.conf.5
doc/mpd.conf.5
+26
-0
mpdconf.example
doc/mpdconf.example
+9
-0
OSXOutputPlugin.cxx
src/output/plugins/OSXOutputPlugin.cxx
+128
-0
No files found.
doc/mpd.conf.5
View file @
4cd9abe6
...
...
@@ -251,6 +251,32 @@ errors on bandwidth-limited devices. Some users have reported good results
with this set to 50000, but not all devices support values this high. Most
users do not need to change this. The default is 256000000 / sample_rate(kHz),
or 5804 microseconds for CD-quality audio.
.SH OPTIONAL OS X OUTPUT PARAMETERS
.TP
.B device <dev>
This specifies the device to use for audio output. The default is
"default". Use the names listed in the "Audio Devices" window of
"Audio MIDI Setup".
.TP
.B channel_map <input,input,input...>
Specifies a channel map. If your audio device has more than two
outputs this allows you to route audio to auxillary outputs. For
predictable results you should also specify a "format" with a fixed
number of channels, e.g. "*:*:2". The number of items in the channel
map must match the number of output channels of your output device.
Each list entry specifies the source for that output channel; use "-1"
to silence an output. For example, if you have a four-channel output
device and you wish to send stereo sound (format "*:*:2") to outputs 3
and 4 while leaving outputs 1 and 2 silent then set the channel map to
"-1,-1,0,1". In this example '0' and '1' denote the left and right
channel respectively.
The channel map may not refer to outputs that do not exist according
to the format. If the format is "*:*:1" (mono) and you have a
four-channel sound card then "-1,-1,0,0" (dual mono output on the
second pair of sound card outputs) is a valid channel map but
"-1,-1,0,1" is not because the second channel ('1') does not exist
when the output is mono.
.SH FILES
.TP
.BI ~/.mpdconf
...
...
doc/mpdconf.example
View file @
4cd9abe6
...
...
@@ -313,6 +313,15 @@ input {
# mixer_type "software"
#}
#
# An example of an OS X output:
#
#audio_output {
# type "osx"
# name "My OS X Device"
## device "Built-in Output" # optional
## channel_map "-1,-1,0,1" # optional
#}
#
## Example "pipe" output:
#
#audio_output {
...
...
src/output/plugins/OSXOutputPlugin.cxx
View file @
4cd9abe6
...
...
@@ -39,6 +39,7 @@ struct OSXOutput {
OSType
component_subtype
;
/* only applicable with kAudioUnitSubType_HALOutput */
const
char
*
device_name
;
const
char
*
channel_map
;
AudioComponentInstance
au
;
AudioStreamBasicDescription
asbd
;
...
...
@@ -93,6 +94,8 @@ osx_output_configure(OSXOutput *oo, const ConfigBlock &block)
/* XXX am I supposed to strdup() this? */
oo
->
device_name
=
device
;
}
oo
->
channel_map
=
block
.
GetBlockValue
(
"channel_map"
);
}
static
AudioOutput
*
...
...
@@ -118,6 +121,126 @@ osx_output_finish(AudioOutput *ao)
}
static
bool
osx_output_parse_channel_map
(
const
char
*
device_name
,
const
char
*
channel_map_str
,
SInt32
channel_map
[],
UInt32
num_channels
,
Error
&
error
)
{
char
*
endptr
;
unsigned
int
inserted_channels
=
0
;
bool
want_number
=
true
;
while
(
*
channel_map_str
)
{
if
(
inserted_channels
>=
num_channels
)
{
error
.
Format
(
osx_output_domain
,
"%s: channel map contains more than %u entries or trailing garbage"
,
device_name
,
num_channels
);
return
false
;
}
if
(
!
want_number
&&
*
channel_map_str
==
','
)
{
++
channel_map_str
;
want_number
=
true
;
continue
;
}
if
(
want_number
&&
(
isdigit
(
*
channel_map_str
)
||
*
channel_map_str
==
'-'
)
)
{
channel_map
[
inserted_channels
]
=
strtol
(
channel_map_str
,
&
endptr
,
10
);
if
(
channel_map
[
inserted_channels
]
<
-
1
)
{
error
.
Format
(
osx_output_domain
,
"%s: channel map value %d not allowed (must be -1 or greater)"
,
device_name
,
channel_map
[
inserted_channels
]);
return
false
;
}
channel_map_str
=
endptr
;
want_number
=
false
;
FormatDebug
(
osx_output_domain
,
"%s: channel_map[%u] = %d"
,
device_name
,
inserted_channels
,
channel_map
[
inserted_channels
]);
++
inserted_channels
;
continue
;
}
error
.
Format
(
osx_output_domain
,
"%s: invalid character '%c' in channel map"
,
device_name
,
*
channel_map_str
);
return
false
;
}
if
(
inserted_channels
<
num_channels
)
{
error
.
Format
(
osx_output_domain
,
"%s: channel map contains less than %u entries"
,
device_name
,
num_channels
);
return
false
;
}
return
true
;
}
static
bool
osx_output_set_channel_map
(
OSXOutput
*
oo
,
Error
&
error
)
{
AudioStreamBasicDescription
desc
;
OSStatus
status
;
SInt32
*
channel_map
=
nullptr
;
UInt32
size
,
num_channels
;
char
errormsg
[
1024
];
bool
ret
=
true
;
size
=
sizeof
(
desc
);
memset
(
&
desc
,
0
,
size
);
status
=
AudioUnitGetProperty
(
oo
->
au
,
kAudioUnitProperty_StreamFormat
,
kAudioUnitScope_Output
,
0
,
&
desc
,
&
size
);
if
(
status
!=
noErr
)
{
osx_os_status_to_cstring
(
status
,
errormsg
,
sizeof
(
errormsg
));
error
.
Format
(
osx_output_domain
,
status
,
"%s: unable to get number of output device channels: %s"
,
oo
->
device_name
,
errormsg
);
ret
=
false
;
goto
done
;
}
num_channels
=
desc
.
mChannelsPerFrame
;
channel_map
=
new
SInt32
[
num_channels
];
if
(
!
osx_output_parse_channel_map
(
oo
->
device_name
,
oo
->
channel_map
,
channel_map
,
num_channels
,
error
)
)
{
ret
=
false
;
goto
done
;
}
size
=
num_channels
*
sizeof
(
SInt32
);
status
=
AudioUnitSetProperty
(
oo
->
au
,
kAudioOutputUnitProperty_ChannelMap
,
kAudioUnitScope_Input
,
0
,
channel_map
,
size
);
if
(
status
!=
noErr
)
{
osx_os_status_to_cstring
(
status
,
errormsg
,
sizeof
(
errormsg
));
error
.
Format
(
osx_output_domain
,
status
,
"%s: unable to set channel map: %s"
,
oo
->
device_name
,
errormsg
);
ret
=
false
;
goto
done
;
}
done:
delete
[]
channel_map
;
return
ret
;
}
static
bool
osx_output_set_device
(
OSXOutput
*
oo
,
Error
&
error
)
{
bool
ret
=
true
;
...
...
@@ -214,6 +337,11 @@ osx_output_set_device(OSXOutput *oo, Error &error)
"set OS X audio output device ID=%u, name=%s"
,
(
unsigned
)
deviceids
[
i
],
name
);
if
(
oo
->
channel_map
&&
!
osx_output_set_channel_map
(
oo
,
error
))
{
ret
=
false
;
goto
done
;
}
done:
delete
[]
deviceids
;
if
(
cfname
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment