]> git.sesse.net Git - casparcg/blob - BluefishSDK_V5_10_0_42/Inc/BlueHANC.h
ntsc-audio-exp: Better synchronization of audio-cadence.
[casparcg] / BluefishSDK_V5_10_0_42 / Inc / BlueHANC.h
1 #pragma once \r
2 #include "BlueDriver_p.h"\r
3 \r
4 #ifdef _WINDOWS\r
5 #pragma pack(push,1)\r
6 #endif\r
7 \r
8 #define BLUE_HANC_INVALID_DID   (0x0)\r
9 \r
10 #define BLUE_HANC_AUDIOGROUP1   (0x2FF)\r
11 #define BLUE_HANC_AUDIOGROUP2   (0x1FD)\r
12 #define BLUE_HANC_AUDIOGROUP3   (0x1FB)\r
13 #define BLUE_HANC_AUDIOGROUP4   (0x2F9)\r
14 #define BLUE_HANC_RP188                 (0x260)\r
15 #define BLUE_HANC_AUDIOGROUP1_CONTROL   (0x1EF)\r
16 #define BLUE_HANC_AUDIOGROUP2_CONTROL   (0x2EE)\r
17 #define BLUE_HANC_AUDIOGROUP3_CONTROL   (0x2ED)\r
18 #define BLUE_HANC_AUDIOGROUP4_CONTROL   (0x1EC)\r
19 #define BLUE_HANC_AUDIOGROUP1_EXTENDED  (0x1FE)\r
20 #define BLUE_HANC_AUDIOGROUP2_EXTENDED  (0x2FC)\r
21 #define BLUE_HANC_AUDIOGROUP3_EXTENDED  (0x2FA)\r
22 #define BLUE_HANC_AUDIOGROUP4_EXTENDED  (0x1F8)\r
23 \r
24 \r
25 #define HANC_PACKET_HEADER_CONST        (0xBFFFFC00)\r
26 \r
27 #define BLUE_HANC_START_NEWLINE(line_number) ((0xC0000000)| (line_number << 16))\r
28 \r
29 #define BLUE_HANC_CONTROL_WORD                           (0xC0000000)\r
30 #define BLUE_HANC_3DATA_PACKET_WORD                      (0x80000000)\r
31 #define BLUE_HANC_2DATA_PACKET_WORD                      (0x40000000)\r
32 #define BLUE_HANC_1DATA_PACKET_WORD                      (0x00000000)\r
33 #define BLUE_HANC_ENDOF_FRAME()                          ((0xC0000000)| (1 << 15))\r
34 \r
35 \r
36 #define AESAUDIO_DATA_BLOCKSIZE                                         (192)\r
37 #define MAX_HANC_BUFFER_SIZE                                            (65536) //256*256\r
38 #define MAX_HANC_BUFFER_SIZE_WITHOUT_HEADER                     (65536 - 0x20/4)        //32 bytes = 8 * 4 (8 * UINT32)\r
39 #define MAX_HANC_BUFFER_SIZE_BYTES                                      (256*1024)\r
40 #define MAX_HANC_BUFFER_SIZE_WITHOUT_HEADER_BYTES       (256*1024 - 0x20)\r
41 /* \r
42 HANC Packet header structure\r
43 Contains 2 type of structure , \r
44 which makes it easier to parse the data\r
45 */\r
46 \r
47 struct GenericV210_structure\r
48 {\r
49 #if defined(__LITTLE_ENDIAN__) || defined(_WINDOWS) || defined(BLUE_LINUX_CODE)\r
50         BLUE_UINT32 first_word:10,second_word:10,third_word:10,unused:2;\r
51 #else\r
52         BLUE_UINT32 unused:2,third_word:10,second_word:10,first_word:10;\r
53 #endif\r
54 #ifndef _WINDOWS\r
55 }__attribute__((packed));\r
56 #else\r
57 };\r
58 #endif\r
59 \r
60 union GenericV210_union\r
61 {\r
62         struct GenericV210_structure v210_struct;\r
63         BLUE_UINT32 v210_word;\r
64 };\r
65 \r
66 /* HANC packet header*/\r
67 struct HancPacketHeaderStruct\r
68 {\r
69 #if defined(__LITTLE_ENDIAN__) || defined(_WINDOWS) || defined(BLUE_LINUX_CODE)\r
70         union GenericV210_union ancillary_data_flag; // 0x0,0x3FF,0x3FF, This is a constant defined by smpte\r
71         union GenericV210_union packet_info;    //  first 10 bit word --> Data ID\r
72                                                 //      Commonly used  Data ID packet values are \r
73                                                 //              1) 0x2FF --> Group1 Embedded Audio packet\r
74                                                 //              2) 0x1FD --> Group2 Embedded Audio Packet\r
75                                                 //              3) 0x1FB --> Group3 Embedded Audio Packet\r
76                                                 //              4) 0x2F9 --> Group4 Embedded Audio packet\r
77                                                 //  second 10 bit word --> Data Block Number\r
78                                                 //      This is used for type 1 packets.\r
79                                                 //  third 10 bit word --> Data Count \r
80                                                 //      This 10 bit word specifies the amount of user data \r
81                                                 //      that this hanc will contain.\r
82 #else\r
83         union GenericV210_union packet_info;\r
84         union GenericV210_union ancillary_data_flag;\r
85 #endif\r
86 #ifndef _WINDOWS\r
87 }__attribute__((packed));\r
88 #else\r
89 };\r
90 #endif\r
91 \r
92 \r
93 /* Audio SubFrame Packet */\r
94 struct BlueAudioSubFrameStruct\r
95 {       \r
96 #if defined(__LITTLE_ENDIAN__) || defined(_WINDOWS) || defined(BLUE_LINUX_CODE)\r
97         BLUE_UINT32     ZBit:1,                                 //bit 0         set to declare start of channel status word\r
98                         Channel:2,                                      //bit 1-2\r
99                         AudioData_0_5:6,                        //bit 3-8\r
100                         NotBit8:1,                                      //bit 9\r
101                         AudioData_6_14:9,                       //bit 10-18\r
102                         NotBit18:1,                                     //bit 19        use same value as NotBit8 (bit 9)\r
103                         AudioData_15_19:5,                      //bit 20-24\r
104                         AESSampleValidityBit:1,         //bit 25\r
105                         AESUserBit:1,                           //bit 26\r
106                         AESAudioChannelStatusBit:1,     //bit 27        one bit of the channel status word\r
107                         ParityBit:1,                            //bit 28        xor of all bits except (NotBit8 (bit 9) and NotBit18 (bit 19))\r
108                         NotBit31:1,                                     //bit 29        not of ParityBit (bit 28)\r
109                         akiraControlBits:2;                     //bit 30-31\r
110 #else\r
111         BLUE_UINT32     akiraControlBits:2,\r
112                         NotBit31:1,\r
113                         ParityBit:1,\r
114                         AESAudioChannelStatusBit:1,\r
115                         AESUserBit:1,\r
116                         AESSampleValidityBit:1,\r
117                         AudioData_15_19:5,\r
118                         NotBit18:1,\r
119                         AudioData_6_14:9,\r
120                         NotBit8:1,\r
121                         AudioData_0_5:6,\r
122                         Channel:2,\r
123                         ZBit:1;\r
124 #endif\r
125 \r
126 #ifndef _WINDOWS\r
127 }__attribute__((packed));\r
128 #else\r
129 };\r
130 #endif\r
131 \r
132 union BlueAudioSubFrameHeader\r
133 {\r
134         struct BlueAudioSubFrameStruct audioSubFrame;\r
135         BLUE_UINT32  BlueAudioSubFrameWord;\r
136         struct GenericV210_structure audioSubFrame_v210;\r
137 };\r
138 \r
139 #define  MAX_AUDIO_SUBFRAMES_IN_A_LINE (64) // 4 samples per audio group  and 4 channesl for each  audio group per sample\r
140 \r
141 \r
142 /*\r
143 Time code structure that the function expects is the same format as LTC time code\r
144 bits 0 - 3 :units of frame \r
145 bits 4 - 7: binary group1 \r
146 bits 8 - 9: tens of frame \r
147 bits 10 -11: flags \r
148 bits 12 -15: binary group2 \r
149 bits 16-19 : units of seconds \r
150 bits 20-23 : binary group3 \r
151 \r
152 bits 24 - 26: tens of seconds\r
153 bit 27 : flag \r
154 bits 28 - 31: group binary4  \r
155 bits 32 -35: units of minutes \r
156 \r
157 bits 36 - 39 :binary5 \r
158 bits 40 - 42: tens of minutes \r
159 bit 43 : flag \r
160 bits 44 - 47: binary group6 \r
161 \r
162 bits 48 - 51: units of hours \r
163 bits 52 - 55: binary group7 \r
164 bits 56 - 57: tens of hours \r
165 bits 58 - 59: flag\r
166 bits 60 - 63: binary8\r
167 \r
168 */\r
169 struct LTC_TimeCode\r
170 {\r
171 #if defined(__LITTLE_ENDIAN__) || defined(_WINDOWS) || defined(BLUE_LINUX_CODE)\r
172         BLUE_UINT64     unit_frame:4,binary1:4,ten_frame:2,drop_frame_flag:1,color_frame_flag:1,\r
173                                  binary2:4,unit_second:4,binary3:4,ten_second:3,unsued_1:1,binary4:4,\r
174                                  unit_minute:4,binary5:4,ten_minute:3,unsued_2:1,binary6:4,unit_hours:4,\r
175                                  binary7:4,ten_hours:2,unsued_3:2,binary8:4;\r
176 #else\r
177         BLUE_UINT64             binary8:4,unsued_3:2,ten_hours:2,binary7:4,\r
178                                 unit_hours:4,binary6:4,unused_2:1,ten_minute:3,binary5:4,unit_minute:4,\r
179                                 binary4:4,unused_1:1,ten_second:3,binary3:4,unit_second:4,binary2:4,\r
180                                 color_frame_flag:1,drop_frame_flag:1,ten_frame:2,binary1:4,unit_frame:4;\r
181 #endif\r
182 \r
183 #ifndef _WINDOWS\r
184 }__attribute__((packed));\r
185 #else\r
186 };\r
187 #endif\r
188 \r
189 struct LTC_TimeCode_union\r
190 {\r
191         union \r
192         {\r
193                 struct LTC_TimeCode struct_ltc;\r
194                 BLUE_UINT64 lt_64_value;\r
195         };\r
196 };\r
197 \r
198 /*\r
199         This is used to unpack the timecode word properly and quickly\r
200         in RP188 each 4 bits of the timecode is put into a 10 bit word.\r
201         So this structure helps in decoding \r
202 */\r
203 struct nibble_struct\r
204 {\r
205         BLUE_UINT8      first_half:4,second_half:4;\r
206 \r
207 #ifndef _WINDOWS\r
208 }__attribute__((packed));\r
209 #else\r
210 };\r
211 #endif\r
212 \r
213 struct TimeCode\r
214 {\r
215         union \r
216         {\r
217         struct LTC_TimeCode struct_ltc;\r
218         BLUE_UINT64 ltc;\r
219         struct nibble_struct ltc_char[8]; \r
220         };\r
221         \r
222 #ifndef _WINDOWS\r
223 }__attribute__((packed));\r
224 #else\r
225 };\r
226 #endif\r
227 \r
228 struct HANCTimeCodeStruct \r
229 {       \r
230 #if defined(__LITTLE_ENDIAN__) || defined(_WINDOWS) || defined(BLUE_LINUX_CODE)\r
231         BLUE_UINT32     zero_0:3,\r
232                                 DBB_0:1,\r
233                                 ANC_0:4,\r
234                                 partiy_0:1,\r
235                                 NotBit8_0:1,\r
236                                 zero_1:3,\r
237                                 DBB_1:1,\r
238                                 ANC_1:4,\r
239                                 partiy_1:1,\r
240                                 NotBit8_1:1,\r
241                                 zero_2:3,\r
242                                 DBB_2:1,\r
243                                 ANC_2:4,\r
244                                 partiy_2:1,\r
245                                 NotBit8_2:1,\r
246                                 akiraControlBits:2;\r
247 #else\r
248         BLUE_UINT32 akiraControlBits:2,\r
249                                 Notbit8_2:1,\r
250                                 partiy_2:1,\r
251                                 ANC_2:4,\r
252                                 DBB_2:1,\r
253                                 zero_2:3,\r
254                                 NotBit81_1:1,\r
255                                 partiy_1:1,\r
256                                 ANC_1:4,\r
257                                 DBB_1:1,\r
258                                 zero_1:3,\r
259                                 NotBit8_0:1,\r
260                                 partiy_0:1,\r
261                                 ANC_0:4,\r
262                                 DBB_0:1,\r
263                                 zero_0:3;\r
264 #endif\r
265 \r
266 #ifndef _WINDOWS\r
267 }__attribute__((packed));\r
268 #else\r
269 };\r
270 #endif\r
271 \r
272 union HANCTimeCode\r
273 {\r
274         struct HANCTimeCodeStruct hanc_struct;\r
275         BLUE_UINT32 hanc_word;\r
276 };\r
277 \r
278 struct BAG2VancTimeCodeStruct \r
279 {       \r
280 #if defined(__LITTLE_ENDIAN__) || defined(_WINDOWS) || defined(BLUE_LINUX_CODE)\r
281         BLUE_UINT16     zero_0:3,\r
282                                 DBB_0:1,\r
283                                 ANC_0:4,\r
284                                 partiy_0:1,\r
285                                 NotBit8_0:1;\r
286 #else\r
287         BLUE_UINT16     NotBit8_0:1,\r
288                                 partiy_0:1,\r
289                                 ANC_0:4,\r
290                                 DBB_0:1,\r
291                                 zero_0:3;\r
292 #endif\r
293 \r
294 #ifndef _WINDOWS\r
295 }__attribute__((packed));\r
296 #else\r
297 };\r
298 #endif\r
299 \r
300 union BAG2VancTimeCode\r
301 {\r
302         struct BAG2VancTimeCodeStruct vanc_struct;\r
303         BLUE_UINT16 vanc_word;\r
304 };\r
305 \r
306 \r
307 inline BLUE_UINT64 convert_countto_timecode(BLUE_UINT32 frame_count,BLUE_UINT32 framePerSec)\r
308 {\r
309         unsigned int frames ,second,minutes ,hour   ;\r
310         struct TimeCode rp188_timcode;\r
311         hour = frame_count/(60*60*framePerSec);\r
312         minutes = frame_count%(60*60*framePerSec);\r
313         second = minutes%(60*framePerSec);\r
314         frames = second %framePerSec;\r
315         second = second/(framePerSec);\r
316         minutes=minutes/(60*framePerSec);\r
317         rp188_timcode.ltc = 0;\r
318         rp188_timcode.struct_ltc.unit_frame = (frames%10);\r
319         rp188_timcode.struct_ltc.ten_frame = (frames/10);\r
320         rp188_timcode.struct_ltc.unit_second = (second%10);\r
321         rp188_timcode.struct_ltc.ten_second = (second/10);\r
322         rp188_timcode.struct_ltc.unit_minute = (minutes%10);\r
323         rp188_timcode.struct_ltc.ten_minute = (minutes/10);\r
324         rp188_timcode.struct_ltc.unit_hours = (hour%10);\r
325         rp188_timcode.struct_ltc.ten_hours = (hour/10);\r
326         \r
327         return rp188_timcode.ltc;\r
328 }\r
329 \r
330 \r
331 inline BLUE_UINT64 convert_timecode_to_count(BLUE_UINT64 timecode,\r
332                                                                                          BLUE_UINT32 framePerSec,\r
333                                                                                          unsigned int & frames ,\r
334                                                                                          unsigned int & second,\r
335                                                                                          unsigned int & minutes ,\r
336                                                                                          unsigned int & hours)\r
337 {\r
338         \r
339         struct TimeCode rp188_timecode;\r
340         rp188_timecode.ltc = timecode;\r
341         hours  = (BLUE_UINT32)((unsigned int)rp188_timecode.struct_ltc.ten_hours*10)+(unsigned int)rp188_timecode.struct_ltc.unit_hours;\r
342         minutes = (BLUE_UINT32)((unsigned int)rp188_timecode.struct_ltc.ten_minute*10)+(unsigned int)rp188_timecode.struct_ltc.unit_minute;\r
343         second =  (BLUE_UINT32)((unsigned int)rp188_timecode.struct_ltc.ten_second*10)+(unsigned int)rp188_timecode.struct_ltc.unit_second;\r
344         frames =         (BLUE_UINT32)((unsigned int)rp188_timecode.struct_ltc.ten_frame*10)+(unsigned int)rp188_timecode.struct_ltc.unit_frame;                \r
345         return rp188_timecode.ltc;\r
346 }\r
347 \r
348 // Determine endianess at run-time\r
349 inline BLUE_UINT32 Int32SwapBigLittle(const BLUE_UINT32 i)\r
350 {\r
351     unsigned char c1, c2, c3, c4;\r
352         const int endian = 1;\r
353         #define is_bigendian() ( (*(char*) & endian) == 0 )\r
354 \r
355     if (is_bigendian())\r
356         {\r
357         c1 = i & 255;\r
358         c2 = (i >> 8) & 255;\r
359         c3 = (i >> 16) & 255;\r
360         c4 = (i >> 24) & 255;\r
361                 \r
362                 return ((int)c1 << 24) + ((int)c2 << 16) + ((int)c3 << 8) + c4;\r
363     }\r
364         else\r
365         {\r
366         return i;\r
367         }\r
368 }\r
369 \r
370 #ifdef _WINDOWS\r
371 #pragma pack(pop)\r
372 #endif