|
a/upmpd/upmpdutils.cxx |
|
b/upmpd/upmpdutils.cxx |
|
... |
|
... |
12 |
* You should have received a copy of the GNU General Public License
|
12 |
* You should have received a copy of the GNU General Public License
|
13 |
* along with this program; if not, write to the
|
13 |
* along with this program; if not, write to the
|
14 |
* Free Software Foundation, Inc.,
|
14 |
* Free Software Foundation, Inc.,
|
15 |
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
15 |
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
16 |
*/
|
16 |
*/
|
|
|
17 |
|
|
|
18 |
//
|
|
|
19 |
// This file has a number of mostly uninteresting and badly
|
|
|
20 |
// implemented small utility functions. This is a bit ugly, but I am
|
|
|
21 |
// not linking to Qt or glib just to get path-concatenating
|
|
|
22 |
// functions...
|
|
|
23 |
|
17 |
#include <unistd.h>
|
24 |
#include <unistd.h>
|
18 |
#include <fcntl.h>
|
25 |
#include <fcntl.h>
|
19 |
#include <sys/types.h>
|
26 |
#include <sys/types.h>
|
20 |
#include <sys/stat.h>
|
27 |
#include <sys/stat.h>
|
21 |
#include <math.h>
|
28 |
#include <math.h>
|
|
... |
|
... |
118 |
string res = s1;
|
125 |
string res = s1;
|
119 |
path_catslash(res);
|
126 |
path_catslash(res);
|
120 |
res += s2;
|
127 |
res += s2;
|
121 |
return res;
|
128 |
return res;
|
122 |
}
|
129 |
}
|
|
|
130 |
|
123 |
string path_home()
|
131 |
string path_home()
|
124 |
{
|
132 |
{
|
125 |
uid_t uid = getuid();
|
133 |
uid_t uid = getuid();
|
126 |
|
134 |
|
127 |
struct passwd *entry = getpwuid(uid);
|
135 |
struct passwd *entry = getpwuid(uid);
|
|
... |
|
... |
155 |
o.replace(0, l+1, entry->pw_dir);
|
163 |
o.replace(0, l+1, entry->pw_dir);
|
156 |
}
|
164 |
}
|
157 |
return o;
|
165 |
return o;
|
158 |
}
|
166 |
}
|
159 |
|
167 |
|
160 |
|
|
|
161 |
void trimstring(string &s, const char *ws)
|
168 |
void trimstring(string &s, const char *ws)
|
162 |
{
|
169 |
{
|
163 |
string::size_type pos = s.find_first_not_of(ws);
|
170 |
string::size_type pos = s.find_first_not_of(ws);
|
164 |
if (pos == string::npos) {
|
171 |
if (pos == string::npos) {
|
165 |
s.clear();
|
172 |
s.clear();
|
|
... |
|
... |
200 |
float db = 10 * log10(ratio);
|
207 |
float db = 10 * log10(ratio);
|
201 |
dbvalue = int(256 * db);
|
208 |
dbvalue = int(256 * db);
|
202 |
}
|
209 |
}
|
203 |
return dbvalue;
|
210 |
return dbvalue;
|
204 |
}
|
211 |
}
|
|
|
212 |
|
|
|
213 |
#ifdef __APPLE__
|
|
|
214 |
#define exp10 __exp10
|
|
|
215 |
#endif
|
|
|
216 |
|
205 |
// Translate VolumeDB to MPD 0-100
|
217 |
// Translate VolumeDB to MPD 0-100
|
206 |
int dbvaluetopercent(int dbvalue)
|
218 |
int dbvaluetopercent(int dbvalue)
|
207 |
{
|
219 |
{
|
208 |
float db = float(dbvalue) / 256.0;
|
220 |
float db = float(dbvalue) / 256.0;
|
209 |
float vol = exp10(db/10);
|
221 |
float vol = exp10(db/10);
|
|
... |
|
... |
230 |
// sprintf(cbuf, "%d:%02d:%02d.%03d", hours, minutes, secs, ms);
|
242 |
// sprintf(cbuf, "%d:%02d:%02d.%03d", hours, minutes, secs, ms);
|
231 |
sprintf(cbuf, "%d:%02d:%02d", hours, minutes, secs);
|
243 |
sprintf(cbuf, "%d:%02d:%02d", hours, minutes, secs);
|
232 |
return cbuf;
|
244 |
return cbuf;
|
233 |
}
|
245 |
}
|
234 |
|
246 |
|
|
|
247 |
// H:M:S to seconds
|
235 |
int upnpdurationtos(const string& dur)
|
248 |
int upnpdurationtos(const string& dur)
|
236 |
{
|
249 |
{
|
237 |
int hours, minutes, seconds;
|
250 |
int hours, minutes, seconds;
|
238 |
sscanf(dur.c_str(), "%d:%d:%d", &hours, &minutes, &seconds);
|
251 |
if (sscanf(dur.c_str(), "%d:%d:%d", &hours, &minutes, &seconds) != 3) {
|
|
|
252 |
return 0;
|
|
|
253 |
}
|
239 |
return 3600 * hours + 60 * minutes + seconds;
|
254 |
return 3600 * hours + 60 * minutes + seconds;
|
240 |
}
|
255 |
}
|
241 |
|
256 |
|
242 |
// Get from ssl unordered_map, return empty string for non-existing key (so this
|
257 |
// Get from ssl unordered_map, return empty string for non-existing
|
243 |
// only works for data where this makes sense.
|
258 |
// key (so this only works for data where this behaviour makes sense).
|
244 |
const string& mapget(const unordered_map<string, string>& im, const string& k)
|
259 |
const string& mapget(const unordered_map<string, string>& im, const string& k)
|
245 |
{
|
260 |
{
|
246 |
static string ns;// null string
|
261 |
static string ns; // null string
|
247 |
unordered_map<string, string>::const_iterator it = im.find(k);
|
262 |
unordered_map<string, string>::const_iterator it = im.find(k);
|
248 |
if (it == im.end())
|
263 |
if (it == im.end())
|
249 |
return ns;
|
264 |
return ns;
|
250 |
else
|
265 |
else
|
251 |
return it->second;
|
266 |
return it->second;
|
|
... |
|
... |
298 |
}
|
313 |
}
|
299 |
}
|
314 |
}
|
300 |
|
315 |
|
301 |
// TBD: the res element normally has size, sampleFrequency,
|
316 |
// TBD: the res element normally has size, sampleFrequency,
|
302 |
// nrAudioChannels and protocolInfo attributes, which are bogus
|
317 |
// nrAudioChannels and protocolInfo attributes, which are bogus
|
|
|
318 |
// for the moment. partly because MPD does not supply them. And
|
303 |
// for the moment. And mostly everything is bogus if next is
|
319 |
// mostly everything is bogus if next is set...
|
304 |
// set... Bitrate keeps changing for VBRs and forces
|
|
|
305 |
// events. Keeping it out for now
|
|
|
306 |
|
320 |
|
307 |
ss << "<res " << "duration=\"" << upnpduration(mpds.songlenms) << "\" "
|
321 |
ss << "<res " << "duration=\"" << upnpduration(mpds.songlenms) << "\" "
|
|
|
322 |
// Bitrate keeps changing for VBRs and forces events. Keeping
|
|
|
323 |
// it out for now.
|
308 |
// << "bitrate=\"" << mpds.kbrate << "\" "
|
324 |
// << "bitrate=\"" << mpds.kbrate << "\" "
|
309 |
<< "sampleFrequency=\"44100\" audioChannels=\"2\" "
|
325 |
<< "sampleFrequency=\"44100\" audioChannels=\"2\" "
|
310 |
<< "protocolInfo=\"http-get:*:audio/mpeg:DLNA.ORG_PN=MP3;DLNA.ORG_OP=01;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=01700000000000000000000000000000\""
|
326 |
<< "protocolInfo=\"http-get:*:audio/mpeg:DLNA.ORG_PN=MP3;DLNA.ORG_OP=01;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=01700000000000000000000000000000\""
|
311 |
<< ">"
|
327 |
<< ">"
|
312 |
<< xmlquote(mapget(songmap, "uri"))
|
328 |
<< xmlquote(mapget(songmap, "uri"))
|
313 |
<< "</res>"
|
329 |
<< "</res>"
|