Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 #include <math.h>
  2 
  3 #define AMP 110
  4 #define DC 60
  5 
  6 static vbi_raw_decoder sim;
  7 static double sim_time;
  8 
  9 static inline double
 10 shape(double ph)
 11 {
 12         double x = sin(ph);
 13 
 14         return x * x;
 15 }
 16 
 17 /*
 18  *  Closed Caption Signal Simulator
 19  */
 20 
 21 static inline double
 22 cc_sim(double t, double F, unsigned char b1, unsigned char b2)
 23 {
 24         int bits = (b2 << 10) + (b1 << 2) + 2; /* start bit 0 -> 1 */
 25         double t1 = 10.5e-6 - .25 / F;
 26         double t2 = t1 + 7 / F;         /* CRI 7 cycles */
 27         double t3 = t2 + 1.5 / F;
 28         double t4 = t3 + 18 / F;        /* 17 bits + raise and fall time */
 29         double ph;
 30 
 31         if (t < t1) {
 32                 return 0.0;
 33         } else if (t < t2) {
 34                 t -= t2;
 35                 ph = M_PI * 2 * t * F - (M_PI * .5);
 36                 return sin(ph) / 2 + .5;
 37         } else if (t < t3) {
 38                 return 0.0;
 39         } else if (t < t4) {
 40                 int i, n;
 41 
 42                 t -= t3;
 43                 i = (t * F - .0);
 44                 n = (bits >> i) & 3; /* low = 0, up, down, high */
 45                 if (n == 0)
 46                         return 0.0;
 47                 else if (n == 3)
 48                         return 1.0;
 49 
 50                 if ((n ^ i) & 1) /* down */
 51                         ph = M_PI * 2 * (t - 1 / F) * F / 4;
 52                 else /* up */
 53                         ph = M_PI * 2 * (t - 0 / F) * F / 4;
 54 
 55                 return shape(ph);
 56         } else {
 57                 return 0.0;
 58         }
 59 }
 60 
 61 /*
 62  *  Wide Screen Signalling Simulator
 63  */
 64 
 65 static inline double
 66 wss625_sim(double t, double F, unsigned int bits)
 67 {
 68         static int twobit[] = { 0xE38, 0xE07, 0x1F8, 0x1C7 };
 69         static char frame[] =
 70                 "\0"
 71                 "\1\1\1\1\1\0\0\0\1\1\1\0\0\0"
 72                 "\1\1\1\0\0\0\1\1\1\0\0\0\1\1\1"
 73                 "\0\0\0\1\1\1\1\0\0\0\1\1\1\1\0\0\0\0\0\1\1\1\1\1"
 74                 "x";
 75         double t1 = 11.0e-6 - .5 / F;
 76         double t4 = t1 + (29 + 24 + 84) / F;
 77         double ph;
 78         int i, j, n;
 79 
 80         frame[1 + 29 + 24] = bits & 1;
 81 
 82         if (t < t1) {
 83                 return 0.0;
 84         } else if (t < t4) {
 85                 t -= t1;
 86                 i = (t * F - .0);
 87                 if (i < 29 + 24) {
 88                         n = frame[i] + 2 * frame[i + 1];
 89                 } else {
 90                         j = i - 29 - 24;
 91                         n = twobit[(bits >> (j / 6)) & 3];
 92                         n = (n >> (j % 6)) & 3;
 93                 }
 94 
 95                 /* low = 0, down, up, high */
 96                 if (n == 0)
 97                         return 0.0;
 98                 else if (n == 3)
 99                         return 1.0;
100                 if ((n ^ i) & 1) 
101                         ph = M_PI * 2 * (t - 1 / F) * F / 4;
102                 else /* down */
103                         ph = M_PI * 2 * (t - 0 / F) * F / 4;
104 
105                 return shape(ph);
106         } else {
107                 return 0.0;
108         }
109 }
110 
111 static inline double
112 wss525_sim(double t, double F, unsigned int bits)
113 {
114         double t1 = 11.2e-6 - .5 / F;
115         double t4 = t1 + (2 + 14 + 6 + 1) / F;
116         double ph;
117         int i, n;
118 
119         bits = bits * 2 + (2 << 21); /* start bits 10, stop 0 */
120 
121         if (t < t1) {
122                 return 0.0;
123         } else if (t < t4) {
124                 t -= t1;
125                 i = (t * F - .0);
126                 n = (bits >> (22 - i)) & 3; /* low = 0, up, down, high */
127 
128                 if (n == 0)
129                         return 0.0;
130                 else if (n == 3)
131                         return 1.0;
132                 if ((n ^ i) & 1) 
133                         ph = M_PI * 2 * (t - 0 / F) * F / 4;
134                 else /* down */
135                         ph = M_PI * 2 * (t - 1 / F) * F / 4;
136 
137                 return shape(ph);
138         } else
139                 return 0.0;
140 }
141 
142 /*
143  *  Teletext Signal Simulator
144  */
145 
146 static inline double
147 ttx_sim(double t, double F, const uint8_t *text)
148 {
149         double t1 = 10.3e-6 - .5 / F;
150         double t2 = t1 + (45 * 8 + 1) / F; /* 45 bytes + raise and fall time */
151         double ph;
152 
153         if (t < t1) {
154                 return 0.0;
155         } else if (t < t2) {
156                 int i, j, n;
157 
158                 t -= t1;
159                 i = (t * F);
160                 j = i >> 3;
161                 i &= 7;
162 
163                 if (j == 0)
164                         n = ((text[0] * 2) >> i) & 3;
165                 else
166                         n = (((text[j - 1] >> 7) + text[j] * 2) >> i) & 3;
167 
168                 if (n == 0) {
169                         return 0.0;
170                 } else if (n == 3) {
171                         return 1.0;
172                 } else if ((n ^ i) & 1) {
173                         ph = M_PI * 2 * (t - 1 / F) * F / 4;
174                         return shape(ph);
175                 } else { /* up */
176                         ph = M_PI * 2 * (t - 0 / F) * F / 4;
177                         return shape(ph);
178                 }
179         } else {
180                 return 0.0;
181         }
182 
183         if (t < t1) {
184                 return 0.0;
185         } else if (t < t2) {
186                 int i, j, n;
187 
188                 t -= t1;
189                 i = (t * F - .0);
190                 j = i >> 3;
191                 if (j < 44)
192                         n = ((text[j + 1] * 256 + text[j]) >> i) & 3;
193                 else
194                         n = (text[i] >> i) & 3;
195 
196                 return shape(ph);
197         }
198 }
199 
200 static unsigned int caption_i = 0;
201 static const uint8_t caption_text[] = {
202         0x14, 0x25, 0x14, 0x25, 'L', 'I', 'B', 'Z',
203         'V', 'B', 'I', ' ', 'C', 'A', 'P', 'T',
204         'I', 'O', 'N', ' ', 'S', 'I', 'M', 'U',
205         'L', 'A', 'T', 'I', 'O', 'N', 0x14, 0x2D,
206         0x14, 0x2D /* even size please, add 0 if neccessary */
207 };
208 
209 static inline int
210 odd(int c)
211 {
212         int n;
213 
214         n = c ^ (c >> 4);
215         n = n ^ (n >> 2);
216         n = n ^ (n >> 1);
217 
218         if (!(n & 1))
219                 c |= 0x80;
220 
221         return c;
222 }
223 
224 static uint8_t *
225 ttx_next(void)
226 {
227         static uint8_t s1[2][10] = {
228                 { 0x02, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15 },
229                 { 0x02, 0x15, 0x02, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15 }
230         };
231         static uint8_t s2[32] = "100\2LIBZVBI\7            00:00:00";
232         static uint8_t s3[40] = "  LIBZVBI TELETEXT SIMULATION           ";
233         static uint8_t s4[40] = "  Page 100                              ";
234         static uint8_t s5[10][42] = {
235                 { 0x02, 0x2f, 0x97, 0x20, 0x37, 0x23, 0x23, 0x23, 0x23, 0x23,
236                   0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
237                   0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
238                   0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
239                   0xb5, 0x20 },
240                 { 0xc7, 0x2f, 0x97, 0x0d, 0xb5, 0x04, 0x20, 0x9d, 0x83, 0x8c,
241                   0x08, 0x2a, 0x2a, 0x2a, 0x89, 0x20, 0x20, 0x0d, 0x54, 0x45,
242                   0xd3, 0x54, 0x20, 0xd0, 0xc1, 0xc7, 0x45, 0x8c, 0x20, 0x20,
243                   0x08, 0x2a, 0x2a, 0x2a, 0x89, 0x0d, 0x20, 0x20, 0x1c, 0x97,
244                   0xb5, 0x20 },
245                 { 0x02, 0xd0, 0x97, 0x20, 0xb5, 0x20, 0x20, 0x20, 0x20, 0x20,
246                   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
247                   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
248                   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
249                   0xea, 0x20 },
250                 { 0xc7, 0xd0, 0x97, 0x20, 0xb5, 0x20, 0x20, 0x20, 0x20, 0x20,
251                   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
252                   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
253                   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
254                   0xb5, 0x20 },
255                 { 0x02, 0xc7, 0x97, 0x20, 0xb5, 0x20, 0x20, 0x20, 0x20, 0x20,
256                   0x20, 0x15, 0x1a, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
257                   0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
258                   0x2c, 0x2c, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x97, 0x19,
259                   0xb5, 0x20 },
260                 { 0xc7, 0xc7, 0x97, 0x20, 0xb5, 0x20, 0x20, 0x20, 0x20, 0x20,
261                   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
262                   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
263                   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
264                   0xb5, 0x20 },
265                 { 0x02, 0x8c, 0x97, 0x9e, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x13,
266                   0x7f, 0x7f, 0x7f, 0x7f, 0x16, 0x7f, 0x7f, 0x7f, 0x7f, 0x92,
267                   0x7f, 0x92, 0x7f, 0x7f, 0x15, 0x7f, 0x7f, 0x15, 0x7f, 0x91,
268                   0x91, 0x7f, 0x7f, 0x91, 0x94, 0x7f, 0x94, 0x7f, 0x94, 0x97,
269                   0xb5, 0x20 },
270                 { 0xc7, 0x8c, 0x97, 0x9e, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x13,
271                   0x7f, 0x7f, 0x7f, 0x7f, 0x16, 0x7f, 0x7f, 0x7f, 0x7f, 0x92,
272                   0x7f, 0x7f, 0x7f, 0x7f, 0x15, 0x7f, 0x7f, 0x7f, 0x7f, 0x91,
273                   0x7f, 0x7f, 0x7f, 0x7f, 0x94, 0x7f, 0x7f, 0x7f, 0x7f, 0x97,
274                   0xb5, 0x20 },
275                 { 0x02, 0x9b, 0x97, 0x9e, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x13,
276                   0x7f, 0x7f, 0x7f, 0x7f, 0x16, 0x7f, 0x7f, 0x7f, 0x7f, 0x92,
277                   0x7f, 0x7f, 0x7f, 0x7f, 0x15, 0x7f, 0x7f, 0x7f, 0x7f, 0x91,
278                   0x7f, 0x7f, 0x7f, 0x7f, 0x94, 0x7f, 0x7f, 0x7f, 0x7f, 0x97,
279                   0xb5, 0x20 },
280                 { 0xc7, 0x9b, 0x97, 0x20, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
281                   0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
282                   0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
283                   0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
284                   0xa1, 0x20 }
285         };
286         static uint8_t buf[45];
287         static int row = 0, page = 0;
288         int i;
289 
290         buf[0] = 0x55;
291         buf[1] = 0x55;
292         buf[2] = 0x27;
293 
294         if (row == 0) {
295                 memcpy(buf + 3, s1[page], 10);
296                 page ^= 1;
297                 for (i = 0; i < 32; i++)
298                         buf[13 + i] = odd(s2[i]);
299         } else if (row == 1) {
300                 buf[3] = 0x02; buf[4] = 0x02;
301                 for (i = 0; i < 40; i++)
302                         buf[5 + i] = odd(s3[i]);
303         } else if (row == 2) {
304                 buf[3] = 0x02; buf[4] = 0x49;
305                 for (i = 0; i < 40; i++)
306                         buf[5 + i] = odd(s4[i]);
307         } else {
308                 memcpy(buf + 3, s5[row - 3], 42);
309         }
310 
311         if (++row >= 13) row = 0;
312 
313         return buf;
314 }
315 
316 static void
317 read_sim(uint8_t *raw_data, vbi_sliced *sliced_data,
318          int *lines, double *timestamp)
319 {
320         uint8_t *buf;
321         double start, inc;
322         int i;
323 
324         memset(raw_data, 0, (sim.count[0] + sim.count[1])
325                             * sim.bytes_per_line);
326 
327         *timestamp = sim_time;
328 
329         if (sim.scanning == 525)
330                 sim_time += 1001 / 30000.0;
331         else
332                 sim_time += 1 / 25.0;
333 
334         start = sim.offset / (double) sim.sampling_rate;
335         inc = 1 / (double) sim.sampling_rate;
336 
337         if (sim.scanning == 525) {
338                 /* Closed Caption */
339                 {
340                         buf = raw_data + (21 - sim.start[0])
341                                 * sim.bytes_per_line;
342 
343                         for (i = 0; i < sim.bytes_per_line; i++)
344                                 buf[i] = cc_sim(start + i * inc, 15734 * 32,
345                                                 odd(caption_text[caption_i]),
346                                                 odd(caption_text[caption_i + 1]))
347                                         * AMP + DC;
348 
349                         if ((caption_i += 2) > sizeof(caption_text))
350                                 caption_i = 0;
351                 }
352 
353                 /* WSS NTSC-Japan */
354                 {
355                         const int poly = (1 << 6) + (1 << 1) + 1;
356                         int b0 = 1, b1 = 1;
357                         int bits = (b0 << 13) + (b1 << 12);
358                         int crc, j;
359 
360                         crc = (((1 << 6) - 1) << (14 + 6)) + (bits << 6);
361 
362                         for (j = 14 + 6 - 1; j >= 0; j--) {
363                                 if (crc & ((1 << 6) << j))
364                                         crc ^= poly << j;
365                         }
366 
367                         bits <<= 6;
368                         bits |= crc;
369 
370                         /* fprintf(stderr, "WSS CPR << %08x\n", bits); */
371 
372                         buf = raw_data + (20 - sim.start[0])
373                                 * sim.bytes_per_line;
374 
375                         for (i = 0; i < sim.bytes_per_line; i++)
376                                 buf[i] = wss525_sim(start + i * inc,
377                                                     447443, bits)
378                                         * AMP + DC;
379                 }
380         } else {
381                 /* Closed Caption */
382                 {
383                         buf = raw_data + (22 - sim.start[0])
384                                 * sim.bytes_per_line;
385 
386                         for (i = 0; i < sim.bytes_per_line; i++)
387                                 buf[i] = cc_sim(start + i * inc, 15625 * 32,
388                                                 odd(caption_text[caption_i]),
389                                                 odd(caption_text[caption_i + 1]))
390                                         * AMP + DC;
391 
392                         if ((caption_i += 2) > sizeof(caption_text))
393                                 caption_i = 0;
394                 }
395 
396                 /* WSS PAL */
397                 {
398                         int g0 = 1, g1 = 2, g2 = 3, g3 = 4;
399                         int bits = (g3 << 11) + (g2 << 8) + (g1 << 4) + g0;
400 
401                         buf = raw_data + (23 - sim.start[0])
402                                 * sim.bytes_per_line;
403 
404                         for (i = 0; i < sim.bytes_per_line; i++)
405                                 buf[i] = wss625_sim(start + i * inc, 15625 * 320,
406                                                     bits) * AMP + DC;
407                 }
408 
409                 /* Teletext */
410                 {
411                         int line, count;
412                         uint8_t *text;
413 
414                         buf = raw_data;
415 
416                         for (line = sim.start[0], count = sim.count[0];
417                              count > 0; line++, count--, buf += sim.bytes_per_line)
418                                 if ((line >= 7 && line <= 15)
419                                     || (line >= 19 && line <= 21)) {
420                                         text = ttx_next();
421                                         for (i = 0; i < sim.bytes_per_line; i++) {
422                                                 buf[i] = ttx_sim(start + i * inc,
423                                                                  15625 * 444,
424                                                                  text) * AMP + DC;
425                                         }
426                                 }
427                         for (line = sim.start[1], count = sim.count[1];
428                              count > 0; line++, count--, buf += sim.bytes_per_line)
429                                 if ((line >= 320 && line <= 328)
430                                     || (line >= 332 && line <= 335)) {
431                                         text = ttx_next();
432                                         for (i = 0; i < sim.bytes_per_line; i++) {
433                                                 buf[i] = ttx_sim(start + i * inc,
434                                                                  15625 * 444,
435                                                                  text) * AMP + DC;
436                                         }
437                                 }
438                 }
439         }
440 
441         *lines = vbi_raw_decode(&sim, raw_data, sliced_data);
442 }
443 
444 static vbi_raw_decoder *
445 init_sim(int scanning, unsigned int services)
446 {
447         vbi_raw_decoder_init(&sim);
448 
449         sim.scanning = scanning;
450         sim.sampling_format = VBI_PIXFMT_YUV420;
451         sim.sampling_rate = 2 * 13500000;
452         sim.bytes_per_line = 1440;
453         sim.offset = 9.7e-6 * sim.sampling_rate;
454         sim.interlaced = FALSE;
455         sim.synchronous = TRUE;
456 
457         if (scanning == 525) {
458                 sim.start[0] = 10;
459                 sim.count[0] = 21 - 10 + 1;
460                 sim.start[1] = 272;
461                 sim.count[1] = 285 - 272 + 1;
462         } else if (scanning == 625) {
463                 sim.start[0] = 6;
464                 sim.count[0] = 23 - 6 + 1;
465                 sim.start[1] = 318;
466                 sim.count[1] = 335 - 318 + 1;
467         } else
468                 assert(!"invalid scanning value");
469 
470         sim_time = 0.0;
471 
472         vbi_raw_decoder_add_services(&sim, services, 0);
473 
474         return &sim;
475 }
476 
  This page was automatically generated by the LXR engine.