Merge branch 'v0.20.x' into master
contains OSX mixer
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
#include "config.h"
|
||||
#include "OSXOutputPlugin.hxx"
|
||||
#include "../OutputAPI.hxx"
|
||||
#include "mixer/MixerList.hxx"
|
||||
#include "util/ScopeExit.hxx"
|
||||
#include "util/RuntimeError.hxx"
|
||||
#include "util/Domain.hxx"
|
||||
@@ -53,6 +54,8 @@ struct OSXOutput final : AudioOutput {
|
||||
OSXOutput(const ConfigBlock &block);
|
||||
|
||||
static AudioOutput *Create(EventLoop &, const ConfigBlock &block);
|
||||
int GetVolume();
|
||||
void SetVolume(unsigned new_volume);
|
||||
|
||||
private:
|
||||
void Enable() override;
|
||||
@@ -137,6 +140,45 @@ OSXOutput::Create(EventLoop &, const ConfigBlock &block)
|
||||
return oo;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
OSXOutput::GetVolume()
|
||||
{
|
||||
AudioUnitParameterValue dvolume;
|
||||
char errormsg[1024];
|
||||
|
||||
OSStatus status = AudioUnitGetParameter(au, kHALOutputParam_Volume,
|
||||
kAudioUnitScope_Global, 0, &dvolume);
|
||||
if (status != noErr) {
|
||||
osx_os_status_to_cstring(status, errormsg, sizeof(errormsg));
|
||||
throw FormatRuntimeError("unable to get volume: %s", errormsg);
|
||||
}
|
||||
|
||||
/* see the explanation in SetVolume, below */
|
||||
return static_cast<int>(dvolume * dvolume * 100.0);
|
||||
}
|
||||
|
||||
void
|
||||
OSXOutput::SetVolume(unsigned new_volume) {
|
||||
char errormsg[1024];
|
||||
|
||||
/* The scaling below makes shifts in volume greater at the lower end
|
||||
* of the scale. This mimics the "feel" of physical volume levers. This is
|
||||
* generally what users of audio software expect.
|
||||
*/
|
||||
|
||||
AudioUnitParameterValue scaled_volume =
|
||||
sqrt(static_cast<AudioUnitParameterValue>(new_volume) / 100.0);
|
||||
|
||||
OSStatus status = AudioUnitSetParameter(au, kHALOutputParam_Volume,
|
||||
kAudioUnitScope_Global, 0, scaled_volume, 0);
|
||||
if (status != noErr) {
|
||||
osx_os_status_to_cstring(status, errormsg, sizeof(errormsg));
|
||||
throw FormatRuntimeError( "unable to set new volume %u: %s",
|
||||
new_volume, errormsg);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
osx_output_parse_channel_map(
|
||||
const char *device_name,
|
||||
@@ -669,6 +711,18 @@ OSXOutput::Delay() const noexcept
|
||||
: std::chrono::milliseconds(25);
|
||||
}
|
||||
|
||||
int
|
||||
osx_output_get_volume(OSXOutput &output)
|
||||
{
|
||||
return output.GetVolume();
|
||||
}
|
||||
|
||||
void
|
||||
osx_output_set_volume(OSXOutput &output, unsigned new_volume)
|
||||
{
|
||||
return output.SetVolume(new_volume);
|
||||
}
|
||||
|
||||
const struct AudioOutputPlugin osx_output_plugin = {
|
||||
"osx",
|
||||
osx_output_test_default_device,
|
||||
|
||||
@@ -20,6 +20,14 @@
|
||||
#ifndef MPD_OSX_OUTPUT_PLUGIN_HXX
|
||||
#define MPD_OSX_OUTPUT_PLUGIN_HXX
|
||||
|
||||
struct OSXOutput;
|
||||
|
||||
extern const struct AudioOutputPlugin osx_output_plugin;
|
||||
|
||||
int
|
||||
osx_output_get_volume(OSXOutput &output);
|
||||
|
||||
void
|
||||
osx_output_set_volume(OSXOutput &output, unsigned new_volume);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user