software tunnel rotation / lower framerate
[gbajam21] / tools / mmutil / samplefix.c
1 /****************************************************************************
2  *                                                          __              *
3  *                ____ ___  ____ __  ______ ___  ____  ____/ /              *
4  *               / __ `__ \/ __ `/ |/ / __ `__ \/ __ \/ __  /               *
5  *              / / / / / / /_/ />  </ / / / / / /_/ / /_/ /                *
6  *             /_/ /_/ /_/\__,_/_/|_/_/ /_/ /_/\____/\__,_/                 *
7  *                                                                          *
8  *         Copyright (c) 2008, Mukunda Johnson (mukunda@maxmod.org)         *
9  *                                                                          *
10  * Permission to use, copy, modify, and/or distribute this software for any *
11  * purpose with or without fee is hereby granted, provided that the above   *
12  * copyright notice and this permission notice appear in all copies.        *
13  *                                                                          *
14  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES *
15  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF         *
16  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR  *
17  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES   *
18  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN    *
19  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF  *
20  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.           *
21  ****************************************************************************/
22
23 #define MAX_UNROLL_THRESHOLD    1024    // will unroll upto 1kb more of data (when fixing NDS samples)
24 #define GBA_MIN_LOOP_SIZE 512
25
26 #include <stdlib.h>
27 #include <string.h>
28 #include <math.h>
29 #include "defs.h"
30 #include "mas.h"
31 #include "errors.h"
32 #include "systems.h"
33 #include "adpcm.h"
34
35 extern int ignore_sflags;
36
37 void Sample_PadStart( Sample* samp, u32 count )
38 {
39         // Pad beginning of sample with zero
40         u8* newdata8;
41         u16* newdata16;
42         u32 x;
43         if( count == 0 )
44                 return;         // nothing to do
45         if( samp->format & SAMPF_16BIT )
46         {
47                 newdata16 = (u16*)malloc( (samp->sample_length+count)*2 );
48                 for( x = 0; x < count; x++ )
49                         newdata16[x]=32768;
50                 for( x = 0; x < samp->sample_length; x++ )
51                         newdata16[count+x]=((u16*)samp->data)[x];
52                 free( samp->data );
53                 samp->data = (void*)newdata16;
54         }
55         else
56         {
57                 newdata8 = (u8*)malloc( (samp->sample_length+count) );
58                 for( x = 0; x < count; x++ )
59                         newdata8[x]=128;
60                 for( x = 0; x < samp->sample_length; x++ )
61                         newdata8[count+x] = ((u8*)samp->data)[x];
62                 free( samp->data );
63                 samp->data = (void*)newdata8;
64         }
65         samp->loop_start    += count;
66         samp->loop_end      += count;
67         samp->sample_length += count;
68 }
69
70 void Sample_PadEnd( Sample* samp, u32 count )
71 {
72         // Pad end of sample with zero
73         u8* newdata8;
74         u16* newdata16;
75         u32 x;
76         if( count == 0 )
77                 return;         // nothing to do
78         if( samp->format & SAMPF_16BIT )
79         {
80                 newdata16 = malloc( (samp->sample_length+count)*2 );
81                 for( x = 0; x < samp->sample_length; x++ )
82                         newdata16[x]= ((u16*)samp->data)[x];
83                 for( x = 0; x < count; x++ )
84                         newdata16[samp->sample_length+x]=32768;
85                 free( samp->data );
86                 samp->data = (void*)newdata16;
87         }
88         else
89         {
90                 newdata8 = malloc( (samp->sample_length+count) );
91                 for( x = 0; x < samp->sample_length; x++ )
92                         newdata8[x]= ((u8*)samp->data)[x];
93                 for( x = 0; x < count; x++ )
94                         newdata8[samp->sample_length+x]=128;
95                 free( samp->data );
96                 samp->data = (void*)newdata8;
97         }
98         samp->loop_end      += count;
99         samp->sample_length += count;
100 }
101
102 void Unroll_Sample_Loop( Sample* samp, u32 count )
103 {
104         // unrolls sample loop (count) times
105         // loop end MUST equal sample length
106         u8* newdata8;
107         u16* newdata16;
108         u32 newlen;
109         u32 looplen;
110         u32 x;
111         looplen = samp->loop_end-samp->loop_start;
112         newlen = samp->sample_length + looplen*count;
113         if( samp->format & SAMPF_16BIT )
114         {
115                 newdata16 = (u16*)malloc( newlen *2 );
116                 for( x = 0; x < samp->sample_length; x++ )
117                         newdata16[x] = ((u16*)samp->data)[x];
118                 for( x = 0; x < looplen*count; x++ )
119                         newdata16[samp->sample_length+x] = ((u16*)samp->data)[samp->loop_start+ (x%looplen)];
120                 free( samp->data );
121                 samp->data = (void*)newdata16;
122         }
123         else
124         {
125                 newdata8 = (u8*)malloc( newlen );
126                 for( x = 0; x < samp->sample_length; x++ )
127                         newdata8[x] = ((u8*)samp->data)[x];
128                 for( x = 0; x < looplen*count; x++ )
129                         newdata8[samp->sample_length+x] = ((u8*)samp->data)[samp->loop_start+ (x%looplen)];
130                 free( samp->data );
131                 samp->data = (void*)newdata8;
132         }
133         samp->loop_end += looplen*count;
134         samp->sample_length += looplen*count;
135 }
136
137 void Unroll_BIDI_Sample( Sample* samp )
138 {
139         // sample length MUST equal sample loop end
140         // sample MUST have loop type 2 (BIDI)
141         u8* newdata8;
142         u16* newdata16;
143         u32 newlen;
144         u32 looplen;
145         u32 x;
146
147         looplen = samp->loop_end-samp->loop_start;
148         newlen = (samp->sample_length + looplen);
149         
150         if( samp->format & SAMPF_16BIT )
151         {
152                 newdata16 = malloc( newlen *2 );
153                 for( x = 0; x < samp->sample_length; x++ )
154                         newdata16[x] = ((u16*)samp->data)[x];
155                 for( x = 0; x < looplen; x++ )
156                         newdata16[x+samp->sample_length] = ((u16*)samp->data)[samp->loop_end-1-x];
157                 free( samp->data );
158                 samp->data = (void*)newdata16;
159         }
160         else
161         {
162                 newdata8 = malloc( newlen );
163                 for( x = 0; x < samp->sample_length; x++ )
164                         newdata8[x] = ((u8*)samp->data)[x];
165                 for( x = 0; x < looplen; x++ )
166                         newdata8[x+samp->sample_length] = ((u8*)samp->data)[samp->loop_end-1-x];
167                 free( samp->data );
168                 samp->data = (void*)newdata8;
169         }
170         samp->loop_type = 1;
171         samp->sample_length += looplen;
172         samp->loop_end += looplen;
173 }
174
175 /* NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
176   The following resample routine was stolen from CHIBITRACKER (http://chibitracker.berlios.de), thanks reduz!
177  NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE */
178
179 void Resample( Sample* samp, u32 newsize )
180 {
181         // output pointers
182         u8      *dst8 =0;
183         u16     *dst16=0;
184         u8      *src8 = (u8*)samp->data;
185         u16     *src16 = (u16*)samp->data;
186         
187         int oldlength = samp->sample_length;
188         int lpoint = samp->loop_start;
189         int i;
190         
191         bool bit16 = samp->format & SAMPF_16BIT;
192         double sign_diff;
193         
194         // allocate memory
195         if( bit16 )
196         {
197                 dst16 = (u16*)malloc(newsize*2);
198                 sign_diff = 32768.0;
199         }
200         else
201         {
202                 dst8 = (u8*)malloc(newsize);
203                 sign_diff = 128.0;
204         }
205                 
206         double tscale = (double)oldlength / (double)newsize;
207         double posf;
208         
209         for( i = 0; i < newsize; i++ )
210         {
211                 posf = (double)i * tscale;
212                 int posi = (int)floor(posf);
213                 
214                 double mu = posf - (double)posi;
215                 double s0, s1, s2, s3;
216                 double mu2, a0, a1, a2, a3, res;
217                 
218                 // get previous, current, next, and after next samples
219                 if( bit16 )
220                 {
221                         s0 = (posi-1) < 0 ? 0 :         ((double)(src16[posi-1]));
222                         s1 =                                                    ((double)(src16[posi  ]));
223                         s2 = (posi+1) >= oldlength ? 
224                                                                         (samp->loop_type ? 
225                                                                                 ((double)(src16[lpoint + (posi + 1 - oldlength)])) : 0) : 
226                                                                                 ((double)(src16[posi+1]));
227                         s3 = (posi+1) >= oldlength ? 
228                                                                         (samp->loop_type ? 
229                                                                                 ((double)(src16[lpoint + (posi + 2 - oldlength)])) : 0) : 
230                                                                                 ((double)(src16[posi+2]));
231                 }
232                 else
233                 {
234                         s0 = (posi-1) < 0 ? 0 :         ((double)(src8[posi-1]));
235                         s1 =                                                    ((double)(src8[posi  ]));
236                         s2 = (posi+1) >= oldlength ? 
237                                                                         (samp->loop_type ? 
238                                                                                 ((double)(src8[lpoint + (posi + 1 - oldlength)])) : 0) : 
239                                                                                 ((double)(src8[posi+1]));
240                         s3 = (posi+1) >= oldlength ? 
241                                                                         (samp->loop_type ? 
242                                                                                 ((double)(src8[lpoint + (posi + 2 - oldlength)])) : 0) : 
243                                                                                 ((double)(src8[posi+2]));
244                 }
245                 
246                 // sign data
247                 s0 -= sign_diff;
248                 s1 -= sign_diff;
249                 s2 -= sign_diff;
250                 s3 -= sign_diff;
251                 
252                 mu2 = mu * mu;
253                 a0 = s3 - s2 - s0 + s1;
254                 a1 = s0 - s1 - a0;
255                 a2 = s2 - s0;
256                 a3 = s1;
257                 
258                 res = a0*mu*mu2 + a1*mu2 + a2*mu + a3;
259                 int resi = ((int)floor(res+0.5));
260                 
261                 if( bit16 )
262                 {
263                         if( resi < -32768 ) resi = -32768;
264                         if( resi > 32767 ) resi = 32767;
265                         dst16[i] = resi + 32768;
266                 }
267                 else
268                 {
269                         if( resi < -128 ) resi = -128;
270                         if( resi > 127 ) resi = 127;
271                         dst8[i] = resi + 128;
272                 }
273                 
274         }
275         
276         free( samp->data );
277         if( bit16 )
278                 samp->data = (void*)dst16;
279         else
280                 samp->data = (void*)dst8;
281         
282         samp->sample_length = newsize;
283         samp->loop_end = newsize;
284         samp->loop_start = (int)(((double)samp->loop_start * (double)newsize+((double)oldlength/2))/(double)oldlength);
285         samp->frequency = (int)(((double)samp->frequency * (double)newsize+((double)oldlength/2))/(double)oldlength);
286 }
287
288 void Sample_8bit( Sample* samp )
289 {
290         if( samp->format & SAMPF_16BIT )
291         {
292                 u8* newdata;
293                 u32 t;
294                 newdata = (u8*)malloc( samp->sample_length );
295                 for( t = 0; t < samp->sample_length; t++ )
296                         newdata[t] = ((u16*)samp->data)[t] / 256;
297                 free( samp->data );
298                 samp->data = newdata;
299 //              samp->bit16=false;
300                 samp->format &= ~SAMPF_16BIT;
301         }
302 }
303
304 void Sample_Sign( Sample* samp )
305 {
306         // sample must be unsigned
307         u32 x;
308         if( samp->format & SAMPF_16BIT )
309         {
310                 for( x =0 ; x < samp->sample_length; x++ )
311                 {
312                         int a =  (( (int) ((u16*)samp->data)[x] ) - 32768);
313                         if(a < -32767) a = -32767;                                              // clamp LOW to -32767 (leave space for interpolation error)
314 //                      if(a > 32765)  a = 32765;                                               // clamp HIGH to 32766
315                         ((u16*)samp->data)[x] = (u16)a ;
316                 }
317         }
318         else
319         {
320                 for( x =0 ; x < samp->sample_length; x++ )
321                 {
322                         int a =  (( (int) ((u8*)samp->data)[x] ) - 128);
323                         if( a == -128 ) a = -127;
324                         ((u8*)samp->data)[x] = (u8) a;
325                 }
326
327         }
328         samp->format |= SAMPF_SIGNED;
329 }
330
331 void FixSample_GBA( Sample* samp )
332 {
333         // convert to 8-bit if neccesary
334         Sample_8bit( samp );
335         
336         // delete data after loop_end if loop exists
337         if( samp->loop_type != 0 )
338                 samp->sample_length = samp->loop_end;
339         
340         // unroll BIDI loop
341         if( samp->loop_type == 2 )
342                 Unroll_BIDI_Sample( samp );
343
344         if( samp->loop_type )
345         {
346                 if( samp->loop_end-samp->loop_start < GBA_MIN_LOOP_SIZE )
347                 {
348                         Unroll_Sample_Loop( samp, (GBA_MIN_LOOP_SIZE / (samp->loop_end-samp->loop_start))+1 );
349                 }
350         }
351 }
352
353 int strcmpshit( char* str1, char* str2 )
354 {
355         int x=0;
356         int f=0;
357         while( str1[x] != 0 )
358         {
359                 if( str1[x] == str2[f] )f++;
360                 else                                    f=0;
361                 if( str2[f] == 0 )              return 1;
362                 x++;
363         }
364         return 0;
365 }
366
367 void FixSample_NDS( Sample* samp )
368 {
369         if( samp->sample_length == 0 )
370         {
371                 // sample has no data
372                 samp->loop_end=samp->loop_start=0;
373                 return;
374         }
375         // delete data after loop_end if loop exists
376         if( samp->loop_type != 0 )
377                 samp->sample_length = samp->loop_end;
378         
379         // unroll BIDI loop
380         if( samp->loop_type == 2 )
381                 Unroll_BIDI_Sample( samp );
382
383         // %o option
384         if( samp->loop_type )
385         {
386                 if( !ignore_sflags )
387                 {
388                         if( ((strcmpshit( samp->name, "%o"  )) > 0) )
389                         {
390                                 Unroll_Sample_Loop( samp, 1 );
391                                 samp->loop_start += (samp->loop_end-samp->loop_start) / 2;
392                         }
393                 }
394         }
395
396         if( !ignore_sflags )
397         {
398                 if( ((strcmpshit( samp->name, "%c" )) > 0) )
399                 {
400                         samp->format |= SAMPF_COMP;
401                 }
402         }
403         
404         // Resize loop
405         if( samp->loop_type )
406         {
407                 int looplen = samp->loop_end-samp->loop_start;
408                 if( !(samp->format & SAMPF_COMP) )
409                 {
410                         if( samp->format & SAMPF_16BIT )
411                         {
412                                 if( looplen & 1 )
413                                 {
414                                         int addition = (samp->loop_end - samp->loop_start);
415                                         if( addition > MAX_UNROLL_THRESHOLD )
416                                                 Resample( samp, samp->sample_length +1 );
417                                         else
418                                                 Unroll_Sample_Loop( samp, 1 );
419                                 }
420                         }
421                         else
422                         {
423                                 if( looplen & 3 )
424                                 {
425                                         int count;
426                                         int addition;
427                                         count = looplen & 3;
428                                         switch( count ) {
429                                         case 0:
430                                                 count=0;        break;
431                                         case 1:
432                                                 count=3;        break;
433                                         case 2:
434                                                 count=1;        break;
435                                         case 3:
436                                                 count=3;        break;
437                                         }
438                                         addition = looplen*count;
439                                         if( addition > MAX_UNROLL_THRESHOLD )
440                                                 Resample( samp, samp->sample_length + (4-(looplen & 3)) );
441                                         else
442                                                 Unroll_Sample_Loop( samp, count );
443                                 }
444                         }
445                 }
446                 else
447                 {
448                         int a = looplen;
449                         int count=0, addition;
450                         while( looplen & 7 )
451                         {
452                                 count++;
453                                 looplen += a;
454                         }
455                         addition = looplen*count;
456                         if( addition > MAX_UNROLL_THRESHOLD )
457                                 Resample( samp, samp->sample_length + (4-(looplen & 7)) );
458                         else
459                                 Unroll_Sample_Loop( samp, count );
460                 }
461         }
462         
463         // Align loop_start
464         if( samp->loop_type )
465         {
466                 int padsize;
467                 if( !(samp->format & SAMPF_COMP) )
468                 {
469                         if( samp->format & SAMPF_16BIT ) {
470                                 padsize = ( (2 - (samp->loop_start & 1)) & 1 );
471                         } else {
472                                 padsize = ( (4 - (samp->loop_start & 3)) & 3 );
473                         }
474                 }
475                 else
476                 {
477                         padsize = ( (8 - (samp->loop_start & 7)) & 7 );
478                 }
479                 Sample_PadStart( samp, padsize );
480         }
481         
482         // Pad end, only happens when loop is disabled
483         if( !(samp->format & SAMPF_COMP) )
484         {
485                 if( samp->format & SAMPF_16BIT )
486                 {
487                         if( samp->sample_length & 1 )
488                         {
489                                 Sample_PadEnd( samp, 2-(samp->sample_length&1) );
490                         }
491                 }
492                 else
493                 {
494                         if( samp->sample_length & 3 )
495                         {
496                                 Sample_PadEnd( samp, 4-(samp->sample_length&3) );
497                         }
498                 }
499         }
500         else
501         {
502                 if( samp->sample_length & 7 )
503                 {
504                         Sample_PadEnd( samp, 8-(samp->sample_length&7) );
505                 }
506         }
507         
508         Sample_Sign( samp );    // DS hardware takes signed samples
509
510         if( samp->format & SAMPF_COMP )
511         {
512                 // compress with IMA-ADPCM hunger owned
513                 adpcm_compress_sample( samp );
514         }
515         else
516         {
517                 
518         }
519 }
520
521 void FixSample( Sample* samp )
522 {
523         // Clamp loop_start and loop_end (f.e. FR_TOWER.MOD)
524         samp->loop_start = CLAMP(samp->loop_start, 0, samp->sample_length);
525         samp->loop_end = CLAMP(samp->loop_end, 0, samp->sample_length);
526
527         if( target_system == SYSTEM_GBA )
528                 FixSample_GBA( samp );
529         else if( target_system == SYSTEM_NDS )
530                 FixSample_NDS( samp );
531 }
532