1/* 2 * tv.5c 3 * 4 * Compute tv encoder subcarrier dda constants 5 * 6 * The TV encoder subcarrier must be set precisely to the 7 * required frequency or the cumulative phase errors will be 8 * quite visible in the output. To accomplish this, the TV encoder 9 * has a complex circuit that takes a fixed clock, generated by the PLL 10 * and generates a precise subcarrier clock from that using the following 11 * formula: 12 * 13 * subcarrier = pixel_clock * (S1 + (S2 + (S3/Z3)) / Z2) / 4096 14 * 15 * Careful selection of the constants will provide the necessarily 16 * precise clock. 17 * 18 * In the code below, S1 is represented by dda1, S2/Z2 by dda2 and S3/Z3 19 * by dda3. 20 */ 21 22typedef struct { 23 int step; 24 int size; 25} term_t; 26 27/* 28 * Find the approximation closest, but no larger than 'v', where 29 * 0 <= v < 1, and the result denominator must be less than 30000. 30 */ 31term_t approx (rational v) 32{ 33 rational best_dist = 1.0; 34 term_t best; 35 36 for (int den = 20000; den < 30000; den++) 37 { 38 int num = floor (v * den); 39 term_t approx = { step = num, size = den }; 40 rational dist = v - approx.step/approx.size; 41 if (dist >= 0 && dist < best_dist) 42 { 43 best_dist = dist; 44 best = approx; 45 } 46 } 47 return best; 48} 49 50typedef struct { 51 rational subcarrier; 52 rational pixel; 53 rational result; 54 term_t dda1; 55 term_t dda2; 56 term_t dda3; 57} dda; 58 59/* 60 * Compute the dda constants for the given pixel clock and 61 * desired subcarrier frequency 62 */ 63 64dda find_dda (rational pixel, rational subcarrier) 65{ 66 dda d; 67 68 d.subcarrier = subcarrier; 69 d.pixel = pixel; 70 71 rational dda1 = subcarrier / pixel * 4096; 72 d.dda1 = (term_t) { step = floor (dda1), size = 4096 }; 73 74 rational dda2 = dda1 - d.dda1.step; 75 d.dda2 = approx (dda2); 76 77 rational dda3 = dda2 * d.dda2.size - d.dda2.step; 78 d.dda3 = approx (dda3); 79 80 /* Compute the resulting pixel clock to compare */ 81 d.result = d.pixel * (d.dda1.step + 82 (d.dda2.step + d.dda3.step/d.dda3.size) / 83 d.dda2.size) / d.dda1.size; 84 return d; 85} 86 87/* 88 * Print out the computed constants 89 */ 90void print_dda (dda d) 91{ 92 printf ("\t/* desired %9.7f actual %9.7f clock %g */\n", 93 d.subcarrier, d.result, d.pixel); 94 printf ("\t.dda1_inc\t= %6d,\n", d.dda1.step); 95 printf ("\t.dda2_inc\t= %6d,\t.dda2_size\t= %6d,\n", 96 d.dda2.step, d.dda2.step != 0 ? d.dda2.size : 0); 97 printf ("\t.dda3_inc\t= %6d,\t.dda3_size\t= %6d,\n", 98 d.dda3.step, d.dda3.step != 0 ? d.dda3.size : 0); 99} 100 101/* 102 * These are all of the required subcarrier frequencies 103 */ 104rational[] subcarriers = { 105 /* these are the values we use; for some reason, this generates 106 * a more stable image (at least for NTSC) */ 107 3.580, 4.434, 3.582, 3.576, 4.430, 108 109 /* these are the values pulled out of the various specs */ 110 3.579545, 4.433618, 3.582056, 3.575611, 4.433618 111}; 112 113/* 114 * We fix the pixel clock to a value which the hardware can 115 * generate exactly 116 */ 117rational pixel = 107.520; 118 119void main () 120{ 121 for (int i = 0; i < dim(subcarriers); i++) 122 { 123 dda d = find_dda (pixel, subcarriers[i]); 124 print_dda (d); 125 } 126} 127 128main (); 129