mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-21 21:55:38 +00:00
Add Volume control in Windows and Linux
Add volume control int Windows through the mixer API (until XP) and the EndpointVolume API (Vista and above). Add volume control in Linux through ALSA. Convert AudioManager to use shared_ptrs.
This commit is contained in:
parent
a1cb5bdda1
commit
edc26aa4e1
|
@ -37,6 +37,11 @@ find_package(FreeImage REQUIRED)
|
|||
find_package(SDL REQUIRED)
|
||||
find_package(Boost REQUIRED COMPONENTS system filesystem)
|
||||
|
||||
#add ALSA for Linux
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
find_package(ALSA REQUIRED)
|
||||
endif()
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
#set up compiler flags and excutable names
|
||||
if(DEFINED BCMHOST)
|
||||
|
@ -71,6 +76,13 @@ set(ES_INCLUDE_DIRS
|
|||
${Boost_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
#add ALSA for Linux
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
LIST(APPEND ES_INCLUDE_DIRS
|
||||
${ALSA_INCLUDE_DIRS}
|
||||
)
|
||||
endif()
|
||||
|
||||
if(DEFINED BCMHOST)
|
||||
LIST(APPEND ES_INCLUDE_DIRS
|
||||
"/opt/vc/include"
|
||||
|
@ -109,6 +121,7 @@ set(ES_HEADERS
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/src/Renderer.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Sound.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/SystemData.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/VolumeControl.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Window.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/XMLReader.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiAnimation.h
|
||||
|
@ -142,6 +155,7 @@ set(ES_SOURCES
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/src/Renderer_init.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Sound.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/SystemData.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/VolumeControl.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Window.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/XMLReader.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiAnimation.cpp
|
||||
|
@ -199,12 +213,24 @@ set(ES_LIBRARIES
|
|||
${SDLMAIN_LIBRARY}
|
||||
)
|
||||
|
||||
#add ALSA for Linux
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
LIST(APPEND ES_LIBRARIES
|
||||
${ALSA_LIBRARY}
|
||||
)
|
||||
endif()
|
||||
|
||||
if(DEFINED BCMHOST)
|
||||
LIST(APPEND ES_LIBRARIES
|
||||
bcm_host
|
||||
EGL
|
||||
)
|
||||
else()
|
||||
if(MSVC)
|
||||
LIST(APPEND ES_LIBRARIES
|
||||
winmm
|
||||
)
|
||||
endif()
|
||||
if(${GLSystem} MATCHES "Desktop OpenGL")
|
||||
LIST(APPEND ES_LIBRARIES
|
||||
${OPENGL_LIBRARIES}
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
#include "AudioManager.h"
|
||||
|
||||
#include "Log.h"
|
||||
#include "VolumeControl.h"
|
||||
|
||||
|
||||
std::vector<std::shared_ptr<Sound>> AudioManager::sSoundVector;
|
||||
std::shared_ptr<AudioManager> AudioManager::sInstance;
|
||||
SDL_AudioSpec AudioManager::sAudioFormat;
|
||||
std::shared_ptr<AudioManager> AudioManager::sInstance;
|
||||
|
||||
|
||||
void AudioManager::mixAudio(void *unused, Uint8 *stream, int len)
|
||||
|
@ -52,6 +53,9 @@ void AudioManager::mixAudio(void *unused, Uint8 *stream, int len)
|
|||
AudioManager::AudioManager()
|
||||
{
|
||||
init();
|
||||
|
||||
//set internal volume
|
||||
//VolumeControl::getInstance()->setVolume(50);
|
||||
}
|
||||
|
||||
AudioManager::~AudioManager()
|
||||
|
@ -95,16 +99,9 @@ void AudioManager::init()
|
|||
|
||||
void AudioManager::deinit()
|
||||
{
|
||||
//stop playing all Sounds
|
||||
for(unsigned int i = 0; i < sSoundVector.size(); i++)
|
||||
{
|
||||
if(sSoundVector.at(i)->isPlaying())
|
||||
{
|
||||
sSoundVector[i]->stop();
|
||||
}
|
||||
}
|
||||
//pause audio and close SDL connection
|
||||
SDL_PauseAudio(1);
|
||||
//stop all playback
|
||||
stop();
|
||||
|
||||
SDL_CloseAudio();
|
||||
}
|
||||
|
||||
|
@ -132,6 +129,24 @@ void AudioManager::unregisterSound(std::shared_ptr<Sound> & sound)
|
|||
void AudioManager::play()
|
||||
{
|
||||
getInstance();
|
||||
|
||||
//set internal audio volume. important after launching a game and returning here
|
||||
//VolumeControl::getInstance()->setVolume(50);
|
||||
|
||||
//unpause audio, the mixer will figure out if samples need to be played...
|
||||
SDL_PauseAudio(0);
|
||||
}
|
||||
|
||||
void AudioManager::stop()
|
||||
{
|
||||
//stop playing all Sounds
|
||||
for(unsigned int i = 0; i < sSoundVector.size(); i++)
|
||||
{
|
||||
if(sSoundVector.at(i)->isPlaying())
|
||||
{
|
||||
sSoundVector[i]->stop();
|
||||
}
|
||||
}
|
||||
//pause audio
|
||||
SDL_PauseAudio(1);
|
||||
}
|
||||
|
|
|
@ -25,10 +25,11 @@ public:
|
|||
void init();
|
||||
void deinit();
|
||||
|
||||
static void registerSound(std::shared_ptr<Sound> & sound);
|
||||
static void unregisterSound(std::shared_ptr<Sound> & sound);
|
||||
void registerSound(std::shared_ptr<Sound> & sound);
|
||||
void unregisterSound(std::shared_ptr<Sound> & sound);
|
||||
|
||||
static void play();
|
||||
void play();
|
||||
void stop();
|
||||
|
||||
virtual ~AudioManager();
|
||||
};
|
||||
|
|
|
@ -95,7 +95,7 @@ void Sound::play()
|
|||
playing = true;
|
||||
}
|
||||
//tell the AudioManager to start playing samples
|
||||
AudioManager::play();
|
||||
AudioManager::getInstance()->play();
|
||||
}
|
||||
|
||||
bool Sound::isPlaying() const
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <SDL_joystick.h>
|
||||
#include "Renderer.h"
|
||||
#include "AudioManager.h"
|
||||
#include "VolumeControl.h"
|
||||
#include "Log.h"
|
||||
#include "InputManager.h"
|
||||
#include <iostream>
|
||||
|
@ -69,6 +70,7 @@ void SystemData::launchGame(Window* window, GameData* game)
|
|||
LOG(LogInfo) << "Attempting to launch game...";
|
||||
|
||||
AudioManager::getInstance()->deinit();
|
||||
VolumeControl::getInstance()->deinit();
|
||||
window->deinit();
|
||||
|
||||
std::string command = mLaunchCommand;
|
||||
|
@ -87,6 +89,7 @@ void SystemData::launchGame(Window* window, GameData* game)
|
|||
}
|
||||
|
||||
window->init();
|
||||
VolumeControl::getInstance()->init();
|
||||
AudioManager::getInstance()->init();
|
||||
}
|
||||
|
||||
|
|
357
src/VolumeControl.cpp
Normal file
357
src/VolumeControl.cpp
Normal file
|
@ -0,0 +1,357 @@
|
|||
#include "VolumeControl.h"
|
||||
|
||||
#include "Log.h"
|
||||
|
||||
|
||||
#if defined(__linux__)
|
||||
const char * VolumeControl::mixerName = "Master";
|
||||
const char * VolumeControl::mixerCard = "default";
|
||||
#endif
|
||||
|
||||
std::shared_ptr<VolumeControl> VolumeControl::sInstance;
|
||||
|
||||
|
||||
VolumeControl::VolumeControl()
|
||||
: originalVolume(0), internalVolume(0)
|
||||
#if defined (__APPLE__)
|
||||
#error TODO: Not implemented for MacOS yet!!!
|
||||
#elif defined(__linux__)
|
||||
, mixerIndex(0), mixerHandle(nullptr), mixerElem(nullptr), mixerSelemId(nullptr)
|
||||
#elif defined(WIN32) || defined(_WIN32)
|
||||
, mixerHandle(nullptr), endpointVolume(nullptr)
|
||||
#endif
|
||||
{
|
||||
init();
|
||||
|
||||
//get original volume levels for system
|
||||
getVolume(originalVolume);
|
||||
}
|
||||
|
||||
VolumeControl::~VolumeControl()
|
||||
{
|
||||
//set original volume levels for system
|
||||
setVolume(originalVolume);
|
||||
|
||||
deinit();
|
||||
}
|
||||
|
||||
std::shared_ptr<VolumeControl> & VolumeControl::getInstance()
|
||||
{
|
||||
//check if an VolumeControl instance is already created, if not create one
|
||||
if (sInstance == nullptr) {
|
||||
sInstance = std::shared_ptr<VolumeControl>(new VolumeControl);
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
void VolumeControl::init()
|
||||
{
|
||||
//initialize audio mixer interface
|
||||
#if defined (__APPLE__)
|
||||
#error TODO: Not implemented for MacOS yet!!!
|
||||
#elif defined(__linux__)
|
||||
//try to open mixer device
|
||||
if (mixerHandle == nullptr)
|
||||
{
|
||||
snd_mixer_selem_id_alloca(&mixerSelemId);
|
||||
//sets simple-mixer index and name
|
||||
snd_mixer_selem_id_set_index(mixerSelemId, mixerIndex);
|
||||
snd_mixer_selem_id_set_name(mixerSelemId, mixerName);
|
||||
//open mixer
|
||||
if (snd_mixer_open(&mixerHandle, 0) >= 0)
|
||||
{
|
||||
LOG(LogDebug) << "AudioManager::init() - Opened ALSA mixer";
|
||||
//ok. attach to defualt card
|
||||
if (snd_mixer_attach(mixerHandle, mixerCard) >= 0)
|
||||
{
|
||||
LOG(LogDebug) << "AudioManager::init() - Attached to default card";
|
||||
//ok. register simple element class
|
||||
if (snd_mixer_selem_register(mixerHandle, NULL, NULL) >= 0)
|
||||
{
|
||||
LOG(LogDebug) << "AudioManager::init() - Registered simple element class";
|
||||
//ok. load registered elements
|
||||
if (snd_mixer_load(mixerHandle) >= 0)
|
||||
{
|
||||
LOG(LogDebug) << "AudioManager::init() - Loaded mixer elements";
|
||||
//ok. find elements now
|
||||
mixerElem = snd_mixer_find_selem(mixerHandle, mixerSelemId);
|
||||
if (mixerElem != nullptr)
|
||||
{
|
||||
//wohoo. good to go...
|
||||
LOG(LogDebug) << "AudioManager::init() - Mixer initialized";
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(LogError) << "AudioManager::init() - Failed to find mixer elements!";
|
||||
snd_mixer_close(mixerHandle);
|
||||
mixerHandle = nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(LogError) << "AudioManager::init() - Failed to load mixer elements!";
|
||||
snd_mixer_close(mixerHandle);
|
||||
mixerHandle = nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(LogError) << "AudioManager::init() - Failed to register simple element class!";
|
||||
snd_mixer_close(mixerHandle);
|
||||
mixerHandle = nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(LogError) << "AudioManager::init() - Failed to attach to default card!";
|
||||
snd_mixer_close(mixerHandle);
|
||||
mixerHandle = nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(LogError) << "AudioManager::init() - Failed to open ALSA mixer!";
|
||||
}
|
||||
}
|
||||
#elif defined(WIN32) || defined(_WIN32)
|
||||
//get windows version information
|
||||
OSVERSIONINFOEXA osVer = {sizeof(OSVERSIONINFO)};
|
||||
::GetVersionExA(reinterpret_cast<LPOSVERSIONINFOA>(&osVer));
|
||||
//check windows version
|
||||
if(osVer.dwMajorVersion < 6)
|
||||
{
|
||||
//Windows older than Vista. use mixer API. open default mixer
|
||||
if (mixerHandle == nullptr)
|
||||
{
|
||||
if (mixerOpen(&mixerHandle, 0, NULL, 0, 0) == MMSYSERR_NOERROR)
|
||||
{
|
||||
//retrieve info on the volume slider control for the "Speaker Out" line
|
||||
MIXERLINECONTROLS mixerLineControls;
|
||||
mixerLineControls.cbStruct = sizeof(MIXERLINECONTROLS);
|
||||
mixerLineControls.dwLineID = 0xFFFF0000; //Id of "Speaker Out" line
|
||||
mixerLineControls.cControls = 1;
|
||||
//mixerLineControls.dwControlID = 0x00000000; //Id of "Speaker Out" line's volume slider
|
||||
mixerLineControls.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME; //Get volume control
|
||||
mixerLineControls.pamxctrl = &mixerControl;
|
||||
mixerLineControls.cbmxctrl = sizeof(MIXERCONTROL);
|
||||
if (mixerGetLineControls((HMIXEROBJ)mixerHandle, &mixerLineControls, MIXER_GETLINECONTROLSF_ONEBYTYPE) != MMSYSERR_NOERROR)
|
||||
{
|
||||
LOG(LogError) << "AudioManager::getVolume() - Failed to get mixer volume control!";
|
||||
mixerClose(mixerHandle);
|
||||
mixerHandle = nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(LogError) << "AudioManager::init() - Failed to open mixer!";
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Windows Vista or above. use EndpointVolume API. get device enumerator
|
||||
if (endpointVolume == nullptr)
|
||||
{
|
||||
CoInitialize(nullptr);
|
||||
IMMDeviceEnumerator * deviceEnumerator = nullptr;
|
||||
CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID *)&deviceEnumerator);
|
||||
if (deviceEnumerator != nullptr)
|
||||
{
|
||||
//get default endpoint
|
||||
IMMDevice * defaultDevice = nullptr;
|
||||
deviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &defaultDevice);
|
||||
if (defaultDevice != nullptr)
|
||||
{
|
||||
//retrieve endpoint volume
|
||||
defaultDevice->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, nullptr, (LPVOID *)&endpointVolume);
|
||||
if (endpointVolume == nullptr)
|
||||
{
|
||||
LOG(LogError) << "AudioManager::init() - Failed to get default audio endpoint volume!";
|
||||
}
|
||||
//release default device. we don't need it anymore
|
||||
defaultDevice->Release();
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(LogError) << "AudioManager::init() - Failed to get default audio endpoint!";
|
||||
}
|
||||
//release device enumerator. we don't need it anymore
|
||||
deviceEnumerator->Release();
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(LogError) << "AudioManager::init() - Failed to get audio endpoint enumerator!";
|
||||
CoUninitialize();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void VolumeControl::deinit()
|
||||
{
|
||||
//deinitialize audio mixer interface
|
||||
#if defined (__APPLE__)
|
||||
#error TODO: Not implemented for MacOS yet!!!
|
||||
#elif defined(__linux__)
|
||||
if (mixerHandle != nullptr) {
|
||||
snd_mixer_close(mixerHandle);
|
||||
mixerHandle = nullptr;
|
||||
mixerElem = nullptr;
|
||||
}
|
||||
#elif defined(WIN32) || defined(_WIN32)
|
||||
if (mixerHandle != nullptr) {
|
||||
mixerClose(mixerHandle);
|
||||
mixerHandle = nullptr;
|
||||
}
|
||||
else if (endpointVolume != nullptr) {
|
||||
endpointVolume->Release();
|
||||
endpointVolume = nullptr;
|
||||
CoUninitialize();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void VolumeControl::getVolume(uint8_t & volume)
|
||||
{
|
||||
volume = 0;
|
||||
|
||||
#if defined (__APPLE__)
|
||||
#error TODO: Not implemented for MacOS yet!!!
|
||||
#elif defined(__linux__)
|
||||
if (mixerElem != nullptr)
|
||||
{
|
||||
//get volume range
|
||||
long minVolume;
|
||||
long maxVolume;
|
||||
if (snd_mixer_selem_get_playback_volume_range(mixerElem, &minVolume, &maxVolume) == 0)
|
||||
{
|
||||
//ok. now get volume
|
||||
long rawVolume;
|
||||
if (snd_mixer_selem_get_playback_volume(mixerElem, SND_MIXER_SCHN_MONO, &rawVolume) == 0)
|
||||
{
|
||||
//worked. bring into range 0-100
|
||||
rawVolume -= minVolume;
|
||||
if (rawVolume > 0)
|
||||
{
|
||||
volume = (rawVolume * 100) / (maxVolume - minVolume);
|
||||
//clamp to 0-100 range
|
||||
if (volume > 100)
|
||||
{
|
||||
volume = 100;
|
||||
}
|
||||
}
|
||||
//else volume = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(LogError) << "VolumeControl::getVolume() - Failed to get mixer volume!";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(LogError) << "VolumeControl::getVolume() - Failed to get volume range!";
|
||||
}
|
||||
}
|
||||
#elif defined(WIN32) || defined(_WIN32)
|
||||
if (mixerHandle != nullptr)
|
||||
{
|
||||
//Windows older than Vista. use mixer API. get volume from line control
|
||||
MIXERCONTROLDETAILS_UNSIGNED value;
|
||||
MIXERCONTROLDETAILS mixerControlDetails;
|
||||
mixerControlDetails.cbStruct = sizeof(MIXERCONTROLDETAILS);
|
||||
mixerControlDetails.dwControlID = mixerControl.dwControlID;
|
||||
mixerControlDetails.cChannels = 1; //always 1 for a MIXERCONTROL_CONTROLF_UNIFORM control
|
||||
mixerControlDetails.cMultipleItems = 0; //always 0 except for a MIXERCONTROL_CONTROLF_MULTIPLE control
|
||||
mixerControlDetails.paDetails = &value;
|
||||
mixerControlDetails.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
|
||||
if (mixerGetControlDetails((HMIXEROBJ)mixerHandle, &mixerControlDetails, MIXER_GETCONTROLDETAILSF_VALUE) == MMSYSERR_NOERROR)
|
||||
{
|
||||
volume = (uint8_t)((value.dwValue * 100) / 65535);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(LogError) << "AudioManager::getVolume() - Failed to get mixer volume!";
|
||||
}
|
||||
}
|
||||
else if (endpointVolume != nullptr)
|
||||
{
|
||||
//Windows Vista or above. use EndpointVolume API
|
||||
float floatVolume = 0.0f; //0-1
|
||||
if (endpointVolume->GetMasterVolumeLevelScalar(&floatVolume) == S_OK)
|
||||
{
|
||||
volume = (uint8_t)(floatVolume * 100.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(LogError) << "AudioManager::setVolume() - Failed to get master volume!";
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void VolumeControl::setVolume(uint8_t volume)
|
||||
{
|
||||
//clamp to 0-100 range
|
||||
if (volume > 100)
|
||||
{
|
||||
volume = 100;
|
||||
}
|
||||
//store values in internal variables
|
||||
internalVolume = volume;
|
||||
#if defined (__APPLE__)
|
||||
#error TODO: Not implemented for MacOS yet!!!
|
||||
#elif defined(__linux__)
|
||||
if (mixerElem != nullptr)
|
||||
{
|
||||
//get volume range
|
||||
long minVolume;
|
||||
long maxVolume;
|
||||
if (snd_mixer_selem_get_playback_volume_range(mixerElem, &minVolume, &maxVolume) == 0)
|
||||
{
|
||||
//ok. bring into minVolume-maxVolume range and set
|
||||
long rawVolume = (volume * (maxVolume - minVolume) / 100) + minVolume;
|
||||
if (snd_mixer_selem_set_playback_volume(mixerElem, SND_MIXER_SCHN_FRONT_LEFT, rawVolume) < 0
|
||||
|| snd_mixer_selem_set_playback_volume(mixerElem, SND_MIXER_SCHN_FRONT_RIGHT, rawVolume) < 0)
|
||||
{
|
||||
LOG(LogError) << "VolumeControl::getVolume() - Failed to set mixer volume!";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(LogError) << "VolumeControl::getVolume() - Failed to get volume range!";
|
||||
}
|
||||
}
|
||||
#elif defined(WIN32) || defined(_WIN32)
|
||||
if (mixerHandle != nullptr)
|
||||
{
|
||||
//Windows older than Vista. use mixer API. get volume from line control
|
||||
MIXERCONTROLDETAILS_UNSIGNED value;
|
||||
value.dwValue = (volume * 65535) / 100;
|
||||
MIXERCONTROLDETAILS mixerControlDetails;
|
||||
mixerControlDetails.cbStruct = sizeof(MIXERCONTROLDETAILS);
|
||||
mixerControlDetails.dwControlID = mixerControl.dwControlID;
|
||||
mixerControlDetails.cChannels = 1; //always 1 for a MIXERCONTROL_CONTROLF_UNIFORM control
|
||||
mixerControlDetails.cMultipleItems = 0; //always 0 except for a MIXERCONTROL_CONTROLF_MULTIPLE control
|
||||
mixerControlDetails.paDetails = &value;
|
||||
mixerControlDetails.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
|
||||
if (mixerSetControlDetails((HMIXEROBJ)mixerHandle, &mixerControlDetails, MIXER_SETCONTROLDETAILSF_VALUE) != MMSYSERR_NOERROR)
|
||||
{
|
||||
LOG(LogError) << "AudioManager::setVolume() - Failed to set mixer volume!";
|
||||
}
|
||||
}
|
||||
else if (endpointVolume != nullptr)
|
||||
{
|
||||
//Windows Vista or above. use EndpointVolume API
|
||||
float floatVolume = 0.0f; //0-1
|
||||
if (volume > 0) {
|
||||
floatVolume = (float)volume / 100.0f;
|
||||
}
|
||||
if (endpointVolume->SetMasterVolumeLevelScalar(floatVolume, nullptr) != S_OK)
|
||||
{
|
||||
LOG(LogError) << "AudioManager::setVolume() - Failed to set master volume!";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
56
src/VolumeControl.h
Normal file
56
src/VolumeControl.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined (__APPLE__)
|
||||
#error TODO: Not implemented for MacOS yet!!!
|
||||
#elif defined(__linux__)
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <alsa/asoundlib.h>
|
||||
#elif defined(WIN32) || defined(_WIN32)
|
||||
#include <Windows.h>
|
||||
#include <MMSystem.h>
|
||||
#include <mmdeviceapi.h>
|
||||
#include <endpointvolume.h>
|
||||
#endif
|
||||
|
||||
/*!
|
||||
Singleton pattern. Call getInstance() to get an object.
|
||||
*/
|
||||
class VolumeControl
|
||||
{
|
||||
#if defined (__APPLE__)
|
||||
#error TODO: Not implemented for MacOS yet!!!
|
||||
#elif defined(__linux__)
|
||||
static const char * mixerName;
|
||||
static const char * mixerCard;
|
||||
int mixerIndex;
|
||||
snd_mixer_t* mixerHandle;
|
||||
snd_mixer_elem_t* mixerElem;
|
||||
snd_mixer_selem_id_t* mixerSelemId;
|
||||
#elif defined(WIN32) || defined(_WIN32)
|
||||
HMIXER mixerHandle;
|
||||
MIXERCONTROL mixerControl;
|
||||
IAudioEndpointVolume * endpointVolume;
|
||||
#endif
|
||||
|
||||
uint8_t originalVolume;
|
||||
uint8_t internalVolume;
|
||||
|
||||
static std::shared_ptr<VolumeControl> sInstance;
|
||||
|
||||
VolumeControl();
|
||||
|
||||
public:
|
||||
static std::shared_ptr<VolumeControl> & getInstance();
|
||||
|
||||
void init();
|
||||
void deinit();
|
||||
|
||||
void getVolume(uint8_t & volume);
|
||||
void setVolume(uint8_t volume);
|
||||
|
||||
virtual ~VolumeControl();
|
||||
};
|
|
@ -69,10 +69,10 @@ GuiTheme::GuiTheme(Window* window, bool detailed, std::string path) : Gui(window
|
|||
mSoundMap["menuOpen"] = std::shared_ptr<Sound>(new Sound);
|
||||
|
||||
//register all sound with the audiomanager
|
||||
AudioManager::registerSound(mSoundMap["menuScroll"]);
|
||||
AudioManager::registerSound(mSoundMap["menuSelect"]);
|
||||
AudioManager::registerSound(mSoundMap["menuBack"]);
|
||||
AudioManager::registerSound(mSoundMap["menuOpen"]);
|
||||
AudioManager::getInstance()->registerSound(mSoundMap["menuScroll"]);
|
||||
AudioManager::getInstance()->registerSound(mSoundMap["menuSelect"]);
|
||||
AudioManager::getInstance()->registerSound(mSoundMap["menuBack"]);
|
||||
AudioManager::getInstance()->registerSound(mSoundMap["menuOpen"]);
|
||||
|
||||
mListFont = NULL;
|
||||
mDescFont = NULL;
|
||||
|
|
Loading…
Reference in a new issue