Advertisement
joric

pt3_player.c

Dec 27th, 2019
227
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 47.57 KB | None | 0 0
  1. // PT3 (ZX Spectrum ProTracker 3 format) music player
  2. // uses portions of AY_Emul, zxssk and ayemu
  3. // plain C version by Joric, 2019
  4.  
  5. #include <stdint.h>
  6. #include <string.h>
  7.  
  8. #pragma pack(1)
  9. typedef struct{
  10.         char            MusicName[0x63];
  11.         uint8_t         TonTableId;
  12.         uint8_t         Delay;
  13.         uint8_t         NumberOfPositions;
  14.         uint8_t         LoopPosition;
  15.         uint16_t        PatternsPointer;
  16.         uint8_t         SamplesPointers_w[32*2]; // WORD array
  17.         uint8_t         OrnamentsPointers_w[16*2]; // WORD array
  18.         uint8_t         PositionList[1]; // open array
  19. } PT3Header;
  20. #pragma pack()
  21.  
  22. typedef struct {
  23.         unsigned Address_In_Pattern, OrnamentPointer, SamplePointer, Ton;
  24.         int     Current_Amplitude_Sliding, Current_Noise_Sliding, Current_Envelope_Sliding,
  25.                 Ton_Slide_Count, Current_OnOff, OnOff_Delay, OffOn_Delay,
  26.                 Ton_Slide_Delay, Current_Ton_Sliding,
  27.                 Ton_Accumulator, Ton_Slide_Step, Ton_Delta;
  28.         int8_t  Note_Skip_Counter;
  29.         uint8_t Loop_Ornament_Position, Ornament_Length, Position_In_Ornament,
  30.                 Loop_Sample_Position, Sample_Length, Position_In_Sample,
  31.                 Volume, Number_Of_Notes_To_Skip, Note, Slide_To_Note, Amplitude;
  32.         uint8_t Envelope_Enabled, Enabled, SimpleGliss;
  33. } PT3_Channel;
  34.  
  35. typedef struct {
  36.         int     Cur_Env_Slide, Env_Slide_Add;
  37.         uint8_t Env_Base_lo, Env_Base_hi;
  38.         uint8_t Noise_Base, Delay, AddToNoise, DelayCounter, CurrentPosition;
  39.         int8_t  Cur_Env_Delay, Env_Delay;
  40. } PT3_Module;
  41.  
  42. typedef struct{
  43.         int TS;
  44. } PlConst;
  45.  
  46. typedef struct {
  47.         unsigned a, aa, ip;
  48. } PatCh;
  49.  
  50. typedef struct {
  51.     PatCh ch[3];
  52. } PatPtr;
  53.  
  54. typedef struct {
  55.         PT3Header* header;
  56.         uint8_t* module;
  57.         PT3_Module mod;
  58.         PT3_Channel ch[3];
  59.         PlConst plconst;
  60. } ChipDef;
  61.  
  62. typedef struct {
  63.         unsigned int time, loop, tick; // whole, loop and current time (in frames)
  64.         uint8_t regs[2][16];
  65.         uint8_t version;
  66.         uint8_t tsMode;
  67.         uint8_t* body;
  68.         unsigned mod_size;
  69.         uint8_t cur_delay;
  70.         ChipDef chip[2];
  71.         int AddToEnv;
  72.         uint8_t TempMixer;
  73. } PT3Player;
  74.  
  75.  
  76. uint8_t PT3Player_fastInitPattern(PT3Player * player, PatPtr * dst, unsigned int i)
  77. {
  78.         if (i > 84*3 || (i % 3) || player->chip[0].header->PatternsPointer + 2*i+8 >= player->mod_size) return 0;
  79.  
  80.         dst->ch[0].ip = player->chip[0].module[player->chip[0].header->PatternsPointer + 2*i + 0] + 0x100 * player->chip[0].module[player->chip[0].header->PatternsPointer + 2*i + 1];
  81.         dst->ch[1].ip = player->chip[0].module[player->chip[0].header->PatternsPointer + 2*i + 2] + 0x100 * player->chip[0].module[player->chip[0].header->PatternsPointer + 2*i + 3];
  82.         dst->ch[2].ip = player->chip[0].module[player->chip[0].header->PatternsPointer + 2*i + 4] + 0x100 * player->chip[0].module[player->chip[0].header->PatternsPointer + 2*i + 5];
  83.         return 1;
  84. }
  85.  
  86. uint8_t PT3Player_fastSimulatePattern(PT3Player * player, PatPtr * pat)
  87. {
  88.         for (int ch = 0; ch < 3; ch++) {
  89.                 if (--pat->ch[ch].a == 0) {
  90.                         if (player->chip[0].module[pat->ch[ch].ip] == 0) {
  91.                                 return 0;
  92.                         }
  93.                         int j = 0, c1 = 0, c2 = 0, c3 = 0, c4 = 0, c5 = 0, c8 = 0;
  94.                         for (;;) {
  95.                                 if (pat->ch[ch].ip >= player->mod_size) {
  96.                                         return 0;
  97.                                 }
  98.                                 uint8_t cc = player->chip[0].module[pat->ch[ch].ip];
  99.                                 if (cc == 0xD0 || cc == 0xC0 || (0x50 <= cc && cc <= 0xAF)) {
  100.                                         pat->ch[ch].a = pat->ch[ch].aa;
  101.                                         pat->ch[ch].ip++;
  102.                                         break;
  103.                                 }
  104.                                 else if (cc == 0x10 || (0xF0 <= cc && cc <= 0xFF)) {
  105.                                         pat->ch[ch].ip++;
  106.                                 }
  107.                                 else if (0xB2 <= cc && cc <= 0xBF) {
  108.                                         pat->ch[ch].ip += 2;
  109.                                 }
  110.                                 else if (cc == 0xB1) {
  111.                                         pat->ch[ch].ip++;
  112.                                         pat->ch[ch].aa = player->chip[0].module[pat->ch[ch].ip];
  113.                                 }
  114.                                 else if (0x11 <= cc && cc <= 0x1F) {
  115.                                         pat->ch[ch].ip += 3;
  116.                                 }
  117.                                 else if (cc == 1) {
  118.                                         j++;
  119.                                         c1 = j;
  120.                                 }
  121.                                 else if (cc == 2) {
  122.                                         j++;
  123.                                         c2 = j;
  124.                                 }
  125.                                 else if (cc == 3) {
  126.                                         j++;
  127.                                         c3 = j;
  128.                                 }
  129.                                 else if (cc == 4) {
  130.                                         j++;
  131.                                         c4 = j;
  132.                                 }
  133.                                 else if (cc == 5) {
  134.                                         j++;
  135.                                         c5 = j;
  136.                                 }
  137.                                 else if (cc == 8) {
  138.                                         j++;
  139.                                         c8 = j;
  140.                                 }
  141.                                 else if (cc == 9) {
  142.                                         j++;
  143.                                 }
  144.                                 pat->ch[ch].ip++;
  145.                         }
  146.                         while (j > 0) {
  147.                                 if (j == c1 || j == c8) pat->ch[ch].ip += 3;
  148.                                 else if (j == c2) pat->ch[ch].ip += 5;
  149.                                 else if (j == c3 || j == c4) pat->ch[ch].ip++;
  150.                                 else if (j == c5) pat->ch[ch].ip += 2;
  151.                                 else {
  152.                                         if (pat->ch[ch].ip >= player->mod_size) {
  153.                                                 return 0;
  154.                                         }
  155.                                         player->cur_delay = player->chip[0].module[pat->ch[ch].ip];
  156.                                         pat->ch[ch].ip++;
  157.                                 }
  158.                                 j--;
  159.                         }
  160.                 }
  161.         }
  162.         return 1;
  163. }
  164.  
  165.  
  166. uint8_t PT3Player_GetTime(PT3Player * player) {
  167.         player->time = 0; player->loop = 0;
  168.         player->cur_delay = player->chip[0].header->Delay;
  169.  
  170.         unsigned TS = (player->chip[0].header->MusicName[13] == '7' || player->chip[0].header->MusicName[13] == '9') ? player->chip[0].header->MusicName[98] : 0x20;
  171.         PatPtr pat[2];
  172.         for (int i = 0; i < 2; i++) {
  173.                 pat[i].ch[0].aa = pat[i].ch[1].aa = pat[i].ch[2].aa = 1;
  174.         }
  175.         int DLCatcher = 256*256; //max 256 patterns 256 lines per pattern
  176.         for (int i = 0; i < player->chip[0].header->NumberOfPositions; i++) {
  177.                 if (i == player->chip[0].header->LoopPosition) player->loop = player->time;
  178.                 if (!PT3Player_fastInitPattern(player, &pat[0], player->chip[0].header->PositionList[i])) {
  179.                         return 0;
  180.                 }
  181.                 pat[0].ch[0].a = pat[0].ch[1].a = pat[0].ch[2].a = 1;
  182.                 if (TS != 0x20) {
  183.                         PT3Player_fastInitPattern(player, &pat[1], TS*3 - 3 - player->chip[0].header->PositionList[i]);
  184.                         pat[1].ch[0].a = pat[1].ch[1].a = pat[1].ch[2].a = 1;
  185.                 }
  186.  
  187.                 for (;;) {
  188.                         if (!PT3Player_fastSimulatePattern(player, &pat[0])) break;
  189.                         if (TS != 0x20 && !PT3Player_fastSimulatePattern(player, &pat[1])) break;
  190.                         player->time += player->cur_delay;
  191.                         if (--DLCatcher == 0) return 0;
  192.                 }
  193.                 if (pat[0].ch[0].ip >= player->mod_size || pat[0].ch[1].ip >= player->mod_size || pat[0].ch[2].ip >= player->mod_size) {
  194.                         return 0;
  195.                 }
  196.                 if (TS != 0x20) {
  197.                         if (pat[1].ch[0].ip >= player->mod_size || pat[1].ch[1].ip >= player->mod_size || pat[1].ch[2].ip >= player->mod_size) {
  198.                                 return 0;
  199.                         }
  200.                 }
  201.         }
  202.         return 1;
  203. }
  204.  
  205.  
  206. uint8_t PT3Player_Init(PT3Player * player, uint8_t * data, uint32_t data_size) {
  207.         // InitForAllTypes
  208.  
  209.         player->body = data;
  210.         player->mod_size = data_size;
  211.  
  212.         memset(&player->chip, 0, sizeof(player->chip));
  213.         memset(&player->regs, 0, sizeof(player->regs));
  214.  
  215.         // PrepareItem / CaseTrModules
  216.  
  217.         player->chip[0].header = (PT3Header*)player->body;
  218.         player->chip[1].header = (PT3Header*)player->body;
  219.         player->chip[0].module = player->body;
  220.         player->chip[1].module = player->body;
  221.  
  222.         if (!PT3Player_GetTime(player)) return 0;
  223.         player->tick = 0;
  224.  
  225.         uint8_t v = player->chip[0].header->MusicName[13];
  226.         player->version = ('0' <= v && v <= '9') ? v - '0' : 6;
  227.         player->chip[0].plconst.TS = player->chip[1].plconst.TS = 0x20;
  228.         int TS = player->chip[0].header->MusicName[98];
  229.         player->tsMode = (TS != 0x20);
  230.         if (player->tsMode) {
  231.                 player->chip[1].plconst.TS = TS;
  232.         } else if (player->mod_size > 400 && !memcmp(player->body+player->mod_size-4, "02TS", 4)) { // try load Vortex II '02TS'
  233.                 unsigned sz1 = player->body[player->mod_size-12] + 0x100*player->body[player->mod_size-11];
  234.                 unsigned sz2 = player->body[player->mod_size-6] + 0x100*player->body[player->mod_size-5];
  235.                 if (sz1 + sz2 < player->mod_size && sz1 > 200 && sz2 > 200) {
  236.                         player->tsMode = 1;
  237.                         player->chip[1].module = player->body + sz1;
  238.                         player->chip[1].header = (PT3Header*)player->chip[1].module;
  239.                 }
  240.         }
  241.  
  242.         // InitTrackerModule code
  243.  
  244.         for (int cnum = 0; cnum < 2; cnum++) {
  245.                 player->chip[cnum].mod.Delay = player->chip[cnum].header->Delay;
  246.                 player->chip[cnum].mod.DelayCounter = 1;
  247.                 int b = player->chip[cnum].plconst.TS;
  248.                 uint8_t i = player->chip[cnum].header->PositionList[0];
  249.                 if (b != 0x20) i = (uint8_t)(3*b - 3 - i);
  250.                 for (int chan = 0; chan < 3; chan++) {
  251.                         player->chip[cnum].ch[chan].Address_In_Pattern =
  252.                                 player->chip[cnum].module[player->chip[cnum].header->PatternsPointer + 2*(i+chan)] +
  253.                                 player->chip[cnum].module[player->chip[cnum].header->PatternsPointer + 2*(i+chan)+1] * 0x100;
  254.  
  255.                         player->chip[cnum].ch[chan].SamplePointer = player->chip[cnum].header->SamplesPointers_w[2] + player->chip[cnum].header->SamplesPointers_w[3] * 0x100;
  256.                         player->chip[cnum].ch[chan].OrnamentPointer = player->chip[cnum].header->OrnamentsPointers_w[0] + player->chip[cnum].header->OrnamentsPointers_w[1] * 0x100;
  257.                         player->chip[cnum].ch[chan].Loop_Ornament_Position = player->chip[cnum].module[player->chip[cnum].ch[chan].OrnamentPointer++];
  258.                         player->chip[cnum].ch[chan].Ornament_Length = player->chip[cnum].module[player->chip[cnum].ch[chan].OrnamentPointer++];
  259.                         player->chip[cnum].ch[chan].Loop_Sample_Position = player->chip[cnum].module[player->chip[cnum].ch[chan].SamplePointer++];
  260.                         player->chip[cnum].ch[chan].Sample_Length = player->chip[cnum].module[player->chip[cnum].ch[chan].SamplePointer++];
  261.                         player->chip[cnum].ch[chan].Volume = 15;
  262.                         player->chip[cnum].ch[chan].Note_Skip_Counter = 1;
  263.                 }
  264.         }
  265.         return 1;
  266. }
  267.  
  268. int PT3NoteTable_PT_33_34r[] = {
  269.   0x0C21,0x0B73,0x0ACE,0x0A33,0x09A0,0x0916,0x0893,0x0818,0x07A4,0x0736,0x06CE,0x066D,
  270.   0x0610,0x05B9,0x0567,0x0519,0x04D0,0x048B,0x0449,0x040C,0x03D2,0x039B,0x0367,0x0336,
  271.   0x0308,0x02DC,0x02B3,0x028C,0x0268,0x0245,0x0224,0x0206,0x01E9,0x01CD,0x01B3,0x019B,
  272.   0x0184,0x016E,0x0159,0x0146,0x0134,0x0122,0x0112,0x0103,0x00F4,0x00E6,0x00D9,0x00CD,
  273.   0x00C2,0x00B7,0x00AC,0x00A3,0x009A,0x0091,0x0089,0x0081,0x007A,0x0073,0x006C,0x0066,
  274.   0x0061,0x005B,0x0056,0x0051,0x004D,0x0048,0x0044,0x0040,0x003D,0x0039,0x0036,0x0033,
  275.   0x0030,0x002D,0x002B,0x0028,0x0026,0x0024,0x0022,0x0020,0x001E,0x001C,0x001B,0x0019,
  276.   0x0018,0x0016,0x0015,0x0014,0x0013,0x0012,0x0011,0x0010,0x000F,0x000E,0x000D,0x000C};
  277.  
  278. int PT3NoteTable_PT_34_35[] = {
  279.   0x0C22,0x0B73,0x0ACF,0x0A33,0x09A1,0x0917,0x0894,0x0819,0x07A4,0x0737,0x06CF,0x066D,
  280.   0x0611,0x05BA,0x0567,0x051A,0x04D0,0x048B,0x044A,0x040C,0x03D2,0x039B,0x0367,0x0337,
  281.   0x0308,0x02DD,0x02B4,0x028D,0x0268,0x0246,0x0225,0x0206,0x01E9,0x01CE,0x01B4,0x019B,
  282.   0x0184,0x016E,0x015A,0x0146,0x0134,0x0123,0x0112,0x0103,0x00F5,0x00E7,0x00DA,0x00CE,
  283.   0x00C2,0x00B7,0x00AD,0x00A3,0x009A,0x0091,0x0089,0x0082,0x007A,0x0073,0x006D,0x0067,
  284.   0x0061,0x005C,0x0056,0x0052,0x004D,0x0049,0x0045,0x0041,0x003D,0x003A,0x0036,0x0033,
  285.   0x0031,0x002E,0x002B,0x0029,0x0027,0x0024,0x0022,0x0020,0x001F,0x001D,0x001B,0x001A,
  286.   0x0018,0x0017,0x0016,0x0014,0x0013,0x0012,0x0011,0x0010,0x000F,0x000E,0x000D,0x000C};
  287.  
  288. int PT3NoteTable_ST[] = {
  289.   0x0EF8,0x0E10,0x0D60,0x0C80,0x0BD8,0x0B28,0x0A88,0x09F0,0x0960,0x08E0,0x0858,0x07E0,
  290.   0x077C,0x0708,0x06B0,0x0640,0x05EC,0x0594,0x0544,0x04F8,0x04B0,0x0470,0x042C,0x03FD,
  291.   0x03BE,0x0384,0x0358,0x0320,0x02F6,0x02CA,0x02A2,0x027C,0x0258,0x0238,0x0216,0x01F8,
  292.   0x01DF,0x01C2,0x01AC,0x0190,0x017B,0x0165,0x0151,0x013E,0x012C,0x011C,0x010A,0x00FC,
  293.   0x00EF,0x00E1,0x00D6,0x00C8,0x00BD,0x00B2,0x00A8,0x009F,0x0096,0x008E,0x0085,0x007E,
  294.   0x0077,0x0070,0x006B,0x0064,0x005E,0x0059,0x0054,0x004F,0x004B,0x0047,0x0042,0x003F,
  295.   0x003B,0x0038,0x0035,0x0032,0x002F,0x002C,0x002A,0x0027,0x0025,0x0023,0x0021,0x001F,
  296.   0x001D,0x001C,0x001A,0x0019,0x0017,0x0016,0x0015,0x0013,0x0012,0x0011,0x0010,0x000F};
  297.  
  298. int PT3NoteTable_ASM_34r[] = {
  299.   0x0D3E,0x0C80,0x0BCC,0x0B22,0x0A82,0x09EC,0x095C,0x08D6,0x0858,0x07E0,0x076E,0x0704,
  300.   0x069F,0x0640,0x05E6,0x0591,0x0541,0x04F6,0x04AE,0x046B,0x042C,0x03F0,0x03B7,0x0382,
  301.   0x034F,0x0320,0x02F3,0x02C8,0x02A1,0x027B,0x0257,0x0236,0x0216,0x01F8,0x01DC,0x01C1,
  302.   0x01A8,0x0190,0x0179,0x0164,0x0150,0x013D,0x012C,0x011B,0x010B,0x00FC,0x00EE,0x00E0,
  303.   0x00D4,0x00C8,0x00BD,0x00B2,0x00A8,0x009F,0x0096,0x008D,0x0085,0x007E,0x0077,0x0070,
  304.   0x006A,0x0064,0x005E,0x0059,0x0054,0x0050,0x004B,0x0047,0x0043,0x003F,0x003C,0x0038,
  305.   0x0035,0x0032,0x002F,0x002D,0x002A,0x0028,0x0026,0x0024,0x0022,0x0020,0x001E,0x001D,
  306.   0x001B,0x001A,0x0019,0x0018,0x0015,0x0014,0x0013,0x0012,0x0011,0x0010,0x000F,0x000E};
  307.  
  308. int PT3NoteTable_ASM_34_35[] = {
  309.   0x0D10,0x0C55,0x0BA4,0x0AFC,0x0A5F,0x09CA,0x093D,0x08B8,0x083B,0x07C5,0x0755,0x06EC,
  310.   0x0688,0x062A,0x05D2,0x057E,0x052F,0x04E5,0x049E,0x045C,0x041D,0x03E2,0x03AB,0x0376,
  311.   0x0344,0x0315,0x02E9,0x02BF,0x0298,0x0272,0x024F,0x022E,0x020F,0x01F1,0x01D5,0x01BB,
  312.   0x01A2,0x018B,0x0174,0x0160,0x014C,0x0139,0x0128,0x0117,0x0107,0x00F9,0x00EB,0x00DD,
  313.   0x00D1,0x00C5,0x00BA,0x00B0,0x00A6,0x009D,0x0094,0x008C,0x0084,0x007C,0x0075,0x006F,
  314.   0x0069,0x0063,0x005D,0x0058,0x0053,0x004E,0x004A,0x0046,0x0042,0x003E,0x003B,0x0037,
  315.   0x0034,0x0031,0x002F,0x002C,0x0029,0x0027,0x0025,0x0023,0x0021,0x001F,0x001D,0x001C,
  316.   0x001A,0x0019,0x0017,0x0016,0x0015,0x0014,0x0012,0x0011,0x0010,0x000F,0x000E,0x000D};
  317.  
  318. int PT3NoteTable_REAL_34r[] = {
  319.   0x0CDA,0x0C22,0x0B73,0x0ACF,0x0A33,0x09A1,0x0917,0x0894,0x0819,0x07A4,0x0737,0x06CF,
  320.   0x066D,0x0611,0x05BA,0x0567,0x051A,0x04D0,0x048B,0x044A,0x040C,0x03D2,0x039B,0x0367,
  321.   0x0337,0x0308,0x02DD,0x02B4,0x028D,0x0268,0x0246,0x0225,0x0206,0x01E9,0x01CE,0x01B4,
  322.   0x019B,0x0184,0x016E,0x015A,0x0146,0x0134,0x0123,0x0113,0x0103,0x00F5,0x00E7,0x00DA,
  323.   0x00CE,0x00C2,0x00B7,0x00AD,0x00A3,0x009A,0x0091,0x0089,0x0082,0x007A,0x0073,0x006D,
  324.   0x0067,0x0061,0x005C,0x0056,0x0052,0x004D,0x0049,0x0045,0x0041,0x003D,0x003A,0x0036,
  325.   0x0033,0x0031,0x002E,0x002B,0x0029,0x0027,0x0024,0x0022,0x0020,0x001F,0x001D,0x001B,
  326.   0x001A,0x0018,0x0017,0x0016,0x0014,0x0013,0x0012,0x0011,0x0010,0x000F,0x000E,0x000D};
  327.  
  328. int PT3NoteTable_REAL_34_35[] = {
  329.   0x0CDA,0x0C22,0x0B73,0x0ACF,0x0A33,0x09A1,0x0917,0x0894,0x0819,0x07A4,0x0737,0x06CF,
  330.   0x066D,0x0611,0x05BA,0x0567,0x051A,0x04D0,0x048B,0x044A,0x040C,0x03D2,0x039B,0x0367,
  331.   0x0337,0x0308,0x02DD,0x02B4,0x028D,0x0268,0x0246,0x0225,0x0206,0x01E9,0x01CE,0x01B4,
  332.   0x019B,0x0184,0x016E,0x015A,0x0146,0x0134,0x0123,0x0112,0x0103,0x00F5,0x00E7,0x00DA,
  333.   0x00CE,0x00C2,0x00B7,0x00AD,0x00A3,0x009A,0x0091,0x0089,0x0082,0x007A,0x0073,0x006D,
  334.   0x0067,0x0061,0x005C,0x0056,0x0052,0x004D,0x0049,0x0045,0x0041,0x003D,0x003A,0x0036,
  335.   0x0033,0x0031,0x002E,0x002B,0x0029,0x0027,0x0024,0x0022,0x0020,0x001F,0x001D,0x001B,
  336.   0x001A,0x0018,0x0017,0x0016,0x0014,0x0013,0x0012,0x0011,0x0010,0x000F,0x000E,0x000D};
  337.  
  338.  
  339. uint8_t PT3VolumeTable_33_34[16][16] = {
  340.   {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  341.   {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
  342.   {0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x02,0x02,0x02,0x02},
  343.   {0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x02,0x02,0x02,0x02,0x03,0x03,0x03,0x03},
  344.   {0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x02,0x02,0x02,0x03,0x03,0x03,0x04,0x04,0x04},
  345.   {0x00,0x00,0x00,0x01,0x01,0x01,0x02,0x02,0x03,0x03,0x03,0x04,0x04,0x04,0x05,0x05},
  346.   {0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06},
  347.   {0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07},
  348.   {0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08},
  349.   {0x00,0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x05,0x05,0x06,0x06,0x07,0x08,0x08,0x09},
  350.   {0x00,0x00,0x01,0x02,0x02,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x0A},
  351.   {0x00,0x00,0x01,0x02,0x03,0x03,0x04,0x05,0x06,0x06,0x07,0x08,0x09,0x09,0x0A,0x0B},
  352.   {0x00,0x00,0x01,0x02,0x03,0x04,0x04,0x05,0x06,0x07,0x08,0x08,0x09,0x0A,0x0B,0x0C},
  353.   {0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D},
  354.   {0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E},
  355.   {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F}};
  356.  
  357. uint8_t PT3VolumeTable_35[16][16] = {
  358.   {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  359.   {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
  360.   {0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x02,0x02,0x02},
  361.   {0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x02,0x02,0x02,0x02,0x03,0x03,0x03},
  362.   {0x00,0x00,0x01,0x01,0x01,0x01,0x02,0x02,0x02,0x02,0x03,0x03,0x03,0x03,0x04,0x04},
  363.   {0x00,0x00,0x01,0x01,0x01,0x02,0x02,0x02,0x03,0x03,0x03,0x04,0x04,0x04,0x05,0x05},
  364.   {0x00,0x00,0x01,0x01,0x02,0x02,0x02,0x03,0x03,0x04,0x04,0x04,0x05,0x05,0x06,0x06},
  365.   {0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07},
  366.   {0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08},
  367.   {0x00,0x01,0x01,0x02,0x02,0x03,0x04,0x04,0x05,0x05,0x06,0x07,0x07,0x08,0x08,0x09},
  368.   {0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x05,0x05,0x06,0x07,0x07,0x08,0x09,0x09,0x0A},
  369.   {0x00,0x01,0x01,0x02,0x03,0x04,0x04,0x05,0x06,0x07,0x07,0x08,0x09,0x0A,0x0A,0x0B},
  370.   {0x00,0x01,0x02,0x02,0x03,0x04,0x05,0x06,0x06,0x07,0x08,0x09,0x0A,0x0A,0x0B,0x0C},
  371.   {0x00,0x01,0x02,0x03,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0A,0x0B,0x0C,0x0D},
  372.   {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E},
  373.   {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F}};
  374.  
  375.  
  376. int PT3Player_GetNoteFreq(PT3Player * player, int cnum, int j) {
  377.         switch (player->chip[cnum].header->TonTableId) {
  378.                 case 0:
  379.                         return (player->version <= 3)
  380.                                 ? PT3NoteTable_PT_33_34r[j]
  381.                                 : PT3NoteTable_PT_34_35[j];
  382.                 case 1:
  383.                         return PT3NoteTable_ST[j];
  384.                 case 2:
  385.                         return (player->version <= 3)
  386.                                 ? PT3NoteTable_ASM_34r[j]
  387.                                 : PT3NoteTable_ASM_34_35[j];
  388.                 default:
  389.                         return (player->version <= 3)
  390.                                 ? PT3NoteTable_REAL_34r[j]
  391.                                 : PT3NoteTable_REAL_34_35[j];
  392.         }
  393. }
  394.  
  395. void PT3Player_PatternInterpreter(PT3Player * player, int cnum, PT3_Channel * chan){
  396.         int PrNote = chan->Note;
  397.         int PrSliding = chan->Current_Ton_Sliding;
  398.         uint8_t counter = 0;
  399.         uint8_t f1 = 0, f2 = 0, f3 = 0, f4 = 0, f5 = 0, f8 = 0, f9 = 0;
  400.         for (;;) {
  401.                 uint8_t cc = player->chip[cnum].module[chan->Address_In_Pattern];
  402.                 if (0xF0 <= cc && cc <= 0xFF) {
  403.                         uint8_t c1 = cc - 0xF0;
  404.                         chan->OrnamentPointer = player->chip[cnum].header->OrnamentsPointers_w[2*c1] + 0x100 * player->chip[cnum].header->OrnamentsPointers_w[2*c1+1];
  405.                         chan->Loop_Ornament_Position = player->chip[cnum].module[chan->OrnamentPointer++];
  406.                         chan->Ornament_Length = player->chip[cnum].module[chan->OrnamentPointer++];
  407.                         chan->Address_In_Pattern++;
  408.                         uint8_t c2 = player->chip[cnum].module[chan->Address_In_Pattern]/2;
  409.                         chan->SamplePointer = player->chip[cnum].header->SamplesPointers_w[2*c2] + 0x100 * player->chip[cnum].header->SamplesPointers_w[2*c2+1];
  410.                         chan->Loop_Sample_Position = player->chip[cnum].module[chan->SamplePointer++];
  411.                         chan->Sample_Length = player->chip[cnum].module[chan->SamplePointer++];
  412.                         chan->Envelope_Enabled = 0;
  413.                         chan->Position_In_Ornament = 0;
  414.                 }
  415.                 else if (0xD1 <= cc && cc <= 0xEF) {
  416.                         uint8_t c2 = cc - 0xD0;
  417.                         chan->SamplePointer = player->chip[cnum].header->SamplesPointers_w[2*c2] + 0x100 * player->chip[cnum].header->SamplesPointers_w[2*c2+1];
  418.                         chan->Loop_Sample_Position = player->chip[cnum].module[chan->SamplePointer++];
  419.                         chan->Sample_Length = player->chip[cnum].module[chan->SamplePointer++];
  420.                 }
  421.                 else if (cc == 0xD0) {
  422.                         chan->Address_In_Pattern++;
  423.                         break;
  424.                 }
  425.                 else if (0xC1 <= cc && cc <= 0xCF) {
  426.                         chan->Volume = cc - 0xC0;
  427.                 }
  428.                 else if (cc == 0xC0) {
  429.                         chan->Position_In_Sample = 0;
  430.                         chan->Current_Amplitude_Sliding = 0;
  431.                         chan->Current_Noise_Sliding = 0;
  432.                         chan->Current_Envelope_Sliding = 0;
  433.                         chan->Position_In_Ornament = 0;
  434.                         chan->Ton_Slide_Count = 0;
  435.                         chan->Current_Ton_Sliding = 0;
  436.                         chan->Ton_Accumulator = 0;
  437.                         chan->Current_OnOff = 0;
  438.                         chan->Enabled = 0;
  439.                         chan->Address_In_Pattern++;
  440.                         break;
  441.                 }
  442.                 else if (0xB2 <= cc && cc <= 0xBF) {
  443.                         chan->Envelope_Enabled = 1;
  444.                         player->regs[cnum][13] = cc - 0xB1;
  445.                         player->chip[cnum].mod.Env_Base_hi = player->chip[cnum].module[++chan->Address_In_Pattern];
  446.                         player->chip[cnum].mod.Env_Base_lo = player->chip[cnum].module[++chan->Address_In_Pattern];
  447.                         chan->Position_In_Ornament = 0;
  448.                         player->chip[cnum].mod.Cur_Env_Slide = 0;
  449.                         player->chip[cnum].mod.Cur_Env_Delay = 0;
  450.                 }
  451.                 else if (cc == 0xB1) {
  452.                         chan->Number_Of_Notes_To_Skip = player->chip[cnum].module[++chan->Address_In_Pattern];
  453.                 }
  454.                 else if (cc == 0xB0) {
  455.                         chan->Envelope_Enabled = 0;
  456.                         chan->Position_In_Ornament = 0;
  457.                 }
  458.                 else if (0x50 <= cc && cc <= 0xAF) {
  459.                         chan->Note = cc - 0x50;
  460.                         chan->Position_In_Sample = 0;
  461.                         chan->Current_Amplitude_Sliding = 0;
  462.                         chan->Current_Noise_Sliding = 0;
  463.                         chan->Current_Envelope_Sliding = 0;
  464.                         chan->Position_In_Ornament = 0;
  465.                         chan->Ton_Slide_Count = 0;
  466.                         chan->Current_Ton_Sliding = 0;
  467.                         chan->Ton_Accumulator = 0;
  468.                         chan->Current_OnOff = 0;
  469.                         chan->Enabled = 1;
  470.                         chan->Address_In_Pattern++;
  471.                         break;
  472.                 }
  473.                 else if (0x40 <= cc && cc <= 0x4F) {
  474.                         uint8_t c1 = cc - 0x40;
  475.                         chan->OrnamentPointer = player->chip[cnum].header->OrnamentsPointers_w[2*c1] + 0x100 * player->chip[cnum].header->OrnamentsPointers_w[2*c1+1];
  476.                         chan->Loop_Ornament_Position = player->chip[cnum].module[chan->OrnamentPointer++];
  477.                         chan->Ornament_Length = player->chip[cnum].module[chan->OrnamentPointer++];
  478.                         chan->Position_In_Ornament = 0;
  479.                 }
  480.                 else if (0x20 <= cc && cc <= 0x3F) {
  481.                         player->chip[cnum].mod.Noise_Base = cc - 0x20;
  482.                 }
  483.                 else if (0x10 <= cc && cc <= 0x1F) {
  484.                         chan->Envelope_Enabled = (cc != 0x10);
  485.                         if (chan->Envelope_Enabled) {
  486.                                 player->regs[cnum][13] = cc - 0x10;
  487.                                 player->chip[cnum].mod.Env_Base_hi = player->chip[cnum].module[++chan->Address_In_Pattern];
  488.                                 player->chip[cnum].mod.Env_Base_lo = player->chip[cnum].module[++chan->Address_In_Pattern];
  489.                                 player->chip[cnum].mod.Cur_Env_Slide = 0;
  490.                                 player->chip[cnum].mod.Cur_Env_Delay = 0;
  491.                         }
  492.                         uint8_t c2 = player->chip[cnum].module[++chan->Address_In_Pattern]/2;
  493.                         chan->SamplePointer = player->chip[cnum].header->SamplesPointers_w[2*c2] + 0x100 * player->chip[cnum].header->SamplesPointers_w[2*c2+1];
  494.                         chan->Loop_Sample_Position = player->chip[cnum].module[chan->SamplePointer++];
  495.                         chan->Sample_Length = player->chip[cnum].module[chan->SamplePointer++];
  496.                         chan->Position_In_Ornament = 0;
  497.                 }
  498.                 else if (cc == 0x09) {
  499.                         f9 = ++counter;
  500.                 }
  501.                 else if (cc == 0x08) {
  502.                         f8 = ++counter;
  503.                 }
  504.                 else if (cc == 0x05) {
  505.                         f5 = ++counter;
  506.                 }
  507.                 else if (cc == 0x04) {
  508.                         f4 = ++counter;
  509.                 }
  510.                 else if (cc == 0x03) {
  511.                         f3 = ++counter;
  512.                 }
  513.                 else if (cc == 0x02) {
  514.                         f2 = ++counter;
  515.                 }
  516.                 else if (cc == 0x01) {
  517.                         f1 = ++counter;
  518.                 }
  519.  
  520.                 chan->Address_In_Pattern++;
  521.         }
  522.  
  523.         while (counter > 0) {
  524.                 if (counter == f1) {
  525.                         chan->Ton_Slide_Delay = player->chip[cnum].module[chan->Address_In_Pattern++];
  526.                         chan->Ton_Slide_Count = chan->Ton_Slide_Delay;
  527.                         chan->Ton_Slide_Step = (int16_t)(player->chip[cnum].module[chan->Address_In_Pattern] + 0x100 * player->chip[cnum].module[chan->Address_In_Pattern+1]);
  528.                         chan->Address_In_Pattern += 2;
  529.                         chan->SimpleGliss = 1;
  530.                         chan->Current_OnOff = 0;
  531.                         if (chan->Ton_Slide_Count == 0 && player->version >= 7)
  532.                                 chan->Ton_Slide_Count++;
  533.                 }
  534.                 else if (counter == f2) {
  535.                         chan->SimpleGliss = 0;
  536.                         chan->Current_OnOff = 0;
  537.                         chan->Ton_Slide_Delay = player->chip[cnum].module[chan->Address_In_Pattern];
  538.                         chan->Ton_Slide_Count = chan->Ton_Slide_Delay;
  539.                         chan->Address_In_Pattern += 3;
  540.                         uint16_t step = player->chip[cnum].module[chan->Address_In_Pattern] + 0x100 * player->chip[cnum].module[chan->Address_In_Pattern+1];
  541.                         chan->Address_In_Pattern += 2;
  542.                         int16_t signed_step = step;
  543.                         chan->Ton_Slide_Step = (signed_step < 0) ? -signed_step : signed_step;
  544.                         chan->Ton_Delta = PT3Player_GetNoteFreq(player, cnum, chan->Note) - PT3Player_GetNoteFreq(player, cnum, PrNote);
  545.                         chan->Slide_To_Note = chan->Note;
  546.                         chan->Note = PrNote;
  547.                         if (player->version >= 6) chan->Current_Ton_Sliding = PrSliding;
  548.                         if (chan->Ton_Delta - chan->Current_Ton_Sliding < 0)
  549.                                 chan->Ton_Slide_Step = -chan->Ton_Slide_Step;
  550.                 }
  551.                 else if (counter == f3) {
  552.                         chan->Position_In_Sample = player->chip[cnum].module[chan->Address_In_Pattern++];
  553.                 }
  554.                 else if (counter == f4) {
  555.                         chan->Position_In_Ornament = player->chip[cnum].module[chan->Address_In_Pattern++];
  556.                 }
  557.                 else if (counter == f5) {
  558.                         chan->OnOff_Delay = player->chip[cnum].module[chan->Address_In_Pattern++];
  559.                         chan->OffOn_Delay = player->chip[cnum].module[chan->Address_In_Pattern++];
  560.                         chan->Current_OnOff = chan->OnOff_Delay;
  561.                         chan->Ton_Slide_Count = 0;
  562.                         chan->Current_Ton_Sliding = 0;
  563.                 }
  564.                 else if (counter == f8) {
  565.                         player->chip[cnum].mod.Env_Delay = player->chip[cnum].module[chan->Address_In_Pattern++];
  566.                         player->chip[cnum].mod.Cur_Env_Delay = player->chip[cnum].mod.Env_Delay;
  567.                         player->chip[cnum].mod.Env_Slide_Add = player->chip[cnum].module[chan->Address_In_Pattern] + 0x100 * player->chip[cnum].module[chan->Address_In_Pattern+1];
  568.                         chan->Address_In_Pattern += 2;
  569.                 }
  570.                 else if (counter == f9) {
  571.                         uint8_t b = player->chip[cnum].module[chan->Address_In_Pattern++];
  572.                         player->chip[cnum].mod.Delay = b;
  573.                         if (player->tsMode && player->chip[1].plconst.TS != 0x20) {
  574.                                 player->chip[0].mod.Delay = b;
  575.                                 player->chip[0].mod.DelayCounter = b;
  576.                                 player->chip[1].mod.Delay = b;
  577.                         }
  578.                 }
  579.                 counter--;
  580.         }
  581.         chan->Note_Skip_Counter = chan->Number_Of_Notes_To_Skip;
  582. }
  583.  
  584.  
  585. void PT3Player_ChangeRegisters(PT3Player * player, int cnum, PT3_Channel * chan)
  586. {
  587.         if (chan->Enabled) {
  588.                 unsigned c1 = chan->SamplePointer + chan->Position_In_Sample*4;
  589.                 uint8_t b0 = player->chip[cnum].module[c1], b1 = player->chip[cnum].module[c1+1];
  590.                 chan->Ton = player->chip[cnum].module[c1+2] + 0x100 * player->chip[cnum].module[c1+3];
  591.                 chan->Ton += chan->Ton_Accumulator;
  592.                 if (b1 & 0x40) chan->Ton_Accumulator = chan->Ton;
  593.                 uint8_t j = chan->Note + player->chip[cnum].module[chan->OrnamentPointer + chan->Position_In_Ornament];
  594.                 if ((int8_t)j < 0) j = 0;
  595.                 else if (j > 95) j = 95;
  596.                 int w = PT3Player_GetNoteFreq(player, cnum, j);
  597.  
  598.                 chan->Ton = (chan->Ton + chan->Current_Ton_Sliding + w) & 0xFFF;
  599.                 if (chan->Ton_Slide_Count > 0) {
  600.                         if (!--chan->Ton_Slide_Count) {
  601.                                 chan->Current_Ton_Sliding += chan->Ton_Slide_Step;
  602.                                 chan->Ton_Slide_Count = chan->Ton_Slide_Delay;
  603.                                 if (!chan->SimpleGliss) {
  604.                                         if ((chan->Ton_Slide_Step < 0 && chan->Current_Ton_Sliding <= chan->Ton_Delta) ||
  605.                                            (chan->Ton_Slide_Step >= 0 && chan->Current_Ton_Sliding >= chan->Ton_Delta))
  606.                                         {
  607.                                                 chan->Note = chan->Slide_To_Note;
  608.                                                 chan->Ton_Slide_Count = 0;
  609.                                                 chan->Current_Ton_Sliding = 0;
  610.                                         }
  611.                                 }
  612.                         }
  613.                 }
  614.                 chan->Amplitude = b1 & 0x0F;
  615.                 if (b0 & 0x80) {
  616.                         if (b0 & 0x40) {
  617.                                 if (chan->Current_Amplitude_Sliding < 15) {
  618.                                         chan->Current_Amplitude_Sliding++;
  619.                                 }
  620.                         } else if (chan->Current_Amplitude_Sliding > -15) {
  621.                                 chan->Current_Amplitude_Sliding--;
  622.                         }
  623.                 }
  624.                 chan->Amplitude += chan->Current_Amplitude_Sliding;
  625.                 if ((int8_t)chan->Amplitude < 0) chan->Amplitude = 0;
  626.                 else if (chan->Amplitude > 15) chan->Amplitude = 15;
  627.                 if (player->version <= 4) chan->Amplitude = PT3VolumeTable_33_34[chan->Volume][chan->Amplitude];
  628.                 else chan->Amplitude = PT3VolumeTable_35[chan->Volume][chan->Amplitude];
  629.  
  630.                 if (!(b0 & 1) && chan->Envelope_Enabled) chan->Amplitude |= 0x10;
  631.                 if (b1 & 0x80) {
  632.                         uint8_t j = (b0 & 0x20)
  633.                                 ? ((b0 >> 1) | 0xF0) + chan->Current_Envelope_Sliding
  634.                                 : ((b0 >> 1) & 0x0F) + chan->Current_Envelope_Sliding;
  635.                         if (b1 & 0x20) chan->Current_Envelope_Sliding = j;
  636.                         player->AddToEnv += j;
  637.                 } else {
  638.                         player->chip[cnum].mod.AddToNoise = (b0 >> 1) + chan->Current_Noise_Sliding;
  639.                         if (b1 & 0x20) chan->Current_Noise_Sliding = player->chip[cnum].mod.AddToNoise;
  640.                 }
  641.                 player->TempMixer |= (b1 >> 1) & 0x48;
  642.                 if (++chan->Position_In_Sample >= chan->Sample_Length)
  643.                         chan->Position_In_Sample = chan->Loop_Sample_Position;
  644.                 if (++chan->Position_In_Ornament >= chan->Ornament_Length)
  645.                         chan->Position_In_Ornament = chan->Loop_Ornament_Position;
  646.         } else {
  647.                 chan->Amplitude = 0;
  648.         }
  649.         player->TempMixer >>= 1;
  650.         if (chan->Current_OnOff > 0) {
  651.                 if (!--chan->Current_OnOff) {
  652.                         chan->Enabled = !chan->Enabled;
  653.                         chan->Current_OnOff = chan->Enabled ? chan->OnOff_Delay : chan->OffOn_Delay;
  654.                 }
  655.         }
  656. }
  657.  
  658.  
  659. void PT3Player_GetRegisters(PT3Player * player, int cnum)
  660. {
  661.         player->regs[cnum][13] = 0xFF;
  662.  
  663.         if (!--player->chip[cnum].mod.DelayCounter) {
  664.                 for (int ch = 0; ch < 3; ch++) {
  665.                         if (!--player->chip[cnum].ch[ch].Note_Skip_Counter) {
  666.                                 if (ch == 0 && player->chip[cnum].module[player->chip[cnum].ch[ch].Address_In_Pattern] == 0) {
  667.                                         if (++player->chip[cnum].mod.CurrentPosition == player->chip[cnum].header->NumberOfPositions)
  668.                                                 player->chip[cnum].mod.CurrentPosition = player->chip[cnum].header->LoopPosition;
  669.                                         uint8_t i = player->chip[cnum].header->PositionList[player->chip[cnum].mod.CurrentPosition];
  670.                                         int b = player->chip[cnum].plconst.TS;
  671.                                         if (b != 0x20) i = (uint8_t)(3*b - 3 - i);
  672.                                         for (int chan = 0; chan < 3; chan++) {
  673.                                                 player->chip[cnum].ch[chan].Address_In_Pattern =
  674.                                                         player->chip[cnum].module[player->chip[cnum].header->PatternsPointer + 2*(i+chan)] +
  675.                                                         player->chip[cnum].module[player->chip[cnum].header->PatternsPointer + 2*(i+chan)+1] * 0x100;
  676.                                         }
  677.                                         player->chip[cnum].mod.Noise_Base = 0;
  678.                                 }
  679.                                 PT3Player_PatternInterpreter(player, cnum, &player->chip[cnum].ch[ch]);
  680.                         }
  681.                 }
  682.                 player->chip[cnum].mod.DelayCounter = player->chip[cnum].mod.Delay;
  683.         }
  684.         player->AddToEnv = 0;
  685.         player->TempMixer = 0;
  686.  
  687.         for (int ch = 0; ch < 3; ch++) PT3Player_ChangeRegisters(player, cnum, &player->chip[cnum].ch[ch]);
  688.  
  689.         player->regs[cnum][7] = player->TempMixer;
  690.         player->regs[cnum][6] = (player->chip[cnum].mod.Noise_Base + player->chip[cnum].mod.AddToNoise) & 0x1F;
  691.  
  692.         for (int ch = 0; ch < 3; ch++) {
  693.                 player->regs[cnum][2*ch+0] = player->chip[cnum].ch[ch].Ton & 0xFF;
  694.                 player->regs[cnum][2*ch+1] = (player->chip[cnum].ch[ch].Ton >> 8) & 0x0F;
  695.                 player->regs[cnum][ch+8] = player->chip[cnum].ch[ch].Amplitude;
  696.         }
  697.         unsigned env = player->chip[cnum].mod.Env_Base_hi * 0x100 + player->chip[cnum].mod.Env_Base_lo + player->AddToEnv + player->chip[cnum].mod.Cur_Env_Slide;
  698.         player->regs[cnum][11] = env & 0xFF;
  699.         player->regs[cnum][12] = (env >> 8) & 0xFF;
  700.  
  701.         if (player->chip[cnum].mod.Cur_Env_Delay > 0) {
  702.                 if (!--player->chip[cnum].mod.Cur_Env_Delay) {
  703.                         player->chip[cnum].mod.Cur_Env_Delay = player->chip[cnum].mod.Env_Delay;
  704.                         player->chip[cnum].mod.Cur_Env_Slide += player->chip[cnum].mod.Env_Slide_Add;
  705.                 }
  706.         }
  707. }
  708.  
  709.  
  710. void PT3Player_Step(PT3Player * player) {
  711.         PT3Player_GetRegisters(player, 0);
  712.         if (player->tsMode) PT3Player_GetRegisters(player, 1);
  713.         player->tick++;
  714. }
  715.  
  716.  
  717.  
  718. // minimal libayemu-based AY sound renderer
  719. // data converted with psg_to_text.py from ayumi
  720.  
  721. #define AYEMU_MAX_AMP 24575
  722. #define AYEMU_DEFAULT_CHIP_FREQ 1773400
  723.  
  724. #include <stdio.h>
  725. #include <malloc.h>
  726. typedef unsigned char ayemu_ay_reg_frame_t[16];
  727.  
  728. typedef struct {
  729.     int tone_a;     /**< R0, R1 */
  730.     int tone_b;     /**< R2, R3 */
  731.     int tone_c;     /**< R4, R5 */
  732.     int noise;      /**< R6 */
  733.     int R7_tone_a;  /**< R7 bit 0 */
  734.     int R7_tone_b;  /**< R7 bit 1 */
  735.     int R7_tone_c;  /**< R7 bit 2 */
  736.     int R7_noise_a; /**< R7 bit 3 */
  737.     int R7_noise_b; /**< R7 bit 4 */
  738.     int R7_noise_c; /**< R7 bit 5 */
  739.     int vol_a;      /**< R8 bits 3-0 */
  740.     int vol_b;      /**< R9 bits 3-0 */
  741.     int vol_c;      /**< R10 bits 3-0 */
  742.     int env_a;      /**< R8 bit 4 */
  743.     int env_b;      /**< R9 bit 4 */
  744.     int env_c;      /**< R10 bit 4 */
  745.     int env_freq;   /**< R11, R12 */
  746.     int env_style;  /**< R13 */
  747. } ayemu_regdata_t;
  748.  
  749.  
  750. typedef struct {
  751.     int freq;           /**< sound freq */
  752.     int channels;       /**< channels (1-mono, 2-stereo) */
  753.     int bpc;            /**< bits (8 or 16) */
  754. } ayemu_sndfmt_t;
  755.  
  756. typedef struct {
  757.     int table[32];          /**< table of volumes for chip */
  758.     int ChipFreq;           /**< chip emulator frequency */
  759.     int eq[6];              /**< volumes for channels, range -100..100 **/
  760.     int bit_a;              /**< state of channel A generator */
  761.     int bit_b;              /**< state of channel B generator */
  762.     int bit_c;              /**< state of channel C generator */
  763.     int bit_n;              /**< current generator state */
  764.     int cnt_a;              /**< back counter of A */
  765.     int cnt_b;              /**< back counter of B */
  766.     int cnt_c;              /**< back counter of C */
  767.     int cnt_n;              /**< back counter of noise generator */
  768.     int cnt_e;              /**< back counter of envelop generator */
  769.     int EnvNum;             /**< number of current envilopment (0...15) */
  770.     int env_pos;            /**< current position in envelop (0...127) */
  771.     int Cur_Seed;           /**< random numbers counter */
  772.     ayemu_regdata_t regs;   /**< parsed registers data */
  773.     ayemu_sndfmt_t sndfmt;  /**< output sound format */
  774.     int ChipTacts_per_outcount;  /**< chip's counts per one sound signal count */
  775.     int Amp_Global;         /**< scale factor for amplitude */
  776.     int vols[6][32];        /**< stereo type (channel volumes) and chip table. This cache calculated by #table and #eq  */
  777. } ayemu_ay_t;
  778.  
  779. #if 0
  780. static int AY_table [16] = {0,513,828,1239,1923,3238,4926,9110,10344,17876,24682,30442,38844,47270,56402,65535};
  781. static const int AY_eq[] = {100,33,70,70,33,100};
  782. #else //YM
  783. static int AY_table [32] = { 0, 0, 190, 286, 375, 470, 560, 664, 866, 1130, 1515, 1803, 2253, 2848, 3351, 3862, 4844, 6058, 7290, 8559, 10474, 12878, 15297, 17787, 21500, 26172, 30866, 35676, 42664, 50986, 58842, 65535};
  784. static const int AY_eq[] = {100, 5, 70, 70, 5, 100};
  785. #endif
  786.  
  787. #define ENVVOL envelope(ay->regs.env_style, ay->env_pos)
  788.  
  789.  
  790. int envelope(int e, int x) {
  791.     int loop = e > 7 && (e % 2)==0;
  792.     int q = (x / 32) & (loop ? 1 : 3);
  793.     int ofs = (q==0 ? (e & 4)==0 : (e == 8 || e==11 || e==13 || e==14)) ? 31 : 0;
  794.     return (q==0 || loop) ? ( ofs + (ofs!=0 ? -1 : 1) * (x % 32) ) : ofs;
  795. }
  796.  
  797.  
  798. void ayemu_init(ayemu_ay_t *ay, int freq, int channels, int bits) {
  799.     ay->ChipFreq = AYEMU_DEFAULT_CHIP_FREQ;
  800.  
  801.     ay->cnt_a = ay->cnt_b = ay->cnt_c = ay->cnt_n = ay->cnt_e = 0;
  802.     ay->bit_a = ay->bit_b = ay->bit_c = ay->bit_n = 0;
  803.     ay->env_pos = ay->EnvNum = 0;
  804.     ay->Cur_Seed = 0xffff;
  805.  
  806.     for (int n = 0; n < 32; n++)
  807.         ay->table[n] = AY_table[ n * (sizeof(AY_table) / sizeof(AY_table[0])) / 32 ];
  808.  
  809.     for (int i = 0 ; i < 6 ; i++)
  810.         ay->eq[i] = AY_eq[i];
  811.  
  812.     ay->sndfmt.freq = freq;
  813.     ay->sndfmt.channels = channels;
  814.     ay->sndfmt.bpc = bits;
  815.  
  816.     int vol, max_l, max_r;
  817.  
  818.     ay->ChipTacts_per_outcount = ay->ChipFreq / ay->sndfmt.freq / 8;
  819.  
  820.     for (int n = 0; n < 32; n++) {
  821.         vol = ay->table[n];
  822.         for (int m=0; m < 6; m++)
  823.             ay->vols[m][n] = (int) (((double) vol * ay->eq[m]) / 100);
  824.     }
  825.  
  826.     max_l = ay->vols[0][31] + ay->vols[2][31] + ay->vols[3][31];
  827.     max_r = ay->vols[1][31] + ay->vols[3][31] + ay->vols[5][31];
  828.  
  829.     vol = (max_l > max_r) ? max_l : max_r;
  830.     ay->Amp_Global = ay->ChipTacts_per_outcount *vol / AYEMU_MAX_AMP;
  831. }
  832.  
  833.  
  834. void ayemu_set_regs(ayemu_ay_t *ay, ayemu_ay_reg_frame_t regs) {
  835.     ay->regs.tone_a = regs[0] + ((regs[1]&0x0f) << 8);
  836.     ay->regs.tone_b = regs[2] + ((regs[3]&0x0f) << 8);
  837.     ay->regs.tone_c = regs[4] + ((regs[5]&0x0f) << 8);
  838.     ay->regs.noise = regs[6] & 0x1f;
  839.     ay->regs.R7_tone_a = ! (regs[7] & 0x01);
  840.     ay->regs.R7_tone_b = ! (regs[7] & 0x02);
  841.     ay->regs.R7_tone_c = ! (regs[7] & 0x04);
  842.     ay->regs.R7_noise_a = ! (regs[7] & 0x08);
  843.     ay->regs.R7_noise_b = ! (regs[7] & 0x10);
  844.     ay->regs.R7_noise_c = ! (regs[7] & 0x20);
  845.     ay->regs.vol_a = regs[8] & 0x0f;
  846.     ay->regs.vol_b = regs[9] & 0x0f;
  847.     ay->regs.vol_c = regs[10] & 0x0f;
  848.     ay->regs.env_a = regs[8] & 0x10;
  849.     ay->regs.env_b = regs[9] & 0x10;
  850.     ay->regs.env_c = regs[10] & 0x10;
  851.     ay->regs.env_freq = regs[11] + (regs[12] << 8);
  852.     if (regs[13] != 0xff) {
  853.         ay->regs.env_style = regs[13] & 0x0f;
  854.         ay->env_pos = ay->cnt_e = 0;
  855.     }
  856. }
  857.  
  858.  
  859. uint32_t ayemu_mix(ayemu_ay_t *ay)
  860. {
  861.     int mix_l, mix_r;
  862.     int tmpvol;
  863.     int m;
  864.     {
  865.         mix_l = mix_r = 0;
  866.  
  867.         for (m = 0 ; m < ay->ChipTacts_per_outcount ; m++) {
  868.  
  869.             if (++ay->cnt_a >= ay->regs.tone_a) {
  870.                 ay->cnt_a = 0;
  871.                 ay->bit_a = ! ay->bit_a;
  872.             }
  873.  
  874.             if (++ay->cnt_b >= ay->regs.tone_b) {
  875.                 ay->cnt_b = 0;
  876.                 ay->bit_b = ! ay->bit_b;
  877.             }
  878.  
  879.             if (++ay->cnt_c >= ay->regs.tone_c) {
  880.                 ay->cnt_c = 0;
  881.                 ay->bit_c = ! ay->bit_c;
  882.             }
  883.  
  884.             if (++ay->cnt_n >= (ay->regs.noise * 2)) {
  885.                 ay->cnt_n = 0;
  886.                 ay->Cur_Seed = (ay->Cur_Seed * 2 + 1) ^ (((ay->Cur_Seed >> 16) ^ (ay->Cur_Seed >> 13)) & 1);
  887.                 ay->bit_n = ((ay->Cur_Seed >> 16) & 1);
  888.             }
  889.            
  890.             if (++ay->cnt_e >= ay->regs.env_freq) {
  891.                 ay->cnt_e = 0;
  892.                 if (++ay->env_pos > 127) ay->env_pos = 64;
  893.             }
  894.  
  895.             if ((ay->bit_a | !ay->regs.R7_tone_a) & (ay->bit_n | !ay->regs.R7_noise_a)) {
  896.                 tmpvol = (ay->regs.env_a)? ENVVOL : ay->regs.vol_a * 2 + 1;
  897.                 mix_l += ay->vols[0][tmpvol];
  898.                 mix_r += ay->vols[1][tmpvol];
  899.             }
  900.            
  901.             if ((ay->bit_b | !ay->regs.R7_tone_b) & (ay->bit_n | !ay->regs.R7_noise_b)) {
  902.                 tmpvol =(ay->regs.env_b)? ENVVOL :  ay->regs.vol_b * 2 + 1;
  903.                 mix_l += ay->vols[2][tmpvol];
  904.                 mix_r += ay->vols[3][tmpvol];
  905.             }
  906.            
  907.             if ((ay->bit_c | !ay->regs.R7_tone_c) & (ay->bit_n | !ay->regs.R7_noise_c)) {
  908.                 tmpvol = (ay->regs.env_c)? ENVVOL : ay->regs.vol_c * 2 + 1;
  909.                 mix_l += ay->vols[4][tmpvol];
  910.                 mix_r += ay->vols[5][tmpvol];
  911.             }
  912.         }
  913.  
  914.         mix_l /= ay->Amp_Global;
  915.         mix_r /= ay->Amp_Global;
  916.     }
  917.  
  918.  
  919.     return (mix_l<<16) | mix_r;
  920. }
  921.  
  922. uint32_t pt3_player(uint32_t sample, uint32_t rate, uint8_t * data, uint32_t size, uint32_t * samples) {
  923.     static int init;
  924.     static ayemu_ay_t ay;
  925.     static PT3Player static_player;
  926.     static int total_samples;
  927.  
  928.     int playerFreq = 50;
  929.     uint32_t samples_per_frame = rate / playerFreq;
  930.  
  931.     PT3Player * player = &static_player;
  932.  
  933.     if (init==0) {
  934.         init = 1;
  935.  
  936.         PT3Player_Init(player, data, size);
  937.  
  938.         ayemu_init(&ay, rate, 2, 16);
  939.         total_samples = samples_per_frame * player->time;
  940.  
  941.         //printf("file size: %d\n", size);
  942.         //printf("time: %d loop: %d\n", player->time, player->loop);
  943.         //printf("total_samples: %d\n", total_samples);
  944.         //printf("samples_per_frame: %d\n", samples_per_frame);
  945.     }
  946.  
  947.     if (sample % samples_per_frame == 0) {
  948.         ayemu_set_regs (&ay, player->regs[0]);
  949.         PT3Player_Step(player);
  950.     }
  951.  
  952.     *samples = total_samples;
  953.  
  954.     return ayemu_mix(&ay);
  955. }
  956.  
  957.  
  958. /*
  959. int main() {
  960.     uint32_t size = 0;
  961.     uint8_t * data = 0;
  962.  
  963. #if 0
  964.     char * filename = (char*)"fatal.pt3";
  965.     FILE * fp = fopen(filename, "rb");
  966.     fseek(fp, 0, SEEK_END);
  967.     int size = ftell(fp);
  968.     fseek(fp, 0, SEEK_SET);
  969.     unsigned char * data = (unsigned char*)malloc(size);
  970.     fread(data, 1, size, fp);
  971.     fclose(fp);
  972. #endif
  973.  
  974. #if 1
  975.     #include "fatal.pt3.h"
  976.     size = fatal_pt3_len;
  977.     data = fatal_pt3;
  978. #endif
  979.  
  980. #if 0
  981.     #include "rage.pt3.h"
  982.     size = rage_pt3_len;
  983.     data = rage_pt3;
  984. #endif
  985.  
  986.     FILE * fp = fopen("out.wav", "wb");
  987.  
  988.     uint32_t samples = 1;
  989.  
  990.     for (uint32_t t=0; t<samples; t++) {
  991.  
  992.         uint32_t amp = pt3_player(t, 44100, data, size, &samples);
  993.  
  994.         if (t==0) {
  995.             int hdr[] = {1179011410, 36, 1163280727, 544501094, 16, 131073, 44100, 176400, 1048580, 1635017060, 0};
  996.             hdr[1] = samples * sizeof(amp) + 15;
  997.             hdr[10] = samples * sizeof(amp);
  998.             fwrite(hdr, 1, sizeof(hdr), fp);
  999.         }
  1000.         fwrite(&amp, 1, sizeof(amp), fp);
  1001.  
  1002.     }
  1003.  
  1004.     fclose(fp);
  1005. }
  1006. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement