]> git.vomp.tv Git - vompclient.git/blob - wwss.cc
Step back a bit when going from ffwd to play
[vompclient.git] / wwss.cc
1 /*
2     Copyright 2006 Chris Tallon
3
4     This file is part of VOMP.
5
6     VOMP is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     VOMP is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with VOMP; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20
21 #include "wwss.h"
22
23 Wwss::Wwss()
24 {
25   format = Video::NTSC;
26 }
27
28 Wwss::~Wwss()
29 {
30 }
31
32 void Wwss::setFormat(UCHAR tformat)
33 {
34   format = tformat;
35 }
36
37 UINT Wwss::gcd(UINT a, UINT b)
38 {
39   UINT t;
40   while (b != 0)
41   {
42     t = b;
43     b = a % b;
44     a = t;
45   }
46   return a;
47 }
48
49 UINT Wwss::lcm(UINT a, UINT b)
50 {
51   return (a / gcd(a, b)) * b;
52 }
53
54 void Wwss::setWide(bool twide)
55 {
56   wide = twide;
57 }
58
59 void Wwss::draw()
60 {
61   if (format == Video::PAL) drawPAL();
62 //  else if (format == Video::NTSC) drawNTSC();
63 }
64
65 void Wwss::drawPAL()
66 {
67   // The aspect43 and aspect169 codes are not what they should be according to the docs, but these are what work...
68   // (1 = 111000, = 0 000111)
69   static UCHAR runIn[]     = {1,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1};                       // 29 pos 0
70   static UCHAR startCode[] = {0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,0,1,1,1,1,1};                                 // 24 pos 29
71   static UCHAR aspect43[]  = {0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,1,1,0,0,0}; // = 0001   4:3 full frame      // 24 pos 53
72   static UCHAR aspect169[] = {1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1}; // = 1110   16:9 anamorphic     // 24 pos 53
73   static UCHAR theRest[]   = {0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,                                  // 60 pos 77
74                               0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,
75                               0,0,0,1,1,1,0,0,0,1,1,1};
76   /*
77   Real PAL pixel frequency: 13.5 MHz
78   WSS element frequency: 5 MHz
79   = 2.7 pal pixels per wss element
80   * 137 wss elements = 369.9 pal pixels (total code width) (round to 370..)
81
82   There is also a 11us gap at the start of the pal raster, but since I don't really have any
83   idea where our 720 pixels start in the raster I can't calculate an offset.
84
85   PAL line 23 seems to be MVP line 6.
86   */
87
88   const UINT   Ns = 137;           // Num pix src
89   const UINT   Nd = 370;           // Num pix dst         359->395 does something. not the right thing, but something.
90   UINT         Nl = lcm(Ns, Nd);   // Num pix in lcm
91   UINT         Ss = Nl / Ns;       // Source split (how many lcm px = 1 src px)
92   UINT         Sd = Nl / Nd;       // Dst split
93   UCHAR src[Ns];
94
95   memcpy(&src[0], runIn, 29);
96   memcpy(&src[29], startCode, 24);
97   if (wide) memcpy(&src[53], aspect169, 24);
98   else      memcpy(&src[53], aspect43, 24);
99   memcpy(&src[77], theRest, 60);
100
101   float dst[Nd];
102   UINT lcmpxbase = 0;
103
104   for(UINT t = 0; t < Nd; t++) // for every destination pixel
105   {
106     dst[t] = 0;
107     for(UINT lcmpx = lcmpxbase; lcmpx < (lcmpxbase + Sd); lcmpx++)
108     {
109       if (src[lcmpx / Ss]) dst[t] += (float)1/Sd;
110     }
111     lcmpxbase += Sd;
112   }
113
114   Colour c;
115   UINT value;
116
117   for(UINT q = 0; q < Nd; q++)
118   {
119     value = (UINT)(dst[q] * 182); // Apparently this is a better number than 255 for the colour value
120     c.set(value, value, value);
121     drawPixel(q, 6, c);
122   }
123 }
124
125 void Wwss::drawNTSC()
126 {
127 /*
128   static UCHAR startCode[] = {1,0,0,0,0,0,0};
129   static UCHAR aspect43[]  = {0};
130   static UCHAR aspect169[] = {1};
131   static UCHAR theRest[]   = {0,0,0,0,0,0,0,0};
132   static UCHAR crc43[]     = {0,0,0,0,0,0};
133   static UCHAR crc169[]    = {0,0,1,1,0,0};
134 */
135   /*
136   Real NTSC pixel frequency: 13.5 MHz
137   WSS bit frequency: 447.443125 kHz
138   = 30.1714 NTSC pixels per wss bit
139   * 22 wss bits = 663.7715 NTSC pixels (total code width) (round to 664..)
140
141   There is also a 11.2us gap at the start of the pal raster, but since I don't really have any
142   idea where our 720 pixels start in the raster I can't calculate an offset.
143
144   PAL line 23 seems to be MVP line 6.
145   */
146
147   const UINT   Ns = 22;            // Num pix src
148   const UINT   Nd = 664;           // Num pix dst
149 //  const UINT   Nd = 518;           // Num pix dst
150   UINT         Nl = lcm(Ns, Nd);   // Num pix in lcm
151   UINT         Ss = Nl / Ns;       // Source split (how many lcm px = 1 src px)
152   UINT         Sd = Nl / Nd;       // Dst split
153 //  UCHAR src[Ns];
154
155 /*
156   memcpy(&src[0], startCode, 7);
157   if (wide) memcpy(&src[7], aspect169, 1);
158   else      memcpy(&src[7], aspect43, 1);
159   memcpy(&src[8], theRest, 8);
160   if (wide) memcpy(&src[16], crc169, 6);
161   else      memcpy(&src[16], crc43, 6);
162 */
163
164 static UCHAR src[22] = {1,0, 0,0,0,0,1,1, 0,0,0,0, 0,0,0,0, 0,0,1,0,0,1 };
165
166
167   float dst[Nd];
168   UINT lcmpxbase = 0;
169
170   for(UINT t = 0; t < Nd; t++) // for every destination pixel
171   {
172     dst[t] = 0;
173     for(UINT lcmpx = lcmpxbase; lcmpx < (lcmpxbase + Sd); lcmpx++)
174     {
175       if (src[lcmpx / Ss]) dst[t] += (float)1/Sd;
176     }
177     lcmpxbase += Sd;
178   }
179
180   Colour c;
181   UINT value;
182
183 // This one is the real one
184 /*
185   for(UINT q = 0; q < Nd; q++)
186   {
187     value = (UINT)(dst[q] * 182); // Apparently this is a better number than 255 for the colour value
188     c.set(value, value, value);
189     drawPixel(q, 6, c);
190   }
191 */
192
193 // This one is testing active
194 for(int yy = 0; yy < 100; yy++)
195 {
196   for(UINT q = 0; q < Nd; q++)
197   {
198     value = (UINT)(dst[q] * 182); // Apparently this is a better number than 255 for the colour value
199     c.set(value, value, value);
200     drawPixel(q+0, yy, c);
201   }
202 }
203
204
205
206 }
207
208 /*
209 x6 + x + 1
210
211 1x6 + 0x5 + 0x4 + 0x3 + 0x2 + 1x1 + 1x0
212 =
213 1      0     0     0     0     1     1
214 =
215 1000011
216 key width = 6
217
218 static UCHAR startCode[] = {1,0};
219 static UCHAR aspect43[]  = {0,0};
220 static UCHAR aspect169[] = {1,0};
221 static UCHAR theRest[]   = {0,0,0,0,0,0,0,0,0,0,0,0};
222 static UCHAR crc43[]     = {0,0,0,0,0,0};
223 static UCHAR crc169[]    = {0,0,1,0,0,1};
224
225 Message 4:3
226
227 1000000000000000
228
229 Message 4:3 augmented
230
231 1000000000000000000000
232
233 Key
234
235 1000011
236
237
238 Ho ho, polynomial long division. Yeeeeaaahhh I remember
239 doing *that*. Of course I do. If you know of a faster,
240 easier, more reliable way of doing this, please let me know.
241
242
243                  100
244          ________________________
245 1000011  ) 1000000000000000000000
246            1000011
247            -------
248             0000110
249             0000000
250             -------
251              0001100
252
253
254
255
256
257
258 Message 16:9
259
260 1010000000000000
261
262 Message 4:3 augmented
263
264 1010000000000000000000
265
266 Key
267
268 1000011
269
270                  1010011110100011
271          ________________________
272 1000011  ) 1010000000000000000000
273            1000011
274             -------
275             0100110
276             0000000
277              -------
278              1001100
279              1000011
280               -------
281               0011110
282               0000000
283                -------
284                0111100
285                0000000
286                 -------
287                 1111000
288                 1000011
289                  -------
290                  1110110
291                  1000011
292                   -------
293                   1101010
294                   1000011
295                    -------
296                    1010010
297                    1000011
298                     -------
299                     0100010
300                     0000000
301                      -------
302                      1000100
303                      1000011
304                       -------
305                       0001110
306                       0000000
307                        -------
308                        0011100
309                        0000000
310                         -------
311                         0111000
312                         0000000
313                          -------
314                          1110000
315                          1000011
316                           -------
317                           1100110
318                           1000011
319                           -------
320                            100101
321 */