|
a/libupnpp/control/renderingcontrol.cxx |
|
b/libupnpp/control/renderingcontrol.cxx |
|
... |
|
... |
23 |
#include <functional> // for _Bind, bind, _1
|
23 |
#include <functional> // for _Bind, bind, _1
|
24 |
#include <ostream> // for basic_ostream, endl, etc
|
24 |
#include <ostream> // for basic_ostream, endl, etc
|
25 |
#include <string> // for string, operator<<, etc
|
25 |
#include <string> // for string, operator<<, etc
|
26 |
#include <utility> // for pair
|
26 |
#include <utility> // for pair
|
27 |
|
27 |
|
|
|
28 |
#include "libupnpp/control/description.hxx"
|
28 |
#include "libupnpp/control/avlastchg.hxx" // for decodeAVLastChange
|
29 |
#include "libupnpp/control/avlastchg.hxx" // for decodeAVLastChange
|
29 |
#include "libupnpp/control/service.hxx" // for VarEventReporter, Service
|
30 |
#include "libupnpp/control/service.hxx" // for VarEventReporter, Service
|
30 |
#include "libupnpp/log.hxx" // for LOGERR, LOGDEB1, LOGINF
|
31 |
#include "libupnpp/log.hxx" // for LOGERR, LOGDEB1, LOGINF
|
31 |
#include "libupnpp/soaphelp.hxx" // for SoapEncodeInput, etc
|
32 |
#include "libupnpp/soaphelp.hxx" // for SoapEncodeInput, etc
|
32 |
#include "libupnpp/upnpp_p.hxx" // for stringToBool
|
33 |
#include "libupnpp/upnpp_p.hxx" // for stringToBool
|
|
... |
|
... |
45 |
{
|
46 |
{
|
46 |
const string::size_type sz(SType.size()-2);
|
47 |
const string::size_type sz(SType.size()-2);
|
47 |
return !SType.compare(0, sz, st, 0, sz);
|
48 |
return !SType.compare(0, sz, st, 0, sz);
|
48 |
}
|
49 |
}
|
49 |
|
50 |
|
|
|
51 |
RenderingControl::RenderingControl(const UPnPDeviceDesc& device,
|
|
|
52 |
const UPnPServiceDesc& service)
|
|
|
53 |
: Service(device, service), m_volmin(0), m_volmax(100), m_volstep(1)
|
|
|
54 |
{
|
|
|
55 |
UPnPServiceDesc::Parsed sdesc;
|
|
|
56 |
if (service.fetchAndParseDesc(device.URLBase, sdesc)) {
|
|
|
57 |
auto it = sdesc.stateTable.find("Volume");
|
|
|
58 |
if (it != sdesc.stateTable.end() && it->second.hasValueRange) {
|
|
|
59 |
setVolParams(it->second.minimum, it->second.maximum,
|
|
|
60 |
it->second.step);
|
|
|
61 |
}
|
|
|
62 |
}
|
|
|
63 |
registerCallback();
|
|
|
64 |
}
|
|
|
65 |
|
|
|
66 |
int RenderingControl::devVolTo0100(int dev_vol)
|
|
|
67 |
{
|
|
|
68 |
int volume;
|
|
|
69 |
if (dev_vol < m_volmin)
|
|
|
70 |
dev_vol = m_volmin;
|
|
|
71 |
if (dev_vol > m_volmax)
|
|
|
72 |
dev_vol = m_volmax;
|
|
|
73 |
if (m_volmin != 0 || m_volmax != 100) {
|
|
|
74 |
float fact = float(m_volmax - m_volmin) / 100.0;
|
|
|
75 |
if (fact <= 0.0) // ??
|
|
|
76 |
fact = 1.0;
|
|
|
77 |
volume = int((dev_vol - m_volmin) / fact);
|
|
|
78 |
} else {
|
|
|
79 |
volume = dev_vol;
|
|
|
80 |
}
|
|
|
81 |
return volume;
|
|
|
82 |
}
|
|
|
83 |
|
50 |
void RenderingControl::evtCallback(
|
84 |
void RenderingControl::evtCallback(
|
51 |
const std::unordered_map<std::string, std::string>& props)
|
85 |
const std::unordered_map<std::string, std::string>& props)
|
52 |
{
|
86 |
{
|
53 |
LOGDEB1("RenderingControl::evtCallback: m_reporter " << m_reporter << endl);
|
87 |
LOGDEB1("RenderingControl::evtCallback: m_reporter " << m_reporter << endl);
|
54 |
for (auto it = props.begin(); it != props.end(); it++) {
|
88 |
for (auto it = props.begin(); it != props.end(); it++) {
|
|
... |
|
... |
61 |
}
|
95 |
}
|
62 |
for (auto it1 = props1.begin(); it1 != props1.end(); it1++) {
|
96 |
for (auto it1 = props1.begin(); it1 != props1.end(); it1++) {
|
63 |
LOGDEB1(" " << it1->first << " -> " <<
|
97 |
LOGDEB1(" " << it1->first << " -> " <<
|
64 |
it1->second << endl);
|
98 |
it1->second << endl);
|
65 |
if (!it1->first.compare("Volume")) {
|
99 |
if (!it1->first.compare("Volume")) {
|
|
|
100 |
int vol = devVolTo0100(atoi(it1->second.c_str()));
|
66 |
if (m_reporter) {
|
101 |
if (m_reporter) {
|
67 |
m_reporter->changed(it1->first.c_str(),
|
102 |
m_reporter->changed(it1->first.c_str(), vol);
|
68 |
atoi(it1->second.c_str()));
|
|
|
69 |
}
|
103 |
}
|
70 |
} else if (!it1->first.compare("Mute")) {
|
104 |
} else if (!it1->first.compare("Mute")) {
|
71 |
bool mute;
|
105 |
bool mute;
|
72 |
if (m_reporter && stringToBool(it1->second, &mute))
|
106 |
if (m_reporter && stringToBool(it1->second, &mute))
|
73 |
m_reporter->changed(it1->first.c_str(), mute);
|
107 |
m_reporter->changed(it1->first.c_str(), mute);
|
|
... |
|
... |
83 |
void RenderingControl::registerCallback()
|
117 |
void RenderingControl::registerCallback()
|
84 |
{
|
118 |
{
|
85 |
Service::registerCallback(bind(&RenderingControl::evtCallback, this, _1));
|
119 |
Service::registerCallback(bind(&RenderingControl::evtCallback, this, _1));
|
86 |
}
|
120 |
}
|
87 |
|
121 |
|
88 |
int RenderingControl::setVolume(int volume, const string& channel)
|
122 |
int RenderingControl::setVolume(int ivol, const string& channel)
|
89 |
{
|
123 |
{
|
|
|
124 |
// Input is always 0-100. Translate to actual range
|
|
|
125 |
if (ivol < 0)
|
|
|
126 |
ivol = 0;
|
|
|
127 |
if (ivol > 100)
|
|
|
128 |
ivol = 100;
|
|
|
129 |
int volume = ivol;
|
|
|
130 |
if (m_volmin != 0 || m_volmax != 100) {
|
|
|
131 |
float fact = float(m_volmax - m_volmin) / 100.0;
|
|
|
132 |
volume = m_volmin + int(float(ivol) * fact);
|
|
|
133 |
}
|
|
|
134 |
//LOGINF("RenderingControl::setVolume: ivol " << ivol <<
|
|
|
135 |
// " m_volmin " << m_volmin << " m_volmax " << m_volmax <<
|
|
|
136 |
// " m_volstep " << m_volstep << " volume " << volume << endl);
|
|
|
137 |
|
90 |
SoapEncodeInput args(m_serviceType, "SetVolume");
|
138 |
SoapEncodeInput args(m_serviceType, "SetVolume");
|
91 |
args("InstanceID", "0")("Channel", channel)
|
139 |
args("InstanceID", "0")("Channel", channel)
|
92 |
("DesiredVolume", SoapHelp::i2s(volume));
|
140 |
("DesiredVolume", SoapHelp::i2s(volume));
|
93 |
SoapDecodeOutput data;
|
141 |
SoapDecodeOutput data;
|
94 |
return runAction(args, data);
|
142 |
return runAction(args, data);
|
|
... |
|
... |
101 |
SoapDecodeOutput data;
|
149 |
SoapDecodeOutput data;
|
102 |
int ret = runAction(args, data);
|
150 |
int ret = runAction(args, data);
|
103 |
if (ret != UPNP_E_SUCCESS) {
|
151 |
if (ret != UPNP_E_SUCCESS) {
|
104 |
return ret;
|
152 |
return ret;
|
105 |
}
|
153 |
}
|
106 |
int volume;
|
154 |
int dev_volume;
|
107 |
if (!data.getInt("CurrentVolume", &volume)) {
|
155 |
if (!data.getInt("CurrentVolume", &dev_volume)) {
|
108 |
LOGERR("RenderingControl:getVolume: missing CurrentVolume in response"
|
156 |
LOGERR("RenderingControl:getVolume: missing CurrentVolume in response"
|
109 |
<< endl);
|
157 |
<< endl);
|
110 |
return UPNP_E_BAD_RESPONSE;
|
158 |
return UPNP_E_BAD_RESPONSE;
|
111 |
}
|
159 |
}
|
112 |
return volume;
|
160 |
|
|
|
161 |
// Output is always 0-100. Translate from device range
|
|
|
162 |
return devVolTo0100(dev_volume);
|
113 |
}
|
163 |
}
|
|
|
164 |
|
114 |
int RenderingControl::setMute(bool mute, const string& channel)
|
165 |
int RenderingControl::setMute(bool mute, const string& channel)
|
115 |
{
|
166 |
{
|
116 |
SoapEncodeInput args(m_serviceType, "SetMute");
|
167 |
SoapEncodeInput args(m_serviceType, "SetMute");
|
117 |
args("InstanceID", "0")("Channel", channel)
|
168 |
args("InstanceID", "0")("Channel", channel)
|
118 |
("DesiredMute", SoapHelp::i2s(mute?1:0));
|
169 |
("DesiredMute", SoapHelp::i2s(mute?1:0));
|