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
69c0f0fe
Commit
69c0f0fe
authored
May 28, 2020
by
Max Kellermann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
apple/AudioUnit: wrapper functions for AudioObject properties
parent
28a00472
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
122 additions
and
90 deletions
+122
-90
AudioUnit.hxx
src/apple/AudioUnit.hxx
+97
-0
OSXOutputPlugin.cxx
src/output/plugins/OSXOutputPlugin.cxx
+25
-90
No files found.
src/apple/AudioUnit.hxx
0 → 100644
View file @
69c0f0fe
/*
* Copyright 2020 Max Kellermann <max.kellermann@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef APPLE_AUDIO_OBJECT_HXX
#define APPLE_AUDIO_OBJECT_HXX
#include "Throw.hxx"
#include "util/AllocatedArray.hxx"
#include <CoreAudio/AudioHardware.h>
#include <cstddef>
std
::
size_t
AudioObjectGetPropertyDataSize
(
AudioObjectID
inObjectID
,
const
AudioObjectPropertyAddress
&
inAddress
)
{
UInt32
size
;
OSStatus
status
=
AudioObjectGetPropertyDataSize
(
inObjectID
,
&
inAddress
,
0
,
nullptr
,
&
size
);
if
(
status
!=
noErr
)
Apple
::
ThrowOSStatus
(
status
);
return
size
;
}
template
<
typename
T
>
T
AudioObjectGetPropertyDataT
(
AudioObjectID
inObjectID
,
const
AudioObjectPropertyAddress
&
inAddress
)
{
OSStatus
status
;
UInt32
size
=
sizeof
(
T
);
T
value
;
status
=
AudioObjectGetPropertyData
(
inObjectID
,
&
inAddress
,
0
,
nullptr
,
&
size
,
&
value
);
if
(
status
!=
noErr
)
Apple
::
ThrowOSStatus
(
status
);
return
value
;
}
template
<
typename
T
>
AllocatedArray
<
T
>
AudioObjectGetPropertyDataArray
(
AudioObjectID
inObjectID
,
const
AudioObjectPropertyAddress
&
inAddress
)
{
OSStatus
status
;
UInt32
size
;
status
=
AudioObjectGetPropertyDataSize
(
inObjectID
,
&
inAddress
,
0
,
nullptr
,
&
size
);
if
(
status
!=
noErr
)
Apple
::
ThrowOSStatus
(
status
);
AllocatedArray
<
T
>
result
(
size
/
sizeof
(
T
));
status
=
AudioObjectGetPropertyData
(
inObjectID
,
&
inAddress
,
0
,
nullptr
,
&
size
,
result
.
begin
());
if
(
status
!=
noErr
)
Apple
::
ThrowOSStatus
(
status
);
return
result
;
}
#endif
src/output/plugins/OSXOutputPlugin.cxx
View file @
69c0f0fe
...
...
@@ -19,6 +19,7 @@
#include "config.h"
#include "OSXOutputPlugin.hxx"
#include "apple/AudioUnit.hxx"
#include "apple/StringRef.hxx"
#include "apple/Throw.hxx"
#include "../OutputAPI.hxx"
...
...
@@ -184,22 +185,14 @@ OSXOutput::Create(EventLoop &, const ConfigBlock &block)
int
OSXOutput
::
GetVolume
()
{
Float32
vol
;
static
constexpr
AudioObjectPropertyAddress
aopa
=
{
kAudioHardwareServiceDeviceProperty_VirtualMasterVolume
,
kAudioObjectPropertyScopeOutput
,
kAudioObjectPropertyElementMaster
,
};
UInt32
size
=
sizeof
(
vol
);
OSStatus
status
=
AudioObjectGetPropertyData
(
dev_id
,
&
aopa
,
0
,
NULL
,
&
size
,
&
vol
);
if
(
status
!=
noErr
)
Apple
::
ThrowOSStatus
(
status
);
const
auto
vol
=
AudioObjectGetPropertyDataT
<
Float32
>
(
dev_id
,
aopa
);
return
static_cast
<
int
>
(
vol
*
100.0
);
}
...
...
@@ -386,65 +379,27 @@ osx_output_set_device_format(AudioDeviceID dev_id,
kAudioObjectPropertyElementMaster
};
UInt32
property_size
;
OSStatus
err
=
AudioObjectGetPropertyDataSize
(
dev_id
,
&
aopa_device_streams
,
0
,
NULL
,
&
property_size
);
if
(
err
!=
noErr
)
throw
FormatRuntimeError
(
"Cannot get number of streams: %d"
,
err
);
const
size_t
n_streams
=
property_size
/
sizeof
(
AudioStreamID
);
static
constexpr
size_t
MAX_STREAMS
=
64
;
if
(
n_streams
>
MAX_STREAMS
)
throw
std
::
runtime_error
(
"Too many streams"
);
OSStatus
err
;
AudioStreamID
streams
[
MAX_STREAMS
];
err
=
AudioObjectGetPropertyData
(
dev_id
,
&
aopa_device_streams
,
0
,
NULL
,
&
property_size
,
streams
);
if
(
err
!=
noErr
)
throw
FormatRuntimeError
(
"Cannot get streams: %d"
,
err
);
const
auto
streams
=
AudioObjectGetPropertyDataArray
<
AudioStreamID
>
(
dev_id
,
aopa_device_streams
);
bool
format_found
=
false
;
int
output_stream
;
AudioStreamBasicDescription
output_format
;
for
(
size_t
i
=
0
;
i
<
n_streams
;
i
++
)
{
UInt32
direction
;
AudioStreamID
stream
=
streams
[
i
];
property_size
=
sizeof
(
direction
);
err
=
AudioObjectGetPropertyData
(
stream
,
&
aopa_stream_direction
,
0
,
NULL
,
&
property_size
,
&
direction
);
if
(
err
!=
noErr
)
throw
FormatRuntimeError
(
"Cannot get streams direction: %d"
,
err
);
for
(
const
auto
stream
:
streams
)
{
const
auto
direction
=
AudioObjectGetPropertyDataT
<
UInt32
>
(
stream
,
aopa_stream_direction
);
if
(
direction
!=
0
)
continue
;
err
=
AudioObjectGetPropertyDataSize
(
stream
,
&
aopa_stream_phys_formats
,
0
,
NULL
,
&
property_size
);
if
(
err
!=
noErr
)
throw
FormatRuntimeError
(
"Unable to get format size s for stream %d. Error = %s"
,
streams
[
i
],
err
);
const
size_t
format_count
=
property_size
/
sizeof
(
AudioStreamRangedDescription
);
static
constexpr
size_t
MAX_FORMATS
=
256
;
if
(
format_count
>
MAX_FORMATS
)
throw
std
::
runtime_error
(
"Too many formats"
);
AudioStreamRangedDescription
format_list
[
MAX_FORMATS
];
err
=
AudioObjectGetPropertyData
(
stream
,
&
aopa_stream_phys_formats
,
0
,
NULL
,
&
property_size
,
format_list
);
if
(
err
!=
noErr
)
throw
FormatRuntimeError
(
"Unable to get available formats for stream %d. Error = %s"
,
streams
[
i
],
err
);
const
auto
format_list
=
AudioObjectGetPropertyDataArray
<
AudioStreamRangedDescription
>
(
stream
,
aopa_stream_phys_formats
);
const
size_t
format_count
=
format_list
.
size
();
float
output_score
=
0
;
for
(
size_t
j
=
0
;
j
<
format_count
;
j
++
)
{
...
...
@@ -542,26 +497,14 @@ osx_output_set_buffer_size(AudioUnit au, AudioStreamBasicDescription desc,
static
void
osx_output_hog_device
(
AudioDeviceID
dev_id
,
bool
hog
)
{
pid_t
hog_pid
;
static
constexpr
AudioObjectPropertyAddress
aopa
=
{
kAudioDevicePropertyHogMode
,
kAudioObjectPropertyScopeOutput
,
kAudioObjectPropertyElementMaster
};
UInt32
size
=
sizeof
(
hog_pid
);
OSStatus
err
=
AudioObjectGetPropertyData
(
dev_id
,
&
aopa
,
0
,
NULL
,
&
size
,
&
hog_pid
);
if
(
err
!=
noErr
)
{
FormatDebug
(
osx_output_domain
,
"Cannot get hog information: %d"
,
err
);
return
;
}
pid_t
hog_pid
=
AudioObjectGetPropertyDataT
<
pid_t
>
(
dev_id
,
aopa
);
if
(
hog
)
{
if
(
hog_pid
!=
-
1
)
{
FormatDebug
(
osx_output_domain
,
...
...
@@ -577,7 +520,8 @@ osx_output_hog_device(AudioDeviceID dev_id, bool hog)
}
hog_pid
=
hog
?
getpid
()
:
-
1
;
size
=
sizeof
(
hog_pid
);
UInt32
size
=
sizeof
(
hog_pid
);
OSStatus
err
;
err
=
AudioObjectSetPropertyData
(
dev_id
,
&
aopa
,
0
,
...
...
@@ -601,31 +545,21 @@ static void
osx_output_set_device
(
OSXOutput
*
oo
)
{
OSStatus
status
;
UInt32
size
,
numdevices
;
UInt32
size
;
if
(
oo
->
component_subtype
!=
kAudioUnitSubType_HALOutput
)
return
;
/*
how many audio devices are there
? */
/*
what are the available audio device IDs
? */
static
constexpr
AudioObjectPropertyAddress
aopa_hw_devices
{
kAudioHardwarePropertyDevices
,
kAudioObjectPropertyScopeGlobal
,
kAudioObjectPropertyElementMaster
,
};
status
=
AudioObjectGetPropertyDataSize
(
kAudioObjectSystemObject
,
&
aopa_hw_devices
,
0
,
nullptr
,
&
size
);
if
(
status
!=
noErr
)
Apple
::
ThrowOSStatus
(
status
);
/* what are the available audio device IDs? */
numdevices
=
size
/
sizeof
(
AudioDeviceID
);
std
::
unique_ptr
<
AudioDeviceID
[]
>
deviceids
(
new
AudioDeviceID
[
numdevices
]);
status
=
AudioObjectGetPropertyData
(
kAudioObjectSystemObject
,
&
aopa_hw_devices
,
0
,
nullptr
,
&
size
,
deviceids
.
get
());
if
(
status
!=
noErr
)
Apple
::
ThrowOSStatus
(
status
);
const
auto
deviceids
=
AudioObjectGetPropertyDataArray
<
AudioDeviceID
>
(
kAudioObjectSystemObject
,
aopa_hw_devices
);
/* which audio device matches oo->device_name? */
static
constexpr
AudioObjectPropertyAddress
aopa_name
{
...
...
@@ -634,6 +568,7 @@ osx_output_set_device(OSXOutput *oo)
kAudioObjectPropertyElementMaster
,
};
const
unsigned
numdevices
=
deviceids
.
size
();
unsigned
i
;
size
=
sizeof
(
CFStringRef
);
for
(
i
=
0
;
i
<
numdevices
;
i
++
)
{
...
...
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