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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1447 by dbug, Thu Oct 22 19:33:01 2015 UTC revision 1448 by dbug, Sat Mar 17 09:36:01 2018 UTC
# Line 17  Line 17 
17    
18  /*  /*
19  bug: having the output (your 0-255) in 0 <= y <= 1 gives "x = 15-2*(log10(1/y)/log10(2))"  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  <_Stefan> x is the psg volume from 0 to 15
21  */  */
22    
23  unsigned char SampleToVolume(unsigned char sample)  unsigned char SampleToVolume(unsigned char sample)
24  {  {
25          if (!sample)    if (!sample)
26          {    {
27                  // To avoid a divide by 0      // To avoid a divide by 0
28                  return 0;      return 0;
29          }    }
30          else    else
31          {    {
32                  double y=(double)sample;      double y=(double)sample;
33                  y=y/255.0;      y=y/255.0;
34    
35                  double x;      double x;
36                  x = 15.0-2.0*(log10(1.0/y)/log10(2.0));      x = 15.0-2.0*(log10(1.0/y)/log10(2.0));
37    
38                  if (x<0.0)      if (x<0.0)
39                  {      {
40                          x=0.0;        x=0.0;
41                  }      }
42                  else      else
43                  if (x>15.0)        if (x>15.0)
44                  {        {
45                          x=15.0;          x=15.0;
46                  }        }
47                  return (unsigned char)x;        return (unsigned char)x;
48          }    }
49  }  }
50    
51    
52    
53  bool LoadFile(const char *ptr_filename,unsigned char *&ptr_buffer,int &size)  bool LoadFile(const char *ptr_filename,unsigned char *&ptr_buffer,int &size)
54  {  {
55          struct _finddata_t      file_info_src;    struct _finddata_t    file_info_src;
56          int     result;    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          result=_findfirst(ptr_filename,&file_info_src);    if (!(handle=_open(ptr_filename,_O_RDONLY|_O_BINARY)))
74          if (result==-1.L)    {
75          {      return false;
76                  return false;    }
77          }    size_read=_read(handle,ptr_buffer,size);
78          _findclose(result);    _close(handle);
79    
80      if (size!=size_read)
81          size=file_info_src.size;    {
82        // Read error
83          ptr_buffer=new unsigned char[size];      return false;
84      }
         long handle;  
         long size_read;  
   
         if (!(handle=_open(ptr_filename,_O_RDONLY|_O_BINARY)))  
         {  
                 return false;  
         }  
         size_read=_read(handle,ptr_buffer,size);  
         _close(handle);  
   
         if (size!=size_read)  
         {  
                 // Read error  
                 return false;  
         }  
85    
86          return true;    return true;
87  }  }
88    
89    
90    
91  bool SaveFile(const char *ptr_filename,unsigned char *ptr_buffer,int size)  bool SaveFile(const char *ptr_filename,unsigned char *ptr_buffer,int size)
92  {  {
93          long handle;    long handle;
94    
95          if (!(handle=_open(ptr_filename,_O_TRUNC|O_BINARY|O_CREAT|O_WRONLY,_S_IREAD|_S_IWRITE )))    if (!(handle=_open(ptr_filename,_O_TRUNC|O_BINARY|O_CREAT|O_WRONLY,_S_IREAD|_S_IWRITE )))
96          {    {
97                  return false;      return false;
98          }    }
99          _write(handle,ptr_buffer,size);    _write(handle,ptr_buffer,size);
100          _close(handle);    _close(handle);
101    
102          return true;    return true;
103  }  }
104    
105    
# Line 113  bool SaveFile(const char *ptr_filename,u Line 113  bool SaveFile(const char *ptr_filename,u
113    
114  void DisplayError()  void DisplayError()
115  {  {
116          printf("\n");    printf("\n");
117          printf("\n旼컴컴컴컴컴컴컴컴컴컴컴컴컴");    printf("\n旼컴컴컴컴컴컴컴컴컴컴컴컴컴");
118          printf("\n   4bits Sample Merger     ");    printf("\n   4bits Sample Merger     ");
119          printf("\n     vers format ORIC      ");    printf("\n     vers format ORIC      ");
120          printf("\n           V0.001          ");    printf("\n           V0.001          ");
121          printf("\n (c) 2002 POINTIER Mickael ");    printf("\n (c) 2002 POINTIER Mickael ");
122          printf("\n읕컴컴컴컴컴컴컴컴컴컴컴컴컴");    printf("\n읕컴컴컴컴컴컴컴컴컴컴컴컴컴");
123          printf("\n");    printf("\n");
124          exit(1);    exit(1);
125  }  }
126    
127    
# Line 131  void DisplayError() Line 131  void DisplayError()
131    
132  bool get_switch(const char *&ptr_arg,const char *ptr_switch)  bool get_switch(const char *&ptr_arg,const char *ptr_switch)
133  {  {
134          int     lenght=strlen(ptr_switch);    int   lenght=strlen(ptr_switch);
135    
136          if (_memicmp(ptr_arg,ptr_switch,lenght))    if (_memicmp(ptr_arg,ptr_switch,lenght))
137          {    {
138                  // Not a match      // Not a match
139                  return false;      return false;
140          }    }
141          // Validate the parameter    // Validate the parameter
142          ptr_arg+=lenght;    ptr_arg+=lenght;
143          return true;    return true;
144  }  }
145    
146    
147  int get_value(const char *&ptr_arg,long default_value)  int get_value(const char *&ptr_arg,long default_value)
148  {  {
149          char    *ptr_end;    char  *ptr_end;
150          long value=strtoul(ptr_arg,&ptr_end,10);    long value=strtoul(ptr_arg,&ptr_end,10);
151          if (ptr_arg==ptr_end)    if (ptr_arg==ptr_end)
152          {    {
153                  value=default_value;      value=default_value;
154          }    }
155          ptr_arg=ptr_end;    ptr_arg=ptr_end;
156          return value;    return value;
157  }  }
158    
159    
# Line 190  void main(int argc,char *argv[]) Line 190  void main(int argc,char *argv[])
190        /*        /*
191        if (get_switch(ptr_arg,"-u"))     // UNPACK        if (get_switch(ptr_arg,"-u"))     // UNPACK
192        {        {
193        flag_pack=false;          flag_pack=false;
194        argc--;          argc--;
195        param++;          param++;
196        }        }
197        else        else
198        if (get_switch(ptr_arg,"-p"))     // PACK        if (get_switch(ptr_arg,"-p"))     // PACK
199        {        {
200        flag_pack=true;          flag_pack=true;
201        argc--;          argc--;
202        param++;          param++;
203        }        }
204        */        */
205        if (nb_arg==argc)   break;        if (nb_arg==argc)   break;
# Line 213  void main(int argc,char *argv[]) Line 213  void main(int argc,char *argv[])
213    }    }
214    
215    
216          //    //
217          // Copy last parameters    // Copy last parameters
218          //    //
219          char    source_name[_MAX_PATH];    char  source_name[_MAX_PATH];
220          char    dest_name[_MAX_PATH];    char  dest_name[_MAX_PATH];
221    
222          strncpy(source_name,argv[param],sizeof(source_name));    strncpy(source_name,argv[param],sizeof(source_name));
223          source_name[sizeof(source_name)-1]=0;    source_name[sizeof(source_name)-1]=0;
224    
225          param++;    param++;
226          strncpy(dest_name,argv[param],sizeof(dest_name));    strncpy(dest_name,argv[param],sizeof(dest_name));
227          dest_name[sizeof(dest_name)-1]=0;    dest_name[sizeof(dest_name)-1]=0;
228    
229    
230          unsigned char *ptr_buffer;    unsigned char *ptr_buffer;
231          int size_buffer_src;    int size_buffer_src;
232    
233          if (!LoadFile(source_name,ptr_buffer,size_buffer_src))    if (!LoadFile(source_name,ptr_buffer,size_buffer_src))
234          {    {
235                  printf("\nUnable to load file '%s'",source_name);      printf("\nUnable to load file '%s'",source_name);
236                  printf("\n");      printf("\n");
237                  exit(1);      exit(1);
238          }    }
239    
240          /*    /*
241          //    //
242          // Stupid Raw=>nibble conversion, no frequency change    // Stupid Raw=>nibble conversion, no frequency change
243          //    //
244          ptr_buffer_dst=new unsigned char[size_buffer_src+8];    ptr_buffer_dst=new unsigned char[size_buffer_src+8];
245          size_buffer_dst=size_buffer_src/2;    size_buffer_dst=size_buffer_src/2;
246    
247          unsigned char   b0,b1,b;    unsigned char b0,b1,b;
248          int i;    int i;
249          unsigned char   *ptr_src;    unsigned char *ptr_src;
250          unsigned char   *ptr_dst;    unsigned char *ptr_dst;
251    
252          ptr_src=ptr_buffer;    ptr_src=ptr_buffer;
253          ptr_dst=ptr_buffer_dst;    ptr_dst=ptr_buffer_dst;
254          for (i=0;i<size_buffer_dst;i++)    for (i=0;i<size_buffer_dst;i++)
255          {    {
256                  b0=*ptr_src++;      b0=*ptr_src++;
257                  b1=*ptr_src++;      b1=*ptr_src++;
258                  b=(b1&0xF0)|(b0>>4);      b=(b1&0xF0)|(b0>>4);
259                  *ptr_dst++=b;      *ptr_dst++=b;
260          }    }
261          */    */
262    
263          //    //
264          // Try to adapt the size of dest buffer based on complex calculations:    // Try to adapt the size of dest buffer based on complex calculations:
265          // Move from source frequency to dest frequency, while trying to round    // Move from source frequency to dest frequency, while trying to round
266          // on a multiple of 80 samples (or 40 bytes)    // on a multiple of 80 samples (or 40 bytes)
267          //    //
268          //size_buffer_dst=(size_buffer_src*4000)/44100; // overflow and get negative on a 581114 bytes sample...    //size_buffer_dst=(size_buffer_src*4000)/44100;       // overflow and get negative on a 581114 bytes sample...
269    
270          /*    /*
271          int delta=size_buffer_dst%80;    int delta=size_buffer_dst%80;
272          if (!delta)    if (!delta)
273          {    {
274                  // Perfectly on a 80 multiple (yoohoo)      // Perfectly on a 80 multiple (yoohoo)
275          }    }
276          else    else
277          if (delta<40)    if (delta<40)
278          {    {
279                  // Reduce the size of dest buffer      // Reduce the size of dest buffer
280                  size_buffer_dst-=delta;      size_buffer_dst-=delta;
281          }    }
282          else    else
283          {    {
284                  // Increase the size of dest buffer      // Increase the size of dest buffer
285                  size_buffer_dst-=delta;      size_buffer_dst-=delta;
286                  size_buffer_dst+=80;      size_buffer_dst+=80;
287          }    }
288          */    */
289    
290          int size_buffer_dst;    int size_buffer_dst;
291          unsigned char *ptr_buffer_dst;    unsigned char *ptr_buffer_dst;
292    
293          // 4.b 'RIFF'    // 4.b 'RIFF'
294          // 4.b size    // 4.b size
295          // 4.b 'WAVE'    // 4.b 'WAVE'
296          // 4.b 'fmt '    // 4.b 'fmt '
297  #if 0  // ATARI DELTA PACK CODE  #if 0  // ATARI DELTA PACK CODE
298          size_buffer_dst=1+(size_buffer_src/2);    size_buffer_dst=1+(size_buffer_src/2);
299          ptr_buffer_dst=new unsigned char[size_buffer_dst+1];    ptr_buffer_dst=new unsigned char[size_buffer_dst+1];
300    
301          // Stores a first byte which is the starting value,    // Stores a first byte which is the starting value,
302          // then encode each value as a 4 bit signed delta relative to the first value    // then encode each value as a 4 bit signed delta relative to the first value
303          unsigned char *ptr_src=ptr_buffer;    unsigned char *ptr_src=ptr_buffer;
304          unsigned char *ptr_dst=ptr_buffer_dst;    unsigned char *ptr_dst=ptr_buffer_dst;
305    
306          // Store first byte twice, so the delta are not on an odd address    // Store first byte twice, so the delta are not on an odd address
307          unsigned char prev=ptr_src[0];    unsigned char prev=ptr_src[0];
308          *ptr_dst++=prev;    *ptr_dst++=prev;
309    
310          bool flip=false;    bool flip=false;
311          unsigned char store=0;    unsigned char store=0;
312    
313          // Then compute the deltas, they will match the following table:    // Then compute the deltas, they will match the following table:
314          // Delta:   0  1  2  4  8 16 32 64 128 -64 -32 -16  -8  -4  -2  -1    // Delta:   0  1  2  4  8 16 32 64 128 -64 -32 -16  -8  -4  -2  -1
315          // Code:   $0 $1 $2 $3 $4 $5 $6 $7  $8  $9  $A  $B  $C  $D  $E  $F    // Code:   $0 $1 $2 $3 $4 $5 $6 $7  $8  $9  $A  $B  $C  $D  $E  $F
316          char delta_table[16]=    char delta_table[16]=
317          {    {
318                  -64,      -64,
319                  -32,      -32,
320                  -16,      -16,
321                  -8,      -8,
322                  -4,      -4,
323                  -2,      -2,
324                  -1,      -1,
325                  0,      0,
326                  1,      1,
327                  2,      2,
328                  4,      4,
329                  8,      8,
330                  16,      16,
331                  32,      32,
332                  64,      64,
333                  127      127
334          };    };
335    
336          int delta_usage[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};    int delta_usage[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
   
   
         for (int i=1;i<size_buffer_src;i++)  
         {  
                 unsigned char delta_index;  
   
                 unsigned char next=ptr_src[i];  
   
                 int max_error=999;  
                 delta_index=0;  
                 for (int delta_entry=0;delta_entry<16;delta_entry++)  
                 {  
                         unsigned char new_next=prev+delta_table[delta_entry];  
                         int error=next-new_next;  
                         if (error<0)  
                         {  
                                 error=-error;  
                         }  
                         /*  
                         if (error>127)  
                         {  
                                 __asm int 3  
                         }  
                         */  
                         if (error<max_error)  
                         {  
                                 max_error=error;  
                                 delta_index=delta_entry;  
                                 if (max_error==0)  
                                 {  
                                         // Can't do better than no error  
                                         break;  
                                 }  
                         }  
                 }  
   
                 unsigned char delta_value=delta_table[delta_index];  
                 delta_usage[delta_index]++;  
                 prev+=delta_value;  
   
                 store<<=4;  
                 store|=delta_index;  
                 flip=!flip;  
                 if (!flip)  
                 {  
                         *ptr_dst++=store;  
                 }  
         }  
337    
 #else   // ORIC 4BIT CODE  
         size_buffer_dst=(size_buffer_src/2)+1;                  // +1 for the 00 final  
         ptr_buffer_dst=new unsigned char[size_buffer_dst];  
338    
339          // ln(1)  -> 0    for (int i=1;i<size_buffer_src;i++)
340          // ln(2)  -> 0.6931    {
341          // ln(16) -> 2.77      unsigned char delta_index;
342    
343          // log(1)=0      unsigned char next=ptr_src[i];
344          // log(16)=1.204  
345          // 1/log(16)= 0.830482      int max_error=999;
346          // ACHANGERDESUITE      delta_index=0;
347        for (int delta_entry=0;delta_entry<16;delta_entry++)
348        {
349          // Volume levels        unsigned char new_next=prev+delta_table[delta_entry];
350          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};        int error=next-new_next;
351          if (error<0)
352          // Create a log table        {
353          // 15 -> 1.0    -> 255          error=-error;
354          // 14 -> 0.707  -> 180,285        }
355          // 13 -> 0.5    -> 128        /*
356          // 12 -> 0.303  ->  77,265        if (error>127)
357          // 11 -> 0.25   ->  63,75        {
358          // 10 -> 0.1515 ->  38,6325        __asm int 3
359          //  9 -> 0.125  ->  31,875        }
360          //  8 -> ?        */
361          //  7 -> 0,0625    -> 15,9375        if (error<max_error)
362          //  6 -> ?        {
363          //  5 -> 0,03125   -> 7,96875          max_error=error;
364          //  4 -> ?          delta_index=delta_entry;
365          //  3 -> 0,015625  -> 3,984375          if (max_error==0)
         //  2 -> ?  
         //  1 -> 0,0078125 -> 1,9921875  
         //  0 -> 0  
         unsigned char logVolume[256];  
         int vol=0;  
         for (int i=0;i<16;i++)  
366          {          {
367            int maxvol=voltab[i];            // Can't do better than no error
368            while (vol<=maxvol)            break;
           {  
             logVolume[vol]=i;  
             vol++;  
           }  
369          }          }
370          }
371        }
372    
373        unsigned char delta_value=delta_table[delta_index];
374        delta_usage[delta_index]++;
375        prev+=delta_value;
376    
377        store<<=4;
378        store|=delta_index;
379        flip=!flip;
380        if (!flip)
381        {
382          *ptr_dst++=store;
383        }
384      }
385    
386    #else   // ORIC 4BIT CODE
387      size_buffer_dst=(size_buffer_src/2)+1;                  // +1 for the 00 final
388      ptr_buffer_dst=new unsigned char[size_buffer_dst];
389    
390          // Convert to 4 bit sample,    // ln(1)  -> 0
391          // each byte contains to sample values; one per nibble    // ln(2)  -> 0.6931
392          unsigned char *ptr_src=ptr_buffer;    // ln(16) -> 2.77
393          unsigned char *ptr_dst=ptr_buffer_dst;  
394          for (int i=0;i<(size_buffer_dst-1);i++)    // log(1)=0
395          {    // log(16)=1.204
396      // 1/log(16)= 0.830482
397      // ACHANGERDESUITE
398    
399    
400      // Volume levels
401      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};
402    
403      // Create a log table
404      // 15 -> 1.0    -> 255
405      // 14 -> 0.707  -> 180,285
406      // 13 -> 0.5    -> 128
407      // 12 -> 0.303  ->  77,265
408      // 11 -> 0.25   ->  63,75
409      // 10 -> 0.1515 ->  38,6325
410      //  9 -> 0.125  ->  31,875
411      //  8 -> ?
412      //  7 -> 0,0625    -> 15,9375
413      //  6 -> ?
414      //  5 -> 0,03125   -> 7,96875
415      //  4 -> ?
416      //  3 -> 0,015625  -> 3,984375
417      //  2 -> ?
418      //  1 -> 0,0078125 -> 1,9921875
419      //  0 -> 0
420      unsigned char logVolume[256];
421      int vol=0;
422      for (int i=0;i<16;i++)
423      {
424        int maxvol=voltab[i];
425        while (vol<=maxvol)
426        {
427          logVolume[vol]=i;
428          vol++;
429        }
430      }
431    
432      // Convert to 4 bit sample,
433      // each byte contains to sample values; one per nibble
434      unsigned char *ptr_src=ptr_buffer;
435      unsigned char *ptr_dst=ptr_buffer_dst;
436      for (int i=0;i<(size_buffer_dst-1);i++)
437      {
438  #if 1  #if 1
439            // Log conversion      // Log conversion
440            unsigned char b0=*ptr_src++;      unsigned char b0=*ptr_src++;
441            b0=logVolume[b0]; //>>4;      b0=logVolume[b0]; //>>4;
442    
443            unsigned char b1=*ptr_src++;      unsigned char b1=*ptr_src++;
444            b1=logVolume[b1]; //>>4;      b1=logVolume[b1]; //>>4;
445            unsigned char b=(b1<<4)|(b0);      unsigned char b=(b1<<4)|(b0);
446  #else  #else
447            /*      /*
448            // Raw conversion      // Raw conversion
449            unsigned char b0=*ptr_src++;      unsigned char b0=*ptr_src++;
450            b0=(((unsigned int)b0)*15)/255;      b0=(((unsigned int)b0)*15)/255;
451    
452            unsigned char b1=*ptr_src++;      unsigned char b1=*ptr_src++;
453            b1=(((unsigned int)b1)*15)/255;      b1=(((unsigned int)b1)*15)/255;
454    
455            unsigned char b=(b1<<4)|(b0);      unsigned char b=(b1<<4)|(b0);
456            */      */
457            // Error based conversion      // Error based conversion
458            unsigned char b0=*ptr_src++;      unsigned char b0=*ptr_src++;
459            b0=(((unsigned int)b0)*15)/255;      b0=(((unsigned int)b0)*15)/255;
460    
461            unsigned char b1=*ptr_src++;      unsigned char b1=*ptr_src++;
462            b1=(((unsigned int)b1)*15)/255;      b1=(((unsigned int)b1)*15)/255;
463    
464            unsigned char b=(b1<<4)|(b0);      unsigned char b=(b1<<4)|(b0);
465  #endif  #endif
466    
467                  if (!b)      if (!b)
468                  {      {
469                    // To avoid a spurious null terminator        // To avoid a spurious null terminator
470                    //b=1;        //b=1;
471                  }      }
472                  *ptr_dst++=b;      *ptr_dst++=b;
473          }    }
474          // Null terminator    // Null terminator
475          *ptr_dst++=0;    *ptr_dst++=0;
476  #endif  #endif
477    
478  #if 0  #if 0
479          // Depack and save in the source file :p    // Depack and save in the source file :p
480          ptr_src=ptr_buffer_dst;    ptr_src=ptr_buffer_dst;
481          ptr_dst=ptr_buffer;    ptr_dst=ptr_buffer;
482    
483          // Store first byte    // Store first byte
484          prev=ptr_src[0];    prev=ptr_src[0];
485          *ptr_dst++=prev;    *ptr_dst++=prev;
486    
487          for (int i=1;i<size_buffer_dst;i++)    for (int i=1;i<size_buffer_dst;i++)
488          {    {
489                  unsigned char store=ptr_src[i];      unsigned char store=ptr_src[i];
490                  unsigned char b1=(store&15);      unsigned char b1=(store&15);
491                  unsigned char b0=((store>>4)&15);      unsigned char b0=((store>>4)&15);
492    
493                  prev+=delta_table[b0];      prev+=delta_table[b0];
494                  *ptr_dst++=prev;      *ptr_dst++=prev;
495    
496                  prev+=delta_table[b1];      prev+=delta_table[b1];
497                  *ptr_dst++=prev;      *ptr_dst++=prev;
498          }    }
499    
500          if (!SaveFile(dest_name,ptr_buffer,size_buffer_src))    if (!SaveFile(dest_name,ptr_buffer,size_buffer_src))
501          {    {
502                  printf("\nUnable to save file '%s'",source_name);      printf("\nUnable to save file '%s'",source_name);
503                  printf("\n");      printf("\n");
504                  exit(1);      exit(1);
505          }    }
506  #else  #else
507          // Save the resulting file    // Save the resulting file
508          if (!SaveFile(dest_name,ptr_buffer_dst,size_buffer_dst))    if (!SaveFile(dest_name,ptr_buffer_dst,size_buffer_dst))
509          {    {
510                  printf("\nUnable to save file '%s'",source_name);      printf("\nUnable to save file '%s'",source_name);
511                  printf("\n");      printf("\n");
512                  exit(1);      exit(1);
513          }    }
514  #endif  #endif
515    
516          //    //
517          // Make some cleaning    // Make some cleaning
518          //    //
519          delete[] ptr_buffer;    delete[] ptr_buffer;
520          delete[] ptr_buffer_dst;    delete[] ptr_buffer_dst;
521  }  }
522    
523    

Legend:
Removed from v.1447  
changed lines
  Added in v.1448

  ViewVC Help
Powered by ViewVC 1.1.26