#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "render.h"
#include "RenderTabs.h"
#include "debug.h"
extern int sam_debug;
unsigned char wait1 = 7;
unsigned char wait2 = 6;
extern unsigned char A, X, Y;
extern unsigned char mem44;
extern unsigned char mem47;
extern unsigned char mem49;
extern unsigned char mem39;
extern unsigned char mem50;
extern unsigned char mem51;
extern unsigned char mem53;
extern unsigned char mem56;
extern unsigned char speed;
extern unsigned char pitch;
extern int singmode;
extern unsigned char phonemeIndexOutput[60]; extern unsigned char stressOutput[60]; extern unsigned char phonemeLengthOutput[60];
unsigned char pitches[256];
unsigned char frequency1[256];
unsigned char frequency2[256];
unsigned char frequency3[256];
unsigned char amplitude1[256];
unsigned char amplitude2[256];
unsigned char amplitude3[256];
unsigned char sampledConsonantFlag[256];
void AddInflection(unsigned char mem48, unsigned char phase1);
unsigned char trans(unsigned char mem39212, unsigned char mem39213);
extern int bufferpos;
extern char *buffer;
int timetable[5][5] =
{
{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}
};
static unsigned oldtimetableindex = 0;
void Output8BitAry(int index, unsigned char ary[5])
{
int k;
bufferpos += timetable[oldtimetableindex][index];
oldtimetableindex = index;
for(k=0; k<5; k++)
buffer[bufferpos/50 + k] = ary[k];
}
void Output8Bit(int index, unsigned char A)
{
unsigned char ary[5] = {A,A,A,A,A};
Output8BitAry(index, ary);
}
unsigned char Read(unsigned char p, unsigned char Y)
{
switch(p)
{
case 168: return pitches[Y];
case 169: return frequency1[Y];
case 170: return frequency2[Y];
case 171: return frequency3[Y];
case 172: return amplitude1[Y];
case 173: return amplitude2[Y];
case 174: return amplitude3[Y];
}
fprintf(stderr,"Error reading to tables");
return 0;
}
void Write(unsigned char p, unsigned char Y, unsigned char value)
{
switch(p)
{
case 168: pitches[Y] = value; return;
case 169: frequency1[Y] = value; return;
case 170: frequency2[Y] = value; return;
case 171: frequency3[Y] = value; return;
case 172: amplitude1[Y] = value; return;
case 173: amplitude2[Y] = value; return;
case 174: amplitude3[Y] = value; return;
}
fprintf(stderr,"Error writing to tables\n");
}
void RenderSample(unsigned char *mem66)
{
int tempA;
mem49 = Y;
A = mem39&7;
X = A-1;
mem56 = X;
mem53 = tab48426[X];
mem47 = X;
A = mem39 & 248;
if(A == 0)
{
Y = mem49;
A = pitches[mem49] >> 4;
goto pos48315;
}
Y = A ^ 255;
pos48274:
mem56 = 8;
A = sampleTable[mem47*256+Y];
pos48280:
tempA = A;
A = A << 1;
if ((tempA & 128) == 0)
{
X = mem53;
Output8Bit(1, (X&0x0f) * 16);
if(X != 0) goto pos48296;
}
Output8Bit(2, 5 * 16);
pos48296:
X = 0;
mem56--;
if (mem56 != 0) goto pos48280;
Y++;
if (Y != 0) goto pos48274;
mem44 = 1;
Y = mem49;
return;
unsigned char phase1;
pos48315:
phase1 = A ^ 255;
Y = *mem66;
do
{
mem56 = 8;
A = sampleTable[mem47*256+Y];
do
{
tempA = A;
A = A << 1;
if ((tempA & 128) != 0)
{
X = 26;
Output8Bit(3, (X&0xf)*16);
} else
{
X=6;
Output8Bit(4, (X&0xf)*16);
}
mem56--;
} while(mem56 != 0);
Y++;
phase1++;
} while (phase1 != 0);
A = 1;
mem44 = 1;
*mem66 = Y;
Y = mem49;
return;
}
void Render()
{
unsigned char phase1 = 0; unsigned char phase2=0;
unsigned char phase3=0;
unsigned char mem66=0;
unsigned char mem38=0;
unsigned char mem40=0;
unsigned char speedcounter=0; unsigned char mem48=0;
int i;
if (phonemeIndexOutput[0] == 255) return;
A = 0;
X = 0;
mem44 = 0;
do
{
Y = mem44;
A = phonemeIndexOutput[mem44];
mem56 = A;
if (A == 255) break;
if (A == 1)
{
A = 1;
mem48 = 1;
AddInflection(mem48, phase1);
}
if (A == 2)
{
mem48 = 255;
AddInflection(mem48, phase1);
}
phase1 = tab47492[stressOutput[Y] + 1];
phase2 = phonemeLengthOutput[Y];
Y = mem56;
do
{
frequency1[X] = freq1data[Y]; frequency2[X] = freq2data[Y]; frequency3[X] = freq3data[Y]; amplitude1[X] = ampl1data[Y]; amplitude2[X] = ampl2data[Y]; amplitude3[X] = ampl3data[Y]; sampledConsonantFlag[X] = sampledConsonantFlags[Y]; pitches[X] = pitch + phase1; X++;
phase2--;
} while(phase2 != 0);
mem44++;
} while(mem44 != 0);
A = 0;
mem44 = 0;
mem49 = 0; X = 0;
while(1) {
Y = phonemeIndexOutput[X];
A = phonemeIndexOutput[X+1];
X++;
if (A == 255) break;
X = A;
mem56 = blendRank[A];
A = blendRank[Y];
if (A == mem56)
{
phase1 = outBlendLength[Y];
phase2 = outBlendLength[X];
} else
if (A < mem56)
{
phase1 = inBlendLength[X];
phase2 = outBlendLength[X];
} else
{
phase1 = outBlendLength[Y];
phase2 = inBlendLength[Y];
}
Y = mem44;
A = mem49 + phonemeLengthOutput[mem44]; mem49 = A; A = A + phase2;
speedcounter = A;
mem47 = 168;
phase3 = mem49 - phase1; A = phase1 + phase2; mem38 = A;
X = A;
X -= 2;
if ((X & 128) == 0)
do {
mem40 = mem38;
if (mem47 == 168) {
unsigned char mem36, mem37;
mem36 = phonemeLengthOutput[mem44] >> 1;
mem37 = phonemeLengthOutput[mem44+1] >> 1;
mem40 = mem36 + mem37; mem37 += mem49; mem36 = mem49 - mem36; A = Read(mem47, mem37);
Y = mem36; mem53 = A - Read(mem47, mem36); } else
{
A = Read(mem47, speedcounter);
Y = phase3;
mem53 = A - Read(mem47, phase3);
}
signed char m53 = (signed char)mem53;
mem50 = mem53 & 128;
unsigned char m53abs = abs(m53);
mem51 = m53abs % mem40; mem53 = (unsigned char)((signed char)(m53) / mem40);
X = mem40; Y = phase3;
mem56 = 0;
while(1) {
A = Read(mem47, Y) + mem53;
mem48 = A;
Y++;
X--;
if(X == 0) break;
mem56 += mem51;
if (mem56 >= mem40) {
mem56 -= mem40; if ((mem50 & 128)==0)
{
if(mem48 != 0) mem48++;
} else mem48--;
}
Write(mem47, Y, mem48);
}
mem47++;
} while (mem47 != 175); mem44++;
X = mem44;
}
mem48 = mem49 + phonemeLengthOutput[mem44];
if (!singmode)
{
for(i=0; i<256; i++) {
pitches[i] -= (frequency1[i] >> 1);
}
}
phase1 = 0;
phase2 = 0;
phase3 = 0;
mem49 = 0;
speedcounter = 72;
for(i=255; i>=0; i--)
{
amplitude1[i] = amplitudeRescale[amplitude1[i]];
amplitude2[i] = amplitudeRescale[amplitude2[i]];
amplitude3[i] = amplitudeRescale[amplitude3[i]];
}
Y = 0;
A = pitches[0];
mem44 = A;
X = A;
mem38 = A - (A>>2);
if (sam_debug)
{
PrintOutput(sampledConsonantFlag, frequency1, frequency2, frequency3, amplitude1, amplitude2, amplitude3, pitches);
}
while(1)
{
A = sampledConsonantFlag[Y];
mem39 = A;
A = A & 248;
if(A != 0)
{
RenderSample(&mem66);
Y += 2;
mem48 -= 2;
} else
{
unsigned char ary[5];
unsigned int p1 = phase1 * 256; unsigned int p2 = phase2 * 256;
unsigned int p3 = phase3 * 256;
int k;
for (k=0; k<5; k++) {
signed char sp1 = (signed char)sinus[0xff & (p1>>8)];
signed char sp2 = (signed char)sinus[0xff & (p2>>8)];
signed char rp3 = (signed char)rectangle[0xff & (p3>>8)];
signed int sin1 = sp1 * ((unsigned char)amplitude1[Y] & 0x0f);
signed int sin2 = sp2 * ((unsigned char)amplitude2[Y] & 0x0f);
signed int rect = rp3 * ((unsigned char)amplitude3[Y] & 0x0f);
signed int mux = sin1 + sin2 + rect;
mux /= 32;
mux += 128; ary[k] = mux;
p1 += frequency1[Y] * 256 / 4; p2 += frequency2[Y] * 256 / 4;
p3 += frequency3[Y] * 256 / 4;
}
Output8BitAry(0, ary);
speedcounter--;
if (speedcounter != 0) goto pos48155;
Y++;
mem48--;
}
if(mem48 == 0) return;
speedcounter = speed;
pos48155:
mem44--;
if(mem44 == 0)
{
pos48159:
A = pitches[Y];
mem44 = A;
A = A - (A>>2);
mem38 = A;
phase1 = 0;
phase2 = 0;
phase3 = 0;
continue;
}
mem38--;
if((mem38 != 0) || (mem39 == 0))
{
phase1 += frequency1[Y];
phase2 += frequency2[Y];
phase3 += frequency3[Y];
continue;
}
RenderSample(&mem66);
goto pos48159;
}
int tempA;
phase1 = A ^ 255;
Y = mem66;
do
{
mem56 = 8;
A = Read(mem47, Y);
do
{
tempA = A;
A = A << 1;
if ((tempA & 128) != 0)
{
X = 26;
bufferpos += 150;
buffer[bufferpos/50] = (X & 15)*16;
} else
{
X=6;
bufferpos += 150;
buffer[bufferpos/50] = (X & 15)*16;
}
for(X = wait2; X>0; X--); mem56--;
} while(mem56 != 0);
Y++;
phase1++;
} while (phase1 != 0);
A = 1;
mem44 = 1;
mem66 = Y;
Y = mem49;
return;
}
void AddInflection(unsigned char mem48, unsigned char phase1)
{
mem49 = X;
A = X;
int Atemp = A;
A = A - 30;
if (Atemp <= 30) A=0;
X = A;
while( (A=pitches[X]) == 127) X++;
pos48398:
A += mem48;
phase1 = A;
pitches[X] = A;
pos48406:
X++;
if (X == mem49) return; if (pitches[X] == 255) goto pos48406;
A = phase1;
goto pos48398;
}
void SetMouthThroat(unsigned char mouth, unsigned char throat)
{
unsigned char initialFrequency;
unsigned char newFrequency = 0;
unsigned char mouthFormants5_29[30] = {
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};
unsigned char throatFormants5_29[30] = {
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};
unsigned char mouthFormants48_53[6] = {19, 27, 21, 27, 18, 13};
unsigned char throatFormants48_53[6] = {72, 39, 31, 43, 30, 34};
unsigned char pos = 5; while(pos != 30)
{
initialFrequency = mouthFormants5_29[pos];
if (initialFrequency != 0) newFrequency = trans(mouth, initialFrequency);
freq1data[pos] = newFrequency;
initialFrequency = throatFormants5_29[pos];
if(initialFrequency != 0) newFrequency = trans(throat, initialFrequency);
freq2data[pos] = newFrequency;
pos++;
}
pos = 48;
Y = 0;
while(pos != 54)
{
initialFrequency = mouthFormants48_53[Y];
newFrequency = trans(mouth, initialFrequency);
freq1data[pos] = newFrequency;
initialFrequency = throatFormants48_53[Y];
newFrequency = trans(throat, initialFrequency);
freq2data[pos] = newFrequency;
Y++;
pos++;
}
}
unsigned char trans(unsigned char mem39212, unsigned char mem39213)
{
unsigned char carry;
int temp;
unsigned char mem39214, mem39215;
A = 0;
mem39215 = 0;
mem39214 = 0;
X = 8;
do
{
carry = mem39212 & 1;
mem39212 = mem39212 >> 1;
if (carry != 0)
{
carry = 0;
A = mem39215;
temp = (int)A + (int)mem39213;
A = A + mem39213;
if (temp > 255) carry = 1;
mem39215 = A;
}
temp = mem39215 & 1;
mem39215 = (mem39215 >> 1) | (carry?128:0);
carry = temp;
X--;
} while (X != 0);
temp = mem39214 & 128;
mem39214 = (mem39214 << 1) | (carry?1:0);
carry = temp;
temp = mem39215 & 128;
mem39215 = (mem39215 << 1) | (carry?1:0);
carry = temp;
return mem39215;
}