📄 fmrxrds.c
字号:
{
// The new byte is a match with the low probability byte. Swap
// them, reset the counter and flag the text as in transition.
// Note that the counter for this character goes higher than
// the validation limit because it will get knocked down later
if(psCnt[addr] >= PS_VALIDATE_LIMIT)
{
textChange = 1;
psCnt[addr] = PS_VALIDATE_LIMIT + 1;
}
else
{
psCnt[addr] = PS_VALIDATE_LIMIT;
}
psTmp1[addr] = psTmp0[addr];
psTmp0[addr] = byte;
}
else if(!psCnt[addr])
{
// The new byte is replacing an empty byte in the high
// proability array
psTmp0[addr] = byte;
psCnt[addr] = 1;
}
else
{
// The new byte doesn't match anything, put it in the
// low probablity array.
psTmp1[addr] = byte;
}
if(textChange)
{
// When the text is changing, decrement the count for all
// characters to prevent displaying part of a message
// that is in transition.
for(i=0;i<sizeof(psCnt);i++)
{
if(psCnt[i] > 1)
{
psCnt[i]--;
}
}
}
// The PS text is incomplete if any character in the high
// probability array has been seen fewer times than the
// validation limit.
for (i=0;i<sizeof(psCnt);i++)
{
if(psCnt[i] < PS_VALIDATE_LIMIT)
{
psComplete = 0;
break;
}
}
// If the PS text in the high probability array is complete
// copy it to the display array
if (psComplete)
{
for (i=0;i<sizeof(psDisplay); i++)
{
psDisplay[i] = psTmp0[i];
}
}
}
//-----------------------------------------------------------------------------
// The basic implementation of the Radio Text update displays data
// immediately but does no additional error detection.
//-----------------------------------------------------------------------------
static void
update_rt_simple(bit abFlag, u8 count, u8 addr, u8 idata * chars)
{
u8 errCount;
u8 blerMax;
u8 i,j;
// If the A/B flag changes, wipe out the rest of the text
if ((abFlag != rtsFlag) && rtsFlagValid)
{
for (i=addr;i<sizeof(rtDisplay);i++)
{
rtSimple[i] = 0;
}
}
rtsFlag = abFlag; // Save the A/B flag
rtsFlagValid = 1; // Now the A/B flag is valid
for (i=0; i<count; i++)
{
// Choose the appropriate block. Count > 2 check is necessary for 2B groups
if ((i < 2) && (count > 2))
{
errCount = BleC;
blerMax = rdsBlerMax[2];
}
else
{
errCount = BleD;
blerMax = rdsBlerMax[3];
}
if(errCount <= blerMax)
{
// Store the data in our temporary array
rtSimple[addr+i] = chars[i];
if(chars[i] == 0x0d)
{
// The end of message character has been received.
// Wipe out the rest of the text.
for (j=addr+i+1;j<sizeof(rtSimple);j++)
{
rtSimple[j] = 0;
}
break;
}
}
}
// Any null character before this should become a space
for (i=0;i<addr;i++)
{
if(!rtSimple[i])
{
rtSimple[i] = ' ';
}
}
}
//-----------------------------------------------------------------------------
// This implelentation of the Radio Text update attempts to display
// only complete messages even if the A/B flag does not toggle as well
// as provide additional error detection. Note that many radio stations
// do not implement the A/B flag properly. In some cases, it is best left
// ignored.
//-----------------------------------------------------------------------------
#define RT_VALIDATE_LIMIT 2
static void
display_rt(void)
{
bit rtComplete = 1;
u8 i;
// The Radio Text is incomplete if any character in the high
// probability array has been seen fewer times than the
// validation limit.
for (i=0; i<sizeof(rtTmp0);i++)
{
if(rtCnt[i] < RT_VALIDATE_LIMIT)
{
rtComplete = 0;
break;
}
if(rtTmp0[i] == 0x0d)
{
// The array is shorter than the maximum allowed
break;
}
}
// If the Radio Text in the high probability array is complete
// copy it to the display array
if (rtComplete)
{
for (i=0;i<sizeof(rtDisplay); i++)
{
rtDisplay[i] = rtTmp0[i];
if(rtTmp0[i] == 0x0d)
{
break;
}
}
// Wipe out everything after the end-of-message marker
for (i++;i<sizeof(rtDisplay);i++)
{
rtDisplay[i] = 0;
rtCnt[i] = 0;
rtTmp0[i] = 0;
rtTmp1[i] = 0;
}
}
}
//-----------------------------------------------------------------------------
// This implementation of the Radio Text update attempts to further error
// correct the data by making sure that the data has been identical for
// multiple receptions of each byte.
//-----------------------------------------------------------------------------
static void
update_rt_advance(bit abFlag, u8 count, u8 addr, u8 idata * byte)
{
u8 i;
bit textChange = 0; // indicates if the Radio Text is changing
if (abFlag != rtFlag && rtFlagValid && !rdsIgnoreAB)
{
// If the A/B message flag changes, try to force a display
// by increasing the validation count of each byte
// and stuffing a space in place of every NUL char
for (i=0;i<sizeof(rtCnt);i++)
{
if (!rtTmp0[i])
{
rtTmp0[i] = ' ';
rtCnt[i]++;
}
}
for (i=0;i<sizeof(rtCnt);i++)
{
rtCnt[i]++;
}
display_rt();
// Wipe out the cached text
for (i=0;i<sizeof(rtCnt);i++)
{
rtCnt[i] = 0;
rtTmp0[i] = 0;
rtTmp1[i] = 0;
}
}
rtFlag = abFlag; // Save the A/B flag
rtFlagValid = 1; // Our copy of the A/B flag is now valid
for(i=0;i<count;i++)
{
u8 errCount;
u8 blerMax;
// Choose the appropriate block. Count > 2 check is necessary for 2B groups
if ((i < 2) && (count > 2))
{
errCount = BleC;
blerMax = rdsBlerMax[2];
}
else
{
errCount = BleD;
blerMax = rdsBlerMax[3];
}
if (errCount <= blerMax)
{
if(!byte[i])
{
byte[i] = ' '; // translate nulls to spaces
}
// The new byte matches the high probability byte
if(rtTmp0[addr+i] == byte[i])
{
if(rtCnt[addr+i] < RT_VALIDATE_LIMIT)
{
rtCnt[addr+i]++;
}
else
{
// we have recieved this byte enough to max out our counter
// and push it into the low probability array as well
rtCnt[addr+i] = RT_VALIDATE_LIMIT;
rtTmp1[addr+i] = byte[i];
}
}
else if(rtTmp1[addr+i] == byte[i])
{
// The new byte is a match with the low probability byte. Swap
// them, reset the counter and flag the text as in transition.
// Note that the counter for this character goes higher than
// the validation limit because it will get knocked down later
if(rtCnt[addr+i] >= RT_VALIDATE_LIMIT)
{
textChange = 1;
rtCnt[addr+i] = RT_VALIDATE_LIMIT + 1;
}
else
{
rtCnt[addr+i] = RT_VALIDATE_LIMIT;
}
rtTmp1[addr+i] = rtTmp0[addr+i];
rtTmp0[addr+i] = byte[i];
}
else if(!rtCnt[addr+i])
{
// The new byte is replacing an empty byte in the high
// proability array
rtTmp0[addr+i] = byte[i];
rtCnt[addr+i] = 1;
}
else
{
// The new byte doesn't match anything, put it in the
// low probablity array.
rtTmp1[addr+i] = byte[i];
}
}
}
if(textChange)
{
// When the text is changing, decrement the count for all
// characters to prevent displaying part of a message
// that is in transition.
for(i=0;i<sizeof(rtCnt);i++)
{
if(rtCnt[i] > 1)
{
rtCnt[i]--;
}
}
}
// Display the Radio Text
display_rt();
}
//-----------------------------------------------------------------------------
// When tracking alternate frequencies, it's important to clear the list
// after tuning to a new station. (unless you are tuning to check an alternate
// frequency.
//-----------------------------------------------------------------------------
static void
init_alt_freq(void)
{
u8 i;
afCount = 0;
for (i = 0; i < sizeof(afList)/sizeof(afList[0]); i++)
{
afList[i] = 0;
}
}
//-----------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -