/[projet1]/public/pc/tools/osdk/main/SampleTweaker/main.cpp
Defence Force logotype

Contents of /public/pc/tools/osdk/main/SampleTweaker/main.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 897 - (show annotations)
Sat Sep 29 15:35:48 2012 UTC (7 years, 1 month ago) by dbug
File size: 10807 byte(s)
Updated the configurations of OSDK for Visual Studio 2010
1 //
2 //
3 //
4 #define _CRT_SECURE_NO_WARNINGS
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <memory.h>
9 #include <io.h>
10 #include <string.h>
11 #include <fcntl.h>
12 #include <sys/stat.h>
13
14 #include <math.h>
15
16
17
18 /*
19 bug: having the output (your 0-255) in 0 <= y <= 1 gives "x = 15-2*(log10(1/y)/log10(2))"
20 <_Stefan> x is the psg volume from 0 to 15
21 */
22
23 unsigned char SampleToVolume(unsigned char sample)
24 {
25 if (!sample)
26 {
27 // To avoid a divide by 0
28 return 0;
29 }
30 else
31 {
32 double y=(double)sample;
33 y=y/255.0;
34
35 double x;
36 x = 15.0-2.0*(log10(1.0/y)/log10(2.0));
37
38 if (x<0.0)
39 {
40 x=0.0;
41 }
42 else
43 if (x>15.0)
44 {
45 x=15.0;
46 }
47 return (unsigned char)x;
48 }
49 }
50
51
52
53 bool LoadFile(const char *ptr_filename,unsigned char *&ptr_buffer,int &size)
54 {
55 struct _finddata_t file_info_src;
56 int result;
57
58 result=_findfirst(ptr_filename,&file_info_src);
59 if (result==-1.L)
60 {
61 return false;
62 }
63 _findclose(result);
64
65
66 size=file_info_src.size;
67
68 ptr_buffer=new unsigned char[size];
69
70 long handle;
71 long size_read;
72
73 if (!(handle=_open(ptr_filename,_O_RDONLY|_O_BINARY)))
74 {
75 return false;
76 }
77 size_read=_read(handle,ptr_buffer,size);
78 _close(handle);
79
80 if (size!=size_read)
81 {
82 // Read error
83 return false;
84 }
85
86 return true;
87 }
88
89
90
91 bool SaveFile(const char *ptr_filename,unsigned char *ptr_buffer,int size)
92 {
93 long handle;
94
95 if (!(handle=_open(ptr_filename,_O_TRUNC|O_BINARY|O_CREAT|O_WRONLY,_S_IREAD|_S_IWRITE )))
96 {
97 return false;
98 }
99 _write(handle,ptr_buffer,size);
100 _close(handle);
101
102 return true;
103 }
104
105
106
107
108
109 // Usage:
110 // FilePack <source_file> <dest_file>
111 //
112
113
114 void DisplayError()
115 {
116 printf("\n");
117 printf("\nÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿");
118 printf("\n³ 4bits Sample Merger ³");
119 printf("\n³ vers format ORIC ³");
120 printf("\n³ V0.001 ³");
121 printf("\n³ (c) 2002 POINTIER Mickael ³");
122 printf("\nÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ");
123 printf("\n");
124 exit(1);
125 }
126
127
128
129 #define NB_ARG 2
130
131
132 bool get_switch(const char *&ptr_arg,const char *ptr_switch)
133 {
134 int lenght=strlen(ptr_switch);
135
136 if (_memicmp(ptr_arg,ptr_switch,lenght))
137 {
138 // Not a match
139 return false;
140 }
141 // Validate the parameter
142 ptr_arg+=lenght;
143 return true;
144 }
145
146
147 int get_value(const char *&ptr_arg,long default_value)
148 {
149 char *ptr_end;
150 long value=strtoul(ptr_arg,&ptr_end,10);
151 if (ptr_arg==ptr_end)
152 {
153 value=default_value;
154 }
155 ptr_arg=ptr_end;
156 return value;
157 }
158
159
160 // Calculates log2 of number.
161 // http://www-crca.ucsd.edu/~msp/techniques/v0.08/book-html/node8.html
162 // http://poi.ribbon.free.fr/tmp/freq2regs.htm
163 // http://logbase2.blogspot.com/2007/12/log-base-2.html
164 //
165 // log2(1)=0
166 // log2(2)=1
167 // log2(4)=2
168 // log2(8)=4
169 float log2( double n )
170 {
171 // log(n)/log(2) is log2.
172 return (float)(log( n ) / log( 2.0 ));
173 }
174
175
176 void main(int argc,char *argv[])
177 {
178 long param;
179 long nb_arg;
180
181 bool flag_pack=true;
182 param=1;
183
184 if (argc>1)
185 {
186 for (;;)
187 {
188 nb_arg=argc;
189 const char *ptr_arg=argv[param];
190 /*
191 if (get_switch(ptr_arg,"-u")) // UNPACK
192 {
193 flag_pack=false;
194 argc--;
195 param++;
196 }
197 else
198 if (get_switch(ptr_arg,"-p")) // PACK
199 {
200 flag_pack=true;
201 argc--;
202 param++;
203 }
204 */
205 if (nb_arg==argc) break;
206 }
207 }
208
209
210 if (argc!=(NB_ARG+1))
211 {
212 DisplayError();
213 }
214
215
216 //
217 // Copy last parameters
218 //
219 char source_name[_MAX_PATH];
220 char dest_name[_MAX_PATH];
221
222 strcpy(source_name,argv[param]);
223 param++;
224 strcpy(dest_name,argv[param]);
225
226
227 unsigned char *ptr_buffer;
228 int size_buffer_src;
229
230 if (!LoadFile(source_name,ptr_buffer,size_buffer_src))
231 {
232 printf("\nUnable to load file '%s'",source_name);
233 printf("\n");
234 exit(1);
235 }
236
237 /*
238 //
239 // Stupid Raw=>nibble conversion, no frequency change
240 //
241 ptr_buffer_dst=new unsigned char[size_buffer_src+8];
242 size_buffer_dst=size_buffer_src/2;
243
244 unsigned char b0,b1,b;
245 int i;
246 unsigned char *ptr_src;
247 unsigned char *ptr_dst;
248
249 ptr_src=ptr_buffer;
250 ptr_dst=ptr_buffer_dst;
251 for (i=0;i<size_buffer_dst;i++)
252 {
253 b0=*ptr_src++;
254 b1=*ptr_src++;
255 b=(b1&0xF0)|(b0>>4);
256 *ptr_dst++=b;
257 }
258 */
259
260 //
261 // Try to adapt the size of dest buffer based on complex calculations:
262 // Move from source frequency to dest frequency, while trying to round
263 // on a multiple of 80 samples (or 40 bytes)
264 //
265 //size_buffer_dst=(size_buffer_src*4000)/44100; // overflow and get negative on a 581114 bytes sample...
266
267 /*
268 int delta=size_buffer_dst%80;
269 if (!delta)
270 {
271 // Perfectly on a 80 multiple (yoohoo)
272 }
273 else
274 if (delta<40)
275 {
276 // Reduce the size of dest buffer
277 size_buffer_dst-=delta;
278 }
279 else
280 {
281 // Increase the size of dest buffer
282 size_buffer_dst-=delta;
283 size_buffer_dst+=80;
284 }
285 */
286
287 int size_buffer_dst;
288 unsigned char *ptr_buffer_dst;
289
290 // 4.b 'RIFF'
291 // 4.b size
292 // 4.b 'WAVE'
293 // 4.b 'fmt '
294 #if 0 // ATARI DELTA PACK CODE
295 size_buffer_dst=1+(size_buffer_src/2);
296 ptr_buffer_dst=new unsigned char[size_buffer_dst+1];
297
298 // Stores a first byte which is the starting value,
299 // then encode each value as a 4 bit signed delta relative to the first value
300 unsigned char *ptr_src=ptr_buffer;
301 unsigned char *ptr_dst=ptr_buffer_dst;
302
303 // Store first byte twice, so the delta are not on an odd address
304 unsigned char prev=ptr_src[0];
305 *ptr_dst++=prev;
306
307 bool flip=false;
308 unsigned char store=0;
309
310 // Then compute the deltas, they will match the following table:
311 // Delta: 0 1 2 4 8 16 32 64 128 -64 -32 -16 -8 -4 -2 -1
312 // Code: $0 $1 $2 $3 $4 $5 $6 $7 $8 $9 $A $B $C $D $E $F
313 char delta_table[16]=
314 {
315 -64,
316 -32,
317 -16,
318 -8,
319 -4,
320 -2,
321 -1,
322 0,
323 1,
324 2,
325 4,
326 8,
327 16,
328 32,
329 64,
330 127
331 };
332
333 int delta_usage[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
334
335
336 for (int i=1;i<size_buffer_src;i++)
337 {
338 unsigned char delta_index;
339
340 unsigned char next=ptr_src[i];
341
342 int max_error=999;
343 delta_index=0;
344 for (int delta_entry=0;delta_entry<16;delta_entry++)
345 {
346 unsigned char new_next=prev+delta_table[delta_entry];
347 int error=next-new_next;
348 if (error<0)
349 {
350 error=-error;
351 }
352 /*
353 if (error>127)
354 {
355 __asm int 3
356 }
357 */
358 if (error<max_error)
359 {
360 max_error=error;
361 delta_index=delta_entry;
362 if (max_error==0)
363 {
364 // Can't do better than no error
365 break;
366 }
367 }
368 }
369
370 unsigned char delta_value=delta_table[delta_index];
371 delta_usage[delta_index]++;
372 prev+=delta_value;
373
374 store<<=4;
375 store|=delta_index;
376 flip=!flip;
377 if (!flip)
378 {
379 *ptr_dst++=store;
380 }
381 }
382
383 #else // ORIC 4BIT CODE
384 size_buffer_dst=(size_buffer_src/2)+1; // +1 for the 00 final
385 ptr_buffer_dst=new unsigned char[size_buffer_dst];
386
387 // ln(1) -> 0
388 // ln(2) -> 0.6931
389 // ln(16) -> 2.77
390
391 // log(1)=0
392 // log(16)=1.204
393 // 1/log(16)= 0.830482
394 // ACHANGERDESUITE
395
396
397 // Volume levels
398 int voltab[] = { 0, 513/257, 828/257, 1239/257, 1923/257, 3238/257, 4926/257, 9110/257, 10344/257, 17876/257, 24682/257, 30442/257, 38844/257, 47270/257, 56402/257, 65535/257};
399
400 // Create a log table
401 // 15 -> 1.0 -> 255
402 // 14 -> 0.707 -> 180,285
403 // 13 -> 0.5 -> 128
404 // 12 -> 0.303 -> 77,265
405 // 11 -> 0.25 -> 63,75
406 // 10 -> 0.1515 -> 38,6325
407 // 9 -> 0.125 -> 31,875
408 // 8 -> ?
409 // 7 -> 0,0625 -> 15,9375
410 // 6 -> ?
411 // 5 -> 0,03125 -> 7,96875
412 // 4 -> ?
413 // 3 -> 0,015625 -> 3,984375
414 // 2 -> ?
415 // 1 -> 0,0078125 -> 1,9921875
416 // 0 -> 0
417 unsigned char logVolume[256];
418 int vol=0;
419 for (int i=0;i<16;i++)
420 {
421 int maxvol=voltab[i];
422 while (vol<=maxvol)
423 {
424 logVolume[vol]=i;
425 vol++;
426 }
427 }
428
429 // Convert to 4 bit sample,
430 // each byte contains to sample values; one per nibble
431 unsigned char *ptr_src=ptr_buffer;
432 unsigned char *ptr_dst=ptr_buffer_dst;
433 for (int i=0;i<(size_buffer_dst-1);i++)
434 {
435 unsigned char b0=*ptr_src++;
436 b0=logVolume[b0]; //>>4;
437
438 unsigned char b1=*ptr_src++;
439 b1=logVolume[b1]; //>>4;
440
441 unsigned char b=(b1<<4)|(b0);
442 if (!b)
443 {
444 // To avoid a spurious null terminator
445 b=1;
446 }
447 *ptr_dst++=b;
448 }
449 // Null terminator
450 *ptr_dst++=0;
451 #endif
452
453 #if 0
454 // Depack and save in the source file :p
455 ptr_src=ptr_buffer_dst;
456 ptr_dst=ptr_buffer;
457
458 // Store first byte
459 prev=ptr_src[0];
460 *ptr_dst++=prev;
461
462 for (int i=1;i<size_buffer_dst;i++)
463 {
464 unsigned char store=ptr_src[i];
465 unsigned char b1=(store&15);
466 unsigned char b0=((store>>4)&15);
467
468 prev+=delta_table[b0];
469 *ptr_dst++=prev;
470
471 prev+=delta_table[b1];
472 *ptr_dst++=prev;
473 }
474
475 if (!SaveFile(dest_name,ptr_buffer,size_buffer_src))
476 {
477 printf("\nUnable to save file '%s'",source_name);
478 printf("\n");
479 exit(1);
480 }
481 #else
482 // Save the resulting file
483 if (!SaveFile(dest_name,ptr_buffer_dst,size_buffer_dst))
484 {
485 printf("\nUnable to save file '%s'",source_name);
486 printf("\n");
487 exit(1);
488 }
489 #endif
490
491 //
492 // Make some cleaning
493 //
494 delete[] ptr_buffer;
495 delete[] ptr_buffer_dst;
496 }
497
498
499 /*
500
501 15 1.0
502 14 0.707 <= 0.606 ???
503 13 0.5
504 12 0.303
505 11 0.25
506 10 0.1515
507 9 0.125
508 8 0.07575
509 7 0.0625
510 6 0.037875
511 5 0.03125
512 4 0.0189375
513 3 0.015625
514 2 0.00946875
515 1 0.0078125
516 0 0.0
517
518
519 V[13]=V[15]/2
520
521
522
523 // calculate the volume->voltage conversion table
524 // The AY-3-8910 has 16 levels, in a logarithmic scale (3dB per step)
525 // The YM2149 still has 16 levels for the tone generators, but 32 for
526 // the envelope generator (1.5dB per step).
527 for (i = 31;i > 0;i--)
528 {
529 // limit volume to avoid clipping
530 if (out > MAX_OUTPUT) PSG->VolTable[i] = MAX_OUTPUT;
531 else PSG->VolTable[i] = (unsigned int)out;
532
533 if (AY_filetype==0)
534 out = out - (MAX_OUTPUT / 32);
535 else
536 out /= 1.188502227; // = 10 ^ (1.5/20) = 1.5dB
537 }
538
539
540
541 Volume Dac output Volume Raw Corrected
542 Corrected
543
544 15 1.0 15.0 255 255
545 14 0.707 12.62 238
546 13 0.5 10.61 221
547 12 0.303 8.93 204
548 11 0.25 7.51 187
549 10 0.1515 6.32 170
550 9 0.125 5.32 153
551 8 0.07575 4.47 136
552 7 0.0625 3.76 119
553 6 0.037875 3.17 102
554 5 0.03125 2.66 85
555 4 0.0189375 2.244 68
556 3 0.015625 1.888 51
557 2 0.00946875 1.58 34
558 1 0.0078125 1.33 17
559 0 0.0 0.0 0 0
560
561 */

  ViewVC Help
Powered by ViewVC 1.1.26