You are on page 1of 19

#include <stdio.h> // standard input/output, used for functions like sprintf #include <string.

h> // used for processing strings, particularly strcpy #include <math.h> // used for advanced mathematical functions - log10 in this case (for base 10 logarithms, used for progress indication) #define _CRT_SECURE_NO_DEPRECATE // gets rid of the warnings from deprecation - sprintf, fopen, etc. is standard C unsigned int Modifier; // adjusts sample rate in file based on source's true speed sample rate // unsigned int Steps; unsigned int BestSpeeds1Start; // the speed ranges of up to 3 best zones, that most listened to unsigned int BestSpeeds1End; unsigned int BestSpeeds2Start; unsigned int BestSpeeds2End; unsigned int BestSpeeds3Start; unsigned int BestSpeeds3End; unsigned int NormalSpeedsStart; // the speed ranges of the normal zone, where the song sounds reasonable unsigned int NormalSpeedsEnd; unsigned int CurrentSpeed = 0; // the current sample rate (speed) unsigned int FrequencyChangeover16K; // the speed (sample rate) at which the output MP3's sample rate increases, to allow for optimization unsigned int FrequencyChangeover24K; unsigned int FrequencyChangeover32K; unsigned int FrequencyChangeover48K; unsigned int ProcessingStage = 1; // a "flag" that indicates whether the normal zone or best zone speeds are reached, or the end unsigned int WithinRange; // a "flag" to indicate that a speed is within the speed zone unsigned int ZoneID; // zone identifier unsigned int ZoneLapCount[7]; // number of loops within each zone (used in the base file's name) unsigned int ReadFlag = 0; // a flag to indicate that the next zone's base file is read, for more control on the displaying of text unsigned int SampleRateInFile; // the sample rate used in the file's info unsigned int BytesPerSecond; // equal to SampleRate*Multiplier unsigned int Multiplier; // the multiplier used for the BytesPerSecond variable, based on the number of bytes per sample unsigned char FileHeadStart[24]; // for copying identical file header data unsigned char FileHeadEnd[7]; // for copying the last parts of the file header data unsigned int FileLength; // the length of the file after the header data in bytes unsigned char FileContents[250000000]; // the contents of the file for copying, since the samples themselves don't change at all // use array with size bigger than file size or malloc it char FileName[128]; // the file name for the output file char SongName[60]; // for the name of the song for easier processing unsigned int DebugTest[16]; // debugging variables FILE *FileHandle; // used for the reading and writing of files void FindNextSampleRate() { /* This function determines the next speed, sets flags and essential in-file data, and determines the zone afterwards. This function has 3 stages: Stage 1: Obtain the next speed based on the mode. Normal speeds have big gaps and "best zone" speeds have tiny gaps. Stage 2: Determine what zone this speed is in. If in range, set the file's sample rate and bytes per second values accordingly If at the end of the normal speeds, restart from the beginning and do the "best zone" speeds. Stage 3: Set flags and essential in-file data. This is needed to determine what file to use. */ if (CurrentSpeed <= 70000) { DebugTest[1] = 1; // a flag DebugTest[2] = CurrentSpeed; // what the speed was originally } else {

DebugTest[1] = 0; // reset } // Stage 1: Obtain the next speed based on the mode. // exclusive to samplers, of which always use the best zone speeds if ((NormalSpeedsStart == BestSpeeds1Start) && (NormalSpeedsEnd == BestSpeeds1End)) { ProcessingStage = 2; } if ((ProcessingStage == 1) && (NormalSpeedsStart < BestSpeeds1Start)) // the normal speeds and not a sampler/special version { if (CurrentSpeed < 20000) { CurrentSpeed = 20000; } // 1/5 else if (CurrentSpeed < 20972) { CurrentSpeed = 20972; } // "speed -2" else if (CurrentSpeed < 22500) { CurrentSpeed = 22500; } else if (CurrentSpeed < 25000) { CurrentSpeed = 25000; } // 1/4; 24 semi-tones lower else if (CurrentSpeed < 26214) { CurrentSpeed = 26214; } // "speed -1" else if (CurrentSpeed < 27500) { CurrentSpeed = 27500; } else if (CurrentSpeed < 30000) { CurrentSpeed = 30000; } else if (CurrentSpeed < 32768) { CurrentSpeed = 32768; } // "speed 0" else if (CurrentSpeed < 33333) { CurrentSpeed = 33333; } // 1/3 else if (CurrentSpeed < 35000) { CurrentSpeed = 35000; } else if (CurrentSpeed < 35355) { CurrentSpeed = 35355; } // sqrt(1/8); 18 semi-tones lower else if (CurrentSpeed < 40000) { CurrentSpeed = 40000; } // extended minimum; 2/5 else if (CurrentSpeed < 40960) { CurrentSpeed = 40960; } // "speed 1" else if (CurrentSpeed < 45000) { CurrentSpeed = 45000; } else if (CurrentSpeed < 50000) { CurrentSpeed = 50000; } // standard minimum; 1/2; 12 semitones lower else if (CurrentSpeed < 51200) { CurrentSpeed = 51200; } // "speed 2" else if (CurrentSpeed < 55000) { CurrentSpeed = 55000; } else if (CurrentSpeed < 60000) { CurrentSpeed = 60000; } else if (CurrentSpeed < 64000) { CurrentSpeed = 64000; } // "speed 3" else if (CurrentSpeed < 66667) { CurrentSpeed = 66667; } // 2/3 else if (CurrentSpeed < 70000) { CurrentSpeed = 70000; } else if (CurrentSpeed < 70711) { CurrentSpeed = 70711; } // sqrt(1/2); 6 semi-tones lower else if (CurrentSpeed < 75000) { CurrentSpeed = 75000; } // 3/4 else if (CurrentSpeed < 80000) { CurrentSpeed = 80000; } // "speed 4"; 4/5 else if (CurrentSpeed < 83333) { CurrentSpeed = 83333; } // 5/6 else if (CurrentSpeed < 90000) { CurrentSpeed = 90000; } else if (CurrentSpeed < 100000) { CurrentSpeed = 100000; } // true speed; "speed 5" else if (CurrentSpeed < 110000) { CurrentSpeed = 110000; } else if (CurrentSpeed < 116667) { CurrentSpeed = 116667; } // 7/6 else if (CurrentSpeed < 125000) { CurrentSpeed = 125000; } // standard maximum; "speed 6"; 5/4 else if (CurrentSpeed < 133333) { CurrentSpeed = 133333; } // 4/3 else if (CurrentSpeed < 140000) { CurrentSpeed = 140000; } // extended maximum else if (CurrentSpeed < 141421) { CurrentSpeed = 141421; } // sqrt(2); 6 semi-tones higher else if (CurrentSpeed < 150000) { CurrentSpeed = 150000; } // 3/2 else if (CurrentSpeed < 156250) { CurrentSpeed = 156250; } // "speed 7" else if (CurrentSpeed < 166667) { CurrentSpeed = 166667; } // 5/3 else if (CurrentSpeed < 175000) { CurrentSpeed = 175000; } else if (CurrentSpeed < 195313) { CurrentSpeed = 195313; } // "speed 8" else if (CurrentSpeed < 200000) { CurrentSpeed = 200000; } // double; 12 semi-tones higher else if (CurrentSpeed < 225000) { CurrentSpeed = 225000; } else if (CurrentSpeed < 244141) { CurrentSpeed = 244141; } // "speed 9" else if (CurrentSpeed < 250000) { CurrentSpeed = 250000; } // 5/2 else if (CurrentSpeed < 282843) { CurrentSpeed = 282843; } // sqrt(8); 18 semi-tones higher else if (CurrentSpeed < 300000) { CurrentSpeed = 300000; } // triple else if (CurrentSpeed < 305176) { CurrentSpeed = 305176; } // "speed 10" else if (CurrentSpeed < 350000) { CurrentSpeed = 350000; } else if (CurrentSpeed < 381470) { CurrentSpeed = 381470; } // "speed 11" else if (CurrentSpeed < 400000) { CurrentSpeed = 400000; } // quadruple; 24 semi-tones higher else if (CurrentSpeed < 450000) { CurrentSpeed = 450000; } else if (CurrentSpeed < 476837) { CurrentSpeed = 476837; } // "speed 12" else if (CurrentSpeed < 500000) { CurrentSpeed = 500000; } // quintuple } if (DebugTest[1] == 1) { DebugTest[3] = CurrentSpeed; // what the speed is after the normal zone }

if ((ProcessingStage == 2) || (NormalSpeedsStart == BestSpeeds1Start)) // the best speeds (or a sampler/special version) { if (CurrentSpeed < 20000) { CurrentSpeed = 20000; } // 1/5 else if (CurrentSpeed < 20250) { CurrentSpeed = 20250; } else if (CurrentSpeed < 20500) { CurrentSpeed = 20500; } else if (CurrentSpeed < 20750) { CurrentSpeed = 20750; } else if (CurrentSpeed < 20972) { CurrentSpeed = 20972; } // "speed -2" else if (CurrentSpeed < 21000) { CurrentSpeed = 21000; } else if (CurrentSpeed < 21250) { CurrentSpeed = 21250; } else if (CurrentSpeed < 21500) { CurrentSpeed = 21500; } else if (CurrentSpeed < 21750) { CurrentSpeed = 21750; } else if (CurrentSpeed < 22000) { CurrentSpeed = 22000; } else if (CurrentSpeed < 22222) { CurrentSpeed = 22222; } // 2/9 else if (CurrentSpeed < 22250) { CurrentSpeed = 22250; } else if (CurrentSpeed < 22500) { CurrentSpeed = 22500; } else if (CurrentSpeed < 22750) { CurrentSpeed = 22750; } else if (CurrentSpeed < 23000) { CurrentSpeed = 23000; } else if (CurrentSpeed < 23250) { CurrentSpeed = 23250; } else if (CurrentSpeed < 23500) { CurrentSpeed = 23500; } else if (CurrentSpeed < 23750) { CurrentSpeed = 23750; } else if (CurrentSpeed < 24000) { CurrentSpeed = 24000; } else if (CurrentSpeed < 24250) { CurrentSpeed = 24250; } else if (CurrentSpeed < 24500) { CurrentSpeed = 24500; } else if (CurrentSpeed < 24750) { CurrentSpeed = 24750; } else if (CurrentSpeed < 25000) { CurrentSpeed = 25000; } // 1/4; 24 semi-tones lower else if (CurrentSpeed < 25250) { CurrentSpeed = 25250; } else if (CurrentSpeed < 25500) { CurrentSpeed = 25500; } else if (CurrentSpeed < 25750) { CurrentSpeed = 25750; } else if (CurrentSpeed < 26000) { CurrentSpeed = 26000; } else if (CurrentSpeed < 26214) { CurrentSpeed = 26214; } // "speed -1" else if (CurrentSpeed < 26250) { CurrentSpeed = 26250; } else if (CurrentSpeed < 26500) { CurrentSpeed = 26500; } else if (CurrentSpeed < 26667) { CurrentSpeed = 26667; } // 4/15 else if (CurrentSpeed < 26750) { CurrentSpeed = 26750; } else if (CurrentSpeed < 27000) { CurrentSpeed = 27000; } else if (CurrentSpeed < 27250) { CurrentSpeed = 27250; } else if (CurrentSpeed < 27500) { CurrentSpeed = 27500; } else if (CurrentSpeed < 27750) { CurrentSpeed = 27750; } else if (CurrentSpeed < 28000) { CurrentSpeed = 28000; } else if (CurrentSpeed < 28250) { CurrentSpeed = 28250; } else if (CurrentSpeed < 28500) { CurrentSpeed = 28500; } else if (CurrentSpeed < 28571) { CurrentSpeed = 28571; } // 2/7 else if (CurrentSpeed < 28750) { CurrentSpeed = 28750; } else if (CurrentSpeed < 29000) { CurrentSpeed = 29000; } else if (CurrentSpeed < 29250) { CurrentSpeed = 29250; } else if (CurrentSpeed < 29500) { CurrentSpeed = 29500; } else if (CurrentSpeed < 29750) { CurrentSpeed = 29750; } else if (CurrentSpeed < 30000) { CurrentSpeed = 30000; } // 3/10 else if (CurrentSpeed < 30250) { CurrentSpeed = 30250; } else if (CurrentSpeed < 30500) { CurrentSpeed = 30500; } else if (CurrentSpeed < 30750) { CurrentSpeed = 30750; } else if (CurrentSpeed < 31000) { CurrentSpeed = 31000; } else if (CurrentSpeed < 31250) { CurrentSpeed = 31250; } else if (CurrentSpeed < 31500) { CurrentSpeed = 31500; } else if (CurrentSpeed < 32000) { CurrentSpeed = 32000; } else if (CurrentSpeed < 32500) { CurrentSpeed = 32500; } else if (CurrentSpeed < 32768) { CurrentSpeed = 32768; } // "speed 0" else if (CurrentSpeed < 33000) { CurrentSpeed = 33000; } else if (CurrentSpeed < 33333) { CurrentSpeed = 33333; } // 1/3 else if (CurrentSpeed < 33500) { CurrentSpeed = 33500; } else if (CurrentSpeed < 34000) { CurrentSpeed = 34000; } else if (CurrentSpeed < 34500) { CurrentSpeed = 34500; } else if (CurrentSpeed < 35000) { CurrentSpeed = 35000; } else if (CurrentSpeed < 35355) { CurrentSpeed = 35355; } // sqrt(1/8); 18 semi-tones lower else if (CurrentSpeed < 35500) { CurrentSpeed = 35500; } else if (CurrentSpeed < 36000) { CurrentSpeed = 36000; } else if (CurrentSpeed < 36500) { CurrentSpeed = 36500; } else if (CurrentSpeed < 37000) { CurrentSpeed = 37000; } else if (CurrentSpeed < 37500) { CurrentSpeed = 37500; } // 3/8 else if (CurrentSpeed < 38000) { CurrentSpeed = 38000; } else if (CurrentSpeed < 38500) { CurrentSpeed = 38500; } else if (CurrentSpeed < 39000) { CurrentSpeed = 39000; } else if (CurrentSpeed < 39500) { CurrentSpeed = 39500; }

else if (CurrentSpeed < 40000) { CurrentSpeed = 40000; } // extended minimum; 2/5 else if (CurrentSpeed < 40500) { CurrentSpeed = 40500; } else if (CurrentSpeed < 40960) { CurrentSpeed = 40960; } // "speed 1" else if (CurrentSpeed < 41000) { CurrentSpeed = 41000; } else if (CurrentSpeed < 41500) { CurrentSpeed = 41500; } else if (CurrentSpeed < 41667) { CurrentSpeed = 41667; } // 5/12 else if (CurrentSpeed < 42000) { CurrentSpeed = 42000; } else if (CurrentSpeed < 42500) { CurrentSpeed = 42500; } else if (CurrentSpeed < 42857) { CurrentSpeed = 42857; } // 3/7 else if (CurrentSpeed < 43000) { CurrentSpeed = 43000; } else if (CurrentSpeed < 43500) { CurrentSpeed = 43500; } else if (CurrentSpeed < 44000) { CurrentSpeed = 44000; } else if (CurrentSpeed < 44444) { CurrentSpeed = 44444; } // 4/9 else if (CurrentSpeed < 44500) { CurrentSpeed = 44500; } else if (CurrentSpeed < 45000) { CurrentSpeed = 45000; } else if (CurrentSpeed < 45500) { CurrentSpeed = 45500; } else if (CurrentSpeed < 46000) { CurrentSpeed = 46000; } else if (CurrentSpeed < 46500) { CurrentSpeed = 46500; } else if (CurrentSpeed < 46667) { CurrentSpeed = 46667; } // 7/15 else if (CurrentSpeed < 47000) { CurrentSpeed = 47000; } else if (CurrentSpeed < 47500) { CurrentSpeed = 47500; } else if (CurrentSpeed < 48000) { CurrentSpeed = 48000; } else if (CurrentSpeed < 48500) { CurrentSpeed = 48500; } else if (CurrentSpeed < 49000) { CurrentSpeed = 49000; } else if (CurrentSpeed < 49500) { CurrentSpeed = 49500; } else if (CurrentSpeed < 50000) { CurrentSpeed = 50000; } // standard minimum; 1/2; 12 semitones lower else if (CurrentSpeed < 50500) { CurrentSpeed = 50500; } else if (CurrentSpeed < 51000) { CurrentSpeed = 51000; } else if (CurrentSpeed < 51200) { CurrentSpeed = 51200; } // "speed 2" else if (CurrentSpeed < 51500) { CurrentSpeed = 51500; } else if (CurrentSpeed < 52000) { CurrentSpeed = 52000; } else if (CurrentSpeed < 52500) { CurrentSpeed = 52500; } else if (CurrentSpeed < 53000) { CurrentSpeed = 53000; } else if (CurrentSpeed < 53333) { CurrentSpeed = 53333; } // 8/15 else if (CurrentSpeed < 53500) { CurrentSpeed = 53500; } else if (CurrentSpeed < 54000) { CurrentSpeed = 54000; } else if (CurrentSpeed < 54500) { CurrentSpeed = 54500; } else if (CurrentSpeed < 55000) { CurrentSpeed = 55000; } else if (CurrentSpeed < 55500) { CurrentSpeed = 55500; } else if (CurrentSpeed < 55556) { CurrentSpeed = 55556; } // 5/9 else if (CurrentSpeed < 56000) { CurrentSpeed = 56000; } else if (CurrentSpeed < 56500) { CurrentSpeed = 56500; } else if (CurrentSpeed < 57000) { CurrentSpeed = 57000; } else if (CurrentSpeed < 57143) { CurrentSpeed = 57143; } // 4/7 else if (CurrentSpeed < 57500) { CurrentSpeed = 57500; } else if (CurrentSpeed < 58000) { CurrentSpeed = 58000; } else if (CurrentSpeed < 58333) { CurrentSpeed = 58333; } // 7/12 else if (CurrentSpeed < 58500) { CurrentSpeed = 58500; } else if (CurrentSpeed < 59000) { CurrentSpeed = 59000; } else if (CurrentSpeed < 59500) { CurrentSpeed = 59500; } else if (CurrentSpeed < 60000) { CurrentSpeed = 60000; } // 3/5 else if (CurrentSpeed < 60500) { CurrentSpeed = 60500; } else if (CurrentSpeed < 61000) { CurrentSpeed = 61000; } else if (CurrentSpeed < 61500) { CurrentSpeed = 61500; } else if (CurrentSpeed < 62000) { CurrentSpeed = 62000; } else if (CurrentSpeed < 62500) { CurrentSpeed = 62500; } // 5/8 else if (CurrentSpeed < 63000) { CurrentSpeed = 63000; } else if (CurrentSpeed < 64000) { CurrentSpeed = 64000; } // "speed 3" else if (CurrentSpeed < 65000) { CurrentSpeed = 65000; } else if (CurrentSpeed < 66000) { CurrentSpeed = 66000; } else if (CurrentSpeed < 66667) { CurrentSpeed = 66667; } // 2/3 else if (CurrentSpeed < 67000) { CurrentSpeed = 67000; } else if (CurrentSpeed < 68000) { CurrentSpeed = 68000; } else if (CurrentSpeed < 69000) { CurrentSpeed = 69000; } else if (CurrentSpeed < 70000) { CurrentSpeed = 70000; } // 7/10 else if (CurrentSpeed < 70711) { CurrentSpeed = 70711; } // sqrt(1/2); 6 semi-tones lower else if (CurrentSpeed < 71000) { CurrentSpeed = 71000; } else if (CurrentSpeed < 71429) { CurrentSpeed = 71429; } // 5/7 else if (CurrentSpeed < 72000) { CurrentSpeed = 72000; } else if (CurrentSpeed < 73000) { CurrentSpeed = 73000; } else if (CurrentSpeed < 73333) { CurrentSpeed = 73333; } // 11/15 else if (CurrentSpeed < 74000) { CurrentSpeed = 74000; } else if (CurrentSpeed < 75000) { CurrentSpeed = 75000; } // 3/4

else if (CurrentSpeed < 76000) { CurrentSpeed = 76000; } else if (CurrentSpeed < 77000) { CurrentSpeed = 77000; } else if (CurrentSpeed < 77778) { CurrentSpeed = 77778; } // 7/8 else if (CurrentSpeed < 78000) { CurrentSpeed = 78000; } else if (CurrentSpeed < 79000) { CurrentSpeed = 79000; } else if (CurrentSpeed < 80000) { CurrentSpeed = 80000; } // 4/5 else if (CurrentSpeed < 81000) { CurrentSpeed = 81000; } else if (CurrentSpeed < 82000) { CurrentSpeed = 82000; } else if (CurrentSpeed < 83000) { CurrentSpeed = 83000; } else if (CurrentSpeed < 83333) { CurrentSpeed = 83333; } // 5/6 else if (CurrentSpeed < 84000) { CurrentSpeed = 84000; } else if (CurrentSpeed < 85000) { CurrentSpeed = 85000; } else if (CurrentSpeed < 85714) { CurrentSpeed = 85714; } // 6/7 else if (CurrentSpeed < 86000) { CurrentSpeed = 86000; } else if (CurrentSpeed < 86667) { CurrentSpeed = 86667; } // 13/15 else if (CurrentSpeed < 87000) { CurrentSpeed = 87000; } else if (CurrentSpeed < 87500) { CurrentSpeed = 87500; } // 7/8 else if (CurrentSpeed < 88000) { CurrentSpeed = 88000; } else if (CurrentSpeed < 88889) { CurrentSpeed = 88889; } // 8/9 else if (CurrentSpeed < 89000) { CurrentSpeed = 89000; } else if (CurrentSpeed < 90000) { CurrentSpeed = 90000; } // 9/10 else if (CurrentSpeed < 91000) { CurrentSpeed = 91000; } else if (CurrentSpeed < 91667) { CurrentSpeed = 91667; } // 11/12 else if (CurrentSpeed < 92000) { CurrentSpeed = 92000; } else if (CurrentSpeed < 93000) { CurrentSpeed = 93000; } else if (CurrentSpeed < 93333) { CurrentSpeed = 93333; } // 14/15 else if (CurrentSpeed < 94000) { CurrentSpeed = 94000; } else if (CurrentSpeed < 95000) { CurrentSpeed = 95000; } else if (CurrentSpeed < 96000) { CurrentSpeed = 96000; } else if (CurrentSpeed < 97000) { CurrentSpeed = 97000; } else if (CurrentSpeed < 98000) { CurrentSpeed = 98000; } else if (CurrentSpeed < 99000) { CurrentSpeed = 99000; } else if (CurrentSpeed < 100000) { CurrentSpeed = 100000; } // true speed; "speed 5" else if (CurrentSpeed < 101000) { CurrentSpeed = 101000; } else if (CurrentSpeed < 102000) { CurrentSpeed = 102000; } else if (CurrentSpeed < 103000) { CurrentSpeed = 103000; } else if (CurrentSpeed < 104000) { CurrentSpeed = 104000; } else if (CurrentSpeed < 105000) { CurrentSpeed = 105000; } else if (CurrentSpeed < 106000) { CurrentSpeed = 106000; } else if (CurrentSpeed < 106667) { CurrentSpeed = 106667; } // 16/15 else if (CurrentSpeed < 107000) { CurrentSpeed = 107000; } else if (CurrentSpeed < 108000) { CurrentSpeed = 108000; } else if (CurrentSpeed < 108333) { CurrentSpeed = 108333; } // 13/12 else if (CurrentSpeed < 109000) { CurrentSpeed = 109000; } else if (CurrentSpeed < 110000) { CurrentSpeed = 110000; } // 11/10 else if (CurrentSpeed < 111000) { CurrentSpeed = 111000; } else if (CurrentSpeed < 111111) { CurrentSpeed = 111111; } // 10/9 else if (CurrentSpeed < 112000) { CurrentSpeed = 112000; } else if (CurrentSpeed < 112500) { CurrentSpeed = 112500; } // 9/8 else if (CurrentSpeed < 113000) { CurrentSpeed = 113000; } else if (CurrentSpeed < 113333) { CurrentSpeed = 113333; } // 17/15 else if (CurrentSpeed < 114000) { CurrentSpeed = 114000; } else if (CurrentSpeed < 114286) { CurrentSpeed = 114286; } // 8/7 else if (CurrentSpeed < 115000) { CurrentSpeed = 115000; } else if (CurrentSpeed < 116000) { CurrentSpeed = 116000; } else if (CurrentSpeed < 116667) { CurrentSpeed = 116667; } // 7/6 else if (CurrentSpeed < 117000) { CurrentSpeed = 117000; } else if (CurrentSpeed < 118000) { CurrentSpeed = 118000; } else if (CurrentSpeed < 119000) { CurrentSpeed = 119000; } else if (CurrentSpeed < 120000) { CurrentSpeed = 120000; } // 6/5 else if (CurrentSpeed < 121000) { CurrentSpeed = 121000; } else if (CurrentSpeed < 122000) { CurrentSpeed = 122000; } else if (CurrentSpeed < 122222) { CurrentSpeed = 122222; } // 11/9 else if (CurrentSpeed < 123000) { CurrentSpeed = 123000; } else if (CurrentSpeed < 124000) { CurrentSpeed = 124000; } else if (CurrentSpeed < 125000) { CurrentSpeed = 125000; } // standard maximum; "speed 6"; 5/4 else if (CurrentSpeed < 127500) { CurrentSpeed = 127500; } else if (CurrentSpeed < 128571) { CurrentSpeed = 128571; } // 9/7 else if (CurrentSpeed < 130000) { CurrentSpeed = 130000; } else if (CurrentSpeed < 132500) { CurrentSpeed = 132500; } else if (CurrentSpeed < 133333) { CurrentSpeed = 133333; } // 4/3 else if (CurrentSpeed < 135000) { CurrentSpeed = 135000; } else if (CurrentSpeed < 137500) { CurrentSpeed = 137500; }

else if (CurrentSpeed < 140000) { CurrentSpeed = 140000; } // extended maximum; 7/5 else if (CurrentSpeed < 141421) { CurrentSpeed = 141421; } // sqrt(2); 6 semi-tones higher else if (CurrentSpeed < 142500) { CurrentSpeed = 142500; } else if (CurrentSpeed < 142857) { CurrentSpeed = 142857; } // 10/7 else if (CurrentSpeed < 145000) { CurrentSpeed = 145000; } else if (CurrentSpeed < 147500) { CurrentSpeed = 147500; } else if (CurrentSpeed < 150000) { CurrentSpeed = 150000; } // 3/2 else if (CurrentSpeed < 152500) { CurrentSpeed = 152500; } else if (CurrentSpeed < 155000) { CurrentSpeed = 155000; } else if (CurrentSpeed < 156250) { CurrentSpeed = 156250; } // "speed 7" else if (CurrentSpeed < 157500) { CurrentSpeed = 157500; } else if (CurrentSpeed < 160000) { CurrentSpeed = 160000; } // 8/5 else if (CurrentSpeed < 162500) { CurrentSpeed = 162500; } else if (CurrentSpeed < 165000) { CurrentSpeed = 165000; } else if (CurrentSpeed < 166667) { CurrentSpeed = 166667; } // 5/3 else if (CurrentSpeed < 167500) { CurrentSpeed = 167500; } else if (CurrentSpeed < 170000) { CurrentSpeed = 170000; } else if (CurrentSpeed < 172500) { CurrentSpeed = 172500; } else if (CurrentSpeed < 175000) { CurrentSpeed = 175000; } // 7/4 else if (CurrentSpeed < 177500) { CurrentSpeed = 177500; } else if (CurrentSpeed < 180000) { CurrentSpeed = 180000; } // 9/5 else if (CurrentSpeed < 182500) { CurrentSpeed = 182500; } else if (CurrentSpeed < 183333) { CurrentSpeed = 183333; } // 11/6 else if (CurrentSpeed < 185000) { CurrentSpeed = 185000; } else if (CurrentSpeed < 187500) { CurrentSpeed = 187500; } else if (CurrentSpeed < 190000) { CurrentSpeed = 190000; } else if (CurrentSpeed < 192500) { CurrentSpeed = 192500; } else if (CurrentSpeed < 195000) { CurrentSpeed = 195000; } else if (CurrentSpeed < 195313) { CurrentSpeed = 195313; } // "speed 8" else if (CurrentSpeed < 197500) { CurrentSpeed = 197500; } else if (CurrentSpeed < 200000) { CurrentSpeed = 200000; } // double; 12 semi-tones higher else if (CurrentSpeed < 202500) { CurrentSpeed = 202500; } else if (CurrentSpeed < 205000) { CurrentSpeed = 205000; } else if (CurrentSpeed < 207500) { CurrentSpeed = 207500; } else if (CurrentSpeed < 210000) { CurrentSpeed = 210000; } else if (CurrentSpeed < 212500) { CurrentSpeed = 212500; } else if (CurrentSpeed < 215000) { CurrentSpeed = 215000; } else if (CurrentSpeed < 217500) { CurrentSpeed = 217500; } else if (CurrentSpeed < 220000) { CurrentSpeed = 220000; } else if (CurrentSpeed < 222500) { CurrentSpeed = 222500; } else if (CurrentSpeed < 225000) { CurrentSpeed = 225000; } // 9/4 else if (CurrentSpeed < 227500) { CurrentSpeed = 227500; } else if (CurrentSpeed < 230000) { CurrentSpeed = 230000; } else if (CurrentSpeed < 232500) { CurrentSpeed = 232500; } else if (CurrentSpeed < 233333) { CurrentSpeed = 233333; } // 7/3 else if (CurrentSpeed < 235000) { CurrentSpeed = 235000; } else if (CurrentSpeed < 237500) { CurrentSpeed = 237500; } else if (CurrentSpeed < 240000) { CurrentSpeed = 240000; } else if (CurrentSpeed < 242500) { CurrentSpeed = 242500; } else if (CurrentSpeed < 244141) { CurrentSpeed = 244141; } // "speed 9" else if (CurrentSpeed < 245000) { CurrentSpeed = 245000; } else if (CurrentSpeed < 247500) { CurrentSpeed = 247500; } else if (CurrentSpeed < 250000) { CurrentSpeed = 250000; } // 5/2 else if (CurrentSpeed < 255000) { CurrentSpeed = 255000; } else if (CurrentSpeed < 260000) { CurrentSpeed = 260000; } else if (CurrentSpeed < 265000) { CurrentSpeed = 265000; } else if (CurrentSpeed < 266667) { CurrentSpeed = 266667; } // 8/3 else if (CurrentSpeed < 270000) { CurrentSpeed = 270000; } else if (CurrentSpeed < 275000) { CurrentSpeed = 275000; } else if (CurrentSpeed < 280000) { CurrentSpeed = 280000; } else if (CurrentSpeed < 282843) { CurrentSpeed = 282843; } // sqrt(8); 18 semi-tones higher else if (CurrentSpeed < 285000) { CurrentSpeed = 285000; } else if (CurrentSpeed < 290000) { CurrentSpeed = 290000; } else if (CurrentSpeed < 295000) { CurrentSpeed = 295000; } else if (CurrentSpeed < 300000) { CurrentSpeed = 300000; } // triple else if (CurrentSpeed < 305000) { CurrentSpeed = 305000; } else if (CurrentSpeed < 305176) { CurrentSpeed = 305176; } // "speed 10" else if (CurrentSpeed < 310000) { CurrentSpeed = 310000; } else if (CurrentSpeed < 315000) { CurrentSpeed = 315000; } else if (CurrentSpeed < 320000) { CurrentSpeed = 320000; } else if (CurrentSpeed < 325000) { CurrentSpeed = 325000; } else if (CurrentSpeed < 330000) { CurrentSpeed = 330000; } else if (CurrentSpeed < 333333) { CurrentSpeed = 333333; } // 10/3 else if (CurrentSpeed < 335000) { CurrentSpeed = 335000; }

else if (CurrentSpeed < 340000) { CurrentSpeed = 340000; } else if (CurrentSpeed < 345000) { CurrentSpeed = 345000; } else if (CurrentSpeed < 350000) { CurrentSpeed = 350000; } // 7/2 else if (CurrentSpeed < 355000) { CurrentSpeed = 355000; } else if (CurrentSpeed < 360000) { CurrentSpeed = 360000; } else if (CurrentSpeed < 365000) { CurrentSpeed = 365000; } else if (CurrentSpeed < 370000) { CurrentSpeed = 370000; } else if (CurrentSpeed < 375000) { CurrentSpeed = 375000; } else if (CurrentSpeed < 380000) { CurrentSpeed = 380000; } else if (CurrentSpeed < 381470) { CurrentSpeed = 381470; } // "speed 11" else if (CurrentSpeed < 385000) { CurrentSpeed = 385000; } else if (CurrentSpeed < 390000) { CurrentSpeed = 390000; } else if (CurrentSpeed < 395000) { CurrentSpeed = 395000; } else if (CurrentSpeed < 400000) { CurrentSpeed = 400000; } // quadruple; 24-semi-tones higher else if (CurrentSpeed < 405000) { CurrentSpeed = 405000; } else if (CurrentSpeed < 410000) { CurrentSpeed = 410000; } else if (CurrentSpeed < 415000) { CurrentSpeed = 415000; } else if (CurrentSpeed < 420000) { CurrentSpeed = 420000; } else if (CurrentSpeed < 425000) { CurrentSpeed = 425000; } else if (CurrentSpeed < 430000) { CurrentSpeed = 430000; } else if (CurrentSpeed < 435000) { CurrentSpeed = 435000; } else if (CurrentSpeed < 440000) { CurrentSpeed = 440000; } else if (CurrentSpeed < 445000) { CurrentSpeed = 445000; } else if (CurrentSpeed < 450000) { CurrentSpeed = 450000; } // 9/2 else if (CurrentSpeed < 455000) { CurrentSpeed = 455000; } else if (CurrentSpeed < 460000) { CurrentSpeed = 460000; } else if (CurrentSpeed < 465000) { CurrentSpeed = 465000; } else if (CurrentSpeed < 470000) { CurrentSpeed = 470000; } else if (CurrentSpeed < 475000) { CurrentSpeed = 475000; } else if (CurrentSpeed < 476837) { CurrentSpeed = 476837; } // "speed 12" else if (CurrentSpeed < 480000) { CurrentSpeed = 480000; } else if (CurrentSpeed < 485000) { CurrentSpeed = 485000; } else if (CurrentSpeed < 490000) { CurrentSpeed = 490000; } else if (CurrentSpeed < 495000) { CurrentSpeed = 495000; } else if (CurrentSpeed < 500000) { CurrentSpeed = 500000; } // quintuple } if (CurrentSpeed > NormalSpeedsEnd) { ProcessingStage = 2; CurrentSpeed = BestSpeeds1Start; } if (DebugTest[1] == 1) { DebugTest[4] = CurrentSpeed; // what the speed is after the best zone } if (DebugTest[1] == 1) { DebugTest[8] = ZoneID; } // Stage 2: Determine what zone this speed is in. if (CurrentSpeed < NormalSpeedsStart) { ZoneID = 0;} // no zone else if ((CurrentSpeed >= NormalSpeedsStart) && (CurrentSpeed < BestSpeeds1Start)) { ZoneID = 1;} else if ((CurrentSpeed >= BestSpeeds1Start) && (CurrentSpeed <= BestSpeeds1End)) { ZoneID = 2;} else if ((CurrentSpeed > BestSpeeds1End) && (CurrentSpeed < BestSpeeds2Start)) { ZoneID = 3;} else if ((CurrentSpeed >= BestSpeeds2Start) && (CurrentSpeed <= BestSpeeds2End)) { ZoneID = 4;} else if ((CurrentSpeed > BestSpeeds2End) && (CurrentSpeed < BestSpeeds3Start)) { ZoneID = 5;} else if ((CurrentSpeed >= BestSpeeds3Start) && (CurrentSpeed <= BestSpeeds3End)) { ZoneID = 6;} else { ZoneID = 7;} if ((NormalSpeedsStart == BestSpeeds1Start) && (NormalSpeedsEnd == BestSpeeds1End)) // samplers only use one zone { ZoneID = 2;

if (CurrentSpeed < BestSpeeds1Start) // if below the initial speed { CurrentSpeed = BestSpeeds1Start; // make it at the initial speed } } if (DebugTest[1] == 1) { DebugTest[9] = ZoneID; } if (DebugTest[1] == 1) { DebugTest[5] = CurrentSpeed; } // Stage 3: Set flags and essential in-file data. if (ProcessingStage == 1) // the normal speeds { // those in any of the "best zone" must not be included - they should get skipped to save time if ((ZoneID == 1) || (ZoneID == 3) || (ZoneID == 5) || (ZoneID == 7)) { WithinRange = 1; // this indicates that the new speed is within range and should be processed // determine the sample rate as it is in the file if (Modifier == 1) // the song's true speed is 50,000 { SampleRateInFile = (CurrentSpeed+1)/2; // Add 1 to allow for rounding } else // true speed is 100,000 Hz { SampleRateInFile = CurrentSpeed; // set it to what this system uses } BytesPerSecond = SampleRateInFile * 2; // all files are 16-bit mono so this value is doubled. // check if at the end - go to mode 2 if done if (CurrentSpeed > NormalSpeedsEnd) { ProcessingStage = 2; // change to mode 2 for doing the best speeds CurrentSpeed = BestSpeeds1Start; // return to the start for one more cycle } // a sampler - always use the best zone if ((NormalSpeedsStart == BestSpeeds1Start) && (NormalSpeedsEnd == BestSpeeds1End)) { ZoneID = 2; ProcessingStage = 2; CurrentSpeed = BestSpeeds1Start; } } else // the best zone - skip it { WithinRange = 0; // it's not in range and the speed is ignored until the next processing stage is reached } } else if (ProcessingStage == 2) { // only those in the "best zone" get processed if ((ZoneID == 2) || (ZoneID == 4) || (ZoneID == 6)) { WithinRange = 1; // this indicates that the new speed is within range and should be processed if (Modifier == 1) // the song's true speed is 50,000 {

SampleRateInFile = (CurrentSpeed+1)/2; // Add 1 to allow for rounding } else // true speed is 100,000 Hz { SampleRateInFile = CurrentSpeed; // set it to what this system uses } BytesPerSecond = SampleRateInFile * 2; // all files are 16-bit mono so this value is doubled. } else // the normal zone, skip it { WithinRange = 0; // skip this speed without processing it and continue on until the next "best zone" occurs } if (ZoneID == 2) // if at the end of the first best zone { if ((CurrentSpeed == BestSpeeds1End) && (BestSpeeds2Start > NormalSpeedsEnd)) // only if at the end of the group and there aren't any other groups after this { ProcessingStage = 3; // done processing } } else if (ZoneID == 4) // if at the end of the second best zone { if ((CurrentSpeed == BestSpeeds2End) && (BestSpeeds3Start > NormalSpeedsEnd)) // only if at the end of the group and there aren't any other groups after this { ProcessingStage = 3; // done processing } } else if (ZoneID == 6) // if at the end of the third best zone { if (CurrentSpeed >= BestSpeeds3End) // only if at the end of the group { ProcessingStage = 3; // done processing } } } if (DebugTest[1] == 1) { DebugTest[6] = CurrentSpeed; } } void CreateOutputFiles() { /* This function reads any input files and writes the output based on the speeds used. There are 4 stages: Stage 1: Obtain the speed to process. Do the normal speeds first then the "best zone" speeds. Use a while loop and the FindNextSampleRate() function for this. Stage 2: Read the source file upon a zone change. If the next speed is in the same zone as the current, don't read the source file. Stage 3: Determine the amount of progress made. The normal, best, and overall progress should be indicated. The actual completion is based solely on the speeds rather than the number completed since it's quite erratic. The formula is "log10(CurrentSpeed/NormalSpeedsStart)/log10(NormalSpeedsEnd/NormalSpeedsStart)". For overall, use a weighted average - 1 part normal, 5 parts best (completing normal means 25% overall completion). The DOS filler characters are used for this, 20 (space; 0), B0 (1/2), B1 (1), B2 (1 1/2), and DB (2). Each "block" is 2 percentage units so 50 are needed. For 13.2% completion, 6 fulls (DB) and a half (B1) are used. Stage 4: Write the data to disk as a WAV file.

The format is in the "[speed] [song name].wav" format where [speed] is a 6-digit number with leading zeros. Progress bar design: Completion (approximate): -------------------------------------------------Normal: | | 100.0% -------------------------------------------------Best: | | 040.0% -------------------------------------------------Overall: | | 055.0% -------------------------------------------------*/ unsigned int PreviousZone = 0; char CompletionString[51]; // used for the progress indicators unsigned int BaseStringPosition; double NormalCompletion; double BestCompletion; double OverallCompletion; double FileSizeMiB = 0.0; double DataWrittenGiB = 0.0; unsigned int Units; // used for progress bars CurrentSpeed = 0; // set the current speed here before processing anything WithinRange = 0; // initiate it and to falsify the loop for stage 1 DebugTest[0] = 0; // a sanity check, fixing a bug when large-range best zones get segmented if (BestSpeeds1End == BestSpeeds2Start) { BestSpeeds1End--; } if (BestSpeeds2End == BestSpeeds3Start) { BestSpeeds2End--; } while (ProcessingStage < 3) { // Stage 1: Obtain the speed to process. PreviousZone = ZoneID; // log the previous zone to prevent excessive rereading while (WithinRange != 1) { FindNextSampleRate(); } if (WithinRange == 1) { // Stage 2: Read the source file upon a zone change. if ((ZoneID != PreviousZone) || (CurrentSpeed == NormalSpeedsStart) || (CurrentSpeed == BestSpeeds1Start)) // if just starting, the zone changed, or read the source file { // exclusive to samplers with just one zone if ((NormalSpeedsStart == BestSpeeds1Start) && (NormalSpeedsEnd == BestSpeeds1End)) { sprintf(FileName, "C:\\My Documents\\Songs for MP3\\source files\\%s base.wav", SongName, ZoneID); // read the contents for the zone's base file } else // standard case { sprintf(FileName, "C:\\My Documents\\Songs for MP3\\source files\\%s base%03d.wav", SongName, ZoneLapCount[ZoneID-1]); // read the contents for the zone's base file } FileHandle = fopen(FileName, "rb"); // read in binary mode (that's what WAV files are)

if (FileHandle != 0) // if the file was found and the file contents changed { fread(&FileHeadStart, 1, 24, FileHandle); // read the first 24 bytes of unchanging header data fseek(FileHandle, 33, SEEK_SET); // skip to byte 33 as this part gets set within the file itself fread(&FileHeadEnd, 1, 7, FileHandle); // read the next 7 bytes of more unchanging header data fread(&FileLength, 4, 1, FileHandle); // read the file length data value, to determine how many bytes are to be read and saved fread(&FileContents, 1, FileLength, FileHandle); // read one-byte chunks for the entire file's length, which is the end of the file fclose(FileHandle); // close the file ReadFlag = 1; // set the read flag } FileSizeMiB = ((double)FileLength+44.0)/1048576.0; // convert file size of whole file (44 bytes for header) to mebibytes, MiB } // Stage 3: Determine the amount of progress made. // samplers only use one zone if ((NormalSpeedsStart == BestSpeeds1Start) && (NormalSpeedsEnd == BestSpeeds1End)) { printf("Zone: 1; Loops: 1; Size: %6.2f MiB; Written: %6.3f GiB\n", FileSizeMiB, DataWrittenGiB); } else { printf("Zone: %d; Loops: %3d; Size: %6.2f MiB; Written: %6.3f GiB\n", ZoneID, ZoneLapCount[ZoneID-1], FileSizeMiB, DataWrittenGiB); } if (CurrentSpeed < FrequencyChangeover16K) // the rare 12K versions { sprintf(FileName, "C:\\My Documents\\Songs for MP3\\source files\\to convert\\12K files\\%06d %s.wav", CurrentSpeed, SongName); printf("Writing: ...\\12K files\\%06d %s.wav", CurrentSpeed, SongName); } else if ((CurrentSpeed >= FrequencyChangeover16K) && (CurrentSpeed < FrequencyChangeover24K)) // the common 16K versions { sprintf(FileName, "C:\\My Documents\\Songs for MP3\\source files\\to convert\\16K files\\%06d %s.wav", CurrentSpeed, SongName); printf("Writing: ...\\16K files\\%06d %s.wav", CurrentSpeed, SongName); } else if ((CurrentSpeed >= FrequencyChangeover24K) && (CurrentSpeed < FrequencyChangeover32K)) // the very common 24K versions { sprintf(FileName, "C:\\My Documents\\Songs for MP3\\source files\\to convert\\24K files\\%06d %s.wav", CurrentSpeed, SongName); printf("Writing: ...\\24K files\\%06d %s.wav", CurrentSpeed, SongName); } else if ((CurrentSpeed >= FrequencyChangeover32K) && (CurrentSpeed < FrequencyChangeover48K)) // the semi-common 32K versions { sprintf(FileName, "C:\\My Documents\\Songs for MP3\\source files\\to convert\\32K files\\%06d %s.wav", CurrentSpeed, SongName); printf("Writing: ...\\32K files\\%06d %s.wav", CurrentSpeed, SongName); } else // the rare 48K versions { sprintf(FileName, "C:\\My Documents\\Songs for MP3\\source files\\to convert\\48K files\\%06d %s.wav", CurrentSpeed, SongName); printf("Writing: ...\\32K files\\%06d %s.wav", CurrentSpeed, SongName); } if (ReadFlag == 1)

{ if ((NormalSpeedsStart == BestSpeeds1Start) && (NormalSpeedsEnd == BestSpeeds1End)) { printf("\nReading base file...."); } else { printf("\nReading zone %d's base file....", ZoneID); } } // printf("\n\nTest 2: %d; Test 3: %d; Test 4: %d;\nTest 5: %d; Test 6: %d; Test 7: %d;\n Test 8: %d; Test 9: %d;", DebugTest[2], DebugTest[3], DebugTest[4], DebugTest[5], DebugTest[6], DebugTest[7], DebugTest[8], DebugTest[9]); // debugging stuff // printf("\n\n\n\n\n\n\n"); // used for debug stuff printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); // normal usage - used to fill the whole command prompt window, like lame does if (ReadFlag == 0) // reading was not needed { printf("\n"); // add one more line feed } ReadFlag = 0; // reset since it's no longer needed printf("Completion (approximate):\n |"); // samplers don't use anything directly in the normal speeds, always the best speeds if ((NormalSpeedsStart == BestSpeeds1Start) && (NormalSpeedsEnd == BestSpeeds1End)) { NormalCompletion = 100.0; Units = 200; } else { if (ProcessingStage == 1) // normal speeds { NormalCompletion = log10((double)CurrentSpeed/(double)NormalSpeedsStart)/log10((double)NormalSpeedsEnd/(double)NormalSpeedsStart)*100.0; Units = (unsigned int)(NormalCompletion*2.0+0.5); // up to 200 units } else { NormalCompletion = 100.0; Units = 200; } } BaseStringPosition = 0; // reset for reuse (ain't recycling nice?) while (BaseStringPosition < 50) { if (Units >= 4) // a full block - 2% { CompletionString[BaseStringPosition] = 0xDB; // the full block character Units -= 4; // more is still possible so subtract it off instead } else if (Units == 3) // 3/4 block - 1.5% { CompletionString[BaseStringPosition] = 0xB2; // the 3/4 block character Units = 0; } else if (Units == 2) // 1/2 block - 1% { --------------------------------------------------\nNormal:

CompletionString[BaseStringPosition] = 0xB1; // the 1/2 block character Units = 0; } else if (Units == 1) // 1/4 block 0.5% { CompletionString[BaseStringPosition] = 0xB0; // the 1/4 block character Units = 0; } else // empty block 0% { CompletionString[BaseStringPosition] = 0x20; // the space character } BaseStringPosition++; } if ((NormalSpeedsStart == BestSpeeds1Start) && (NormalSpeedsEnd == BestSpeeds1End)) { printf("%s| XXX.X%%\n --------------------------------------------------\nBest: CompletionString, NormalCompletion); } else { printf("%s| %05.1f%%\n --------------------------------------------------\nBest: CompletionString, NormalCompletion); } if (ProcessingStage == 1) // normal speeds { BestCompletion = 0.0; Units = 0; // up to 200 units } else { if (BestSpeeds3Start < NormalSpeedsEnd) // if a third group of best speeds is involved { BestCompletion = log10((double)CurrentSpeed/(double)BestSpeeds1Start)/log10((double)BestSpeeds3End/(double)BestSpeeds1Start)*100.0; Units = (unsigned int)(BestCompletion*2.0+0.5); // up to 200 units } else if (BestSpeeds2Start < NormalSpeedsEnd) // if a second group of best speeds is involved instead { BestCompletion = log10((double)CurrentSpeed/(double)BestSpeeds1Start)/log10((double)BestSpeeds2End/(double)BestSpeeds1Start)*100.0; Units = (unsigned int)(BestCompletion*2.0+0.5); // up to 200 units } else // only one best zone is used { BestCompletion = log10((double)CurrentSpeed/(double)BestSpeeds1Start)/log10((double)BestSpeeds1End/(double)BestSpeeds1Start)*100.0; Units = (unsigned int)(BestCompletion*2.0+0.5); // up to 200 units } } BaseStringPosition = 0; // reset for reuse (ain't recycling nice?) while (BaseStringPosition < 50) { if (Units >= 4) // a full block - 2% { CompletionString[BaseStringPosition] = 0xDB; // the full block character Units -= 4; // more is still possible so subtract it off instead } else if (Units == 3) // 3/4 block - 1.5% {

|",

|",

CompletionString[BaseStringPosition] = 0xB2; // the 3/4 block character Units = 0; } else if (Units == 2) // 1/2 block - 1% { CompletionString[BaseStringPosition] = 0xB1; // the 1/2 block character Units = 0; } else if (Units == 1) // 1/4 block 0.5% { CompletionString[BaseStringPosition] = 0xB0; // the 1/4 block character Units = 0; } else // empty block 0% { CompletionString[BaseStringPosition] = 0x20; // the space character } BaseStringPosition++; } printf("%s| %05.1f%%\n --------------------------------------------------\nOverall: |", CompletionString, BestCompletion); if ((NormalSpeedsStart == BestSpeeds1Start) && (NormalSpeedsEnd == BestSpeeds1End)) { OverallCompletion = BestCompletion; // samplers only use the best zone speeds } else { OverallCompletion = (NormalCompletion + BestCompletion*5.0)/6.0; // a weighted average - 3 parts best and one part normal } Units = (unsigned int)(OverallCompletion*2.0+0.5); // up to 400 units BaseStringPosition = 0; // reset for reuse (ain't recycling nice?) while (BaseStringPosition < 50) { if (Units >= 4) // a full block - 2% { CompletionString[BaseStringPosition] = 0xDB; // the full block character Units -= 4; // more is still possible so subtract it off instead } else if (Units == 3) // 3/4 block - 1.5% { CompletionString[BaseStringPosition] = 0xB2; // the 3/4 block character Units = 0; } else if (Units == 2) // 1/2 block - 1% { CompletionString[BaseStringPosition] = 0xB1; // the 1/2 block character Units = 0; } else if (Units == 1) // 1/4 block 0.5% { CompletionString[BaseStringPosition] = 0xB0; // the 1/4 block character Units = 0; } else // empty block 0% { CompletionString[BaseStringPosition] = 0x20; // the space character } BaseStringPosition++;

} printf("%s| %05.1f%%\n OverallCompletion); --------------------------------------------------\n", CompletionString,

// Stage 4: Write the data to disk as a WAV file. FileHandle = fopen(FileName, "wb"); // open the file for writing in binary mode (WAV files are binary) if (FileHandle != 0) // do only if the pointer is valid { // write the details in the same order as it was read in but including the sample rate and bytes per second fwrite(&FileHeadStart, 1, 24, FileHandle); fwrite(&SampleRateInFile, 4, 1, FileHandle); fwrite(&BytesPerSecond, 4, 1, FileHandle); fwrite(&Multiplier, 1, 1, FileHandle); fwrite(&FileHeadEnd, 1, 7, FileHandle); fwrite(&FileLength, 4, 1, FileHandle); fwrite(&FileContents, 1, FileLength, FileHandle); // copies all the rest of the data, the samples themselves DataWrittenGiB += (FileSizeMiB/1024.0); // convert to gibibytes, GiB } // check if at the end - go to mode 2 if done if ((ProcessingStage == 1) && (CurrentSpeed >= NormalSpeedsEnd)) { ProcessingStage = 2; // change to mode 2 for doing the best speeds CurrentSpeed = NormalSpeedsStart; // return to the start for one more cycle } WithinRange = 0; // reset to update the speed } DebugTest[0]++; } } void Settings() { /* This function is used to set the song's title, the true speed sample rate, and speed ranges. To do (in order of importance): 1. Obtain the highest quality versions for as many songs as possible: Felix, FF9, Sno, Sonic 3D Blast, and a few others; */ // change the name of the song in the quotations here strcpy(SongName, "Final Fantasy 6 World"); // if true speed in the original base file is 50,000 Hz, use 1 here. If it is 100,000 Hz instead, use 2. Modifier = 1; // set the range for where the song sounds reasonably well NormalSpeedsStart = 50000; // The starting, slowest speed - below here is where the song is boring NormalSpeedsEnd = 150000; // The ending, fastest speed - above here is where the song is irritating // set the ranges of the best-sounding speeds for up to 3 "zones" - have something out of range if a zone is not used. BestSpeeds1Start = 70000; // The start, slowest, of first best zone BestSpeeds1End = 130000; // The end, fastest, of first best zone BestSpeeds2Start = 600000; // The start, slowest, of second best zone BestSpeeds2End = 700000; // The end, fastest, of second best zone BestSpeeds3Start = 800000; // The start, slowest, of third best zone BestSpeeds3End = 900000; // The end, fastest, of third best zone // set the number of loops used within each zone - use anything if the zone is not used; the array index number is one below the zone ZoneLapCount[0] = 2;

ZoneLapCount[1] = 3; ZoneLapCount[2] = 3; ZoneLapCount[3] = 0; ZoneLapCount[4] = 0; ZoneLapCount[5] = 0; ZoneLapCount[6] = 0; // set the speeds at which the sample rate in the MP3's changes to the given new rate (12,000 Hz uses 19 Kbps and 6000 Hz max) - have something out of range if not used FrequencyChangeover16K = 46000; // The 16,000 Hz speeds start here (23 Kbps and 60008000 Hz range) FrequencyChangeover24K = 62000; // The 24,000 Hz speeds start here (31 Kbps and 800012,000 Hz range) FrequencyChangeover32K = 93000; // The 32,000 Hz speeds start here (40 Kbps and 12,00016,000 Hz range) FrequencyChangeover48K = 124000; // The 48,000 Hz speeds start here (58 Kbps and 12,000-16,000 Hz range) /* The frequencies, speed ranges, sample rate changeovers, and loop counts are listed below for reference: What the columns mean: Notes - quick side notes related to the song, or things common with other songs. Song - the name of the song (obvious?) - the song's actual name is used, but the speed indication is left out (50 characters max) 16K - the speed (as a percentage) at which the sample rate changes from 12,000 Hz to 16,000 Hz // Used for 6000 to 8000 Hz range (used as the basis for the other frequencies) 24K - the speed (as a percentage) at which the sample rate changes from 16,000 Hz to 24,000 Hz // used for 8000 to 12,000 Hz range (multiply 16K's by 4/3 to find) 32K - the speed (as a percentage) at which the sample rate changes from 24,000 Hz to 32,000 Hz // used for 12,000 to 16,000 Hz range (multiply 24K's by 3/2 to find) 48K - the speed (as a percentage) at which the sample rate changes from 32,000 Hz to 48,000 Hz // used for 16,000+ Hz range (multiply 32K's by 4/3 to find) Best zones - the speed "zones" at which the song sounds the best (these use more speeds and more loops) - samplers use the normal range, but all best zone speeds Normal - the overall speed range that song uses - the point at which the song doesn't sound any more decent - samplers use the normal range, but all best zone speeds Loop order - the number of loops in each zone that is involved - samplers, special versions (actually 20), and non-looping versions use 1. +-----------+--------------------------------------------------+---+---+---+---+-------------------------+-------+-------------------------+ |Notes |Song |16K|24K|32K|48K|Best zones |Normal |loop order | +-----------+--------------------------------------------------+---+---+---+---+-------------------------+-------+-------------------------+ |01 |Aero the Acrobat Track 13 | | | | | | | |01 |Aero the Acrobat Track 14 | | | | | | | |01 |Aero the Acrobat Track 20 | | | | | | | |01 |Aero the Acrobat Track 20 20-lap | | | | | | |immune: special version |19 |Angelisland |37 |50 |75 |100|55-85, 85-130 |40-150 |2, 4, X, 6, 5 | |01 |Arctic Zone | | | | | | | |01 |Bahamas Zone | | | | | | |immune: nonlooping |01 |Battle Zone |90 |X |X |X |55-115 |40-140 |2, 6, 4 | |01 |Battle Zone sampler |70 |90 |140|X |immune: sampler |25-230 |immune: sampler | | |Between Planets |43 |58 |87 |116|80-130 |70-140 |immune: non-looping | |01 |Blaster Master Area 2 | | | | | | | |01 |Blaster Master Area 4 | | | | | | | |01? |Cactus Point | | | | | | |immune: non-looping | |Carnival Night |43 |58 |87 |X |65-95 |40-125 |immune: non-looping | |01 |Delfino Plaza | | | | | | | | |Desert Zone |46 |62 |93 |X |70-110 |40-140 |3, 10, 7 | | |Desert Zone 20-lap |46 |62 |93 |X |70-110 |70-110 |immune: special version | | |Du-di-da |43 |58 |87 |116|70-130 |50-160 |4, 10,

10 | |02 |Felix World 1 | | | | | | | | |Final Fantasy 1 Battle |39 |52 |78 |104|75-110 |60-140 |4, 7, 7 | |1A |Final Fantasy 1 Cave |39 |52 |78 |104|70-105, 105-160 |60-200 |2, 5, X, 7, 6 | |12 |Final Fantasy 1 World |39 |52 |78 |104|60-90, 90-135 |40-180 |2, 4, X, 6, 5 | | |Final Fantasy 1 World sampler |39 |52 |78 |104|immune: sampler |30270 |immune: sampler | |01 |Final Fantasy 5 Castle | | | | | | | |01 |Final Fantasy 6 Battle | | | | | | | | |Final Fantasy 6 World |46 |62 |93 |124|70-130 |50-150 |2, 3, 3 | | |Final Fantasy 6 World sampler |46 |62 |93 |124|immune: sampler |35260 |immune: sampler | |06 |Final Fantasy 7 Chocobo Farm | | | | | | | | 03 |Final Fantasy 7 Chocobo Racing |43 |58 |87 |116|65-125 |50150 |2, 4, 4 | | |Final Fantasy Tactics Shops |49 |66 |99 |132|60-130 |40-160 |4, 11, 11 | |01 |Gnasty's Loot | | | | | | |immune: non-looping |02 |Haunted Castle | | | | | | | |01 |Jaws (game) Ending Theme | | | | | | |immune: non-looping |01 |Looney Tunes Back In Action Map | | | | | | |immune: non-looping |01 |Marble Madness Practice Race | | | | | | | |06 |Marble Madness Ultimate Race | | | | | | | |02 |Marvin's House | | | | | | | | |Metropolis |37 |50 |75 |100|55-115 |40-135 |3, 7, 7 | |01 |Misty Bog | | | | | | |immune: non-looping |02 |Mountains So Beautiful | | | | | | | |02 |Mosphoran Highwaste | | | | | | | | |Mountains So Far Away |37 |50 |75 |100|50-75, 75-110 |35-150 |2, 4, X, 6, 6 | |01 |Nature in the Rough | | | | | | |immune: nonlooping |01 |Noki Bay | | | | | | | |01 |Oh What a World | | | | | | | |01 11 |Oh What a World 2 |110|150|X |X |65-100, 100-160, 160-250 |35300 |2, 4, X, 6, X, 8, 7 | |07 |Oh What a World X | | | | | | | | |On Parade |43 |58 |87 |116|65-125 |50-140 |3, 7, 6 | | |Out Where the Lake Is |46 |62 |93 |X |60-100 |30-125 |2, 5, 5 | |02 |Ozmone Plain | | | | | | | |01 |Playland | | | | | | |immune: non-looping |02 |Retro Zone | | | | | | |immune: non-looping |16 |Sky Chase |37 |50 |75 |100|60-90, 90-140 |50-150 |4, 7, X, 11, 10 | |05 |Sluminda | | | | | | | |01 |Sno | | | | | | |immune: non-looping |17 |Sonic 3 Extra Life |37 |50 |75 |100|30-55, 55-95 |20-125 |immune: non-looping | | |Sonic 3 Invincibility |37 |50 |75 |100|40-85 |30-125 |8, 21, 24 | |13 14 |Sonic 3 and Knuckles Extra Life |37 |50 |75 |100|30-50, 50-85, 85-150 |20-225 |immune: non-looping | |15 |Sonic 3 and Knuckles Invincibility |37 |50 |75 |100|45-90, 90-180 |30250 |8, 20, X, 40, 44 | | |Super Monkey Ball 2 Boat |41 |55 |82 |X |70-90 |50-125 |2, 3, 2 | | |Super Monkey Ball 2 Title |41 |55 |82 |X |60-80 |50-125 |10, 24, 18 | | |Super Monkey Ball 2 World 5 |41 |55 |82 |X |70-95 |50-125 |2, 5, 4 | | |Super Monkey Ball 2 World 6 |41 |55 |82 |110|65-120 |50-140 |2, 4, 4 | | |Super Monkey Ball 2 World 7 |41 |55 |82 |X |70-115 |50-140 |2, 7, 5 | |09 |Super Monkey Ball 2 World 7 sampler |41 |55 |82 |110|immune: sampler

|35-230 |immune: sampler | | |Super Monkey Ball 2 World 7 20-lap |41 |55 |82 |X |70-115 |70-115 |immune: special version | |10 08 |Target Zone |41 |55 |82 |110|110-180, 180-290, 290-480|60500 |3, 7, X, 13, X, 23, 18 | |01 |Tiny Toon theme | | | | | | | | |Tree Climb |43 |58 |87 |116|60-120 |40-140 |2, 3, 3 | | |Ultima Exodus Towns |43 |58 |87 |116|75-115 |60-170 |3, 7, 7 | |01 |Vegas Zone | | | | | | | | |Village Zone |43 |58 |87 |X |70-100 |50-125 |2, 4, 3 | | |Winter Land |37 |50 |75 |100|80-125 |50-180 |2, 5, 5 | |01 |Winter Zone Version 1 Remix | | | | | | | |18 |Winter Zone Version 1 |37 |50 |75 |100|55-85, 85-130 |30-180 |2, 3, X, 4, 4 | |01 |Winter Zone Version 2 Remix | | | | | | | |18 |Winter Zone Version 2 |37 |50 |75 |100|55-85, 85-130 |30-180 |2, 3, X, 4, 4 | |05 |Zeliard Title | | | | | | |immune: non-looping |03? 2B? 56?|Test case: this is a song's longest allowed title|120|160|240| |100-120, 180250, 300-400|100-300|10, 25, 15, 30, 20, 40, 30| +-----------+--------------------------------------------------+---+---+---+---+-------------------------+-------+-------------------------+ Notes: 01 This song uses a very old version and really needs to be updated 02 This song has a quality upgrade compared to 01, but used the old method for obtaining - a new one is in order 03 This song needs to be reprocessed due to the frequency change-over points changing. 04 This song needs to be reprocessed to extend the range of the best zone. Double the 16K's changeover is the basis to use for readjusting. 05 This song was recorded from a tape recorder and is of terrible quality, worse than 01. 06 This song has yet to be obtained. 07 This song has other variants that need to be obtained, but I'm unsure of just how many there are. 08 This song may need a 48 KHz version as there are still audible distortions even at 32 KHz. 09 This song's base file is incorrect and it needs to be redone. 0A This song's speed ranges have changed and it needs to be reprocessed, including any base files. 0B-0F - reserved for common things. 10 Target Zone has potential for the normal being beyond even 800% true speed (!!!). It's huge 110-480 best zone speed range means that it must be segmented. This is for best optimization of the MP3 player's capacity and loops. Segmenting is done when the speed range for the best zone is at least 2.2 and involves a square root or cubic root to keep within this 2.2 max span. For this song, it's based on the cubic root of "fast/slow", "480/110", or a bit over 1.6 (mental estimate). This gives 110180, 180-290, 290-480 as the segments. 11 Because the best zone is so vast (65-250), it needs to be segmented into different subzones for best optimization. The segmenting involves the speeds 65-100, 100-160, and 160-250. 12 This song's best zone, 60-135, is rather wide and has thus been segmented into 60-90 and 90-135. 13 This song's normal zone can drop as low as 15% true speed, highly unusual. 14 This song's best zone, 30-150, is truly gigantic and is segmented into 30-50, 50-85, and 85150 segments because of it. 15 This song's best zone, 45-180, is vast and has been segmented into 45-90 and 90-180. 16 This song's best zone is also large, 60-140 and is split into 60-90 and 90-140. 17 Yet another song with its best zone being large - 30-95 is segmented into 30-55 and 55-95. 18 These two songs are nearly identical to each other in many ways. The length (56 measures vs 48), affecting loop count, and intrument timing are a bit different. The wide best zone span, 55-130, is segmented into 55-85 and 85130 for both as this aspect is the same. 19 Like many songs with Sonic, for some reason, this song, too, has a large 55-130 best range with 55-85 and 85-130 as it's two "zones". 1A This song's best zone, 70-160, is a bit too large and is thus segmented into 70-105 and 105-160. 1B When processing a song, do the following 11 stages:

1. Determine what the normal speed range is. 2. Determine where the best-sounding speeds lie. 3. Determine what lowpass frequency has the intensity less than 0.05 max. 4. Use this frequency to determine the frequency changeover points. 5. With the best and normal speeds obtained, determine how many loops are needed: 5a. If the song is non-looping, a sampler, or is a special version (like a 20-lap) it's immune to this and must be counted as 1. 5b. For the speeds in any range, the base speed for determining the loop count is the exponential mid-point (40 for a 20-80 range). 5c. The basis for the normal speeds is 4 minutes. 5d. If the song has no intro or the intro is well-liked, the basis for 6 minutes. 5e. If the intro is not liked, the basis is 8 minutes. 6. Save each unique version as a WAV file and have the number after "base" be that of the number of loops used, with 3 digits for leading zeros. 7. Adjust the settings above based on the information from stages 1 through 5. 8. Delete any leftover files from the previous run, if any, then run this program. 9. Use the BAT files to convert to MP3. 10. Copy the output files into a folder dedicated to the game then the song itself. 11. Copy this folder to the MP3 player to finish. */ } int main() { // main function, required with C, but used to call the related functions Settings(); // gets some settings set CreateOutputFiles(); // initiate the loop for creating the output files copying the data above changing the 8 bytes as needed return 0; // function must return something, usually 0 }

You might also like