From f192d444298640d0147494405eb669d018b4115c Mon Sep 17 00:00:00 2001 From: podulator Date: Sat, 11 Jan 2020 19:57:10 +0100 Subject: [PATCH] refactored soundcard for alsa api, improved main loop render polling logic --- Makefile.linux | 2 +- Makefile.rg-350 | 2 +- src/esoteric.cpp | 41 +++++++++----- src/hw-generic.cpp | 37 ++++++++----- src/hw-generic.h | 2 + src/hw-gkd350h.cpp | 22 +++++--- src/hw-gkd350h.h | 2 + src/hw-ihardware.h | 15 +++-- src/hw-linux.cpp | 38 ++++++++----- src/hw-linux.h | 2 + src/hw-pg2.cpp | 37 +++++++++++-- src/hw-pg2.h | 13 ++++- src/hw-rg350.cpp | 27 ++++++--- src/hw-rg350.h | 12 ++-- src/hw-soundcard.h | 130 ++++++++++++++++++++++++++++++++++++++++++++ src/progressbar.cpp | 7 ++- src/renderer.cpp | 51 +++++++++++------ src/renderer.h | 2 + 18 files changed, 347 insertions(+), 95 deletions(-) create mode 100644 src/hw-soundcard.h diff --git a/Makefile.linux b/Makefile.linux index 1548c15..faf4768 100644 --- a/Makefile.linux +++ b/Makefile.linux @@ -23,7 +23,7 @@ CFLAGS = -ggdb \ -Wno-narrowing CXXFLAGS := $(CFLAGS) -LDFLAGS := $(SDL_LIBS) -lSDL_image -lSDL_ttf -lSDL_gfx -lSDL_mixer -lfreetype -lpthread -lpng -L/usr/local/lib -lopk +LDFLAGS := $(SDL_LIBS) -lSDL_image -lSDL_ttf -lSDL_gfx -lSDL_mixer -lfreetype -lpthread -lpng -L/usr/local/lib -lopk -lasound OBJDIR = objs/$(TARGET) DISTDIR = dist/$(TARGET)/esoteric diff --git a/Makefile.rg-350 b/Makefile.rg-350 index f08d973..a587c7b 100644 --- a/Makefile.rg-350 +++ b/Makefile.rg-350 @@ -33,7 +33,7 @@ CFLAGS = \ -fomit-frame-pointer CXXFLAGS = $(CFLAGS) -LDFLAGS = $(SDL_LIBS) -lfreetype -lSDL_image -lSDL_ttf -lSDL_gfx -lSDL_mixer -lSDL -lpthread -lopk -lpng +LDFLAGS = $(SDL_LIBS) -lfreetype -lSDL_image -lSDL_ttf -lSDL_gfx -lSDL_mixer -lSDL -lpthread -lopk -lpng -lasound OBJDIR = objs/$(TARGET) DISTDIR = dist/$(TARGET)/esoteric diff --git a/src/esoteric.cpp b/src/esoteric.cpp index 6d7fb15..ead92ee 100644 --- a/src/esoteric.cpp +++ b/src/esoteric.cpp @@ -156,7 +156,7 @@ Esoteric::Esoteric() { if (this->config->setHwLevelsOnBoot() && Loader::isFirstRun()) { TRACE("backlight, volume, aspect ratio and performance mode"); this->hw->setBacklightLevel(config->backlightLevel()); - this->hw->setVolumeLevel(this->config->globalVolume()); + this->hw->Soundcard()->setVolume(this->config->globalVolume()); this->hw->setKeepAspectRatio(this->config->aspectRatio()); this->hw->setPerformanceMode(this->config->performance()); } @@ -449,13 +449,13 @@ void Esoteric::main() { this->menu->setLinkIndex(this->config->link()); } - renderer->startPolling(); this->screenManager->resetTimer(); this->powerManager->resetTimer(); bool uiControlledQuit= false; + renderer->startPolling(); while (!this->quitApp) { try { - TRACE("loop"); + //TRACE("loop"); renderer->render(); if (showGreeting) { @@ -482,7 +482,10 @@ void Esoteric::main() { bool inputAction = this->inputManager->update(true); if (inputAction) { - if ((*this->inputManager)[QUIT] ) { + + if ((*this->inputManager)[NOOP]) { + continue; + } else if ((*this->inputManager)[QUIT] ) { INFO("We got a quit request"); this->quitApp = true; uiControlledQuit = true; @@ -490,9 +493,12 @@ void Esoteric::main() { } else if ((*this->inputManager)[POWER] && this->inputManager->isOnlyActive(POWER)) { this->poweroffDialog(); continue; - } else if ((*this->inputManager)[NOOP]) { - continue; - } else if ((*this->inputManager)[CONFIRM] && this->menu->selLink() != NULL) { + } + + // if we get here then we can block the renderer while we act on the command + renderer->stopPolling(); + + if ((*this->inputManager)[CONFIRM] && this->menu->selLink() != NULL) { TRACE("******************RUNNING THIS*******************"); if (menu->selLinkApp() != NULL && menu->selLinkApp()->getSelectorDir().empty()) { MessageBox mb(this, tr["Launching "] + menu->selLink()->getTitle().c_str(), menu->selLink()->getIconPath()); @@ -534,6 +540,8 @@ void Esoteric::main() { } else if ((*this->inputManager)[MANUAL] && this->menu->selLinkApp() != NULL) { showManual(); } + // and start polling again now we're done + renderer->startPolling(); } } @@ -846,7 +854,7 @@ void Esoteric::deviceMenu() { int selected = 0; int backlightLevel = this->hw->getBacklightLevel(); - int volumeLevel = this->hw->getVolumeLevel(); + int volumeLevel = this->hw->Soundcard()->getVolume(); int backlightTimeout = config->backlightTimeout(); bool keepAspectRatio = this->hw->getKeepAspectRatio(); int buttonRepeatRate = this->config->buttonRepeatRate(); @@ -993,9 +1001,9 @@ void Esoteric::deviceMenu() { } } - if (volumeLevel != this->hw->getVolumeLevel()) { + if (volumeLevel != this->hw->Soundcard()->getVolume()) { this->config->globalVolume(volumeLevel); - this->hw->setVolumeLevel(volumeLevel); + this->hw->Soundcard()->setVolume(volumeLevel); } if (backlightLevel != this->hw->getBacklightLevel()) { this->config->backlightLevel(backlightLevel); @@ -1523,8 +1531,6 @@ void Esoteric::skinColors() { void Esoteric::about() { TRACE("enter"); - std::vector text; - std::string temp; std::string uptime = this->hw->uptime(); int battLevel = this->hw->getBatteryLevel(); @@ -1559,7 +1565,13 @@ void Esoteric::about() { cpuFreq += " mhz"; } - temp = "\n"; + std::string volume; + std::stringstream ss; + ss << this->hw->Soundcard()->getVolume(); + ss >> volume; + volume += "%"; + + std::string temp = "\n"; temp += tr["Build date: "] + __BUILDTIME__ + "\n"; temp += tr["App: "] + appPath + "\n"; temp += tr["Config: "] + this->config->configFile() + "\n"; @@ -1567,7 +1579,8 @@ void Esoteric::about() { temp += tr["Device: "] + this->hw->getDeviceType() + "\n"; temp += tr["Uptime: "] + uptime + "\n"; temp += tr["Battery: "] + ((battLevel == IHardware::BATTERY_CHARGING) ? tr["Charging"] : batt) + "\n"; - temp += tr["CPU: "] + cpuFreq + " \n"; + temp += tr["CPU: "] + cpuFreq + "\n"; + temp += tr["Volume: "] + volume + "\n"; temp += tr["Internal storage size: "] + this->hw->getDiskSize(this->hw->getInternalMountDevice()) + "\n"; temp += tr["Internal storage free: "] + this->hw->getDiskFree("/media/data") + "\n"; diff --git a/src/hw-generic.cpp b/src/hw-generic.cpp index 680150f..f516cb3 100644 --- a/src/hw-generic.cpp +++ b/src/hw-generic.cpp @@ -23,14 +23,25 @@ HwGeneric::HwGeneric() : IHardware() { this->performanceModes_.insert({"performance", "Performance"}); this->clock_ = new SysClock(); + this->soundcard_ = new DummySoundcard(); + TRACE( + "brightness: %i, volume : %i", + this->getBacklightLevel(), + this->soundcard_->getVolume()); } HwGeneric::~HwGeneric() { delete this->clock_; + delete this->soundcard_; } -IClock *HwGeneric::Clock() { return (IClock *)this->clock_; }; +IClock *HwGeneric::Clock() { + return (IClock *)this->clock_; +} +ISoundcard *HwGeneric::Soundcard() { + return (ISoundcard *)this->soundcard_; +} -bool HwGeneric::getTVOutStatus() { return 0; }; +bool HwGeneric::getTVOutStatus() { return 0; } std::string HwGeneric::getTVOutMode() { return "OFF"; } void HwGeneric::setTVOutMode(std::string mode) { std::string val = mode; @@ -77,22 +88,22 @@ std::vector HwGeneric::getPerformanceModes() { } bool HwGeneric::supportsOverClocking() { return false; } -uint32_t HwGeneric::getCPUSpeed() { return 0; }; -bool HwGeneric::setCPUSpeed(uint32_t mhz) { return true; }; +uint32_t HwGeneric::getCPUSpeed() { return 0; } +bool HwGeneric::setCPUSpeed(uint32_t mhz) { return true; } -uint32_t HwGeneric::getCpuDefaultSpeed() { return 0; }; +uint32_t HwGeneric::getCpuDefaultSpeed() { return 0; } -void HwGeneric::ledOn(int flashSpeed) { return; }; -void HwGeneric::ledOff() { return; }; +void HwGeneric::ledOn(int flashSpeed) { return; } +void HwGeneric::ledOff() { return; } -int HwGeneric::getBatteryLevel() { return IHardware::BATTERY_CHARGING; }; +int HwGeneric::getBatteryLevel() { return IHardware::BATTERY_CHARGING; } -int HwGeneric::getBacklightLevel() { return 100; }; -int HwGeneric::setBacklightLevel(int val) { return val; }; +int HwGeneric::getBacklightLevel() { return 100; } +int HwGeneric::setBacklightLevel(int val) { return val; } -bool HwGeneric::getKeepAspectRatio() { return true; }; -bool HwGeneric::setKeepAspectRatio(bool val) { return val; }; +bool HwGeneric::getKeepAspectRatio() { return true; } +bool HwGeneric::setKeepAspectRatio(bool val) { return val; } std::string HwGeneric::getDeviceType() { return "Generic"; } -bool HwGeneric::setScreenState(const bool &enable) { return true; }; +bool HwGeneric::setScreenState(const bool &enable) { return true; } diff --git a/src/hw-generic.h b/src/hw-generic.h index 640437a..8c6b4e9 100644 --- a/src/hw-generic.h +++ b/src/hw-generic.h @@ -19,12 +19,14 @@ class HwGeneric : IHardware { std::string performanceMode_ = "ondemand"; const std::string defaultPerformanceMode = "ondemand"; SysClock * clock_; + DummySoundcard * soundcard_; public: HwGeneric(); ~HwGeneric(); IClock * Clock(); + ISoundcard * Soundcard(); bool getTVOutStatus(); std::string getTVOutMode(); diff --git a/src/hw-gkd350h.cpp b/src/hw-gkd350h.cpp index 7a009cd..adc4c72 100644 --- a/src/hw-gkd350h.cpp +++ b/src/hw-gkd350h.cpp @@ -16,26 +16,32 @@ HwGkd350h::HwGkd350h() : IHardware() { this->EXTERNAL_MOUNT_POINT = EXTERNAL_CARD_PATH; this->clock_ = new RTC(); + this->soundcard_ = new AlsaSoundcard("default", "Master"); this->pollBatteries = fileExists(BATTERY_CHARGING_PATH) && fileExists(BATTERY_LEVEL_PATH); this->pollBacklight = fileExists(BACKLIGHT_PATH); this->getBacklightLevel(); - this->getVolumeLevel(); this->getKeepAspectRatio(); this->resetKeymap(); TRACE( - "brightness - current : %i, volume : %i", - this->backlightLevel_, - this->volumeLevel_); + "brightness: %i, volume : %i", + this->getBacklightLevel(), + this->soundcard_->getVolume()); TRACE("exit"); } HwGkd350h::~HwGkd350h() { delete this->clock_; + delete this->soundcard_; } -IClock *HwGkd350h::Clock() { return (IClock *)this->clock_; }; +IClock *HwGkd350h::Clock() { + return (IClock *)this->clock_; +} +ISoundcard *HwGkd350h::Soundcard() { + return (ISoundcard *)this->soundcard_; +} bool HwGkd350h::getTVOutStatus() { return false; } @@ -56,11 +62,13 @@ std::vector HwGkd350h::getPerformanceModes() { bool HwGkd350h::supportsOverClocking() { return true; } -uint32_t HwGkd350h::getCPUSpeed() { return 0; }; +uint32_t HwGkd350h::getCPUSpeed() { + return this->getCpuDefaultSpeed(); +} bool HwGkd350h::setCPUSpeed(uint32_t mhz) { return true; } -uint32_t HwGkd350h::getCpuDefaultSpeed() { return 0; } +uint32_t HwGkd350h::getCpuDefaultSpeed() { return 1500; } void HwGkd350h::ledOn(int flashSpeed) { return; } diff --git a/src/hw-gkd350h.h b/src/hw-gkd350h.h index b535c80..bf3c317 100644 --- a/src/hw-gkd350h.h +++ b/src/hw-gkd350h.h @@ -15,6 +15,7 @@ class HwGkd350h : IHardware { void resetKeymap(); RTC * clock_; + AlsaSoundcard * soundcard_; int backlightLevel_ = 0; @@ -34,6 +35,7 @@ class HwGkd350h : IHardware { HwGkd350h(); ~HwGkd350h(); IClock * Clock(); + ISoundcard * Soundcard(); bool getTVOutStatus(); void setTVOutMode(std::string mode); diff --git a/src/hw-ihardware.h b/src/hw-ihardware.h index 939dd82..50a90f7 100644 --- a/src/hw-ihardware.h +++ b/src/hw-ihardware.h @@ -9,7 +9,6 @@ #include #include -#include #include #include #include @@ -25,6 +24,7 @@ #include "debug.h" #include "utilities.h" #include "iclock.h" +#include "hw-soundcard.h" class IHardware { @@ -33,12 +33,12 @@ class IHardware { std::string kernelVersion_; protected: - +/* int volumeLevel_ = 0; - bool pollVolume = true; const std::string GET_VOLUME_PATH = "/dev/mixer"; const std::string SET_VOLUME_PATH = "/dev/mixer"; +*/ std::vector cpuSpeeds_; int16_t curMMCStatus; @@ -73,10 +73,14 @@ class IHardware { }; IHardware() { + /* + this->volumeLevel_ = 0; this->pollVolume = fileExists(GET_VOLUME_PATH); + */ } virtual IClock * Clock() = 0; + virtual ISoundcard * Soundcard() = 0; virtual bool getTVOutStatus() = 0; virtual void setTVOutMode(std::string mode) = 0; @@ -119,6 +123,7 @@ class IHardware { /*! Gets or sets the devices volume level, scale 0 - 100 */ +/* virtual int getVolumeLevel() { TRACE("enter"); @@ -135,6 +140,8 @@ class IHardware { } else { TRACE("couldn't read value"); } + } else { + TRACE("couldn't open : '%s' for read only access", GET_VOLUME_PATH.c_str()); } } @@ -162,7 +169,7 @@ class IHardware { TRACE("exit : %i", this->volumeLevel_); return this->volumeLevel_; }; - +*/ /*! Gets or sets the devices backlight level, scale 0 - 100 */ diff --git a/src/hw-linux.cpp b/src/hw-linux.cpp index f65c3be..b71ba3c 100644 --- a/src/hw-linux.cpp +++ b/src/hw-linux.cpp @@ -13,19 +13,27 @@ HwLinux::HwLinux() : IHardware() { this->performanceModes_.insert({"performance", "Performance"}); this->clock_ = new SysClock(); - + this->soundcard_ = new AlsaSoundcard("default", "Master"); this->getBacklightLevel(); - this->getVolumeLevel(); this->getKeepAspectRatio(); + TRACE( + "brightness: %i, volume : %i", + this->getBacklightLevel(), + this->soundcard_->getVolume()); } HwLinux::~HwLinux() { delete this->clock_; + delete this->soundcard_; } -IClock *HwLinux::Clock() { return (IClock *)this->clock_; }; - -bool HwLinux::getTVOutStatus() { return 0; }; +IClock *HwLinux::Clock() { + return (IClock *)this->clock_; +} +ISoundcard *HwLinux::Soundcard() { + return (ISoundcard *)this->soundcard_; +} +bool HwLinux::getTVOutStatus() { return 0; } std::string HwLinux::getTVOutMode() { return "OFF"; } void HwLinux::setTVOutMode(std::string mode) { std::string val = mode; @@ -71,21 +79,21 @@ std::vector HwLinux::getPerformanceModes() { } bool HwLinux::supportsOverClocking() { return false; } -uint32_t HwLinux::getCPUSpeed() { return 0; }; -bool HwLinux::setCPUSpeed(uint32_t mhz) { return true; }; +uint32_t HwLinux::getCPUSpeed() { return 0; } +bool HwLinux::setCPUSpeed(uint32_t mhz) { return true; } -uint32_t HwLinux::getCpuDefaultSpeed() { return 0; }; +uint32_t HwLinux::getCpuDefaultSpeed() { return 0; } -void HwLinux::ledOn(int flashSpeed) { return; }; -void HwLinux::ledOff() { return; }; +void HwLinux::ledOn(int flashSpeed) { return; } +void HwLinux::ledOff() { return; } -int HwLinux::getBatteryLevel() { return 100; }; +int HwLinux::getBatteryLevel() { return 100; } int HwLinux::getBacklightLevel() { return 100; }; -int HwLinux::setBacklightLevel(int val) { return val; }; +int HwLinux::setBacklightLevel(int val) { return val; } -bool HwLinux::getKeepAspectRatio() { return true; }; -bool HwLinux::setKeepAspectRatio(bool val) { return val; }; +bool HwLinux::getKeepAspectRatio() { return true; } +bool HwLinux::setKeepAspectRatio(bool val) { return val; } std::string HwLinux::getDeviceType() { return "Linux"; } @@ -101,7 +109,7 @@ void HwLinux::reboot() { int HwLinux::defaultScreenWidth() { return 320; } int HwLinux::defaultScreenHeight() { return 240; } -bool HwLinux::setScreenState(const bool &enable) { return true; }; +bool HwLinux::setScreenState(const bool &enable) { return true; } std::string HwLinux::performanceModeMap(std::string fromInternal) { std::unordered_map::iterator it; diff --git a/src/hw-linux.h b/src/hw-linux.h index c4b2101..a462e7c 100644 --- a/src/hw-linux.h +++ b/src/hw-linux.h @@ -18,12 +18,14 @@ class HwLinux : IHardware { std::string performanceMode_ = "ondemand"; const std::string defaultPerformanceMode = "ondemand"; SysClock * clock_; + AlsaSoundcard * soundcard_; public: HwLinux(); ~HwLinux(); IClock * Clock(); + ISoundcard * Soundcard(); bool getTVOutStatus(); std::string getTVOutMode(); diff --git a/src/hw-pg2.cpp b/src/hw-pg2.cpp index 2b8c05b..0131136 100644 --- a/src/hw-pg2.cpp +++ b/src/hw-pg2.cpp @@ -20,6 +20,7 @@ HwPG2::HwPG2() : IHardware() { this->EXTERNAL_MOUNT_POINT = EXTERNAL_CARD_PATH; this->clock_ = new RTC(); + this->soundcard_ = new AlsaSoundcard("default", "PCM"); this->ledMaxBrightness_ = fileExists(LED_MAX_BRIGHTNESS_PATH) ? fileReader(LED_MAX_BRIGHTNESS_PATH) : 0; this->performanceModes_.insert({"ondemand", "On demand"}); @@ -33,22 +34,26 @@ HwPG2::HwPG2() : IHardware() { this->cpuSpeeds_ = { 360, 1080 }; this->getBacklightLevel(); - this->getVolumeLevel(); this->getKeepAspectRatio(); this->resetKeymap(); TRACE( - "brightness - max : %s, current : %i, volume : %i", - ledMaxBrightness_.c_str(), - this->backlightLevel_, - this->volumeLevel_); + "brightness: %i, volume : %i", + this->getBacklightLevel(), + this->soundcard_->getVolume()); } HwPG2::~HwPG2() { delete this->clock_; + delete this->soundcard_; this->ledOff(); } -IClock *HwPG2::Clock() { return (IClock *)this->clock_; }; +IClock *HwPG2::Clock() { + return (IClock *)this->clock_; +} +ISoundcard *HwPG2::Soundcard() { + return (ISoundcard *)this->soundcard_; +} bool HwPG2::getTVOutStatus() { return 0; }; std::string HwPG2::getTVOutMode() { return "OFF"; } @@ -177,6 +182,26 @@ void HwPG2::ledOff() { return; } +/* +todo :: clean me +int HwPG2::getVolumeLevel() { + TRACE("enter"); + if (this->pollVolume) { + int vol = -1; + std::string volPath = GET_VOLUME_PATH + " " + VOLUME_ARGS; + std::string result = exec(volPath.c_str()); + if (result.length() > 0) { + vol = atoi(trim(result).c_str()); + } + // scale 0 - 31, turn to percent + vol = ceil(vol * 100 / 31); + this->volumeLevel_ = vol; + } + TRACE("exit : %i", this->volumeLevel_); + return this->volumeLevel_; +} +*/ + int HwPG2::getBatteryLevel() { int online, result = 0; if (!this->pollBatteries) diff --git a/src/hw-pg2.h b/src/hw-pg2.h index 307c959..f6f1bf7 100644 --- a/src/hw-pg2.h +++ b/src/hw-pg2.h @@ -21,6 +21,8 @@ class HwPG2 : IHardware { void resetKeymap(); RTC * clock_; + AlsaSoundcard * soundcard_; + std::unordered_map performanceModes_; std::string ledMaxBrightness_; std::string performanceMode_ = "ondemand"; @@ -44,7 +46,12 @@ class HwPG2 : IHardware { const std::string BATTERY_CHARGING_PATH = "/sys/class/power_supply/usb/online"; const std::string BATTERY_LEVEL_PATH = "/sys/class/power_supply/battery/capacity"; const std::string ALT_KEYMAP_FILE = "/sys/devices/platform/linkdev/alt_key_map"; - + /* + todo :: clean me + const std::string GET_VOLUME_PATH = "/usr/bin/alsa-getvolume"; + const std::string SET_VOLUME_PATH = "/usr/bin/alsa-setvolume"; + const std::string VOLUME_ARGS = "default PCM"; + */ const std::string SYSFS_CPUFREQ_PATH = "/sys/devices/system/cpu/cpu0/cpufreq"; const std::string SYSFS_CPUFREQ_MAX = SYSFS_CPUFREQ_PATH + "/scaling_max_freq"; const std::string SYSFS_CPUFREQ_SET = SYSFS_CPUFREQ_PATH + "/scaling_setspeed"; @@ -62,6 +69,7 @@ class HwPG2 : IHardware { ~HwPG2(); IClock * Clock(); + ISoundcard * Soundcard(); bool getTVOutStatus(); std::string getTVOutMode(); @@ -83,6 +91,9 @@ class HwPG2 : IHardware { int getBatteryLevel(); +/* + int getVolumeLevel(); +*/ int getBacklightLevel(); int setBacklightLevel(int val); diff --git a/src/hw-rg350.cpp b/src/hw-rg350.cpp index 9552136..3b66c26 100644 --- a/src/hw-rg350.cpp +++ b/src/hw-rg350.cpp @@ -21,6 +21,7 @@ HwRg350::HwRg350() : IHardware() { this->EXTERNAL_MOUNT_POINT = EXTERNAL_CARD_PATH; this->clock_ = new RTC(); + this->soundcard_ = new AlsaSoundcard("default", "PCM"); this->ledMaxBrightness_ = fileExists(LED_MAX_BRIGHTNESS_PATH) ? fileReader(LED_MAX_BRIGHTNESS_PATH) : 0; this->performanceModes_.insert({"ondemand", "On demand"}); @@ -28,29 +29,34 @@ HwRg350::HwRg350() : IHardware() { this->pollBacklight = fileExists(BACKLIGHT_PATH); this->pollBatteries = fileExists(BATTERY_CHARGING_PATH) && fileExists(BATTERY_LEVEL_PATH); - this->pollVolume = fileExists(GET_VOLUME_PATH); + //this->pollVolume = fileExists(GET_VOLUME_PATH); this->supportsOverclocking_ = fileExists(SYSFS_CPUFREQ_SET); this->supportsPowerGovernors_ = fileExists(SYSFS_CPU_SCALING_GOVERNOR); this->cpuSpeeds_ = { 360, 1080 }; this->getBacklightLevel(); - this->getVolumeLevel(); + //this->getVolumeLevel(); this->getKeepAspectRatio(); this->resetKeymap(); TRACE( - "brightness - max : %s, current : %i, volume : %i", - ledMaxBrightness_.c_str(), - this->backlightLevel_, - this->volumeLevel_); + "brightness: %i, volume : %i", + this->getBacklightLevel(), + this->soundcard_->getVolume()); } HwRg350::~HwRg350() { delete this->clock_; + delete this->soundcard_; this->ledOff(); } -IClock *HwRg350::Clock() { return (IClock *)this->clock_; }; +IClock *HwRg350::Clock() { + return (IClock *)this->clock_; +} +ISoundcard *HwRg350::Soundcard() { + return (ISoundcard *)this->soundcard_; +} bool HwRg350::getTVOutStatus() { return 0; }; std::string HwRg350::getTVOutMode() { return "OFF"; } @@ -208,6 +214,8 @@ int HwRg350::getBatteryLevel() { return result; }; +/* +todo :: clean me int HwRg350::getVolumeLevel() { TRACE("enter"); if (this->pollVolume) { @@ -223,7 +231,7 @@ int HwRg350::getVolumeLevel() { } TRACE("exit : %i", this->volumeLevel_); return this->volumeLevel_; -}; +} int HwRg350::setVolumeLevel(int val) { TRACE("enter - %i", val); if (val < 0) @@ -246,7 +254,8 @@ int HwRg350::setVolumeLevel(int val) { } this->volumeLevel_ = val; return val; -}; +} +*/ int HwRg350::getBacklightLevel() { TRACE("enter"); diff --git a/src/hw-rg350.h b/src/hw-rg350.h index 506361d..f278a38 100644 --- a/src/hw-rg350.h +++ b/src/hw-rg350.h @@ -21,16 +21,16 @@ class HwRg350 : IHardware { void resetKeymap(); RTC * clock_; + AlsaSoundcard * soundcard_; + std::unordered_map performanceModes_; std::string ledMaxBrightness_; std::string performanceMode_ = "ondemand"; const std::string defaultPerformanceMode = "ondemand"; - int volumeLevel_ = 0; int backlightLevel_ = 0; bool keepAspectRatio_ = false; bool pollBacklight = false; bool pollBatteries = false; - bool pollVolume = false; bool supportsOverclocking_ = false; bool supportsPowerGovernors_ = false; @@ -41,9 +41,12 @@ class HwRg350 : IHardware { const std::string LED_DELAY_ON_PATH = LED_PREFIX + "delay_on"; const std::string LED_DELAY_OFF_PATH = LED_PREFIX + "delay_off"; const std::string LED_TRIGGER_PATH = LED_PREFIX + "trigger"; +/* +todo :: clean me const std::string GET_VOLUME_PATH = "/usr/bin/alsa-getvolume"; const std::string SET_VOLUME_PATH = "/usr/bin/alsa-setvolume"; const std::string VOLUME_ARGS = "default PCM"; +*/ const std::string BACKLIGHT_PATH = "/sys/class/backlight/pwm-backlight/brightness"; const std::string ASPECT_RATIO_PATH = "/sys/devices/platform/jz-lcd.0/keep_aspect_ratio"; const std::string BATTERY_CHARGING_PATH = "/sys/class/power_supply/usb/online"; @@ -67,6 +70,7 @@ class HwRg350 : IHardware { ~HwRg350(); IClock * Clock(); + ISoundcard * Soundcard(); bool getTVOutStatus(); std::string getTVOutMode(); @@ -87,10 +91,10 @@ class HwRg350 : IHardware { void ledOff(); int getBatteryLevel(); - +/* int getVolumeLevel(); int setVolumeLevel(int val); - +*/ int getBacklightLevel(); int setBacklightLevel(int val); diff --git a/src/hw-soundcard.h b/src/hw-soundcard.h new file mode 100644 index 0000000..4cd98b3 --- /dev/null +++ b/src/hw-soundcard.h @@ -0,0 +1,130 @@ +#ifndef _ISOUNDCARD_ +#define _ISOUNDCARD_ + +#include +#include +#include +#include + +#include "debug.h" +#include "constants.h" +#include "utilities.h" + +// generic interface +class ISoundcard { + protected: + ISoundcard() {}; + + public: + ISoundcard(std::string card, std::string channel) {}; + virtual int getVolume() = 0; + virtual bool setVolume(int val) = 0; +}; + +class DummySoundcard : ISoundcard { + public: + DummySoundcard(std::string card="blank", std::string channel="none") : ISoundcard() {}; + int getVolume() { return 100; }; + bool setVolume(int val) { return true; }; +}; + +class AlsaSoundcard : ISoundcard { + + private: + std::string card_; + std::string channel_; + protected: + + public: + + AlsaSoundcard(std::string card, std::string channel) : ISoundcard(card, channel) { + this->card_ = card; + this->channel_ = channel; + } + + int getVolume() { + TRACE("enter"); + int result = -1; + long min, max; + snd_mixer_t *handle; + snd_mixer_selem_id_t *sid; + const char *card = this->card_.c_str(); + const char *selem_name = this->channel_.c_str(); + + int sndFd = snd_mixer_open(&handle, 0); + if (0 == sndFd) { + int cardFd = snd_mixer_attach(handle, card); + if (0 == cardFd) { + snd_mixer_selem_register(handle, NULL, NULL); + snd_mixer_load(handle); + + snd_mixer_selem_id_alloca(&sid); + snd_mixer_selem_id_set_index(sid, 0); + snd_mixer_selem_id_set_name(sid, selem_name); + snd_mixer_elem_t* elem = snd_mixer_find_selem(handle, sid); + + if (NULL != elem) { + TRACE("we're good to make the read"); + snd_mixer_selem_get_playback_volume_range(elem, &min, &max); + TRACE("min : %lu, max : %lu", min, max); + long unscaled = -1; + snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_MONO, &unscaled); + TRACE("raw result : %lu", unscaled); + result = (int) ((unscaled * 100) / max); + TRACE("scaled result : %i", result); + } else { + TRACE("couldn't find channel : '%s'", selem_name); + } + } else { + TRACE("couldn't attach to card : '%s'", card); + } + snd_mixer_close(handle); + } else { + TRACE("couldn't open sound mixer"); + } + + TRACE("exit : %i", result); + return result; + } + + bool setVolume(int val) { + bool result = false; + long min, max; + snd_mixer_t *handle; + snd_mixer_selem_id_t *sid; + const char *card = this->card_.c_str(); + const char *selem_name = this->channel_.c_str(); + + int sndFd = snd_mixer_open(&handle, 0); + if (0 == sndFd) { + int cardFd = snd_mixer_attach(handle, card); + if (0 == cardFd) { + snd_mixer_selem_register(handle, NULL, NULL); + snd_mixer_load(handle); + + snd_mixer_selem_id_alloca(&sid); + snd_mixer_selem_id_set_index(sid, 0); + snd_mixer_selem_id_set_name(sid, selem_name); + snd_mixer_elem_t* elem = snd_mixer_find_selem(handle, sid); + + if (NULL != elem) { + TRACE("we're good to make the write"); + snd_mixer_selem_get_playback_volume_range(elem, &min, &max); + TRACE("min : %lu, max : %lu", min, max); + snd_mixer_selem_set_playback_volume_all(elem, val * max / 100); + } else { + TRACE("couldn't find channel : '%s'", selem_name); + } + } else { + TRACE("couldn't attach to card : '%s'", card); + } + snd_mixer_close(handle); + } else { + TRACE("couldn't open sound mixer"); + } + return result; + } + +}; + +#endif diff --git a/src/progressbar.cpp b/src/progressbar.cpp index 9ea729c..e4609cd 100644 --- a/src/progressbar.cpp +++ b/src/progressbar.cpp @@ -60,8 +60,9 @@ ProgressBar::~ProgressBar() { void ProgressBar::free() { TRACE("enter"); if (this->timerId_ > 0) { - SDL_SetTimer(0, NULL); + //SDL_SetTimer(0, NULL); SDL_RemoveTimer(this->timerId_); + this->timerId_ = 0; } TRACE("exit"); } @@ -94,7 +95,7 @@ uint32_t ProgressBar::render(uint32_t interval, void * data) { //outer box me->app->screen->box(box, me->app->skin->colours.msgBoxBackground); - + //draw inner rectangle me->app->screen->rectangle( box.x + 2, @@ -132,7 +133,7 @@ uint32_t ProgressBar::render(uint32_t interval, void * data) { me->app->skin->colours.fontAltOutline); me->app->screen->flip(); - return(interval); + return interval; } void ProgressBar::exec() { diff --git a/src/renderer.cpp b/src/renderer.cpp index 36af70c..ad9d287 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -57,15 +57,19 @@ Renderer::~Renderer() { } void Renderer::startPolling() { - if (this->timerId_ != 0) - return; + TRACE("enter"); + if (this->timerId_ != 0) { + TRACE("we already have a timer running"); + return; + } this->timerId_ = SDL_AddTimer(this->interval_, callback, this); + TRACE("timer started with id : %lu", (long)this->timerId_); } void Renderer::stopPolling() { TRACE("enter - timer id : %lu", (long)this->timerId_); if (this->timerId_ > 0) { - SDL_SetTimer(0, NULL); + //SDL_SetTimer(0, NULL); SDL_RemoveTimer(this->timerId_); this->timerId_ = 0; } @@ -165,7 +169,7 @@ void Renderer::render() { } // SECTIONS - TRACE("sections"); + //TRACE("sections"); if (app->skin->sectionBar) { // do we have an image @@ -282,10 +286,10 @@ void Renderer::render() { int localXpos = ix + app->linkSpacing + padding; int localAlignTitle = VAlignMiddle; int totalFontHeight = app->fontTitle->getHeight() + app->font->getHeight(); - TRACE("total Font Height : %i, linkHeight: %i", totalFontHeight, app->linkHeight); + //TRACE("total Font Height : %i, linkHeight: %i", totalFontHeight, app->linkHeight); if (app->skin->sectionBar == Skin::SB_BOTTOM || app->skin->sectionBar == Skin::SB_TOP || app->skin->sectionBar == Skin::SB_OFF) { - TRACE("HITTING MIDDLE ALIGN"); + //TRACE("HITTING MIDDLE ALIGN"); localXpos = app->linksRect.w / 2; localAlignTitle = HAlignCenter | VAlignMiddle; } @@ -519,6 +523,14 @@ void Renderer::render() { } // app->skin->sectionBar + #if (LOG_LEVEL >= INFO_L) + if (this->polling_) { + app->screen->box( + { 2, 2, 6, 6 }, + {255, 0, 0, 255}); + } + #endif + //TRACE("flip"); app->screen->flip(); this->locked_ = false; @@ -532,10 +544,10 @@ void Renderer::layoutHelperIcons(vector icons, int rootXPos, int rootY int iconsPerRow = 0; if (app->sectionBarRect.w > app->sectionBarRect.h) { iconsPerRow = (int)(app->sectionBarRect.h / (float)helperHeight); - TRACE("horizontal mode - %i items in %i pixels", iconsPerRow, app->sectionBarRect.h); + //TRACE("horizontal mode - %i items in %i pixels", iconsPerRow, app->sectionBarRect.h); } else { iconsPerRow = (int)(app->sectionBarRect.w / (float)helperHeight); - TRACE("vertical mode - %i items in %i pixels", iconsPerRow, app->sectionBarRect.w); + //TRACE("vertical mode - %i items in %i pixels", iconsPerRow, app->sectionBarRect.w); } if (0 == iconsPerRow) { @@ -548,7 +560,7 @@ void Renderer::layoutHelperIcons(vector icons, int rootXPos, int rootY int currentYOffset = 0; for(std::vector::iterator it = icons.begin(); it != icons.end(); ++it) { - TRACE("blitting"); + //TRACE("blitting"); Surface *surface = (*it); if (NULL == surface) continue; @@ -584,10 +596,12 @@ void Renderer::pollHW() { if (this->app->screenManager->isAsleep()) return; - TRACE("section bar test"); + this->polling_ = true; + + //TRACE("section bar test"); if (this->app->skin->sectionBar) { - TRACE("section bar exists in skin settings"); - TRACE("updating helper icon status"); + //TRACE("section bar exists in skin settings"); + //TRACE("updating helper icon status"); this->batteryIcon = this->app->hw->getBatteryLevel(); if (this->batteryIcon > 5) this->batteryIcon = 6; @@ -595,31 +609,34 @@ void Renderer::pollHW() { if (this->brightnessIcon > 4 || this->iconBrightness[this->brightnessIcon] == NULL) this->brightnessIcon = 5; - int currentVolume = this->app->hw->getVolumeLevel(); + int currentVolume = this->app->hw->Soundcard()->getVolume(); this->currentVolumeMode = this->getVolumeMode(currentVolume); - TRACE("helper icon status updated"); + //TRACE("helper icon status updated"); } - TRACE("checking clock skin flag"); + //TRACE("checking clock skin flag"); if (this->app->skin->showClock) { TRACE("refreshing the clock"); app->hw->Clock()->getDateTime(); } this->app->inputManager->noop(); + this->polling_ = false; TRACE("exit"); + } uint32_t Renderer::callback(uint32_t interval, void * data) { TRACE("enter"); Renderer * me = static_cast(data); if (me->finished_) { + TRACE("callback returning early because of finished flag"); return 0; } me->pollHW(); - TRACE("exit"); - return me->interval_; + TRACE("exit : %i", interval); + return interval; } uint8_t Renderer::getVolumeMode(uint8_t vol) { diff --git a/src/renderer.h b/src/renderer.h index 3dacc97..c25c39d 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -13,6 +13,8 @@ class Renderer { int interval_; bool finished_; bool locked_; + bool polling_; + Esoteric *app; std::string prevBackdrop;