using static SAMSharp.Process; using static SAMSharp.Sam; using static SAMSharp.Transitions; namespace SAMSharp { class Renderer { const int PHONEME_PERIOD = 1; const int PHONEME_QUESTION = 2; const int RISING_INFLECTION = 1; const int FALLING_INFLECTION = 255; static byte[] tab48426 = { 0x18, 0x1A, 0x17, 0x17, 0x17 }; static byte[] tab47492 = { 0 , 0 , 0xE0 , 0xE6 , 0xEC , 0xF3 , 0xF9 , 0 , 6 , 0xC , 6 }; static byte[] amplitudeRescale = { 0 , 1 , 2 , 2 , 2 , 3 , 3 , 4 , 4 , 5 , 6 , 8 , 9 ,0xB ,0xD ,0xF, 0 //17 elements? }; // Used to decide which phoneme's blend lengths. The candidate with the lower score is selected. // tab45856 public static byte[] blendRank = { 0 , 0x1F , 0x1F , 0x1F , 0x1F , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 5 , 5 , 2 ,0xA , 2 , 8 , 5 , 5 ,0xB ,0xA , 9 , 8 , 8 , 0xA0 , 8 , 8 , 0x17 , 0x1F , 0x12 , 0x12 , 0x12 , 0x12 , 0x1E , 0x1E , 0x14 , 0x14 , 0x14 , 0x14 , 0x17 , 0x17 , 0x1A , 0x1A , 0x1D , 0x1D , 2 , 2 , 2 , 2 , 2 , 2 , 0x1A , 0x1D , 0x1B , 0x1A , 0x1D , 0x1B , 0x1A , 0x1D , 0x1B , 0x1A , 0x1D , 0x1B , 0x17 , 0x1D , 0x17 , 0x17 , 0x1D , 0x17 , 0x17 , 0x1D , 0x17 , 0x17 , 0x1D , 0x17 , 0x17 , 0x17 }; // Number of frames at the end of a phoneme devoted to interpolating to next phoneme's final value //tab45696 public static byte[] outBlendLength = { 0 , 2 , 2 , 2 , 2 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 3 , 2 , 4 , 4 , 2 , 2 , 2 , 2 , 2 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 2 , 2 , 2 , 1 , 0 , 1 , 0 , 1 , 0 , 5 , 5 , 5 , 5 , 5 , 4 , 4 , 2 , 0 , 1 , 2 , 0 , 1 , 2 , 0 , 1 , 2 , 0 , 1 , 2 , 0 , 2 , 2 , 0 , 1 , 3 , 0 , 2 , 3 , 0 , 2 , 0xA0 , 0xA0 }; // Number of frames at beginning of a phoneme devoted to interpolating to phoneme's final value // tab45776 public static byte[] inBlendLength = { 0 , 2 , 2 , 2 , 2 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 3 , 3 , 4 , 4 , 3 , 3 , 3 , 3 , 3 , 1 , 2 , 3 , 2 , 1 , 3 , 3 , 3 , 3 , 1 , 1 , 3 , 3 , 3 , 2 , 2 , 3 , 2 , 3 , 0 , 0 , 5 , 5 , 5 , 5 , 4 , 4 , 2 , 0 , 2 , 2 , 0 , 3 , 2 , 0 , 4 , 2 , 0 , 3 , 2 , 0 , 2 , 2 , 0 , 2 , 3 , 0 , 3 , 3 , 0 , 3 , 0xB0 , 0xA0 }; // Looks like it's used as bit flags // High bits masked by 248 (11111000) // // 32: S* 241 11110001 // 33: SH 226 11100010 // 34: F* 211 11010011 // 35: TH 187 10111011 // 36: /H 124 01111100 // 37: /X 149 10010101 // 38: Z* 1 00000001 // 39: ZH 2 00000010 // 40: V* 3 00000011 // 41: DH 3 00000011 // 43: ** 114 01110010 // 45: ** 2 00000010 // 67: ** 27 00011011 // 70: ** 25 00011001 // tab45936 public static byte[] sampledConsonantFlags = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0xF1 , 0xE2 , 0xD3 , 0xBB , 0x7C , 0x95 , 1 , 2 , 3 , 3 , 0 , 0x72 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x1B , 0 , 0 , 0x19 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }; //tab45056 static byte[] freq1data = { 0x00 ,0x13 ,0x13 ,0x13 ,0x13 , 0xA , 0xE ,0x12 , 0x18 ,0x1A ,0x16 ,0x14 ,0x10 ,0x14 , 0xE ,0x12 , 0xE ,0x12 ,0x12 ,0x10 , 0xC , 0xE , 0xA ,0x12 , 0xE ,0xA , 8 , 6 , 6 , 6 , 6 ,0x11 , 6 , 6 , 6 , 6 ,0xE , 0x10 , 9 ,0xA , 8 ,0xA , 6 , 6 , 6 , 5 , 6 , 0 , 0x12 , 0x1A , 0x14 , 0x1A , 0x12 ,0xC , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 ,0xA ,0xA , 6 , 6 , 6 , 0x2C , 0x13 }; //tab451356 static byte[] freq2data = { 0x00 , 0x43 , 0x43 , 0x43 , 0x43 , 0x54 , 0x48 , 0x42 , 0x3E , 0x28 , 0x2C , 0x1E , 0x24 , 0x2C , 0x48 , 0x30 , 0x24 , 0x1E , 0x32 , 0x24 , 0x1C , 0x44 , 0x18 , 0x32 , 0x1E , 0x18 , 0x52 , 0x2E , 0x36 , 0x56 , 0x36 , 0x43 , 0x49 , 0x4F , 0x1A , 0x42 , 0x49 , 0x25 , 0x33 , 0x42 , 0x28 , 0x2F , 0x4F , 0x4F , 0x42 , 0x4F , 0x6E , 0x00 , 0x48 , 0x26 , 0x1E , 0x2A , 0x1E , 0x22 , 0x1A , 0x1A , 0x1A , 0x42 , 0x42 , 0x42 , 0x6E , 0x6E , 0x6E , 0x54 , 0x54 , 0x54 , 0x1A , 0x1A , 0x1A , 0x42 , 0x42 , 0x42 , 0x6D , 0x56 , 0x6D , 0x54 , 0x54 , 0x54 , 0x7F , 0x7F }; //tab45216 static byte[] freq3data = { 0x00 , 0x5B , 0x5B , 0x5B , 0x5B , 0x6E , 0x5D , 0x5B , 0x58 , 0x59 , 0x57 , 0x58 , 0x52 , 0x59 , 0x5D , 0x3E , 0x52 , 0x58 , 0x3E , 0x6E , 0x50 , 0x5D , 0x5A , 0x3C , 0x6E , 0x5A , 0x6E , 0x51 , 0x79 , 0x65 , 0x79 , 0x5B , 0x63 , 0x6A , 0x51 , 0x79 , 0x5D , 0x52 , 0x5D , 0x67 , 0x4C , 0x5D , 0x65 , 0x65 , 0x79 , 0x65 , 0x79 , 0x00 , 0x5A , 0x58 , 0x58 , 0x58 , 0x58 , 0x52 , 0x51 , 0x51 , 0x51 , 0x79 , 0x79 , 0x79 , 0x70 , 0x6E , 0x6E , 0x5E , 0x5E , 0x5E , 0x51 , 0x51 , 0x51 , 0x79 , 0x79 , 0x79 , 0x65 , 0x65 , 0x70 , 0x5E , 0x5E , 0x5E , 0x08 , 0x01 }; static byte[] ampl1data = { 0 , 0 , 0 , 0 , 0 ,0xD ,0xD ,0xE , 0xF ,0xF ,0xF ,0xF ,0xF ,0xC ,0xD ,0xC , 0xF ,0xF ,0xD ,0xD ,0xD ,0xE ,0xD ,0xC , 0xD ,0xD ,0xD ,0xC , 9 , 9 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,0xB ,0xB , 0xB ,0xB , 0 , 0 , 1 ,0xB , 0 , 2 , 0xE ,0xF ,0xF ,0xF ,0xF ,0xD , 2 , 4 , 0 , 2 , 4 , 0 , 1 , 4 , 0 , 1 , 4 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,0xC , 0 , 0 , 0 , 0 ,0xF ,0xF }; static byte[] ampl2data = { 0 , 0 , 0 , 0 , 0 ,0xA ,0xB ,0xD , 0xE ,0xD ,0xC ,0xC ,0xB , 9 ,0xB ,0xB , 0xC ,0xC ,0xC , 8 , 8 ,0xC , 8 ,0xA , 8 , 8 ,0xA , 3 , 9 , 6 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 3 , 5 , 3 , 4 , 0 , 0 , 0 , 5 ,0xA , 2 , 0xE ,0xD ,0xC ,0xD ,0xC , 8 , 0 , 1 , 0 , 0 , 1 , 0 , 0 , 1 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,0xA , 0 , 0 ,0xA , 0 , 0 , 0 }; static byte[] ampl3data = { 0 , 0 , 0 , 0 , 0 , 8 , 7 , 8 , 8 , 1 , 1 , 0 , 1 , 0 , 7 , 5 , 1 , 0 , 6 , 1 , 0 , 7 , 0 , 5 , 1 , 0 , 8 , 0 , 0 , 3 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 1 ,0xE , 1 , 9 , 1 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 7 , 0 , 0 , 5 , 0 , 0x13 , 0x10 }; //tab42240 public static byte[] sinus = { 0x00 , 0x00 , 0x00 , 0x10 , 0x10 , 0x10 , 0x10 , 0x10 , 0x10 , 0x20 , 0x20 , 0x20 , 0x20 , 0x20 , 0x20 , 0x30 , 0x30 , 0x30 , 0x30 , 0x30 , 0x30 , 0x30 , 0x40 , 0x40 , 0x40 , 0x40 , 0x40 , 0x40 , 0x40 , 0x50 , 0x50 , 0x50 , 0x50 , 0x50 , 0x50 , 0x50 , 0x50 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x60 , 0x50 , 0x50 , 0x50 , 0x50 , 0x50 , 0x50 , 0x50 , 0x50 , 0x40 , 0x40 , 0x40 , 0x40 , 0x40 , 0x40 , 0x40 , 0x30 , 0x30 , 0x30 , 0x30 , 0x30 , 0x30 , 0x30 , 0x20 , 0x20 , 0x20 , 0x20 , 0x20 , 0x20 , 0x10 , 0x10 , 0x10 , 0x10 , 0x10 , 0x10 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0xF0 , 0xF0 , 0xF0 , 0xF0 , 0xF0 , 0xF0 , 0xE0 , 0xE0 , 0xE0 , 0xE0 , 0xE0 , 0xE0 , 0xD0 , 0xD0 , 0xD0 , 0xD0 , 0xD0 , 0xD0 , 0xD0 , 0xC0 , 0xC0 , 0xC0 , 0xC0 , 0xC0 , 0xC0 , 0xC0 , 0xB0 , 0xB0 , 0xB0 , 0xB0 , 0xB0 , 0xB0 , 0xB0 , 0xB0 , 0xA0 , 0xA0 , 0xA0 , 0xA0 , 0xA0 , 0xA0 , 0xA0 , 0xA0 , 0xA0 , 0xA0 , 0xA0 , 0xA0 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0xA0 , 0xA0 , 0xA0 , 0xA0 , 0xA0 , 0xA0 , 0xA0 , 0xA0 , 0xA0 , 0xA0 , 0xA0 , 0xA0 , 0xB0 , 0xB0 , 0xB0 , 0xB0 , 0xB0 , 0xB0 , 0xB0 , 0xB0 , 0xC0 , 0xC0 , 0xC0 , 0xC0 , 0xC0 , 0xC0 , 0xC0 , 0xD0 , 0xD0 , 0xD0 , 0xD0 , 0xD0 , 0xD0 , 0xD0 , 0xE0 , 0xE0 , 0xE0 , 0xE0 , 0xE0 , 0xE0 , 0xF0 , 0xF0 , 0xF0 , 0xF0 , 0xF0 , 0xF0 , 0x00 , 0x00 }; //tab42496 public static byte[] rectangle = { 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 }; //tab42752 public static byte[] multtable = { 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 , 0x01 , 0x02 , 0x02 , 0x03 , 0x03 , 0x04 , 0x04 , 0x05 , 0x05 , 0x06 , 0x06 , 0x07 , 0x07 , 0x00 , 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 , 0x08 , 0x09 , 0x0A , 0x0B , 0x0C , 0x0D , 0x0E , 0x0F , 0x00 , 0x01 , 0x03 , 0x04 , 0x06 , 0x07 , 0x09 , 0x0A , 0x0C , 0x0D , 0x0F , 0x10 , 0x12 , 0x13 , 0x15 , 0x16 , 0x00 , 0x02 , 0x04 , 0x06 , 0x08 , 0x0A , 0x0C , 0x0E , 0x10 , 0x12 , 0x14 , 0x16 , 0x18 , 0x1A , 0x1C , 0x1E , 0x00 , 0x02 , 0x05 , 0x07 , 0x0A , 0x0C , 0x0F , 0x11 , 0x14 , 0x16 , 0x19 , 0x1B , 0x1E , 0x20 , 0x23 , 0x25 , 0x00 , 0x03 , 0x06 , 0x09 , 0x0C , 0x0F , 0x12 , 0x15 , 0x18 , 0x1B , 0x1E , 0x21 , 0x24 , 0x27 , 0x2A , 0x2D , 0x00 , 0x03 , 0x07 , 0x0A , 0x0E , 0x11 , 0x15 , 0x18 , 0x1C , 0x1F , 0x23 , 0x26 , 0x2A , 0x2D , 0x31 , 0x34 , 0x00 , 0xFC , 0xF8 , 0xF4 , 0xF0 , 0xEC , 0xE8 , 0xE4 , 0xE0 , 0xDC , 0xD8 , 0xD4 , 0xD0 , 0xCC , 0xC8 , 0xC4 , 0x00 , 0xFC , 0xF9 , 0xF5 , 0xF2 , 0xEE , 0xEB , 0xE7 , 0xE4 , 0xE0 , 0xDD , 0xD9 , 0xD6 , 0xD2 , 0xCF , 0xCB , 0x00 , 0xFD , 0xFA , 0xF7 , 0xF4 , 0xF1 , 0xEE , 0xEB , 0xE8 , 0xE5 , 0xE2 , 0xDF , 0xDC , 0xD9 , 0xD6 , 0xD3 , 0x00 , 0xFD , 0xFB , 0xF8 , 0xF6 , 0xF3 , 0xF1 , 0xEE , 0xEC , 0xE9 , 0xE7 , 0xE4 , 0xE2 , 0xDF , 0xDD , 0xDA , 0x00 , 0xFE , 0xFC , 0xFA , 0xF8 , 0xF6 , 0xF4 , 0xF2 , 0xF0 , 0xEE , 0xEC , 0xEA , 0xE8 , 0xE6 , 0xE4 , 0xE2 , 0x00 , 0xFE , 0xFD , 0xFB , 0xFA , 0xF8 , 0xF7 , 0xF5 , 0xF4 , 0xF2 , 0xF1 , 0xEF , 0xEE , 0xEC , 0xEB , 0xE9 , 0x00 , 0xFF , 0xFE , 0xFD , 0xFC , 0xFB , 0xFA , 0xF9 , 0xF8 , 0xF7 , 0xF6 , 0xF5 , 0xF4 , 0xF3 , 0xF2 , 0xF1 , 0x00 , 0xFF , 0xFF , 0xFE , 0xFE , 0xFD , 0xFD , 0xFC , 0xFC , 0xFB , 0xFB , 0xFA , 0xFA , 0xF9 , 0xF9 , 0xF8 }; //random data ? static byte[] sampleTable = { //00 0x38 , 0x84 , 0x6B , 0x19 , 0xC6 , 0x63 , 0x18 , 0x86 , 0x73 , 0x98 , 0xC6 , 0xB1 , 0x1C , 0xCA , 0x31 , 0x8C , 0xC7 , 0x31 , 0x88 , 0xC2 , 0x30 , 0x98 , 0x46 , 0x31 , 0x18 , 0xC6 , 0x35 ,0xC , 0xCA , 0x31 ,0xC , 0xC6 //20 , 0x21 , 0x10 , 0x24 , 0x69 , 0x12 , 0xC2 , 0x31 , 0x14 , 0xC4 , 0x71 , 8 , 0x4A , 0x22 , 0x49 , 0xAB , 0x6A , 0xA8 , 0xAC , 0x49 , 0x51 , 0x32 , 0xD5 , 0x52 , 0x88 , 0x93 , 0x6C , 0x94 , 0x22 , 0x15 , 0x54 , 0xD2 , 0x25 //40 , 0x96 , 0xD4 , 0x50 , 0xA5 , 0x46 , 0x21 , 8 , 0x85 , 0x6B , 0x18 , 0xC4 , 0x63 , 0x10 , 0xCE , 0x6B , 0x18 , 0x8C , 0x71 , 0x19 , 0x8C , 0x63 , 0x35 ,0xC , 0xC6 , 0x33 , 0x99 , 0xCC , 0x6C , 0xB5 , 0x4E , 0xA2 , 0x99 //60 , 0x46 , 0x21 , 0x28 , 0x82 , 0x95 , 0x2E , 0xE3 , 0x30 , 0x9C , 0xC5 , 0x30 , 0x9C , 0xA2 , 0xB1 , 0x9C , 0x67 , 0x31 , 0x88 , 0x66 , 0x59 , 0x2C , 0x53 , 0x18 , 0x84 , 0x67 , 0x50 , 0xCA , 0xE3 ,0xA , 0xAC , 0xAB , 0x30 //80 , 0xAC , 0x62 , 0x30 , 0x8C , 0x63 , 0x10 , 0x94 , 0x62 , 0xB1 , 0x8C , 0x82 , 0x28 , 0x96 , 0x33 , 0x98 , 0xD6 , 0xB5 , 0x4C , 0x62 , 0x29 , 0xA5 , 0x4A , 0xB5 , 0x9C , 0xC6 , 0x31 , 0x14 , 0xD6 , 0x38 , 0x9C , 0x4B , 0xB4 //A0 , 0x86 , 0x65 , 0x18 , 0xAE , 0x67 , 0x1C , 0xA6 , 0x63 , 0x19 , 0x96 , 0x23 , 0x19 , 0x84 , 0x13 , 8 , 0xA6 , 0x52 , 0xAC , 0xCA , 0x22 , 0x89 , 0x6E , 0xAB , 0x19 , 0x8C , 0x62 , 0x34 , 0xC4 , 0x62 , 0x19 , 0x86 , 0x63 //C0 , 0x18 , 0xC4 , 0x23 , 0x58 , 0xD6 , 0xA3 , 0x50 , 0x42 , 0x54 , 0x4A , 0xAD , 0x4A , 0x25 , 0x11 , 0x6B , 0x64 , 0x89 , 0x4A , 0x63 , 0x39 , 0x8A , 0x23 , 0x31 , 0x2A , 0xEA , 0xA2 , 0xA9 , 0x44 , 0xC5 , 0x12 , 0xCD , 0x42 //E0 , 0x34 , 0x8C , 0x62 , 0x18 , 0x8C , 0x63 , 0x11 , 0x48 , 0x66 , 0x31 , 0x9D , 0x44 , 0x33 , 0x1D , 0x46 , 0x31 , 0x9C , 0xC6 , 0xB1 ,0xC , 0xCD , 0x32 , 0x88 , 0xC4 , 0x73 , 0x18 , 0x86 , 0x73 , 8 , 0xD6 , 0x63 , 0x58 //100 , 7 , 0x81 , 0xE0 , 0xF0 , 0x3C , 7 , 0x87 , 0x90 , 0x3C , 0x7C ,0xF , 0xC7 , 0xC0 , 0xC0 , 0xF0 , 0x7C , 0x1E , 7 , 0x80 , 0x80 , 0 , 0x1C , 0x78 , 0x70 , 0xF1 , 0xC7 , 0x1F , 0xC0 ,0xC , 0xFE , 0x1C , 0x1F //120 , 0x1F ,0xE ,0xA , 0x7A , 0xC0 , 0x71 , 0xF2 , 0x83 , 0x8F , 3 ,0xF ,0xF ,0xC , 0 , 0x79 , 0xF8 , 0x61 , 0xE0 , 0x43 ,0xF , 0x83 , 0xE7 , 0x18 , 0xF9 , 0xC1 , 0x13 , 0xDA , 0xE9 , 0x63 , 0x8F ,0xF , 0x83 //140 , 0x83 , 0x87 , 0xC3 , 0x1F , 0x3C , 0x70 , 0xF0 , 0xE1 , 0xE1 , 0xE3 , 0x87 , 0xB8 , 0x71 ,0xE , 0x20 , 0xE3 , 0x8D , 0x48 , 0x78 , 0x1C , 0x93 , 0x87 , 0x30 , 0xE1 , 0xC1 , 0xC1 , 0xE4 , 0x78 , 0x21 , 0x83 , 0x83 , 0xC3 //160 , 0x87 , 6 , 0x39 , 0xE5 , 0xC3 , 0x87 , 7 ,0xE , 0x1C , 0x1C , 0x70 , 0xF4 , 0x71 , 0x9C , 0x60 , 0x36 , 0x32 , 0xC3 , 0x1E , 0x3C , 0xF3 , 0x8F ,0xE , 0x3C , 0x70 , 0xE3 , 0xC7 , 0x8F ,0xF ,0xF ,0xE , 0x3C //180 , 0x78 , 0xF0 , 0xE3 , 0x87 , 6 , 0xF0 , 0xE3 , 7 , 0xC1 , 0x99 , 0x87 ,0xF , 0x18 , 0x78 , 0x70 , 0x70 , 0xFC , 0xF3 , 0x10 , 0xB1 , 0x8C , 0x8C , 0x31 , 0x7C , 0x70 , 0xE1 , 0x86 , 0x3C , 0x64 , 0x6C , 0xB0 , 0xE1 //1A0 , 0xE3 ,0xF , 0x23 , 0x8F ,0xF , 0x1E , 0x3E , 0x38 , 0x3C , 0x38 , 0x7B , 0x8F , 7 ,0xE , 0x3C , 0xF4 , 0x17 , 0x1E , 0x3C , 0x78 , 0xF2 , 0x9E , 0x72 , 0x49 , 0xE3 , 0x25 , 0x36 , 0x38 , 0x58 , 0x39 , 0xE2 , 0xDE //1C0 , 0x3C , 0x78 , 0x78 , 0xE1 , 0xC7 , 0x61 , 0xE1 , 0xE1 , 0xB0 , 0xF0 , 0xF0 , 0xC3 , 0xC7 ,0xE , 0x38 , 0xC0 , 0xF0 , 0xCE , 0x73 , 0x73 , 0x18 , 0x34 , 0xB0 , 0xE1 , 0xC7 , 0x8E , 0x1C , 0x3C , 0xF8 , 0x38 , 0xF0 , 0xE1 //1E0 , 0xC1 , 0x8B , 0x86 , 0x8F , 0x1C , 0x78 , 0x70 , 0xF0 , 0x78 , 0xAC , 0xB1 , 0x8F , 0x39 , 0x31 , 0xDB , 0x38 , 0x61 , 0xC3 ,0xE ,0xE , 0x38 , 0x78 , 0x73 , 0x17 , 0x1E , 0x39 , 0x1E , 0x38 , 0x64 , 0xE1 , 0xF1 , 0xC1 //200 , 0x4E ,0xF , 0x40 , 0xA2 , 2 , 0xC5 , 0x8F , 0x81 , 0xA1 , 0xFC , 0x12 , 8 , 0x64 , 0xE0 , 0x3C , 0x22 , 0xE0 , 0x45 , 7 , 0x8E ,0xC , 0x32 , 0x90 , 0xF0 , 0x1F , 0x20 , 0x49 , 0xE0 , 0xF8 ,0xC , 0x60 , 0xF0 //220 , 0x17 , 0x1A , 0x41 , 0xAA , 0xA4 , 0xD0 , 0x8D , 0x12 , 0x82 , 0x1E , 0x1E , 3 , 0xF8 , 0x3E , 3 ,0xC , 0x73 , 0x80 , 0x70 , 0x44 , 0x26 , 3 , 0x24 , 0xE1 , 0x3E , 4 , 0x4E , 4 , 0x1C , 0xC1 , 9 , 0xCC //240 , 0x9E , 0x90 , 0x21 , 7 , 0x90 , 0x43 , 0x64 , 0xC0 , 0xF , 0xC6 , 0x90 , 0x9C , 0xC1 , 0x5B , 3 , 0xE2 , 0x1D , 0x81 , 0xE0 , 0x5E , 0x1D , 3 , 0x84 , 0xB8 , 0x2C ,0xF , 0x80 , 0xB1 , 0x83 , 0xE0 , 0x30 , 0x41 //260 , 0x1E , 0x43 , 0x89 , 0x83 , 0x50 , 0xFC , 0x24 , 0x2E , 0x13 , 0x83 , 0xF1 , 0x7C , 0x4C , 0x2C , 0xC9 ,0xD , 0x83 , 0xB0 , 0xB5 , 0x82 , 0xE4 , 0xE8 , 6 , 0x9C , 7 , 0xA0 , 0x99 , 0x1D , 7 , 0x3E , 0x82 , 0x8F //280 , 0x70 , 0x30 , 0x74 , 0x40 , 0xCA , 0x10 , 0xE4 , 0xE8 , 0xF , 0x92 , 0x14 , 0x3F , 6 , 0xF8 , 0x84 , 0x88 , 0x43 , 0x81 ,0xA , 0x34 , 0x39 , 0x41 , 0xC6 , 0xE3 , 0x1C , 0x47 , 3 , 0xB0 , 0xB8 , 0x13 ,0xA , 0xC2 //2A0 , 0x64 , 0xF8 , 0x18 , 0xF9 , 0x60 , 0xB3 , 0xC0 , 0x65 , 0x20 , 0x60 , 0xA6 , 0x8C , 0xC3 , 0x81 , 0x20 , 0x30 , 0x26 , 0x1E , 0x1C , 0x38 , 0xD3 , 1 , 0xB0 , 0x26 , 0x40 , 0xF4 ,0xB , 0xC3 , 0x42 , 0x1F , 0x85 , 0x32 //2C0 , 0x26 , 0x60 , 0x40 , 0xC9 , 0xCB , 1 , 0xEC , 0x11 , 0x28 , 0x40 , 0xFA , 4 , 0x34 , 0xE0 , 0x70 , 0x4C , 0x8C , 0x1D , 7 , 0x69 , 3 , 0x16 , 0xC8 , 4 , 0x23 , 0xE8 , 0xC6 , 0x9A ,0xB , 0x1A , 3 , 0xE0 //2E0 , 0x76 , 6 , 5 , 0xCF , 0x1E , 0xBC , 0x58 , 0x31 , 0x71 , 0x66 , 0 , 0xF8 , 0x3F , 4 , 0xFC ,0xC , 0x74 , 0x27 , 0x8A , 0x80 , 0x71 , 0xC2 , 0x3A , 0x26 , 6 , 0xC0 , 0x1F , 5 ,0xF , 0x98 , 0x40 , 0xAE //300 , 1 , 0x7F , 0xC0 , 7 , 0xFF , 0 ,0xE , 0xFE , 0 , 3 , 0xDF , 0x80 , 3 , 0xEF , 0x80 , 0x1B , 0xF1 , 0xC2 , 0 , 0xE7 , 0xE0 , 0x18 , 0xFC , 0xE0 , 0x21 , 0xFC , 0x80 , 0x3C , 0xFC , 0x40 ,0xE , 0x7E //320 , 0 , 0x3F , 0x3E , 0 ,0xF , 0xFE , 0 , 0x1F , 0xFF , 0 , 0x3E , 0xF0 , 7 , 0xFC , 0 , 0x7E , 0x10 , 0x3F , 0xFF , 0 , 0x3F , 0x38 ,0xE , 0x7C , 1 , 0x87 ,0xC , 0xFC , 0xC7 , 0 , 0x3E , 4 //340 , 0xF , 0x3E , 0x1F ,0xF ,0xF , 0x1F ,0xF , 2 , 0x83 , 0x87 , 0xCF , 3 , 0x87 ,0xF , 0x3F , 0xC0 , 7 , 0x9E , 0x60 , 0x3F , 0xC0 , 3 , 0xFE , 0 , 0x3F , 0xE0 , 0x77 , 0xE1 , 0xC0 , 0xFE , 0xE0 , 0xC3 //360 , 0xE0 , 1 , 0xDF , 0xF8 , 3 , 7 , 0 , 0x7E , 0x70 , 0 , 0x7C , 0x38 , 0x18 , 0xFE ,0xC , 0x1E , 0x78 , 0x1C , 0x7C , 0x3E ,0xE , 0x1F , 0x1E , 0x1E , 0x3E , 0 , 0x7F , 0x83 , 7 , 0xDB , 0x87 , 0x83 //380 , 7 , 0xC7 , 7 , 0x10 , 0x71 , 0xFF , 0 , 0x3F , 0xE2 , 1 , 0xE0 , 0xC1 , 0xC3 , 0xE1 , 0 , 0x7F , 0xC0 , 5 , 0xF0 , 0x20 , 0xF8 , 0xF0 , 0x70 , 0xFE , 0x78 , 0x79 , 0xF8 , 2 , 0x3F ,0xC , 0x8F , 3 //3a0 , 0xF , 0x9F , 0xE0 , 0xC1 , 0xC7 , 0x87 , 3 , 0xC3 , 0xC3 , 0xB0 , 0xE1 , 0xE1 , 0xC1 , 0xE3 , 0xE0 , 0x71 , 0xF0 , 0 , 0xFC , 0x70 , 0x7C ,0xC , 0x3E , 0x38 , 0xE , 0x1C , 0x70 , 0xC3 , 0xC7 , 3 , 0x81 , 0xC1 //3c0 , 0xC7 , 0xE7 , 0 ,0xF , 0xC7 , 0x87 , 0x19 , 9 , 0xEF , 0xC4 , 0x33 , 0xE0 , 0xC1 , 0xFC , 0xF8 , 0x70 , 0xF0 , 0x78 , 0xF8 , 0xF0 , 0x61 , 0xC7 , 0 , 0x1F , 0xF8 , 1 , 0x7C , 0xF8 , 0xF0 , 0x78 , 0x70 , 0x3C //3e0 , 0x7C , 0xCE ,0xE , 0x21 , 0x83 , 0xCF , 8 , 7 , 0x8F , 8 , 0xC1 , 0x87 , 0x8F , 0x80 , 0xC7 , 0xE3 , 0 , 7 , 0xF8 , 0xE0 , 0xEF , 0 , 0x39 , 0xF7 , 0x80 ,0xE , 0xF8 , 0xE1 , 0xE3 , 0xF8 , 0x21 , 0x9F //400 , 0xC0 , 0xFF , 3 , 0xF8 , 7 , 0xC0 , 0x1F , 0xF8 , 0xC4 , 4 , 0xFC , 0xC4 , 0xC1 , 0xBC , 0x87 , 0xF0 , 0xF , 0xC0 , 0x7F , 5 , 0xE0 , 0x25 , 0xEC , 0xC0 , 0x3E , 0x84 , 0x47 , 0xF0 , 0x8E , 3 , 0xF8 , 3 //420 , 0xFB , 0xC0 , 0x19 , 0xF8 , 7 , 0x9C ,0xC , 0x17 , 0xF8 , 7 , 0xE0 , 0x1F , 0xA1 , 0xFC ,0xF , 0xFC , 1 , 0xF0 , 0x3F , 0 , 0xFE , 3 , 0xF0 , 0x1F , 0 , 0xFD , 0 , 0xFF , 0x88 ,0xD , 0xF9 , 1 //440 , 0xFF , 0 , 0x70 , 7 , 0xC0 , 0x3E , 0x42 , 0xF3 , 0xD , 0xC4 , 0x7F , 0x80 , 0xFC , 7 , 0xF0 , 0x5E , 0xC0 , 0x3F , 0 , 0x78 , 0x3F , 0x81 , 0xFF , 1 , 0xF8 , 1 , 0xC3 , 0xE8 ,0xC , 0xE4 , 0x64 , 0x8F ////460 , 0xE4 ,0xF , 0xF0 , 7 , 0xF0 , 0xC2 , 0x1F , 0 , 0x7F , 0xC0 , 0x6F , 0x80 , 0x7E , 3 , 0xF8 , 7 , 0xF0 , 0x3F , 0xC0 , 0x78 ,0xF , 0x82 , 7 , 0xFE , 0x22 , 0x77 , 0x70 , 2 , 0x76 , 3 , 0xFE , 0 //480 , 0xFE , 0x67 , 0 , 0x7C , 0xC7 , 0xF1 , 0x8E , 0xC6 , 0x3B , 0xE0 , 0x3F , 0x84 , 0xF3 , 0x19 , 0xD8 , 3 , 0x99 , 0xFC , 9 , 0xB8 ,0xF , 0xF8 , 0 , 0x9D , 0x24 , 0x61 , 0xF9 ,0xD , 0 , 0xFD , 3 , 0xF0 //4a0 , 0x1F , 0x90 , 0x3F , 1 , 0xF8 , 0x1F , 0xD0 ,0xF , 0xF8 , 0x37 , 1 , 0xF8 , 7 , 0xF0 ,0xF , 0xC0 , 0x3F , 0 , 0xFE , 3 , 0xF8 ,0xF , 0xC0 , 0x3F , 0 , 0xFA , 3 , 0xF0 ,0xF , 0x80 , 0xFF , 1 //4c0 , 0xB8 , 7 , 0xF0 , 1 , 0xFC , 1 , 0xBC , 0x80 , 0x13 , 0x1E , 0 , 0x7F , 0xE1 , 0x40 , 0x7F , 0xA0 , 0x7F , 0xB0 , 0 , 0x3F , 0xC0 , 0x1F , 0xC0 , 0x38 , 0xF , 0xF0 , 0x1F , 0x80 , 0xFF , 1 , 0xFC , 3 //4e0 , 0xF1 , 0x7E , 1 , 0xFE , 1 , 0xF0 , 0xFF , 0 , 0x7F , 0xC0 , 0x1D , 7 , 0xF0 ,0xF , 0xC0 , 0x7E , 6 , 0xE0 , 7 , 0xE0 ,0xF , 0xF8 , 6 , 0xC1 , 0xFE , 1 , 0xFC , 3 , 0xE0 ,0xF , 0 , 0xFC }; public static byte[] pitches = new byte[256]; // tab43008 public static byte[] frequency1 = new byte[256]; public static byte[] frequency2 = new byte[256]; public static byte[] frequency3 = new byte[256]; public static byte[] amplitude1 = new byte[256]; public static byte[] amplitude2 = new byte[256]; public static byte[] amplitude3 = new byte[256]; public static byte[] sampledConsonantFlag = new byte[256]; // tab44800 //return = hibyte(mem39212*mem39213) << 1 static byte trans(byte a, byte b) => (byte)((((uint)a * b) >> 8) << 1); //timetable for more accurate c64 simulation static readonly int[,] timetable = { {162, 167, 167, 127, 128}, {226, 60, 60, 0, 0}, {225, 60, 59, 0, 0}, {200, 0, 0, 54, 55}, {199, 0, 0, 54, 54} }; public static void Output(int index, byte A) { uint oldtimetableindex = 0; int k; bufferpos += timetable[oldtimetableindex,index]; oldtimetableindex = (uint)index; // write a little bit in advance for (k = 0; k < 5; k++) buffer[bufferpos / 50 + k] = (byte)((A & 15) * 16); } static byte RenderVoicedSample(ushort hi, byte off, byte phase1) { do { byte bit = 8; byte sample = sampleTable[hi + off]; do { if ((sample & 128) != 0) Output(3, 26); else Output(4, 6); sample <<= 1; } while (--bit != 0); off++; } while (++phase1 != 0); return off; } static void RenderUnvoicedSample(ushort hi, byte off, byte mem53) { do { byte bit = 8; byte sample = sampleTable[hi + off]; do { if ((sample & 128) != 0) Output(2, 5); else Output(1, mem53); sample <<= 1; } while (--bit != 0); } while (++off != 0); } // ------------------------------------------------------------------------- //Code48227 // Render a sampled sound from the sampleTable. // // Phoneme Sample Start Sample End // 32: S* 15 255 // 33: SH 257 511 // 34: F* 559 767 // 35: TH 583 767 // 36: /H 903 1023 // 37: /X 1135 1279 // 38: Z* 84 119 // 39: ZH 340 375 // 40: V* 596 639 // 41: DH 596 631 // // 42: CH // 43: ** 399 511 // // 44: J* // 45: ** 257 276 // 46: ** // // 66: P* // 67: ** 743 767 // 68: ** // // 69: T* // 70: ** 231 255 // 71: ** // // The SampledPhonemesTable[] holds flags indicating if a phoneme is // voiced or not. If the upper 5 bits are zero, the sample is voiced. // // Samples in the sampleTable are compressed, with bits being converted to // bytes from high bit to low, as follows: // // unvoiced 0 bit -> X // unvoiced 1 bit -> 5 // // voiced 0 bit -> 6 // voiced 1 bit -> 24 // // Where X is a value from the table: // // { 0x18, 0x1A, 0x17, 0x17, 0x17 }; // // The index into this table is determined by masking off the lower // 3 bits from the SampledPhonemesTable: // // index = (SampledPhonemesTable[i] & 7) - 1; // // For voices samples, samples are interleaved between voiced output. public static void RenderSample(byte mem66, byte consonantFlag, byte mem49) { // mem49 == current phoneme's index // mask low three bits and subtract 1 get value to // convert 0 bits on unvoiced samples. byte hibyte = (byte)((consonantFlag & 7) - 1); // determine which offset to use from table { 0x18, 0x1A, 0x17, 0x17, 0x17 } // T, S, Z 0 0x18 // CH, J, SH, ZH 1 0x1A // P, F*, V, TH, DH 2 0x17 // /H 3 0x17 // /X 4 0x17 ushort hi = (ushort)(hibyte * 256); // voiced sample? byte pitchl = (byte)(consonantFlag & 248); if (pitchl == 0) { // voiced phoneme: Z*, ZH, V*, DH pitchl = (byte)(pitches[mem49] >> 4); mem66 = RenderVoicedSample(hi, mem66, (byte)(pitchl ^ 255)); } else RenderUnvoicedSample(hi, (byte)(pitchl ^ 255), tab48426[hibyte]); } // CREATE FRAMES // // The length parameter in the list corresponds to the number of frames // to expand the phoneme to. Each frame represents 10 milliseconds of time. // So a phoneme with a length of 7 = 7 frames = 70 milliseconds duration. // // The parameters are copied from the phoneme to the frame verbatim. // static void CreateFrames() { byte X = 0; uint i = 0; while (i < 256) { // get the phoneme at the index byte phoneme = phonemeIndexOutput[i]; byte phase1; uint phase2; // if terminal phoneme, exit the loop if (phoneme == 255) break; if (phoneme == PHONEME_PERIOD) AddInflection(RISING_INFLECTION, X); else if (phoneme == PHONEME_QUESTION) AddInflection(FALLING_INFLECTION, X); // get the stress amount (more stress = higher pitch) phase1 = tab47492[stressOutput[i] + 1]; // get number of frames to write phase2 = phonemeLengthOutput[i]; // copy from the source to the frames list do { frequency1[X] = freq1data[phoneme]; // F1 frequency frequency2[X] = freq2data[phoneme]; // F2 frequency frequency3[X] = freq3data[phoneme]; // F3 frequency amplitude1[X] = ampl1data[phoneme]; // F1 amplitude amplitude2[X] = ampl2data[phoneme]; // F2 amplitude amplitude3[X] = ampl3data[phoneme]; // F3 amplitude sampledConsonantFlag[X] = sampledConsonantFlags[phoneme]; // phoneme data for sampled consonants pitches[X] = (byte)(pitch + phase1); // pitch ++X; } while (--phase2 != 0); ++i; } } // RESCALE AMPLITUDE // // Rescale volume from a linear scale to decibels. // static void RescaleAmplitude() { for (int i = 255; i >= 0; i--) { try { amplitude1[i] = amplitudeRescale[amplitude1[i]]; } catch { } try { amplitude2[i] = amplitudeRescale[amplitude2[i]]; } catch { } try { amplitude3[i] = amplitudeRescale[amplitude3[i]]; } catch { } } } // ASSIGN PITCH CONTOUR // // This subtracts the F1 frequency from the pitch to create a // pitch contour. Without this, the output would be at a single // pitch level (monotone). static void AssignPitchContour() { int i; for (i = 0; i < 256; i++) { // subtract half the frequency of the formant 1. // this adds variety to the voice pitches[i] -= (byte)(frequency1[i] >> 1); } } // RENDER THE PHONEMES IN THE LIST // // The phoneme list is converted into sound through the steps: // // 1. Copy each phoneme number of times into the frames list, // where each frame represents 10 milliseconds of sound. // // 2. Determine the transitions lengths between phonemes, and linearly // interpolate the values across the frames. // // 3. Offset the pitches by the fundamental frequency. // // 4. Render the each frame. public static void Render() { byte t; if (phonemeIndexOutput[0] == 255) return; //exit if no data CreateFrames(); t = CreateTransitions(); if (singmode == 0) AssignPitchContour(); RescaleAmplitude(); ProcessFrames(t); } // Create a rising or falling inflection 30 frames prior to // index X. A rising inflection is used for questions, and // a falling inflection is used for statements. static void AddInflection(byte inflection, byte pos) { byte A; // store the location of the punctuation byte end = pos; if (pos < 30) pos = 0; else pos -= 30; // FIXME: Explain this fix better, it's not obvious // ML : A =, fixes a problem with invalid pitch with '.' while ((A = pitches[pos]) == 127) ++pos; while (pos != end) { // add the inflection direction A += inflection; // set the inflection pitches[pos] = A; while ((++pos != end) && pitches[pos] == 255) ; } } /* SAM's voice can be altered by changing the frequencies of the mouth formant (F1) and the throat formant (F2). Only the voiced phonemes (5-29 and 48-53) are altered. */ public static void SetMouthThroat(byte mouth, byte throat) { // mouth formants (F1) 5..29 byte[] mouthFormants5_29 = { 0, 0, 0, 0, 0, 10, 14, 19, 24, 27, 23, 21, 16, 20, 14, 18, 14, 18, 18, 16, 13, 15, 11, 18, 14, 11, 9, 6, 6, 6}; // throat formants (F2) 5..29 byte[] throatFormants5_29 = { 255, 255, 255, 255, 255, 84, 73, 67, 63, 40, 44, 31, 37, 45, 73, 49, 36, 30, 51, 37, 29, 69, 24, 50, 30, 24, 83, 46, 54, 86, }; // there must be no zeros in this 2 tables // formant 1 frequencies (mouth) 48..53 byte[] mouthFormants48_53 = { 19, 27, 21, 27, 18, 13 }; // formant 2 frequencies (throat) 48..53 byte[] throatFormants48_53 = { 72, 39, 31, 43, 30, 34 }; byte newFrequency = 0; byte pos = 5; // recalculate formant frequencies 5..29 for the mouth (F1) and throat (F2) while (pos < 30) { // recalculate mouth frequency byte initialFrequency = mouthFormants5_29[pos]; if (initialFrequency != 0) newFrequency = trans(mouth, initialFrequency); freq1data[pos] = newFrequency; // recalculate throat frequency initialFrequency = throatFormants5_29[pos]; if (initialFrequency != 0) newFrequency = trans(throat, initialFrequency); freq2data[pos] = newFrequency; pos++; } // recalculate formant frequencies 48..53 pos = 0; while (pos < 6) { // recalculate F1 (mouth formant) byte initialFrequency = mouthFormants48_53[pos]; freq1data[pos + 48] = trans(mouth, initialFrequency); // recalculate F2 (throat formant) initialFrequency = throatFormants48_53[pos]; freq2data[pos + 48] = trans(throat, initialFrequency); pos++; } } } }