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,9 @@ struct OSXOutput {
|
||||
boost::lockfree::spsc_queue<uint8_t> *ring_buffer;
|
||||
|
||||
OSXOutput(const ConfigBlock &block);
|
||||
|
||||
int GetVolume();
|
||||
void SetVolume(unsigned new_volume);
|
||||
};
|
||||
|
||||
static constexpr Domain osx_output_domain("osx_output");
|
||||
@@ -103,6 +107,44 @@ OSXOutput::OSXOutput(const ConfigBlock &block)
|
||||
sync_sample_rate = block.GetBlockValue("sync_sample_rate", false);
|
||||
}
|
||||
|
||||
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 AudioOutput *
|
||||
osx_output_init(const ConfigBlock &block)
|
||||
{
|
||||
@@ -678,6 +720,18 @@ osx_output_delay(AudioOutput *ao) 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,
|
||||
@@ -693,5 +747,6 @@ const struct AudioOutputPlugin osx_output_plugin = {
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
|
||||
&osx_mixer_plugin,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user