-
Notifications
You must be signed in to change notification settings - Fork 110
Expand file tree
/
Copy pathnrsc5.h
More file actions
832 lines (777 loc) · 30.8 KB
/
nrsc5.h
File metadata and controls
832 lines (777 loc) · 30.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
#ifndef NRSC5_H_
#define NRSC5_H_
/** \file nrsc5.h
* External API for the nrsc5 library.
*/
/*! \mainpage Quick API Reference
*
* The library API is documented in nrsc5.h -- see the *Functions* section.
*
* Useful information about the protocol is provided in standards
* documents available from https://www.nrscstandards.org/
*
* Note: this documentation was *not* written by the authors of **nrsc5**;
* its accuracy cannot be guaranteed.
*/
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
/*
* Definitions.
*/
#define NRSC5_SCAN_BEGIN 87.9e6
#define NRSC5_SCAN_END 107.9e6
#define NRSC5_SCAN_SKIP 0.2e6
#define NRSC5_MIME_PRIMARY_IMAGE 0xBE4B7536 /**< MIME type for album art */
#define NRSC5_MIME_STATION_LOGO 0xD9C72536 /**< MIME type for station logo */
#define NRSC5_MIME_NAVTEQ 0x2D42AC3E
#define NRSC5_MIME_HERE_TPEG 0x82F03DFC
#define NRSC5_MIME_HERE_IMAGE 0xB7F03DFC
#define NRSC5_MIME_HD_TMC 0xEECB55B6
#define NRSC5_MIME_HDC 0x4DC66C5A /**< MIME type for HD Codec audio */
#define NRSC5_MIME_TEXT 0xBB492AAC /**< MIME type for text file */
#define NRSC5_MIME_JPEG 0x1E653E9C /**< MIME type for JPEG image */
#define NRSC5_MIME_PNG 0x4F328CA0 /**< MIME type for PNG image */
#define NRSC5_MIME_TTN_TPEG_1 0xB39EBEB2
#define NRSC5_MIME_TTN_TPEG_2 0x4EB03469
#define NRSC5_MIME_TTN_TPEG_3 0x52103469
#define NRSC5_MIME_TTN_STM_TRAFFIC 0xFF8422D7
#define NRSC5_MIME_TTN_STM_WEATHER 0xEF042E96
#define NRSC5_MIME_UNKNOWN_00000000 0x00000000
#define NRSC5_MIME_UNKNOWN_B81FFAA8 0xB81FFAA8
#define NRSC5_MIME_UNKNOWN_FFFFFFFF 0xFFFFFFFF
#define NRSC5_AUDIO_FRAME_SAMPLES 2048 /**< Number of audio samples per HDC frame */
#define NRSC5_SAMPLE_RATE_CU8 1488375 /**< Sample rate at which nrsc5_pipe_samples_cu8() expects samples (FM or AM) */
#define NRSC5_SAMPLE_RATE_CS16_FM 744187.5 /**< Sample rate at which nrsc5_pipe_samples_cs16() expects samples (FM only) */
#define NRSC5_SAMPLE_RATE_CS16_AM 46511.71875 /**< Sample rate at which nrsc5_pipe_samples_cs16() expects samples (AM only) */
#define NRSC5_SAMPLE_RATE_AUDIO 44100 /**< Sample rate of outgoing audio */
#ifdef NRSC5_EXPORTS
#ifdef __MINGW32__
#define NRSC5_API __declspec(dllexport)
#else
#define NRSC5_API
#endif
#else
#define NRSC5_API
#endif
enum
{
NRSC5_MODE_FM,
NRSC5_MODE_AM
};
/*
* Data types.
*/
enum
{
NRSC5_SIG_COMPONENT_AUDIO,
NRSC5_SIG_COMPONENT_DATA
};
enum
{
NRSC5_AAS_TYPE_STREAM = 0,
NRSC5_AAS_TYPE_PACKET = 1,
NRSC5_AAS_TYPE_LOT = 3
};
/** Represents a service component.
*
* An element of a linked list that accompanies a nrsc5_sig_service_t
* describing a component of a SIG record. This provides further
* information about the audio or data in the channel.
*/
struct nrsc5_sig_component_t
{
struct nrsc5_sig_component_t *next; /**< Pointer to next element or NULL */
uint8_t type; /**< NRSC5_SIG_SERVICE_AUDIO or NRSC5_SIG_SERVICE_DATA */
uint8_t id; /**< Component identifier, 0, 1, 2,... */
union
{
/*! Data service information
*/
struct {
uint16_t port; /**< distinguishes packets for this service */
/** e.g. NRSC5_SERVICE_DATA_TYPE_AUDIO_RELATED_DATA */
uint16_t service_data_type;
uint8_t type; /**< NRSC5_AAS_TYPE_STREAM, NRSC5_AAS_TYPE_PACKET, or NRSC5_AAS_TYPE_LOT */
uint32_t mime; /**< content, e.g. NRSC5_MIME_STATION_LOGO */
} data;
/*! Audio service information
*/
struct {
uint8_t port; /**< distinguishes packets for this service */
uint8_t type; /**< program type, e.g. NRSC5_PROGRAM_TYPE_JAZZ */
uint32_t mime; /**< content, e.g. NRSC5_MIME_HDC */
} audio;
};
};
/**
* Defines a typename for struct nrsc5_sig_component_t
*/
typedef struct nrsc5_sig_component_t nrsc5_sig_component_t;
enum
{
NRSC5_SIG_SERVICE_AUDIO,
NRSC5_SIG_SERVICE_DATA
};
/** Represents Station Information Guide (SIG) records
*
* Element of a linked list that will accompany an NRSC5_EVENT_SIG type event.
* Each element describes a channel (audio or data), with a name, e.g. "MPS"
* is used to indicate main program service, "SPS1" to indicate
* supplemental program service 1. Each service may include a linked
* list of type nrsc5_sig_component_t describing its components, which
* may include both audio and other data.
*
* Note: Stations which have only a single audio program and no data services
* may not broadcast a SIG table. Applications should not assume that a SIG
* table will be present. Information about audio services can be obtained
* from PDU headers (reported in NRSC5_EVENT_AUDIO_SERVICE events) instead.
*/
struct nrsc5_sig_service_t
{
struct nrsc5_sig_service_t *next; /**< Pointer to next element or NULL */
uint8_t type; /**< NRSC5_SIG_SERVICE_AUDIO or NRSC5_SIG_SERVICE_DATA */
uint16_t number; /**< Channel number: 1,2,3,4 */
const char *name; /**< Channel name, e.g. "MPS" or "SPS1" */
nrsc5_sig_component_t *components; /**< Head of linked list of components */
nrsc5_sig_component_t *audio_component; /**< Direct link to the audio component of an audio service, or NULL for a data service */
};
/**
* Defines a typename for struct nrsc5_sig_service_t
*/
typedef struct nrsc5_sig_service_t nrsc5_sig_service_t;
enum
{
NRSC5_EVENT_LOST_DEVICE,
NRSC5_EVENT_IQ,
NRSC5_EVENT_SYNC,
NRSC5_EVENT_LOST_SYNC,
NRSC5_EVENT_MER,
NRSC5_EVENT_BER,
NRSC5_EVENT_HDC,
NRSC5_EVENT_AUDIO,
NRSC5_EVENT_ID3,
NRSC5_EVENT_SIG,
NRSC5_EVENT_LOT,
NRSC5_EVENT_SIS,
NRSC5_EVENT_STREAM,
NRSC5_EVENT_PACKET,
NRSC5_EVENT_AUDIO_SERVICE,
NRSC5_EVENT_STATION_ID,
NRSC5_EVENT_STATION_NAME,
NRSC5_EVENT_STATION_SLOGAN,
NRSC5_EVENT_STATION_MESSAGE,
NRSC5_EVENT_STATION_LOCATION,
NRSC5_EVENT_AUDIO_SERVICE_DESCRIPTOR,
NRSC5_EVENT_DATA_SERVICE_DESCRIPTOR,
NRSC5_EVENT_EMERGENCY_ALERT,
NRSC5_EVENT_HERE_IMAGE,
NRSC5_EVENT_LOT_HEADER,
NRSC5_EVENT_LOT_FRAGMENT,
NRSC5_EVENT_AGC
};
enum
{
NRSC5_ACCESS_PUBLIC,
NRSC5_ACCESS_RESTRICTED
};
enum
{
NRSC5_PROGRAM_TYPE_UNDEFINED = 0,
NRSC5_PROGRAM_TYPE_NEWS = 1,
NRSC5_PROGRAM_TYPE_INFORMATION = 2,
NRSC5_PROGRAM_TYPE_SPORTS = 3,
NRSC5_PROGRAM_TYPE_TALK = 4,
NRSC5_PROGRAM_TYPE_ROCK = 5,
NRSC5_PROGRAM_TYPE_CLASSIC_ROCK = 6,
NRSC5_PROGRAM_TYPE_ADULT_HITS = 7,
NRSC5_PROGRAM_TYPE_SOFT_ROCK = 8,
NRSC5_PROGRAM_TYPE_TOP_40 = 9,
NRSC5_PROGRAM_TYPE_COUNTRY = 10,
NRSC5_PROGRAM_TYPE_OLDIES = 11,
NRSC5_PROGRAM_TYPE_SOFT = 12,
NRSC5_PROGRAM_TYPE_NOSTALGIA = 13,
NRSC5_PROGRAM_TYPE_JAZZ = 14,
NRSC5_PROGRAM_TYPE_CLASSICAL = 15,
NRSC5_PROGRAM_TYPE_RHYTHM_AND_BLUES = 16,
NRSC5_PROGRAM_TYPE_SOFT_RHYTHM_AND_BLUES = 17,
NRSC5_PROGRAM_TYPE_FOREIGN_LANGUAGE = 18,
NRSC5_PROGRAM_TYPE_RELIGIOUS_MUSIC = 19,
NRSC5_PROGRAM_TYPE_RELIGIOUS_TALK = 20,
NRSC5_PROGRAM_TYPE_PERSONALITY = 21,
NRSC5_PROGRAM_TYPE_PUBLIC = 22,
NRSC5_PROGRAM_TYPE_COLLEGE = 23,
NRSC5_PROGRAM_TYPE_SPANISH_TALK = 24,
NRSC5_PROGRAM_TYPE_SPANISH_MUSIC = 25,
NRSC5_PROGRAM_TYPE_HIP_HOP = 26,
NRSC5_PROGRAM_TYPE_WEATHER = 29,
NRSC5_PROGRAM_TYPE_EMERGENCY_TEST = 30,
NRSC5_PROGRAM_TYPE_EMERGENCY = 31,
NRSC5_PROGRAM_TYPE_TRAFFIC = 65,
NRSC5_PROGRAM_TYPE_SPECIAL_READING_SERVICES = 76
};
enum
{
NRSC5_BLEND_DISABLE,
NRSC5_BLEND_SELECT,
NRSC5_BLEND_ENABLE
};
enum
{
NRSC5_LOCATION_FORMAT_SAME,
NRSC5_LOCATION_FORMAT_FIPS,
NRSC5_LOCATION_FORMAT_ZIP
};
enum
{
NRSC5_ALERT_CATEGORY_NON_SPECIFIC = 1,
NRSC5_ALERT_CATEGORY_GEOPHYSICAL = 2,
NRSC5_ALERT_CATEGORY_WEATHER = 3,
NRSC5_ALERT_CATEGORY_SAFETY = 4,
NRSC5_ALERT_CATEGORY_SECURITY = 5,
NRSC5_ALERT_CATEGORY_RESCUE = 6,
NRSC5_ALERT_CATEGORY_FIRE = 7,
NRSC5_ALERT_CATEGORY_HEALTH = 8,
NRSC5_ALERT_CATEGORY_ENVIRONMENTAL = 9,
NRSC5_ALERT_CATEGORY_TRANSPORTATION = 10,
NRSC5_ALERT_CATEGORY_UTILITIES = 11,
NRSC5_ALERT_CATEGORY_HAZMAT = 12,
NRSC5_ALERT_CATEGORY_TEST = 30
};
enum
{
NRSC5_HERE_IMAGE_TRAFFIC = 8,
NRSC5_HERE_IMAGE_WEATHER = 13
};
/**
* Station Information Service *Audio* service descriptor. This is a
* linked list element that may point to further audio service
* descriptor elements. Refer to NRSC-5 document SY_IDD_1020s.
*
* Note: Not all stations broadcast SIS audio service descriptors, so
* applications should not assume that they will be present. Audio service
* data from PDU headers (reported in NRSC5_EVENT_AUDIO_SERVICE events) can
* be used instead.
*/
struct nrsc5_sis_asd_t
{
struct nrsc5_sis_asd_t *next; /**< Pointer to next element or NULL */
unsigned int program; /**< program number 0, 1, ..., 7 */
unsigned int access; /**< NRSC5_ACCESS_PUBLIC or NRSC5_ACCESS_RESTRICTED */
unsigned int type; /**< program type, e.g. NRSC5_PROGRAM_TYPE_JAZZ */
unsigned int sound_exp; /**< 0 is none, 2 is Dolby Pro Logic II Surround */
};
/**
* Defines a typename for struct nrsc5_sis_asd_t
*/
typedef struct nrsc5_sis_asd_t nrsc5_sis_asd_t;
enum
{
NRSC5_SERVICE_DATA_TYPE_NON_SPECIFIC = 0,
NRSC5_SERVICE_DATA_TYPE_NEWS = 1,
NRSC5_SERVICE_DATA_TYPE_SPORTS = 3,
NRSC5_SERVICE_DATA_TYPE_WEATHER = 29,
NRSC5_SERVICE_DATA_TYPE_EMERGENCY = 31,
NRSC5_SERVICE_DATA_TYPE_TRAFFIC = 65,
NRSC5_SERVICE_DATA_TYPE_IMAGE_MAPS = 66,
NRSC5_SERVICE_DATA_TYPE_TEXT = 80,
NRSC5_SERVICE_DATA_TYPE_ADVERTISING = 256,
NRSC5_SERVICE_DATA_TYPE_FINANCIAL = 257,
NRSC5_SERVICE_DATA_TYPE_STOCK_TICKER = 258,
NRSC5_SERVICE_DATA_TYPE_NAVIGATION = 259,
NRSC5_SERVICE_DATA_TYPE_ELECTRONIC_PROGRAM_GUIDE = 260,
NRSC5_SERVICE_DATA_TYPE_AUDIO = 261,
NRSC5_SERVICE_DATA_TYPE_PRIVATE_DATA_NETWORK = 262,
NRSC5_SERVICE_DATA_TYPE_SERVICE_MAINTENANCE = 263,
NRSC5_SERVICE_DATA_TYPE_HD_RADIO_SYSTEM_SERVICES = 264,
NRSC5_SERVICE_DATA_TYPE_AUDIO_RELATED_DATA = 265,
NRSC5_SERVICE_DATA_TYPE_RESERVED_FOR_SPECIAL_TESTS = 511
};
/**
* Station Information Service *Data* service descriptor. This is a
* linked list element that may point to further data service descriptors
* via `next` member if not `NULL`. See
* nrsc5_service_data_type_name() for named types of data.
* Refer to NRSC-5 document SY_IDD_1020s.
*/
struct nrsc5_sis_dsd_t
{
struct nrsc5_sis_dsd_t *next; /**< Pointer to next element or NULL */
unsigned int access; /**< NRSC5_ACCESS_PUBLIC or NRSC5_ACCESS_RESTRICTED */
unsigned int type; /**< data service type, e.g. NRSC5_SERVICE_DATA_TYPE_TEXT */
uint32_t mime_type; /**< MIME type, e.g. `NRSC5_MIME_TEXT` */
};
/**
* Defines a typename for struct nrsc5_sis_dsd_t
*/
typedef struct nrsc5_sis_dsd_t nrsc5_sis_dsd_t;
/**
* ID3 comment descriptor. This is a linked list element that may point to further
* comments via `next` member if not `NULL`.
* Refer to HD-Radio document SY_IDD_1028s.
*/
struct nrsc5_id3_comment_t {
struct nrsc5_id3_comment_t *next; /**< Pointer to next element or NULL */
char *lang; /**< language code, e.g. "eng" */
char *short_content_desc; /**< short content description */
char *full_text; /**< full text */
};
/**
* Defines a typename for struct nrsc5_id3_comment_t
*/
typedef struct nrsc5_id3_comment_t nrsc5_id3_comment_t;
enum
{
NRSC5_PKT_FLAGS_NONE = 0,
NRSC5_PKT_FLAGS_CRC_ERROR = 1 << 0, /** Failed the CRC check. Could be corrupted packet. */
};
/** Incoming event from receiver.
*
* This event structure is passed to your application supplied
* callback function--see nrsc5_set_callback(). It is a union of
* various structs, keyed by member `event`.
*/
struct nrsc5_event_t
{
/*! Type of event.
* The member `event` determines which sort of event occurred:
* - `NRSC5_EVENT_LOST_DEVICE` : RTL-SDR device was disconnected
* - `NRSC5_EVENT_IQ` : IQ data, see the `iq` union member
* - `NRSC5_EVENT_SYNC` : indicates synchronization achieved, see the `sync` union member
* - `NRSC5_EVENT_LOST_SYNC` : indicates synchronization lost
* - `NRSC5_EVENT_MER` : modulation error ratio, see the `mer` union member, and NRSC5 document SY_TN_2646s
* - `NRSC5_EVENT_BER` : Bit Error Ratio data, see the `ber` union member
* - `NRSC5_EVENT_HDC` : HDC audio packet, see the `hdc` union member
* - `NRSC5_EVENT_AUDIO` : audio buffer, see the `audio` union member
* - `NRSC5_EVENT_ID3` : ID3 information packet arrived, see `id3` member and information in HD-Radio document SY_IDD_1028s.
* - `NRSC5_EVENT_SIG` : service information arrived, see `sig` member
* - `NRSC5_EVENT_LOT` : LOT file data available, see `lot` member
* - `NRSC5_EVENT_LOT_HEADER` : LOT file header metadata available, see `lot` member
* - `NRSC5_EVENT_LOT_FRAGMENT` : fragment of a LOT file received, see `lot_fragment` member
* - `NRSC5_EVENT_SIS` : DEPRECATED. Use `NRSC5_EVENT_STATION_ID`, `NRSC5_EVENT_STATION_NAME`, `NRSC5_EVENT_STATION_SLOGAN`, `NRSC5_EVENT_STATION_MESSAGE`, `NRSC5_EVENT_STATION_LOCATION`, `NRSC5_EVENT_AUDIO_SERVICE_DESCRIPTOR`, `NRSC5_EVENT_DATA_SERVICE_DESCRIPTOR`, and `NRSC5_EVENT_EMERGENCY_ALERT` instead.
* - `NRSC5_EVENT_STREAM` : stream data available, see `stream` member
* - `NRSC5_EVENT_PACKET` : packet data available, see `packet` member
* - `NRSC5_EVENT_AUDIO_SERVICE` : audio service available, see `audio_service` member
* - `NRSC5_EVENT_STATION_ID` : station ID number, see `station_id` member
* - `NRSC5_EVENT_STATION_NAME` : station name, see `station_name` member
* - `NRSC5_EVENT_STATION_SLOGAN` : station slogan, see `station_slogan` member
* - `NRSC5_EVENT_STATION_MESSAGE` : station message, see `station_message` member
* - `NRSC5_EVENT_STATION_LOCATION` : station location, see `station_location` member
* - `NRSC5_EVENT_AUDIO_SERVICE_DESCRIPTOR` : SIS audio service descriptor, see `asd` member
* - `NRSC5_EVENT_DATA_SERVICE_DESCRIPTOR` : SIS data service descriptor, see `dsd` member
* - `NRSC5_EVENT_EMERGENCY_ALERT` : emergency alert, see `emergency_alert` member
* - `NRSC5_EVENT_HERE_IMAGE` : HERE Images traffic/weather map, see `here_image` member
* - `NRSC5_EVENT_AGC` : automatic gain control status, see `agc` member
*/
unsigned int event;
union
{
struct {
const void *data;
size_t count;
} iq;
struct {
float freq_offset; /**< Frequency offset in Hz */
int psmi; /**< Primary Service Mode Indicator (1, 2, 3, 5, 6, or 11 for FM; 1 or 2 for AM) */
} sync;
struct {
float cber;
} ber;
struct {
float lower;
float upper;
} mer;
struct {
unsigned int program;
const uint8_t *data;
size_t count;
unsigned int flags; /** The specific status of the hdc packet. Example `NRSC5_PKT_FLAGS_CRC_ERROR` **/
} hdc;
struct {
unsigned int program;
const int16_t *data;
size_t count;
} audio;
struct {
unsigned int program;
const char *title;
const char *artist;
const char *album;
const char *genre;
struct {
const char *owner;
const char *id;
} ufid;
struct {
uint32_t mime;
int param;
int lot;
} xhdr;
nrsc5_id3_comment_t *comments;
} id3;
struct {
uint16_t port; /**< DEPRECATED: Use `component->data.port` instead */
uint16_t seq;
unsigned int size;
uint32_t mime; /**< DEPRECATED: Use `component->data.mime` instead */
const uint8_t *data;
nrsc5_sig_service_t *service;
nrsc5_sig_component_t *component;
} stream;
struct {
uint16_t port; /**< DEPRECATED: Use `component->data.port` instead */
uint16_t seq;
unsigned int size;
uint32_t mime; /**< DEPRECATED: Use `component->data.mime` instead */
const uint8_t *data;
nrsc5_sig_service_t *service;
nrsc5_sig_component_t *component;
} packet;
struct {
uint16_t port; /**< DEPRECATED: Use `component->data.port` instead */
unsigned int lot; /**< LOT id of the file */
unsigned int size; /**< number of bytes in the file */
uint32_t mime; /**< MIME type of the file, e.g. NRSC5_MIME_PNG */
const char *name; /**< filename */
const uint8_t *data; /**< contents of the file (if the event type is NRSC5_EVENT_LOT), or NULL (if the event type is NRSC5_EVENT_LOT_HEADER) */
struct tm *expiry_utc; /**< time after which the file should be deleted */
nrsc5_sig_service_t *service; /**< pointer to the associated SIG service */
nrsc5_sig_component_t *component; /**< pointer to the associated SIG component */
} lot;
struct {
unsigned int lot; /**< LOT id of the file this fragment belongs to */
unsigned int seq; /**< sequence number of this fragment within the LOT file */
unsigned int repeat; /**< number of repetitions remaining */
unsigned int size; /**< number of bytes in this fragment */
unsigned int bytes_so_far; /**< total number of bytes received for this LOT file, across all received fragments */
int is_duplicate; /**< 1 if this fragment was previously received, otherwise 0 */
const uint8_t *data; /**< pointer to the data bytes of this fragment */
nrsc5_sig_service_t *service; /**< pointer to the associated SIG service */
nrsc5_sig_component_t *component; /**< pointer to the associated SIG component */
} lot_fragment;
struct {
unsigned int program; /**< program number 0, 1, ..., 7 */
unsigned int access; /**< NRSC5_ACCESS_PUBLIC or NRSC5_ACCESS_RESTRICTED */
unsigned int type; /**< program type, e.g. NRSC5_PROGRAM_TYPE_JAZZ */
unsigned int codec_mode; /**< audio codec mode. See SY_IDD_1017s Table 5-2. */
unsigned int blend_control; /**< blend control (NRSC5_BLEND_DISABLE, NRSC5_BLEND_SELECT, or NRSC5_BLEND_ENABLE). See SY_IDD_1017s section 5.2.1.2. */
int digital_audio_gain; /**< TX digital audio gain, in dB. See SY_IDD_1017s section 5.2.1.3. */
unsigned int common_delay; /**< post-decoded common delay, in audio frame periods. See SY_IDD_1017s Table 5-1. */
unsigned int latency; /**< audio codec latency, in audio frame periods. See SY_IDD_1017s Table 5-1. */
} audio_service;
struct {
nrsc5_sig_service_t *services;
} sig;
struct {
const char *country_code;
int fcc_facility_id;
const char *name;
const char *slogan;
const char *message;
const char *alert;
float latitude;
float longitude;
int altitude;
nrsc5_sis_asd_t *audio_services;
nrsc5_sis_dsd_t *data_services;
const uint8_t *alert_cnt;
int alert_cnt_length;
int alert_category1;
int alert_category2;
int alert_location_format;
int alert_num_locations;
const int *alert_locations;
} sis;
struct {
const char *country_code;
int fcc_facility_id;
} station_id;
struct {
const char *name;
} station_name;
struct {
const char *slogan;
} station_slogan;
struct {
const char *message;
} station_message;
struct {
float latitude;
float longitude;
int altitude;
} station_location;
struct {
unsigned int program; /**< program number 0, 1, ..., 7 */
unsigned int access; /**< NRSC5_ACCESS_PUBLIC or NRSC5_ACCESS_RESTRICTED */
unsigned int type; /**< program type, e.g. NRSC5_PROGRAM_TYPE_JAZZ */
unsigned int sound_exp; /**< 0 is none, 2 is Dolby Pro Logic II Surround */
} asd;
struct {
unsigned int access; /**< NRSC5_ACCESS_PUBLIC or NRSC5_ACCESS_RESTRICTED */
unsigned int type; /**< data service type, e.g. NRSC5_SERVICE_DATA_TYPE_TEXT */
uint32_t mime_type; /**< MIME type, e.g. `NRSC5_MIME_TEXT` */
} dsd;
struct {
const char *message;
const uint8_t *control_data;
int control_data_length;
int category1;
int category2;
int location_format;
int num_locations;
const int *locations;
} emergency_alert;
struct {
int image_type; /**< NRSC5_HERE_IMAGE_TRAFFIC or NRSC5_HERE_IMAGE_WEATHER */
int seq; /**< sequence number (1-15); increments when traffic/weather image changes */
int n1; /**< part number (1-9) for traffic, or incrementing sequence number for weather */
int n2; /**< number of parts (9) for traffic, or incrementing sequence number for weather */
struct tm *time_utc; /**< UTC time of traffic or weather image */
float latitude1; /**< latitude of north map edge */
float longitude1; /**< longitude of west map edge */
float latitude2; /**< latitude of south map edge */
float longitude2; /**< longitude of east map edge */
const char *name; /**< filename, e.g. "trafficMap_1_2_rdhs.png" or "WeatherImage_0_0_rdhs.png" */
unsigned int size; /**< size of image file, in bytes */
const uint8_t *data; /**< contents of image file */
} here_image;
struct {
float gain_db; /**< SDR gain value in dB */
float peak_dbfs; /**< peak signal amplitude in dB, relative to full scale */
int is_final; /**< 1 if this is the final (best) gain value, otherwise 0 */
} agc;
};
};
/**
* Defines a typename for struct nrsc5_event_t
*/
typedef struct nrsc5_event_t nrsc5_event_t;
/**
* Prototype for a user event handling callback function.
* The function will be invoked with a pointer to the nrsc5_event_t
* and a pointer to a second contextual argument, established by
* nrsc5_set_callback().
*/
typedef void (*nrsc5_callback_t)(const nrsc5_event_t *evt, void *opaque);
/**
* An opaque data type used by API functions to represent session information.
* Applications should acquire a pointer to one via the `open_` functions:
* nrsc5_open(), nrsc5_open_file(), nrsc5_open_pipe(), or nrsc5_open_rtltcp().
*/
typedef struct nrsc5_t nrsc5_t;
/* ============================================================================
* Public functions. All functions return void or an error code (0 == success).
*/
/**
* Retrieves the version string of the library.
* @param[out] version character pointer that will reference the version string.
*/
NRSC5_API void nrsc5_get_version(const char **version);
/**
* Retrieves a string corresponding to a service data type.
* @param[in] type a service data type integer.
* @param[out] name character pointer to a string naming the service type
*
* This name will be quite short, e.g. "News" or "Weather". If the type is
* not recognized, it will be the string "Unknown".
*/
NRSC5_API void nrsc5_service_data_type_name(unsigned int type, const char **name);
/**
* Retrieves a string corresponding to a program type.
* @param[in] type a program data type integer.
* @param[out] name character pointer to a string naming the service type
*
* This name will be quite short, e.g. "News" or "Rock". If the type is
* not recognized, it will be the string "Unknown".
*/
NRSC5_API void nrsc5_program_type_name(unsigned int type, const char **name);
/**
* Retrieves a string corresponding to an alert category.
* @param[in] type an alert category integer.
* @param[out] name character pointer to a string naming the alert category
*
* This name will be quite short, e.g. "Weather" or "Safety". If the type is
* not recognized, it will be the string "Unknown".
*/
NRSC5_API void nrsc5_alert_category_name(unsigned int category, const char **name);
/**
* Initializes a session for a particular RTLSDR radio dongle.
* @param[out] st handle for an nrsc5_t
* @param[in] device_index the RTLSDR device index
* @return 0 on success, nonzero on error
*
* The `device_index` is commonly 0 on systems with a single radio dongle.
* This, or another `open_` command should be issued before using the other API
* functions that need an `nrsc5_t` session handle.
* This function will allocate and initialize an opaque `nsrc5_t` struct and set
* the pointer `result` to it on success. It uses librtlsdr to:
*
* - open the RTLSDR device indicated by `device_index`
* - set the sample rate to constant SAMPLE_RATE
* - set the tuner gain mode to 1 (auto)
* - set offset tuning to 1
*
* Other session options are initialized to defaults, e.g. mode to FM.
* It creates (but does not start) a worker thread.
*/
NRSC5_API int nrsc5_open(nrsc5_t **st, int device_index);
/**
* Initializes a session given an open `FILE` pointer.
* @param[out] st handle for an `nrsc5_t`
* @param[in] fp FILE pointer handle with nrsc5 data
* @return 0 on success, nonzero on error
*
*/
NRSC5_API int nrsc5_open_file(nrsc5_t **st, FILE *fp);
/**
* Initializes a session for use with a pipe.
* @param[out] st handle for an `nrsc5_t`
* @return 0 on success, nonzero on error
*
*/
NRSC5_API int nrsc5_open_pipe(nrsc5_t **st);
/**
* Initializes a session given a TCP socket file descriptor.
* @param[out] st handle for an `nrsc5_t`
* @param[in] socket the TCP socket with nrsc5 data
* @return 0 on success, nonzero on error
*
*/
NRSC5_API int nrsc5_open_rtltcp(nrsc5_t **st, int socket);
/**
* Closes an nrsc5 session.
* @param[in] st pointer to an `nrsc5_t`
*
* Any worker thread is signalled to exit, files and sockets are closed,
* and I/O buffers are freed.
*/
NRSC5_API void nrsc5_close(nrsc5_t *st);
/**
* Signals the worker to *start* demodulation.
* @param[in] st pointer to an `nrsc5_t` session object
*
*/
NRSC5_API void nrsc5_start(nrsc5_t *st);
/**
* Signals the worker to *stop* demodulation.
* @param[in] st pointer to an `nrsc5_t` session object
*
* This function will block until the worker is stopped.
*/
NRSC5_API void nrsc5_stop(nrsc5_t *st);
/**
* Set the session mode to AM or FM.
* @param[in] st pointer to an `nrsc5_t` session object
* @param[in] mode either `NRSC5_MODE_FM` or `NRSC5_MODE_AM`
* @return 0 on success or nonzero on error.
*
*/
NRSC5_API int nrsc5_set_mode(nrsc5_t *st, int mode);
/**
* Enable or disable the bias-T for the radio.
* @param[in] st pointer to an `nrsc5_t` session object
* @param[in] on 1 indicates enabled, and 0 indicates disabled
* @return Return 0 on success or nonzero on error.
*
* This works with both a local SDR and over a TCP connection.
* A Bias-T is often used to power a low noise amplifier by injecting
* DC on the antenna cable. Do not enable this unless you know you
* have an LNA and compatible antenna.
*/
NRSC5_API int nrsc5_set_bias_tee(nrsc5_t *st, int on);
/**
* Enable or disable direct sampling.
* @param[in] st pointer to an `nrsc5_t` session object
* @param[in] on 1 indicates enabled, and 0 indicates disabled
* @return 0 on success or nonzero on error.
*
* This works with both a local SDR and over a TCP connection.
*/
NRSC5_API int nrsc5_set_direct_sampling(nrsc5_t *st, int on);
/**
* Adjust the radio frequency correction.
* @param[in] st pointer to an `nrsc5_t` session object
* @param[in] ppm_error correction offset in parts-per-million
* @return Return 0 on success or nonzero on error.
*
* This works with both a local SDR and over a TCP connection.
*/
NRSC5_API int nrsc5_set_freq_correction(nrsc5_t *st, int ppm_error);
/**
* Retrieve the frequency to which the device is currently tuned
* if initialized to a local dongle, otherwise the cached frequency.
*
* @param[in] st pointer to an `nrsc5_t` session object
* @param[out] freq frequency in Hz
*/
NRSC5_API void nrsc5_get_frequency(nrsc5_t *st, float *freq);
/**
* Sets the frequency to which the receiver is tuned.
*
* @param[in] st pointer to an `nrsc5_t` session object
* @param[out] freq frequency in Hz
* @return 0 on success or nonzero on error
*
* This function may only be called when the device is **stopped**.
* Input, output are reset. Gain is reset if auto-gain is enabled.
* Works with both a local SDR and over a TCP connection.
*/
NRSC5_API int nrsc5_set_frequency(nrsc5_t *st, float freq);
/**
* Retrieve the actual receiver gain.
*
* @param[in] st pointer to an `nrsc5_t` session object
* @param[out] gain in dB
*
*/
NRSC5_API void nrsc5_get_gain(nrsc5_t *st, float *gain);
/**
* Set the receiver gain.
*
* @param[in] st pointer to an `nrsc5_t` session object
* @param[in] gain in dB
* @return 0 on success or nonzero on error
*
*/
NRSC5_API int nrsc5_set_gain(nrsc5_t *st, float gain);
/**
* Enable or disable receiver auto-gain control.
*
* @param[in] st pointer to an `nrsc5_t` session object
* @param[in] enabled set to 1 to enable auto gain, 0 to disable
*
*/
NRSC5_API void nrsc5_set_auto_gain(nrsc5_t *st, int enabled);
/**
* Establish a callback function.
*
* @param[in] st pointer to an `nrsc5_t` session object
* @param[in] callback pointer to an event handling function of two arguments
* @param[in] opaque pointer to the function's intended 2nd argument
*
*/
NRSC5_API void nrsc5_set_callback(nrsc5_t *st, nrsc5_callback_t callback, void *opaque);
/**
* Push an IQ array of 8-bit unsigned samples into the demodulator.
*
* @param[in] st pointer to an `nrsc5_t` session object
* @param[in] samples pointer to an array 8-bit unsigned samples
* @param[in] length the number of samples in the array
* @see NRSC5_SAMPLE_RATE_CU8 for required sample rate
* @return 0 on success, nonzero on error
*
*/
NRSC5_API int nrsc5_pipe_samples_cu8(nrsc5_t *st, const uint8_t *samples, unsigned int length);
/**
* Push an IQ input array of 16-bit signed samples into the demodulator.
*
* @param[in] st pointer to an `nrsc5_t` session object
* @param[in] samples pointer to an array 16-bit signed samples
* @param[in] length the number of samples in the array
* @see NRSC5_SAMPLE_RATE_CS16_FM & NRSC5_SAMPLE_RATE_CS16_AM for required sample rate
* @return 0 on success, nonzero on error
*
*/
NRSC5_API int nrsc5_pipe_samples_cs16(nrsc5_t *st, const int16_t *samples, unsigned int length);
#endif /* NRSC5_H_ */