summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--service.c217
-rw-r--r--service.h26
-rw-r--r--skinconfig.c12
3 files changed, 238 insertions, 17 deletions
diff --git a/service.c b/service.c
index 15d761c..222729f 100644
--- a/service.c
+++ b/service.c
@@ -16,6 +16,10 @@
#include <vdr/plugin.h>
+#include <map>
+
+
+const char* pluginName = "graphlcd"; // for span
cGraphLCDService::cGraphLCDService(cGraphLCDState * state)
{
@@ -26,8 +30,9 @@ cGraphLCDService::cGraphLCDService(cGraphLCDState * state)
lcrActive = false; lcrChanged = false; lcrUse = false;
femonActive = false; femonChanged = false; femonUse = false;
mailboxActive = false; mailboxChanged = false; mailboxUse = false;
+ spanActive = false; spanChanged = false; spanUse = false;
- radioLastChange = lcrLastChange = femonLastChange = mailboxLastChange = 0;
+ radioLastChange = lcrLastChange = femonLastChange = mailboxLastChange = spanLastChange = 0;
femonVersionChecked = femonVersionValid = false;
@@ -36,6 +41,7 @@ cGraphLCDService::cGraphLCDService(cGraphLCDState * state)
lcrUpdateDelay = 60000; // 60 sec
femonUpdateDelay = 2000; // 2 sec
mailboxUpdateDelay = 10000; // 10 sec
+ spanUpdateDelay = 500; // 1/2 sec
// pre-init strings
checkRTSData.rds_text = (char*)"";
@@ -50,6 +56,24 @@ cGraphLCDService::cGraphLCDService(cGraphLCDState * state)
currFemonData.fe_name = (char*)"";
currFemonData.fe_status = (char*)"";
#endif
+
+ // pre-init span stuff (real initialisation will happen at 1st call of ServiceIsAvailable())
+ checkSpanData.bands = 0;
+ checkSpanData.barHeights = NULL;
+ checkSpanData.barHeightsLeftChannel = NULL;
+ checkSpanData.barHeightsRightChannel = NULL;
+ checkSpanData.volumeLeftChannel = new unsigned int[1];
+ checkSpanData.volumeRightChannel = new unsigned int[1];
+ checkSpanData.volumeBothChannels = new unsigned int[1];
+ checkSpanData.name = pluginName;
+ checkSpanData.falloff = 8;
+ checkSpanData.barPeaksBothChannels = NULL;
+ checkSpanData.barPeaksLeftChannel = NULL;
+ checkSpanData.barPeaksRightChannel = NULL;
+
+ currSpanData.volumeLeftChannel = new unsigned int[1];
+ currSpanData.volumeRightChannel = new unsigned int[1];
+ currSpanData.volumeBothChannels = new unsigned int[1];
}
cGraphLCDService::~cGraphLCDService()
@@ -57,21 +81,111 @@ cGraphLCDService::~cGraphLCDService()
}
-bool cGraphLCDService::ServiceIsAvailable(const std::string & Name) {
+bool cGraphLCDService::ServiceIsAvailable(const std::string & Name, const std::string & Options) {
+ bool rvAvail = false;
+ bool firstTime = false;
+
if (Name == "RadioTextService-v1.0" || Name == "radio") {
- radioUse = true;
- return (mState->GetChannelInfo().isRadio) ? radioActive : false;
+ if (!radioUse) {
+ firstTime = true;
+ radioUse = true;
+ }
+ rvAvail = (mState->GetChannelInfo().isRadio) ? radioActive : false;
} else if (Name == "LcrService-v1.0" || Name == "lcr") {
- lcrUse = true;
- return lcrActive;
+ if (!lcrUse) {
+ firstTime = true;
+ lcrUse = true;
+ }
+ rvAvail = lcrActive;
} else if (Name == "FemonService-v1.0" || Name == "femon") {
- femonUse = true;
- return femonActive;
+ if (!femonUse) {
+ firstTime = true;
+ femonUse = true;
+ }
+ rvAvail = femonActive;
} else if (Name == "MailBox-1.0" || Name == "mailbox") {
- mailboxUse = true;
- return mailboxActive;
+ if (!mailboxUse) {
+ firstTime = true;
+ mailboxUse = true;
+ }
+ rvAvail = mailboxActive;
+ } else if (Name == "span") {
+ if (!spanUse) {
+ firstTime = true;
+ spanUse = true;
+ }
+ //spanUse = true;
+ rvAvail = spanActive;
}
- return false;
+
+
+ if (firstTime) {
+ std::map<std::string, std::string> opts;
+ std::map<std::string, std::string>::iterator it;
+
+ if (Options.length() > 0) {
+ size_t pos = 0;
+ while (pos < Options.length() && pos != std::string::npos) {
+ size_t start = pos;
+ pos = Options.find(",", start);
+
+ std::string curropt = (pos != std::string::npos) ? Options.substr(start, pos-start) : Options.substr(start);
+ size_t delim = curropt.find("=");
+ if ( (delim != std::string::npos) && (delim < curropt.length()-1) ) {
+ opts[curropt.substr(0, delim)] = curropt.substr(delim+1);
+ }
+
+ if (pos != std::string::npos)
+ pos++;
+ }
+ }
+
+ // options valid for all services
+ it = opts.find("delay");
+ if (it != opts.end()) {
+ int delay = atoi( (*it).second.c_str() );
+ if (delay > 100) {
+ SetServiceUpdateDelay(Name, delay);
+ }
+ }
+
+ // indiv. options
+ if (Name == "span") {
+ int bands = 0; // default: no bands, only volume
+ it = opts.find("bands");
+ if (it != opts.end()) {
+ bands = atoi( (*it).second.c_str() );
+ }
+ if (bands < 0 || bands > 100)
+ bands = 0;
+
+ if (bands != 0) {
+ checkSpanData.bands = bands;
+ checkSpanData.barHeights = new unsigned int[bands];
+ checkSpanData.barHeightsLeftChannel = new unsigned int[bands];
+ checkSpanData.barHeightsRightChannel = new unsigned int[bands];
+ checkSpanData.barPeaksBothChannels = new unsigned int[bands];
+ checkSpanData.barPeaksLeftChannel = new unsigned int[bands];
+ checkSpanData.barPeaksRightChannel = new unsigned int[bands];
+
+ currSpanData.barHeights = new unsigned int[bands];
+ currSpanData.barHeightsLeftChannel = new unsigned int[bands];
+ currSpanData.barHeightsRightChannel = new unsigned int[bands];
+ currSpanData.barPeaksBothChannels = new unsigned int[bands];
+ currSpanData.barPeaksLeftChannel = new unsigned int[bands];
+ currSpanData.barPeaksRightChannel = new unsigned int[bands];
+ }
+
+ it = opts.find("falloff");
+ if (it != opts.end()) { // if no option 'falloff': use preset value
+ int falloff = atoi( (*it).second.c_str() );
+ if (falloff > 0 && falloff < 100)
+ checkSpanData.falloff = falloff;
+ }
+ }
+ }
+
+ return rvAvail;
}
@@ -87,6 +201,8 @@ void cGraphLCDService::SetServiceUpdateDelay(const std::string & Name, int delay
femonUpdateDelay = delay;
} else if (Name == "MailBox-1.0" || Name == "mailbox") {
mailboxUpdateDelay = delay;
+ } else if (Name == "span") {
+ spanUpdateDelay = delay;
}
}
@@ -235,6 +351,37 @@ GLCD::cType cGraphLCDService::GetItem(const std::string & ServiceName, const std
}
}
}
+ } else if (ServiceName == "span") {
+ spanUse = true;
+ if (spanActive) {
+ int index = 0;
+ if (ItemFormat != "") {
+ index = atoi(ItemFormat.c_str());
+ }
+ if (ItemName == "" || ItemName == "default" || ItemName == "VolumeBoth" || ItemName == "volume") {
+ return (int)checkSpanData.volumeBothChannels[0];
+ } else if (ItemName == "VolumeLeft" || ItemName == "volumel") {
+ return (int)checkSpanData.volumeLeftChannel[0];
+ } else if (ItemName == "VolumeRight" || ItemName == "volumer") {
+ return (int)checkSpanData.volumeRightChannel[0];
+ } else if (ItemName == "Bands" || ItemName == "bands") {
+ return (int)checkSpanData.bands;
+ } else if (ItemName == "Falloff" || ItemName == "falloff") {
+ return (int)checkSpanData.falloff;
+ } else if (ItemName == "BarHeight" || ItemName == "height") {
+ return (int)checkSpanData.barHeights[index];
+ } else if (ItemName == "BarHeightLeft" || ItemName == "heightl") {
+ return (int)checkSpanData.barHeightsLeftChannel[index];
+ } else if (ItemName == "BarHeightRight" || ItemName == "heightr") {
+ return (int)checkSpanData.barHeightsRightChannel[index];
+ } else if (ItemName == "BarPeak" || ItemName == "peak") {
+ return (int)checkSpanData.barPeaksBothChannels[index];
+ } else if (ItemName == "BarPeakLeft" || ItemName == "peakl") {
+ return (int)checkSpanData.barPeaksLeftChannel[index];
+ } else if (ItemName == "BarPeakRight" || ItemName == "peakr") {
+ return (int)checkSpanData.barPeaksRightChannel[index];
+ }
+ }
}
return "";
@@ -252,6 +399,7 @@ bool cGraphLCDService::NeedsUpdate(uint64_t CurrentTime)
/*lcrActive = false;*/ lcrChanged = false;
/*femonActive = false;*/ femonChanged = false;
mailboxChanged = false;
+ spanChanged = false;
cPlugin *p = NULL;
@@ -423,6 +571,51 @@ bool cGraphLCDService::NeedsUpdate(uint64_t CurrentTime)
}
}
+ // span
+ // only ask if span-services are defined in the skin and min. request delay exceeded
+ if (checkSpanData.bands > 0 && spanUse && ((CurrentTime-spanLastChange) >= (uint64_t)spanUpdateDelay)) {
+ spanLastChange = CurrentTime;
+ spanActive = false;
+ p = cPluginManager::CallFirstService("Span-ClientCheck-v1.0", NULL);
+ if (p) {
+ cControl* c = cControl::Control(); // workaround a bug somewhere in music or span-plugin
+ if (c != NULL && cPluginManager::CallFirstService("Span-GetBarHeights-v1.0", &checkSpanData)) {
+ spanActive = true;
+ bool chg = false;
+
+ if ( (currSpanData.volumeLeftChannel[0] != checkSpanData.volumeLeftChannel[0]) ||
+ (currSpanData.volumeRightChannel[0] != checkSpanData.volumeRightChannel[0]) ||
+ (currSpanData.volumeBothChannels[0] != checkSpanData.volumeBothChannels[0])
+ )
+ {
+ chg = true;
+ currSpanData.volumeLeftChannel[0] = checkSpanData.volumeLeftChannel[0];
+ currSpanData.volumeRightChannel[0] = checkSpanData.volumeRightChannel[0];
+ currSpanData.volumeBothChannels[0] = checkSpanData.volumeBothChannels[0];
+ }
+ for (unsigned int i = 0; i < checkSpanData.bands; i++) {
+ if ( (currSpanData.barHeights[i] != checkSpanData.barHeights[i]) ||
+ (currSpanData.barHeightsLeftChannel[i] != checkSpanData.barHeightsLeftChannel[i]) ||
+ (currSpanData.barHeightsRightChannel[i] != checkSpanData.barHeightsRightChannel[i]) ||
+ (currSpanData.barPeaksBothChannels[i] != checkSpanData.barPeaksBothChannels[i]) ||
+ (currSpanData.barPeaksLeftChannel[i] != checkSpanData.barPeaksLeftChannel[i]) ||
+ (currSpanData.barPeaksRightChannel[i] != checkSpanData.barPeaksRightChannel[i])
+ )
+ {
+ chg = true;
+ currSpanData.barHeights[i] = checkSpanData.barHeights[i];
+ currSpanData.barHeightsLeftChannel[i] = checkSpanData.barHeightsLeftChannel[i];
+ currSpanData.barHeightsRightChannel[i] = checkSpanData.barHeightsRightChannel[i];
+ currSpanData.barPeaksBothChannels[i] = checkSpanData.barPeaksBothChannels[i];
+ currSpanData.barPeaksLeftChannel[i] = checkSpanData.barPeaksLeftChannel[i];
+ currSpanData.barPeaksRightChannel[i] = checkSpanData.barPeaksRightChannel[i];
+ }
+ }
+ spanChanged = chg;
+ }
+ }
+ }
+
//mutex.Unlock();
- return (radioChanged || lcrChanged || femonChanged || mailboxChanged);
+ return (radioChanged || lcrChanged || femonChanged || mailboxChanged || spanChanged);
}
diff --git a/service.h b/service.h
index 564f13e..d9a118f 100644
--- a/service.h
+++ b/service.h
@@ -49,6 +49,23 @@ struct FemonService_v1_0 {
double dolby_bitrate;
};
+// Span
+struct Span_GetBarHeights_v1_0 {
+ // all heights are normalized to 100(%)
+ unsigned int bands; // number of bands to compute
+ unsigned int *barHeights; // the heights of the bars of the two channels combined
+ unsigned int *barHeightsLeftChannel; // the heights of the bars of the left channel
+ unsigned int *barHeightsRightChannel; // the heights of the bars of the right channel
+ unsigned int *volumeLeftChannel; // the volume of the left channels
+ unsigned int *volumeRightChannel; // the volume of the right channels
+ unsigned int *volumeBothChannels; // the combined volume of the two channels
+ const char *name; // name of the plugin that wants to get the data
+ // (must be unique for each client!)
+ unsigned int falloff; // bar falloff value
+ unsigned int *barPeaksBothChannels; // bar peaks of the two channels combined
+ unsigned int *barPeaksLeftChannel; // bar peaks of the left channel
+ unsigned int *barPeaksRightChannel; // bar peaks of the right channel
+};
class cGraphLCDService
@@ -60,6 +77,7 @@ private:
RadioTextService_v1_0 checkRTSData, currRTSData;
LcrService_v1_0 checkLcrData, currLcrData;
FemonService_v1_0 checkFemonData, currFemonData;
+ Span_GetBarHeights_v1_0 checkSpanData, currSpanData;
bool checkMailboxNewData, currMailboxNewData;
unsigned long checkMailboxUnseenData, currMailboxUnseenData;
/* __Changed = data has been changed */
@@ -69,21 +87,21 @@ private:
bool lcrChanged, lcrActive, lcrUse;
bool femonChanged, femonActive, femonUse;
bool mailboxChanged, mailboxActive, mailboxUse;
+ bool spanChanged, spanActive, spanUse;
// timestamp of last service update request
- uint64_t radioLastChange, lcrLastChange, femonLastChange, mailboxLastChange;
+ uint64_t radioLastChange, lcrLastChange, femonLastChange, mailboxLastChange, spanLastChange;
// min. delay between two service update requests
- int radioUpdateDelay, lcrUpdateDelay, femonUpdateDelay, mailboxUpdateDelay;
+ int radioUpdateDelay, lcrUpdateDelay, femonUpdateDelay, mailboxUpdateDelay, spanUpdateDelay;
// check if femon version <= 1.7.7
bool femonVersionChecked, femonVersionValid;
-
//protected:
public:
cGraphLCDService(cGraphLCDState * state);
virtual ~cGraphLCDService();
- bool ServiceIsAvailable(const std::string & Name);
+ bool ServiceIsAvailable(const std::string & Name, const std::string & Options = NULL);
void SetServiceUpdateDelay(const std::string & Name, int delay);
bool NeedsUpdate(uint64_t CurrentTime);
GLCD::cType GetItem(const std::string & ServiceName, const std::string & Item);
diff --git a/skinconfig.c b/skinconfig.c
index 3a03315..ec39da0 100644
--- a/skinconfig.c
+++ b/skinconfig.c
@@ -688,7 +688,17 @@ GLCD::cType cGraphLCDSkinConfig::GetToken(const GLCD::tSkinToken & Token)
if (Token.Attrib.Text == "")
return false;
- return s->ServiceIsAvailable(Token.Attrib.Text);
+ size_t found = Token.Attrib.Text.find(",");
+ std::string ServiceName = "";
+ std::string Options = "";
+
+ if (found != std::string::npos) {
+ ServiceName = Token.Attrib.Text.substr(0, found);
+ Options = Token.Attrib.Text.substr(found+1);
+ } else {
+ ServiceName = Token.Attrib.Text;
+ }
+ return s->ServiceIsAvailable(ServiceName, Options);
}
break;
case tokServiceItem: {