changeset 28 | 075425b8d9a4 |
parent 24 | 6df133bd92e1 |
child 32 | 189d20c34778 |
child 34 | bc10a61bd7d3 |
24:6df133bd92e1 | 28:075425b8d9a4 |
---|---|
23 #include "radiostation_p.h" |
23 #include "radiostation_p.h" |
24 #include "radiologger.h" |
24 #include "radiologger.h" |
25 #include "radio_global.h" |
25 #include "radio_global.h" |
26 |
26 |
27 // Constants |
27 // Constants |
28 const QString KTagArtist = "artist"; |
28 const QString TAG_ARTIST = "artist"; |
29 const QString KTagTitle = "title"; |
29 const QString TAG_TITLE = "title"; |
30 const QString KLinkArtist = "<a href=\"" + KTagArtist + "\">"; |
30 const QString HTML_ARTIST = "<a href=\"" + TAG_ARTIST + "\">"; |
31 const QString KLinkTitle = "<a href=\"" + KTagTitle + "\">"; |
31 const QString HTML_TITLE = "<a href=\"" + TAG_TITLE + "\">"; |
32 const QString KLinkClose = "</a>"; |
32 const QString HTML_CLOSE = "</a>"; |
33 |
33 |
34 const char* callSign[KThreeLetterCallSignCount] = |
34 const uint LAST_CALLSIGN_CHAR_CODE = 25; |
35 const uint THREE_LETTER_CALLSIGN_COUNT = 72; |
|
36 const uint KXXX_CALLSIGN_PI_FIRST = 0x1000; |
|
37 const uint WXXX_CALLSIGN_PI_FIRST = 0x54A8; |
|
38 const uint WXXX_CALLSIGN_PI_LAST = 0x994F; |
|
39 const uint XXX_CALLSIGN_PI_FIRST = 0x9950; |
|
40 const uint XXX_CALLSIGN_PI_LAST = 0x99B9; |
|
41 |
|
42 const char* CALLSIGN_TABLE[THREE_LETTER_CALLSIGN_COUNT] = |
|
35 {"KBW", "KCY", "KDB", "KDF", "KEX", "KFH","KFI","KGA","KGB", |
43 {"KBW", "KCY", "KDB", "KDF", "KEX", "KFH","KFI","KGA","KGB", |
36 "KGO", "KGU", "KGW", "KGY", "KHQ", "KID", "KIT", "KJR", "KLO", |
44 "KGO", "KGU", "KGW", "KGY", "KHQ", "KID", "KIT", "KJR", "KLO", |
37 "KLZ", "KMA", "KMJ", "KNX", "KOA", "KOB", "KOY", "KPQ", "KQV", |
45 "KLZ", "KMA", "KMJ", "KNX", "KOA", "KOB", "KOY", "KPQ", "KQV", |
38 "KSD", "KSL", "KUJ", "KUT", "KVI", "KWG", "KXL", "KXO", "KYW", |
46 "KSD", "KSL", "KUJ", "KUT", "KVI", "KWG", "KXL", "KXO", "KYW", |
39 "WBT", "WBZ", "WDZ", "WEW", "WGH", "WGL", "WGN", "WGR", "WGY", |
47 "WBT", "WBZ", "WDZ", "WEW", "WGH", "WGL", "WGN", "WGR", "WGY", |
40 "WHA", "WHB", "WHK", "WHO", "WHP", "WIL", "WIP", "WIS", "WJR", |
48 "WHA", "WHB", "WHK", "WHO", "WHP", "WIL", "WIP", "WIS", "WJR", |
41 "WJW", "WJZ", "WKY", "WLS", "WLW", "WMC", "WMT", "WOC", "WOI", |
49 "WJW", "WJZ", "WKY", "WLS", "WLW", "WMC", "WMT", "WOC", "WOI", |
42 "WOL", "WOR", "WOW", "WRC", "WRR", "WSB", "WSM", "WWJ", "WWL"}; |
50 "WOL", "WOR", "WOW", "WRC", "WRR", "WSB", "WSM", "WWJ", "WWL"}; |
43 |
51 |
44 const uint piCode[KThreeLetterCallSignCount] = |
52 const uint PI_CODE_TABLE[THREE_LETTER_CALLSIGN_COUNT] = |
45 {0x99A5, 0x99A6, 0x9990, 0x99A7, 0x9950, 0x9951, 0x9952, 0x9953, |
53 {0x99A5, 0x99A6, 0x9990, 0x99A7, 0x9950, 0x9951, 0x9952, 0x9953, |
46 0x9991, 0x9954, 0x9955, 0x9956, 0x9957, 0x99AA, 0x9958, 0x9959, |
54 0x9991, 0x9954, 0x9955, 0x9956, 0x9957, 0x99AA, 0x9958, 0x9959, |
47 0x995A, 0x995B, 0x995C, 0x995D, 0x995E, 0x995F, 0x9960, 0x99AB, |
55 0x995A, 0x995B, 0x995C, 0x995D, 0x995E, 0x995F, 0x9960, 0x99AB, |
48 0x9992, 0x9993, 0x9964, 0x9994, 0x9965, 0x9966, 0x9995, 0x9967, |
56 0x9992, 0x9993, 0x9964, 0x9994, 0x9965, 0x9966, 0x9995, 0x9967, |
49 0x9968, 0x9996, 0x9997, 0x996B, 0x9999, 0x996D, 0x996E, 0x996F, |
57 0x9968, 0x9996, 0x9997, 0x996B, 0x9999, 0x996D, 0x996E, 0x996F, |
50 0x999A, 0x9971, 0x9972, 0x9973, 0x999B, 0x9975, 0x9976, 0x9977, |
58 0x999A, 0x9971, 0x9972, 0x9973, 0x999B, 0x9975, 0x9976, 0x9977, |
51 0x9978, 0x999C, 0x999D, 0x997A, 0x99B3, 0x997B, 0x99B4, 0x99B5, |
59 0x9978, 0x999C, 0x999D, 0x997A, 0x99B3, 0x997B, 0x99B4, 0x99B5, |
52 0x997C, 0x997D, 0x997E, 0x999E, 0x999F, 0x9981, 0x99A0, 0x9983, |
60 0x997C, 0x997D, 0x997E, 0x999E, 0x999F, 0x9981, 0x99A0, 0x9983, |
53 0x9984, 0x99A1, 0x99B9, 0x99A2, 0x99A3, 0x99A4, 0x9988, 0x9989}; |
61 0x9984, 0x99A1, 0x99B9, 0x99A2, 0x99A3, 0x99A4, 0x9988, 0x9989}; |
54 |
62 |
55 const uint KDisableLocalAreaCoverageMask = 0x0800; |
63 const uint DISABLE_LOCAL_AREA_COVERAGE_MASK = 0x0800; |
56 |
64 |
57 const int KPsNameChangeThresholdSeconds = 10; |
65 const int PS_NAME_CHANGE_THRESHOLD_SECONDS = 10; |
58 |
66 |
59 /** |
67 /** |
60 * Static shared data instance that is used by all default-constructed RadioStation instances |
68 * Static shared data instance that is used by all default-constructed RadioStation instances |
61 */ |
69 */ |
62 Q_GLOBAL_STATIC_WITH_ARGS( RadioStationPrivate, shared_null, ( RadioStation::SharedNull ) ) |
70 Q_GLOBAL_STATIC_WITH_ARGS( RadioStationPrivate, shared_null, ( RadioStation::SharedNull ) ) |
65 * |
73 * |
66 */ |
74 */ |
67 QString RadioStation::parseFrequency( uint frequency ) |
75 QString RadioStation::parseFrequency( uint frequency ) |
68 { |
76 { |
69 QString freqString; |
77 QString freqString; |
70 freqString.sprintf( "%.1f", qreal( frequency ) / KFrequencyMultiplier ); |
78 freqString.sprintf( "%.1f", qreal( frequency ) / FREQUENCY_MULTIPLIER ); |
71 return freqString; |
79 return freqString; |
72 } |
80 } |
73 |
81 |
74 /*! |
82 /*! |
75 * |
83 * |
177 // Save the time when PS name changed and if the last change was too close to the current time |
185 // Save the time when PS name changed and if the last change was too close to the current time |
178 // change the PS type to dynamic if it has already been incorrectly determined to be static. |
186 // change the PS type to dynamic if it has already been incorrectly determined to be static. |
179 QTime previousChange = mData->mLastPsNameChangeTime; |
187 QTime previousChange = mData->mLastPsNameChangeTime; |
180 mData->mLastPsNameChangeTime = QTime::currentTime(); |
188 mData->mLastPsNameChangeTime = QTime::currentTime(); |
181 if ( previousChange.isValid() && mData->mPsType == RadioStation::Static && |
189 if ( previousChange.isValid() && mData->mPsType == RadioStation::Static && |
182 previousChange.secsTo( mData->mLastPsNameChangeTime ) < KPsNameChangeThresholdSeconds ) { |
190 previousChange.secsTo( mData->mLastPsNameChangeTime ) < PS_NAME_CHANGE_THRESHOLD_SECONDS ) { |
183 LOG( "Station changed PS name too often. PS type changed to Dynamic" ); |
191 LOG( "Station changed PS name too often. PS type changed to Dynamic" ); |
184 mData->mPsType = RadioStation::Dynamic; |
192 mData->mPsType = RadioStation::Dynamic; |
185 mData->mDynamicPsText = mData->mName; |
193 mData->mDynamicPsText = mData->mName; |
186 mData->mName = ""; |
194 mData->mName = ""; |
187 mData->mChangeFlags |= RadioStation::PsTypeChanged | RadioStation::DynamicPsChanged; |
195 mData->mChangeFlags |= RadioStation::PsTypeChanged | RadioStation::DynamicPsChanged; |
230 { |
238 { |
231 LOG_FORMAT( "RadioStation::setPiCode new PI: %d", piCode ); |
239 LOG_FORMAT( "RadioStation::setPiCode new PI: %d", piCode ); |
232 // toggling local area coverage bit code must not be interpreted as new PI code |
240 // toggling local area coverage bit code must not be interpreted as new PI code |
233 if( region != RadioRegion::America ) |
241 if( region != RadioRegion::America ) |
234 { |
242 { |
235 piCode &= ~KDisableLocalAreaCoverageMask; |
243 piCode &= ~DISABLE_LOCAL_AREA_COVERAGE_MASK; |
236 } |
244 } |
237 |
245 |
238 LOG_FORMAT( "stored PI: %d", mData->mPiCode ); |
246 LOG_FORMAT( "stored PI: %d", mData->mPiCode ); |
239 LOG_FORMAT( "call sign check done: %d", mData->mCallSignCheckDone ); |
247 LOG_FORMAT( "call sign check done: %d", mData->mCallSignCheckDone ); |
240 //prevent executing the below code when unnessesary |
248 //prevent executing the below code when unnessesary |
309 } |
317 } |
310 |
318 |
311 detach(); |
319 detach(); |
312 QString replacement = ""; |
320 QString replacement = ""; |
313 if ( rtPlusClass == RtPlus::Artist ) { |
321 if ( rtPlusClass == RtPlus::Artist ) { |
314 replacement = KLinkArtist; |
322 replacement = HTML_ARTIST; |
315 } else if ( rtPlusClass == RtPlus::Title ) { |
323 } else if ( rtPlusClass == RtPlus::Title ) { |
316 replacement = KLinkTitle; |
324 replacement = HTML_TITLE; |
317 } |
325 } |
318 replacement += rtPlusItem + KLinkClose; |
326 replacement += rtPlusItem + HTML_CLOSE; |
319 |
327 |
320 mData->mRadioText.replace( rtPlusItem, replacement ); |
328 mData->mRadioText.replace( rtPlusItem, replacement ); |
321 mData->mChangeFlags |= RadioStation::RadioTextChanged; |
329 mData->mChangeFlags |= RadioStation::RadioTextChanged; |
322 } |
330 } |
323 } |
331 } |
384 /*! |
392 /*! |
385 * |
393 * |
386 */ |
394 */ |
387 QString RadioStation::frequencyMhz() const |
395 QString RadioStation::frequencyMhz() const |
388 { |
396 { |
389 return parseFrequency( mData->mFrequency ); |
397 return qtTrId( "txt_rad_list_l1_mhz_big" ).arg( parseFrequency( mData->mFrequency ) ); |
398 } |
|
399 |
|
400 /*! |
|
401 * |
|
402 */ |
|
403 QString RadioStation::nameOrFrequencyMhz() const |
|
404 { |
|
405 if ( !mData->mName.isEmpty() ) { |
|
406 return mData->mName; |
|
407 } |
|
408 return frequencyMhz(); |
|
390 } |
409 } |
391 |
410 |
392 /*! |
411 /*! |
393 * |
412 * |
394 */ |
413 */ |
574 { |
593 { |
575 QString callSign; |
594 QString callSign; |
576 |
595 |
577 LOG_FORMAT( "RadioStation::piCodeToCallSign PI: %d", programmeIdentification ); |
596 LOG_FORMAT( "RadioStation::piCodeToCallSign PI: %d", programmeIdentification ); |
578 // call signs beginning with 'K' |
597 // call signs beginning with 'K' |
579 if( ( programmeIdentification>=KKxxxCallSignPiFirst ) && ( programmeIdentification < KWxxxCallSignPiFirst ) ) { |
598 if( ( programmeIdentification>=KXXX_CALLSIGN_PI_FIRST ) && ( programmeIdentification < WXXX_CALLSIGN_PI_FIRST ) ) { |
580 callSign += "K"; |
599 callSign += "K"; |
581 callSign += iterateCallSign( KKxxxCallSignPiFirst, programmeIdentification ); |
600 callSign += iterateCallSign( KXXX_CALLSIGN_PI_FIRST, programmeIdentification ); |
582 } |
601 } |
583 // call signs beginning with 'W' |
602 // call signs beginning with 'W' |
584 else if (( programmeIdentification >= KWxxxCallSignPiFirst ) && ( programmeIdentification <= KWxxxCallSignPiLast )) { |
603 else if (( programmeIdentification >= WXXX_CALLSIGN_PI_FIRST ) && ( programmeIdentification <= WXXX_CALLSIGN_PI_LAST )) { |
585 callSign += "W"; |
604 callSign += "W"; |
586 callSign += iterateCallSign( KWxxxCallSignPiFirst, programmeIdentification ); |
605 callSign += iterateCallSign( WXXX_CALLSIGN_PI_FIRST, programmeIdentification ); |
587 } |
606 } |
588 // 3 letter only call signs |
607 // 3 letter only call signs |
589 else if(( programmeIdentification >= KxxxCallSignPiFirst ) && ( programmeIdentification <= KxxxCallSignPiLast)) { |
608 else if(( programmeIdentification >= XXX_CALLSIGN_PI_FIRST ) && ( programmeIdentification <= XXX_CALLSIGN_PI_LAST)) { |
590 callSign += callSignString( programmeIdentification ); |
609 callSign += callSignString( programmeIdentification ); |
591 } |
610 } |
592 else |
611 else |
593 { |
612 { |
594 LOG( "RadioStation::piCodeToCallSign - Unhandled else" ); |
613 LOG( "RadioStation::piCodeToCallSign - Unhandled else" ); |
639 /*! |
658 /*! |
640 * |
659 * |
641 */ |
660 */ |
642 QString RadioStation::callSignString( uint programmeIdentification ) |
661 QString RadioStation::callSignString( uint programmeIdentification ) |
643 { |
662 { |
644 for ( uint i = 0; i < KThreeLetterCallSignCount; ++i ) { |
663 for ( uint i = 0; i < THREE_LETTER_CALLSIGN_COUNT; ++i ) { |
645 if( piCode[i] == programmeIdentification ) { |
664 if( PI_CODE_TABLE[i] == programmeIdentification ) { |
646 return callSign[i]; |
665 return CALLSIGN_TABLE[i]; |
647 } |
666 } |
648 } |
667 } |
649 |
668 |
650 LOG_FORMAT( "RadioStation::callSignString, Not found PI: %d", programmeIdentification ); |
669 LOG_FORMAT( "RadioStation::callSignString, Not found PI: %d", programmeIdentification ); |
651 |
670 |
656 * |
675 * |
657 */ |
676 */ |
658 char RadioStation::callSignChar( uint decimalValue ) |
677 char RadioStation::callSignChar( uint decimalValue ) |
659 { |
678 { |
660 LOG_FORMAT( "RadioStation::callSignChar A+: %d", decimalValue ); |
679 LOG_FORMAT( "RadioStation::callSignChar A+: %d", decimalValue ); |
661 if ( decimalValue <= KLastCallSignCharCode ) { |
680 if ( decimalValue <= LAST_CALLSIGN_CHAR_CODE ) { |
662 return static_cast<char>( 'A' + decimalValue ); |
681 return static_cast<char>( 'A' + decimalValue ); |
663 } |
682 } |
664 return '?'; |
683 return '?'; |
665 } |
684 } |
666 |
685 |