summaryrefslogtreecommitdiff
path: root/rds.c
diff options
context:
space:
mode:
Diffstat (limited to 'rds.c')
-rw-r--r--rds.c117
1 files changed, 58 insertions, 59 deletions
diff --git a/rds.c b/rds.c
index b204b0d..fb6b020 100644
--- a/rds.c
+++ b/rds.c
@@ -49,14 +49,14 @@ cRds::cRds(cPostData *_postdata)
{
postdata = _postdata;
recstat = recWait;
-
+
buf.data = new uchar[RDS_BUF_SIZE];
buf.length = 0;
buf.offset = 0;
-
+
rt_length = 0;
lb0xfd = false;
-
+
last_tb = -1;
last_rb = -1;
}
@@ -71,31 +71,31 @@ cRds::~cRds()
void cRds::put_data(uchar *data, int length)
{
int c, pos, len;
-
+
pos = length - 1;
len = data[pos - 1]; /* length of rds data */
-
+
if (data[pos] != 0xfd || len == 0)
return;
-
+
if (buf.length + len >= RDS_BUF_SIZE) {
dsyslog("[audiorecorder]: buffer overflow <%s> (%s, %s())",
postdata->get_channel().c_str(), __FILE__, __func__);
buf.length = 0;
buf.offset = 0;
}
-
+
/* reverse rds data */
for (c = 2; c < len + 2; ++c) {
-
+
/* byte stuffing */
int bs = data[pos - c];
-
+
if (bs == 0xfd) {
lb0xfd = true;
continue;
}
-
+
if (lb0xfd) {
switch (bs) {
case 0x00:
@@ -107,10 +107,10 @@ void cRds::put_data(uchar *data, int length)
default:
bs = 0xff;
}
-
+
lb0xfd = false;
}
-
+
/* copy rds value on the buffer */
buf.data[buf.length] = bs;
++buf.length;
@@ -121,44 +121,44 @@ void cRds::put_data(uchar *data, int length)
bool cRds::set_next_frame(void)
{
int offset;
-
+
offset = buf.offset;
rds_frame.data = NULL;
rds_frame.length = 0;
-
+
for (; buf.offset < buf.length - 4; ++buf.offset) {
if (buf.data[buf.offset] == 0xfe) {
/* rds start marker found */
rds_frame.length = buf.data[buf.offset + 4] + 8;
-
+
if (buf.offset + rds_frame.length > buf.length)
break;
-
+
rds_frame.data = buf.data + buf.offset;
-
+
/* check rds end marker */
if (rds_frame.data[rds_frame.length - 1] != 0xff)
dsyslog("[audiorecorder]: no rds end marker "
"found <%s> (%s, %s())",
postdata->get_channel().c_str(),
__FILE__, __func__);
-
+
break;
}
}
-
+
if (buf.offset != offset && cPluginAudiorecorder::get_dbg_level() > 0)
cout << "skipped " << (buf.offset - offset) << " byte(s) <"
<< postdata->get_channel() << "> (" << __FILE__
<< ", " << __func__ << "())" << endl;
-
+
if (! rds_frame.data) {
delete_data(buf.offset);
return false;
}
-
+
buf.offset += rds_frame.length;
-
+
return true;
}
@@ -166,10 +166,10 @@ bool cRds::set_next_frame(void)
void cRds::delete_data(int length)
{
/* clear the buffer */
-
+
if (length < 1)
return;
-
+
buf.length -= length;
buf.offset -= length;
memmove(buf.data, buf.data + length, buf.length);
@@ -189,8 +189,8 @@ eRecStat cRds::decode_frame(void)
default:
break;
}
-
-
+
+
if (rds_frame.data[5] == mecRT)
decode_radiotext();
else if (rds_frame.data[5] == mecODA && rds_frame.data[7] == 0x4b &&
@@ -198,17 +198,17 @@ eRecStat cRds::decode_frame(void)
decode_rtp();
else if (rds_frame.data[5] == mecPTY) {
int pty = rds_frame.data[8];
-
+
if (recstat == recRun && postdata->get_genre().empty()) {
if ((pty > 9 && pty < 16) || (pty > 23 && pty < 29))
postdata->set_genre(ptys[pty]);
}
-
+
if (cPluginAudiorecorder::get_dbg_level() > 1)
cout << "pty-code <" << postdata->get_channel() <<
">: " << pty << endl;
}
-
+
return recstat;
}
@@ -216,20 +216,20 @@ eRecStat cRds::decode_frame(void)
void cRds::decode_radiotext(void)
{
int c, rt_ab_flag;
-
+
rt_length = rds_frame.data[8] - 1;
rt_ab_flag = rds_frame.data[9] & 0x01;
-
+
for (c = 0; c < rt_length; ++c) {
if (rds_frame.data[c + 10] >= 0x80)
rds_frame.data[c + 10] =
rt_trans[(rds_frame.data[c + 10] - 0x80)];
-
+
radiotext[c] = rds_frame.data[c + 10];
}
-
+
radiotext[rt_length] = '\0';
-
+
if (cPluginAudiorecorder::get_dbg_level() > 1)
cout << "radiotext (" << rt_ab_flag << ") <" <<
postdata->get_channel() << ">: " << radiotext << endl;
@@ -239,39 +239,39 @@ void cRds::decode_radiotext(void)
void cRds::decode_rtp(void)
{
int rb, tb;
-
+
bool toggle_tb = false;
bool toggle_rb = false;
-
+
tb = (rds_frame.data[10] >> 4) & 0x01;
if (last_tb == -1)
last_tb = tb;
-
+
rb = (rds_frame.data[10] >> 3) & 0x01;
if (last_rb == -1)
last_rb = rb;
-
+
if (cPluginAudiorecorder::get_dbg_level() > 1)
cout << "rtp-data <" << postdata->get_channel() << ">: toggle "
"bit: " << tb << ", running bit: " << rb << endl;
-
+
if (last_tb != tb)
toggle_tb = true;
-
+
if (last_rb != rb)
toggle_rb = true;
-
+
last_tb = tb;
last_rb = rb;
-
+
if (recstat == recWait) {
if (! toggle_tb && ! toggle_rb)
return;
-
+
/* ready to record */
recstat = recOff;
}
-
+
if (rb == 1) {
/* running bit is on */
if (recstat == recOff) {
@@ -287,10 +287,9 @@ void cRds::decode_rtp(void)
/* running bit is off */
if (recstat == recRun)
recstat = recStop;
-
return;
}
-
+
if (recstat == recRun && rt_length > 0)
decode_rtp_items();
}
@@ -299,26 +298,26 @@ void cRds::decode_rtp(void)
void cRds::decode_rtp_items(void)
{
int c, t[2], s[2], l[2];
-
+
/* tag 1 */
t[0] = ((rds_frame.data[10] << 3) & 0x38) | (rds_frame.data[11] >> 5);
s[0] = ((rds_frame.data[11] << 1) & 0x3e) | (rds_frame.data[12] >> 7);
l[0] = ((rds_frame.data[12] >> 1) & 0x3f) + 1;
-
+
/* tag 2*/
t[1] = ((rds_frame.data[12] << 5) & 0x20) | (rds_frame.data[13] >> 3);
s[1] = ((rds_frame.data[13] << 3) & 0x38) | (rds_frame.data[14] >> 5);
l[1] = (rds_frame.data[14] & 0x1f) + 1;
-
+
for (c = 0; c < 2; ++c) {
if (cPluginAudiorecorder::get_dbg_level() > 1)
cout << "rtp-data <" << postdata->get_channel() << ">: "
"type: " << t[c] << ", start:" << s[c] <<
", length: " << l[c] << endl;
-
+
if (t[c] < 1 || t[c] > 10)
continue;
-
+
if (t[c] == ItemTitle) {
if (correct_rtp_tag(t[c], s[c], l[c]))
postdata->set_title(radiotext + s[c]);
@@ -344,10 +343,10 @@ void cRds::decode_rtp_items(void)
bool cRds::correct_rtp_tag(int &type, int &start, int &length)
{
int original_length = length;
-
+
if (start + length > rt_length) {
length = rt_length - start;
-
+
if (original_length - length > 1 || length < 0) {
if (cPluginAudiorecorder::get_dbg_level() > 1)
cout << "rtp-data <" << postdata->get_channel()
@@ -356,31 +355,31 @@ bool cRds::correct_rtp_tag(int &type, int &start, int &length)
return false;
}
}
-
+
/* remove ' ', '"' or "-" at the beginning of the tag */
int end = start + length;
for (; start < end; ++start) {
if (radiotext[start] != ' ' && radiotext[start] != '"' &&
radiotext[start] != '-')
break;
-
+
--length;
}
-
+
/* remove ' ' or '"' at the end of the tag */
for (; length > 0; length--) {
if (radiotext[start + length - 1] != ' ' && radiotext[start +
length - 1] != '"')
break;
}
-
+
if (length <= 1 && cPluginAudiorecorder::get_dbg_level() > 1) {
cout << "rtp-data <" << postdata->get_channel() << ">: got "
"buggy tag-infos, length is too short !" << endl;
return false;
}
-
+
radiotext[start + length] = '\0';
-
+
return true;
}