From be106565d953e557bd9d9446361cdab895af6fdf Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sat, 13 Dec 2014 23:16:27 +0000 Subject: [PATCH 001/109] Refactoring loop --- src/render.c | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/src/render.c b/src/render.c index fa7b8a38..c7a12369 100755 --- a/src/render.c +++ b/src/render.c @@ -856,27 +856,24 @@ void AddInflection(unsigned char mem48, unsigned char phase1) // ML : A =, fixes a problem with invalid pitch with '.' while( (A=pitches[X]) == 127) X++; - -pos48398: - //48398: CLC - //48399: ADC 48 - - // add the inflection direction - A += mem48; - phase1 = A; - - // set the inflection - pitches[X] = A; -pos48406: - - // increment the position - X++; + while (1) + { + // add the inflection direction + A += mem48; + phase1 = A; - // exit if the punctuation has been reached - if (X == mem49) return; //goto pos47615; - if (pitches[X] == 255) goto pos48406; - A = phase1; - goto pos48398; + // set the inflection + pitches[X] = A; + + do { + // increment the position + X++; + + // exit if the punctuation has been reached + if (X == mem49) return; + } while (pitches[X] == 255); + A = phase1; + } } /* From 28250af5494e4038f6fa1814c013dcf398a1308b Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sat, 13 Dec 2014 23:23:08 +0000 Subject: [PATCH 002/109] Split out rendering of voiced samples into separate function --- src/render.c | 131 ++++++++++++++++++++++++++------------------------- 1 file changed, 67 insertions(+), 64 deletions(-) diff --git a/src/render.c b/src/render.c index c7a12369..328e12d4 100755 --- a/src/render.c +++ b/src/render.c @@ -19,6 +19,7 @@ extern unsigned char mem39; extern unsigned char mem50; extern unsigned char mem51; extern unsigned char mem53; + extern unsigned char mem56; extern unsigned char speed; @@ -123,6 +124,70 @@ void Write(unsigned char p, unsigned char Y, unsigned char value) +void RenderVoicedSample(unsigned char * mem66) +{ + unsigned char phase1; + + // number of samples? + phase1 = A ^ 255; + + Y = *mem66; + do + { + //pos48321: + + // shift through all 8 bits + mem56 = 8; + //A = Read(mem47, Y); + + // fetch value from table + A = sampleTable[mem47*256+Y]; + + // loop 8 times + //pos48327: + do + { + //48327: ASL A + //48328: BCC 48337 + + // left shift and check high bit + unsigned char tempA = A; + A = A << 1; + if ((tempA & 128) != 0) + { + // if bit set, output 26 + X = 26; + Output(3, X); + } else + { + //timetable 4 + // bit is not set, output a 6 + X=6; + Output(4, X); + } + + mem56--; + } while(mem56 != 0); + + // move ahead in the table + Y++; + + // continue until counter done + phase1++; + + } while (phase1 != 0); + // if (phase1 != 0) goto pos48321; + + // restore values and return + A = 1; + mem44 = 1; + *mem66 = Y; + Y = mem49; + return; + +} + + // ------------------------------------------------------------------------- //Code48227 // Render a sampled sound from the sampleTable. @@ -213,7 +278,8 @@ void RenderSample(unsigned char *mem66) A = pitches[mem49] >> 4; // jump to voiced portion - goto pos48315; + RenderVoicedSample(mem66); + return; } Y = A ^ 255; @@ -267,68 +333,6 @@ void RenderSample(unsigned char *mem66) Y = mem49; return; - - unsigned char phase1; - -pos48315: -// handle voiced samples here - - // number of samples? - phase1 = A ^ 255; - - Y = *mem66; - do - { - //pos48321: - - // shift through all 8 bits - mem56 = 8; - //A = Read(mem47, Y); - - // fetch value from table - A = sampleTable[mem47*256+Y]; - - // loop 8 times - //pos48327: - do - { - //48327: ASL A - //48328: BCC 48337 - - // left shift and check high bit - tempA = A; - A = A << 1; - if ((tempA & 128) != 0) - { - // if bit set, output 26 - X = 26; - Output(3, X); - } else - { - //timetable 4 - // bit is not set, output a 6 - X=6; - Output(4, X); - } - - mem56--; - } while(mem56 != 0); - - // move ahead in the table - Y++; - - // continue until counter done - phase1++; - - } while (phase1 != 0); - // if (phase1 != 0) goto pos48321; - - // restore values and return - A = 1; - mem44 = 1; - *mem66 = Y; - Y = mem49; - return; } @@ -394,7 +398,6 @@ do if (A == 1) { // add rising inflection - A = 1; mem48 = 1; //goto pos48376; AddInflection(mem48, phase1); From bb6ba34f55674d8375fc748cef6a1ff1796106ce Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sat, 13 Dec 2014 23:57:30 +0000 Subject: [PATCH 003/109] Refactored / simplified RenderVoicedSample() --- src/render.c | 77 ++++++++++------------------------------------------ 1 file changed, 14 insertions(+), 63 deletions(-) diff --git a/src/render.c b/src/render.c index 328e12d4..f4192b57 100755 --- a/src/render.c +++ b/src/render.c @@ -124,67 +124,19 @@ void Write(unsigned char p, unsigned char Y, unsigned char value) -void RenderVoicedSample(unsigned char * mem66) +unsigned char RenderVoicedSample(unsigned char hibyte, unsigned char off, unsigned char phase1) { - unsigned char phase1; - - // number of samples? - phase1 = A ^ 255; - - Y = *mem66; - do - { - //pos48321: - - // shift through all 8 bits - mem56 = 8; - //A = Read(mem47, Y); - - // fetch value from table - A = sampleTable[mem47*256+Y]; - - // loop 8 times - //pos48327: - do - { - //48327: ASL A - //48328: BCC 48337 - - // left shift and check high bit - unsigned char tempA = A; - A = A << 1; - if ((tempA & 128) != 0) - { - // if bit set, output 26 - X = 26; - Output(3, X); - } else - { - //timetable 4 - // bit is not set, output a 6 - X=6; - Output(4, X); - } - - mem56--; - } while(mem56 != 0); - - // move ahead in the table - Y++; - - // continue until counter done - phase1++; - - } while (phase1 != 0); - // if (phase1 != 0) goto pos48321; - - // restore values and return - A = 1; - mem44 = 1; - *mem66 = Y; - Y = mem49; - return; - + do { + unsigned char sample = sampleTable[hibyte*256+off]; + unsigned char bit = 8; + do { + if ((sample & 128) != 0) Output(3, 26); + else Output(4, 6); + sample <<= 1; + } while(--bit != 0); + off++; + } while (++phase1 != 0); + return off; } @@ -276,9 +228,8 @@ void RenderSample(unsigned char *mem66) // voiced phoneme: Z*, ZH, V*, DH Y = mem49; A = pitches[mem49] >> 4; - - // jump to voiced portion - RenderVoicedSample(mem66); + *mem66 = RenderVoicedSample(mem47, *mem66, A ^ 255); + mem44 = 1; return; } From f656c15f35ed7fb2b1d35e933881b5e001085498 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 14 Dec 2014 00:30:06 +0000 Subject: [PATCH 004/109] Refactored RenderSample() --- src/render.c | 96 +++++++++++++--------------------------------------- 1 file changed, 24 insertions(+), 72 deletions(-) diff --git a/src/render.c b/src/render.c index f4192b57..2f1c84ce 100755 --- a/src/render.c +++ b/src/render.c @@ -123,11 +123,10 @@ void Write(unsigned char p, unsigned char Y, unsigned char value) } - -unsigned char RenderVoicedSample(unsigned char hibyte, unsigned char off, unsigned char phase1) +static unsigned char RenderVoicedSample(unsigned short hi, unsigned char off, unsigned char phase1) { do { - unsigned char sample = sampleTable[hibyte*256+off]; + unsigned char sample = sampleTable[hi+off]; unsigned char bit = 8; do { if ((sample & 128) != 0) Output(3, 26); @@ -139,6 +138,20 @@ unsigned char RenderVoicedSample(unsigned char hibyte, unsigned char off, unsign return off; } +static void RenderUnvoicedSample(unsigned short hi, unsigned char off, unsigned char mem53) +{ + do { + unsigned char bit = 8; + unsigned char 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 @@ -195,20 +208,14 @@ unsigned char RenderVoicedSample(unsigned char hibyte, unsigned char off, unsign // For voices samples, samples are interleaved between voiced output. -// Code48227() void RenderSample(unsigned char *mem66) { - int tempA; // current phoneme's index mem49 = Y; // mask low three bits and subtract 1 get value to // convert 0 bits on unvoiced samples. - A = mem39&7; - X = A-1; - - // store the result - mem56 = X; + unsigned char mem56 = (mem39&7)-1; // determine which offset to use from table { 0x18, 0x1A, 0x17, 0x17, 0x17 } // T, S, Z 0 0x18 @@ -217,73 +224,18 @@ void RenderSample(unsigned char *mem66) // /H 3 0x17 // /X 4 0x17 - // get value from the table - mem53 = tab48426[X]; - mem47 = X; //46016+mem[56]*256 + mem44 = 1; + unsigned short hi = mem56*256; // voiced sample? - A = mem39 & 248; - if(A == 0) - { + unsigned char pitch = mem39 & 248; + if(pitch == 0) { // voiced phoneme: Z*, ZH, V*, DH - Y = mem49; - A = pitches[mem49] >> 4; - *mem66 = RenderVoicedSample(mem47, *mem66, A ^ 255); - mem44 = 1; + pitch = pitches[mem49] >> 4; + *mem66 = RenderVoicedSample(hi, *mem66, pitch ^ 255); return; } - - Y = A ^ 255; -pos48274: - - // step through the 8 bits in the sample - mem56 = 8; - - // get the next sample from the table - // mem47*256 = offset to start of samples - A = sampleTable[mem47*256+Y]; -pos48280: - - // left shift to get the high bit - tempA = A; - A = A << 1; - //48281: BCC 48290 - - // bit not set? - if ((tempA & 128) == 0) - { - // convert the bit to value from table - X = mem53; - //mem[54296] = X; - // output the byte - Output(1, X); - // if X != 0, exit loop - if(X != 0) goto pos48296; - } - - // output a 5 for the on bit - Output(2, 5); - - //48295: NOP -pos48296: - - X = 0; - - // decrement counter - mem56--; - - // if not done, jump to top of loop - if (mem56 != 0) goto pos48280; - - // increment position - Y++; - if (Y != 0) goto pos48274; - - // restore values and return - mem44 = 1; - Y = mem49; - return; - + RenderUnvoicedSample(hi, pitch^255, tab48426[mem56]); } From 31ffe0ffa6461b6899e93b632d75d32471a408c6 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 14 Dec 2014 00:57:31 +0000 Subject: [PATCH 005/109] Refactored out frame output --- src/render.c | 235 +++++++++++++++++++-------------------------------- 1 file changed, 87 insertions(+), 148 deletions(-) diff --git a/src/render.c b/src/render.c index 2f1c84ce..904b8a6f 100755 --- a/src/render.c +++ b/src/render.c @@ -239,6 +239,92 @@ void RenderSample(unsigned char *mem66) } +// PROCESS THE FRAMES +// +// In traditional vocal synthesis, the glottal pulse drives filters, which +// are attenuated to the frequencies of the formants. +// +// SAM generates these formants directly with sin and rectangular waves. +// To simulate them being driven by the glottal pulse, the waveforms are +// reset at the beginning of each glottal pulse. +// +void ProcessFrames(unsigned char mem48, unsigned char phase1, unsigned char phase2, + unsigned char phase3, unsigned char speedcounter, unsigned char mem38) +{ + unsigned char mem66; + + while(1) { + mem39 = sampledConsonantFlag[Y]; + + // unvoiced sampled phoneme? + if(mem39 & 248) { + RenderSample(&mem66); + // skip ahead two in the phoneme buffer + Y += 2; + mem48 -= 2; + if(mem48 == 0) return; + speedcounter = speed; + } else { + // simulate the glottal pulse and formants + unsigned char mem56 = multtable[sinus[phase1] | amplitude1[Y]]; + unsigned char carry = ((mem56+multtable[sinus[phase2] | amplitude2[Y]] ) > 255); + mem56 += multtable[sinus[phase2] | amplitude2[Y]]; + unsigned char A = mem56 + multtable[rectangle[phase3] | amplitude3[Y]] + (carry?1:0); + A = ((A + 136) & 255) >> 4; //there must be also a carry + + // output the accumulated value + Output(0, A); + speedcounter--; + if (speedcounter == 0) { + Y++; //go to next amplitude + // decrement the frame count + mem48--; + if(mem48 == 0) return; + speedcounter = speed; + } + } + + // decrement the remaining length of the glottal pulse + mem44--; + + // finished with a glottal pulse? + if(mem44 == 0) { +pos48159: + // fetch the next glottal pulse length + + mem44 = pitches[Y]; + mem38 = A = mem44 - (mem44>>2); + + // reset the formant wave generators to keep them in + // sync with the glottal pulse + phase1 = 0; + phase2 = 0; + phase3 = 0; + continue; + } + + // decrement the count + mem38--; + + // is the count non-zero and the sampled flag is zero? + if((mem38 != 0) || (mem39 == 0)) + { + // reset the phase of the formants to match the pulse + phase1 += frequency1[Y]; + phase2 += frequency2[Y]; + phase3 += frequency3[Y]; + continue; + } + + // voiced sampled phonemes interleave the sample with the + // glottal pulse. The sample flag is non-zero, so render + // the sample for the phoneme. + RenderSample(&mem66); + goto pos48159; + } //while + +} + // RENDER THE PHONEMES IN THE LIST // @@ -262,13 +348,11 @@ void Render() unsigned char phase1 = 0; //mem43 unsigned char phase2; unsigned char phase3; - unsigned char mem66; unsigned char mem38; unsigned char mem40; unsigned char speedcounter; //mem45 unsigned char mem48; int i; - int carry; if (phonemeIndexOutput[0] == 255) return; //exit if no data A = 0; @@ -588,152 +672,7 @@ if (debug) PrintOutput(sampledConsonantFlag, frequency1, frequency2, frequency3, amplitude1, amplitude2, amplitude3, pitches); } -// PROCESS THE FRAMES -// -// In traditional vocal synthesis, the glottal pulse drives filters, which -// are attenuated to the frequencies of the formants. -// -// SAM generates these formants directly with sin and rectangular waves. -// To simulate them being driven by the glottal pulse, the waveforms are -// reset at the beginning of each glottal pulse. - - //finally the loop for sound output - //pos48078: - while(1) - { - // get the sampled information on the phoneme - A = sampledConsonantFlag[Y]; - mem39 = A; - - // unvoiced sampled phoneme? - A = A & 248; - if(A != 0) - { - // render the sample for the phoneme - RenderSample(&mem66); - - // skip ahead two in the phoneme buffer - Y += 2; - mem48 -= 2; - } else - { - // simulate the glottal pulse and formants - mem56 = multtable[sinus[phase1] | amplitude1[Y]]; - - carry = 0; - if ((mem56+multtable[sinus[phase2] | amplitude2[Y]] ) > 255) carry = 1; - mem56 += multtable[sinus[phase2] | amplitude2[Y]]; - A = mem56 + multtable[rectangle[phase3] | amplitude3[Y]] + (carry?1:0); - A = ((A + 136) & 255) >> 4; //there must be also a carry - //mem[54296] = A; - - // output the accumulated value - Output(0, A); - speedcounter--; - if (speedcounter != 0) goto pos48155; - Y++; //go to next amplitude - - // decrement the frame count - mem48--; - } - - // if the frame count is zero, exit the loop - if(mem48 == 0) return; - speedcounter = speed; -pos48155: - - // decrement the remaining length of the glottal pulse - mem44--; - - // finished with a glottal pulse? - if(mem44 == 0) - { -pos48159: - // fetch the next glottal pulse length - A = pitches[Y]; - mem44 = A; - A = A - (A>>2); - mem38 = A; - - // reset the formant wave generators to keep them in - // sync with the glottal pulse - phase1 = 0; - phase2 = 0; - phase3 = 0; - continue; - } - - // decrement the count - mem38--; - - // is the count non-zero and the sampled flag is zero? - if((mem38 != 0) || (mem39 == 0)) - { - // reset the phase of the formants to match the pulse - phase1 += frequency1[Y]; - phase2 += frequency2[Y]; - phase3 += frequency3[Y]; - continue; - } - - // voiced sampled phonemes interleave the sample with the - // glottal pulse. The sample flag is non-zero, so render - // the sample for the phoneme. - RenderSample(&mem66); - goto pos48159; - } //while - - - // The following code is never reached. It's left over from when - // the voiced sample code was part of this loop, instead of part - // of RenderSample(); - - //pos48315: - int tempA; - phase1 = A ^ 255; - Y = mem66; - do - { - //pos48321: - - mem56 = 8; - A = Read(mem47, Y); - - //pos48327: - do - { - //48327: ASL A - //48328: BCC 48337 - tempA = A; - A = A << 1; - if ((tempA & 128) != 0) - { - X = 26; - // mem[54296] = X; - bufferpos += 150; - buffer[bufferpos/50] = (X & 15)*16; - } else - { - //mem[54296] = 6; - X=6; - bufferpos += 150; - buffer[bufferpos/50] = (X & 15)*16; - } - - for(X = wait2; X>0; X--); //wait - mem56--; - } while(mem56 != 0); - - Y++; - phase1++; - - } while (phase1 != 0); - // if (phase1 != 0) goto pos48321; - A = 1; - mem44 = 1; - mem66 = Y; - Y = mem49; - return; + ProcessFrames(mem48,phase1,phase2,phase3, speedcounter,mem38); } From 69d8b7032579537a94d6b6795ac5935982a940b1 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 14 Dec 2014 02:21:15 +0000 Subject: [PATCH 006/109] Further refactoring / splitting up Render() --- src/render.c | 478 ++++++++++++++++++++++----------------------------- 1 file changed, 210 insertions(+), 268 deletions(-) diff --git a/src/render.c b/src/render.c index 904b8a6f..ba1eedce 100755 --- a/src/render.c +++ b/src/render.c @@ -215,7 +215,7 @@ void RenderSample(unsigned char *mem66) // mask low three bits and subtract 1 get value to // convert 0 bits on unvoiced samples. - unsigned char mem56 = (mem39&7)-1; + unsigned char hibyte = (mem39&7)-1; // determine which offset to use from table { 0x18, 0x1A, 0x17, 0x17, 0x17 } // T, S, Z 0 0x18 @@ -226,7 +226,7 @@ void RenderSample(unsigned char *mem66) mem44 = 1; - unsigned short hi = mem56*256; + unsigned short hi = hibyte*256; // voiced sample? unsigned char pitch = mem39 & 248; if(pitch == 0) { @@ -235,7 +235,7 @@ void RenderSample(unsigned char *mem66) *mem66 = RenderVoicedSample(hi, *mem66, pitch ^ 255); return; } - RenderUnvoicedSample(hi, pitch^255, tab48426[mem56]); + RenderUnvoicedSample(hi, pitch^255, tab48426[hibyte]); } @@ -248,10 +248,19 @@ void RenderSample(unsigned char *mem66) // To simulate them being driven by the glottal pulse, the waveforms are // reset at the beginning of each glottal pulse. // -void ProcessFrames(unsigned char mem48, unsigned char phase1, unsigned char phase2, - unsigned char phase3, unsigned char speedcounter, unsigned char mem38) +void ProcessFrames(unsigned char mem48) { + + unsigned char speedcounter = 72; + unsigned char phase1 = 0; + unsigned char phase2 = 0; + unsigned char phase3 = 0; unsigned char mem66; + + Y = 0; + mem44 = pitches[0]; + + unsigned char mem38 = mem44 - (mem44 >> 2); while(1) { mem39 = sampledConsonantFlag[Y]; @@ -326,108 +335,6 @@ void ProcessFrames(unsigned char mem48, unsigned char phase1, unsigned char phas } -// 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. - - - -//void Code47574() -void Render() -{ - unsigned char phase1 = 0; //mem43 - unsigned char phase2; - unsigned char phase3; - unsigned char mem38; - unsigned char mem40; - unsigned char speedcounter; //mem45 - unsigned char mem48; - int i; - if (phonemeIndexOutput[0] == 255) return; //exit if no data - - A = 0; - X = 0; - mem44 = 0; - - -// 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. - - -// pos47587: -do -{ - // get the index - Y = mem44; - // get the phoneme at the index - A = phonemeIndexOutput[mem44]; - mem56 = A; - - // if terminal phoneme, exit the loop - if (A == 255) break; - - // period phoneme *. - if (A == 1) - { - // add rising inflection - mem48 = 1; - //goto pos48376; - AddInflection(mem48, phase1); - } - /* - if (A == 2) goto pos48372; - */ - - // question mark phoneme? - if (A == 2) - { - // create falling inflection - mem48 = 255; - AddInflection(mem48, phase1); - } - // pos47615: - - // get the stress amount (more stress = higher pitch) - phase1 = tab47492[stressOutput[Y] + 1]; - - // get number of frames to write - phase2 = phonemeLengthOutput[Y]; - Y = mem56; - - // copy from the source to the frames list - do - { - frequency1[X] = freq1data[Y]; // F1 frequency - frequency2[X] = freq2data[Y]; // F2 frequency - frequency3[X] = freq3data[Y]; // F3 frequency - amplitude1[X] = ampl1data[Y]; // F1 amplitude - amplitude2[X] = ampl2data[Y]; // F2 amplitude - amplitude3[X] = ampl3data[Y]; // F3 amplitude - sampledConsonantFlag[X] = sampledConsonantFlags[Y]; // phoneme data for sampled consonants - pitches[X] = pitch + phase1; // pitch - X++; - phase2--; - } while(phase2 != 0); - mem44++; -} while(mem44 != 0); -// ------------------- -//pos47694: - // CREATE TRANSITIONS // @@ -463,166 +370,201 @@ do // pitch from the center of the current phoneme to the center of the next // phoneme. - A = 0; +unsigned char CreateTransitions() +{ + unsigned char phase1; + unsigned char phase2; + unsigned char A = 0; mem44 = 0; - mem49 = 0; // mem49 starts at as 0 - X = 0; - while(1) //while No. 1 - { - + mem49 = 0; + unsigned char pos = 0; + while(1) { // get the current and following phoneme - Y = phonemeIndexOutput[X]; - A = phonemeIndexOutput[X+1]; - X++; + unsigned char phoneme = phonemeIndexOutput[pos]; + A = phonemeIndexOutput[pos+1]; + pos++; // exit loop at end token - if (A == 255) break;//goto pos47970; - + if (A == 255) break; // get the ranking of each phoneme - X = A; + pos = A; mem56 = blendRank[A]; - A = blendRank[Y]; + + unsigned char rank = blendRank[phoneme]; // compare the rank - lower rank value is stronger - if (A == mem56) - { + if (rank == mem56) { // same rank, so use out blend lengths from each phoneme - phase1 = outBlendLength[Y]; - phase2 = outBlendLength[X]; - } else - if (A < mem56) - { + phase1 = outBlendLength[phoneme]; + phase2 = outBlendLength[pos]; + } else if (rank < mem56) { // first phoneme is stronger, so us it's blend lengths - phase1 = inBlendLength[X]; - phase2 = outBlendLength[X]; - } else - { + phase1 = inBlendLength[pos]; + phase2 = outBlendLength[pos]; + } else { // second phoneme is stronger, so use it's blend lengths // note the out/in are swapped - phase1 = outBlendLength[Y]; - phase2 = inBlendLength[Y]; + phase1 = outBlendLength[phoneme]; + phase2 = inBlendLength[phoneme]; } - Y = mem44; A = mem49 + phonemeLengthOutput[mem44]; // A is mem49 + length mem49 = A; // mem49 now holds length + position - A = A + phase2; //Maybe Problem because of carry flag + A = mem49 + phase2; //Maybe Problem because of carry flag //47776: ADC 42 - speedcounter = A; + unsigned char speedcounter = A; mem47 = 168; - phase3 = mem49 - phase1; // what is mem49 - A = phase1 + phase2; // total transition? - mem38 = A; + unsigned char phase3 = mem49 - phase1; // what is mem49 + unsigned char mem38 = phase1 + phase2; // total transition? - X = A; - X -= 2; - if ((X & 128) == 0) - do //while No. 2 - { - //pos47810: - - // mem47 is used to index the tables: - // 168 pitches[] - // 169 frequency1 - // 170 frequency2 - // 171 frequency3 - // 172 amplitude1 - // 173 amplitude2 - // 174 amplitude3 - - mem40 = mem38; - - if (mem47 == 168) // pitch - { - - // unlike the other values, the pitches[] interpolates from - // the middle of the current phoneme to the middle of the - // next phoneme + pos = mem38; + pos -= 2; + if ((pos & 128) == 0) + do { + // mem47 is used to index the tables: + // 168 pitches[] + // 169 frequency1 + // 170 frequency2 + // 171 frequency3 + // 172 amplitude1 + // 173 amplitude2 + // 174 amplitude3 + + unsigned char mem40 = mem38; + + if (mem47 == 168) { // pitch + // unlike the other values, the pitches[] interpolates from + // the middle of the current phoneme to the middle of the + // next phoneme - unsigned char mem36, mem37; - // half the width of the current phoneme - mem36 = phonemeLengthOutput[mem44] >> 1; - // half the width of the next phoneme - mem37 = phonemeLengthOutput[mem44+1] >> 1; - // sum the values - mem40 = mem36 + mem37; // length of both halves - mem37 += mem49; // center of next phoneme - mem36 = mem49 - mem36; // center index of current phoneme - A = Read(mem47, mem37); // value at center of next phoneme - end interpolation value - //A = mem[address]; - - Y = mem36; // start index of interpolation - mem53 = A - Read(mem47, mem36); // value to center of current phoneme - } else - { - // value to interpolate to - A = Read(mem47, speedcounter); - // position to start interpolation from - Y = phase3; - // value to interpolate from - mem53 = A - Read(mem47, phase3); - } + // half the width of the current phoneme + unsigned char mem36 = phonemeLengthOutput[mem44] >> 1; + // half the width of the next phoneme + unsigned char mem37 = phonemeLengthOutput[mem44+1] >> 1; + // sum the values + mem40 = mem36 + mem37; // length of both halves + mem37 += mem49; // center of next phoneme + mem36 = mem49 - mem36; // center index of current phoneme + unsigned char A = Read(mem47, mem37); // value at center of next phoneme - end interpolation value + mem53 = A - Read(mem47, mem36); // value to center of current phoneme + } else { + // value to interpolate to + unsigned char A = Read(mem47, speedcounter); + // position to start interpolation from + // value to interpolate from + mem53 = A - Read(mem47, phase3); + } - //Code47503(mem40); - // ML : Code47503 is division with remainder, and mem50 gets the sign + //Code47503(mem40); + // ML : Code47503 is division with remainder, and mem50 gets the sign - // calculate change per frame - mem50 = (((char)(mem53) < 0) ? 128 : 0); - mem51 = abs((char)mem53) % mem40; - mem53 = (unsigned char)((char)(mem53) / mem40); - - // interpolation range - X = mem40; // number of frames to interpolate over - Y = phase3; // starting frame - - - // linearly interpolate values - - mem56 = 0; - //47907: CLC - //pos47908: - while(1) //while No. 3 - { - A = Read(mem47, Y) + mem53; //carry alway cleared - - mem48 = A; - Y++; - X--; - if(X == 0) break; - - mem56 += mem51; - if (mem56 >= mem40) //??? - { - mem56 -= mem40; //carry? is set - //if ((mem56 & 128)==0) - if ((mem50 & 128)==0) - { - //47935: BIT 50 - //47937: BMI 47943 - if(mem48 != 0) mem48++; - } else mem48--; - } - //pos47945: - Write(mem47, Y, mem48); - } //while No. 3 - - //pos47952: - mem47++; - //if (mem47 != 175) goto pos47810; - } while (mem47 != 175); //while No. 2 - //pos47963: - mem44++; - X = mem44; - } //while No. 1 - - //goto pos47701; - //pos47970: + // calculate change per frame + mem50 = (((char)(mem53) < 0) ? 128 : 0); + mem51 = abs((char)mem53) % mem40; + mem53 = (unsigned char)((char)(mem53) / mem40); + + // interpolation range + pos = mem40; // number of frames to interpolate over + unsigned char frame = phase3; // starting frame + + // linearly interpolate values + mem56 = 0; + while(1) { + A = Read(mem47, frame) + mem53; //carry alway cleared + + unsigned char mem48 = A; + frame++; + pos--; + if(pos == 0) break; + + mem56 += mem51; + if (mem56 >= mem40) { //??? + mem56 -= mem40; //carry? is set + if ((mem50 & 128)==0) { + if(mem48 != 0) mem48++; + } else mem48--; + } + Write(mem47, frame, mem48); + } //while No. 3 + + mem47++; + } while (mem47 != 175); //while No. 2 + pos = ++mem44; + } // add the length of this phoneme - mem48 = mem49 + phonemeLengthOutput[mem44]; + return mem49 + phonemeLengthOutput[mem44]; +} + + + +// 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() +{ + unsigned char mem44 = 0; + unsigned char phase1 = 0; + + X = 0; + do { + // get the phoneme at the index + unsigned char phoneme = phonemeIndexOutput[mem44]; + + // if terminal phoneme, exit the loop + if (phoneme == 255) break; + + // period phoneme *. + if (phoneme == 1) AddInflection(1, phase1); // rising + // question mark phoneme? + if (phoneme == 2) AddInflection(255, phase1); // falling + + // get the stress amount (more stress = higher pitch) + phase1 = tab47492[stressOutput[mem44] + 1]; + + // get number of frames to write + unsigned phase2 = phonemeLengthOutput[mem44]; + // 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] = pitch + phase1; // pitch + X++; + } while(--phase2 != 0); + mem44++; + } while(mem44 != 0); +} + + +// RESCALE AMPLITUDE +// +// Rescale volume from a linear scale to decibels. +// +void RescaleAmplitude() +{ + int i; + for(i=255; i>=0; i--) + { + amplitude1[i] = amplitudeRescale[amplitude1[i]]; + amplitude2[i] = amplitudeRescale[amplitude2[i]]; + amplitude3[i] = amplitudeRescale[amplitude3[i]]; + } +} + + // ASSIGN PITCH CONTOUR // @@ -630,49 +572,49 @@ do // pitch contour. Without this, the output would be at a single // pitch level (monotone). - +void AssignPitchContour() +{ // don't adjust pitch if in sing mode - if (!singmode) - { + if (!singmode) { // iterate through the buffer - for(i=0; i<256; i++) { + int i; + for(i=0; i<256; i++) { // subtract half the frequency of the formant 1. // this adds variety to the voice pitches[i] -= (frequency1[i] >> 1); } } +} - phase1 = 0; - phase2 = 0; - phase3 = 0; - mem49 = 0; - speedcounter = 72; //sam standard speed -// RESCALE AMPLITUDE +// RENDER THE PHONEMES IN THE LIST // -// Rescale volume from a linear scale to decibels. +// 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. +void Render() +{ + if (phonemeIndexOutput[0] == 255) return; //exit if no data - //amplitude rescaling - for(i=255; i>=0; i--) - { - amplitude1[i] = amplitudeRescale[amplitude1[i]]; - amplitude2[i] = amplitudeRescale[amplitude2[i]]; - amplitude3[i] = amplitudeRescale[amplitude3[i]]; - } + CreateFrames(); + unsigned char t = CreateTransitions(); - Y = 0; - A = pitches[0]; - mem44 = A; - X = A; - mem38 = A - (A>>2); // 3/4*A ??? + AssignPitchContour(); + RescaleAmplitude(); -if (debug) -{ - PrintOutput(sampledConsonantFlag, frequency1, frequency2, frequency3, amplitude1, amplitude2, amplitude3, pitches); -} + if (debug) { + PrintOutput(sampledConsonantFlag, frequency1, frequency2, frequency3, amplitude1, amplitude2, amplitude3, pitches); + } - ProcessFrames(mem48,phase1,phase2,phase3, speedcounter,mem38); + ProcessFrames(t); } From 445c181b013e1dd389aaae2a678e32eb5b8904c1 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Mon, 15 Dec 2014 18:45:39 +0000 Subject: [PATCH 007/109] More refactoring --- src/render.c | 77 ++++++++++++++++++++++++---------------------------- 1 file changed, 35 insertions(+), 42 deletions(-) diff --git a/src/render.c b/src/render.c index ba1eedce..2baa0282 100755 --- a/src/render.c +++ b/src/render.c @@ -1,3 +1,4 @@ + #include #include #include @@ -208,14 +209,14 @@ static void RenderUnvoicedSample(unsigned short hi, unsigned char off, unsigned // For voices samples, samples are interleaved between voiced output. -void RenderSample(unsigned char *mem66) +void RenderSample(unsigned char *mem66, unsigned char consonantFlag) { // current phoneme's index mem49 = Y; // mask low three bits and subtract 1 get value to // convert 0 bits on unvoiced samples. - unsigned char hibyte = (mem39&7)-1; + unsigned char hibyte = (consonantFlag & 7)-1; // determine which offset to use from table { 0x18, 0x1A, 0x17, 0x17, 0x17 } // T, S, Z 0 0x18 @@ -228,7 +229,7 @@ void RenderSample(unsigned char *mem66) unsigned short hi = hibyte*256; // voiced sample? - unsigned char pitch = mem39 & 248; + unsigned char pitch = consonantFlag & 248; if(pitch == 0) { // voiced phoneme: Z*, ZH, V*, DH pitch = pitches[mem49] >> 4; @@ -267,7 +268,7 @@ void ProcessFrames(unsigned char mem48) // unvoiced sampled phoneme? if(mem39 & 248) { - RenderSample(&mem66); + RenderSample(&mem66, mem39); // skip ahead two in the phoneme buffer Y += 2; mem48 -= 2; @@ -298,7 +299,6 @@ void ProcessFrames(unsigned char mem48) // finished with a glottal pulse? if(mem44 == 0) { -pos48159: // fetch the next glottal pulse length mem44 = pitches[Y]; @@ -328,8 +328,17 @@ void ProcessFrames(unsigned char mem48) // voiced sampled phonemes interleave the sample with the // glottal pulse. The sample flag is non-zero, so render // the sample for the phoneme. - RenderSample(&mem66); - goto pos48159; + RenderSample(&mem66, mem39); + + // fetch the next glottal pulse length + mem44 = pitches[Y]; + mem38 = A = mem44 - (mem44>>2); + + // reset the formant wave generators to keep them in + // sync with the glottal pulse + phase1 = 0; + phase2 = 0; + phase3 = 0; } //while } @@ -409,19 +418,16 @@ unsigned char CreateTransitions() phase2 = inBlendLength[phoneme]; } - A = mem49 + phonemeLengthOutput[mem44]; // A is mem49 + length - mem49 = A; // mem49 now holds length + position - A = mem49 + phase2; //Maybe Problem because of carry flag + mem49 += phonemeLengthOutput[mem44]; - //47776: ADC 42 - unsigned char speedcounter = A; - mem47 = 168; - unsigned char phase3 = mem49 - phase1; // what is mem49 - unsigned char mem38 = phase1 + phase2; // total transition? + unsigned char speedcounter = mem49 + phase2; + unsigned table = 168; + unsigned char phase3 = mem49 - phase1; + unsigned char transition = phase1 + phase2; // total transition? - pos = mem38; + pos = transition; pos -= 2; - if ((pos & 128) == 0) + if ((pos & 128) == 0) { do { // mem47 is used to index the tables: // 168 pitches[] @@ -432,9 +438,9 @@ unsigned char CreateTransitions() // 173 amplitude2 // 174 amplitude3 - unsigned char mem40 = mem38; + unsigned char mem40 = transition; - if (mem47 == 168) { // pitch + if (table == 168) { // pitch // unlike the other values, the pitches[] interpolates from // the middle of the current phoneme to the middle of the // next phoneme @@ -445,16 +451,10 @@ unsigned char CreateTransitions() unsigned char mem37 = phonemeLengthOutput[mem44+1] >> 1; // sum the values mem40 = mem36 + mem37; // length of both halves - mem37 += mem49; // center of next phoneme - mem36 = mem49 - mem36; // center index of current phoneme - unsigned char A = Read(mem47, mem37); // value at center of next phoneme - end interpolation value - mem53 = A - Read(mem47, mem36); // value to center of current phoneme + mem53 = Read(table, mem37 + mem49) - Read(table, mem49-mem36); } else { - // value to interpolate to - unsigned char A = Read(mem47, speedcounter); - // position to start interpolation from - // value to interpolate from - mem53 = A - Read(mem47, phase3); + // Interpolate - + mem53 = Read(table, speedcounter) - Read(table, phase3); } //Code47503(mem40); @@ -472,9 +472,7 @@ unsigned char CreateTransitions() // linearly interpolate values mem56 = 0; while(1) { - A = Read(mem47, frame) + mem53; //carry alway cleared - - unsigned char mem48 = A; + unsigned char mem48 = Read(table, frame) + mem53; //carry alway cleared frame++; pos--; if(pos == 0) break; @@ -486,11 +484,12 @@ unsigned char CreateTransitions() if(mem48 != 0) mem48++; } else mem48--; } - Write(mem47, frame, mem48); + Write(table, frame, mem48); } //while No. 3 - mem47++; - } while (mem47 != 175); //while No. 2 + table++; + } while (table != 175); //while No. 2 + } pos = ++mem44; } @@ -630,14 +629,8 @@ void AddInflection(unsigned char mem48, unsigned char phase1) // store the location of the punctuation mem49 = X; - A = X; - int Atemp = A; - - // backup 30 frames - A = A - 30; - // if index is before buffer, point to start of buffer - if (Atemp <= 30) A=0; - X = A; + if (X < 30) X = 0; + else X-= 30; // FIXME: Explain this fix better, it's not obvious // ML : A =, fixes a problem with invalid pitch with '.' From 6f1ba145c1640ca0f8ba50f7ad1c3e346623a7f5 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Wed, 17 Dec 2014 02:13:30 +0000 Subject: [PATCH 008/109] Split ProcessFrames into separate file to start narrow down the interdependencies --- Makefile | 2 +- src/processframes.c | 115 ++++++++++++++++++++++++++++++++++ src/render.c | 147 +++++--------------------------------------- src/render.h | 9 +++ 4 files changed, 142 insertions(+), 131 deletions(-) create mode 100644 src/processframes.c diff --git a/Makefile b/Makefile index 44db0e31..f1a6533a 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -OBJS = reciter.o sam.o render.o main.o debug.o +OBJS = reciter.o sam.o render.o main.o debug.o processframes.o CC = gcc diff --git a/src/processframes.c b/src/processframes.c new file mode 100644 index 00000000..8ec7b1e9 --- /dev/null +++ b/src/processframes.c @@ -0,0 +1,115 @@ + +#include "render.h" + +extern unsigned char mem39; +extern unsigned char Y; +extern unsigned char mem44; +extern unsigned char speed; + +// From RenderTabs.h +extern unsigned char multtable[]; +extern unsigned char sinus[]; +extern unsigned char rectangle[]; + +// From render.c +extern unsigned char pitches[256]; +extern unsigned char sampledConsonantFlag[256]; // tab44800 +extern unsigned char amplitude1[256]; +extern unsigned char amplitude2[256]; +extern unsigned char amplitude3[256]; +extern unsigned char frequency1[256]; +extern unsigned char frequency2[256]; +extern unsigned char frequency3[256]; + +extern void Output(int index, unsigned char A); + + +// PROCESS THE FRAMES +// +// In traditional vocal synthesis, the glottal pulse drives filters, which +// are attenuated to the frequencies of the formants. +// +// SAM generates these formants directly with sin and rectangular waves. +// To simulate them being driven by the glottal pulse, the waveforms are +// reset at the beginning of each glottal pulse. +// +void ProcessFrames(unsigned char mem48) +{ + + unsigned char speedcounter = 72; + unsigned char phase1 = 0; + unsigned char phase2 = 0; + unsigned char phase3 = 0; + unsigned char mem66; + + Y = 0; + mem44 = pitches[0]; + + unsigned char mem38 = mem44 - (mem44 >> 2); + + while(1) { + mem39 = sampledConsonantFlag[Y]; + + // unvoiced sampled phoneme? + if(mem39 & 248) { + RenderSample(&mem66, mem39); + // skip ahead two in the phoneme buffer + Y += 2; + mem48 -= 2; + if(mem48 == 0) return; + speedcounter = speed; + } else { + // simulate the glottal pulse and formants + unsigned char mem56 = multtable[sinus[phase1] | amplitude1[Y]]; + unsigned char carry = ((mem56+multtable[sinus[phase2] | amplitude2[Y]] ) > 255); + mem56 += multtable[sinus[phase2] | amplitude2[Y]]; + unsigned char tmp = mem56 + multtable[rectangle[phase3] | amplitude3[Y]] + (carry?1:0); + tmp = ((tmp + 136) & 255) >> 4; //there must be also a carry + + // output the accumulated value + Output(0, tmp); + speedcounter--; + if (speedcounter == 0) { + Y++; //go to next amplitude + // decrement the frame count + mem48--; + if(mem48 == 0) return; + speedcounter = speed; + } + } + + // decrement the remaining length of the glottal pulse + mem44--; + + // finished with a glottal pulse? + if(mem44 != 0) { + // decrement the count + mem38--; + + // is the count non-zero and the sampled flag is zero? + if((mem38 != 0) || (mem39 == 0)) { + // reset the phase of the formants to match the pulse + phase1 += frequency1[Y]; + phase2 += frequency2[Y]; + phase3 += frequency3[Y]; + continue; + } + + // voiced sampled phonemes interleave the sample with the + // glottal pulse. The sample flag is non-zero, so render + // the sample for the phoneme. + RenderSample(&mem66, mem39); + } + + // fetch the next glottal pulse length + mem44 = pitches[Y]; + mem38 = mem44 - (mem44>>2); // mem44 * 0.75 + + // reset the formant wave generators to keep them in + // sync with the glottal pulse + phase1 = 0; + phase2 = 0; + phase3 = 0; + } +} + diff --git a/src/render.c b/src/render.c index 2baa0282..b6eda19b 100755 --- a/src/render.c +++ b/src/render.c @@ -14,13 +14,8 @@ 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; @@ -240,107 +235,9 @@ void RenderSample(unsigned char *mem66, unsigned char consonantFlag) } -// PROCESS THE FRAMES -// -// In traditional vocal synthesis, the glottal pulse drives filters, which -// are attenuated to the frequencies of the formants. -// -// SAM generates these formants directly with sin and rectangular waves. -// To simulate them being driven by the glottal pulse, the waveforms are -// reset at the beginning of each glottal pulse. -// -void ProcessFrames(unsigned char mem48) -{ - - unsigned char speedcounter = 72; - unsigned char phase1 = 0; - unsigned char phase2 = 0; - unsigned char phase3 = 0; - unsigned char mem66; - - Y = 0; - mem44 = pitches[0]; - - unsigned char mem38 = mem44 - (mem44 >> 2); - - while(1) { - mem39 = sampledConsonantFlag[Y]; - - // unvoiced sampled phoneme? - if(mem39 & 248) { - RenderSample(&mem66, mem39); - // skip ahead two in the phoneme buffer - Y += 2; - mem48 -= 2; - if(mem48 == 0) return; - speedcounter = speed; - } else { - // simulate the glottal pulse and formants - unsigned char mem56 = multtable[sinus[phase1] | amplitude1[Y]]; - unsigned char carry = ((mem56+multtable[sinus[phase2] | amplitude2[Y]] ) > 255); - mem56 += multtable[sinus[phase2] | amplitude2[Y]]; - unsigned char A = mem56 + multtable[rectangle[phase3] | amplitude3[Y]] + (carry?1:0); - A = ((A + 136) & 255) >> 4; //there must be also a carry - - // output the accumulated value - Output(0, A); - speedcounter--; - if (speedcounter == 0) { - Y++; //go to next amplitude - // decrement the frame count - mem48--; - if(mem48 == 0) return; - speedcounter = speed; - } - } - - // decrement the remaining length of the glottal pulse - mem44--; - - // finished with a glottal pulse? - if(mem44 == 0) { - // fetch the next glottal pulse length - - mem44 = pitches[Y]; - mem38 = A = mem44 - (mem44>>2); - - // reset the formant wave generators to keep them in - // sync with the glottal pulse - phase1 = 0; - phase2 = 0; - phase3 = 0; - continue; - } - - // decrement the count - mem38--; - - // is the count non-zero and the sampled flag is zero? - if((mem38 != 0) || (mem39 == 0)) - { - // reset the phase of the formants to match the pulse - phase1 += frequency1[Y]; - phase2 += frequency2[Y]; - phase3 += frequency3[Y]; - continue; - } - - // voiced sampled phonemes interleave the sample with the - // glottal pulse. The sample flag is non-zero, so render - // the sample for the phoneme. - RenderSample(&mem66, mem39); - - // fetch the next glottal pulse length - mem44 = pitches[Y]; - mem38 = A = mem44 - (mem44>>2); - - // reset the formant wave generators to keep them in - // sync with the glottal pulse - phase1 = 0; - phase2 = 0; - phase3 = 0; - } //while +void Interpolate() +{ } @@ -383,14 +280,13 @@ unsigned char CreateTransitions() { unsigned char phase1; unsigned char phase2; - unsigned char A = 0; mem44 = 0; mem49 = 0; unsigned char pos = 0; while(1) { // get the current and following phoneme unsigned char phoneme = phonemeIndexOutput[pos]; - A = phonemeIndexOutput[pos+1]; + unsigned char A = phonemeIndexOutput[pos+1]; pos++; // exit loop at end token @@ -461,8 +357,8 @@ unsigned char CreateTransitions() // ML : Code47503 is division with remainder, and mem50 gets the sign // calculate change per frame - mem50 = (((char)(mem53) < 0) ? 128 : 0); - mem51 = abs((char)mem53) % mem40; + unsigned char sign = ((char)(mem53) < 0); + unsigned char mem51 = abs((char)mem53) % mem40; mem53 = (unsigned char)((char)(mem53) / mem40); // interpolation range @@ -470,7 +366,7 @@ unsigned char CreateTransitions() unsigned char frame = phase3; // starting frame // linearly interpolate values - mem56 = 0; + unsigned char mem56 = 0; while(1) { unsigned char mem48 = Read(table, frame) + mem53; //carry alway cleared frame++; @@ -480,12 +376,13 @@ unsigned char CreateTransitions() mem56 += mem51; if (mem56 >= mem40) { //??? mem56 -= mem40; //carry? is set - if ((mem50 & 128)==0) { + if (!sign) { if(mem48 != 0) mem48++; } else mem48--; } Write(table, frame, mem48); } //while No. 3 + table++; } while (table != 175); //while No. 2 @@ -520,10 +417,8 @@ static void CreateFrames() // if terminal phoneme, exit the loop if (phoneme == 255) break; - // period phoneme *. - if (phoneme == 1) AddInflection(1, phase1); // rising - // question mark phoneme? - if (phoneme == 2) AddInflection(255, phase1); // falling + if (phoneme == PHONEME_PERIOD) AddInflection(RISING_INFLECTION, phase1); + if (phoneme == PHONEME_QUESTION) AddInflection(FALLING_INFLECTION, phase1); // get the stress amount (more stress = higher pitch) phase1 = tab47492[stressOutput[mem44] + 1]; @@ -573,16 +468,12 @@ void RescaleAmplitude() void AssignPitchContour() { - // don't adjust pitch if in sing mode - if (!singmode) { - // iterate through the buffer - int i; - for(i=0; i<256; i++) { - // subtract half the frequency of the formant 1. - // this adds variety to the voice - pitches[i] -= (frequency1[i] >> 1); - } - } + int i; + for(i=0; i<256; i++) { + // subtract half the frequency of the formant 1. + // this adds variety to the voice + pitches[i] -= (frequency1[i] >> 1); + } } @@ -606,7 +497,7 @@ void Render() CreateFrames(); unsigned char t = CreateTransitions(); - AssignPitchContour(); + if (!singmode) AssignPitchContour(); RescaleAmplitude(); if (debug) { @@ -623,10 +514,6 @@ void Render() void AddInflection(unsigned char mem48, unsigned char phase1) { - //pos48372: - // mem48 = 255; -//pos48376: - // store the location of the punctuation mem49 = X; if (X < 30) X = 0; diff --git a/src/render.h b/src/render.h index 98ec440b..a0c09bec 100755 --- a/src/render.h +++ b/src/render.h @@ -4,4 +4,13 @@ void Render(); void SetMouthThroat(unsigned char mouth, unsigned char throat); +void ProcessFrames(unsigned char mem48); +void RenderSample(unsigned char *mem66, unsigned char consonantFlag); + +#define PHONEME_PERIOD (1) +#define PHONEME_QUESTION (2) + +#define RISING_INFLECTION (1) +#define FALLING_INFLECTION (255) + #endif From b8199f25a9ec30beb602e076e581ed9be51f890d Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Wed, 17 Dec 2014 05:14:31 +0000 Subject: [PATCH 009/109] Untangled 'trans()' --- src/render.c | 41 +---------------------------------------- 1 file changed, 1 insertion(+), 40 deletions(-) diff --git a/src/render.c b/src/render.c index b6eda19b..23f622b6 100755 --- a/src/render.c +++ b/src/render.c @@ -612,48 +612,9 @@ void SetMouthThroat(unsigned char mouth, unsigned char throat) } -//return = (mem39212*mem39213) >> 1 unsigned char trans(unsigned char mem39212, unsigned char mem39213) { - //pos39008: - 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) - { - /* - 39018: LSR 39212 - 39021: BCC 39033 - */ - 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; - //39033: ROR 39215 - 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; + return (mem39212 * mem39213) >> 7 & 0xfe; } From cbf341351039582b5b001a96f3862ebc9767f02a Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Wed, 17 Dec 2014 05:21:54 +0000 Subject: [PATCH 010/109] More refactoring --- Makefile | 3 +- src/createtransitions.c | 172 +++++++++++++++++++++++++++ src/render.c | 256 +++++++--------------------------------- src/render.h | 1 + 4 files changed, 215 insertions(+), 217 deletions(-) create mode 100644 src/createtransitions.c diff --git a/Makefile b/Makefile index f1a6533a..1153e0cf 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -OBJS = reciter.o sam.o render.o main.o debug.o processframes.o +OBJS = reciter.o sam.o render.o main.o debug.o processframes.o createtransitions.o CC = gcc @@ -21,4 +21,3 @@ package: clean: rm *.o - diff --git a/src/createtransitions.c b/src/createtransitions.c new file mode 100644 index 00000000..0db6ed1b --- /dev/null +++ b/src/createtransitions.c @@ -0,0 +1,172 @@ + +#include +#include "render.h" + +// CREATE TRANSITIONS +// +// Linear transitions are now created to smoothly connect each +// phoeneme. This transition is spread between the ending frames +// of the old phoneme (outBlendLength), and the beginning frames +// of the new phoneme (inBlendLength). +// +// To determine how many frames to use, the two phonemes are +// compared using the blendRank[] table. The phoneme with the +// smaller score is used. In case of a tie, a blend of each is used: +// +// if blendRank[phoneme1] == blendRank[phomneme2] +// // use lengths from each phoneme +// outBlendFrames = outBlend[phoneme1] +// inBlendFrames = outBlend[phoneme2] +// else if blendRank[phoneme1] < blendRank[phoneme2] +// // use lengths from first phoneme +// outBlendFrames = outBlendLength[phoneme1] +// inBlendFrames = inBlendLength[phoneme1] +// else +// // use lengths from the second phoneme +// // note that in and out are swapped around! +// outBlendFrames = inBlendLength[phoneme2] +// inBlendFrames = outBlendLength[phoneme2] +// +// Blend lengths can't be less than zero. +// +// For most of the parameters, SAM interpolates over the range of the last +// outBlendFrames-1 and the first inBlendFrames. +// +// The exception to this is the Pitch[] parameter, which is interpolates the +// pitch from the center of the current phoneme to the center of the next +// phoneme. + +// From render.c +extern unsigned char phonemeIndexOutput[60]; //tab47296 +extern unsigned char phonemeLengthOutput[60]; //tab47416 + +// from RenderTabs.h +extern unsigned char blendRank[]; +extern unsigned char outBlendLength[]; +extern unsigned char inBlendLength[]; +extern unsigned char pitches[]; + +extern unsigned char Read(unsigned char p, unsigned char Y); +extern void Write(unsigned char p, unsigned char Y, unsigned char value); + +unsigned char CreateTransitions() +{ + unsigned char phase1; + unsigned char phase2; + unsigned char mem53; + unsigned char mem44 = 0; + unsigned char mem49 = 0; + unsigned char pos = 0; + while(1) { + // get the current and following phoneme + unsigned char phoneme = phonemeIndexOutput[pos]; + unsigned char A = phonemeIndexOutput[pos+1]; + pos++; + + // exit loop at end token + if (A == 255) break; + + // get the ranking of each phoneme + pos = A; + unsigned char mem56 = blendRank[A]; + + unsigned char rank = blendRank[phoneme]; + + // compare the rank - lower rank value is stronger + if (rank == mem56) { + // same rank, so use out blend lengths from each phoneme + phase1 = outBlendLength[phoneme]; + phase2 = outBlendLength[pos]; + } else if (rank < mem56) { + // first phoneme is stronger, so us it's blend lengths + phase1 = inBlendLength[pos]; + phase2 = outBlendLength[pos]; + } else { + // second phoneme is stronger, so use it's blend lengths + // note the out/in are swapped + phase1 = outBlendLength[phoneme]; + phase2 = inBlendLength[phoneme]; + } + + mem49 += phonemeLengthOutput[mem44]; + + unsigned char speedcounter = mem49 + phase2; + unsigned table = 168; + unsigned char phase3 = mem49 - phase1; + unsigned char transition = phase1 + phase2; // total transition? + + pos = transition; + pos -= 2; + if ((pos & 128) == 0) { + do { + // mem47 is used to index the tables: + // 168 pitches[] + // 169 frequency1 + // 170 frequency2 + // 171 frequency3 + // 172 amplitude1 + // 173 amplitude2 + // 174 amplitude3 + + unsigned char mem40 = transition; + + if (table == 168) { // pitch + // unlike the other values, the pitches[] interpolates from + // the middle of the current phoneme to the middle of the + // next phoneme + + // half the width of the current phoneme + unsigned char mem36 = phonemeLengthOutput[mem44] >> 1; + // half the width of the next phoneme + unsigned char mem37 = phonemeLengthOutput[mem44+1] >> 1; + // sum the values + mem40 = mem36 + mem37; // length of both halves + mem53 = pitches[mem37 + mem49] - pitches[mem49-mem36]; + } else { + // Interpolate - + mem53 = Read(table, speedcounter) - Read(table, phase3); + } + + //Code47503(mem40); + // ML : Code47503 is division with remainder, and mem50 gets the sign + + // calculate change per frame + unsigned char sign = ((char)(mem53) < 0); + unsigned char mem51 = abs((char)mem53) % mem40; + mem53 = (unsigned char)((char)(mem53) / mem40); + + // interpolation range + pos = mem40; // number of frames to interpolate over + unsigned char frame = phase3; // starting frame + + // linearly interpolate values + unsigned char mem56 = 0; + while(1) { + unsigned char mem48 = Read(table, frame) + mem53; //carry alway cleared + frame++; + pos--; + if(pos == 0) break; + + mem56 += mem51; + if (mem56 >= mem40) { //??? + mem56 -= mem40; //carry? is set + if (!sign) { + if(mem48 != 0) mem48++; + } else mem48--; + } + Write(table, frame, mem48); + } //while No. 3 + + + table++; + } while (table != 175); //while No. 2 + } + pos = ++mem44; + } + + // add the length of this phoneme + return mem49 + phonemeLengthOutput[mem44]; +} + + + diff --git a/src/render.c b/src/render.c index 23f622b6..ca58a5c2 100755 --- a/src/render.c +++ b/src/render.c @@ -14,9 +14,6 @@ unsigned char wait2 = 6; extern unsigned char A, X, Y; extern unsigned char mem44; -extern unsigned char mem49; -extern unsigned char mem53; -extern unsigned char mem56; extern unsigned char speed; extern unsigned char pitch; @@ -40,8 +37,15 @@ unsigned char amplitude3[256]; unsigned char sampledConsonantFlag[256]; // tab44800 -void AddInflection(unsigned char mem48, unsigned char phase1); -unsigned char trans(unsigned char mem39212, unsigned char mem39213); +void AddInflection(unsigned char mem48, unsigned char phase1, unsigned char X); + +//return = hibyte(mem39212*mem39213) << 1 +unsigned char trans(unsigned char a, unsigned char b) +{ + return ((a * b) >> 8) << 1; +} + + // contains the final soundbuffer @@ -207,7 +211,7 @@ static void RenderUnvoicedSample(unsigned short hi, unsigned char off, unsigned void RenderSample(unsigned char *mem66, unsigned char consonantFlag) { // current phoneme's index - mem49 = Y; + unsigned char mem49 = Y; // mask low three bits and subtract 1 get value to // convert 0 bits on unvoiced samples. @@ -236,166 +240,6 @@ void RenderSample(unsigned char *mem66, unsigned char consonantFlag) -void Interpolate() -{ -} - - - -// CREATE TRANSITIONS -// -// Linear transitions are now created to smoothly connect each -// phoeneme. This transition is spread between the ending frames -// of the old phoneme (outBlendLength), and the beginning frames -// of the new phoneme (inBlendLength). -// -// To determine how many frames to use, the two phonemes are -// compared using the blendRank[] table. The phoneme with the -// smaller score is used. In case of a tie, a blend of each is used: -// -// if blendRank[phoneme1] == blendRank[phomneme2] -// // use lengths from each phoneme -// outBlendFrames = outBlend[phoneme1] -// inBlendFrames = outBlend[phoneme2] -// else if blendRank[phoneme1] < blendRank[phoneme2] -// // use lengths from first phoneme -// outBlendFrames = outBlendLength[phoneme1] -// inBlendFrames = inBlendLength[phoneme1] -// else -// // use lengths from the second phoneme -// // note that in and out are swapped around! -// outBlendFrames = inBlendLength[phoneme2] -// inBlendFrames = outBlendLength[phoneme2] -// -// Blend lengths can't be less than zero. -// -// For most of the parameters, SAM interpolates over the range of the last -// outBlendFrames-1 and the first inBlendFrames. -// -// The exception to this is the Pitch[] parameter, which is interpolates the -// pitch from the center of the current phoneme to the center of the next -// phoneme. - -unsigned char CreateTransitions() -{ - unsigned char phase1; - unsigned char phase2; - mem44 = 0; - mem49 = 0; - unsigned char pos = 0; - while(1) { - // get the current and following phoneme - unsigned char phoneme = phonemeIndexOutput[pos]; - unsigned char A = phonemeIndexOutput[pos+1]; - pos++; - - // exit loop at end token - if (A == 255) break; - - // get the ranking of each phoneme - pos = A; - mem56 = blendRank[A]; - - unsigned char rank = blendRank[phoneme]; - - // compare the rank - lower rank value is stronger - if (rank == mem56) { - // same rank, so use out blend lengths from each phoneme - phase1 = outBlendLength[phoneme]; - phase2 = outBlendLength[pos]; - } else if (rank < mem56) { - // first phoneme is stronger, so us it's blend lengths - phase1 = inBlendLength[pos]; - phase2 = outBlendLength[pos]; - } else { - // second phoneme is stronger, so use it's blend lengths - // note the out/in are swapped - phase1 = outBlendLength[phoneme]; - phase2 = inBlendLength[phoneme]; - } - - mem49 += phonemeLengthOutput[mem44]; - - unsigned char speedcounter = mem49 + phase2; - unsigned table = 168; - unsigned char phase3 = mem49 - phase1; - unsigned char transition = phase1 + phase2; // total transition? - - pos = transition; - pos -= 2; - if ((pos & 128) == 0) { - do { - // mem47 is used to index the tables: - // 168 pitches[] - // 169 frequency1 - // 170 frequency2 - // 171 frequency3 - // 172 amplitude1 - // 173 amplitude2 - // 174 amplitude3 - - unsigned char mem40 = transition; - - if (table == 168) { // pitch - // unlike the other values, the pitches[] interpolates from - // the middle of the current phoneme to the middle of the - // next phoneme - - // half the width of the current phoneme - unsigned char mem36 = phonemeLengthOutput[mem44] >> 1; - // half the width of the next phoneme - unsigned char mem37 = phonemeLengthOutput[mem44+1] >> 1; - // sum the values - mem40 = mem36 + mem37; // length of both halves - mem53 = Read(table, mem37 + mem49) - Read(table, mem49-mem36); - } else { - // Interpolate - - mem53 = Read(table, speedcounter) - Read(table, phase3); - } - - //Code47503(mem40); - // ML : Code47503 is division with remainder, and mem50 gets the sign - - // calculate change per frame - unsigned char sign = ((char)(mem53) < 0); - unsigned char mem51 = abs((char)mem53) % mem40; - mem53 = (unsigned char)((char)(mem53) / mem40); - - // interpolation range - pos = mem40; // number of frames to interpolate over - unsigned char frame = phase3; // starting frame - - // linearly interpolate values - unsigned char mem56 = 0; - while(1) { - unsigned char mem48 = Read(table, frame) + mem53; //carry alway cleared - frame++; - pos--; - if(pos == 0) break; - - mem56 += mem51; - if (mem56 >= mem40) { //??? - mem56 -= mem40; //carry? is set - if (!sign) { - if(mem48 != 0) mem48++; - } else mem48--; - } - Write(table, frame, mem48); - } //while No. 3 - - - table++; - } while (table != 175); //while No. 2 - } - pos = ++mem44; - } - - // add the length of this phoneme - return mem49 + phonemeLengthOutput[mem44]; -} - - - // CREATE FRAMES // // The length parameter in the list corresponds to the number of frames @@ -406,25 +250,25 @@ unsigned char CreateTransitions() // static void CreateFrames() { - unsigned char mem44 = 0; unsigned char phase1 = 0; - X = 0; - do { + unsigned char X = 0; + unsigned int i = 0; + while(i < 256) { // get the phoneme at the index - unsigned char phoneme = phonemeIndexOutput[mem44]; + unsigned char phoneme = phonemeIndexOutput[i]; // if terminal phoneme, exit the loop if (phoneme == 255) break; - if (phoneme == PHONEME_PERIOD) AddInflection(RISING_INFLECTION, phase1); - if (phoneme == PHONEME_QUESTION) AddInflection(FALLING_INFLECTION, phase1); + if (phoneme == PHONEME_PERIOD) AddInflection(RISING_INFLECTION, phase1,X); + else if (phoneme == PHONEME_QUESTION) AddInflection(FALLING_INFLECTION, phase1,X); // get the stress amount (more stress = higher pitch) - phase1 = tab47492[stressOutput[mem44] + 1]; + phase1 = tab47492[stressOutput[i] + 1]; // get number of frames to write - unsigned phase2 = phonemeLengthOutput[mem44]; + unsigned phase2 = phonemeLengthOutput[i]; // copy from the source to the frames list do { @@ -436,10 +280,11 @@ static void CreateFrames() amplitude3[X] = ampl3data[phoneme]; // F3 amplitude sampledConsonantFlag[X] = sampledConsonantFlags[phoneme]; // phoneme data for sampled consonants pitches[X] = pitch + phase1; // pitch - X++; + ++X; } while(--phase2 != 0); - mem44++; - } while(mem44 != 0); + + ++i; + } } @@ -512,34 +357,27 @@ void Render() // index X. A rising inflection is used for questions, and // a falling inflection is used for statements. -void AddInflection(unsigned char mem48, unsigned char phase1) +void AddInflection(unsigned char inflection, unsigned char phase1, unsigned char pos) { + unsigned char A; // store the location of the punctuation - mem49 = X; - if (X < 30) X = 0; - else X-= 30; + unsigned char 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[X]) == 127) X++; + while( (A = pitches[pos]) == 127) ++pos; - while (1) - { + while (pos != end) { // add the inflection direction - A += mem48; - phase1 = A; + A += inflection; // set the inflection - pitches[X] = A; + pitches[pos] = A; - do { - // increment the position - X++; - - // exit if the punctuation has been reached - if (X == mem49) return; - } while (pitches[X] == 255); - A = phase1; + while ((++pos != end) && pitches[pos] == 255); } } @@ -552,8 +390,6 @@ void SetMouthThroat(unsigned char mouth, unsigned char throat) { unsigned char initialFrequency; unsigned char newFrequency = 0; - //unsigned char mouth; //mem38880 - //unsigned char throat; //mem38881 // mouth formants (F1) 5..29 unsigned char mouthFormants5_29[30] = { @@ -565,7 +401,8 @@ void SetMouthThroat(unsigned char mouth, unsigned char throat) 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}; + 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 @@ -574,10 +411,10 @@ void SetMouthThroat(unsigned char mouth, unsigned char throat) // formant 2 frequencies (throat) 48..53 unsigned char throatFormants48_53[6] = {72, 39, 31, 43, 30, 34}; - unsigned char pos = 5; //mem39216 -//pos38942: + unsigned char pos = 5; + // recalculate formant frequencies 5..29 for the mouth (F1) and throat (F2) - while(pos != 30) + while(pos < 30) { // recalculate mouth frequency initialFrequency = mouthFormants5_29[pos]; @@ -591,30 +428,19 @@ void SetMouthThroat(unsigned char mouth, unsigned char throat) pos++; } -//pos39059: // recalculate formant frequencies 48..53 pos = 48; - Y = 0; - while(pos != 54) - { + while(pos < 54) { // recalculate F1 (mouth formant) - initialFrequency = mouthFormants48_53[Y]; + initialFrequency = mouthFormants48_53[pos-48]; newFrequency = trans(mouth, initialFrequency); freq1data[pos] = newFrequency; // recalculate F2 (throat formant) - initialFrequency = throatFormants48_53[Y]; + initialFrequency = throatFormants48_53[pos-48]; newFrequency = trans(throat, initialFrequency); freq2data[pos] = newFrequency; - Y++; pos++; } } - -unsigned char trans(unsigned char mem39212, unsigned char mem39213) -{ - return (mem39212 * mem39213) >> 7 & 0xfe; -} - - diff --git a/src/render.h b/src/render.h index a0c09bec..b3354656 100755 --- a/src/render.h +++ b/src/render.h @@ -6,6 +6,7 @@ void SetMouthThroat(unsigned char mouth, unsigned char throat); void ProcessFrames(unsigned char mem48); void RenderSample(unsigned char *mem66, unsigned char consonantFlag); +unsigned char CreateTransitions(); #define PHONEME_PERIOD (1) #define PHONEME_QUESTION (2) From 1c9c54875d38933d814347effcd3d0c66ec3d552 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Wed, 17 Dec 2014 07:57:24 +0000 Subject: [PATCH 011/109] Further refactoring --- src/RenderTabs.h | 12 +++---- src/processframes.c | 86 ++++++++++++++++++++++----------------------- src/render.c | 11 +++--- src/render.h | 2 +- 4 files changed, 54 insertions(+), 57 deletions(-) diff --git a/src/RenderTabs.h b/src/RenderTabs.h index be356c26..4af26819 100755 --- a/src/RenderTabs.h +++ b/src/RenderTabs.h @@ -248,7 +248,7 @@ unsigned char rectangle[] = 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 , +d 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 , @@ -268,11 +268,11 @@ unsigned char multtable[] = { 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , - 0x00 , 0x00 , 1 , 1 , 2 , 2 , 3 , 3 , - 4 , 4 , 5 , 5 , 6 , 6 , 7 , 7 , - 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , - 8 , 9 ,0xA ,0xB ,0xC ,0xD ,0xE ,0xF , - 0x00 , 1 , 3 , 4 , 6 , 7 , 9 ,0xA , + 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 , 9 ,0xA ,0xB ,0xC ,0xD ,0xE ,0xF , + 0x00 , 0x01 , 3 , 4 , 6 , 7 , 9 ,0xA , 0xC ,0xD ,0xF , 0x10 , 0x12 , 0x13 , 0x15 , 0x16 , 0x00 , 2 , 4 , 6 , 8 ,0xA ,0xC ,0xE , 0x10 , 0x12 , 0x14 , 0x16 , 0x18 , 0x1A , 0x1C , 0x1E , diff --git a/src/processframes.c b/src/processframes.c index 8ec7b1e9..7eb20b72 100644 --- a/src/processframes.c +++ b/src/processframes.c @@ -1,9 +1,6 @@ #include "render.h" -extern unsigned char mem39; -extern unsigned char Y; -extern unsigned char mem44; extern unsigned char speed; // From RenderTabs.h @@ -23,6 +20,19 @@ extern unsigned char frequency3[256]; extern void Output(int index, unsigned char A); +static void CombineGlottalAndFormants(unsigned char phase1, unsigned char phase2, unsigned char phase3, unsigned char Y) +{ + unsigned int tmp; + + tmp = multtable[sinus[phase1] | amplitude1[Y]]; + tmp += multtable[sinus[phase2] | amplitude2[Y]]; + tmp += tmp > 255 ? 1 : 0; // if addition above overflows, we for some reason add one; + tmp += multtable[rectangle[phase3] | amplitude3[Y]]; + tmp += 136; + tmp >>= 4; // Scale down to 0..15 range of C64 audio. + + Output(0, tmp & 0xf); +} // PROCESS THE FRAMES // @@ -42,32 +52,24 @@ void ProcessFrames(unsigned char mem48) unsigned char phase3 = 0; unsigned char mem66; - Y = 0; - mem44 = pitches[0]; + unsigned char Y = 0; - unsigned char mem38 = mem44 - (mem44 >> 2); + unsigned char glottal_pulse = pitches[0]; + unsigned char mem38 = glottal_pulse - (glottal_pulse >> 2); // mem44 * 0.75 - while(1) { - mem39 = sampledConsonantFlag[Y]; + while(mem48) { + unsigned char flags = sampledConsonantFlag[Y]; // unvoiced sampled phoneme? - if(mem39 & 248) { - RenderSample(&mem66, mem39); + if(flags & 248) { + RenderSample(&mem66, flags,Y); // skip ahead two in the phoneme buffer Y += 2; mem48 -= 2; - if(mem48 == 0) return; speedcounter = speed; } else { - // simulate the glottal pulse and formants - unsigned char mem56 = multtable[sinus[phase1] | amplitude1[Y]]; - unsigned char carry = ((mem56+multtable[sinus[phase2] | amplitude2[Y]] ) > 255); - mem56 += multtable[sinus[phase2] | amplitude2[Y]]; - unsigned char tmp = mem56 + multtable[rectangle[phase3] | amplitude3[Y]] + (carry?1:0); - tmp = ((tmp + 136) & 255) >> 4; //there must be also a carry - - // output the accumulated value - Output(0, tmp); + CombineGlottalAndFormants(phase1, phase2, phase3, Y); + speedcounter--; if (speedcounter == 0) { Y++; //go to next amplitude @@ -76,34 +78,32 @@ void ProcessFrames(unsigned char mem48) if(mem48 == 0) return; speedcounter = speed; } - } - // decrement the remaining length of the glottal pulse - mem44--; + --glottal_pulse; - // finished with a glottal pulse? - if(mem44 != 0) { - // decrement the count - mem38--; - - // is the count non-zero and the sampled flag is zero? - if((mem38 != 0) || (mem39 == 0)) { - // reset the phase of the formants to match the pulse - phase1 += frequency1[Y]; - phase2 += frequency2[Y]; - phase3 += frequency3[Y]; - continue; + if(glottal_pulse != 0) { + // not finished with a glottal pulse + + --mem38; + // within the first 75% of the glottal pulse? + // is the count non-zero and the sampled flag is zero? + if((mem38 != 0) || (flags == 0)) { + // reset the phase of the formants to match the pulse + phase1 += frequency1[Y]; + phase2 += frequency2[Y]; + phase3 += frequency3[Y]; + continue; + } + + // voiced sampled phonemes interleave the sample with the + // glottal pulse. The sample flag is non-zero, so render + // the sample for the phoneme. + RenderSample(&mem66, flags,Y); } - - // voiced sampled phonemes interleave the sample with the - // glottal pulse. The sample flag is non-zero, so render - // the sample for the phoneme. - RenderSample(&mem66, mem39); } - // fetch the next glottal pulse length - mem44 = pitches[Y]; - mem38 = mem44 - (mem44>>2); // mem44 * 0.75 + glottal_pulse = pitches[Y]; + mem38 = glottal_pulse - (glottal_pulse>>2); // mem44 * 0.75 // reset the formant wave generators to keep them in // sync with the glottal pulse diff --git a/src/render.c b/src/render.c index ca58a5c2..f269f5e3 100755 --- a/src/render.c +++ b/src/render.c @@ -12,8 +12,8 @@ extern int debug; unsigned char wait1 = 7; unsigned char wait2 = 6; -extern unsigned char A, X, Y; -extern unsigned char mem44; +//extern unsigned char A, X, Y; +//extern unsigned char mem44; extern unsigned char speed; extern unsigned char pitch; @@ -208,10 +208,9 @@ static void RenderUnvoicedSample(unsigned short hi, unsigned char off, unsigned // For voices samples, samples are interleaved between voiced output. -void RenderSample(unsigned char *mem66, unsigned char consonantFlag) +void RenderSample(unsigned char *mem66, unsigned char consonantFlag, unsigned char mem49) { - // current phoneme's index - unsigned char mem49 = Y; + // mem49 == current phoneme's index // mask low three bits and subtract 1 get value to // convert 0 bits on unvoiced samples. @@ -224,8 +223,6 @@ void RenderSample(unsigned char *mem66, unsigned char consonantFlag) // /H 3 0x17 // /X 4 0x17 - mem44 = 1; - unsigned short hi = hibyte*256; // voiced sample? unsigned char pitch = consonantFlag & 248; diff --git a/src/render.h b/src/render.h index b3354656..d44f898c 100755 --- a/src/render.h +++ b/src/render.h @@ -5,7 +5,7 @@ void Render(); void SetMouthThroat(unsigned char mouth, unsigned char throat); void ProcessFrames(unsigned char mem48); -void RenderSample(unsigned char *mem66, unsigned char consonantFlag); +void RenderSample(unsigned char *mem66, unsigned char consonantFlag, unsigned char mem49); unsigned char CreateTransitions(); #define PHONEME_PERIOD (1) From ecafefd7694bed24e3ff699fcaada6ff1bf20335 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Fri, 19 Dec 2014 22:16:53 +0000 Subject: [PATCH 012/109] Refactoring of reciter --- src/reciter.c | 893 +++++++++++++++++++++----------------------------- 1 file changed, 373 insertions(+), 520 deletions(-) diff --git a/src/reciter.c b/src/reciter.c index ca976e92..2e835bf9 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -10,13 +10,13 @@ extern int debug; static unsigned char inputtemp[256]; // secure copy of input tab36096 void Code37055(unsigned char mem59) -{ - X = mem59; - X--; - A = inputtemp[X]; - Y = A; - A = tab36376[Y]; - return; +{ + X = mem59; + X--; + A = inputtemp[X]; + Y = A; + A = tab36376[Y]; + return; } void Code37066(unsigned char mem58) @@ -37,518 +37,371 @@ unsigned char GetRuleByte(unsigned short mem62, unsigned char Y) address -= 37541; return rules2[address+Y]; } - address -= 32000; - return rules[address+Y]; -} - -int TextToPhonemes(char *input) // Code36484 -{ - //unsigned char *tab39445 = &mem[39445]; //input and output - //unsigned char mem29; - unsigned char mem56; //output position for phonemes - unsigned char mem57; - unsigned char mem58; - unsigned char mem59; - unsigned char mem60; - unsigned char mem61; - unsigned short mem62; // memory position of current rule - - unsigned char mem64; // position of '=' or current character - unsigned char mem65; // position of ')' - unsigned char mem66; // position of '(' - unsigned char mem36653; - - inputtemp[0] = 32; - - // secure copy of input - // because input will be overwritten by phonemes - X = 1; - Y = 0; - do - { - //pos36499: - A = input[Y] & 127; - if ( A >= 112) A = A & 95; - else if ( A >= 96) A = A & 79; - - inputtemp[X] = A; - X++; - Y++; - } while (Y != 255); - - - X = 255; - inputtemp[X] = 27; - mem61 = 255; - - -pos36550: - A = 255; - mem56 = 255; - - -pos36554: - while(1) - { - mem61++; - X = mem61; - A = inputtemp[X]; - mem64 = A; - if (A == '[') - { - mem56++; - X = mem56; - A = 155; - input[X] = 155; - //goto pos36542; - // Code39771(); //Code39777(); - return 1; - } - - //pos36579: - if (A != '.') break; - X++; - Y = inputtemp[X]; - A = tab36376[Y] & 1; - if(A != 0) break; - mem56++; - X = mem56; - A = '.'; - input[X] = '.'; - } //while - - - //pos36607: - A = mem64; - Y = A; - A = tab36376[A]; - mem57 = A; - if((A&2) != 0) - { - mem62 = 37541; - goto pos36700; - } - - //pos36630: - A = mem57; - if(A != 0) goto pos36677; - A = 32; - inputtemp[X] = ' '; - mem56++; - X = mem56; - if (X > 120) goto pos36654; - input[X] = A; - goto pos36554; - - // ----- - - //36653 is unknown. Contains position - -pos36654: - input[X] = 155; - A = mem61; - mem36653 = A; - // mem29 = A; // not used - // Code36538(); das ist eigentlich - return 1; - //Code39771(); - //go on if there is more input ??? - mem61 = mem36653; - goto pos36550; - -pos36677: - A = mem57 & 128; - if(A == 0) - { - //36683: BRK - return 0; - } - - // go to the right rules for this character. - X = mem64 - 'A'; - mem62 = tab37489[X] | (tab37515[X]<<8); - - // ------------------------------------- - // go to next rule - // ------------------------------------- - -pos36700: - - // find next rule - Y = 0; - do - { - mem62 += 1; - A = GetRuleByte(mem62, Y); - } while ((A & 128) == 0); - Y++; - - //pos36720: - // find '(' - while(1) - { - A = GetRuleByte(mem62, Y); - if (A == '(') break; - Y++; - } - mem66 = Y; - - //pos36732: - // find ')' - do - { - Y++; - A = GetRuleByte(mem62, Y); - } while(A != ')'); - mem65 = Y; - - //pos36741: - // find '=' - do - { - Y++; - A = GetRuleByte(mem62, Y); - A = A & 127; - } while (A != '='); - mem64 = Y; - - X = mem61; - mem60 = X; - - // compare the string within the bracket - Y = mem66; - Y++; - //pos36759: - while(1) - { - mem57 = inputtemp[X]; - A = GetRuleByte(mem62, Y); - if (A != mem57) goto pos36700; - Y++; - if(Y == mem65) break; - X++; - mem60 = X; - } - -// the string in the bracket is correct - -//pos36787: - A = mem61; - mem59 = mem61; - -pos36791: - while(1) - { - mem66--; - Y = mem66; - A = GetRuleByte(mem62, Y); - mem57 = A; - //36800: BPL 36805 - if ((A & 128) != 0) goto pos37180; - X = A & 127; - A = tab36376[X] & 128; - if (A == 0) break; - X = mem59-1; - A = inputtemp[X]; - if (A != mem57) goto pos36700; - mem59 = X; - } - -//pos36833: - A = mem57; - if (A == ' ') goto pos36895; - if (A == '#') goto pos36910; - if (A == '.') goto pos36920; - if (A == '&') goto pos36935; - if (A == '@') goto pos36967; - if (A == '^') goto pos37004; - if (A == '+') goto pos37019; - if (A == ':') goto pos37040; - // Code42041(); //Error - //36894: BRK - return 0; - - // -------------- - -pos36895: - Code37055(mem59); - A = A & 128; - if(A != 0) goto pos36700; -pos36905: - mem59 = X; - goto pos36791; - - // -------------- - -pos36910: - Code37055(mem59); - A = A & 64; - if(A != 0) goto pos36905; - goto pos36700; - - // -------------- - - -pos36920: - Code37055(mem59); - A = A & 8; - if(A == 0) goto pos36700; -pos36930: - mem59 = X; - goto pos36791; - - // -------------- - -pos36935: - Code37055(mem59); - A = A & 16; - if(A != 0) goto pos36930; - A = inputtemp[X]; - if (A != 72) goto pos36700; - X--; - A = inputtemp[X]; - if ((A == 67) || (A == 83)) goto pos36930; - goto pos36700; - - // -------------- - -pos36967: - Code37055(mem59); - A = A & 4; - if(A != 0) goto pos36930; - A = inputtemp[X]; - if (A != 72) goto pos36700; - if ((A != 84) && (A != 67) && (A != 83)) goto pos36700; - mem59 = X; - goto pos36791; - - // -------------- - - -pos37004: - Code37055(mem59); - A = A & 32; - if(A == 0) goto pos36700; - -pos37014: - mem59 = X; - goto pos36791; - - // -------------- - -pos37019: - X = mem59; - X--; - A = inputtemp[X]; - if ((A == 'E') || (A == 'I') || (A == 'Y')) goto pos37014; - goto pos36700; - // -------------- - -pos37040: - Code37055(mem59); - A = A & 32; - if(A == 0) goto pos36791; - mem59 = X; - goto pos37040; - -//--------------------------------------- - - -pos37077: - X = mem58+1; - A = inputtemp[X]; - if (A != 'E') goto pos37157; - X++; - Y = inputtemp[X]; - X--; - A = tab36376[Y] & 128; - if(A == 0) goto pos37108; - X++; - A = inputtemp[X]; - if (A != 'R') goto pos37113; -pos37108: - mem58 = X; - goto pos37184; -pos37113: - if ((A == 83) || (A == 68)) goto pos37108; // 'S' 'D' - if (A != 76) goto pos37135; // 'L' - X++; - A = inputtemp[X]; - if (A != 89) goto pos36700; - goto pos37108; - -pos37135: - if (A != 70) goto pos36700; - X++; - A = inputtemp[X]; - if (A != 85) goto pos36700; - X++; - A = inputtemp[X]; - if (A == 76) goto pos37108; - goto pos36700; - -pos37157: - if (A != 73) goto pos36700; - X++; - A = inputtemp[X]; - if (A != 78) goto pos36700; - X++; - A = inputtemp[X]; - if (A == 71) goto pos37108; - //pos37177: - goto pos36700; - - // ----------------------------------------- - -pos37180: - - A = mem60; - mem58 = A; - -pos37184: - Y = mem65 + 1; - - //37187: CPY 64 - // if(? != 0) goto pos37194; - if(Y == mem64) goto pos37455; - mem65 = Y; - //37196: LDA (62),y - A = GetRuleByte(mem62, Y); - mem57 = A; - X = A; - A = tab36376[X] & 128; - if(A == 0) goto pos37226; - X = mem58+1; - A = inputtemp[X]; - if (A != mem57) goto pos36700; - mem58 = X; - goto pos37184; -pos37226: - A = mem57; - if (A == 32) goto pos37295; // ' ' - if (A == 35) goto pos37310; // '#' - if (A == 46) goto pos37320; // '.' - if (A == 38) goto pos37335; // '&' - if (A == 64) goto pos37367; // '' - if (A == 94) goto pos37404; // '' - if (A == 43) goto pos37419; // '+' - if (A == 58) goto pos37440; // ':' - if (A == 37) goto pos37077; // '%' - //pos37291: - // Code42041(); //Error - //37294: BRK - return 0; - - // -------------- -pos37295: - Code37066(mem58); - A = A & 128; - if(A != 0) goto pos36700; -pos37305: - mem58 = X; - goto pos37184; - - // -------------- - -pos37310: - Code37066(mem58); - A = A & 64; - if(A != 0) goto pos37305; - goto pos36700; - - // -------------- - - -pos37320: - Code37066(mem58); - A = A & 8; - if(A == 0) goto pos36700; - -pos37330: - mem58 = X; - goto pos37184; - - // -------------- - -pos37335: - Code37066(mem58); - A = A & 16; - if(A != 0) goto pos37330; - A = inputtemp[X]; - if (A != 72) goto pos36700; - X++; - A = inputtemp[X]; - if ((A == 67) || (A == 83)) goto pos37330; - goto pos36700; - - // -------------- - - -pos37367: - Code37066(mem58); - A = A & 4; - if(A != 0) goto pos37330; - A = inputtemp[X]; - if (A != 72) goto pos36700; - if ((A != 84) && (A != 67) && (A != 83)) goto pos36700; - mem58 = X; - goto pos37184; - - // -------------- - -pos37404: - Code37066(mem58); - A = A & 32; - if(A == 0) goto pos36700; -pos37414: - mem58 = X; - goto pos37184; - - // -------------- - -pos37419: - X = mem58; - X++; - A = inputtemp[X]; - if ((A == 69) || (A == 73) || (A == 89)) goto pos37414; - goto pos36700; - -// ---------------------- - -pos37440: - - Code37066(mem58); - A = A & 32; - if(A == 0) goto pos37184; - mem58 = X; - goto pos37440; -pos37455: - Y = mem64; - mem61 = mem60; - - if (debug) - PrintRule(mem62); - -pos37461: - //37461: LDA (62),y - A = GetRuleByte(mem62, Y); - mem57 = A; - A = A & 127; - if (A != '=') - { - mem56++; - X = mem56; - input[X] = A; - } - - //37478: BIT 57 - //37480: BPL 37485 //not negative flag - if ((mem57 & 128) == 0) goto pos37485; //??? - goto pos36554; -pos37485: - Y++; - goto pos37461; -} - + address -= 32000; + return rules[address+Y]; +} + +int TextToPhonemes(char *input) +{ + unsigned char mem56; //output position for phonemes + unsigned char mem57; + unsigned char mem58; + unsigned char mem59; + unsigned char mem60; + unsigned char mem61; + unsigned short mem62; // memory position of current rule + unsigned char mem64; // position of '=' or current character + unsigned char mem65; // position of ')' + unsigned char mem66; // position of '(' + + inputtemp[0] = 32; + + // secure copy of input + // because input will be overwritten by phonemes + X = 1; + Y = 0; + + do { + A = input[Y] & 127; + if ( A >= 112) A = A & 95; + else if ( A >= 96) A = A & 79; + + inputtemp[X] = A; + X++; + } while (++Y != 255); + + inputtemp[255] = 27; + mem61 = 255; + + mem56 = 255; + +pos36554: + do { + + while(1) + { + X = ++mem61; + A = inputtemp[mem61]; + mem64 = A; + if (A == '[') + { + ++mem56; + X = mem56; + A = 155; + input[X] = 155; + return 1; + } + + if (A != '.') break; + X++; + Y = inputtemp[X]; + A = tab36376[Y] & 1; + if(A != 0) break; + mem56++; + X = mem56; + A = '.'; + input[X] = '.'; + } + + A = mem64; + Y = A; + A = tab36376[A]; + mem57 = A; + if((A&2) != 0) + { + mem62 = 37541; + goto pos36700; + } + + A = mem57; + if(A != 0) goto pos36677; + A = 32; + inputtemp[X] = ' '; + X = ++mem56; + input[X] = A; + } while (mem56 <= 120); + + input[X] = 155; + A = mem61; + + return 1; + +pos36677: + A = mem57 & 128; + if(A == 0) return 0; + + // go to the right rules for this character. + X = mem64 - 'A'; + mem62 = tab37489[X] | (tab37515[X]<<8); + + // ------------------------------------- + // go to next rule + // ------------------------------------- +pos36700: + // find next rule + Y = 0; + do { + A = GetRuleByte(++mem62, Y); + } while ((A & 128) == 0); + ++Y; + + // find '(' + while(1) { + A = GetRuleByte(mem62, Y); + if (A == '(') break; + Y++; + } + mem66 = Y; + + while (GetRuleByte(mem62, ++Y) != ')'); + mem65 = Y; + + // find '=' + while ((GetRuleByte(mem62, ++Y) & 127) != '='); + mem64 = Y; + + mem60 = X = mem61; + + // compare the string within the bracket + Y = mem66 + 1; + + while(1) { + mem57 = inputtemp[X]; + if (GetRuleByte(mem62, Y) != mem57) goto pos36700; + ++Y; + if(Y == mem65) break; + ++X; + mem60 = X; + } + + // the string in the bracket is correct + mem59 = mem61; + + pos36791: + while(1) { + Y = --mem66; + mem57 = GetRuleByte(mem62, Y); + if ((mem57 & 128) != 0) { + mem58 = A = mem60; + goto pos37184; + } + X = mem57 & 127; + A = tab36376[X] & 128; + if (A == 0) break; + X = mem59-1; + A = inputtemp[X]; + if (A != mem57) goto pos36700; + mem59 = X; + } + + A = mem57; + switch (A) { + case ' ': + Code37055(mem59); + if ((A & 128) != 0) goto pos36700; + break; + case '#': + Code37055(mem59); + if((A&64) == 0) goto pos36700; + break; + case '.': + Code37055(mem59); + if((A&8) == 0) goto pos36700; + break; + case '&': + Code37055(mem59); + if((A & 16) != 0) break; + A = inputtemp[X]; + if (A != 72) goto pos36700; + X--; + A = inputtemp[X]; + if ((A == 67) || (A == 83)) break; + goto pos36700; + case '@': + Code37055(mem59); + if(A & 4!= 0) break; + A = inputtemp[X]; + if (A != 72) goto pos36700; + if ((A != 84) && (A != 67) && (A != 83)) goto pos36700; + break; + case '^': + Code37055(mem59); + if((A & 32) == 0) goto pos36700; + break; + case '+': + X = mem59; + X--; + A = inputtemp[X]; + if ((A == 'E') || (A == 'I') || (A == 'Y')) break; + goto pos36700; + case ':': + while((tab36376[inputtemp[mem59-1]] & 32)) --mem59; + goto pos36791; + default: + return 0; + }; + + mem59 = X; + goto pos36791; + + pos37077: + X = mem58+1; + A = inputtemp[X]; + if (A != 'E') goto pos37157; + Y = inputtemp[X+1]; + A = tab36376[Y] & 128; + if(A == 0) { + mem58 = X; + goto pos37184; + } + A = inputtemp[++X]; + + + if ((A == 'R') || (A == 'S') || (A == 'D')) { + mem58 = X; + goto pos37184; + } + if (A == 'L') { + X++; + A = inputtemp[X]; + if (A != 89) goto pos36700; + mem58 = X; + goto pos37184; + } + + if (A == 70) { + A = inputtemp[++X]; + if (A == 85) { + A = inputtemp[++X]; + if (A == 76) { + mem58 = X; + goto pos37184; + } + } + } + goto pos36700; + +pos37157: + if (A == 73) { + A = inputtemp[++X]; + if (A == 78) { + A = inputtemp[++X]; + if (A == 71) { + mem58 = X; + goto pos37184; + } + } + } + goto pos36700; + + // ----------------------------------------- + +pos37184: + while (1) { + Y = mem65 + 1; + if(Y == mem64) { + Y = mem64; + mem61 = mem60; + + if (debug) PrintRule(mem62); + + while(1) { + mem57 = GetRuleByte(mem62, Y); + A = mem57 & 127; + if (A != '=') { + mem56++; + X = mem56; + input[X] = A; + } + if ((mem57 & 128) != 0) goto pos36554; + Y++; + } + } + mem65 = Y; + X = mem57 = GetRuleByte(mem62, Y); + A = tab36376[X] & 128; + if(A == 0) break; + X = mem58+1; + A = inputtemp[X]; + if (A != mem57) goto pos36700; + mem58 = X; + } + + A = mem57; + switch(A) { + case ' ': + Code37066(mem58); + A = A & 128; + if(A != 0) goto pos36700; + mem58 = X; + goto pos37184; + case '#': + Code37066(mem58); + if((A & 64) == 0) goto pos36700; + mem58 = X; + goto pos37184; + case '.': + Code37066(mem58); + if((A & 8) == 0) goto pos36700; + mem58 = X; + goto pos37184; + case '&': + Code37066(mem58); + A = A & 16; + if(A != 0) { + mem58 = X; + goto pos37184; + } + A = inputtemp[X]; + if (A != 72) goto pos36700; + X++; + A = inputtemp[X]; + if ((A == 67) || (A == 83)) { + mem58 = X; + goto pos37184; + } + goto pos36700; + case 64: + Code37066(mem58); + if((A & 4) != 0) { + mem58 = X; + goto pos37184; + } + A = inputtemp[X]; + if (A != 72) goto pos36700; + if ((A != 84) && (A != 67) && (A != 83)) goto pos36700; + mem58 = X; + goto pos37184; + + case 94: + Code37066(mem58); + if((A & 32) == 0) goto pos36700; + mem58 = X; + goto pos37184; + + case '+': + X = mem59; + X--; + A = inputtemp[X]; + if ((A == 'E') || (A == 'I') || (A == 'Y')) { + mem58 = X; + goto pos37184; + } + goto pos36700; + case ':': + while (1) { + Code37066(mem58); + A = A & 32; + if(A == 0) goto pos37184; + mem58 = X; + } + case '%': + goto pos37077; + } + + + return 0; +} + From 05439ddca3cea469283c3d303b4eaa2e1d69d58f Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Fri, 2 Jan 2015 05:21:47 +0000 Subject: [PATCH 013/109] More refactoring --- src/reciter.c | 883 +++++++++++++++++++++++++++++--------------------- 1 file changed, 515 insertions(+), 368 deletions(-) diff --git a/src/reciter.c b/src/reciter.c index 2e835bf9..df9bbe68 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -1,33 +1,33 @@ -#include -#include -#include "reciter.h" -#include "ReciterTabs.h" -#include "debug.h" - -unsigned char A, X, Y; +#include +#include +#include "reciter.h" +#include "ReciterTabs.h" +#include "debug.h" + +unsigned char A, X, Y; extern int debug; - -static unsigned char inputtemp[256]; // secure copy of input tab36096 - -void Code37055(unsigned char mem59) + +static unsigned char inputtemp[256]; // secure copy of input tab36096 + +/* Retrieve flags for character at mem59-1 */ +unsigned char Code37055(unsigned char mem59) { - X = mem59; - X--; + X = mem59 - 1; + unsigned char A = inputtemp[X]; + Y = A; + A = tab36376[A]; + return A; +} + +/* Retrieve flags for character at mem58 + 1 */ +void Code37066(unsigned char mem58) +{ + X = mem58 + 1; A = inputtemp[X]; Y = A; A = tab36376[Y]; - return; -} - -void Code37066(unsigned char mem58) -{ - X = mem58; - X++; - A = inputtemp[X]; - Y = A; - A = tab36376[Y]; -} - +} + unsigned char GetRuleByte(unsigned short mem62, unsigned char Y) { unsigned int address = mem62; @@ -37,371 +37,518 @@ unsigned char GetRuleByte(unsigned short mem62, unsigned char Y) address -= 37541; return rules2[address+Y]; } - address -= 32000; - return rules[address+Y]; -} - -int TextToPhonemes(char *input) -{ - unsigned char mem56; //output position for phonemes - unsigned char mem57; - unsigned char mem58; - unsigned char mem59; - unsigned char mem60; - unsigned char mem61; - unsigned short mem62; // memory position of current rule - unsigned char mem64; // position of '=' or current character - unsigned char mem65; // position of ')' - unsigned char mem66; // position of '(' - - inputtemp[0] = 32; - - // secure copy of input - // because input will be overwritten by phonemes - X = 1; - Y = 0; - - do { - A = input[Y] & 127; - if ( A >= 112) A = A & 95; - else if ( A >= 96) A = A & 79; - - inputtemp[X] = A; - X++; - } while (++Y != 255); - - inputtemp[255] = 27; - mem61 = 255; - - mem56 = 255; - -pos36554: - do { - - while(1) - { - X = ++mem61; - A = inputtemp[mem61]; - mem64 = A; - if (A == '[') - { - ++mem56; - X = mem56; - A = 155; - input[X] = 155; - return 1; - } - - if (A != '.') break; - X++; - Y = inputtemp[X]; - A = tab36376[Y] & 1; - if(A != 0) break; - mem56++; - X = mem56; - A = '.'; - input[X] = '.'; - } - - A = mem64; - Y = A; - A = tab36376[A]; - mem57 = A; - if((A&2) != 0) - { - mem62 = 37541; - goto pos36700; - } - - A = mem57; - if(A != 0) goto pos36677; - A = 32; - inputtemp[X] = ' '; - X = ++mem56; - input[X] = A; - } while (mem56 <= 120); - - input[X] = 155; - A = mem61; - - return 1; - -pos36677: - A = mem57 & 128; - if(A == 0) return 0; - - // go to the right rules for this character. - X = mem64 - 'A'; - mem62 = tab37489[X] | (tab37515[X]<<8); + address -= 32000; + return rules[address+Y]; +} + +int TextToPhonemes(char *input) // Code36484 +{ + //unsigned char *tab39445 = &mem[39445]; //input and output + //unsigned char mem29; + unsigned char mem56; //output position for phonemes + unsigned char mem57; + unsigned char mem58; + unsigned char mem59; + unsigned char mem60; + unsigned char mem61; + unsigned short mem62; // memory position of current rule + + unsigned char mem64; // position of '=' or current character + unsigned char mem65; // position of ')' + unsigned char mem66; // position of '(' + unsigned char mem36653; + + inputtemp[0] = 32; + + // secure copy of input + // because input will be overwritten by phonemes + X = 1; + Y = 0; + do + { + //pos36499: + A = input[Y] & 127; + if ( A >= 112) A = A & 95; + else if ( A >= 96) A = A & 79; + + inputtemp[X] = A; + X++; + Y++; + } while (Y != 255); + + + X = 255; + inputtemp[X] = 27; + mem61 = 255; + + +pos36550: + A = 255; + mem56 = 255; + + +pos36554: + while(1) + { + mem61++; + X = mem61; + A = inputtemp[X]; + mem64 = A; + if (A == '[') + { + mem56++; + X = mem56; + A = 155; + input[X] = 155; + //goto pos36542; + // Code39771(); //Code39777(); + return 1; + } + + //pos36579: + if (A != '.') break; + X++; + Y = inputtemp[X]; + A = tab36376[Y] & 1; + if(A != 0) break; + mem56++; + X = mem56; + A = '.'; + input[X] = '.'; + } //while + + + //pos36607: + A = mem64; + Y = A; + A = tab36376[A]; + mem57 = A; + if((A&2) != 0) + { + mem62 = 37541; + goto pos36700; + } + + //pos36630: + A = mem57; + if(A != 0) goto pos36677; + A = 32; + inputtemp[X] = ' '; + mem56++; + X = mem56; + if (X > 120) goto pos36654; + input[X] = A; + goto pos36554; + + // ----- + + //36653 is unknown. Contains position + +pos36654: + input[X] = 155; + A = mem61; + mem36653 = A; + // mem29 = A; // not used + // Code36538(); das ist eigentlich + return 1; + //Code39771(); + //go on if there is more input ??? + mem61 = mem36653; + goto pos36550; + +pos36677: + A = mem57 & 128; + if(A == 0) + { + //36683: BRK + return 0; + } + + // go to the right rules for this character. + X = mem64 - 'A'; + mem62 = tab37489[X] | (tab37515[X]<<8); + + // ------------------------------------- + // go to next rule + // ------------------------------------- + +pos36700: + + // find next rule + Y = 0; + do + { + mem62 += 1; + A = GetRuleByte(mem62, Y); + } while ((A & 128) == 0); + Y++; + + //pos36720: + // find '(' + while(1) + { + A = GetRuleByte(mem62, Y); + if (A == '(') break; + Y++; + } + mem66 = Y; + + //pos36732: + // find ')' + do + { + Y++; + A = GetRuleByte(mem62, Y); + } while(A != ')'); + mem65 = Y; + + //pos36741: + // find '=' + do + { + Y++; + A = GetRuleByte(mem62, Y); + A = A & 127; + } while (A != '='); + mem64 = Y; + + X = mem61; + mem60 = X; + + // compare the string within the bracket + Y = mem66; + Y++; + //pos36759: + while(1) + { + mem57 = inputtemp[X]; + A = GetRuleByte(mem62, Y); + if (A != mem57) goto pos36700; + Y++; + if(Y == mem65) break; + X++; + mem60 = X; + } + +// the string in the bracket is correct + +//pos36787: + A = mem61; + mem59 = mem61; + +pos36791: + while(1) + { + mem66--; + Y = mem66; + A = GetRuleByte(mem62, Y); + mem57 = A; + //36800: BPL 36805 + if ((A & 128) != 0) goto pos37180; + X = A & 127; + A = tab36376[X] & 128; + if (A == 0) break; + X = mem59-1; + A = inputtemp[X]; + if (A != mem57) goto pos36700; + mem59 = X; + } + +//pos36833: + A = mem57; + if (A == ' ') goto pos36895; + if (A == '#') goto pos36910; + if (A == '.') goto pos36920; + if (A == '&') goto pos36935; + if (A == '@') goto pos36967; + if (A == '^') goto pos37004; + if (A == '+') goto pos37019; + if (A == ':') goto pos37040; + // Code42041(); //Error + //36894: BRK + return 0; + // -------------- + +pos36895: + A = Code37055(mem59) & 128; + if(A != 0) goto pos36700; +pos36905: + mem59 = X; + goto pos36791; - // ------------------------------------- - // go to next rule - // ------------------------------------- -pos36700: - // find next rule - Y = 0; - do { - A = GetRuleByte(++mem62, Y); - } while ((A & 128) == 0); - ++Y; + // -------------- - // find '(' - while(1) { - A = GetRuleByte(mem62, Y); - if (A == '(') break; - Y++; - } - mem66 = Y; +pos36910: + A = Code37055(mem59) & 64; + if(A != 0) goto pos36905; + goto pos36700; - while (GetRuleByte(mem62, ++Y) != ')'); - mem65 = Y; + // -------------- - // find '=' - while ((GetRuleByte(mem62, ++Y) & 127) != '='); - mem64 = Y; +pos36920: + A = Code37055(mem59) & 8; + if(A == 0) goto pos36700; + --mem59; + goto pos36791; - mem60 = X = mem61; +pos36930: + mem59 = X; + goto pos36791; - // compare the string within the bracket - Y = mem66 + 1; + // -------------- - while(1) { - mem57 = inputtemp[X]; - if (GetRuleByte(mem62, Y) != mem57) goto pos36700; - ++Y; - if(Y == mem65) break; - ++X; - mem60 = X; - } +pos36935: + A = Code37055(mem59) & 16; + if(A != 0) goto pos36930; + A = inputtemp[X]; + if (A != 72) goto pos36700; + X--; + A = inputtemp[X]; + if ((A == 67) || (A == 83)) goto pos36930; + goto pos36700; - // the string in the bracket is correct - mem59 = mem61; + // -------------- - pos36791: - while(1) { - Y = --mem66; - mem57 = GetRuleByte(mem62, Y); - if ((mem57 & 128) != 0) { - mem58 = A = mem60; - goto pos37184; - } - X = mem57 & 127; - A = tab36376[X] & 128; - if (A == 0) break; - X = mem59-1; - A = inputtemp[X]; - if (A != mem57) goto pos36700; - mem59 = X; - } +pos36967: + A = Code37055(mem59) & 4; + if(A != 0) goto pos36930; + A = inputtemp[X]; + if (A != 72) goto pos36700; + if ((A != 84) && (A != 67) && (A != 83)) goto pos36700; + mem59 = X; + goto pos36791; - A = mem57; - switch (A) { - case ' ': - Code37055(mem59); - if ((A & 128) != 0) goto pos36700; - break; - case '#': - Code37055(mem59); - if((A&64) == 0) goto pos36700; - break; - case '.': - Code37055(mem59); - if((A&8) == 0) goto pos36700; - break; - case '&': - Code37055(mem59); - if((A & 16) != 0) break; - A = inputtemp[X]; - if (A != 72) goto pos36700; - X--; - A = inputtemp[X]; - if ((A == 67) || (A == 83)) break; - goto pos36700; - case '@': - Code37055(mem59); - if(A & 4!= 0) break; - A = inputtemp[X]; - if (A != 72) goto pos36700; - if ((A != 84) && (A != 67) && (A != 83)) goto pos36700; - break; - case '^': - Code37055(mem59); - if((A & 32) == 0) goto pos36700; - break; - case '+': - X = mem59; - X--; - A = inputtemp[X]; - if ((A == 'E') || (A == 'I') || (A == 'Y')) break; - goto pos36700; - case ':': - while((tab36376[inputtemp[mem59-1]] & 32)) --mem59; - goto pos36791; - default: - return 0; - }; + // -------------- +pos37004: + A = Code37055(mem59) & 32; + if(A == 0) goto pos36700; mem59 = X; goto pos36791; - pos37077: - X = mem58+1; - A = inputtemp[X]; - if (A != 'E') goto pos37157; - Y = inputtemp[X+1]; - A = tab36376[Y] & 128; - if(A == 0) { - mem58 = X; - goto pos37184; - } - A = inputtemp[++X]; +pos37014: + mem59 = X; + goto pos36791; + // -------------- - if ((A == 'R') || (A == 'S') || (A == 'D')) { - mem58 = X; - goto pos37184; - } - if (A == 'L') { - X++; - A = inputtemp[X]; - if (A != 89) goto pos36700; - mem58 = X; - goto pos37184; - } - - if (A == 70) { - A = inputtemp[++X]; - if (A == 85) { - A = inputtemp[++X]; - if (A == 76) { - mem58 = X; - goto pos37184; - } - } +pos37019: + X = mem59; + X--; + A = inputtemp[X]; + if ((A == 'E') || (A == 'I') || (A == 'Y')) { + mem59 = X; + goto pos36791; } - goto pos36700; -pos37157: - if (A == 73) { - A = inputtemp[++X]; - if (A == 78) { - A = inputtemp[++X]; - if (A == 71) { - mem58 = X; - goto pos37184; - } - } - } goto pos36700; + // -------------- - // ----------------------------------------- - -pos37184: +pos37040: while (1) { - Y = mem65 + 1; - if(Y == mem64) { - Y = mem64; - mem61 = mem60; - - if (debug) PrintRule(mem62); - - while(1) { - mem57 = GetRuleByte(mem62, Y); - A = mem57 & 127; - if (A != '=') { - mem56++; - X = mem56; - input[X] = A; - } - if ((mem57 & 128) != 0) goto pos36554; - Y++; - } - } - mem65 = Y; - X = mem57 = GetRuleByte(mem62, Y); - A = tab36376[X] & 128; - if(A == 0) break; - X = mem58+1; - A = inputtemp[X]; - if (A != mem57) goto pos36700; - mem58 = X; - } - - A = mem57; - switch(A) { - case ' ': - Code37066(mem58); - A = A & 128; - if(A != 0) goto pos36700; - mem58 = X; - goto pos37184; - case '#': - Code37066(mem58); - if((A & 64) == 0) goto pos36700; - mem58 = X; - goto pos37184; - case '.': - Code37066(mem58); - if((A & 8) == 0) goto pos36700; - mem58 = X; - goto pos37184; - case '&': - Code37066(mem58); - A = A & 16; - if(A != 0) { - mem58 = X; - goto pos37184; - } - A = inputtemp[X]; - if (A != 72) goto pos36700; - X++; - A = inputtemp[X]; - if ((A == 67) || (A == 83)) { - mem58 = X; - goto pos37184; - } - goto pos36700; - case 64: - Code37066(mem58); - if((A & 4) != 0) { - mem58 = X; - goto pos37184; - } - A = inputtemp[X]; - if (A != 72) goto pos36700; - if ((A != 84) && (A != 67) && (A != 83)) goto pos36700; - mem58 = X; - goto pos37184; - - case 94: - Code37066(mem58); - if((A & 32) == 0) goto pos36700; - mem58 = X; - goto pos37184; - - case '+': - X = mem59; - X--; - A = inputtemp[X]; - if ((A == 'E') || (A == 'I') || (A == 'Y')) { - mem58 = X; - goto pos37184; - } - goto pos36700; - case ':': - while (1) { - Code37066(mem58); - A = A & 32; - if(A == 0) goto pos37184; - mem58 = X; - } - case '%': - goto pos37077; + A = Code37055(mem59) & 32; + if(A == 0) goto pos36791; + mem59 = X; } - - return 0; -} - +//--------------------------------------- + + +pos37077: + X = mem58+1; + A = inputtemp[X]; + if (A != 'E') goto pos37157; + X++; + Y = inputtemp[X]; + X--; + A = tab36376[Y] & 128; + if(A == 0) goto pos37108; + X++; + A = inputtemp[X]; + if (A != 'R') goto pos37113; +pos37108: + mem58 = X; + goto pos37184; +pos37113: + if ((A == 83) || (A == 68)) goto pos37108; // 'S' 'D' + if (A != 76) goto pos37135; // 'L' + X++; + A = inputtemp[X]; + if (A != 89) goto pos36700; + goto pos37108; + +pos37135: + if (A != 70) goto pos36700; + X++; + A = inputtemp[X]; + if (A != 85) goto pos36700; + X++; + A = inputtemp[X]; + if (A == 76) goto pos37108; + goto pos36700; + +pos37157: + if (A != 73) goto pos36700; + X++; + A = inputtemp[X]; + if (A != 78) goto pos36700; + X++; + A = inputtemp[X]; + if (A == 71) goto pos37108; + //pos37177: + goto pos36700; + + // ----------------------------------------- + +pos37180: + + A = mem60; + mem58 = A; + +pos37184: + Y = mem65 + 1; + + //37187: CPY 64 + // if(? != 0) goto pos37194; + if(Y == mem64) goto pos37455; + mem65 = Y; + //37196: LDA (62),y + A = GetRuleByte(mem62, Y); + mem57 = A; + X = A; + A = tab36376[X] & 128; + if(A == 0) goto pos37226; + X = mem58+1; + A = inputtemp[X]; + if (A != mem57) goto pos36700; + mem58 = X; + goto pos37184; +pos37226: + A = mem57; + if (A == 32) goto pos37295; // ' ' + if (A == 35) goto pos37310; // '#' + if (A == 46) goto pos37320; // '.' + if (A == 38) goto pos37335; // '&' + if (A == 64) goto pos37367; // '' + if (A == 94) goto pos37404; // '' + if (A == 43) goto pos37419; // '+' + if (A == 58) goto pos37440; // ':' + if (A == 37) goto pos37077; // '%' + //pos37291: + // Code42041(); //Error + //37294: BRK + return 0; + + // -------------- +pos37295: + Code37066(mem58); + A = A & 128; + if(A != 0) goto pos36700; +pos37305: + mem58 = X; + goto pos37184; + + // -------------- + +pos37310: + Code37066(mem58); + A = A & 64; + if(A != 0) goto pos37305; + goto pos36700; + + // -------------- + + +pos37320: + Code37066(mem58); + A = A & 8; + if(A == 0) goto pos36700; + +pos37330: + mem58 = X; + goto pos37184; + + // -------------- + +pos37335: + Code37066(mem58); + A = A & 16; + if(A != 0) goto pos37330; + A = inputtemp[X]; + if (A != 72) goto pos36700; + X++; + A = inputtemp[X]; + if ((A == 67) || (A == 83)) goto pos37330; + goto pos36700; + + // -------------- + + +pos37367: + Code37066(mem58); + A = A & 4; + if(A != 0) goto pos37330; + A = inputtemp[X]; + if (A != 72) goto pos36700; + if ((A != 84) && (A != 67) && (A != 83)) goto pos36700; + mem58 = X; + goto pos37184; + + // -------------- + +pos37404: + Code37066(mem58); + A = A & 32; + if(A == 0) goto pos36700; +pos37414: + mem58 = X; + goto pos37184; + + // -------------- + +pos37419: + X = mem58; + X++; + A = inputtemp[X]; + if ((A == 69) || (A == 73) || (A == 89)) goto pos37414; + goto pos36700; + +// ---------------------- + +pos37440: + + Code37066(mem58); + A = A & 32; + if(A == 0) goto pos37184; + mem58 = X; + goto pos37440; +pos37455: + Y = mem64; + mem61 = mem60; + + if (debug) + PrintRule(mem62); + +pos37461: + //37461: LDA (62),y + A = GetRuleByte(mem62, Y); + mem57 = A; + A = A & 127; + if (A != '=') + { + mem56++; + X = mem56; + input[X] = A; + } + + //37478: BIT 57 + //37480: BPL 37485 //not negative flag + if ((mem57 & 128) == 0) goto pos37485; //??? + goto pos36554; +pos37485: + Y++; + goto pos37461; +} + From e1e4a0a5d9cfad6b89468077b33f00e290cd318b Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Fri, 2 Jan 2015 05:36:06 +0000 Subject: [PATCH 014/109] More refactoring --- src/reciter.c | 188 ++++++++++++++++++++------------------------------ 1 file changed, 75 insertions(+), 113 deletions(-) diff --git a/src/reciter.c b/src/reciter.c index df9bbe68..83b01fb1 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -230,126 +230,88 @@ int TextToPhonemes(char *input) // Code36484 mem60 = X; } -// the string in the bracket is correct - -//pos36787: - A = mem61; - mem59 = mem61; - -pos36791: - while(1) - { - mem66--; - Y = mem66; - A = GetRuleByte(mem62, Y); - mem57 = A; - //36800: BPL 36805 - if ((A & 128) != 0) goto pos37180; - X = A & 127; - A = tab36376[X] & 128; - if (A == 0) break; - X = mem59-1; - A = inputtemp[X]; - if (A != mem57) goto pos36700; - mem59 = X; - } - -//pos36833: - A = mem57; - if (A == ' ') goto pos36895; - if (A == '#') goto pos36910; - if (A == '.') goto pos36920; - if (A == '&') goto pos36935; - if (A == '@') goto pos36967; - if (A == '^') goto pos37004; - if (A == '+') goto pos37019; - if (A == ':') goto pos37040; - // Code42041(); //Error - //36894: BRK - return 0; - // -------------- - -pos36895: - A = Code37055(mem59) & 128; - if(A != 0) goto pos36700; -pos36905: - mem59 = X; - goto pos36791; - - // -------------- - -pos36910: - A = Code37055(mem59) & 64; - if(A != 0) goto pos36905; - goto pos36700; - // -------------- + // the string in the bracket is correct -pos36920: - A = Code37055(mem59) & 8; - if(A == 0) goto pos36700; - --mem59; - goto pos36791; + A = mem61; + mem59 = mem61; -pos36930: - mem59 = X; - goto pos36791; + while(1) { + while(1) { + mem66--; + Y = mem66; + A = GetRuleByte(mem62, Y); + mem57 = A; + if ((A & 128) != 0) goto pos37180; + X = A & 127; + A = tab36376[X] & 128; + if (A == 0) break; + X = mem59-1; + A = inputtemp[X]; + if (A != mem57) goto pos36700; + mem59 = X; + } - // -------------- - -pos36935: - A = Code37055(mem59) & 16; - if(A != 0) goto pos36930; - A = inputtemp[X]; - if (A != 72) goto pos36700; - X--; - A = inputtemp[X]; - if ((A == 67) || (A == 83)) goto pos36930; - goto pos36700; - - // -------------- - -pos36967: - A = Code37055(mem59) & 4; - if(A != 0) goto pos36930; - A = inputtemp[X]; - if (A != 72) goto pos36700; - if ((A != 84) && (A != 67) && (A != 83)) goto pos36700; - mem59 = X; - goto pos36791; - - // -------------- - -pos37004: - A = Code37055(mem59) & 32; - if(A == 0) goto pos36700; - mem59 = X; - goto pos36791; - -pos37014: - mem59 = X; - goto pos36791; - - // -------------- - -pos37019: - X = mem59; - X--; - A = inputtemp[X]; - if ((A == 'E') || (A == 'I') || (A == 'Y')) { + unsigned char ch = mem57; + switch(ch) { + case ' ': + A = Code37055(mem59) & 128; + if(A != 0) goto pos36700; + break; + + case '#': + A = Code37055(mem59) & 64; + if(A == 0) goto pos36700; + break; + + case '.': + A = Code37055(mem59) & 8; + if(A == 0) goto pos36700; + break; + + case '&': + A = Code37055(mem59) & 16; + if(A == 0) { + A = inputtemp[X]; + if (A != 72) goto pos36700; + X--; + A = inputtemp[X]; + if ((A != 67) && (A != 83)) goto pos36700; + } + break; + + case '@': + A = Code37055(mem59) & 4; + if(A == 0) { + A = inputtemp[X]; + if (A != 72) goto pos36700; + if ((A != 84) && (A != 67) && (A != 83)) goto pos36700; + } + break; + + case '^': + A = Code37055(mem59) & 32; + if(A == 0) goto pos36700; + break; + + case '+': + X = mem59; + X--; + A = inputtemp[X]; + if ((A != 'E') && (A != 'I') && (A && 'Y')) goto pos36700; + break; + + case ':': + while ((A = (Code37055(mem59) & 32))) --mem59; + continue; + + default: + return 0; + } + mem59 = X; - goto pos36791; } - goto pos36700; - // -------------- - -pos37040: - while (1) { - A = Code37055(mem59) & 32; - if(A == 0) goto pos36791; - mem59 = X; - } //--------------------------------------- From 46c954e81b9c5c21b781bdc7f632b319eb522d21 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Fri, 20 Jan 2017 19:31:58 +0000 Subject: [PATCH 015/109] Fix typo --- src/RenderTabs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/RenderTabs.h b/src/RenderTabs.h index 4af26819..6f86e515 100755 --- a/src/RenderTabs.h +++ b/src/RenderTabs.h @@ -248,7 +248,7 @@ unsigned char rectangle[] = 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , 0x70 , -d 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 , From 0ddfa1dfa6a4a9633144ea19a9702a14be87e04b Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 03:51:21 +0000 Subject: [PATCH 016/109] Refactoring to increase locality/cohesion --- src/createtransitions.c | 51 +++++++++++++++++++++++++++++++++++++++++ src/render.c | 47 ------------------------------------- 2 files changed, 51 insertions(+), 47 deletions(-) diff --git a/src/createtransitions.c b/src/createtransitions.c index 0db6ed1b..18249795 100644 --- a/src/createtransitions.c +++ b/src/createtransitions.c @@ -1,4 +1,5 @@ +#include #include #include "render.h" @@ -49,6 +50,56 @@ extern unsigned char pitches[]; extern unsigned char Read(unsigned char p, unsigned char Y); extern void Write(unsigned char p, unsigned char Y, unsigned char value); +extern unsigned char frequency1[256]; +extern unsigned char frequency2[256]; +extern unsigned char frequency3[256]; + +extern unsigned char amplitude1[256]; +extern unsigned char amplitude2[256]; +extern unsigned char amplitude3[256]; + +//written by me because of different table positions. +// mem[47] = ... +// 168=pitches +// 169=frequency1 +// 170=frequency2 +// 171=frequency3 +// 172=amplitude1 +// 173=amplitude2 +// 174=amplitude3 +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]; + } + printf("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; + } + printf("Error writing to tables\n"); +} + + unsigned char CreateTransitions() { unsigned char phase1; diff --git a/src/render.c b/src/render.c index f269f5e3..83f33e6b 100755 --- a/src/render.c +++ b/src/render.c @@ -76,53 +76,6 @@ void Output(int index, unsigned char A) } - - - - - -//written by me because of different table positions. -// mem[47] = ... -// 168=pitches -// 169=frequency1 -// 170=frequency2 -// 171=frequency3 -// 172=amplitude1 -// 173=amplitude2 -// 174=amplitude3 -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]; - } - printf("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; - } - printf("Error writing to tables\n"); -} - - static unsigned char RenderVoicedSample(unsigned short hi, unsigned char off, unsigned char phase1) { do { From ee7806dc3a214f9bdbed6ea773efd48d030e0291 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 03:53:42 +0000 Subject: [PATCH 017/109] Minor refactoring --- src/render.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/render.c b/src/render.c index 83f33e6b..5468c2f4 100755 --- a/src/render.c +++ b/src/render.c @@ -379,17 +379,17 @@ void SetMouthThroat(unsigned char mouth, unsigned char throat) } // recalculate formant frequencies 48..53 - pos = 48; - while(pos < 54) { + pos = 0; + while(pos < 6) { // recalculate F1 (mouth formant) - initialFrequency = mouthFormants48_53[pos-48]; + initialFrequency = mouthFormants48_53[pos]; newFrequency = trans(mouth, initialFrequency); - freq1data[pos] = newFrequency; + freq1data[pos+48] = newFrequency; // recalculate F2 (throat formant) - initialFrequency = throatFormants48_53[pos-48]; + initialFrequency = throatFormants48_53[pos]; newFrequency = trans(throat, initialFrequency); - freq2data[pos] = newFrequency; + freq2data[pos+48] = newFrequency; pos++; } } From 4379d74aef4152c6a089730e70f054fc2d0f8edc Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 03:53:56 +0000 Subject: [PATCH 018/109] Minor cleanup --- src/reciter.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/reciter.c b/src/reciter.c index 83b01fb1..c64ac324 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -453,19 +453,17 @@ int TextToPhonemes(char *input) // Code36484 A = inputtemp[X]; if (A != 72) goto pos36700; if ((A != 84) && (A != 67) && (A != 83)) goto pos36700; - mem58 = X; - goto pos37184; - - // -------------- - -pos37404: - Code37066(mem58); - A = A & 32; - if(A == 0) goto pos36700; -pos37414: - mem58 = X; - goto pos37184; - + mem58 = X; + goto pos37184; + +pos37404: + Code37066(mem58); + A = A & 32; + if(A == 0) goto pos36700; +pos37414: + mem58 = X; + goto pos37184; + // -------------- pos37419: From d5973d09a94cb7431f4c335ff2b813d445c779da Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 03:54:39 +0000 Subject: [PATCH 019/109] Refactoring for clarity, including splitting out separate function for the actual interpolation --- src/createtransitions.c | 127 +++++++++++++++++----------------------- 1 file changed, 55 insertions(+), 72 deletions(-) diff --git a/src/createtransitions.c b/src/createtransitions.c index 18249795..f3da1596 100644 --- a/src/createtransitions.c +++ b/src/createtransitions.c @@ -1,4 +1,3 @@ - #include #include #include "render.h" @@ -100,57 +99,72 @@ void Write(unsigned char p, unsigned char Y, unsigned char value) } +// linearly interpolate values +void interpolate(unsigned char width, unsigned char table, unsigned char frame, unsigned char mem53) +{ + unsigned char sign = ((char)(mem53) < 0); + unsigned char remainder = abs((char)mem53) % width; + unsigned char div = (unsigned char)((char)(mem53) / width); + + unsigned char error = 0; + unsigned char pos = width; + unsigned char val = Read(table, frame) + div; + + while(--pos) { + error += remainder; + if (error >= width) { // accumulated a whole integer error, so adjust output + error -= width; + if (sign) val--; + else if (val) val++; // if input is 0, we always leave it alone + } + Write(table, ++frame, val); // Write updated value back to next frame. + val += div; + } +} + + unsigned char CreateTransitions() { unsigned char phase1; unsigned char phase2; - unsigned char mem53; - unsigned char mem44 = 0; unsigned char mem49 = 0; unsigned char pos = 0; while(1) { - // get the current and following phoneme - unsigned char phoneme = phonemeIndexOutput[pos]; - unsigned char A = phonemeIndexOutput[pos+1]; - pos++; + unsigned char phoneme = phonemeIndexOutput[pos]; + unsigned char next_phoneme = phonemeIndexOutput[pos+1]; - // exit loop at end token - if (A == 255) break; + if (next_phoneme == 255) break; // 255 == end_token // get the ranking of each phoneme - pos = A; - unsigned char mem56 = blendRank[A]; - - unsigned char rank = blendRank[phoneme]; + unsigned char next_rank = blendRank[next_phoneme]; + unsigned char rank = blendRank[phoneme]; // compare the rank - lower rank value is stronger - if (rank == mem56) { + if (rank == next_rank) { // same rank, so use out blend lengths from each phoneme phase1 = outBlendLength[phoneme]; - phase2 = outBlendLength[pos]; - } else if (rank < mem56) { - // first phoneme is stronger, so us it's blend lengths - phase1 = inBlendLength[pos]; - phase2 = outBlendLength[pos]; + phase2 = outBlendLength[next_phoneme]; + } else if (rank < next_rank) { + // next phoneme is stronger, so us its blend lengths + phase1 = inBlendLength[next_phoneme]; + phase2 = outBlendLength[next_phoneme]; } else { - // second phoneme is stronger, so use it's blend lengths + // current phoneme is stronger, so use its blend lengths // note the out/in are swapped phase1 = outBlendLength[phoneme]; phase2 = inBlendLength[phoneme]; } - mem49 += phonemeLengthOutput[mem44]; + mem49 += phonemeLengthOutput[pos]; unsigned char speedcounter = mem49 + phase2; - unsigned table = 168; - unsigned char phase3 = mem49 - phase1; - unsigned char transition = phase1 + phase2; // total transition? + unsigned char phase3 = mem49 - phase1; + unsigned char transition = phase1 + phase2; // total transition? - pos = transition; - pos -= 2; - if ((pos & 128) == 0) { - do { - // mem47 is used to index the tables: + if (((transition - 2) & 128) == 0) { + unsigned table = 168; + while (table < 175) { + // tables: // 168 pitches[] // 169 frequency1 // 170 frequency2 @@ -159,64 +173,33 @@ unsigned char CreateTransitions() // 173 amplitude2 // 174 amplitude3 - unsigned char mem40 = transition; + // number of frames to interpolate over + unsigned char width = transition; + unsigned char mem53; if (table == 168) { // pitch // unlike the other values, the pitches[] interpolates from // the middle of the current phoneme to the middle of the // next phoneme - // half the width of the current phoneme - unsigned char mem36 = phonemeLengthOutput[mem44] >> 1; - // half the width of the next phoneme - unsigned char mem37 = phonemeLengthOutput[mem44+1] >> 1; + // half the width of the current and next phoneme + unsigned char cur_width = phonemeLengthOutput[pos] / 2; + unsigned char next_width = phonemeLengthOutput[pos+1] / 2; // sum the values - mem40 = mem36 + mem37; // length of both halves - mem53 = pitches[mem37 + mem49] - pitches[mem49-mem36]; + width = cur_width + next_width; + mem53 = pitches[next_width + mem49] - pitches[mem49- cur_width]; } else { - // Interpolate - mem53 = Read(table, speedcounter) - Read(table, phase3); } - - //Code47503(mem40); - // ML : Code47503 is division with remainder, and mem50 gets the sign - - // calculate change per frame - unsigned char sign = ((char)(mem53) < 0); - unsigned char mem51 = abs((char)mem53) % mem40; - mem53 = (unsigned char)((char)(mem53) / mem40); - - // interpolation range - pos = mem40; // number of frames to interpolate over - unsigned char frame = phase3; // starting frame - - // linearly interpolate values - unsigned char mem56 = 0; - while(1) { - unsigned char mem48 = Read(table, frame) + mem53; //carry alway cleared - frame++; - pos--; - if(pos == 0) break; - - mem56 += mem51; - if (mem56 >= mem40) { //??? - mem56 -= mem40; //carry? is set - if (!sign) { - if(mem48 != 0) mem48++; - } else mem48--; - } - Write(table, frame, mem48); - } //while No. 3 - - + interpolate(width, table, phase3, mem53); table++; - } while (table != 175); //while No. 2 + } } - pos = ++mem44; + ++pos; } // add the length of this phoneme - return mem49 + phonemeLengthOutput[mem44]; + return mem49 + phonemeLengthOutput[pos]; } From b55fac1340d6f3b747e6829236bad8e4c9df3391 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 04:46:24 +0000 Subject: [PATCH 020/109] Refactoring --- src/reciter.c | 64 ++++++++++++++++++++++----------------------------- 1 file changed, 28 insertions(+), 36 deletions(-) diff --git a/src/reciter.c b/src/reciter.c index c64ac324..70499b64 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -475,40 +475,32 @@ int TextToPhonemes(char *input) // Code36484 // ---------------------- -pos37440: - - Code37066(mem58); - A = A & 32; - if(A == 0) goto pos37184; - mem58 = X; - goto pos37440; +pos37440: + while (1) { + Code37066(mem58); + A = A & 32; + if(A == 0) goto pos37184; + mem58 = X; + } + pos37455: - Y = mem64; - mem61 = mem60; - - if (debug) - PrintRule(mem62); - -pos37461: - //37461: LDA (62),y - A = GetRuleByte(mem62, Y); - mem57 = A; - A = A & 127; - if (A != '=') - { - mem56++; - X = mem56; - input[X] = A; - } - - //37478: BIT 57 - //37480: BPL 37485 //not negative flag - if ((mem57 & 128) == 0) goto pos37485; //??? - goto pos36554; -pos37485: - Y++; - goto pos37461; -} - - - + Y = mem64; + mem61 = mem60; + + if (debug) PrintRule(mem62); + + while(1) { + A = GetRuleByte(mem62, Y); + mem57 = A; + A = A & 127; + if (A != '=') + { + mem56++; + X = mem56; + input[X] = A; + } + if ((mem57 & 128) != 0) goto pos36554; + Y++; + } +} + From 07b782389f20319555a2fe04e449e8d3032981e0 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 04:48:53 +0000 Subject: [PATCH 021/109] Refactoring --- src/reciter.c | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/src/reciter.c b/src/reciter.c index 70499b64..53018a14 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -394,7 +394,15 @@ int TextToPhonemes(char *input) // Code36484 if (A == 64) goto pos37367; // '' if (A == 94) goto pos37404; // '' if (A == 43) goto pos37419; // '+' - if (A == 58) goto pos37440; // ':' + if (A == ':') { + while (1) { + Code37066(mem58); + A = A & 32; + if(A == 0) goto pos37184; + mem58 = X; + } + } + if (A == 37) goto pos37077; // '%' //pos37291: // Code42041(); //Error @@ -460,30 +468,19 @@ int TextToPhonemes(char *input) // Code36484 Code37066(mem58); A = A & 32; if(A == 0) goto pos36700; -pos37414: mem58 = X; goto pos37184; - // -------------- - -pos37419: - X = mem58; - X++; - A = inputtemp[X]; - if ((A == 69) || (A == 73) || (A == 89)) goto pos37414; - goto pos36700; - -// ---------------------- - -pos37440: - while (1) { - Code37066(mem58); - A = A & 32; - if(A == 0) goto pos37184; +pos37419: + X = mem58 + 1; + A = inputtemp[X]; + if ((A == 69) || (A == 73) || (A == 89)) { mem58 = X; + goto pos37184; } + goto pos36700; -pos37455: +pos37455: Y = mem64; mem61 = mem60; From 85744d3feb65041f06a571305a138079ccf84c86 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 04:50:07 +0000 Subject: [PATCH 022/109] Refactoring --- src/reciter.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/reciter.c b/src/reciter.c index 53018a14..f9ccbee7 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -467,9 +467,11 @@ int TextToPhonemes(char *input) // Code36484 pos37404: Code37066(mem58); A = A & 32; - if(A == 0) goto pos36700; - mem58 = X; - goto pos37184; + if(A != 0) { + mem58 = X; + goto pos37184; + } + goto pos36700; pos37419: X = mem58 + 1; From 784629fe5c04b30875fd798dcfbaa3e938be3137 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 04:50:45 +0000 Subject: [PATCH 023/109] Refactoring --- src/reciter.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/reciter.c b/src/reciter.c index f9ccbee7..3cdfac0b 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -432,8 +432,10 @@ int TextToPhonemes(char *input) // Code36484 pos37320: Code37066(mem58); A = A & 8; - if(A == 0) goto pos36700; - + if(A == 0) goto pos36700; + mem58 = X; + goto pos37184; + pos37330: mem58 = X; goto pos37184; @@ -443,7 +445,10 @@ int TextToPhonemes(char *input) // Code36484 pos37335: Code37066(mem58); A = A & 16; - if(A != 0) goto pos37330; + if(A != 0) { + mem58 = X; + goto pos37184; + } A = inputtemp[X]; if (A != 72) goto pos36700; X++; From d2cf3171584f274506c8aa2f6d426ea62ff5a4ca Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 04:51:05 +0000 Subject: [PATCH 024/109] Refactoring --- src/reciter.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/reciter.c b/src/reciter.c index 3cdfac0b..df4e6352 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -453,7 +453,10 @@ int TextToPhonemes(char *input) // Code36484 if (A != 72) goto pos36700; X++; A = inputtemp[X]; - if ((A == 67) || (A == 83)) goto pos37330; + if ((A == 67) || (A == 83)) { + mem58 = X; + goto pos37184; + } goto pos36700; // -------------- From 9bc90aa77dceb81c8eee5087517178ff10ec4e43 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 04:55:01 +0000 Subject: [PATCH 025/109] Refactoring --- src/reciter.c | 76 ++++++++++++++++++++++----------------------------- 1 file changed, 33 insertions(+), 43 deletions(-) diff --git a/src/reciter.c b/src/reciter.c index df4e6352..fe3ffb23 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -340,13 +340,13 @@ int TextToPhonemes(char *input) // Code36484 goto pos37108; pos37135: - if (A != 70) goto pos36700; - X++; - A = inputtemp[X]; - if (A != 85) goto pos36700; - X++; - A = inputtemp[X]; - if (A == 76) goto pos37108; + if (A == 'F') { + A = inputtemp[++X]; + if (A == 'U') { + A = inputtemp[++X]; + if (A == 76) goto pos37108; + } + } goto pos36700; pos37157: @@ -404,31 +404,24 @@ int TextToPhonemes(char *input) // Code36484 } if (A == 37) goto pos37077; // '%' - //pos37291: - // Code42041(); //Error - //37294: BRK - return 0; - - // -------------- -pos37295: - Code37066(mem58); - A = A & 128; - if(A != 0) goto pos36700; -pos37305: - mem58 = X; - goto pos37184; - - // -------------- - -pos37310: + return 0; + +pos37295: + Code37066(mem58); + A = A & 128; + if(A != 0) goto pos36700; + mem58 = X; + goto pos37184; + +pos37310: Code37066(mem58); - A = A & 64; - if(A != 0) goto pos37305; - goto pos36700; - - // -------------- - - + A = A & 64; + if(A != 0) { + mem58 = X; + goto pos37184; + } + goto pos36700; + pos37320: Code37066(mem58); A = A & 8; @@ -457,18 +450,15 @@ int TextToPhonemes(char *input) // Code36484 mem58 = X; goto pos37184; } - goto pos36700; - - // -------------- - - -pos37367: - Code37066(mem58); - A = A & 4; - if(A != 0) goto pos37330; - A = inputtemp[X]; - if (A != 72) goto pos36700; - if ((A != 84) && (A != 67) && (A != 83)) goto pos36700; + goto pos36700; + +pos37367: + Code37066(mem58); + A = A & 4; + if(A != 0) goto pos37330; + A = inputtemp[X]; + if (A != 72) goto pos36700; + if ((A != 84) && (A != 67) && (A != 83)) goto pos36700; mem58 = X; goto pos37184; From db47b69ba5b628383092fc18a9335a5d4ad7024a Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 04:59:52 +0000 Subject: [PATCH 026/109] Refactoring --- src/reciter.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/reciter.c b/src/reciter.c index fe3ffb23..4bbb645b 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -429,12 +429,6 @@ int TextToPhonemes(char *input) // Code36484 mem58 = X; goto pos37184; -pos37330: - mem58 = X; - goto pos37184; - - // -------------- - pos37335: Code37066(mem58); A = A & 16; @@ -455,7 +449,10 @@ int TextToPhonemes(char *input) // Code36484 pos37367: Code37066(mem58); A = A & 4; - if(A != 0) goto pos37330; + if(A != 0) { + mem58 = X; + goto pos37184; + } A = inputtemp[X]; if (A != 72) goto pos36700; if ((A != 84) && (A != 67) && (A != 83)) goto pos36700; From 52d6f378e0fe8c6eba07432716378b9602f86849 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 05:02:54 +0000 Subject: [PATCH 027/109] Refactoring --- src/reciter.c | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/src/reciter.c b/src/reciter.c index 4bbb645b..d092812f 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -242,7 +242,11 @@ int TextToPhonemes(char *input) // Code36484 Y = mem66; A = GetRuleByte(mem62, Y); mem57 = A; - if ((A & 128) != 0) goto pos37180; + if ((A & 128) != 0) { + A = mem60; + mem58 = A; + goto pos37184; + } X = A & 127; A = tab36376[X] & 128; if (A == 0) break; @@ -350,23 +354,17 @@ int TextToPhonemes(char *input) // Code36484 goto pos36700; pos37157: - if (A != 73) goto pos36700; - X++; - A = inputtemp[X]; - if (A != 78) goto pos36700; - X++; - A = inputtemp[X]; - if (A == 71) goto pos37108; - //pos37177: + if (A == 73) { + X++; + A = inputtemp[X]; + if (A == 78) { + X++; + A = inputtemp[X]; + if (A == 71) goto pos37108; + } + } goto pos36700; - - // ----------------------------------------- - -pos37180: - - A = mem60; - mem58 = A; - + pos37184: Y = mem65 + 1; @@ -384,7 +382,8 @@ int TextToPhonemes(char *input) // Code36484 A = inputtemp[X]; if (A != mem57) goto pos36700; mem58 = X; - goto pos37184; + goto pos37184; + pos37226: A = mem57; if (A == 32) goto pos37295; // ' ' @@ -415,8 +414,7 @@ int TextToPhonemes(char *input) // Code36484 pos37310: Code37066(mem58); - A = A & 64; - if(A != 0) { + if((A & 64) != 0) { mem58 = X; goto pos37184; } @@ -487,7 +485,7 @@ int TextToPhonemes(char *input) // Code36484 A = GetRuleByte(mem62, Y); mem57 = A; A = A & 127; - if (A != '=') + if (A != '=') { mem56++; X = mem56; From 60cb5266dd7e58d3c3fd09090185033cb265b67b Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 05:03:28 +0000 Subject: [PATCH 028/109] Refactoring --- src/reciter.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/reciter.c b/src/reciter.c index d092812f..3ef2f624 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -353,14 +353,14 @@ int TextToPhonemes(char *input) // Code36484 } goto pos36700; -pos37157: - if (A == 73) { +pos37157: + if (A == 'I') { X++; A = inputtemp[X]; - if (A == 78) { - X++; - A = inputtemp[X]; - if (A == 71) goto pos37108; + if (A == 'N') { + X++; + A = inputtemp[X]; + if (A == 'G') goto pos37108; } } goto pos36700; From e128f32bdc6882280ba8633dc65fd6bfeb69d2f2 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 05:20:17 +0000 Subject: [PATCH 029/109] Refactoring --- src/reciter.c | 67 ++++++++++++++++++++++----------------------------- 1 file changed, 29 insertions(+), 38 deletions(-) diff --git a/src/reciter.c b/src/reciter.c index 3ef2f624..1a182895 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -28,6 +28,16 @@ void Code37066(unsigned char mem58) A = tab36376[Y]; } +unsigned int match(const char * str) { + unsigned char ch; + while ((ch = *str)) { + A = inputtemp[X++]; + if (A != ch) return 0; + ++str; + } + return 1; +} + unsigned char GetRuleByte(unsigned short mem62, unsigned char Y) { unsigned int address = mem62; @@ -321,49 +331,30 @@ int TextToPhonemes(char *input) // Code36484 pos37077: - X = mem58+1; - A = inputtemp[X]; - if (A != 'E') goto pos37157; - X++; - Y = inputtemp[X]; - X--; - A = tab36376[Y] & 128; - if(A == 0) goto pos37108; - X++; - A = inputtemp[X]; - if (A != 'R') goto pos37113; -pos37108: - mem58 = X; - goto pos37184; -pos37113: - if ((A == 83) || (A == 68)) goto pos37108; // 'S' 'D' - if (A != 76) goto pos37135; // 'L' - X++; - A = inputtemp[X]; - if (A != 89) goto pos36700; - goto pos37108; - -pos37135: - if (A == 'F') { - A = inputtemp[++X]; - if (A == 'U') { - A = inputtemp[++X]; - if (A == 76) goto pos37108; - } + X = mem58+1; + A = inputtemp[X]; + + if (A != 'E') { + if (!match("ING")) goto pos36700; + mem58 = X; + goto pos37184; } - goto pos36700; - -pos37157: - if (A == 'I') { + + X++; + Y = inputtemp[X]; + X--; + A = tab36376[Y] & 128; + if(A != 0) { X++; A = inputtemp[X]; - if (A == 'N') { - X++; - A = inputtemp[X]; - if (A == 'G') goto pos37108; + if ((A != 'R') && (A != 'S') && (A != 'D')) { + if (A == 'L') { + if (inputtemp[++X] != 'Y') goto pos36700; + } else { + if (!match("FUL")) goto pos36700; + } } } - goto pos36700; pos37184: Y = mem65 + 1; From 9a65d4aab51bcf92ca4f017602e3c1832635a507 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 05:21:41 +0000 Subject: [PATCH 030/109] Refactoring --- src/reciter.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/reciter.c b/src/reciter.c index 1a182895..3a0afd1d 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -340,9 +340,7 @@ int TextToPhonemes(char *input) // Code36484 goto pos37184; } - X++; - Y = inputtemp[X]; - X--; + Y = inputtemp[X+1]; A = tab36376[Y] & 128; if(A != 0) { X++; From 3989925d461522574aa8e58055de9c75daf13335 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 05:22:10 +0000 Subject: [PATCH 031/109] Refactoring --- src/reciter.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/reciter.c b/src/reciter.c index 3a0afd1d..21cf8cdc 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -341,10 +341,8 @@ int TextToPhonemes(char *input) // Code36484 } Y = inputtemp[X+1]; - A = tab36376[Y] & 128; - if(A != 0) { - X++; - A = inputtemp[X]; + if((tab36376[Y] & 128) != 0) { + A = inputtemp[++X]; if ((A != 'R') && (A != 'S') && (A != 'D')) { if (A == 'L') { if (inputtemp[++X] != 'Y') goto pos36700; From 312845a216b59dd12cbb17c9f13233360ca66d7f Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 05:31:30 +0000 Subject: [PATCH 032/109] Refactoring --- src/reciter.c | 129 +++++++++++++++++++++++--------------------------- 1 file changed, 58 insertions(+), 71 deletions(-) diff --git a/src/reciter.c b/src/reciter.c index 21cf8cdc..b0dda127 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -326,11 +326,7 @@ int TextToPhonemes(char *input) // Code36484 mem59 = X; } - -//--------------------------------------- - - -pos37077: +pos37077: X = mem58+1; A = inputtemp[X]; @@ -352,34 +348,64 @@ int TextToPhonemes(char *input) // Code36484 } } -pos37184: - Y = mem65 + 1; - - //37187: CPY 64 - // if(? != 0) goto pos37194; - if(Y == mem64) goto pos37455; - mem65 = Y; - //37196: LDA (62),y - A = GetRuleByte(mem62, Y); - mem57 = A; - X = A; - A = tab36376[X] & 128; - if(A == 0) goto pos37226; - X = mem58+1; - A = inputtemp[X]; - if (A != mem57) goto pos36700; - mem58 = X; - goto pos37184; +pos37184: + while(1) { + Y = mem65 + 1; + if(Y == mem64) goto pos37455; + mem65 = Y; + mem57 = GetRuleByte(mem62, Y); + if((tab36376[mem57] & 128) == 0) break; + A = inputtemp[mem58+1]; + if (A != mem57) goto pos36700; + ++mem58; + } + + A = mem57; + if (A == ' ') { + Code37066(mem58); + A = A & 128; + if(A != 0) goto pos36700; + mem58 = X; + goto pos37184; + } + + if (A == '#') { + Code37066(mem58); + if((A & 64) != 0) { + mem58 = X; + goto pos37184; + } + goto pos36700; + } + if (A == '.') { + Code37066(mem58); + A = A & 8; + if(A == 0) goto pos36700; + mem58 = X; + goto pos37184; + } + + if (A == '&') { + Code37066(mem58); + A = A & 16; + if(A != 0) { + mem58 = X; + goto pos37184; + } + A = inputtemp[X]; + if (A != 72) goto pos36700; + X++; + A = inputtemp[X]; + if ((A == 67) || (A == 83)) { + mem58 = X; + goto pos37184; + } + goto pos36700; + } + if (A == '@') goto pos37367; + if (A == '^') goto pos37404; + if (A == '+') goto pos37419; -pos37226: - A = mem57; - if (A == 32) goto pos37295; // ' ' - if (A == 35) goto pos37310; // '#' - if (A == 46) goto pos37320; // '.' - if (A == 38) goto pos37335; // '&' - if (A == 64) goto pos37367; // '' - if (A == 94) goto pos37404; // '' - if (A == 43) goto pos37419; // '+' if (A == ':') { while (1) { Code37066(mem58); @@ -392,45 +418,6 @@ int TextToPhonemes(char *input) // Code36484 if (A == 37) goto pos37077; // '%' return 0; -pos37295: - Code37066(mem58); - A = A & 128; - if(A != 0) goto pos36700; - mem58 = X; - goto pos37184; - -pos37310: - Code37066(mem58); - if((A & 64) != 0) { - mem58 = X; - goto pos37184; - } - goto pos36700; - -pos37320: - Code37066(mem58); - A = A & 8; - if(A == 0) goto pos36700; - mem58 = X; - goto pos37184; - -pos37335: - Code37066(mem58); - A = A & 16; - if(A != 0) { - mem58 = X; - goto pos37184; - } - A = inputtemp[X]; - if (A != 72) goto pos36700; - X++; - A = inputtemp[X]; - if ((A == 67) || (A == 83)) { - mem58 = X; - goto pos37184; - } - goto pos36700; - pos37367: Code37066(mem58); A = A & 4; From f46fe0fe8395956c8196c6c822eb4012f7fa15d7 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 05:32:13 +0000 Subject: [PATCH 033/109] Refactoring --- src/reciter.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/reciter.c b/src/reciter.c index b0dda127..f0c84d45 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -386,8 +386,8 @@ int TextToPhonemes(char *input) // Code36484 } if (A == '&') { - Code37066(mem58); - A = A & 16; + Code37066(mem58); + A = A & 16; if(A != 0) { mem58 = X; goto pos37184; @@ -402,7 +402,20 @@ int TextToPhonemes(char *input) // Code36484 } goto pos36700; } - if (A == '@') goto pos37367; + if (A == '@') { + Code37066(mem58); + A = A & 4; + if(A != 0) { + mem58 = X; + goto pos37184; + } + A = inputtemp[X]; + if (A != 72) goto pos36700; + if ((A != 84) && (A != 67) && (A != 83)) goto pos36700; + mem58 = X; + goto pos37184; + } + if (A == '^') goto pos37404; if (A == '+') goto pos37419; @@ -418,19 +431,6 @@ int TextToPhonemes(char *input) // Code36484 if (A == 37) goto pos37077; // '%' return 0; -pos37367: - Code37066(mem58); - A = A & 4; - if(A != 0) { - mem58 = X; - goto pos37184; - } - A = inputtemp[X]; - if (A != 72) goto pos36700; - if ((A != 84) && (A != 67) && (A != 83)) goto pos36700; - mem58 = X; - goto pos37184; - pos37404: Code37066(mem58); A = A & 32; From ebb975fb4548ff8c7c821789ffff2a3aae200525 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 05:33:05 +0000 Subject: [PATCH 034/109] Refactoring --- src/reciter.c | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/src/reciter.c b/src/reciter.c index f0c84d45..0bb403f7 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -416,8 +416,25 @@ int TextToPhonemes(char *input) // Code36484 goto pos37184; } - if (A == '^') goto pos37404; - if (A == '+') goto pos37419; + if (A == '^') { + Code37066(mem58); + A = A & 32; + if(A != 0) { + mem58 = X; + goto pos37184; + } + goto pos36700; + } + + if (A == '+') { + X = mem58 + 1; + A = inputtemp[X]; + if ((A == 69) || (A == 73) || (A == 89)) { + mem58 = X; + goto pos37184; + } + goto pos36700; + } if (A == ':') { while (1) { @@ -431,24 +448,6 @@ int TextToPhonemes(char *input) // Code36484 if (A == 37) goto pos37077; // '%' return 0; -pos37404: - Code37066(mem58); - A = A & 32; - if(A != 0) { - mem58 = X; - goto pos37184; - } - goto pos36700; - -pos37419: - X = mem58 + 1; - A = inputtemp[X]; - if ((A == 69) || (A == 73) || (A == 89)) { - mem58 = X; - goto pos37184; - } - goto pos36700; - pos37455: Y = mem64; mem61 = mem60; From 6fbd0085222e071da81069afba7e933ed768455a Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 05:34:23 +0000 Subject: [PATCH 035/109] Refactoring --- src/reciter.c | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/src/reciter.c b/src/reciter.c index 0bb403f7..0b5eed72 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -351,7 +351,26 @@ int TextToPhonemes(char *input) // Code36484 pos37184: while(1) { Y = mem65 + 1; - if(Y == mem64) goto pos37455; + if(Y == mem64) { + Y = mem64; + mem61 = mem60; + + if (debug) PrintRule(mem62); + + while(1) { + A = GetRuleByte(mem62, Y); + mem57 = A; + A = A & 127; + if (A != '=') + { + mem56++; + X = mem56; + input[X] = A; + } + if ((mem57 & 128) != 0) goto pos36554; + Y++; + } + } mem65 = Y; mem57 = GetRuleByte(mem62, Y); if((tab36376[mem57] & 128) == 0) break; @@ -447,25 +466,5 @@ int TextToPhonemes(char *input) // Code36484 if (A == 37) goto pos37077; // '%' return 0; - -pos37455: - Y = mem64; - mem61 = mem60; - - if (debug) PrintRule(mem62); - - while(1) { - A = GetRuleByte(mem62, Y); - mem57 = A; - A = A & 127; - if (A != '=') - { - mem56++; - X = mem56; - input[X] = A; - } - if ((mem57 & 128) != 0) goto pos36554; - Y++; - } } From 35ea821d7cdf2d03b764f4f9cec143244679b015 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 05:41:54 +0000 Subject: [PATCH 036/109] Refactoring --- src/reciter.c | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/reciter.c b/src/reciter.c index 0b5eed72..fa83355d 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -326,30 +326,30 @@ int TextToPhonemes(char *input) // Code36484 mem59 = X; } -pos37077: - X = mem58+1; - A = inputtemp[X]; - - if (A != 'E') { - if (!match("ING")) goto pos36700; - mem58 = X; - goto pos37184; - } - - Y = inputtemp[X+1]; - if((tab36376[Y] & 128) != 0) { - A = inputtemp[++X]; - if ((A != 'R') && (A != 'S') && (A != 'D')) { - if (A == 'L') { - if (inputtemp[++X] != 'Y') goto pos36700; + do { + X = mem58+1; + A = inputtemp[X]; + + if (A != 'E') { + if (!match("ING")) goto pos36700; + mem58 = X; + goto pos37184; + } + + Y = inputtemp[X+1]; + if((tab36376[Y] & 128) != 0) { + A = inputtemp[++X]; + if ((A != 'R') && (A != 'S') && (A != 'D')) { + if (A == 'L') { + if (inputtemp[++X] != 'Y') goto pos36700; } else { - if (!match("FUL")) goto pos36700; - } + if (!match("FUL")) goto pos36700; + } + } } - } - + pos37184: - while(1) { + while (1) { Y = mem65 + 1; if(Y == mem64) { Y = mem64; @@ -417,7 +417,7 @@ int TextToPhonemes(char *input) // Code36484 A = inputtemp[X]; if ((A == 67) || (A == 83)) { mem58 = X; - goto pos37184; + goto pos37184; } goto pos36700; } @@ -464,7 +464,7 @@ int TextToPhonemes(char *input) // Code36484 } } - if (A == 37) goto pos37077; // '%' + } while (A == '%'); return 0; } From f2a956093964eea4fe7276974fd09ca7527abc81 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 05:45:10 +0000 Subject: [PATCH 037/109] Refactoring --- src/reciter.c | 184 +++++++++++++++++++++++++------------------------- 1 file changed, 92 insertions(+), 92 deletions(-) diff --git a/src/reciter.c b/src/reciter.c index fa83355d..fd105ea8 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -342,7 +342,7 @@ int TextToPhonemes(char *input) // Code36484 if ((A != 'R') && (A != 'S') && (A != 'D')) { if (A == 'L') { if (inputtemp[++X] != 'Y') goto pos36700; - } else { + } else { if (!match("FUL")) goto pos36700; } } @@ -350,120 +350,120 @@ int TextToPhonemes(char *input) // Code36484 pos37184: while (1) { - Y = mem65 + 1; - if(Y == mem64) { - Y = mem64; - mem61 = mem60; - - if (debug) PrintRule(mem62); - - while(1) { - A = GetRuleByte(mem62, Y); - mem57 = A; - A = A & 127; - if (A != '=') + Y = mem65 + 1; + if(Y == mem64) { + Y = mem64; + mem61 = mem60; + + if (debug) PrintRule(mem62); + + while(1) { + A = GetRuleByte(mem62, Y); + mem57 = A; + A = A & 127; + if (A != '=') { mem56++; X = mem56; input[X] = A; } - if ((mem57 & 128) != 0) goto pos36554; - Y++; + if ((mem57 & 128) != 0) goto pos36554; + Y++; + } } + mem65 = Y; + mem57 = GetRuleByte(mem62, Y); + if((tab36376[mem57] & 128) == 0) break; + A = inputtemp[mem58+1]; + if (A != mem57) goto pos36700; + ++mem58; } - mem65 = Y; - mem57 = GetRuleByte(mem62, Y); - if((tab36376[mem57] & 128) == 0) break; - A = inputtemp[mem58+1]; - if (A != mem57) goto pos36700; - ++mem58; - } - - A = mem57; - if (A == ' ') { - Code37066(mem58); - A = A & 128; - if(A != 0) goto pos36700; - mem58 = X; - goto pos37184; - } - - if (A == '#') { - Code37066(mem58); - if((A & 64) != 0) { - mem58 = X; - goto pos37184; - } - goto pos36700; - } - if (A == '.') { - Code37066(mem58); - A = A & 8; - if(A == 0) goto pos36700; - mem58 = X; - goto pos37184; - } - if (A == '&') { - Code37066(mem58); - A = A & 16; - if(A != 0) { + A = mem57; + if (A == ' ') { + Code37066(mem58); + A = A & 128; + if(A != 0) goto pos36700; mem58 = X; goto pos37184; } - A = inputtemp[X]; - if (A != 72) goto pos36700; - X++; - A = inputtemp[X]; - if ((A == 67) || (A == 83)) { - mem58 = X; - goto pos37184; + + if (A == '#') { + Code37066(mem58); + if((A & 64) != 0) { + mem58 = X; + goto pos37184; + } + goto pos36700; } - goto pos36700; - } - if (A == '@') { - Code37066(mem58); - A = A & 4; - if(A != 0) { + if (A == '.') { + Code37066(mem58); + A = A & 8; + if(A == 0) goto pos36700; mem58 = X; goto pos37184; } - A = inputtemp[X]; - if (A != 72) goto pos36700; - if ((A != 84) && (A != 67) && (A != 83)) goto pos36700; - mem58 = X; - goto pos37184; - } - if (A == '^') { - Code37066(mem58); - A = A & 32; - if(A != 0) { - mem58 = X; - goto pos37184; + if (A == '&') { + Code37066(mem58); + A = A & 16; + if(A != 0) { + mem58 = X; + goto pos37184; + } + A = inputtemp[X]; + if (A != 72) goto pos36700; + X++; + A = inputtemp[X]; + if ((A == 67) || (A == 83)) { + mem58 = X; + goto pos37184; + } + goto pos36700; } - goto pos36700; - } - - if (A == '+') { - X = mem58 + 1; - A = inputtemp[X]; - if ((A == 69) || (A == 73) || (A == 89)) { + if (A == '@') { + Code37066(mem58); + A = A & 4; + if(A != 0) { + mem58 = X; + goto pos37184; + } + A = inputtemp[X]; + if (A != 72) goto pos36700; + if ((A != 84) && (A != 67) && (A != 83)) goto pos36700; mem58 = X; goto pos37184; } - goto pos36700; - } - - if (A == ':') { - while (1) { + + if (A == '^') { Code37066(mem58); A = A & 32; - if(A == 0) goto pos37184; - mem58 = X; + if(A != 0) { + mem58 = X; + goto pos37184; + } + goto pos36700; } - } - + + if (A == '+') { + X = mem58 + 1; + A = inputtemp[X]; + if ((A == 69) || (A == 73) || (A == 89)) { + mem58 = X; + goto pos37184; + } + goto pos36700; + } + + if (A == ':') { + while (1) { + Code37066(mem58); + A = A & 32; + if(A == 0) goto pos37184; + mem58 = X; + } + } + } while (A == '%'); return 0; } From 7e5c17932ba3c899bfe5abe9ad0e10a67a861d60 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 05:53:43 +0000 Subject: [PATCH 038/109] Refactoring --- src/reciter.c | 114 +++++++++++++++++--------------------------------- 1 file changed, 38 insertions(+), 76 deletions(-) diff --git a/src/reciter.c b/src/reciter.c index fd105ea8..c5f80681 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -165,83 +165,45 @@ int TextToPhonemes(char *input) // Code36484 //go on if there is more input ??? mem61 = mem36653; goto pos36550; - -pos36677: - A = mem57 & 128; - if(A == 0) - { - //36683: BRK - return 0; - } - - // go to the right rules for this character. - X = mem64 - 'A'; - mem62 = tab37489[X] | (tab37515[X]<<8); - - // ------------------------------------- - // go to next rule - // ------------------------------------- - -pos36700: - - // find next rule - Y = 0; - do - { - mem62 += 1; - A = GetRuleByte(mem62, Y); - } while ((A & 128) == 0); - Y++; - - //pos36720: - // find '(' - while(1) - { - A = GetRuleByte(mem62, Y); - if (A == '(') break; - Y++; - } - mem66 = Y; - - //pos36732: - // find ')' - do - { - Y++; - A = GetRuleByte(mem62, Y); - } while(A != ')'); - mem65 = Y; - - //pos36741: - // find '=' - do - { - Y++; - A = GetRuleByte(mem62, Y); - A = A & 127; - } while (A != '='); - mem64 = Y; - - X = mem61; - mem60 = X; - - // compare the string within the bracket - Y = mem66; - Y++; - //pos36759: - while(1) - { - mem57 = inputtemp[X]; - A = GetRuleByte(mem62, Y); - if (A != mem57) goto pos36700; - Y++; - if(Y == mem65) break; - X++; - mem60 = X; - } - - // the string in the bracket is correct +pos36677: + A = mem57 & 128; + if(A == 0) return 0; + + // go to the right rules for this character. + X = mem64 - 'A'; + mem62 = tab37489[X] | (tab37515[X]<<8); + +pos36700: + // find next rule + Y = 0; + do { + mem62 += 1; + A = GetRuleByte(mem62, Y); + } while ((A & 128) == 0); + Y++; + + while(GetRuleByte(mem62, Y) != '(') ++Y; + mem66 = Y; + while(GetRuleByte(mem62, ++Y) != ')'); + mem65 = Y; + while((GetRuleByte(mem62, ++Y) & 127) != '='); + mem64 = Y; + + + mem60 = X = mem61; + // compare the string within the bracket + Y = mem66 + 1; + + while(1) { + if (GetRuleByte(mem62, Y) != inputtemp[X]) goto pos36700; + if(++Y == mem65) break; + ++X; + mem60 = X; + } + + + // the string in the bracket is correct A = mem61; mem59 = mem61; From 92248c30f2182ee22c8e0f9c0113169bedfed846 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 06:09:30 +0000 Subject: [PATCH 039/109] Refactoring --- src/reciter.c | 77 ++++++++++++++++++--------------------------------- 1 file changed, 27 insertions(+), 50 deletions(-) diff --git a/src/reciter.c b/src/reciter.c index c5f80681..23895bfe 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -20,12 +20,12 @@ unsigned char Code37055(unsigned char mem59) } /* Retrieve flags for character at mem58 + 1 */ -void Code37066(unsigned char mem58) +unsigned char Code37066(unsigned char mem58, unsigned char mask) { X = mem58 + 1; - A = inputtemp[X]; - Y = A; - A = tab36376[Y]; + Y = inputtemp[X]; + A = tab36376[Y] & mask; + return A; } unsigned int match(const char * str) { @@ -205,8 +205,7 @@ int TextToPhonemes(char *input) // Code36484 // the string in the bracket is correct - A = mem61; - mem59 = mem61; + A = mem59 = mem61; while(1) { while(1) { @@ -312,23 +311,16 @@ int TextToPhonemes(char *input) // Code36484 pos37184: while (1) { - Y = mem65 + 1; + unsigned char Y = mem65 + 1; if(Y == mem64) { - Y = mem64; mem61 = mem60; if (debug) PrintRule(mem62); while(1) { - A = GetRuleByte(mem62, Y); - mem57 = A; + mem57 = A = GetRuleByte(mem62, Y); A = A & 127; - if (A != '=') - { - mem56++; - X = mem56; - input[X] = A; - } + if (A != '=') input[++mem56] = A; if ((mem57 & 128) != 0) goto pos36554; Y++; } @@ -336,57 +328,46 @@ int TextToPhonemes(char *input) // Code36484 mem65 = Y; mem57 = GetRuleByte(mem62, Y); if((tab36376[mem57] & 128) == 0) break; - A = inputtemp[mem58+1]; - if (A != mem57) goto pos36700; + if (inputtemp[mem58+1] != mem57) goto pos36700; ++mem58; } A = mem57; if (A == ' ') { - Code37066(mem58); - A = A & 128; - if(A != 0) goto pos36700; - mem58 = X; - goto pos37184; - } - - if (A == '#') { - Code37066(mem58); - if((A & 64) != 0) { + if (Code37066(mem58, 128) == 0) { mem58 = X; goto pos37184; } goto pos36700; } + + if (A == '#') { + if (Code37066(mem58, 64) == 0) goto pos36700; + mem58 = X; + goto pos37184; + } if (A == '.') { - Code37066(mem58); - A = A & 8; - if(A == 0) goto pos36700; + if(Code37066(mem58, 8) == 0) goto pos36700; mem58 = X; goto pos37184; } if (A == '&') { - Code37066(mem58); - A = A & 16; - if(A != 0) { + if(Code37066(mem58, 16) != 0) { mem58 = X; goto pos37184; } - A = inputtemp[X]; - if (A != 72) goto pos36700; - X++; - A = inputtemp[X]; - if ((A == 67) || (A == 83)) { - mem58 = X; - goto pos37184; + if (inputtemp[X] == 72) { + A = inputtemp[++X]; + if ((A == 67) || (A == 83)) { + mem58 = X; + goto pos37184; + } } goto pos36700; } if (A == '@') { - Code37066(mem58); - A = A & 4; - if(A != 0) { + if(Code37066(mem58, 4) != 0) { mem58 = X; goto pos37184; } @@ -398,9 +379,7 @@ int TextToPhonemes(char *input) // Code36484 } if (A == '^') { - Code37066(mem58); - A = A & 32; - if(A != 0) { + if (Code37066(mem58, 32) != 0) { mem58 = X; goto pos37184; } @@ -419,9 +398,7 @@ int TextToPhonemes(char *input) // Code36484 if (A == ':') { while (1) { - Code37066(mem58); - A = A & 32; - if(A == 0) goto pos37184; + if(Code37066(mem58, 32) == 0) goto pos37184; mem58 = X; } } From 3b3d28ae6a8cb0b1b7752f5ef860388c5f925d07 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 06:19:18 +0000 Subject: [PATCH 040/109] Refactoring --- src/reciter.c | 138 +++++++++++++++++++++----------------------------- 1 file changed, 57 insertions(+), 81 deletions(-) diff --git a/src/reciter.c b/src/reciter.c index 23895bfe..b9b42873 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -311,98 +311,74 @@ int TextToPhonemes(char *input) // Code36484 pos37184: while (1) { - unsigned char Y = mem65 + 1; - if(Y == mem64) { - mem61 = mem60; - - if (debug) PrintRule(mem62); - - while(1) { - mem57 = A = GetRuleByte(mem62, Y); - A = A & 127; - if (A != '=') input[++mem56] = A; - if ((mem57 & 128) != 0) goto pos36554; - Y++; + while (1) { + unsigned char Y = mem65 + 1; + if(Y == mem64) { + mem61 = mem60; + + if (debug) PrintRule(mem62); + + while(1) { + mem57 = A = GetRuleByte(mem62, Y); + A = A & 127; + if (A != '=') input[++mem56] = A; + if ((mem57 & 128) != 0) goto pos36554; + Y++; + } } + mem65 = Y; + mem57 = GetRuleByte(mem62, Y); + if((tab36376[mem57] & 128) == 0) break; + if (inputtemp[mem58+1] != mem57) goto pos36700; + ++mem58; } - mem65 = Y; - mem57 = GetRuleByte(mem62, Y); - if((tab36376[mem57] & 128) == 0) break; - if (inputtemp[mem58+1] != mem57) goto pos36700; - ++mem58; - } - A = mem57; - if (A == ' ') { - if (Code37066(mem58, 128) == 0) { + A = mem57; + if (A == ' ') { + if (Code37066(mem58, 128) != 0) goto pos36700; mem58 = X; - goto pos37184; - } - goto pos36700; - } - - if (A == '#') { - if (Code37066(mem58, 64) == 0) goto pos36700; - mem58 = X; - goto pos37184; - } - if (A == '.') { - if(Code37066(mem58, 8) == 0) goto pos36700; - mem58 = X; - goto pos37184; - } - - if (A == '&') { - if(Code37066(mem58, 16) != 0) { + } else if (A == '#') { + if (Code37066(mem58, 64) == 0) goto pos36700; mem58 = X; - goto pos37184; - } - if (inputtemp[X] == 72) { - A = inputtemp[++X]; - if ((A == 67) || (A == 83)) { - mem58 = X; - goto pos37184; - } - } - goto pos36700; - } - if (A == '@') { - if(Code37066(mem58, 4) != 0) { + } else if (A == '.') { + if(Code37066(mem58, 8) == 0) goto pos36700; mem58 = X; - goto pos37184; - } - A = inputtemp[X]; - if (A != 72) goto pos36700; - if ((A != 84) && (A != 67) && (A != 83)) goto pos36700; - mem58 = X; - goto pos37184; - } - - if (A == '^') { - if (Code37066(mem58, 32) != 0) { + } else if (A == '&') { + if(Code37066(mem58, 16) == 0) { + if (inputtemp[X] == 72) { + A = inputtemp[++X]; + if ((A == 67) || (A == 83)) { + mem58 = X; + continue; + } + } + goto pos36700; + } mem58 = X; - goto pos37184; - } - goto pos36700; - } - - if (A == '+') { - X = mem58 + 1; - A = inputtemp[X]; - if ((A == 69) || (A == 73) || (A == 89)) { + } else if (A == '@') { + if(Code37066(mem58, 4) == 0) { + A = inputtemp[X]; + if (A != 72) goto pos36700; + if ((A != 84) && (A != 67) && (A != 83)) goto pos36700; + mem58 = X; + } + } else if (A == '^') { + if (Code37066(mem58, 32) == 0) goto pos36700; mem58 = X; - goto pos37184; - } - goto pos36700; - } - - if (A == ':') { - while (1) { - if(Code37066(mem58, 32) == 0) goto pos37184; + } else if (A == '+') { + X = mem58 + 1; + A = inputtemp[X]; + if ((A != 69) && (A != 73) && (A != 89)) goto pos36700; mem58 = X; + } else if (A == ':') { + while (1) { + if(Code37066(mem58, 32) == 0) break; + mem58 = X; + } + } else { + break; } } - } while (A == '%'); return 0; } From 5b94cf9bfa9b8e1e07d6f886b5c65f7a7b10118f Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 06:24:33 +0000 Subject: [PATCH 041/109] Refactoring --- src/reciter.c | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/src/reciter.c b/src/reciter.c index b9b42873..85335d20 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -23,9 +23,7 @@ unsigned char Code37055(unsigned char mem59) unsigned char Code37066(unsigned char mem58, unsigned char mask) { X = mem58 + 1; - Y = inputtemp[X]; - A = tab36376[Y] & mask; - return A; + return tab36376[inputtemp[X]] & mask; } unsigned int match(const char * str) { @@ -336,25 +334,19 @@ int TextToPhonemes(char *input) // Code36484 A = mem57; if (A == ' ') { if (Code37066(mem58, 128) != 0) goto pos36700; - mem58 = X; } else if (A == '#') { if (Code37066(mem58, 64) == 0) goto pos36700; - mem58 = X; } else if (A == '.') { if(Code37066(mem58, 8) == 0) goto pos36700; - mem58 = X; } else if (A == '&') { if(Code37066(mem58, 16) == 0) { - if (inputtemp[X] == 72) { - A = inputtemp[++X]; - if ((A == 67) || (A == 83)) { - mem58 = X; - continue; - } + if (inputtemp[X] != 72) goto pos36700; + A = inputtemp[++X]; + if ((A == 67) || (A == 83)) { + mem58 = X; + continue; } - goto pos36700; } - mem58 = X; } else if (A == '@') { if(Code37066(mem58, 4) == 0) { A = inputtemp[X]; @@ -362,22 +354,23 @@ int TextToPhonemes(char *input) // Code36484 if ((A != 84) && (A != 67) && (A != 83)) goto pos36700; mem58 = X; } + continue; } else if (A == '^') { if (Code37066(mem58, 32) == 0) goto pos36700; - mem58 = X; } else if (A == '+') { X = mem58 + 1; A = inputtemp[X]; if ((A != 69) && (A != 73) && (A != 89)) goto pos36700; - mem58 = X; } else if (A == ':') { while (1) { if(Code37066(mem58, 32) == 0) break; mem58 = X; } + continue; } else { break; } + mem58 = X; } } while (A == '%'); return 0; From 0c981040c87320e5c868ac5d61d1842f3c868971 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 06:35:24 +0000 Subject: [PATCH 042/109] Refactoring --- src/reciter.c | 45 +++++++++++++++++---------------------------- 1 file changed, 17 insertions(+), 28 deletions(-) diff --git a/src/reciter.c b/src/reciter.c index 85335d20..872c169c 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -174,13 +174,8 @@ int TextToPhonemes(char *input) // Code36484 pos36700: // find next rule - Y = 0; - do { - mem62 += 1; - A = GetRuleByte(mem62, Y); - } while ((A & 128) == 0); - Y++; - + while ((GetRuleByte(++mem62, 0) & 128) == 0); + Y = 1; while(GetRuleByte(mem62, Y) != '(') ++Y; mem66 = Y; while(GetRuleByte(mem62, ++Y) != ')'); @@ -196,8 +191,7 @@ int TextToPhonemes(char *input) // Code36484 while(1) { if (GetRuleByte(mem62, Y) != inputtemp[X]) goto pos36700; if(++Y == mem65) break; - ++X; - mem60 = X; + mem60 = ++X; } @@ -208,12 +202,9 @@ int TextToPhonemes(char *input) // Code36484 while(1) { while(1) { mem66--; - Y = mem66; - A = GetRuleByte(mem62, Y); - mem57 = A; + mem57 = A = GetRuleByte(mem62, mem66); if ((A & 128) != 0) { - A = mem60; - mem58 = A; + mem58 = mem60; goto pos37184; } X = A & 127; @@ -289,22 +280,20 @@ int TextToPhonemes(char *input) // Code36484 X = mem58+1; A = inputtemp[X]; - if (A != 'E') { + if (A == 'E') { + if((tab36376[inputtemp[X+1]] & 128) != 0) { + A = inputtemp[++X]; + if ((A != 'R') && (A != 'S') && (A != 'D')) { + if (A == 'L') { + if (inputtemp[++X] != 'Y') goto pos36700; + } else { + if (!match("FUL")) goto pos36700; + } + } + } + } else { if (!match("ING")) goto pos36700; mem58 = X; - goto pos37184; - } - - Y = inputtemp[X+1]; - if((tab36376[Y] & 128) != 0) { - A = inputtemp[++X]; - if ((A != 'R') && (A != 'S') && (A != 'D')) { - if (A == 'L') { - if (inputtemp[++X] != 'Y') goto pos36700; - } else { - if (!match("FUL")) goto pos36700; - } - } } pos37184: From 21a7ce35af3eaae216fce9f2bba8124588538ff2 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 06:36:00 +0000 Subject: [PATCH 043/109] Refactoring --- src/reciter.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/reciter.c b/src/reciter.c index 872c169c..fd353c22 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -278,9 +278,8 @@ int TextToPhonemes(char *input) // Code36484 do { X = mem58+1; - A = inputtemp[X]; - - if (A == 'E') { + + if (inputtemp[X] == 'E') { if((tab36376[inputtemp[X+1]] & 128) != 0) { A = inputtemp[++X]; if ((A != 'R') && (A != 'S') && (A != 'D')) { From 8a942dbba73888850383ac8efbf05c1c1bf1adc2 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 06:39:14 +0000 Subject: [PATCH 044/109] Refactoring --- src/reciter.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/reciter.c b/src/reciter.c index fd353c22..7562982f 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -219,27 +219,21 @@ int TextToPhonemes(char *input) // Code36484 unsigned char ch = mem57; switch(ch) { case ' ': - A = Code37055(mem59) & 128; - if(A != 0) goto pos36700; + if((Code37055(mem59) & 128)) goto pos36700; break; case '#': - A = Code37055(mem59) & 64; - if(A == 0) goto pos36700; + if(!(Code37055(mem59) & 64)) goto pos36700; break; case '.': - A = Code37055(mem59) & 8; - if(A == 0) goto pos36700; + if(!(Code37055(mem59) & 8)) goto pos36700; break; case '&': - A = Code37055(mem59) & 16; - if(A == 0) { - A = inputtemp[X]; - if (A != 72) goto pos36700; - X--; - A = inputtemp[X]; + if (!(Code37055(mem59) & 16)) { + if (inputtemp[X] != 72) goto pos36700; + A = inputtemp[--X]; if ((A != 67) && (A != 83)) goto pos36700; } break; From 58f0c15e6a1a5b722bcdf9d935a9080d7c2efd94 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 06:39:47 +0000 Subject: [PATCH 045/109] Refactoring --- src/reciter.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/reciter.c b/src/reciter.c index 7562982f..311b39be 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -239,8 +239,7 @@ int TextToPhonemes(char *input) // Code36484 break; case '@': - A = Code37055(mem59) & 4; - if(A == 0) { + if(!(Code37055(mem59) & 4)) { A = inputtemp[X]; if (A != 72) goto pos36700; if ((A != 84) && (A != 67) && (A != 83)) goto pos36700; From 5b02f185a84509d0f17311454b6147216f370118 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 06:51:19 +0000 Subject: [PATCH 046/109] Refactoring --- src/reciter.c | 166 +++++++++++++++++++------------------------------- 1 file changed, 62 insertions(+), 104 deletions(-) diff --git a/src/reciter.c b/src/reciter.c index 311b39be..7ff294c0 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -64,113 +64,71 @@ int TextToPhonemes(char *input) // Code36484 unsigned char mem64; // position of '=' or current character unsigned char mem65; // position of ')' unsigned char mem66; // position of '(' - unsigned char mem36653; - - inputtemp[0] = 32; - - // secure copy of input - // because input will be overwritten by phonemes - X = 1; - Y = 0; - do - { - //pos36499: - A = input[Y] & 127; - if ( A >= 112) A = A & 95; - else if ( A >= 96) A = A & 79; - - inputtemp[X] = A; - X++; - Y++; - } while (Y != 255); - - - X = 255; - inputtemp[X] = 27; - mem61 = 255; - - -pos36550: - A = 255; - mem56 = 255; - - -pos36554: - while(1) - { - mem61++; - X = mem61; - A = inputtemp[X]; - mem64 = A; - if (A == '[') - { - mem56++; - X = mem56; - A = 155; - input[X] = 155; - //goto pos36542; - // Code39771(); //Code39777(); - return 1; - } - - //pos36579: - if (A != '.') break; - X++; - Y = inputtemp[X]; - A = tab36376[Y] & 1; - if(A != 0) break; - mem56++; - X = mem56; - A = '.'; - input[X] = '.'; - } //while - - - //pos36607: - A = mem64; - Y = A; - A = tab36376[A]; - mem57 = A; - if((A&2) != 0) - { - mem62 = 37541; - goto pos36700; - } - - //pos36630: - A = mem57; - if(A != 0) goto pos36677; - A = 32; - inputtemp[X] = ' '; - mem56++; - X = mem56; - if (X > 120) goto pos36654; - input[X] = A; - goto pos36554; - - // ----- - - //36653 is unknown. Contains position - -pos36654: - input[X] = 155; - A = mem61; - mem36653 = A; - // mem29 = A; // not used - // Code36538(); das ist eigentlich - return 1; - //Code39771(); - //go on if there is more input ??? - mem61 = mem36653; - goto pos36550; -pos36677: - A = mem57 & 128; - if(A == 0) return 0; + inputtemp[0] = 32; + + // secure copy of input + // because input will be overwritten by phonemes + X = 1; + Y = 0; + do { + A = input[Y] & 127; + if ( A >= 112) A = A & 95; + else if ( A >= 96) A = A & 79; + inputtemp[X] = A; + X++; + Y++; + } while (Y != 255); + inputtemp[255] = 27; + mem61 = 255; + A = 255; + mem56 = 255; + +pos36554: + while (1) { + while(1) { + X = ++mem61; + A = inputtemp[X]; + mem64 = A; + if (A == '[') { + X = ++mem56; + input[X] = 155; + return 1; + } + + if (A != '.') break; + X++; + Y = inputtemp[X]; + A = tab36376[Y] & 1; + if(A != 0) break; + mem56++; + X = mem56; + A = '.'; + input[X] = '.'; + } + Y = mem64; + mem57 = tab36376[Y]; + if((mem57&2) != 0) { + mem62 = 37541; + goto pos36700; + } + + if(mem57 != 0) break; + inputtemp[X] = ' '; + X = ++mem56; + if (X > 120) { + input[X] = 155; + return 1; + } + input[X] = 32; + } + + if(!(mem57 & 128)) return 0; + // go to the right rules for this character. - X = mem64 - 'A'; - mem62 = tab37489[X] | (tab37515[X]<<8); + X = mem64 - 'A'; + mem62 = tab37489[X] | (tab37515[X]<<8); pos36700: // find next rule From 785efbf3ad110bac2049971b8aabc1233ce03000 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 06:51:55 +0000 Subject: [PATCH 047/109] Refactoring --- src/reciter.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/reciter.c b/src/reciter.c index 7ff294c0..9f185260 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -49,21 +49,19 @@ unsigned char GetRuleByte(unsigned short mem62, unsigned char Y) return rules[address+Y]; } -int TextToPhonemes(char *input) // Code36484 -{ - //unsigned char *tab39445 = &mem[39445]; //input and output - //unsigned char mem29; +int TextToPhonemes(char *input) +{ unsigned char mem56; //output position for phonemes - unsigned char mem57; - unsigned char mem58; - unsigned char mem59; - unsigned char mem60; - unsigned char mem61; - unsigned short mem62; // memory position of current rule - - unsigned char mem64; // position of '=' or current character - unsigned char mem65; // position of ')' - unsigned char mem66; // position of '(' + unsigned char mem57; + unsigned char mem58; + unsigned char mem59; + unsigned char mem60; + unsigned char mem61; + unsigned short mem62; // memory position of current rule + + unsigned char mem64; // position of '=' or current character + unsigned char mem65; // position of ')' + unsigned char mem66; // position of '(' inputtemp[0] = 32; From 35b39376d9e554fb97e4dc1fcb1bb0ca5118591c Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 06:56:56 +0000 Subject: [PATCH 048/109] Refactoring --- src/reciter.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/reciter.c b/src/reciter.c index 9f185260..dc1471d7 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -13,10 +13,7 @@ static unsigned char inputtemp[256]; // secure copy of input tab36096 unsigned char Code37055(unsigned char mem59) { X = mem59 - 1; - unsigned char A = inputtemp[X]; - Y = A; - A = tab36376[A]; - return A; + return tab36376[inputtemp[X]]; } /* Retrieve flags for character at mem58 + 1 */ @@ -164,12 +161,9 @@ int TextToPhonemes(char *input) goto pos37184; } X = A & 127; - A = tab36376[X] & 128; - if (A == 0) break; - X = mem59-1; - A = inputtemp[X]; - if (A != mem57) goto pos36700; - mem59 = X; + if ((tab36376[X] & 128) == 0) break; + if (inputtemp[mem59-1] != mem57) goto pos36700; + --mem59; } unsigned char ch = mem57; @@ -188,9 +182,9 @@ int TextToPhonemes(char *input) case '&': if (!(Code37055(mem59) & 16)) { - if (inputtemp[X] != 72) goto pos36700; + if (inputtemp[X] != 'H') goto pos36700; A = inputtemp[--X]; - if ((A != 67) && (A != 83)) goto pos36700; + if ((A != 'C') && (A != 'S')) goto pos36700; } break; From a1058d6a0067f354239add44124f3b4145459fb9 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 06:57:31 +0000 Subject: [PATCH 049/109] Refactoring --- src/reciter.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/reciter.c b/src/reciter.c index dc1471d7..1f9e248e 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -155,12 +155,12 @@ int TextToPhonemes(char *input) while(1) { while(1) { mem66--; - mem57 = A = GetRuleByte(mem62, mem66); - if ((A & 128) != 0) { + mem57 = GetRuleByte(mem62, mem66); + if ((mem57 & 128) != 0) { mem58 = mem60; goto pos37184; } - X = A & 127; + X = mem57 & 127; if ((tab36376[X] & 128) == 0) break; if (inputtemp[mem59-1] != mem57) goto pos36700; --mem59; From af104711605a35a5182d2706245a55de48520937 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 07:03:03 +0000 Subject: [PATCH 050/109] Refactoring --- src/reciter.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/src/reciter.c b/src/reciter.c index 1f9e248e..6793d737 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -60,25 +60,19 @@ int TextToPhonemes(char *input) unsigned char mem65; // position of ')' unsigned char mem66; // position of '(' - inputtemp[0] = 32; + inputtemp[0] = ' '; // secure copy of input // because input will be overwritten by phonemes - X = 1; - Y = 0; + X = 0; do { - A = input[Y] & 127; + A = input[X] & 127; if ( A >= 112) A = A & 95; else if ( A >= 96) A = A & 79; - - inputtemp[X] = A; - X++; - Y++; - } while (Y != 255); + inputtemp[++X] = A; + } while (X < 255); inputtemp[255] = 27; - mem61 = 255; - A = 255; - mem56 = 255; + mem56 = mem61 = 255; pos36554: while (1) { @@ -150,7 +144,7 @@ int TextToPhonemes(char *input) // the string in the bracket is correct - A = mem59 = mem61; + mem59 = mem61; while(1) { while(1) { From 17a5c3bd3d845338ee1ea212426d85d8f511c3db Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 07:04:11 +0000 Subject: [PATCH 051/109] Refactoring --- src/reciter.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/reciter.c b/src/reciter.c index 6793d737..feb73afe 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -88,16 +88,14 @@ int TextToPhonemes(char *input) if (A != '.') break; X++; - Y = inputtemp[X]; - A = tab36376[Y] & 1; + A = tab36376[inputtemp[X]] & 1; if(A != 0) break; mem56++; X = mem56; A = '.'; input[X] = '.'; } - Y = mem64; - mem57 = tab36376[Y]; + mem57 = tab36376[mem64]; if((mem57&2) != 0) { mem62 = 37541; goto pos36700; From 1c30d2e117eebca8ba9cddaf25a97e17beda7b0e Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 07:04:28 +0000 Subject: [PATCH 052/109] Refactoring --- src/reciter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/reciter.c b/src/reciter.c index feb73afe..4d95baf3 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -120,7 +120,7 @@ int TextToPhonemes(char *input) pos36700: // find next rule while ((GetRuleByte(++mem62, 0) & 128) == 0); - Y = 1; + unsigned char Y = 1; while(GetRuleByte(mem62, Y) != '(') ++Y; mem66 = Y; while(GetRuleByte(mem62, ++Y) != ')'); From 85337bdf58061e20078d839b799277dbf8d823f8 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 07:26:39 +0000 Subject: [PATCH 053/109] Refactoring --- src/reciter.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/reciter.c b/src/reciter.c index 4d95baf3..a39b343f 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -78,15 +78,14 @@ int TextToPhonemes(char *input) while (1) { while(1) { X = ++mem61; - A = inputtemp[X]; - mem64 = A; - if (A == '[') { + mem64 = inputtemp[X]; + if (mem64 == '[') { X = ++mem56; input[X] = 155; return 1; } - if (A != '.') break; + if (mem64 != '.') break; X++; A = tab36376[inputtemp[X]] & 1; if(A != 0) break; @@ -234,7 +233,7 @@ int TextToPhonemes(char *input) while (1) { while (1) { unsigned char Y = mem65 + 1; - if(Y == mem64) { + if(Y == mem64) { mem61 = mem60; if (debug) PrintRule(mem62); From 2a30079cd46ab57f7525d393ebc2c221bc62e8e6 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 07:37:50 +0000 Subject: [PATCH 054/109] Refactoring --- src/reciter.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/reciter.c b/src/reciter.c index a39b343f..576c6871 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -49,9 +49,7 @@ unsigned char GetRuleByte(unsigned short mem62, unsigned char Y) int TextToPhonemes(char *input) { unsigned char mem56; //output position for phonemes - unsigned char mem57; unsigned char mem58; - unsigned char mem59; unsigned char mem60; unsigned char mem61; unsigned short mem62; // memory position of current rule @@ -74,6 +72,7 @@ int TextToPhonemes(char *input) inputtemp[255] = 27; mem56 = mem61 = 255; + unsigned char mem57; pos36554: while (1) { while(1) { @@ -141,7 +140,7 @@ int TextToPhonemes(char *input) // the string in the bracket is correct - mem59 = mem61; + unsigned char mem59 = mem61; while(1) { while(1) { @@ -231,6 +230,7 @@ int TextToPhonemes(char *input) pos37184: while (1) { + unsigned char mem57; while (1) { unsigned char Y = mem65 + 1; if(Y == mem64) { From 414a10e5ae9d2368120ee6cd688d1d43e36dd33d Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 07:39:23 +0000 Subject: [PATCH 055/109] Refactoring --- src/reciter.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/reciter.c b/src/reciter.c index 576c6871..4bf6cd6c 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -284,10 +284,7 @@ int TextToPhonemes(char *input) A = inputtemp[X]; if ((A != 69) && (A != 73) && (A != 89)) goto pos36700; } else if (A == ':') { - while (1) { - if(Code37066(mem58, 32) == 0) break; - mem58 = X; - } + while (Code37066(mem58, 32)) mem58 = X; continue; } else { break; From 391eac5d6f0d0d35a8d9fabd42d936d9f9f4e85d Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 07:40:56 +0000 Subject: [PATCH 056/109] Refactoring --- src/reciter.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/reciter.c b/src/reciter.c index 4bf6cd6c..ee8e8af3 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -187,8 +187,7 @@ int TextToPhonemes(char *input) break; case '^': - A = Code37055(mem59) & 32; - if(A == 0) goto pos36700; + if(!(Code37055(mem59) & 32)) goto pos36700; break; case '+': From 437b83180e83b91ab59ff409bdab93245c1135c4 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 07:41:26 +0000 Subject: [PATCH 057/109] Refactoring --- src/reciter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/reciter.c b/src/reciter.c index ee8e8af3..e8bc47d4 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -198,7 +198,7 @@ int TextToPhonemes(char *input) break; case ':': - while ((A = (Code37055(mem59) & 32))) --mem59; + while (Code37055(mem59) & 32) --mem59; continue; default: From 48c7c8139a87d1ac43a83a56c68300e7e3c2c013 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 07:43:25 +0000 Subject: [PATCH 058/109] Refactoring --- src/reciter.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/reciter.c b/src/reciter.c index e8bc47d4..42e6a52a 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -10,10 +10,10 @@ extern int debug; static unsigned char inputtemp[256]; // secure copy of input tab36096 /* Retrieve flags for character at mem59-1 */ -unsigned char Code37055(unsigned char mem59) +unsigned char Code37055(unsigned char mem59, unsigned char mask) { X = mem59 - 1; - return tab36376[inputtemp[X]]; + return tab36376[inputtemp[X]] & mask; } /* Retrieve flags for character at mem58 + 1 */ @@ -159,19 +159,19 @@ int TextToPhonemes(char *input) unsigned char ch = mem57; switch(ch) { case ' ': - if((Code37055(mem59) & 128)) goto pos36700; + if(Code37055(mem59,128)) goto pos36700; break; case '#': - if(!(Code37055(mem59) & 64)) goto pos36700; + if(!Code37055(mem59, 64)) goto pos36700; break; case '.': - if(!(Code37055(mem59) & 8)) goto pos36700; + if(!Code37055(mem59,8)) goto pos36700; break; case '&': - if (!(Code37055(mem59) & 16)) { + if (!Code37055(mem59,16)) { if (inputtemp[X] != 'H') goto pos36700; A = inputtemp[--X]; if ((A != 'C') && (A != 'S')) goto pos36700; @@ -179,7 +179,7 @@ int TextToPhonemes(char *input) break; case '@': - if(!(Code37055(mem59) & 4)) { + if(!Code37055(mem59,4)) { A = inputtemp[X]; if (A != 72) goto pos36700; if ((A != 84) && (A != 67) && (A != 83)) goto pos36700; @@ -187,7 +187,7 @@ int TextToPhonemes(char *input) break; case '^': - if(!(Code37055(mem59) & 32)) goto pos36700; + if(!Code37055(mem59,32)) goto pos36700; break; case '+': @@ -198,7 +198,7 @@ int TextToPhonemes(char *input) break; case ':': - while (Code37055(mem59) & 32) --mem59; + while (Code37055(mem59,32)) --mem59; continue; default: From 0815e470017bf153899394bfc127cde4651538d4 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 07:49:45 +0000 Subject: [PATCH 059/109] Refactoring --- src/reciter.c | 39 ++++++++++++++++----------------------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/src/reciter.c b/src/reciter.c index 42e6a52a..80cffd4d 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -10,19 +10,12 @@ extern int debug; static unsigned char inputtemp[256]; // secure copy of input tab36096 /* Retrieve flags for character at mem59-1 */ -unsigned char Code37055(unsigned char mem59, unsigned char mask) +unsigned char Code37055(unsigned char npos, unsigned char mask) { - X = mem59 - 1; + X = npos; return tab36376[inputtemp[X]] & mask; } -/* Retrieve flags for character at mem58 + 1 */ -unsigned char Code37066(unsigned char mem58, unsigned char mask) -{ - X = mem58 + 1; - return tab36376[inputtemp[X]] & mask; -} - unsigned int match(const char * str) { unsigned char ch; while ((ch = *str)) { @@ -159,19 +152,19 @@ int TextToPhonemes(char *input) unsigned char ch = mem57; switch(ch) { case ' ': - if(Code37055(mem59,128)) goto pos36700; + if(Code37055(mem59-1,128)) goto pos36700; break; case '#': - if(!Code37055(mem59, 64)) goto pos36700; + if(!Code37055(mem59-1, 64)) goto pos36700; break; case '.': - if(!Code37055(mem59,8)) goto pos36700; + if(!Code37055(mem59-1,8)) goto pos36700; break; case '&': - if (!Code37055(mem59,16)) { + if (!Code37055(mem59-1,16)) { if (inputtemp[X] != 'H') goto pos36700; A = inputtemp[--X]; if ((A != 'C') && (A != 'S')) goto pos36700; @@ -179,7 +172,7 @@ int TextToPhonemes(char *input) break; case '@': - if(!Code37055(mem59,4)) { + if(!Code37055(mem59-1,4)) { A = inputtemp[X]; if (A != 72) goto pos36700; if ((A != 84) && (A != 67) && (A != 83)) goto pos36700; @@ -187,7 +180,7 @@ int TextToPhonemes(char *input) break; case '^': - if(!Code37055(mem59,32)) goto pos36700; + if(!Code37055(mem59-1,32)) goto pos36700; break; case '+': @@ -198,7 +191,7 @@ int TextToPhonemes(char *input) break; case ':': - while (Code37055(mem59,32)) --mem59; + while (Code37055(mem59-1,32)) --mem59; continue; default: @@ -254,13 +247,13 @@ int TextToPhonemes(char *input) A = mem57; if (A == ' ') { - if (Code37066(mem58, 128) != 0) goto pos36700; + if (Code37055(mem58+1, 128) != 0) goto pos36700; } else if (A == '#') { - if (Code37066(mem58, 64) == 0) goto pos36700; + if (Code37055(mem58+1, 64) == 0) goto pos36700; } else if (A == '.') { - if(Code37066(mem58, 8) == 0) goto pos36700; + if(Code37055(mem58+1, 8) == 0) goto pos36700; } else if (A == '&') { - if(Code37066(mem58, 16) == 0) { + if(Code37055(mem58+1, 16) == 0) { if (inputtemp[X] != 72) goto pos36700; A = inputtemp[++X]; if ((A == 67) || (A == 83)) { @@ -269,7 +262,7 @@ int TextToPhonemes(char *input) } } } else if (A == '@') { - if(Code37066(mem58, 4) == 0) { + if(Code37055(mem58+1, 4) == 0) { A = inputtemp[X]; if (A != 72) goto pos36700; if ((A != 84) && (A != 67) && (A != 83)) goto pos36700; @@ -277,13 +270,13 @@ int TextToPhonemes(char *input) } continue; } else if (A == '^') { - if (Code37066(mem58, 32) == 0) goto pos36700; + if (Code37055(mem58+1, 32) == 0) goto pos36700; } else if (A == '+') { X = mem58 + 1; A = inputtemp[X]; if ((A != 69) && (A != 73) && (A != 89)) goto pos36700; } else if (A == ':') { - while (Code37066(mem58, 32)) mem58 = X; + while (Code37055(mem58+1, 32)) mem58 = X; continue; } else { break; From a98ea6e527ec7503e79c1ac6bd9b04e7e0df8530 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 08:09:31 +0000 Subject: [PATCH 060/109] Refactoring --- src/sam.c | 161 +++++++++++++++++++----------------------------------- 1 file changed, 55 insertions(+), 106 deletions(-) diff --git a/src/sam.c b/src/sam.c index 66a4bbaa..0d779f83 100644 --- a/src/sam.c +++ b/src/sam.c @@ -284,49 +284,36 @@ void InsertBreath() //void Code41883() -void CopyStress() -{ - // loop thought all the phonemes to be output - unsigned char pos=0; //mem66 - while(1) - { - // get the phomene - Y = phonemeindex[pos]; - - // exit at end of buffer - if (Y == 255) return; - - // if CONSONANT_FLAG set, skip - only vowels get stress - if ((flags[Y] & 64) == 0) {pos++; continue;} - // get the next phoneme - Y = phonemeindex[pos+1]; - if (Y == 255) //prevent buffer overflow - { - pos++; continue; - } else +void CopyStress() { + // loop thought all the phonemes to be output + unsigned char pos=0; //mem66 + unsigned char Y; + while((Y = phonemeindex[pos]) != 255) { + // if CONSONANT_FLAG set, skip - only vowels get stress + if ((flags[Y] & 64) == 0) {pos++; continue;} + Y = phonemeindex[pos+1]; + if (Y == 255) //prevent buffer overflow + { + pos++; continue; + } // if the following phoneme is a vowel, skip - if ((flags[Y] & 128) == 0) {pos++; continue;} - - // get the stress value at the next position - Y = stress[pos+1]; - - // if next phoneme is not stressed, skip - if (Y == 0) {pos++; continue;} - - // if next phoneme is not a VOWEL OR ER, skip - if ((Y & 128) != 0) {pos++; continue;} - - // copy stress from prior phoneme to this one - stress[pos] = Y+1; - - // advance pointer - pos++; - } - -} - - -//void Code41014() + if ((flags[Y] & 128) == 0) {pos++; continue;} + + // get the stress value at the next position + Y = stress[pos+1]; + + // if next phoneme is not stressed, skip + if (Y == 0) {pos++; continue;} + // if next phoneme is not a VOWEL OR ER, skip + if ((Y & 128) != 0) {pos++; continue;} + + // copy stress from prior phoneme to this one + stress[pos] = Y+1; + + ++pos; + } +} + void Insert(unsigned char position/*var57*/, unsigned char mem60, unsigned char mem59, unsigned char mem58) { int i; @@ -1386,68 +1373,30 @@ if (debug) printf("phoneme %d (%c%c) length %d\n", debugX-1, signInputTable1[pho // Decrease by 2 // liquic consonant? - if ((flags2[index] & 16) != 0) - { - // R*, L*, W*, Y* - - // get the prior phoneme - index = phonemeindex[X-1]; - - // prior phoneme a stop consonant> - if((flags[index] & 2) != 0) - // Rule: - -if (debug) printf("RULE: - decrease by 2\n"); + if ((flags2[index] & 16) != 0) + { + // R*, L*, W*, Y* + + // get the prior phoneme + index = phonemeindex[X-1]; + + // prior phoneme a stop consonant> + if((flags[index] & 2) != 0) + // Rule: + +if (debug) printf("RULE: - decrease by 2\n"); if (debug) printf("PRE\n"); -if (debug) printf("phoneme %d (%c%c) length %d\n", X, signInputTable1[phonemeindex[X]], signInputTable2[phonemeindex[X]], phonemeLength[X]); - - // decrease the phoneme length by 2 frames (20 ms) - phonemeLength[X] -= 2; - -if (debug) printf("POST\n"); -if (debug) printf("phoneme %d (%c%c) length %d\n", X, signInputTable1[phonemeindex[X]], signInputTable2[phonemeindex[X]], phonemeLength[X]); - } - - // move to next phoneme - loopIndex++; - continue; - } -// goto pos48701; -} - -// ------------------------------------------------------------------------- -// ML : Code47503 is division with remainder, and mem50 gets the sign -void Code47503(unsigned char mem52) -{ - - Y = 0; - if ((mem53 & 128) != 0) - { - mem53 = -mem53; - Y = 128; - } - mem50 = Y; - A = 0; - for(X=8; X > 0; X--) - { - int temp = mem53; - mem53 = mem53 << 1; - A = A << 1; - if (temp >= 128) A++; - if (A >= mem52) - { - A = A - mem52; - mem53++; - } - } - - mem51 = A; - if ((mem50 & 128) != 0) mem53 = -mem53; - -} - - - - - - +if (debug) printf("phoneme %d (%c%c) length %d\n", X, signInputTable1[phonemeindex[X]], signInputTable2[phonemeindex[X]], phonemeLength[X]); + + // decrease the phoneme length by 2 frames (20 ms) + phonemeLength[X] -= 2; + +if (debug) printf("POST\n"); +if (debug) printf("phoneme %d (%c%c) length %d\n", X, signInputTable1[phonemeindex[X]], signInputTable2[phonemeindex[X]], phonemeLength[X]); + } + + // move to next phoneme + loopIndex++; + continue; + } +} From b11cfe2fad7201d64320bf383594d4d77865c154 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 22 Jan 2017 08:14:02 +0000 Subject: [PATCH 061/109] Refactoring --- src/sam.c | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/src/sam.c b/src/sam.c index 0d779f83..1963ff60 100644 --- a/src/sam.c +++ b/src/sam.c @@ -383,22 +383,19 @@ void Insert(unsigned char position/*var57*/, unsigned char mem60, unsigned char // function returns with a 1 indicating success. int Parser1() { - int i; - unsigned char sign1; - unsigned char sign2; - unsigned char position = 0; - X = 0; - A = 0; - Y = 0; - - // CLEAR THE STRESS TABLE - for(i=0; i<256; i++) - stress[i] = 0; - - // THIS CODE MATCHES THE PHONEME LETTERS TO THE TABLE - // pos41078: - while(1) - { + int i; + unsigned char sign1; + unsigned char sign2; + unsigned char position = 0; + X = 0; + A = 0; + Y = 0; + + // CLEAR THE STRESS TABLE + for(i=0; i<256; i++) stress[i] = 0; + + // THIS CODE MATCHES THE PHONEME LETTERS TO THE TABLE + while(1) { // GET THE FIRST CHARACTER FROM THE PHONEME BUFFER sign1 = input[X]; // TEST FOR 155 (›) END OF LINE MARKER From de8d12c71f46c260538817ac7dc590a807143392 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Mon, 23 Jan 2017 19:51:31 +0000 Subject: [PATCH 062/109] Refactoring --- src/sam.c | 81 +++++++++++++++++++++++++------------------------------ 1 file changed, 36 insertions(+), 45 deletions(-) diff --git a/src/sam.c b/src/sam.c index 1963ff60..381cde41 100644 --- a/src/sam.c +++ b/src/sam.c @@ -174,51 +174,42 @@ int SAMMain() } -//void Code48547() -void PrepareOutput() -{ - A = 0; - X = 0; - Y = 0; - - //pos48551: - while(1) - { - A = phonemeindex[X]; - if (A == 255) - { - A = 255; - phonemeIndexOutput[Y] = 255; - Render(); - return; - } - if (A == 254) - { - X++; - int temp = X; - //mem[48546] = X; - phonemeIndexOutput[Y] = 255; - Render(); - //X = mem[48546]; - X=temp; - Y = 0; - continue; - } - - if (A == 0) - { - X++; - continue; - } - - phonemeIndexOutput[Y] = A; - phonemeLengthOutput[Y] = phonemeLength[X]; - stressOutput[Y] = stress[X]; - X++; - Y++; - } -} - + +void PrepareOutput() { + unsigned char X = 0; // Position in source + unsigned char Y = 0; // Position in output + + while(1) { + unsigned char A = phonemeindex[X]; + + phonemeIndexOutput[Y] = A; + + if (A == 255) { // End of input + Render(); + return; + } + + if (A == 254) { + ++X; + phonemeIndexOutput[Y] = 255; + Render(); + Y = 0; + continue; + } + + if (A == 0) { + ++X; + continue; + } + + phonemeIndexOutput[Y] = A; + phonemeLengthOutput[Y] = phonemeLength[X]; + stressOutput[Y] = stress[X]; + ++X; + ++Y; + } +} + //void Code48431() void InsertBreath() { From cb59aaa615c48bd8577321cda2a4bf0c6252e6c0 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Mon, 23 Jan 2017 19:56:46 +0000 Subject: [PATCH 063/109] Refactoring --- src/sam.c | 83 ++++++++++++++++++++++--------------------------------- 1 file changed, 33 insertions(+), 50 deletions(-) diff --git a/src/sam.c b/src/sam.c index 381cde41..a567902f 100644 --- a/src/sam.c +++ b/src/sam.c @@ -210,56 +210,39 @@ void PrepareOutput() { } } -//void Code48431() -void InsertBreath() -{ - unsigned char mem54; - unsigned char mem55; - unsigned char index; //variable Y - mem54 = 255; - X++; - mem55 = 0; - unsigned char mem66 = 0; - while(1) - { - //pos48440: - X = mem66; - index = phonemeindex[X]; - if (index == 255) return; - mem55 += phonemeLength[X]; - - if (mem55 < 232) - { - if (index != 254) // ML : Prevents an index out of bounds problem - { - A = flags2[index]&1; - if(A != 0) - { - X++; - mem55 = 0; - Insert(X, 254, mem59, 0); - mem66++; - mem66++; - continue; - } - } - if (index == 0) mem54 = X; - mem66++; - continue; - } - X = mem54; - phonemeindex[X] = 31; // 'Q*' glottal stop - phonemeLength[X] = 4; - stress[X] = 0; - X++; - mem55 = 0; - Insert(X, 254, mem59, 0); - X++; - mem66 = X; - } - -} - + +void InsertBreath() { + unsigned char mem54 = 255; + unsigned char mem55 = 0; + unsigned char index; //variable Y + unsigned char mem66 = 0; + while((index = phonemeindex[mem66]) != 255) { + mem55 += phonemeLength[mem66]; + + if (mem55 < 232) { + if (index != 254) { // ML : Prevents an index out of bounds problem + if((flags2[index]&1) != 0) { + mem55 = 0; + Insert(mem66+1, 254, mem59, 0); + mem66 += 2; + continue; + } + } + if (index == 0) mem54 = mem66; + ++mem66; + continue; + } + + phonemeindex[mem54] = 31; // 'Q*' glottal stop + phonemeLength[mem54] = 4; + stress[mem54] = 0; + mem55 = 0; + Insert(mem54+1, 254, mem59, 0); + mem66 = mem54+2; + } +} + + // Iterates through the phoneme buffer, copying the stress value from // the following phoneme under the following circumstance: From 339e0324c6b50dec7b255694dc729939721cdd0b Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Mon, 23 Jan 2017 20:02:42 +0000 Subject: [PATCH 064/109] Refactoring --- src/sam.c | 118 +++++++++++++++++++++++------------------------------- 1 file changed, 50 insertions(+), 68 deletions(-) diff --git a/src/sam.c b/src/sam.c index a567902f..48df20a4 100644 --- a/src/sam.c +++ b/src/sam.c @@ -475,74 +475,56 @@ int Parser1() // SET THE STRESS FOR THE PRIOR PHONEME stress[position-1] = Y; } //while -} - - - - -//change phonemelength depedendent on stress -//void Code41203() -void SetPhonemeLength() -{ - unsigned char A; - int position = 0; - while(phonemeindex[position] != 255 ) - { - A = stress[position]; - //41218: BMI 41229 - if ((A == 0) || ((A&128) != 0)) - { - phonemeLength[position] = phonemeLengthTable[phonemeindex[position]]; - } else - { - phonemeLength[position] = phonemeStressedLengthTable[phonemeindex[position]]; - } - position++; - } -} - - -void Code41240() -{ - unsigned char pos=0; - - while(phonemeindex[pos] != 255) - { - unsigned char index; //register AC - X = pos; - index = phonemeindex[pos]; - if ((flags[index]&2) == 0) - { - pos++; - continue; - } else - if ((flags[index]&1) == 0) - { - Insert(pos+1, index+1, phonemeLengthTable[index+1], stress[pos]); - Insert(pos+2, index+2, phonemeLengthTable[index+2], stress[pos]); - pos += 3; - continue; - } - - do - { - X++; - A = phonemeindex[X]; - } while(A==0); - - if (A != 255) - { - if ((flags[A] & 8) != 0) {pos++; continue;} - if ((A == 36) || (A == 37)) {pos++; continue;} // '/H' '/X' - } - - Insert(pos+1, index+1, phonemeLengthTable[index+1], stress[pos]); - Insert(pos+2, index+2, phonemeLengthTable[index+2], stress[pos]); - pos += 3; - }; - -} - +} + + +//change phonemelength depedendent on stress +void SetPhonemeLength() { + unsigned char A; + int position = 0; + while(phonemeindex[position] != 255 ) + { + A = stress[position]; + if ((A == 0) || ((A&128) != 0)) { + phonemeLength[position] = phonemeLengthTable[phonemeindex[position]]; + } else { + phonemeLength[position] = phonemeStressedLengthTable[phonemeindex[position]]; + } + position++; + } +} + + +void Code41240() { + unsigned char pos=0; + + while(phonemeindex[pos] != 255) { + unsigned char index; //register AC + X = pos; + index = phonemeindex[pos]; + if ((flags[index]&2) == 0) { + pos++; + continue; + } else if ((flags[index]&1) == 0) { + Insert(pos+1, index+1, phonemeLengthTable[index+1], stress[pos]); + Insert(pos+2, index+2, phonemeLengthTable[index+2], stress[pos]); + pos += 3; + continue; + } + + while(!(A = phonemeindex[++X])); + + if (A != 255) { + if ((flags[A] & 8) != 0) {pos++; continue;} + if ((A == 36) || (A == 37)) {pos++; continue;} // '/H' '/X' + } + + Insert(pos+1, index+1, phonemeLengthTable[index+1], stress[pos]); + Insert(pos+2, index+2, phonemeLengthTable[index+2], stress[pos]); + pos += 3; + } +} + // Rewrites the phonemes using the following rules: // // -> WX From 17dcee98e1ba7f1bc63ef1cdb9f5fc779dd2aaaf Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Mon, 23 Jan 2017 20:03:27 +0000 Subject: [PATCH 065/109] Refactoring --- src/sam.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sam.c b/src/sam.c index 48df20a4..41d22764 100644 --- a/src/sam.c +++ b/src/sam.c @@ -500,7 +500,7 @@ void Code41240() { while(phonemeindex[pos] != 255) { unsigned char index; //register AC - X = pos; + unsigned char X = pos; index = phonemeindex[pos]; if ((flags[index]&2) == 0) { pos++; From 4c8c09410a14203b6fd1d92adeaf05252d43dadd Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Mon, 23 Jan 2017 20:04:12 +0000 Subject: [PATCH 066/109] Refactoring --- src/sam.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sam.c b/src/sam.c index 41d22764..b13a9a01 100644 --- a/src/sam.c +++ b/src/sam.c @@ -515,8 +515,8 @@ void Code41240() { while(!(A = phonemeindex[++X])); if (A != 255) { - if ((flags[A] & 8) != 0) {pos++; continue;} - if ((A == 36) || (A == 37)) {pos++; continue;} // '/H' '/X' + if (flags[A] & 8) { ++pos; continue;} + if ((A == 36) || (A == 37)) {++pos; continue;} // '/H' '/X' } Insert(pos+1, index+1, phonemeLengthTable[index+1], stress[pos]); From de21135b6974487caed1aed0ccb042e246bbbdc9 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Mon, 23 Jan 2017 20:07:46 +0000 Subject: [PATCH 067/109] Refactoring --- src/sam.c | 67 +++++++++++++++++++++---------------------------------- 1 file changed, 25 insertions(+), 42 deletions(-) diff --git a/src/sam.c b/src/sam.c index b13a9a01..7620e103 100644 --- a/src/sam.c +++ b/src/sam.c @@ -132,48 +132,31 @@ void Init() phonemeindex[255] = 255; //to prevent buffer overflow // ML : changed from 32 to 255 to stop freezing with long inputs } - - -//int Code39771() -int SAMMain() -{ - Init(); - phonemeindex[255] = 32; //to prevent buffer overflow - - if (!Parser1()) return 0; - if (debug) - PrintPhonemes(phonemeindex, phonemeLength, stress); - Parser2(); - CopyStress(); - SetPhonemeLength(); - AdjustLengths(); - Code41240(); - do - { - A = phonemeindex[X]; - if (A > 80) - { - phonemeindex[X] = 255; - break; // error: delete all behind it - } - X++; - } while (X != 0); - - //pos39848: - InsertBreath(); - - //mem[40158] = 255; - if (debug) - { - PrintPhonemes(phonemeindex, phonemeLength, stress); - } - - PrepareOutput(); - - return 1; -} - - + +int SAMMain() { + Init(); + phonemeindex[255] = 32; //to prevent buffer overflow + + if (!Parser1()) return 0; + if (debug) PrintPhonemes(phonemeindex, phonemeLength, stress); + Parser2(); + CopyStress(); + SetPhonemeLength(); + AdjustLengths(); + Code41240(); + do { + if (phonemeindex[X] > 80) { + phonemeindex[X] = 255; + break; // error: delete all behind it + } + } while (++X != 0); + InsertBreath(); + + if (debug) PrintPhonemes(phonemeindex, phonemeLength, stress); + + PrepareOutput(); + return 1; +} void PrepareOutput() { unsigned char X = 0; // Position in source From 717bde6f66b5fab38d51a812955ce8f862255556 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Mon, 23 Jan 2017 20:11:29 +0000 Subject: [PATCH 068/109] Refactoring --- src/sam.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/sam.c b/src/sam.c index 7620e103..ae08c604 100644 --- a/src/sam.c +++ b/src/sam.c @@ -198,21 +198,23 @@ void InsertBreath() { unsigned char mem54 = 255; unsigned char mem55 = 0; unsigned char index; //variable Y - unsigned char mem66 = 0; - while((index = phonemeindex[mem66]) != 255) { - mem55 += phonemeLength[mem66]; + + unsigned char pos = 0; + + while((index = phonemeindex[pos]) != 255) { + mem55 += phonemeLength[pos]; if (mem55 < 232) { if (index != 254) { // ML : Prevents an index out of bounds problem if((flags2[index]&1) != 0) { mem55 = 0; - Insert(mem66+1, 254, mem59, 0); - mem66 += 2; + Insert(pos+1, 254, mem59, 0); + pos += 2; continue; } } - if (index == 0) mem54 = mem66; - ++mem66; + if (index == 0) mem54 = pos; + ++pos; continue; } @@ -221,7 +223,7 @@ void InsertBreath() { stress[mem54] = 0; mem55 = 0; Insert(mem54+1, 254, mem59, 0); - mem66 = mem54+2; + pos = mem54+2; } } From 49d506d9706ae8b7c83a661e2f12989caa3c4366 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Mon, 23 Jan 2017 20:12:02 +0000 Subject: [PATCH 069/109] Refactoring --- src/sam.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sam.c b/src/sam.c index ae08c604..62f34919 100644 --- a/src/sam.c +++ b/src/sam.c @@ -242,7 +242,7 @@ void InsertBreath() { // to the L that precedes it. -//void Code41883() + void CopyStress() { // loop thought all the phonemes to be output unsigned char pos=0; //mem66 From 696bb1b76832cfd83193397d006ab3a69ebb6cdd Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Mon, 23 Jan 2017 20:19:22 +0000 Subject: [PATCH 070/109] Refactoring --- src/sam.c | 117 +++++++++++++++++++++++++----------------------------- 1 file changed, 53 insertions(+), 64 deletions(-) diff --git a/src/sam.c b/src/sam.c index 62f34919..336e4164 100644 --- a/src/sam.c +++ b/src/sam.c @@ -27,7 +27,7 @@ unsigned char mem56; unsigned char mem59=0; -unsigned char A, X, Y; +unsigned char X; unsigned char stress[256]; //numbers from 0 to 8 unsigned char phonemeLength[256]; //tab40160 @@ -346,71 +346,59 @@ int Parser1() unsigned char sign1; unsigned char sign2; unsigned char position = 0; - X = 0; - A = 0; - Y = 0; + unsigned char X = 0; + unsigned char A = 0; + unsigned char Y = 0; // CLEAR THE STRESS TABLE for(i=0; i<256; i++) stress[i] = 0; // THIS CODE MATCHES THE PHONEME LETTERS TO THE TABLE while(1) { - // GET THE FIRST CHARACTER FROM THE PHONEME BUFFER - sign1 = input[X]; - // TEST FOR 155 (›) END OF LINE MARKER - if (sign1 == 155) - { - // MARK ENDPOINT AND RETURN - phonemeindex[position] = 255; //mark endpoint - // REACHED END OF PHONEMES, SO EXIT - return 1; //all ok - } - - // GET THE NEXT CHARACTER FROM THE BUFFER - X++; - sign2 = input[X]; - - // NOW sign1 = FIRST CHARACTER OF PHONEME, AND sign2 = SECOND CHARACTER OF PHONEME - - // TRY TO MATCH PHONEMES ON TWO TWO-CHARACTER NAME - // IGNORE PHONEMES IN TABLE ENDING WITH WILDCARDS - - // SET INDEX TO 0 - Y = 0; -pos41095: - - // GET FIRST CHARACTER AT POSITION Y IN signInputTable - // --> should change name to PhonemeNameTable1 - A = signInputTable1[Y]; - - // FIRST CHARACTER MATCHES? - if (A == sign1) - { - // GET THE CHARACTER FROM THE PhonemeSecondLetterTable - A = signInputTable2[Y]; - // NOT A SPECIAL AND MATCHES SECOND CHARACTER? - if ((A != '*') && (A == sign2)) - { - // STORE THE INDEX OF THE PHONEME INTO THE phomeneIndexTable - phonemeindex[position] = Y; - - // ADVANCE THE POINTER TO THE phonemeIndexTable - position++; - // ADVANCE THE POINTER TO THE phonemeInputBuffer - X++; - - // CONTINUE PARSING - continue; - } - } - - // NO MATCH, TRY TO MATCH ON FIRST CHARACTER TO WILDCARD NAMES (ENDING WITH '*') - - // ADVANCE TO THE NEXT POSITION - Y++; - // IF NOT END OF TABLE, CONTINUE - if (Y != 81) goto pos41095; - + // GET THE FIRST CHARACTER FROM THE PHONEME BUFFER + sign1 = input[X]; + // TEST FOR 155 (›) END OF LINE MARKER + if (sign1 == 155) { + phonemeindex[position] = 255; //mark endpoint + return 1; // REACHED END OF PHONEMES, SO EXIT + } + + // GET THE NEXT CHARACTER FROM THE BUFFER + sign2 = input[++X]; + + // NOW sign1 = FIRST CHARACTER OF PHONEME, AND sign2 = SECOND CHARACTER OF PHONEME + + // TRY TO MATCH PHONEMES ON TWO TWO-CHARACTER NAME + // IGNORE PHONEMES IN TABLE ENDING WITH WILDCARDS + Y = 0; // SET INDEX TO 0 +pos41095: + // GET FIRST CHARACTER AT POSITION Y IN signInputTable + // --> should change name to PhonemeNameTable1 + A = signInputTable1[Y]; + + if (A == sign1) { + // GET THE CHARACTER FROM THE PhonemeSecondLetterTable + A = signInputTable2[Y]; + // NOT A SPECIAL AND MATCHES SECOND CHARACTER? + if ((A != '*') && (A == sign2)) + { + // STORE THE INDEX OF THE PHONEME INTO THE phomeneIndexTable + phonemeindex[position] = Y; + + // ADVANCE THE POINTER TO THE phonemeIndexTable + ++position; + // ADVANCE THE POINTER TO THE phonemeInputBuffer + ++X; + // CONTINUE PARSING + continue; + } + } + + // NO MATCH, TRY TO MATCH ON FIRST CHARACTER TO WILDCARD NAMES (ENDING WITH '*') + + // ADVANCE TO THE NEXT POSITION. IF NOT END OF TABLE, CONTINUE + if (++Y != 81) goto pos41095; + // REACHED END OF TABLE WITHOUT AN EXACT (2 CHARACTER) MATCH. // THIS TIME, SEARCH FOR A 1 CHARACTER MATCH AGAINST THE WILDCARDS @@ -497,6 +485,7 @@ void Code41240() { continue; } + unsigned char A; while(!(A = phonemeindex[++X])); if (A != 255) { @@ -549,7 +538,7 @@ void Parser2() // SET X TO THE CURRENT POSITION X = pos; // GET THE PHONEME AT THE CURRENT POSITION - A = phonemeindex[pos]; + unsigned char A = phonemeindex[pos]; // DEBUG: Print phoneme and index if (debug && A != 255) printf("%d: %c%c\n", X, signInputTable1[A], signInputTable2[A]); @@ -566,7 +555,7 @@ void Parser2() if (A == 255) return; // Copy the current phoneme index to Y - Y = A; + unsigned char Y = A; // RULE: // -> WX @@ -1049,7 +1038,7 @@ void AdjustLengths() //if(A == 0) goto pos48688; // get the phoneme length - A = phonemeLength[X]; + unsigned char A = phonemeLength[X]; // change phoneme length to (length * 1.5) + 1 A = (A >> 1) + A + 1; @@ -1086,7 +1075,7 @@ if (debug) printf("phoneme %d (%c%c) length %d\n", X, signInputTable1[phonemeind if (index == 255) return; // vowel? - A = flags[index] & 128; + unsigned char A = flags[index] & 128; if (A != 0) { // get next phoneme From fbc3694129051032fd7562a1441cd624a27053ec Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Mon, 23 Jan 2017 20:20:23 +0000 Subject: [PATCH 071/109] Refactoring --- src/sam.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sam.c b/src/sam.c index 336e4164..38f92e14 100644 --- a/src/sam.c +++ b/src/sam.c @@ -23,8 +23,6 @@ unsigned char mem49; unsigned char mem50; unsigned char mem51; unsigned char mem53; -unsigned char mem56; - unsigned char mem59=0; unsigned char X; @@ -1076,6 +1074,7 @@ if (debug) printf("phoneme %d (%c%c) length %d\n", X, signInputTable1[phonemeind // vowel? unsigned char A = flags[index] & 128; + unsigned char mem56; if (A != 0) { // get next phoneme From 9115ca3b1450609accc3fe77a7cbbf7b47690f9a Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Tue, 24 Jan 2017 01:08:46 +0000 Subject: [PATCH 072/109] Refactoring --- src/sam.c | 774 +++++++++++++++++++++++------------------------------- 1 file changed, 334 insertions(+), 440 deletions(-) diff --git a/src/sam.c b/src/sam.c index 38f92e14..ef1db525 100644 --- a/src/sam.c +++ b/src/sam.c @@ -465,7 +465,6 @@ void SetPhonemeLength() { } } - void Code41240() { unsigned char pos=0; @@ -520,446 +519,341 @@ void Code41240() { // J -> J J' (J requires two phonemes to represent it) // T -> DX // D -> DX - - -//void Code41397() -void Parser2() -{ - if (debug) printf("Parser2\n"); - unsigned char pos = 0; //mem66; - unsigned char mem58 = 0; - - - // Loop through phonemes - while(1) - { -// SET X TO THE CURRENT POSITION - X = pos; -// GET THE PHONEME AT THE CURRENT POSITION + + +void Parser2() { + if (debug) printf("Parser2\n"); + unsigned char pos = 0; //mem66; + + // Loop through phonemes + while(1) { + X = pos; unsigned char A = phonemeindex[pos]; - -// DEBUG: Print phoneme and index - if (debug && A != 255) printf("%d: %c%c\n", X, signInputTable1[A], signInputTable2[A]); - -// Is phoneme pause? - if (A == 0) - { -// Move ahead to the - pos++; - continue; - } - -// If end of phonemes flag reached, exit routine - if (A == 255) return; - -// Copy the current phoneme index to Y - unsigned char Y = A; - -// RULE: -// -> WX -// -> YX -// Example: OIL, COW - - -// Check for DIPTHONG - if ((flags[A] & 16) == 0) goto pos41457; - -// Not a dipthong. Get the stress - mem58 = stress[pos]; - -// End in IY sound? - A = flags[Y] & 32; - -// If ends with IY, use YX, else use WX - if (A == 0) A = 20; else A = 21; // 'WX' = 20 'YX' = 21 - //pos41443: -// Insert at WX or YX following, copying the stress - - if (debug) if (A==20) printf("RULE: insert WX following dipthong NOT ending in IY sound\n"); - if (debug) if (A==21) printf("RULE: insert YX following dipthong ending in IY sound\n"); - Insert(pos+1, A, mem59, mem58); - X = pos; -// Jump to ??? - goto pos41749; - - - -pos41457: - -// RULE: -// UL -> AX L -// Example: MEDDLE - -// Get phoneme - A = phonemeindex[X]; -// Skip this rule if phoneme is not UL - if (A != 78) goto pos41487; // 'UL' - A = 24; // 'L' //change 'UL' to 'AX L' - - if (debug) printf("RULE: UL -> AX L\n"); - -pos41466: -// Get current phoneme stress - mem58 = stress[X]; - -// Change UL to AX - phonemeindex[X] = 13; // 'AX' -// Perform insert. Note code below may jump up here with different values - Insert(X+1, A, mem59, mem58); - pos++; -// Move to next phoneme - continue; - -pos41487: - -// RULE: -// UM -> AX M -// Example: ASTRONOMY - -// Skip rule if phoneme != UM - if (A != 79) goto pos41495; // 'UM' - // Jump up to branch - replaces current phoneme with AX and continues - A = 27; // 'M' //change 'UM' to 'AX M' - if (debug) printf("RULE: UM -> AX M\n"); - goto pos41466; -pos41495: - -// RULE: -// UN -> AX N -// Example: FUNCTION - - -// Skip rule if phoneme != UN - if (A != 80) goto pos41503; // 'UN' - - // Jump up to branch - replaces current phoneme with AX and continues - A = 28; // 'N' //change UN to 'AX N' - if (debug) printf("RULE: UN -> AX N\n"); - goto pos41466; -pos41503: - -// RULE: -// -> Q -// EXAMPLE: AWAY EIGHT - - Y = A; -// VOWEL set? - A = flags[A] & 128; - -// Skip if not a vowel - if (A != 0) - { -// Get the stress - A = stress[X]; - -// If stressed... - if (A != 0) - { -// Get the following phoneme - X++; - A = phonemeindex[X]; -// If following phoneme is a pause - - if (A == 0) - { -// Get the phoneme following pause - X++; - Y = phonemeindex[X]; - -// Check for end of buffer flag - if (Y == 255) //buffer overflow -// ??? Not sure about these flags - A = 65&128; - else -// And VOWEL flag to current phoneme's flags - A = flags[Y] & 128; - -// If following phonemes is not a pause - if (A != 0) - { -// If the following phoneme is not stressed - A = stress[X]; - if (A != 0) - { -// Insert a glottal stop and move forward - if (debug) printf("RULE: Insert glottal stop between two stressed vowels with space between them\n"); - // 31 = 'Q' - Insert(X, 31, mem59, 0); - pos++; - continue; - } - } - } - } - } - - -// RULES FOR PHONEMES BEFORE R -// T R -> CH R -// Example: TRACK - - -// Get current position and phoneme - X = pos; - A = phonemeindex[pos]; - if (A != 23) goto pos41611; // 'R' - -// Look at prior phoneme - X--; - A = phonemeindex[pos-1]; - //pos41567: - if (A == 69) // 'T' - { -// Change T to CH - if (debug) printf("RULE: T R -> CH R\n"); - phonemeindex[pos-1] = 42; - goto pos41779; - } - - -// RULES FOR PHONEMES BEFORE R -// D R -> J R -// Example: DRY - -// Prior phonemes D? - if (A == 57) // 'D' - { -// Change D to J - phonemeindex[pos-1] = 44; - if (debug) printf("RULE: D R -> J R\n"); - goto pos41788; - } - -// RULES FOR PHONEMES BEFORE R -// R -> RX -// Example: ART - - -// If vowel flag is set change R to RX - A = flags[A] & 128; - if (debug) printf("RULE: R -> RX\n"); - if (A != 0) phonemeindex[pos] = 18; // 'RX' - -// continue to next phoneme - pos++; - continue; - -pos41611: - -// RULE: -// L -> LX -// Example: ALL - -// Is phoneme L? - if (A == 24) // 'L' - { -// If prior phoneme does not have VOWEL flag set, move to next phoneme - if ((flags[phonemeindex[pos-1]] & 128) == 0) {pos++; continue;} -// Prior phoneme has VOWEL flag set, so change L to LX and move to next phoneme - if (debug) printf("RULE: L -> LX\n"); - phonemeindex[X] = 19; // 'LX' - pos++; - continue; - } - -// RULE: -// G S -> G Z -// -// Can't get to fire - -// 1. The G -> GX rule intervenes -// 2. Reciter already replaces GS -> GZ - -// Is current phoneme S? - if (A == 32) // 'S' - { -// If prior phoneme is not G, move to next phoneme - if (phonemeindex[pos-1] != 60) {pos++; continue;} -// Replace S with Z and move on - if (debug) printf("RULE: G S -> G Z\n"); - phonemeindex[pos] = 38; // 'Z' - pos++; - continue; - } - -// RULE: -// K -> KX -// Example: COW - -// Is current phoneme K? - if (A == 72) // 'K' - { -// Get next phoneme - Y = phonemeindex[pos+1]; -// If at end, replace current phoneme with KX - if (Y == 255) phonemeindex[pos] = 75; // ML : prevents an index out of bounds problem - else - { -// VOWELS AND DIPTHONGS ENDING WITH IY SOUND flag set? - A = flags[Y] & 32; - if (debug) if (A==0) printf("RULE: K -> KX \n"); -// Replace with KX - if (A == 0) phonemeindex[pos] = 75; // 'KX' - } - } - else - -// RULE: -// G -> GX -// Example: GO - - -// Is character a G? - if (A == 60) // 'G' - { -// Get the following character - unsigned char index = phonemeindex[pos+1]; - -// At end of buffer? - if (index == 255) //prevent buffer overflow - { - pos++; continue; - } - else -// If dipthong ending with YX, move continue processing next phoneme - if ((flags[index] & 32) != 0) {pos++; continue;} -// replace G with GX and continue processing next phoneme - if (debug) printf("RULE: G -> GX \n"); - phonemeindex[pos] = 63; // 'GX' - pos++; - continue; - } - -// RULE: -// S P -> S B -// S T -> S D -// S K -> S G -// S KX -> S GX -// Examples: SPY, STY, SKY, SCOWL - - Y = phonemeindex[pos]; - //pos41719: -// Replace with softer version? - A = flags[Y] & 1; - if (A == 0) goto pos41749; - A = phonemeindex[pos-1]; - if (A != 32) // 'S' - { - A = Y; - goto pos41812; - } - // Replace with softer version - if (debug) printf("RULE: S* %c%c -> S* %c%c\n", signInputTable1[Y], signInputTable2[Y],signInputTable1[Y-12], signInputTable2[Y-12]); - phonemeindex[pos] = Y-12; - pos++; - continue; - - -pos41749: - -// RULE: -// UW -> UX -// -// Example: NEW, DEW, SUE, ZOO, THOO, TOO - -// UW -> UX - - A = phonemeindex[X]; - if (A == 53) // 'UW' - { -// ALVEOLAR flag set? - Y = phonemeindex[X-1]; - A = flags2[Y] & 4; -// If not set, continue processing next phoneme - if (A == 0) {pos++; continue;} - if (debug) printf("RULE: UW -> UX\n"); - phonemeindex[X] = 16; - pos++; - continue; - } -pos41779: - -// RULE: -// CH -> CH CH' (CH requires two phonemes to represent it) -// Example: CHEW - - if (A == 42) // 'CH' - { - // pos41783: - if (debug) printf("CH -> CH CH+1\n"); - Insert(X+1, A+1, mem59, stress[X]); - pos++; - continue; - } - -pos41788: - -// RULE: -// J -> J J' (J requires two phonemes to represent it) -// Example: JAY - - - if (A == 44) // 'J' - { - if (debug) printf("J -> J J+1\n"); - Insert(X+1, A+1, mem59, stress[X]); - pos++; - continue; - } - -// Jump here to continue -pos41812: - -// RULE: Soften T following vowel -// NOTE: This rule fails for cases such as "ODD" -// T -> DX -// D -> DX -// Example: PARTY, TARDY - - -// Past this point, only process if phoneme is T or D - - if (A != 69) // 'T' - if (A != 57) {pos++; continue;} // 'D' - //pos41825: - - -// If prior phoneme is not a vowel, continue processing phonemes - if ((flags[phonemeindex[X-1]] & 128) == 0) {pos++; continue;} - -// Get next phoneme - X++; - A = phonemeindex[X]; - //pos41841 -// Is the next phoneme a pause? - if (A != 0) - { -// If next phoneme is not a pause, continue processing phonemes - if ((flags[A] & 128) == 0) {pos++; continue;} -// If next phoneme is stressed, continue processing phonemes -// FIXME: How does a pause get stressed? - if (stress[X] != 0) {pos++; continue;} -//pos41856: -// Set phonemes to DX - if (debug) printf("RULE: Soften T or D following vowel or ER and preceding a pause -> DX\n"); - phonemeindex[pos] = 30; // 'DX' - } else - { - A = phonemeindex[X+1]; - if (A == 255) //prevent buffer overflow - A = 65 & 128; - else -// Is next phoneme a vowel or ER? - A = flags[A] & 128; - if (debug) if (A != 0) printf("RULE: Soften T or D following vowel or ER and preceding a pause -> DX\n"); - if (A != 0) phonemeindex[pos] = 30; // 'DX' - } - - pos++; - - } // while -} - - + + // DEBUG: Print phoneme and index + if (debug && A != 255) printf("%d: %c%c\n", X, signInputTable1[A], signInputTable2[A]); + + if (A == 0) { // Is phoneme pause? + ++pos; + continue; + } + + if (A == 255) return; + + unsigned char Y = A; // Copy the current phoneme index to Y + + // RULE: + // -> WX + // -> YX + // Example: OIL, COW + + // Check for DIPTHONG + if ((flags[A] & 16) != 0) { // Not a dipthong. + A = flags[Y] & 32; // End in IY sound? + + // If ends with IY, use YX, else use WX + if (A == 0) A = 20; else A = 21; // 'WX' = 20 'YX' = 21 + + // Insert at WX or YX following, copying the stress + + if (debug) if (A==20) printf("RULE: insert WX following dipthong NOT ending in IY sound\n"); + if (debug) if (A==21) printf("RULE: insert YX following dipthong ending in IY sound\n"); + Insert(pos+1, A, mem59, stress[pos]); + X = pos; + + goto pos41749; + } + + // RULE: + // UL -> AX L + // Example: MEDDLE + + A = phonemeindex[X]; + + if (A == 78) { // 'UL' + if (debug) printf("RULE: UL -> AX L\n"); + phonemeindex[X] = 13; // 'AX' + Insert(X+1, 24, mem59, stress[X]); + pos++; + continue; + } + + // RULE: + // UM -> AX M + // Example: ASTRONOMY + if (A == 79) { // 'UM' + if (debug) printf("RULE: UM -> AX M\n"); + phonemeindex[X] = 13; // 'AX' + Insert(X+1, 27, mem59, stress[X]); + pos++; + continue; + } + + // RULE: + // UN -> AX N + // Example: FUNCTION + if (A == 80) { // 'UN' + if (debug) printf("RULE: UN -> AX N\n"); + phonemeindex[X] = 13; // AX + // Perform insert. Note code below may jump up here with different values + Insert(X+1, 28, mem59, stress[X]); + pos++; + continue; + } + + // RULE: + // -> Q + // EXAMPLE: AWAY EIGHT + Y = A; + A = flags[A] & 128; // VOWEL set? + // Skip if not a vowel + if (A != 0) { + A = stress[X]; + if (A != 0) { // If stressed... + A = phonemeindex[++X]; + if (A == 0) { // If following phoneme is a pause, get next + Y = phonemeindex[++X]; + // Check for end of buffer flag + if (Y == 255) { //buffer overflow + // ??? Not sure about these flags + A = 65&128; + } else { + // And VOWEL flag to current phoneme's flags + A = flags[Y] & 128; + } + + // If following phonemes is not a pause + if (A != 0) { + // If the following phoneme is not stressed + A = stress[X]; + if (A != 0) { + // Insert a glottal stop and move forward + if (debug) printf("RULE: Insert glottal stop between two stressed vowels with space between them\n"); + Insert(X, 31, mem59, 0); // 31 = 'Q' + pos++; + continue; + } + } + } + } + } + + // RULES FOR PHONEMES BEFORE R + // T R -> CH R + // Example: TRACK + + // Get current position and phoneme + X = pos; + A = phonemeindex[pos]; + if (A == 23) { // 'R' + // Look at prior phoneme + X--; + A = phonemeindex[pos-1]; + + if (A == 69) { // 'T' + if (debug) printf("RULE: T R -> CH R\n"); + phonemeindex[pos-1] = 42; + goto pos41779; + } + + // RULES FOR PHONEMES BEFORE R + // D R -> J R + // Example: DRY + if (A == 57) { // 'D' + if (debug) printf("RULE: D R -> J R\n"); + phonemeindex[pos-1] = 44; + goto pos41788; + } + + // RULES FOR PHONEMES BEFORE R + // R -> RX + // Example: ART + + // If vowel flag is set change R to RX + A = flags[A] & 128; + if (A != 0) { + if (debug) printf("RULE: R -> RX\n"); + phonemeindex[pos] = 18; // 'RX' + } + + // continue to next phoneme + pos++; + continue; + } + + // RULE: + // L -> LX + // Example: ALL + // Is phoneme L? + if (A == 24) { // 'L' + // If prior phoneme does not have VOWEL flag set, move to next phoneme + if ((flags[phonemeindex[pos-1]] & 128) == 0) {pos++; continue;} + // Prior phoneme has VOWEL flag set, so change L to LX and move to next phoneme + if (debug) printf("RULE: L -> LX\n"); + phonemeindex[X] = 19; // 'LX' + pos++; + continue; + } + + // RULE: + // G S -> G Z + // + // Can't get to fire - + // 1. The G -> GX rule intervenes + // 2. Reciter already replaces GS -> GZ + + if (A == 32) { // 'S' + // If prior phoneme is not G, move to next phoneme + if (phonemeindex[pos-1] != 60) {pos++; continue;} + // Replace S with Z and move on + if (debug) printf("RULE: G S -> G Z\n"); + phonemeindex[pos] = 38; // 'Z' + pos++; + continue; + } + + // RULE: + // K -> KX + // Example: COW + + if (A == 72) { // 'K' + // Get next phoneme + Y = phonemeindex[pos+1]; + // If at end, replace current phoneme with KX + if (Y == 255) phonemeindex[pos] = 75; // ML : prevents an index out of bounds problem + else { + // VOWELS AND DIPTHONGS ENDING WITH IY SOUND flag set? + A = flags[Y] & 32; + if (debug) if (A==0) printf("RULE: K -> KX \n"); + // Replace with KX + if (A == 0) phonemeindex[pos] = 75; // 'KX' + } + } + else + + // RULE: + // G -> GX + // Example: GO + + // Is character a G? + if (A == 60) { // 'G' + // Get the following character + unsigned char index = phonemeindex[pos+1]; + + if (index == 255) { pos++; continue; } + else + // If dipthong ending with YX, move continue processing next phoneme + if ((flags[index] & 32) != 0) {pos++; continue;} + // replace G with GX and continue processing next phoneme + if (debug) printf("RULE: G -> GX \n"); + phonemeindex[pos] = 63; // 'GX' + pos++; + continue; + } + + // RULE: + // S P -> S B + // S T -> S D + // S K -> S G + // S KX -> S GX + // Examples: SPY, STY, SKY, SCOWL + + Y = phonemeindex[pos]; + // Replace with softer version? + A = flags[Y] & 1; + if (A) { + A = phonemeindex[pos-1]; + if (A != 32) { // 'S' + A = Y; + goto pos41812; + } + // Replace with softer version + if (debug) printf("RULE: S* %c%c -> S* %c%c\n", signInputTable1[Y], signInputTable2[Y],signInputTable1[Y-12], signInputTable2[Y-12]); + phonemeindex[pos] = Y-12; + pos++; + continue; + } + +pos41749: + // RULE: + // UW -> UX + // + // Example: NEW, DEW, SUE, ZOO, THOO, TOO + A = phonemeindex[X]; + if (A == 53) { // 'UW' + // ALVEOLAR flag set? + A = flags2[phonemeindex[X-1]] & 4; + if (A) { + if (debug) printf("RULE: UW -> UX\n"); + phonemeindex[X] = 16; + } + ++pos; + continue; + } + + pos41779: + // RULE: + // CH -> CH CH' (CH requires two phonemes to represent it) + // Example: CHEW + if (A == 42) { // 'CH' + if (debug) printf("CH -> CH CH+1\n"); + Insert(X+1, A+1, mem59, stress[X]); + pos++; + continue; + } + + pos41788: + // RULE: + // J -> J J' (J requires two phonemes to represent it) + // Example: JAY + if (A == 44) { // 'J' + if (debug) printf("J -> J J+1\n"); + Insert(X+1, A+1, mem59, stress[X]); + pos++; + continue; + } + + // Jump here to continue + pos41812: + // RULE: Soften T following vowel + // NOTE: This rule fails for cases such as "ODD" + // T -> DX + // D -> DX + // Example: PARTY, TARDY + + // Past this point, only process if phoneme is T or D + if (A != 69) // 'T' + if (A != 57) {pos++; continue;} // 'D' + + // If prior phoneme is not a vowel, continue processing phonemes + if ((flags[phonemeindex[X-1]] & 128) == 0) {pos++; continue;} + + A = phonemeindex[++X]; + if (A != 0) { + // If next phoneme is not a pause, continue processing phonemes + if ((flags[A] & 128) == 0) {pos++; continue;} + // If next phoneme is stressed, continue processing phonemes + // FIXME: How does a pause get stressed? + if (stress[X] != 0) {pos++; continue;} + + // Set phonemes to DX + if (debug) printf("RULE: Soften T or D following vowel or ER and preceding a pause -> DX\n"); + phonemeindex[pos] = 30; // 'DX' + } else { + A = phonemeindex[X+1]; + if (A == 255) //prevent buffer overflow + A = 65 & 128; + else + // Is next phoneme a vowel or ER? + A = flags[A] & 128; + if (debug) if (A != 0) printf("RULE: Soften T or D following vowel or ER and preceding a pause -> DX\n"); + if (A != 0) phonemeindex[pos] = 30; // 'DX' + } + pos++; + } // while +} + + // Applies various rules that adjust the lengths of phonemes // // Lengthen or between and by 1.5 From 94f7d01a7f593517ddd9cba48b3173f8d5158e32 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Tue, 24 Jan 2017 01:29:26 +0000 Subject: [PATCH 073/109] Refactoring --- src/sam.c | 141 ++++++++++++++++++++++++------------------------------ 1 file changed, 62 insertions(+), 79 deletions(-) diff --git a/src/sam.c b/src/sam.c index ef1db525..95edf666 100644 --- a/src/sam.c +++ b/src/sam.c @@ -496,6 +496,15 @@ void Code41240() { } } + +void ChangeRule(unsigned char position, unsigned char rule,unsigned char mem60, unsigned char mem59, unsigned char stress, const char * descr) +{ + if (debug) printf("RULE: %s\n",descr); + phonemeindex[position] = rule; + Insert(position+1, mem60, mem59, stress); +} + + // Rewrites the phonemes using the following rules: // // -> WX @@ -564,40 +573,26 @@ void Parser2() { goto pos41749; } - // RULE: - // UL -> AX L - // Example: MEDDLE - A = phonemeindex[X]; + // RULE: UL -> AX L -- Example: MEDDLE if (A == 78) { // 'UL' - if (debug) printf("RULE: UL -> AX L\n"); - phonemeindex[X] = 13; // 'AX' - Insert(X+1, 24, mem59, stress[X]); - pos++; + ChangeRule(X, 13, 24, mem59, stress[X],"UL -> AX L"); + ++pos; continue; } - // RULE: - // UM -> AX M - // Example: ASTRONOMY + // RULE: UM -> AX M -- Example: ASTRONOMY if (A == 79) { // 'UM' - if (debug) printf("RULE: UM -> AX M\n"); - phonemeindex[X] = 13; // 'AX' - Insert(X+1, 27, mem59, stress[X]); - pos++; + ChangeRule(X, 13, 27, mem59, stress[X], "UM -> AX M"); + ++pos; continue; } - // RULE: - // UN -> AX N - // Example: FUNCTION + // RULE: UN -> AX N -- Example: FUNCTION if (A == 80) { // 'UN' - if (debug) printf("RULE: UN -> AX N\n"); - phonemeindex[X] = 13; // AX - // Perform insert. Note code below may jump up here with different values - Insert(X+1, 28, mem59, stress[X]); - pos++; + ChangeRule(X, 13, 28, mem59, stress[X], "UN -> AX N"); + ++pos; continue; } @@ -605,38 +600,33 @@ void Parser2() { // -> Q // EXAMPLE: AWAY EIGHT Y = A; - A = flags[A] & 128; // VOWEL set? - // Skip if not a vowel - if (A != 0) { - A = stress[X]; - if (A != 0) { // If stressed... - A = phonemeindex[++X]; - if (A == 0) { // If following phoneme is a pause, get next - Y = phonemeindex[++X]; - // Check for end of buffer flag - if (Y == 255) { //buffer overflow - // ??? Not sure about these flags - A = 65&128; - } else { - // And VOWEL flag to current phoneme's flags - A = flags[Y] & 128; + if ((flags[A] & 128) && stress[X]) { // VOWEL && stressed + A = phonemeindex[++X]; + if (A == 0) { // If following phoneme is a pause, get next + Y = phonemeindex[++X]; + // Check for end of buffer flag + if (Y == 255) { //buffer overflow + // ??? Not sure about these flags + A = 65&128; + } else { + // And VOWEL flag to current phoneme's flags + A = flags[Y] & 128; + } + + // If following phonemes is not a pause + if (A != 0) { + // If the following phoneme is not stressed + A = stress[X]; + if (A != 0) { + // Insert a glottal stop and move forward + if (debug) printf("RULE: Insert glottal stop between two stressed vowels with space between them\n"); + Insert(X, 31, mem59, 0); // 31 = 'Q' + pos++; + continue; } - - // If following phonemes is not a pause - if (A != 0) { - // If the following phoneme is not stressed - A = stress[X]; - if (A != 0) { - // Insert a glottal stop and move forward - if (debug) printf("RULE: Insert glottal stop between two stressed vowels with space between them\n"); - Insert(X, 31, mem59, 0); // 31 = 'Q' - pos++; - continue; - } - } - } - } - } + } + } + } // RULES FOR PHONEMES BEFORE R // T R -> CH R @@ -670,13 +660,11 @@ void Parser2() { // Example: ART // If vowel flag is set change R to RX - A = flags[A] & 128; - if (A != 0) { + if (flags[A] & 128) { if (debug) printf("RULE: R -> RX\n"); phonemeindex[pos] = 18; // 'RX' } - // continue to next phoneme pos++; continue; } @@ -717,7 +705,6 @@ void Parser2() { // Example: COW if (A == 72) { // 'K' - // Get next phoneme Y = phonemeindex[pos+1]; // If at end, replace current phoneme with KX if (Y == 255) phonemeindex[pos] = 75; // ML : prevents an index out of bounds problem @@ -774,7 +761,7 @@ void Parser2() { continue; } -pos41749: + pos41749: // RULE: // UW -> UX // @@ -854,26 +841,22 @@ void Parser2() { } -// Applies various rules that adjust the lengths of phonemes -// -// Lengthen or between and by 1.5 -// - decrease length by 1 -// - decrease vowel by 1/8th -// - increase vowel by 1/2 + 1 -// - set nasal = 5, consonant = 6 -// {optional silence} - shorten both to 1/2 + 1 -// - decrease by 2 - - -//void Code48619() -void AdjustLengths() -{ - - // LENGTHEN VOWELS PRECEDING PUNCTUATION - // - // Search for punctuation. If found, back up to the first vowel, then - // process all phonemes between there and up to (but not including) the punctuation. - // If any phoneme is found that is a either a fricative or voiced, the duration is +// Applies various rules that adjust the lengths of phonemes +// +// Lengthen or between and by 1.5 +// - decrease length by 1 +// - decrease vowel by 1/8th +// - increase vowel by 1/2 + 1 +// - set nasal = 5, consonant = 6 +// {optional silence} - shorten both to 1/2 + 1 +// - decrease by 2 + +void AdjustLengths() { + // LENGTHEN VOWELS PRECEDING PUNCTUATION + // + // Search for punctuation. If found, back up to the first vowel, then + // process all phonemes between there and up to (but not including) the punctuation. + // If any phoneme is found that is a either a fricative or voiced, the duration is // increased by (length * 1.5) + 1 // loop index From af3f0412befacf07a3cde153eb5746f0d56ff8ae Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Tue, 24 Jan 2017 01:40:06 +0000 Subject: [PATCH 074/109] Refactoring --- src/sam.c | 220 ++++++++++++++++++++++-------------------------------- 1 file changed, 88 insertions(+), 132 deletions(-) diff --git a/src/sam.c b/src/sam.c index 95edf666..a20040c7 100644 --- a/src/sam.c +++ b/src/sam.c @@ -857,146 +857,102 @@ void AdjustLengths() { // Search for punctuation. If found, back up to the first vowel, then // process all phonemes between there and up to (but not including) the punctuation. // If any phoneme is found that is a either a fricative or voiced, the duration is - // increased by (length * 1.5) + 1 - - // loop index - X = 0; - unsigned char index; - - // iterate through the phoneme list - unsigned char loopIndex=0; - while(1) - { - // get a phoneme - index = phonemeindex[X]; - - // exit loop if end on buffer token - if (index == 255) break; - - // not punctuation? - if((flags2[index] & 1) == 0) - { - // skip - X++; - continue; - } - - // hold index - loopIndex = X; - - // Loop backwards from this point -pos48644: - - // back up one phoneme - X--; - - // stop once the beginning is reached - if(X == 0) break; - - // get the preceding phoneme - index = phonemeindex[X]; - - if (index != 255) //inserted to prevent access overrun - if((flags[index] & 128) == 0) goto pos48644; // if not a vowel, continue looping - - //pos48657: - do - { - // test for vowel - index = phonemeindex[X]; - - if (index != 255)//inserted to prevent access overrun + // increased by (length * 1.5) + 1 + + // loop index + unsigned char X = 0; + unsigned char index; + + // iterate through the phoneme list + unsigned char loopIndex=0; + while((index = phonemeindex[X]) != 255) { + // not punctuation? + if((flags2[index] & 1) == 0) { // skip + ++X; + continue; + } + + // hold index + loopIndex = X; + + while (--X && !(flags[phonemeindex[X]] & 128)); // back up while not a vowel + if (X == 0) break; + + do { + // test for vowel + index = phonemeindex[X]; + + //if (index != 255)//inserted to prevent access overrun // test for fricative/unvoiced or not voiced if(((flags2[index] & 32) == 0) || ((flags[index] & 4) != 0)) //nochmal überprüfen - { - //A = flags[Y] & 4; - //if(A == 0) goto pos48688; - - // get the phoneme length + { unsigned char A = phonemeLength[X]; - - // change phoneme length to (length * 1.5) + 1 - A = (A >> 1) + A + 1; -if (debug) printf("RULE: Lengthen or between and by 1.5\n"); -if (debug) printf("PRE\n"); -if (debug) printf("phoneme %d (%c%c) length %d\n", X, signInputTable1[phonemeindex[X]], signInputTable2[phonemeindex[X]], phonemeLength[X]); - - phonemeLength[X] = A; - -if (debug) printf("POST\n"); -if (debug) printf("phoneme %d (%c%c) length %d\n", X, signInputTable1[phonemeindex[X]], signInputTable2[phonemeindex[X]], phonemeLength[X]); - - } - // keep moving forward - X++; - } while (X != loopIndex); - // if (X != loopIndex) goto pos48657; - X++; - } // while - + + // change phoneme length to (length * 1.5) + 1 + A = (A >> 1) + A + 1; + if (debug) printf("RULE: Lengthen or between and by 1.5\n"); + if (debug) printf("PRE\n"); + if (debug) printf("phoneme %d (%c%c) length %d\n", X, signInputTable1[phonemeindex[X]], signInputTable2[phonemeindex[X]], phonemeLength[X]); + + phonemeLength[X] = A; + + if (debug) printf("POST\n"); + if (debug) printf("phoneme %d (%c%c) length %d\n", X, signInputTable1[phonemeindex[X]], signInputTable2[phonemeindex[X]], phonemeLength[X]); + } + // keep moving forward + X++; + } while (X != loopIndex); + X++; + } // while + // Similar to the above routine, but shorten vowels under some circumstances // Loop throught all phonemes loopIndex = 0; - //pos48697 - - while(1) - { - // get a phoneme - X = loopIndex; - index = phonemeindex[X]; - - // exit routine at end token - if (index == 255) return; - - // vowel? - unsigned char A = flags[index] & 128; + + while(1) { + // get a phoneme + X = loopIndex; + index = phonemeindex[X]; + + // exit routine at end token + if (index == 255) return; + + // vowel? + unsigned char A = flags[index] & 128; unsigned char mem56; - if (A != 0) - { - // get next phoneme - X++; - index = phonemeindex[X]; - - // get flags - if (index == 255) - mem56 = 65; // use if end marker - else - mem56 = flags[index]; - - // not a consonant - if ((flags[index] & 64) == 0) - { - // RX or LX? - if ((index == 18) || (index == 19)) // 'RX' & 'LX' - { - // get the next phoneme - X++; - index = phonemeindex[X]; - - // next phoneme a consonant? - if ((flags[index] & 64) != 0) { - // RULE: RX | LX - - -if (debug) printf("RULE: - decrease length by 1\n"); -if (debug) printf("PRE\n"); -if (debug) printf("phoneme %d (%c%c) length %d\n", loopIndex, signInputTable1[phonemeindex[loopIndex]], signInputTable2[phonemeindex[loopIndex]], phonemeLength[loopIndex]); - - // decrease length of vowel by 1 frame - phonemeLength[loopIndex]--; - -if (debug) printf("POST\n"); -if (debug) printf("phoneme %d (%c%c) length %d\n", loopIndex, signInputTable1[phonemeindex[loopIndex]], signInputTable2[phonemeindex[loopIndex]], phonemeLength[loopIndex]); - - } - // move ahead - loopIndex++; - continue; - } - // move ahead - loopIndex++; - continue; + if (A != 0) { + index = phonemeindex[++X]; + // get flags + if (index == 255) + mem56 = 65; // use if end marker + else + mem56 = flags[index]; + + // not a consonant + if ((flags[index] & 64) == 0) { + // RX or LX? + if ((index == 18) || (index == 19)) { // 'RX' & 'LX' + index = phonemeindex[++X]; + + // next phoneme a consonant? + if ((flags[index] & 64) != 0) { + // RULE: RX | LX + + if (debug) printf("RULE: - decrease length by 1\n"); + if (debug) printf("PRE\n"); + if (debug) printf("phoneme %d (%c%c) length %d\n", loopIndex, signInputTable1[phonemeindex[loopIndex]], signInputTable2[phonemeindex[loopIndex]], phonemeLength[loopIndex]); + + // decrease length of vowel by 1 frame + phonemeLength[loopIndex]--; + + if (debug) printf("POST\n"); + if (debug) printf("phoneme %d (%c%c) length %d\n", loopIndex, signInputTable1[phonemeindex[loopIndex]], signInputTable2[phonemeindex[loopIndex]], phonemeLength[loopIndex]); + } + } + // move ahead + loopIndex++; + continue; } From efa8ebe9ef60960ab1516fed928e607eefc8a62a Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Tue, 24 Jan 2017 01:45:06 +0000 Subject: [PATCH 075/109] Refactoring --- src/sam.c | 172 ++++++++++++++++++++++++------------------------------ 1 file changed, 77 insertions(+), 95 deletions(-) diff --git a/src/sam.c b/src/sam.c index a20040c7..78161359 100644 --- a/src/sam.c +++ b/src/sam.c @@ -953,102 +953,84 @@ void AdjustLengths() { // move ahead loopIndex++; continue; - } - - - // Got here if not - - // not voiced - if ((mem56 & 4) == 0) - { - - // Unvoiced - // *, .*, ?*, ,*, -*, DX, S*, SH, F*, TH, /H, /X, CH, P*, T*, K*, KX - - // not an unvoiced plosive? - if((mem56 & 1) == 0) { - // move ahead - loopIndex++; - continue; - } - - // P*, T*, K*, KX - - - // RULE: - // - - // move back - X--; - -if (debug) printf("RULE: - decrease vowel by 1/8th\n"); -if (debug) printf("PRE\n"); -if (debug) printf("phoneme %d (%c%c) length %d\n", X, signInputTable1[phonemeindex[X]], signInputTable2[phonemeindex[X]], phonemeLength[X]); - - // decrease length by 1/8th - mem56 = phonemeLength[X] >> 3; - phonemeLength[X] -= mem56; - -if (debug) printf("POST\n"); -if (debug) printf("phoneme %d (%c%c) length %d\n", X, signInputTable1[phonemeindex[X]], signInputTable2[phonemeindex[X]], phonemeLength[X]); - - // move ahead - loopIndex++; - continue; - } - - // RULE: - // - -if (debug) printf("RULE: - increase vowel by 1/2 + 1\n"); -if (debug) printf("PRE\n"); -if (debug) printf("phoneme %d (%c%c) length %d\n", X-1, signInputTable1[phonemeindex[X-1]], signInputTable2[phonemeindex[X-1]], phonemeLength[X-1]); - - // decrease length - A = phonemeLength[X-1]; - phonemeLength[X-1] = (A >> 2) + A + 1; // 5/4*A + 1 - -if (debug) printf("POST\n"); -if (debug) printf("phoneme %d (%c%c) length %d\n", X-1, signInputTable1[phonemeindex[X-1]], signInputTable2[phonemeindex[X-1]], phonemeLength[X-1]); - - // move ahead - loopIndex++; - continue; - - } - - - // WH, R*, L*, W*, Y*, M*, N*, NX, Q*, Z*, ZH, V*, DH, J*, B*, D*, G*, GX - -//pos48821: - - // RULE: - // Set punctuation length to 6 - // Set stop consonant length to 5 - - // nasal? - if((flags2[index] & 8) != 0) - { - - // M*, N*, NX, - - // get the next phoneme - X++; - index = phonemeindex[X]; - - // end of buffer? - if (index == 255) + } + + + // Got here if not + + // not voiced + if ((mem56 & 4) == 0) { + // Unvoiced + // *, .*, ?*, ,*, -*, DX, S*, SH, F*, TH, /H, /X, CH, P*, T*, K*, KX + + // not an unvoiced plosive? + if((mem56 & 1) == 0) { + // move ahead + loopIndex++; + continue; + } + + // RULE: + // + + // move back + --X; + + if (debug) printf("RULE: - decrease vowel by 1/8th\n"); + if (debug) printf("PRE\n"); + if (debug) printf("phoneme %d (%c%c) length %d\n", X, signInputTable1[phonemeindex[X]], signInputTable2[phonemeindex[X]], phonemeLength[X]); + + // decrease length by 1/8th + mem56 = phonemeLength[X] >> 3; + phonemeLength[X] -= mem56; + + if (debug) printf("POST\n"); + if (debug) printf("phoneme %d (%c%c) length %d\n", X, signInputTable1[phonemeindex[X]], signInputTable2[phonemeindex[X]], phonemeLength[X]); + + loopIndex++; + continue; + } + + // RULE: + // + + if (debug) printf("RULE: - increase vowel by 1/2 + 1\n"); + if (debug) printf("PRE\n"); + if (debug) printf("phoneme %d (%c%c) length %d\n", X-1, signInputTable1[phonemeindex[X-1]], signInputTable2[phonemeindex[X-1]], phonemeLength[X-1]); + + // decrease length + A = phonemeLength[X-1]; + phonemeLength[X-1] = (A >> 2) + A + 1; // 5/4*A + 1 + + if (debug) printf("POST\n"); + if (debug) printf("phoneme %d (%c%c) length %d\n", X-1, signInputTable1[phonemeindex[X-1]], signInputTable2[phonemeindex[X-1]], phonemeLength[X-1]); + + loopIndex++; + continue; + } + + // WH, R*, L*, W*, Y*, M*, N*, NX, Q*, Z*, ZH, V*, DH, J*, B*, D*, G*, GX + + // RULE: + // Set punctuation length to 6 + // Set stop consonant length to 5 + + // nasal? + if((flags2[index] & 8) != 0) { + // M*, N*, NX, + + index = phonemeindex[++X]; + + // end of buffer? + if (index == 255) A = 65&2; //prevent buffer overflow - else - A = flags[index] & 2; // check for stop consonant - - - // is next phoneme a stop consonant? - if (A != 0) - - // B*, D*, G*, GX, P*, T*, K*, KX - - { + else + A = flags[index] & 2; // check for stop consonant + + // is next phoneme a stop consonant? + if (A != 0) { + // B*, D*, G*, GX, P*, T*, K*, KX + if (debug) printf("RULE: - set nasal = 5, consonant = 6\n"); if (debug) printf("POST\n"); if (debug) printf("phoneme %d (%c%c) length %d\n", X, signInputTable1[phonemeindex[X]], signInputTable2[phonemeindex[X]], phonemeLength[X]); From e40653464878e5b46c17a720bb32617f1ac6cd0a Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Tue, 24 Jan 2017 01:48:59 +0000 Subject: [PATCH 076/109] Refactoring --- src/sam.c | 156 ++++++++++++++++++++++++------------------------------ 1 file changed, 70 insertions(+), 86 deletions(-) diff --git a/src/sam.c b/src/sam.c index 78161359..a40c957f 100644 --- a/src/sam.c +++ b/src/sam.c @@ -1031,99 +1031,83 @@ void AdjustLengths() { if (A != 0) { // B*, D*, G*, GX, P*, T*, K*, KX -if (debug) printf("RULE: - set nasal = 5, consonant = 6\n"); -if (debug) printf("POST\n"); -if (debug) printf("phoneme %d (%c%c) length %d\n", X, signInputTable1[phonemeindex[X]], signInputTable2[phonemeindex[X]], phonemeLength[X]); -if (debug) printf("phoneme %d (%c%c) length %d\n", X-1, signInputTable1[phonemeindex[X-1]], signInputTable2[phonemeindex[X-1]], phonemeLength[X-1]); - - // set stop consonant length to 6 - phonemeLength[X] = 6; - - // set nasal length to 5 - phonemeLength[X-1] = 5; - -if (debug) printf("POST\n"); -if (debug) printf("phoneme %d (%c%c) length %d\n", X, signInputTable1[phonemeindex[X]], signInputTable2[phonemeindex[X]], phonemeLength[X]); -if (debug) printf("phoneme %d (%c%c) length %d\n", X-1, signInputTable1[phonemeindex[X-1]], signInputTable2[phonemeindex[X-1]], phonemeLength[X-1]); - - } - // move to next phoneme - loopIndex++; - continue; - } - - - // WH, R*, L*, W*, Y*, Q*, Z*, ZH, V*, DH, J*, B*, D*, G*, GX - - // RULE: {optional silence} - // Shorten both to (length/2 + 1) - - // (voiced) stop consonant? - if((flags[index] & 2) != 0) - { - // B*, D*, G*, GX - - // move past silence - do - { - // move ahead - X++; - index = phonemeindex[X]; - } while(index == 0); - - - // check for end of buffer - if (index == 255) //buffer overflow - { - // ignore, overflow code - if ((65 & 2) == 0) {loopIndex++; continue;} - } else if ((flags[index] & 2) == 0) { - // if another stop consonant, move ahead - loopIndex++; - continue; - } - + if (debug) printf("RULE: - set nasal = 5, consonant = 6\n"); + if (debug) printf("POST\n"); + if (debug) printf("phoneme %d (%c%c) length %d\n", X, signInputTable1[phonemeindex[X]], signInputTable2[phonemeindex[X]], phonemeLength[X]); + if (debug) printf("phoneme %d (%c%c) length %d\n", X-1, signInputTable1[phonemeindex[X-1]], signInputTable2[phonemeindex[X-1]], phonemeLength[X-1]); + + phonemeLength[X] = 6; // set stop consonant length to 6 + phonemeLength[X-1] = 5; // set nasal length to 5 + + if (debug) printf("POST\n"); + if (debug) printf("phoneme %d (%c%c) length %d\n", X, signInputTable1[phonemeindex[X]], signInputTable2[phonemeindex[X]], phonemeLength[X]); + if (debug) printf("phoneme %d (%c%c) length %d\n", X-1, signInputTable1[phonemeindex[X-1]], signInputTable2[phonemeindex[X-1]], phonemeLength[X-1]); + } + loopIndex++; + continue; + } + + // WH, R*, L*, W*, Y*, Q*, Z*, ZH, V*, DH, J*, B*, D*, G*, GX + + // RULE: {optional silence} + // Shorten both to (length/2 + 1) + + // (voiced) stop consonant? + if((flags[index] & 2) != 0) { + // B*, D*, G*, GX + + // move past silence + while ((index = phonemeindex[++X]) == 0); + + // check for end of buffer + if (index == 255) //buffer overflow + { + // ignore, overflow code + if ((65 & 2) == 0) {loopIndex++; continue;} + } else if ((flags[index] & 2) == 0) { + // if another stop consonant, move ahead + loopIndex++; + continue; + } + // RULE: {optional silence} -if (debug) printf("RULE: {optional silence} - shorten both to 1/2 + 1\n"); -if (debug) printf("PRE\n"); -if (debug) printf("phoneme %d (%c%c) length %d\n", X, signInputTable1[phonemeindex[X]], signInputTable2[phonemeindex[X]], phonemeLength[X]); -if (debug) printf("phoneme %d (%c%c) length %d\n", X-1, signInputTable1[phonemeindex[X-1]], signInputTable2[phonemeindex[X-1]], phonemeLength[X-1]); -// X gets overwritten, so hold prior X value for debug statement -int debugX = X; - // shorten the prior phoneme length to (length/2 + 1) - phonemeLength[X] = (phonemeLength[X] >> 1) + 1; - X = loopIndex; - - // also shorten this phoneme length to (length/2 +1) - phonemeLength[loopIndex] = (phonemeLength[loopIndex] >> 1) + 1; - -if (debug) printf("POST\n"); -if (debug) printf("phoneme %d (%c%c) length %d\n", debugX, signInputTable1[phonemeindex[debugX]], signInputTable2[phonemeindex[debugX]], phonemeLength[debugX]); -if (debug) printf("phoneme %d (%c%c) length %d\n", debugX-1, signInputTable1[phonemeindex[debugX-1]], signInputTable2[phonemeindex[debugX-1]], phonemeLength[debugX-1]); - - - // move ahead - loopIndex++; - continue; - } - - - // WH, R*, L*, W*, Y*, Q*, Z*, ZH, V*, DH, J*, **, - - // RULE: - // Decrease by 2 - - // liquic consonant? - if ((flags2[index] & 16) != 0) - { + if (debug) printf("RULE: {optional silence} - shorten both to 1/2 + 1\n"); + if (debug) printf("PRE\n"); + if (debug) printf("phoneme %d (%c%c) length %d\n", X, signInputTable1[phonemeindex[X]], signInputTable2[phonemeindex[X]], phonemeLength[X]); + if (debug) printf("phoneme %d (%c%c) length %d\n", X-1, signInputTable1[phonemeindex[X-1]], signInputTable2[phonemeindex[X-1]], phonemeLength[X-1]); + // X gets overwritten, so hold prior X value for debug statement + int debugX = X; + // shorten the prior phoneme length to (length/2 + 1) + phonemeLength[X] = (phonemeLength[X] >> 1) + 1; + X = loopIndex; + + // also shorten this phoneme length to (length/2 +1) + phonemeLength[loopIndex] = (phonemeLength[loopIndex] >> 1) + 1; + + if (debug) printf("POST\n"); + if (debug) printf("phoneme %d (%c%c) length %d\n", debugX, signInputTable1[phonemeindex[debugX]], signInputTable2[phonemeindex[debugX]], phonemeLength[debugX]); + if (debug) printf("phoneme %d (%c%c) length %d\n", debugX-1, signInputTable1[phonemeindex[debugX-1]], signInputTable2[phonemeindex[debugX-1]], phonemeLength[debugX-1]); + + loopIndex++; + continue; + } + // WH, R*, L*, W*, Y*, Q*, Z*, ZH, V*, DH, J*, **, + + // RULE: + // Decrease by 2 + + // liquic consonant? + if ((flags2[index] & 16) != 0) { // R*, L*, W*, Y* // get the prior phoneme index = phonemeindex[X-1]; + + // FIXME: The debug code here breaks the rule. // prior phoneme a stop consonant> - if((flags[index] & 2) != 0) - // Rule: + if((flags[index] & 2) != 0) + // Rule: if (debug) printf("RULE: - decrease by 2\n"); if (debug) printf("PRE\n"); From aeb0441543b58f4b8e6cdcd9c7ce5009aa7a7e13 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Tue, 24 Jan 2017 01:54:48 +0000 Subject: [PATCH 077/109] Refactoring --- src/sam.c | 42 +++++++++++++++++------------------------- 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/src/sam.c b/src/sam.c index a40c957f..ca5a9e66 100644 --- a/src/sam.c +++ b/src/sam.c @@ -841,6 +841,17 @@ void Parser2() { } +void drule_pre(const char *descr, unsigned char X) { + if (debug) printf("RULE: %s\n", descr); + if (debug) printf("PRE\n"); + if (debug) printf("phoneme %d (%c%c) length %d\n", X, signInputTable1[phonemeindex[X]], signInputTable2[phonemeindex[X]], phonemeLength[X]); +} + +void drule_post(unsigned char X) { + if (debug) printf("POST\n"); + if (debug) printf("phoneme %d (%c%c) length %d\n", X, signInputTable1[phonemeindex[X]], signInputTable2[phonemeindex[X]], phonemeLength[X]); +} + // Applies various rules that adjust the lengths of phonemes // // Lengthen or between and by 1.5 @@ -937,17 +948,9 @@ void AdjustLengths() { // next phoneme a consonant? if ((flags[index] & 64) != 0) { - // RULE: RX | LX - - if (debug) printf("RULE: - decrease length by 1\n"); - if (debug) printf("PRE\n"); - if (debug) printf("phoneme %d (%c%c) length %d\n", loopIndex, signInputTable1[phonemeindex[loopIndex]], signInputTable2[phonemeindex[loopIndex]], phonemeLength[loopIndex]); - - // decrease length of vowel by 1 frame + drule_pre(" - decrease length of vowel by 1\n", loopIndex); phonemeLength[loopIndex]--; - - if (debug) printf("POST\n"); - if (debug) printf("phoneme %d (%c%c) length %d\n", loopIndex, signInputTable1[phonemeindex[loopIndex]], signInputTable2[phonemeindex[loopIndex]], phonemeLength[loopIndex]); + drule_post(loopIndex); } } // move ahead @@ -976,16 +979,10 @@ void AdjustLengths() { // move back --X; - if (debug) printf("RULE: - decrease vowel by 1/8th\n"); - if (debug) printf("PRE\n"); - if (debug) printf("phoneme %d (%c%c) length %d\n", X, signInputTable1[phonemeindex[X]], signInputTable2[phonemeindex[X]], phonemeLength[X]); - - // decrease length by 1/8th + drule_pre(" - decrease vowel by 1/8th",X); mem56 = phonemeLength[X] >> 3; phonemeLength[X] -= mem56; - - if (debug) printf("POST\n"); - if (debug) printf("phoneme %d (%c%c) length %d\n", X, signInputTable1[phonemeindex[X]], signInputTable2[phonemeindex[X]], phonemeLength[X]); + drule_post(X); loopIndex++; continue; @@ -994,16 +991,11 @@ void AdjustLengths() { // RULE: // - if (debug) printf("RULE: - increase vowel by 1/2 + 1\n"); - if (debug) printf("PRE\n"); - if (debug) printf("phoneme %d (%c%c) length %d\n", X-1, signInputTable1[phonemeindex[X-1]], signInputTable2[phonemeindex[X-1]], phonemeLength[X-1]); - + drule_pre(" - increase vowel by 1/2 + 1\n",X-1); // decrease length A = phonemeLength[X-1]; phonemeLength[X-1] = (A >> 2) + A + 1; // 5/4*A + 1 - - if (debug) printf("POST\n"); - if (debug) printf("phoneme %d (%c%c) length %d\n", X-1, signInputTable1[phonemeindex[X-1]], signInputTable2[phonemeindex[X-1]], phonemeLength[X-1]); + drule_post(X); loopIndex++; continue; From 5073fa9e73c6a5f515f91664e0f4971ba460ebf2 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Tue, 24 Jan 2017 02:17:24 +0000 Subject: [PATCH 078/109] Refactoring --- src/sam.c | 121 ++++++++++++++++++++++++++---------------------------- 1 file changed, 58 insertions(+), 63 deletions(-) diff --git a/src/sam.c b/src/sam.c index ca5a9e66..327458d9 100644 --- a/src/sam.c +++ b/src/sam.c @@ -549,8 +549,6 @@ void Parser2() { if (A == 255) return; - unsigned char Y = A; // Copy the current phoneme index to Y - // RULE: // -> WX // -> YX @@ -558,7 +556,7 @@ void Parser2() { // Check for DIPTHONG if ((flags[A] & 16) != 0) { // Not a dipthong. - A = flags[Y] & 32; // End in IY sound? + A = flags[A] & 32; // End in IY sound? // If ends with IY, use YX, else use WX if (A == 0) A = 20; else A = 21; // 'WX' = 20 'YX' = 21 @@ -599,11 +597,11 @@ void Parser2() { // RULE: // -> Q // EXAMPLE: AWAY EIGHT - Y = A; + if ((flags[A] & 128) && stress[X]) { // VOWEL && stressed A = phonemeindex[++X]; if (A == 0) { // If following phoneme is a pause, get next - Y = phonemeindex[++X]; + unsigned char Y = phonemeindex[++X]; // Check for end of buffer flag if (Y == 255) { //buffer overflow // ??? Not sure about these flags @@ -635,12 +633,15 @@ void Parser2() { // Get current position and phoneme X = pos; A = phonemeindex[pos]; + + unsigned char prior = phonemeindex[pos-1]; + if (A == 23) { // 'R' // Look at prior phoneme X--; - A = phonemeindex[pos-1]; + A = prior; - if (A == 69) { // 'T' + if (prior == 69) { // 'T' if (debug) printf("RULE: T R -> CH R\n"); phonemeindex[pos-1] = 42; goto pos41779; @@ -649,7 +650,7 @@ void Parser2() { // RULES FOR PHONEMES BEFORE R // D R -> J R // Example: DRY - if (A == 57) { // 'D' + if (prior == 57) { // 'D' if (debug) printf("RULE: D R -> J R\n"); phonemeindex[pos-1] = 44; goto pos41788; @@ -660,25 +661,21 @@ void Parser2() { // Example: ART // If vowel flag is set change R to RX - if (flags[A] & 128) { + if (flags[prior] & 128) { if (debug) printf("RULE: R -> RX\n"); phonemeindex[pos] = 18; // 'RX' } - pos++; + ++pos; continue; } - // RULE: - // L -> LX - // Example: ALL - // Is phoneme L? + // RULE: L -> LX -- Example: ALL if (A == 24) { // 'L' - // If prior phoneme does not have VOWEL flag set, move to next phoneme - if ((flags[phonemeindex[pos-1]] & 128) == 0) {pos++; continue;} - // Prior phoneme has VOWEL flag set, so change L to LX and move to next phoneme - if (debug) printf("RULE: L -> LX\n"); - phonemeindex[X] = 19; // 'LX' + if (flags[prior] & 128) { // VOWEL flag set, so change L to LX + if (debug) printf("RULE: L -> LX\n"); + phonemeindex[X] = 19; // 'LX' + } pos++; continue; } @@ -691,11 +688,11 @@ void Parser2() { // 2. Reciter already replaces GS -> GZ if (A == 32) { // 'S' - // If prior phoneme is not G, move to next phoneme - if (phonemeindex[pos-1] != 60) {pos++; continue;} - // Replace S with Z and move on - if (debug) printf("RULE: G S -> G Z\n"); - phonemeindex[pos] = 38; // 'Z' + if (prior == 60) { // prior is G + // Replace S with Z and move on + if (debug) printf("RULE: G S -> G Z\n"); + phonemeindex[pos] = 38; // 'Z' + } pos++; continue; } @@ -705,7 +702,7 @@ void Parser2() { // Example: COW if (A == 72) { // 'K' - Y = phonemeindex[pos+1]; + unsigned char Y = phonemeindex[pos+1]; // If at end, replace current phoneme with KX if (Y == 255) phonemeindex[pos] = 75; // ML : prevents an index out of bounds problem else { @@ -717,7 +714,6 @@ void Parser2() { } } else - // RULE: // G -> GX // Example: GO @@ -745,20 +741,21 @@ void Parser2() { // S KX -> S GX // Examples: SPY, STY, SKY, SCOWL - Y = phonemeindex[pos]; + unsigned char Y = phonemeindex[pos]; // Replace with softer version? A = flags[Y] & 1; if (A) { - A = phonemeindex[pos-1]; - if (A != 32) { // 'S' + A = prior; + if (A == 32) { // 'S' + // Replace with softer version + if (debug) printf("RULE: S* %c%c -> S* %c%c\n", signInputTable1[Y], signInputTable2[Y],signInputTable1[Y-12], signInputTable2[Y-12]); + phonemeindex[pos] = Y-12; + pos++; + continue; + } else { A = Y; goto pos41812; } - // Replace with softer version - if (debug) printf("RULE: S* %c%c -> S* %c%c\n", signInputTable1[Y], signInputTable2[Y],signInputTable1[Y-12], signInputTable2[Y-12]); - phonemeindex[pos] = Y-12; - pos++; - continue; } pos41749: @@ -808,35 +805,33 @@ void Parser2() { // D -> DX // Example: PARTY, TARDY - // Past this point, only process if phoneme is T or D - if (A != 69) // 'T' - if (A != 57) {pos++; continue;} // 'D' - - // If prior phoneme is not a vowel, continue processing phonemes - if ((flags[phonemeindex[X-1]] & 128) == 0) {pos++; continue;} - - A = phonemeindex[++X]; - if (A != 0) { - // If next phoneme is not a pause, continue processing phonemes - if ((flags[A] & 128) == 0) {pos++; continue;} - // If next phoneme is stressed, continue processing phonemes - // FIXME: How does a pause get stressed? - if (stress[X] != 0) {pos++; continue;} - - // Set phonemes to DX - if (debug) printf("RULE: Soften T or D following vowel or ER and preceding a pause -> DX\n"); - phonemeindex[pos] = 30; // 'DX' - } else { - A = phonemeindex[X+1]; - if (A == 255) //prevent buffer overflow - A = 65 & 128; - else - // Is next phoneme a vowel or ER? - A = flags[A] & 128; - if (debug) if (A != 0) printf("RULE: Soften T or D following vowel or ER and preceding a pause -> DX\n"); - if (A != 0) phonemeindex[pos] = 30; // 'DX' - } - pos++; + if (A == 69 || A == 57) { // 'T', 'D' + + // If prior phoneme is not a vowel, continue processing phonemes + if (flags[phonemeindex[X-1]] & 128) { + if ((A = phonemeindex[++X])) { + if (flags[A] & 128) { // pause + // FIXME: How does a pause get stressed? + if (stress[X] == 0) { // unstressed + // Set phonemes to DX + if (debug) printf("RULE: Soften T or D following vowel or ER and preceding a pause -> DX\n"); + phonemeindex[pos] = 30; // 'DX' + } + } + } else { + A = phonemeindex[X+1]; + if (A == 255) //prevent buffer overflow + A = 65 & 128; + else + // Is next phoneme a vowel or ER? + if (flags[A] & 128) { + if (debug) printf("RULE: Soften T or D following vowel or ER and preceding a pause -> DX\n"); + if (A != 0) phonemeindex[pos] = 30; // 'DX' + } + } + } + } + pos++; } // while } From 51f5c8c450b4fcb0edf5e4815a887c1344dd7944 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Tue, 24 Jan 2017 04:54:31 +0000 Subject: [PATCH 079/109] Refactoring --- src/sam.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/sam.c b/src/sam.c index 327458d9..ba34abd3 100644 --- a/src/sam.c +++ b/src/sam.c @@ -713,26 +713,23 @@ void Parser2() { if (A == 0) phonemeindex[pos] = 75; // 'KX' } } - else + else if (A == 60) { // 'G' // RULE: // G -> GX // Example: GO - // Is character a G? - if (A == 60) { // 'G' - // Get the following character - unsigned char index = phonemeindex[pos+1]; - - if (index == 255) { pos++; continue; } - else - // If dipthong ending with YX, move continue processing next phoneme - if ((flags[index] & 32) != 0) {pos++; continue;} + // Get the following character + unsigned char index = phonemeindex[pos+1]; + + // If dipthong ending with YX, move continue processing next phoneme + if ((index != 255) && ((flags[index] & 32) == 0)) { // replace G with GX and continue processing next phoneme if (debug) printf("RULE: G -> GX \n"); phonemeindex[pos] = 63; // 'GX' - pos++; - continue; } + pos++; + continue; + } // RULE: // S P -> S B From dc3468d18568793861829226bdce6d05c65e747e Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Tue, 24 Jan 2017 05:22:57 +0000 Subject: [PATCH 080/109] Refactoring --- src/sam.c | 165 ++++++++++++++++++++++-------------------------------- 1 file changed, 67 insertions(+), 98 deletions(-) diff --git a/src/sam.c b/src/sam.c index ba34abd3..02c8e3f8 100644 --- a/src/sam.c +++ b/src/sam.c @@ -537,17 +537,20 @@ void Parser2() { // Loop through phonemes while(1) { X = pos; - unsigned char A = phonemeindex[pos]; + unsigned char p = phonemeindex[pos]; + unsigned char A = p; // DEBUG: Print phoneme and index - if (debug && A != 255) printf("%d: %c%c\n", X, signInputTable1[A], signInputTable2[A]); + if (debug && p != 255) printf("%d: %c%c\n", X, signInputTable1[p], signInputTable2[p]); - if (A == 0) { // Is phoneme pause? + if (p == 0) { // Is phoneme pause? ++pos; continue; } - if (A == 255) return; + if (p == 255) return; + + unsigned char pf = flags[p]; // RULE: // -> WX @@ -555,11 +558,9 @@ void Parser2() { // Example: OIL, COW // Check for DIPTHONG - if ((flags[A] & 16) != 0) { // Not a dipthong. - A = flags[A] & 32; // End in IY sound? - + if ((pf & 16) != 0) { // Not a dipthong. // If ends with IY, use YX, else use WX - if (A == 0) A = 20; else A = 21; // 'WX' = 20 'YX' = 21 + A = (pf & 32) ? 21 : 20; // 'WX' = 20 'YX' = 21 // Insert at WX or YX following, copying the stress @@ -571,25 +572,10 @@ void Parser2() { goto pos41749; } - A = phonemeindex[X]; - - // RULE: UL -> AX L -- Example: MEDDLE - if (A == 78) { // 'UL' - ChangeRule(X, 13, 24, mem59, stress[X],"UL -> AX L"); - ++pos; - continue; - } - - // RULE: UM -> AX M -- Example: ASTRONOMY - if (A == 79) { // 'UM' - ChangeRule(X, 13, 27, mem59, stress[X], "UM -> AX M"); - ++pos; - continue; - } - - // RULE: UN -> AX N -- Example: FUNCTION - if (A == 80) { // 'UN' - ChangeRule(X, 13, 28, mem59, stress[X], "UN -> AX N"); + if (p == 78 || p == 79 || p == 80) { + if (p == 78) ChangeRule(X, 13, 24, mem59, stress[X],"UL -> AX L"); // Example: MEDDLE + else if (p == 79) ChangeRule(X, 13, 27, mem59, stress[X], "UM -> AX M"); // Example: ASTRONOMY + else if (p == 80) ChangeRule(X, 13, 28, mem59, stress[X], "UN -> AX N"); // Example: FUNCTION ++pos; continue; } @@ -598,7 +584,7 @@ void Parser2() { // -> Q // EXAMPLE: AWAY EIGHT - if ((flags[A] & 128) && stress[X]) { // VOWEL && stressed + if ((pf & 128) && stress[X]) { // VOWEL && stressed A = phonemeindex[++X]; if (A == 0) { // If following phoneme is a pause, get next unsigned char Y = phonemeindex[++X]; @@ -626,43 +612,35 @@ void Parser2() { } } - // RULES FOR PHONEMES BEFORE R - // T R -> CH R - // Example: TRACK - // Get current position and phoneme X = pos; - A = phonemeindex[pos]; + A = p; unsigned char prior = phonemeindex[pos-1]; - if (A == 23) { // 'R' + if (p == 23) { // 'R' + // RULES FOR PHONEMES BEFORE R // Look at prior phoneme X--; A = prior; - + + // Example: TRACK if (prior == 69) { // 'T' - if (debug) printf("RULE: T R -> CH R\n"); + drule("T R -> CH R"); phonemeindex[pos-1] = 42; goto pos41779; } - // RULES FOR PHONEMES BEFORE R - // D R -> J R // Example: DRY if (prior == 57) { // 'D' - if (debug) printf("RULE: D R -> J R\n"); + drule("D R -> J R"); phonemeindex[pos-1] = 44; goto pos41788; } - // RULES FOR PHONEMES BEFORE R - // R -> RX // Example: ART - - // If vowel flag is set change R to RX if (flags[prior] & 128) { - if (debug) printf("RULE: R -> RX\n"); + drule(" R -> RX"); phonemeindex[pos] = 18; // 'RX' } @@ -670,34 +648,41 @@ void Parser2() { continue; } - // RULE: L -> LX -- Example: ALL - if (A == 24) { // 'L' - if (flags[prior] & 128) { // VOWEL flag set, so change L to LX - if (debug) printf("RULE: L -> LX\n"); + if (p == 24 || p == 32 || A == 60) { + // Example: ALL + if (p == 24 && (flags[prior] & 128)) { // 'L' + prior has VOWEL flag set + drule(" L -> LX"); phonemeindex[X] = 19; // 'LX' } - pos++; - continue; - } - - // RULE: - // G S -> G Z - // - // Can't get to fire - - // 1. The G -> GX rule intervenes - // 2. Reciter already replaces GS -> GZ - - if (A == 32) { // 'S' - if (prior == 60) { // prior is G - // Replace S with Z and move on - if (debug) printf("RULE: G S -> G Z\n"); + + // G S -> G Z + // Can't get to fire - + // 1. The G -> GX rule intervenes + // 2. Reciter already replaces GS -> GZ + if (prior == 60 && p == 32) { // 'G' 'S' + drule("G S -> G Z"); phonemeindex[pos] = 38; // 'Z' } - pos++; - continue; + + if (p == 60) { // 'G' + // G -> GX + // Example: GO + + unsigned char index = phonemeindex[pos+1]; + + // If dipthong ending with YX, move continue processing next phoneme + if ((index != 255) && ((flags[index] & 32) == 0)) { + // replace G with GX and continue processing next phoneme + if (debug) printf("RULE: G -> GX \n"); + phonemeindex[pos] = 63; // 'GX' + } + } + + pos++; + continue; } + - // RULE: // K -> KX // Example: COW @@ -713,23 +698,6 @@ void Parser2() { if (A == 0) phonemeindex[pos] = 75; // 'KX' } } - else if (A == 60) { // 'G' - // RULE: - // G -> GX - // Example: GO - - // Get the following character - unsigned char index = phonemeindex[pos+1]; - - // If dipthong ending with YX, move continue processing next phoneme - if ((index != 255) && ((flags[index] & 32) == 0)) { - // replace G with GX and continue processing next phoneme - if (debug) printf("RULE: G -> GX \n"); - phonemeindex[pos] = 63; // 'GX' - } - pos++; - continue; - } // RULE: // S P -> S B @@ -740,19 +708,17 @@ void Parser2() { unsigned char Y = phonemeindex[pos]; // Replace with softer version? - A = flags[Y] & 1; - if (A) { - A = prior; - if (A == 32) { // 'S' - // Replace with softer version - if (debug) printf("RULE: S* %c%c -> S* %c%c\n", signInputTable1[Y], signInputTable2[Y],signInputTable1[Y-12], signInputTable2[Y-12]); - phonemeindex[pos] = Y-12; - pos++; - continue; - } else { - A = Y; - goto pos41812; - } + if ((flags[Y] & 1) && (prior == 32)) { // 'S' + // Replace with softer version + if (debug) printf("RULE: S* %c%c -> S* %c%c\n", signInputTable1[Y], signInputTable2[Y],signInputTable1[Y-12], signInputTable2[Y-12]); + phonemeindex[pos] = Y-12; + pos++; + continue; + } + + if ((flags[Y] & 1)) { + A = Y; + goto pos41812; } pos41749: @@ -778,7 +744,7 @@ void Parser2() { // Example: CHEW if (A == 42) { // 'CH' if (debug) printf("CH -> CH CH+1\n"); - Insert(X+1, A+1, mem59, stress[X]); + Insert(X+1, 43, mem59, stress[X]); pos++; continue; } @@ -789,7 +755,7 @@ void Parser2() { // Example: JAY if (A == 44) { // 'J' if (debug) printf("J -> J J+1\n"); - Insert(X+1, A+1, mem59, stress[X]); + Insert(X+1, 45, mem59, stress[X]); pos++; continue; } @@ -832,6 +798,9 @@ void Parser2() { } // while } +void drule(const char * str) { + if (debug) printf("RULE: %s\n",str); +} void drule_pre(const char *descr, unsigned char X) { if (debug) printf("RULE: %s\n", descr); From d60df886cd428e96350ffd4897e5b9c746bf01d9 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Tue, 24 Jan 2017 05:32:11 +0000 Subject: [PATCH 081/109] Refactoring --- src/sam.c | 60 +++++++++++++++++++++++++------------------------------ 1 file changed, 27 insertions(+), 33 deletions(-) diff --git a/src/sam.c b/src/sam.c index 02c8e3f8..45248ee2 100644 --- a/src/sam.c +++ b/src/sam.c @@ -563,9 +563,8 @@ void Parser2() { A = (pf & 32) ? 21 : 20; // 'WX' = 20 'YX' = 21 // Insert at WX or YX following, copying the stress - - if (debug) if (A==20) printf("RULE: insert WX following dipthong NOT ending in IY sound\n"); - if (debug) if (A==21) printf("RULE: insert YX following dipthong ending in IY sound\n"); + if (A==20) drule("insert WX following dipthong NOT ending in IY sound"); + if (A==21) drule("insert YX following dipthong ending in IY sound"); Insert(pos+1, A, mem59, stress[pos]); X = pos; @@ -585,8 +584,7 @@ void Parser2() { // EXAMPLE: AWAY EIGHT if ((pf & 128) && stress[X]) { // VOWEL && stressed - A = phonemeindex[++X]; - if (A == 0) { // If following phoneme is a pause, get next + if (!phonemeindex[++X]) { // If following phoneme is a pause, get next unsigned char Y = phonemeindex[++X]; // Check for end of buffer flag if (Y == 255) { //buffer overflow @@ -628,14 +626,14 @@ void Parser2() { if (prior == 69) { // 'T' drule("T R -> CH R"); phonemeindex[pos-1] = 42; - goto pos41779; + goto pos41812; } // Example: DRY if (prior == 57) { // 'D' drule("D R -> J R"); phonemeindex[pos-1] = 44; - goto pos41788; + goto pos41812; } // Example: ART @@ -727,35 +725,31 @@ void Parser2() { // // Example: NEW, DEW, SUE, ZOO, THOO, TOO A = phonemeindex[X]; - if (A == 53) { // 'UW' - // ALVEOLAR flag set? - A = flags2[phonemeindex[X-1]] & 4; - if (A) { - if (debug) printf("RULE: UW -> UX\n"); - phonemeindex[X] = 16; + if (A == 53 || A == 42 || A == 44) { + if (A == 53) { // 'UW' + // ALVEOLAR flag set? + A = flags2[phonemeindex[X-1]] & 4; + if (A) { + if (debug) printf("RULE: UW -> UX\n"); + phonemeindex[X] = 16; + } } - ++pos; - continue; - } - pos41779: - // RULE: - // CH -> CH CH' (CH requires two phonemes to represent it) - // Example: CHEW - if (A == 42) { // 'CH' - if (debug) printf("CH -> CH CH+1\n"); - Insert(X+1, 43, mem59, stress[X]); - pos++; - continue; - } + // RULE: + // CH -> CH CH' (CH requires two phonemes to represent it) + // Example: CHEW + if (A == 42) { // 'CH' + if (debug) printf("CH -> CH CH+1\n"); + Insert(X+1, 43, mem59, stress[X]); + } - pos41788: - // RULE: - // J -> J J' (J requires two phonemes to represent it) - // Example: JAY - if (A == 44) { // 'J' - if (debug) printf("J -> J J+1\n"); - Insert(X+1, 45, mem59, stress[X]); + // RULE: + // J -> J J' (J requires two phonemes to represent it) + // Example: JAY + if (A == 44) { // 'J' + if (debug) printf("J -> J J+1\n"); + Insert(X+1, 45, mem59, stress[X]); + } pos++; continue; } From 8ada5142e5c06809f00ef944b1fe7b1dcf519d41 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Tue, 24 Jan 2017 05:35:07 +0000 Subject: [PATCH 082/109] Refactoring --- src/sam.c | 48 ++++++++++++++++++++++-------------------------- 1 file changed, 22 insertions(+), 26 deletions(-) diff --git a/src/sam.c b/src/sam.c index 45248ee2..41802eb7 100644 --- a/src/sam.c +++ b/src/sam.c @@ -504,6 +504,21 @@ void ChangeRule(unsigned char position, unsigned char rule,unsigned char mem60, Insert(position+1, mem60, mem59, stress); } +void drule(const char * str) { + if (debug) printf("RULE: %s\n",str); +} + +void drule_pre(const char *descr, unsigned char X) { + if (debug) printf("RULE: %s\n", descr); + if (debug) printf("PRE\n"); + if (debug) printf("phoneme %d (%c%c) length %d\n", X, signInputTable1[phonemeindex[X]], signInputTable2[phonemeindex[X]], phonemeLength[X]); +} + +void drule_post(unsigned char X) { + if (debug) printf("POST\n"); + if (debug) printf("phoneme %d (%c%c) length %d\n", X, signInputTable1[phonemeindex[X]], signInputTable2[phonemeindex[X]], phonemeLength[X]); +} + // Rewrites the phonemes using the following rules: // @@ -595,17 +610,13 @@ void Parser2() { A = flags[Y] & 128; } - // If following phonemes is not a pause - if (A != 0) { - // If the following phoneme is not stressed - A = stress[X]; - if (A != 0) { - // Insert a glottal stop and move forward - if (debug) printf("RULE: Insert glottal stop between two stressed vowels with space between them\n"); - Insert(X, 31, mem59, 0); // 31 = 'Q' - pos++; - continue; - } + + if (A && stress[X]) { // If following phonemes is not a pause, and is not stressed + // Insert a glottal stop and move forward + if (debug) printf("RULE: Insert glottal stop between two stressed vowels with space between them\n"); + Insert(X, 31, mem59, 0); // 31 = 'Q' + pos++; + continue; } } } @@ -792,21 +803,6 @@ void Parser2() { } // while } -void drule(const char * str) { - if (debug) printf("RULE: %s\n",str); -} - -void drule_pre(const char *descr, unsigned char X) { - if (debug) printf("RULE: %s\n", descr); - if (debug) printf("PRE\n"); - if (debug) printf("phoneme %d (%c%c) length %d\n", X, signInputTable1[phonemeindex[X]], signInputTable2[phonemeindex[X]], phonemeLength[X]); -} - -void drule_post(unsigned char X) { - if (debug) printf("POST\n"); - if (debug) printf("phoneme %d (%c%c) length %d\n", X, signInputTable1[phonemeindex[X]], signInputTable2[phonemeindex[X]], phonemeLength[X]); -} - // Applies various rules that adjust the lengths of phonemes // // Lengthen or between and by 1.5 From 92e4bcd62c1e12a78ff8f63eaad4f99dc9783d4a Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sat, 28 Jan 2017 02:33:29 +0000 Subject: [PATCH 083/109] Refactoring --- src/sam.c | 190 +++++++++++++++++++++--------------------------------- 1 file changed, 75 insertions(+), 115 deletions(-) diff --git a/src/sam.c b/src/sam.c index 41802eb7..ee3e626f 100644 --- a/src/sam.c +++ b/src/sam.c @@ -509,7 +509,7 @@ void drule(const char * str) { } void drule_pre(const char *descr, unsigned char X) { - if (debug) printf("RULE: %s\n", descr); + drule(descr); if (debug) printf("PRE\n"); if (debug) printf("phoneme %d (%c%c) length %d\n", X, signInputTable1[phonemeindex[X]], signInputTable2[phonemeindex[X]], phonemeLength[X]); } @@ -555,16 +555,15 @@ void Parser2() { unsigned char p = phonemeindex[pos]; unsigned char A = p; - // DEBUG: Print phoneme and index - if (debug && p != 255) printf("%d: %c%c\n", X, signInputTable1[p], signInputTable2[p]); + if (p == 255) return; + + if (debug) printf("%d: %c%c\n", X, signInputTable1[p], signInputTable2[p]); if (p == 0) { // Is phoneme pause? ++pos; continue; } - if (p == 255) return; - unsigned char pf = flags[p]; // RULE: @@ -627,53 +626,43 @@ void Parser2() { unsigned char prior = phonemeindex[pos-1]; - if (p == 23) { // 'R' - // RULES FOR PHONEMES BEFORE R - // Look at prior phoneme - X--; - A = prior; - - // Example: TRACK - if (prior == 69) { // 'T' - drule("T R -> CH R"); - phonemeindex[pos-1] = 42; - goto pos41812; - } - - // Example: DRY - if (prior == 57) { // 'D' - drule("D R -> J R"); - phonemeindex[pos-1] = 44; - goto pos41812; - } - - // Example: ART - if (flags[prior] & 128) { - drule(" R -> RX"); - phonemeindex[pos] = 18; // 'RX' - } - - ++pos; - continue; - } + if (p == 23 || p == 24 || p == 32 || A == 60) { - if (p == 24 || p == 32 || A == 60) { - // Example: ALL - if (p == 24 && (flags[prior] & 128)) { // 'L' + prior has VOWEL flag set + if (p == 23) { // 'R' + // RULES FOR PHONEMES BEFORE R + // Look at prior phoneme + X--; + A = prior; + + if (prior == 69 || prior == 57) { + if (prior == 69) { // 'T' + // Example: TRACK + drule("T R -> CH R"); + phonemeindex[pos-1] = 42; + } else if (prior == 57) { // 'D' + // Example: DRY + drule("D R -> J R"); + phonemeindex[pos-1] = 44; + } + goto pos41812; + } + + // Example: ART + if (flags[prior] & 128) { + drule(" R -> RX"); + phonemeindex[pos] = 18; // 'RX' + } + } else if (p == 24 && (flags[prior] & 128)) { // 'L' + prior has VOWEL flag set + // Example: ALL drule(" L -> LX"); phonemeindex[X] = 19; // 'LX' - } - - // G S -> G Z - // Can't get to fire - - // 1. The G -> GX rule intervenes - // 2. Reciter already replaces GS -> GZ - if (prior == 60 && p == 32) { // 'G' 'S' + } else if (prior == 60 && p == 32) { // 'G' 'S' + // Can't get to fire - + // 1. The G -> GX rule intervenes + // 2. Reciter already replaces GS -> GZ drule("G S -> G Z"); phonemeindex[pos] = 38; // 'Z' - } - - if (p == 60) { // 'G' + } else if (p == 60) { // 'G' // G -> GX // Example: GO @@ -852,14 +841,9 @@ void AdjustLengths() { // change phoneme length to (length * 1.5) + 1 A = (A >> 1) + A + 1; - if (debug) printf("RULE: Lengthen or between and by 1.5\n"); - if (debug) printf("PRE\n"); - if (debug) printf("phoneme %d (%c%c) length %d\n", X, signInputTable1[phonemeindex[X]], signInputTable2[phonemeindex[X]], phonemeLength[X]); - + drule_pre("Lengthen or between and by 1.5",X); phonemeLength[X] = A; - - if (debug) printf("POST\n"); - if (debug) printf("phoneme %d (%c%c) length %d\n", X, signInputTable1[phonemeindex[X]], signInputTable2[phonemeindex[X]], phonemeLength[X]); + drule_post(X); } // keep moving forward X++; @@ -867,24 +851,19 @@ void AdjustLengths() { X++; } // while - // Similar to the above routine, but shorten vowels under some circumstances - - // Loop throught all phonemes - loopIndex = 0; + // Similar to the above routine, but shorten vowels under some circumstances - while(1) { - // get a phoneme - X = loopIndex; - index = phonemeindex[X]; - - // exit routine at end token - if (index == 255) return; + // Loop throught all phonemes + loopIndex = 0; + + while((index = phonemeindex[loopIndex]) != 255) { + unsigned char X = loopIndex; // vowel? unsigned char A = flags[index] & 128; unsigned char mem56; if (A != 0) { - index = phonemeindex[++X]; + index = phonemeindex[loopIndex+1]; // get flags if (index == 255) mem56 = 65; // use if end marker @@ -893,9 +872,8 @@ void AdjustLengths() { // not a consonant if ((flags[index] & 64) == 0) { - // RX or LX? - if ((index == 18) || (index == 19)) { // 'RX' & 'LX' - index = phonemeindex[++X]; + if ((index == 18) || (index == 19)) { // 'RX', 'LX' + index = phonemeindex[loopIndex+2]; // next phoneme a consonant? if ((flags[index] & 64) != 0) { @@ -917,38 +895,27 @@ void AdjustLengths() { // Unvoiced // *, .*, ?*, ,*, -*, DX, S*, SH, F*, TH, /H, /X, CH, P*, T*, K*, KX - // not an unvoiced plosive? - if((mem56 & 1) == 0) { - // move ahead - loopIndex++; - continue; + if((mem56 & 1)) { // unvoiced plosive + // RULE: + // + + drule_pre(" - decrease vowel by 1/8th",loopIndex); + mem56 = phonemeLength[loopIndex] >> 3; + phonemeLength[loopIndex] -= mem56; + drule_post(loopIndex); } + } else { + // RULE: + // + + drule_pre(" - increase vowel by 1/2 + 1\n",X-1); + // decrease length + A = phonemeLength[loopIndex]; + phonemeLength[loopIndex] = (A >> 2) + A + 1; // 5/4*A + 1 + drule_post(loopIndex); + } - // RULE: - // - - // move back - --X; - - drule_pre(" - decrease vowel by 1/8th",X); - mem56 = phonemeLength[X] >> 3; - phonemeLength[X] -= mem56; - drule_post(X); - - loopIndex++; - continue; - } - - // RULE: - // - - drule_pre(" - increase vowel by 1/2 + 1\n",X-1); - // decrease length - A = phonemeLength[X-1]; - phonemeLength[X-1] = (A >> 2) + A + 1; // 5/4*A + 1 - drule_post(X); - - loopIndex++; + ++loopIndex; continue; } @@ -966,7 +933,7 @@ void AdjustLengths() { // end of buffer? if (index == 255) - A = 65&2; //prevent buffer overflow + A = 65&2; //prevent buffer overflow else A = flags[index] & 2; // check for stop consonant @@ -974,8 +941,8 @@ void AdjustLengths() { if (A != 0) { // B*, D*, G*, GX, P*, T*, K*, KX - if (debug) printf("RULE: - set nasal = 5, consonant = 6\n"); - if (debug) printf("POST\n"); + drule(" - set nasal = 5, consonant = 6\n"); + if (debug) printf("PRE\n"); if (debug) printf("phoneme %d (%c%c) length %d\n", X, signInputTable1[phonemeindex[X]], signInputTable2[phonemeindex[X]], phonemeLength[X]); if (debug) printf("phoneme %d (%c%c) length %d\n", X-1, signInputTable1[phonemeindex[X-1]], signInputTable2[phonemeindex[X-1]], phonemeLength[X-1]); @@ -1003,9 +970,7 @@ void AdjustLengths() { while ((index = phonemeindex[++X]) == 0); // check for end of buffer - if (index == 255) //buffer overflow - { - // ignore, overflow code + if (index == 255) { if ((65 & 2) == 0) {loopIndex++; continue;} } else if ((flags[index] & 2) == 0) { // if another stop consonant, move ahead @@ -1046,21 +1011,16 @@ void AdjustLengths() { // get the prior phoneme index = phonemeindex[X-1]; - // FIXME: The debug code here breaks the rule. // prior phoneme a stop consonant> if((flags[index] & 2) != 0) // Rule: -if (debug) printf("RULE: - decrease by 2\n"); -if (debug) printf("PRE\n"); -if (debug) printf("phoneme %d (%c%c) length %d\n", X, signInputTable1[phonemeindex[X]], signInputTable2[phonemeindex[X]], phonemeLength[X]); - - // decrease the phoneme length by 2 frames (20 ms) - phonemeLength[X] -= 2; - -if (debug) printf("POST\n"); -if (debug) printf("phoneme %d (%c%c) length %d\n", X, signInputTable1[phonemeindex[X]], signInputTable2[phonemeindex[X]], phonemeLength[X]); + drule_pre(" - decrease by 2",X); + + // decrease the phoneme length by 2 frames (20 ms) + phonemeLength[X] -= 2; + drule_post(X); } // move to next phoneme From 0cb172c4a545d402b7f1a8fd3b0bd6b10cf11f93 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sat, 28 Jan 2017 02:49:35 +0000 Subject: [PATCH 084/109] Refactoring --- src/sam.c | 89 ++++++++++++++++++++++++------------------------------- 1 file changed, 39 insertions(+), 50 deletions(-) diff --git a/src/sam.c b/src/sam.c index ee3e626f..2389af23 100644 --- a/src/sam.c +++ b/src/sam.c @@ -70,7 +70,7 @@ void SetPhonemeLength(); void AdjustLengths(); void Code41240(); void Insert(unsigned char position, unsigned char mem60, unsigned char mem59, unsigned char mem58); -void InsertBreath(); +void InsertBreath(unsigned char mem59); void PrepareOutput(); void SetMouthThroat(unsigned char mouth, unsigned char throat); @@ -148,7 +148,7 @@ int SAMMain() { break; // error: delete all behind it } } while (++X != 0); - InsertBreath(); + InsertBreath(mem59); if (debug) PrintPhonemes(phonemeindex, phonemeLength, stress); @@ -157,71 +157,60 @@ int SAMMain() { } void PrepareOutput() { - unsigned char X = 0; // Position in source - unsigned char Y = 0; // Position in output + unsigned char srcpos = 0; // Position in source + unsigned char destpos = 0; // Position in output while(1) { - unsigned char A = phonemeindex[X]; - - phonemeIndexOutput[Y] = A; - - if (A == 255) { // End of input + unsigned char A = phonemeindex[srcpos]; + phonemeIndexOutput[destpos] = A; + switch(A) { + case 255: // End of input Render(); return; - } - - if (A == 254) { - ++X; - phonemeIndexOutput[Y] = 255; + case 254: // Break + phonemeIndexOutput[destpos] = 255; Render(); - Y = 0; - continue; - } - - if (A == 0) { - ++X; - continue; - } - - phonemeIndexOutput[Y] = A; - phonemeLengthOutput[Y] = phonemeLength[X]; - stressOutput[Y] = stress[X]; - ++X; - ++Y; + destpos = 0; + break; + case 0: + break; + default: + phonemeLengthOutput[destpos] = phonemeLength[srcpos]; + stressOutput[destpos] = stress[srcpos]; + ++destpos; + } + ++srcpos; } } -void InsertBreath() { +void InsertBreath(unsigned char mem59) { unsigned char mem54 = 255; - unsigned char mem55 = 0; + unsigned char len = 0; unsigned char index; //variable Y unsigned char pos = 0; while((index = phonemeindex[pos]) != 255) { - mem55 += phonemeLength[pos]; - - if (mem55 < 232) { - if (index != 254) { // ML : Prevents an index out of bounds problem - if((flags2[index]&1) != 0) { - mem55 = 0; - Insert(pos+1, 254, mem59, 0); - pos += 2; - continue; - } + len += phonemeLength[pos]; + if (len < 232) { + if (index != 254 && + (flags2[index]&1) != 0) { + len = 0; + Insert(pos+1, 254, mem59, 0); + pos += 2; + continue; } if (index == 0) mem54 = pos; - ++pos; - continue; - } - - phonemeindex[mem54] = 31; // 'Q*' glottal stop - phonemeLength[mem54] = 4; - stress[mem54] = 0; - mem55 = 0; - Insert(mem54+1, 254, mem59, 0); - pos = mem54+2; + } else { + pos = mem54; + phonemeindex[pos] = 31; // 'Q*' glottal stop + phonemeLength[pos] = 4; + stress[pos] = 0; + len = 0; + Insert(++pos, 254, mem59, 0); + } + ++pos; } } From 98c5986aa73a3b9a022f626c08a47555f66e9fa8 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sat, 28 Jan 2017 03:27:17 +0000 Subject: [PATCH 085/109] Refactoring --- src/sam.c | 95 ++++++++++++++++++------------------------------------- 1 file changed, 30 insertions(+), 65 deletions(-) diff --git a/src/sam.c b/src/sam.c index 2389af23..c7b34cad 100644 --- a/src/sam.c +++ b/src/sam.c @@ -849,15 +849,8 @@ void AdjustLengths() { unsigned char X = loopIndex; // vowel? - unsigned char A = flags[index] & 128; - unsigned char mem56; - if (A != 0) { + if (flags[index] & 128) { index = phonemeindex[loopIndex+1]; - // get flags - if (index == 255) - mem56 = 65; // use if end marker - else - mem56 = flags[index]; // not a consonant if ((flags[index] & 64) == 0) { @@ -871,41 +864,31 @@ void AdjustLengths() { drule_post(loopIndex); } } - // move ahead - loopIndex++; - continue; - } - - - // Got here if not - - // not voiced - if ((mem56 & 4) == 0) { - // Unvoiced - // *, .*, ?*, ,*, -*, DX, S*, SH, F*, TH, /H, /X, CH, P*, T*, K*, KX - - if((mem56 & 1)) { // unvoiced plosive - // RULE: - // - - drule_pre(" - decrease vowel by 1/8th",loopIndex); - mem56 = phonemeLength[loopIndex] >> 3; - phonemeLength[loopIndex] -= mem56; + } else { + // Got here if not + + unsigned char flag = (index == 255) ? 65 : flags[index]; // 65 if end marker + + if (!(flag & 4)) { // Unvoiced + // *, .*, ?*, ,*, -*, DX, S*, SH, F*, TH, /H, /X, CH, P*, T*, K*, KX + if((flag & 1)) { // unvoiced plosive + // RULE: + // + drule_pre(" - decrease vowel by 1/8th",loopIndex); + phonemeLength[loopIndex] -= (phonemeLength[loopIndex] >> 3); + drule_post(loopIndex); + } + } else { + // RULE: + // + + drule_pre(" - increase vowel by 1/2 + 1\n",X-1); + // decrease length + unsigned char A = phonemeLength[loopIndex]; + phonemeLength[loopIndex] = (A >> 2) + A + 1; // 5/4*A + 1 drule_post(loopIndex); } - } else { - // RULE: - // - - drule_pre(" - increase vowel by 1/2 + 1\n",X-1); - // decrease length - A = phonemeLength[loopIndex]; - phonemeLength[loopIndex] = (A >> 2) + A + 1; // 5/4*A + 1 - drule_post(loopIndex); } - - ++loopIndex; - continue; } // WH, R*, L*, W*, Y*, M*, N*, NX, Q*, Z*, ZH, V*, DH, J*, B*, D*, G*, GX @@ -915,19 +898,11 @@ void AdjustLengths() { // Set stop consonant length to 5 // nasal? - if((flags2[index] & 8) != 0) { + else if((flags2[index] & 8) != 0) { // M*, N*, NX, index = phonemeindex[++X]; - - // end of buffer? - if (index == 255) - A = 65&2; //prevent buffer overflow - else - A = flags[index] & 2; // check for stop consonant - - // is next phoneme a stop consonant? - if (A != 0) { + if (index != 255 && (flags[index] & 2)) { // stop consonant? // B*, D*, G*, GX, P*, T*, K*, KX drule(" - set nasal = 5, consonant = 6\n"); @@ -942,8 +917,6 @@ void AdjustLengths() { if (debug) printf("phoneme %d (%c%c) length %d\n", X, signInputTable1[phonemeindex[X]], signInputTable2[phonemeindex[X]], phonemeLength[X]); if (debug) printf("phoneme %d (%c%c) length %d\n", X-1, signInputTable1[phonemeindex[X-1]], signInputTable2[phonemeindex[X-1]], phonemeLength[X-1]); } - loopIndex++; - continue; } // WH, R*, L*, W*, Y*, Q*, Z*, ZH, V*, DH, J*, B*, D*, G*, GX @@ -952,7 +925,7 @@ void AdjustLengths() { // Shorten both to (length/2 + 1) // (voiced) stop consonant? - if((flags[index] & 2) != 0) { + else if((flags[index] & 2) != 0) { // B*, D*, G*, GX // move past silence @@ -985,8 +958,6 @@ void AdjustLengths() { if (debug) printf("phoneme %d (%c%c) length %d\n", debugX, signInputTable1[phonemeindex[debugX]], signInputTable2[phonemeindex[debugX]], phonemeLength[debugX]); if (debug) printf("phoneme %d (%c%c) length %d\n", debugX-1, signInputTable1[phonemeindex[debugX-1]], signInputTable2[phonemeindex[debugX-1]], phonemeLength[debugX-1]); - loopIndex++; - continue; } // WH, R*, L*, W*, Y*, Q*, Z*, ZH, V*, DH, J*, **, @@ -994,26 +965,20 @@ void AdjustLengths() { // Decrease by 2 // liquic consonant? - if ((flags2[index] & 16) != 0) { + else if ((flags2[index] & 16) != 0) { // R*, L*, W*, Y* - // get the prior phoneme - index = phonemeindex[X-1]; + index = phonemeindex[X-1]; // prior phoneme; // FIXME: The debug code here breaks the rule. // prior phoneme a stop consonant> if((flags[index] & 2) != 0) - // Rule: - drule_pre(" - decrease by 2",X); - // decrease the phoneme length by 2 frames (20 ms) - phonemeLength[X] -= 2; + phonemeLength[X] -= 2; // 20ms drule_post(X); } - // move to next phoneme - loopIndex++; - continue; + ++loopIndex; } } From 8a11e1d16e90d93287570d5d5dc4df8e10406918 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sat, 28 Jan 2017 05:34:43 +0000 Subject: [PATCH 086/109] Refactoring --- src/sam.c | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/src/sam.c b/src/sam.c index c7b34cad..aa0ac339 100644 --- a/src/sam.c +++ b/src/sam.c @@ -236,26 +236,21 @@ void CopyStress() { unsigned char Y; while((Y = phonemeindex[pos]) != 255) { // if CONSONANT_FLAG set, skip - only vowels get stress - if ((flags[Y] & 64) == 0) {pos++; continue;} - Y = phonemeindex[pos+1]; - if (Y == 255) //prevent buffer overflow - { - pos++; continue; - } - // if the following phoneme is a vowel, skip - if ((flags[Y] & 128) == 0) {pos++; continue;} - - // get the stress value at the next position - Y = stress[pos+1]; - - // if next phoneme is not stressed, skip - if (Y == 0) {pos++; continue;} - // if next phoneme is not a VOWEL OR ER, skip - if ((Y & 128) != 0) {pos++; continue;} + if (flags[Y] & 64) { + Y = phonemeindex[pos+1]; + + // if the following phoneme is the end, or a vowel, skip + if (Y != 255 && (flags[Y] & 128) != 0) { + // get the stress value at the next position + Y = stress[pos+1]; + if (Y && !(Y&128)) { + // if next phoneme is stressed, and a VOWEL OR ER + // copy stress from next phoneme to this one + stress[pos] = Y+1; + } + } + } - // copy stress from prior phoneme to this one - stress[pos] = Y+1; - ++pos; } } From 5485558cfe863c59d378d36ee80aeb5915903138 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sat, 28 Jan 2017 06:25:02 +0000 Subject: [PATCH 087/109] Refactoring --- src/sam.c | 296 ++++++++++++++++++++++-------------------------------- 1 file changed, 122 insertions(+), 174 deletions(-) diff --git a/src/sam.c b/src/sam.c index aa0ac339..132e75fc 100644 --- a/src/sam.c +++ b/src/sam.c @@ -270,7 +270,36 @@ void Insert(unsigned char position/*var57*/, unsigned char mem60, unsigned char stress[position] = mem58; return; } - + + +signed int full_match(unsigned char sign1, unsigned char sign2) { + unsigned char Y = 0; + do { + // GET FIRST CHARACTER AT POSITION Y IN signInputTable + // --> should change name to PhonemeNameTable1 + unsigned char A = signInputTable1[Y]; + + if (A == sign1) { + A = signInputTable2[Y]; + // NOT A SPECIAL AND MATCHES SECOND CHARACTER? + if ((A != '*') && (A == sign2)) return Y; + } + } while (++Y != 81); + return -1; +} + +signed int wild_match(unsigned char sign1, unsigned char sign2) { + signed int Y = 0; + do { + if (signInputTable2[Y] == '*') { + if (signInputTable1[Y] == sign1) return Y; + } + } while (++Y != 81); + return -1; +} + + + // The input[] buffer contains a string of phonemes and stress markers along // the lines of: // @@ -309,127 +338,53 @@ void Insert(unsigned char position/*var57*/, unsigned char mem60, unsigned char // 1. phonemeIndex[] will contain the index of all the phonemes. // 2. The last index in phonemeIndex[] will be 255. // 3. stress[] will contain the stress value for each phoneme - -// input[] holds the string of phonemes, each two bytes wide -// signInputTable1[] holds the first character of each phoneme -// signInputTable2[] holds te second character of each phoneme -// phonemeIndex[] holds the indexes of the phonemes after parsing input[] -// -// The parser scans through the input[], finding the names of the phonemes -// by searching signInputTable1[] and signInputTable2[]. On a match, it -// copies the index of the phoneme into the phonemeIndexTable[]. -// -// The character <0x9B> marks the end of text in input[]. When it is reached, -// the index 255 is placed at the end of the phonemeIndexTable[], and the -// function returns with a 1 indicating success. -int Parser1() -{ + +// input[] holds the string of phonemes, each two bytes wide +// signInputTable1[] holds the first character of each phoneme +// signInputTable2[] holds te second character of each phoneme +// phonemeIndex[] holds the indexes of the phonemes after parsing input[] +// +// The parser scans through the input[], finding the names of the phonemes +// by searching signInputTable1[] and signInputTable2[]. On a match, it +// copies the index of the phoneme into the phonemeIndexTable[]. +// +// The character <0x9B> marks the end of text in input[]. When it is reached, +// the index 255 is placed at the end of the phonemeIndexTable[], and the +// function returns with a 1 indicating success. +int Parser1() +{ int i; unsigned char sign1; unsigned char sign2; unsigned char position = 0; - unsigned char X = 0; - unsigned char A = 0; - unsigned char Y = 0; - - // CLEAR THE STRESS TABLE - for(i=0; i<256; i++) stress[i] = 0; - - // THIS CODE MATCHES THE PHONEME LETTERS TO THE TABLE - while(1) { - // GET THE FIRST CHARACTER FROM THE PHONEME BUFFER - sign1 = input[X]; - // TEST FOR 155 (›) END OF LINE MARKER - if (sign1 == 155) { - phonemeindex[position] = 255; //mark endpoint - return 1; // REACHED END OF PHONEMES, SO EXIT - } - - // GET THE NEXT CHARACTER FROM THE BUFFER - sign2 = input[++X]; - - // NOW sign1 = FIRST CHARACTER OF PHONEME, AND sign2 = SECOND CHARACTER OF PHONEME - - // TRY TO MATCH PHONEMES ON TWO TWO-CHARACTER NAME - // IGNORE PHONEMES IN TABLE ENDING WITH WILDCARDS - Y = 0; // SET INDEX TO 0 -pos41095: - // GET FIRST CHARACTER AT POSITION Y IN signInputTable - // --> should change name to PhonemeNameTable1 - A = signInputTable1[Y]; - - if (A == sign1) { - // GET THE CHARACTER FROM THE PhonemeSecondLetterTable - A = signInputTable2[Y]; - // NOT A SPECIAL AND MATCHES SECOND CHARACTER? - if ((A != '*') && (A == sign2)) - { - // STORE THE INDEX OF THE PHONEME INTO THE phomeneIndexTable - phonemeindex[position] = Y; - - // ADVANCE THE POINTER TO THE phonemeIndexTable - ++position; - // ADVANCE THE POINTER TO THE phonemeInputBuffer - ++X; - // CONTINUE PARSING - continue; - } - } - - // NO MATCH, TRY TO MATCH ON FIRST CHARACTER TO WILDCARD NAMES (ENDING WITH '*') + unsigned char srcpos = 0; + + for(i=0; i<256; i++) stress[i] = 0; // Clear the stress table. + + while((sign1 = input[srcpos]) != 155) { // 155 (\233) is end of line marker + sign2 = input[++srcpos]; + signed int match = 0; + if ((match = full_match(sign1, sign2)) != -1) { + // Matched both characters (no wildcards) + phonemeindex[position++] = (unsigned char)match; + ++srcpos; // Skip the second character of the input as we've matched it + } else if ((match=wild_match(sign1,sign2)) != -1) { + // Matched just the first character (with second character matching '*' + phonemeindex[position++] = (unsigned char)match; + } else { + // Should be a stress character. Search through the + // stress table backwards. + match = 8; // End of stress table. FIXME: Don't hardcode. + while( (sign1 != stressInputTable[match]) && (match>0)) --match; + + if (match == 0) return 0; // failure - // ADVANCE TO THE NEXT POSITION. IF NOT END OF TABLE, CONTINUE - if (++Y != 81) goto pos41095; + stress[position-1] = match; // Set stress for prior phoneme + } + } //while -// REACHED END OF TABLE WITHOUT AN EXACT (2 CHARACTER) MATCH. -// THIS TIME, SEARCH FOR A 1 CHARACTER MATCH AGAINST THE WILDCARDS - -// RESET THE INDEX TO POINT TO THE START OF THE PHONEME NAME TABLE - Y = 0; -pos41134: -// DOES THE PHONEME IN THE TABLE END WITH '*'? - if (signInputTable2[Y] == '*') - { -// DOES THE FIRST CHARACTER MATCH THE FIRST LETTER OF THE PHONEME - if (signInputTable1[Y] == sign1) - { - // SAVE THE POSITION AND MOVE AHEAD - phonemeindex[position] = Y; - - // ADVANCE THE POINTER - position++; - - // CONTINUE THROUGH THE LOOP - continue; - } - } - Y++; - if (Y != 81) goto pos41134; //81 is size of PHONEME NAME table - -// FAILED TO MATCH WITH A WILDCARD. ASSUME THIS IS A STRESS -// CHARACTER. SEARCH THROUGH THE STRESS TABLE - - // SET INDEX TO POSITION 8 (END OF STRESS TABLE) - Y = 8; - - // WALK BACK THROUGH TABLE LOOKING FOR A MATCH - while( (sign1 != stressInputTable[Y]) && (Y>0)) - { - // DECREMENT INDEX - Y--; - } - - // REACHED THE END OF THE SEARCH WITHOUT BREAKING OUT OF LOOP? - if (Y == 0) - { - //mem[39444] = X; - //41181: JSR 42043 //Error - // FAILED TO MATCH ANYTHING, RETURN 0 ON FAILURE - return 0; - } -// SET THE STRESS FOR THE PRIOR PHONEME - stress[position-1] = Y; - } //while + phonemeindex[position] = 255; //mark endpoint + return 1; } @@ -529,6 +484,40 @@ void drule_post(unsigned char X) { // D -> DX +void rule_alveolar_uw(unsigned char X) { + // ALVEOLAR flag set? + unsigned char A = flags2[phonemeindex[X-1]] & 4; + if (A) { + drule(" UW -> UX"); + phonemeindex[X] = 16; + } +} + +void rule_ch(unsigned char X, unsigned char mem59) { + drule("CH -> CH CH+1"); + Insert(X+1, 43, mem59, stress[X]); +} + +void rule_j(unsigned char X, unsigned char mem59) { + drule("J -> J J+1"); + Insert(X+1, 45, mem59, stress[X]); +} + +void rule_g(unsigned char pos) { + // G -> GX + // Example: GO + + unsigned char index = phonemeindex[pos+1]; + + // If dipthong ending with YX, move continue processing next phoneme + if ((index != 255) && ((flags[index] & 32) == 0)) { + // replace G with GX and continue processing next phoneme + if (debug) printf("RULE: G -> GX \n"); + phonemeindex[pos] = 63; // 'GX' + } +} + + void Parser2() { if (debug) printf("Parser2\n"); unsigned char pos = 0; //mem66; @@ -646,19 +635,7 @@ void Parser2() { // 2. Reciter already replaces GS -> GZ drule("G S -> G Z"); phonemeindex[pos] = 38; // 'Z' - } else if (p == 60) { // 'G' - // G -> GX - // Example: GO - - unsigned char index = phonemeindex[pos+1]; - - // If dipthong ending with YX, move continue processing next phoneme - if ((index != 255) && ((flags[index] & 32) == 0)) { - // replace G with GX and continue processing next phoneme - if (debug) printf("RULE: G -> GX \n"); - phonemeindex[pos] = 63; // 'GX' - } - } + } else if (p == 60) rule_g(pos); pos++; continue; @@ -698,46 +675,21 @@ void Parser2() { continue; } - if ((flags[Y] & 1)) { - A = Y; - goto pos41812; - } + if (!(flags[Y] & 1)) { pos41749: - // RULE: - // UW -> UX - // - // Example: NEW, DEW, SUE, ZOO, THOO, TOO - A = phonemeindex[X]; - if (A == 53 || A == 42 || A == 44) { - if (A == 53) { // 'UW' - // ALVEOLAR flag set? - A = flags2[phonemeindex[X-1]] & 4; - if (A) { - if (debug) printf("RULE: UW -> UX\n"); - phonemeindex[X] = 16; - } - } - - // RULE: - // CH -> CH CH' (CH requires two phonemes to represent it) - // Example: CHEW - if (A == 42) { // 'CH' - if (debug) printf("CH -> CH CH+1\n"); - Insert(X+1, 43, mem59, stress[X]); - } - - // RULE: - // J -> J J' (J requires two phonemes to represent it) - // Example: JAY - if (A == 44) { // 'J' - if (debug) printf("J -> J J+1\n"); - Insert(X+1, 45, mem59, stress[X]); + A = phonemeindex[X]; + if (A == 53 || A == 42 || A == 44) { + if (A == 53) rule_alveolar_uw(X); // Example: NEW, DEW, SUE, ZOO, THOO, TOO + else if (A == 42) rule_ch(X,mem59); // Example: CHEW + else if (A == 44) rule_j(X,mem59); // Example: JAY + pos++; + continue; } - pos++; - continue; - } - + } else { + A = Y; + } + // Jump here to continue pos41812: // RULE: Soften T following vowel @@ -761,14 +713,10 @@ void Parser2() { } } else { A = phonemeindex[X+1]; - if (A == 255) //prevent buffer overflow - A = 65 & 128; - else - // Is next phoneme a vowel or ER? - if (flags[A] & 128) { - if (debug) printf("RULE: Soften T or D following vowel or ER and preceding a pause -> DX\n"); - if (A != 0) phonemeindex[pos] = 30; // 'DX' - } + if (A != 255 && (flags[A] & 128)) { // Next phoneme is a vowel or ER + if (debug) printf("RULE: Soften T or D following vowel or ER and preceding a pause -> DX\n"); + if (A != 0) phonemeindex[pos] = 30; // 'DX' + } } } } From 8b635440ff9994b9028463dbb8cafe52bb7bf2ec Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sat, 28 Jan 2017 06:31:50 +0000 Subject: [PATCH 088/109] Cleanup formatting --- src/RenderTabs.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/RenderTabs.h b/src/RenderTabs.h index 6f86e515..06ab4080 100755 --- a/src/RenderTabs.h +++ b/src/RenderTabs.h @@ -271,14 +271,14 @@ unsigned char multtable[] = 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 , 9 ,0xA ,0xB ,0xC ,0xD ,0xE ,0xF , - 0x00 , 0x01 , 3 , 4 , 6 , 7 , 9 ,0xA , - 0xC ,0xD ,0xF , 0x10 , 0x12 , 0x13 , 0x15 , 0x16 , - 0x00 , 2 , 4 , 6 , 8 ,0xA ,0xC ,0xE , + 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 , 2 , 5 , 7 ,0xA ,0xC ,0xF , 0x11 , + 0x00 , 0x02 , 0x05 , 0x07 , 0x0A , 0x0C , 0x0F , 0x11 , 0x14 , 0x16 , 0x19 , 0x1B , 0x1E , 0x20 , 0x23 , 0x25 , - 0x00 , 3 , 6 , 9 ,0xC ,0xF , 0x12 , 0x15 , + 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 , From eaa41acb5677b224c38cfccd958a27af4c037315 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sat, 4 Feb 2017 02:21:36 +0000 Subject: [PATCH 089/109] Refactoring --- src/sam.c | 107 ++++++++++++++++-------------------------------------- 1 file changed, 31 insertions(+), 76 deletions(-) diff --git a/src/sam.c b/src/sam.c index 132e75fc..1b1d15f8 100644 --- a/src/sam.c +++ b/src/sam.c @@ -255,21 +255,21 @@ void CopyStress() { } } -void Insert(unsigned char position/*var57*/, unsigned char mem60, unsigned char mem59, unsigned char mem58) -{ - int i; - for(i=253; i >= position; i--) // ML : always keep last safe-guarding 255 - { - phonemeindex[i+1] = phonemeindex[i]; - phonemeLength[i+1] = phonemeLength[i]; - stress[i+1] = stress[i]; - } - - phonemeindex[position] = mem60; - phonemeLength[position] = mem59; - stress[position] = mem58; - return; -} +void Insert(unsigned char position/*var57*/, unsigned char mem60, unsigned char mem59, unsigned char mem58) +{ + int i; + for(i=253; i >= position; i--) // ML : always keep last safe-guarding 255 + { + phonemeindex[i+1] = phonemeindex[i]; + phonemeLength[i+1] = phonemeLength[i]; + stress[i+1] = stress[i]; + } + + phonemeindex[position] = mem60; + phonemeLength[position] = mem59; + stress[position] = mem58; + return; +} signed int full_match(unsigned char sign1, unsigned char sign2) { @@ -573,19 +573,12 @@ void Parser2() { if ((pf & 128) && stress[X]) { // VOWEL && stressed if (!phonemeindex[++X]) { // If following phoneme is a pause, get next unsigned char Y = phonemeindex[++X]; - // Check for end of buffer flag - if (Y == 255) { //buffer overflow - // ??? Not sure about these flags - A = 65&128; - } else { - // And VOWEL flag to current phoneme's flags - A = flags[Y] & 128; - } - + // And VOWEL flag to current phoneme's flags + A = (Y == 255) ? 0 : flags[Y] & 128; if (A && stress[X]) { // If following phonemes is not a pause, and is not stressed // Insert a glottal stop and move forward - if (debug) printf("RULE: Insert glottal stop between two stressed vowels with space between them\n"); + drule("Insert glottal stop between two stressed vowels with space between them"); Insert(X, 31, mem59, 0); // 31 = 'Q' pos++; continue; @@ -822,9 +815,6 @@ void AdjustLengths() { drule_post(loopIndex); } } else { - // RULE: - // - drule_pre(" - increase vowel by 1/2 + 1\n",X-1); // decrease length unsigned char A = phonemeLength[loopIndex]; @@ -840,75 +830,40 @@ void AdjustLengths() { // Set punctuation length to 6 // Set stop consonant length to 5 - // nasal? - else if((flags2[index] & 8) != 0) { + + else if((flags2[index] & 8) != 0) { // nasal? // M*, N*, NX, index = phonemeindex[++X]; if (index != 255 && (flags[index] & 2)) { // stop consonant? - // B*, D*, G*, GX, P*, T*, K*, KX - drule(" - set nasal = 5, consonant = 6\n"); - if (debug) printf("PRE\n"); - if (debug) printf("phoneme %d (%c%c) length %d\n", X, signInputTable1[phonemeindex[X]], signInputTable2[phonemeindex[X]], phonemeLength[X]); - if (debug) printf("phoneme %d (%c%c) length %d\n", X-1, signInputTable1[phonemeindex[X-1]], signInputTable2[phonemeindex[X-1]], phonemeLength[X-1]); - phonemeLength[X] = 6; // set stop consonant length to 6 phonemeLength[X-1] = 5; // set nasal length to 5 - - if (debug) printf("POST\n"); - if (debug) printf("phoneme %d (%c%c) length %d\n", X, signInputTable1[phonemeindex[X]], signInputTable2[phonemeindex[X]], phonemeLength[X]); - if (debug) printf("phoneme %d (%c%c) length %d\n", X-1, signInputTable1[phonemeindex[X-1]], signInputTable2[phonemeindex[X-1]], phonemeLength[X-1]); } - } - - // WH, R*, L*, W*, Y*, Q*, Z*, ZH, V*, DH, J*, B*, D*, G*, GX - - // RULE: {optional silence} - // Shorten both to (length/2 + 1) - - // (voiced) stop consonant? - else if((flags[index] & 2) != 0) { - // B*, D*, G*, GX + } else if((flags[index] & 2) != 0) { // (voiced) stop consonant? + // RULE: {optional silence} + // Shorten both to (length/2 + 1) // move past silence while ((index = phonemeindex[++X]) == 0); - // check for end of buffer - if (index == 255) { - if ((65 & 2) == 0) {loopIndex++; continue;} - } else if ((flags[index] & 2) == 0) { - // if another stop consonant, move ahead + if (index == 255 || (flags[index] & 2) == 0) { + // if end of buffer or another stop consonant, move ahead loopIndex++; continue; } + // FIXME, this looks wrong? // RULE: {optional silence} if (debug) printf("RULE: {optional silence} - shorten both to 1/2 + 1\n"); - if (debug) printf("PRE\n"); - if (debug) printf("phoneme %d (%c%c) length %d\n", X, signInputTable1[phonemeindex[X]], signInputTable2[phonemeindex[X]], phonemeLength[X]); - if (debug) printf("phoneme %d (%c%c) length %d\n", X-1, signInputTable1[phonemeindex[X-1]], signInputTable2[phonemeindex[X-1]], phonemeLength[X-1]); - // X gets overwritten, so hold prior X value for debug statement - int debugX = X; - // shorten the prior phoneme length to (length/2 + 1) - phonemeLength[X] = (phonemeLength[X] >> 1) + 1; + phonemeLength[X] = (phonemeLength[X] >> 1) + 1; X = loopIndex; - - // also shorten this phoneme length to (length/2 +1) phonemeLength[loopIndex] = (phonemeLength[loopIndex] >> 1) + 1; + } else if ((flags2[index] & 16) != 0) { // liquic consonant? + // WH, R*, L*, W*, Y*, Q*, Z*, ZH, V*, DH, J*, **, - if (debug) printf("POST\n"); - if (debug) printf("phoneme %d (%c%c) length %d\n", debugX, signInputTable1[phonemeindex[debugX]], signInputTable2[phonemeindex[debugX]], phonemeLength[debugX]); - if (debug) printf("phoneme %d (%c%c) length %d\n", debugX-1, signInputTable1[phonemeindex[debugX-1]], signInputTable2[phonemeindex[debugX-1]], phonemeLength[debugX-1]); - - } - // WH, R*, L*, W*, Y*, Q*, Z*, ZH, V*, DH, J*, **, - - // RULE: - // Decrease by 2 - - // liquic consonant? - else if ((flags2[index] & 16) != 0) { + // RULE: + // Decrease by 2 // R*, L*, W*, Y* index = phonemeindex[X-1]; // prior phoneme; From 2f64530cd1ddb4d87202229e8f3b3537767c6382 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sat, 4 Feb 2017 02:40:29 +0000 Subject: [PATCH 090/109] Refactoring --- src/sam.c | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/src/sam.c b/src/sam.c index 1b1d15f8..089d1c89 100644 --- a/src/sam.c +++ b/src/sam.c @@ -5,6 +5,13 @@ #include "sam.h" #include "render.h" #include "SamTabs.h" + +enum { + BREAK = 254, + END = 255 +}; + + char input[256]; //tab39445 //standard sam sound @@ -127,7 +134,7 @@ void Init() stressOutput[i] = 0; phonemeLengthOutput[i] = 0; } - phonemeindex[255] = 255; //to prevent buffer overflow // ML : changed from 32 to 255 to stop freezing with long inputs + phonemeindex[255] = END; //to prevent buffer overflow // ML : changed from 32 to 255 to stop freezing with long inputs } @@ -164,11 +171,11 @@ void PrepareOutput() { unsigned char A = phonemeindex[srcpos]; phonemeIndexOutput[destpos] = A; switch(A) { - case 255: // End of input + case END: Render(); return; - case 254: // Break - phonemeIndexOutput[destpos] = 255; + case BREAK: + phonemeIndexOutput[destpos] = END; Render(); destpos = 0; break; @@ -191,24 +198,24 @@ void InsertBreath(unsigned char mem59) { unsigned char pos = 0; - while((index = phonemeindex[pos]) != 255) { + while((index = phonemeindex[pos]) != END) { len += phonemeLength[pos]; if (len < 232) { - if (index != 254 && - (flags2[index]&1) != 0) { + if (index == BREAK) { + } else if (!(flags2[index]&1)) { + if (index == 0) mem54 = pos; + } else { len = 0; - Insert(pos+1, 254, mem59, 0); - pos += 2; - continue; - } - if (index == 0) mem54 = pos; + Insert(++pos, BREAK, mem59, 0); + } } else { pos = mem54; phonemeindex[pos] = 31; // 'Q*' glottal stop phonemeLength[pos] = 4; stress[pos] = 0; + len = 0; - Insert(++pos, 254, mem59, 0); + Insert(++pos, BREAK, mem59, 0); } ++pos; } @@ -390,11 +397,9 @@ int Parser1() //change phonemelength depedendent on stress void SetPhonemeLength() { - unsigned char A; int position = 0; - while(phonemeindex[position] != 255 ) - { - A = stress[position]; + while(phonemeindex[position] != 255 ) { + unsigned char A = stress[position]; if ((A == 0) || ((A&128) != 0)) { phonemeLength[position] = phonemeLengthTable[phonemeindex[position]]; } else { From 3bf6ff83142cb9cd146e65f871c9a19254ecf1c3 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sat, 4 Feb 2017 03:47:34 +0000 Subject: [PATCH 091/109] Merged flags and flags2 --- src/SamTabs.h | 48 +++++++++++++++++++----------------------------- src/sam.c | 34 +++++++++++++++++----------------- 2 files changed, 36 insertions(+), 46 deletions(-) diff --git a/src/SamTabs.h b/src/SamTabs.h index 59209129..d135a0a9 100644 --- a/src/SamTabs.h +++ b/src/SamTabs.h @@ -39,38 +39,28 @@ unsigned char signInputTable2[] = }; //loc_9F8C -unsigned char flags[]={ - 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0xA4 , 0xA4 , 0xA4 , - 0xA4 , 0xA4 , 0xA4 , 0x84 , 0x84 , 0xA4 , 0xA4 , 0x84 , - 0x84 , 0x84 , 0x84 , 0x84 , 0x84 , 0x84 , 0x44 , 0x44 , - 0x44 , 0x44 , 0x44 , 0x4C , 0x4C , 0x4C , 0x48 , 0x4C , - 0x40 , 0x40 , 0x40 , 0x40 , 0x40 , 0x40 , 0x44 , 0x44 , - 0x44 , 0x44 , 0x48 , 0x40 , 0x4C , 0x44 , 0x00 , 0x00 , - 0xB4 , 0xB4 , 0xB4 , 0x94 , 0x94 , 0x94 , 0x4E , 0x4E , - 0x4E , 0x4E , 0x4E , 0x4E , 0x4E , 0x4E , 0x4E , 0x4E , - 0x4E , 0x4E , 0x4B , 0x4B , 0x4B , 0x4B , 0x4B , 0x4B , - 0x4B , 0x4B , 0x4B , 0x4B , 0x4B , 0x4B , 0x80 , 0xC1 , - 0xC1 - - +enum { + FLAG_PUNCT = 0x0100, + FLAG_ALVEOLAR = 0x0400, + FLAG_NASAL = 0x0800, + FLAG_LIQUIC = 0x1000 /* liquic consonant */ }; -//??? flags overlap flags2 -//loc_9FDA -unsigned char flags2[] = -{ - 0x80 , 0xC1 , 0xC1 , 0xC1 , 0xC1 , 0x00 , 0x00 , 0x00 , - 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , - 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 , - 0x10 , 0x10 , 0x10 , 0x08 , 0x0C , 0x08 , 0x04 , 0x40 , - 0x24 , 0x20 , 0x20 , 0x24 , 0x00 , 0x00 , 0x24 , 0x20 , - 0x20 , 0x24 , 0x20 , 0x20 , 0x00 , 0x20 , 0x00 , 0x00 , - 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , - 0x00 , 0x04 , 0x04 , 0x04 , 0x00 , 0x00 , 0x00 , 0x00 , - 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x04 , 0x04 , 0x04 , - 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 -}; +unsigned short flags[]={ + 0x8000 , 0xC100 , 0xC100 , 0xC100 , 0xC100 , 0x00A4 , 0x00A4 , 0x00A4 , + 0x00A4 , 0x00A4 , 0x00A4 , 0x0084 , 0x0084 , 0x00A4 , 0x00A4 , 0x0084 , + 0x0084 , 0x0084 , 0x0084 , 0x0084 , 0x0084 , 0x0084 , 0x0044 , 0x1044 , + 0x1044 , 0x1044 , 0x1044 , 0x084C , 0x0C4C , 0x084C , 0x0448 , 0x404C , + + 0x2440 , 0x2040 , 0x2040 , 0x2440 , 0x0040 , 0x0040 , 0x2444 , 0x2044 , + 0x2044 , 0x2444 , 0x2048 , 0x2040 , 0x004C , 0x2044 , 0x0000 , 0x0000 , + 0x00B4 , 0x00B4 , 0x00B4 , 0x0094 , 0x0094 , 0x0094 , 0x004E , 0x004E , + 0x004E , 0x044E , 0x044E , 0x044E , 0x004E , 0x004E , 0x004E , 0x004E , + 0x004E , 0x004E , 0x004B , 0x004B , 0x004B , 0x044B , 0x044B , 0x044B , + 0x004B , 0x004B , 0x004B , 0x004B , 0x004B , 0x004B , 0x0080 , 0x00C1 , + 0x00C1 +}; //tab45616??? diff --git a/src/sam.c b/src/sam.c index 089d1c89..6b78ce87 100644 --- a/src/sam.c +++ b/src/sam.c @@ -7,6 +7,9 @@ #include "SamTabs.h" enum { + pR = 23, + pD = 57, + pT = 69, BREAK = 254, END = 255 }; @@ -202,7 +205,7 @@ void InsertBreath(unsigned char mem59) { len += phonemeLength[pos]; if (len < 232) { if (index == BREAK) { - } else if (!(flags2[index]&1)) { + } else if (!(flags[index]& FLAG_PUNCT)) { if (index == 0) mem54 = pos; } else { len = 0; @@ -241,13 +244,13 @@ void CopyStress() { // loop thought all the phonemes to be output unsigned char pos=0; //mem66 unsigned char Y; - while((Y = phonemeindex[pos]) != 255) { + while((Y = phonemeindex[pos]) != END) { // if CONSONANT_FLAG set, skip - only vowels get stress if (flags[Y] & 64) { Y = phonemeindex[pos+1]; // if the following phoneme is the end, or a vowel, skip - if (Y != 255 && (flags[Y] & 128) != 0) { + if (Y != END && (flags[Y] & 128) != 0) { // get the stress value at the next position Y = stress[pos+1]; if (Y && !(Y&128)) { @@ -390,7 +393,7 @@ int Parser1() } } //while - phonemeindex[position] = 255; //mark endpoint + phonemeindex[position] = END; return 1; } @@ -491,8 +494,7 @@ void drule_post(unsigned char X) { void rule_alveolar_uw(unsigned char X) { // ALVEOLAR flag set? - unsigned char A = flags2[phonemeindex[X-1]] & 4; - if (A) { + if (flags[phonemeindex[X-1]] & FLAG_ALVEOLAR) { drule(" UW -> UX"); phonemeindex[X] = 16; } @@ -593,24 +595,22 @@ void Parser2() { // Get current position and phoneme X = pos; - A = p; unsigned char prior = phonemeindex[pos-1]; - if (p == 23 || p == 24 || p == 32 || A == 60) { + if (p == pR || p == 24 || p == 32 || A == 60) { - if (p == 23) { // 'R' + if (p == pR) { // 'R' // RULES FOR PHONEMES BEFORE R // Look at prior phoneme X--; A = prior; - - if (prior == 69 || prior == 57) { - if (prior == 69) { // 'T' + if (prior == pT || prior == pD) { + if (prior == pT) { // Example: TRACK drule("T R -> CH R"); phonemeindex[pos-1] = 42; - } else if (prior == 57) { // 'D' + } else if (prior == pD) { // Example: DRY drule("D R -> J R"); phonemeindex[pos-1] = 44; @@ -748,7 +748,7 @@ void AdjustLengths() { unsigned char loopIndex=0; while((index = phonemeindex[X]) != 255) { // not punctuation? - if((flags2[index] & 1) == 0) { // skip + if((flags[index] & FLAG_PUNCT) == 0) { // skip ++X; continue; } @@ -765,7 +765,7 @@ void AdjustLengths() { //if (index != 255)//inserted to prevent access overrun // test for fricative/unvoiced or not voiced - if(((flags2[index] & 32) == 0) || ((flags[index] & 4) != 0)) //nochmal überprüfen + if(((flags[index] & 0x2000) == 0) || ((flags[index] & 4) != 0)) //nochmal überprüfen { unsigned char A = phonemeLength[X]; @@ -836,7 +836,7 @@ void AdjustLengths() { // Set stop consonant length to 5 - else if((flags2[index] & 8) != 0) { // nasal? + else if((flags[index] & FLAG_NASAL) != 0) { // nasal? // M*, N*, NX, index = phonemeindex[++X]; @@ -864,7 +864,7 @@ void AdjustLengths() { phonemeLength[X] = (phonemeLength[X] >> 1) + 1; X = loopIndex; phonemeLength[loopIndex] = (phonemeLength[loopIndex] >> 1) + 1; - } else if ((flags2[index] & 16) != 0) { // liquic consonant? + } else if ((flags[index] & 0x1000) != 0) { // liquic consonant? // WH, R*, L*, W*, Y*, Q*, Z*, ZH, V*, DH, J*, **, // RULE: From 26ddb545bd077fc5ad6e59b7360577093863aaf9 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sat, 4 Feb 2017 04:14:21 +0000 Subject: [PATCH 092/109] Refactoring --- src/sam.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/sam.c b/src/sam.c index 6b78ce87..eff37b27 100644 --- a/src/sam.c +++ b/src/sam.c @@ -560,15 +560,22 @@ void Parser2() { if (A==20) drule("insert WX following dipthong NOT ending in IY sound"); if (A==21) drule("insert YX following dipthong ending in IY sound"); Insert(pos+1, A, mem59, stress[pos]); - X = pos; - goto pos41749; + if (p == 53 || p == 42 || p == 44) { + if (p == 53) rule_alveolar_uw(pos); // Example: NEW, DEW, SUE, ZOO, THOO, TOO + else if (p == 42) rule_ch(pos,mem59); // Example: CHEW + else if (p == 44) rule_j(pos,mem59); // Example: JAY + pos++; + continue; + } + goto pos41812; } if (p == 78 || p == 79 || p == 80) { if (p == 78) ChangeRule(X, 13, 24, mem59, stress[X],"UL -> AX L"); // Example: MEDDLE else if (p == 79) ChangeRule(X, 13, 27, mem59, stress[X], "UM -> AX M"); // Example: ASTRONOMY else if (p == 80) ChangeRule(X, 13, 28, mem59, stress[X], "UN -> AX N"); // Example: FUNCTION + ++pos; continue; } @@ -615,6 +622,7 @@ void Parser2() { drule("D R -> J R"); phonemeindex[pos-1] = 44; } + A=p; goto pos41812; } @@ -674,8 +682,6 @@ void Parser2() { } if (!(flags[Y] & 1)) { - - pos41749: A = phonemeindex[X]; if (A == 53 || A == 42 || A == 44) { if (A == 53) rule_alveolar_uw(X); // Example: NEW, DEW, SUE, ZOO, THOO, TOO @@ -711,7 +717,7 @@ void Parser2() { } } else { A = phonemeindex[X+1]; - if (A != 255 && (flags[A] & 128)) { // Next phoneme is a vowel or ER + if (A != END && (flags[A] & 128)) { // Next phoneme is a vowel or ER if (debug) printf("RULE: Soften T or D following vowel or ER and preceding a pause -> DX\n"); if (A != 0) phonemeindex[pos] = 30; // 'DX' } @@ -864,7 +870,7 @@ void AdjustLengths() { phonemeLength[X] = (phonemeLength[X] >> 1) + 1; X = loopIndex; phonemeLength[loopIndex] = (phonemeLength[loopIndex] >> 1) + 1; - } else if ((flags[index] & 0x1000) != 0) { // liquic consonant? + } else if ((flags[index] & FLAG_LIQUIC) != 0) { // liquic consonant? // WH, R*, L*, W*, Y*, Q*, Z*, ZH, V*, DH, J*, **, // RULE: From ae9dddab6c7955d082b2519f387efa3bf55ba4cb Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sat, 4 Feb 2017 05:38:52 +0000 Subject: [PATCH 093/109] Refactoring --- src/sam.c | 76 +++++++++++++++++++++++-------------------------------- 1 file changed, 31 insertions(+), 45 deletions(-) diff --git a/src/sam.c b/src/sam.c index eff37b27..ade2d4f1 100644 --- a/src/sam.c +++ b/src/sam.c @@ -535,7 +535,7 @@ void Parser2() { unsigned char p = phonemeindex[pos]; unsigned char A = p; - if (p == 255) return; + if (p == END) return; if (debug) printf("%d: %c%c\n", X, signInputTable1[p], signInputTable2[p]); @@ -546,33 +546,27 @@ void Parser2() { unsigned char pf = flags[p]; - // RULE: - // -> WX - // -> YX - // Example: OIL, COW - - // Check for DIPTHONG - if ((pf & 16) != 0) { // Not a dipthong. - // If ends with IY, use YX, else use WX - A = (pf & 32) ? 21 : 20; // 'WX' = 20 'YX' = 21 - - // Insert at WX or YX following, copying the stress - if (A==20) drule("insert WX following dipthong NOT ending in IY sound"); - if (A==21) drule("insert YX following dipthong ending in IY sound"); - Insert(pos+1, A, mem59, stress[pos]); - - if (p == 53 || p == 42 || p == 44) { - if (p == 53) rule_alveolar_uw(pos); // Example: NEW, DEW, SUE, ZOO, THOO, TOO - else if (p == 42) rule_ch(pos,mem59); // Example: CHEW - else if (p == 44) rule_j(pos,mem59); // Example: JAY - pos++; - continue; - } - goto pos41812; - } - - if (p == 78 || p == 79 || p == 80) { - if (p == 78) ChangeRule(X, 13, 24, mem59, stress[X],"UL -> AX L"); // Example: MEDDLE + if ((pf & 16) || p == 78 || p == 79 || p == 80) { + if ((pf & 16)) { // Check for DIPTHONG + // RULE: + // -> WX + // -> YX + // Example: OIL, COW + + // If ends with IY, use YX, else use WX + A = (pf & 32) ? 21 : 20; // 'WX' = 20 'YX' = 21 + + // Insert at WX or YX following, copying the stress + if (A==20) drule("insert WX following dipthong NOT ending in IY sound"); + if (A==21) drule("insert YX following dipthong ending in IY sound"); + Insert(pos+1, A, mem59, stress[pos]); + + if (p == 53 || p == 42 || p == 44) { + if (p == 53) rule_alveolar_uw(pos); // Example: NEW, DEW, SUE, ZOO, THOO, TOO + else if (p == 42) rule_ch(pos,mem59); // Example: CHEW + else if (p == 44) rule_j(pos,mem59); // Example: JAY + } + } else if (p == 78) ChangeRule(X, 13, 24, mem59, stress[X],"UL -> AX L"); // Example: MEDDLE else if (p == 79) ChangeRule(X, 13, 27, mem59, stress[X], "UM -> AX M"); // Example: ASTRONOMY else if (p == 80) ChangeRule(X, 13, 28, mem59, stress[X], "UN -> AX N"); // Example: FUNCTION @@ -584,12 +578,13 @@ void Parser2() { // -> Q // EXAMPLE: AWAY EIGHT - if ((pf & 128) && stress[X]) { // VOWEL && stressed - if (!phonemeindex[++X]) { // If following phoneme is a pause, get next - unsigned char Y = phonemeindex[++X]; + else if ((pf & 128) && stress[X]) { // VOWEL && stressed + if (!phonemeindex[X+1]) { // If following phoneme is a pause, get next + X+=2; + unsigned char Y = phonemeindex[X]; // And VOWEL flag to current phoneme's flags - A = (Y == 255) ? 0 : flags[Y] & 128; + A = (Y == END) ? 0 : flags[Y] & 128; if (A && stress[X]) { // If following phonemes is not a pause, and is not stressed // Insert a glottal stop and move forward drule("Insert glottal stop between two stressed vowels with space between them"); @@ -600,13 +595,8 @@ void Parser2() { } } - // Get current position and phoneme - X = pos; - unsigned char prior = phonemeindex[pos-1]; - if (p == pR || p == 24 || p == 32 || A == 60) { - if (p == pR) { // 'R' // RULES FOR PHONEMES BEFORE R // Look at prior phoneme @@ -650,18 +640,14 @@ void Parser2() { // K -> KX // Example: COW - if (A == 72) { // 'K' unsigned char Y = phonemeindex[pos+1]; // If at end, replace current phoneme with KX - if (Y == 255) phonemeindex[pos] = 75; // ML : prevents an index out of bounds problem - else { - // VOWELS AND DIPTHONGS ENDING WITH IY SOUND flag set? - A = flags[Y] & 32; - if (debug) if (A==0) printf("RULE: K -> KX \n"); + if ((flags[Y] & 32)==0 || Y==END) { // VOWELS AND DIPTHONGS ENDING WITH IY SOUND flag set? + if (debug) printf("RULE: K -> KX \n"); // Replace with KX - if (A == 0) phonemeindex[pos] = 75; // 'KX' - } + phonemeindex[pos] = 75; // 'KX' + } } // RULE: From 4f58147c0f193073c191616d8f7765ea71e800eb Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sat, 4 Feb 2017 20:47:24 +0000 Subject: [PATCH 094/109] Refactoring --- src/SamTabs.h | 9 ++- src/sam.c | 166 +++++++++++++++++++------------------------------- 2 files changed, 70 insertions(+), 105 deletions(-) diff --git a/src/SamTabs.h b/src/SamTabs.h index d135a0a9..bd6f8dbd 100644 --- a/src/SamTabs.h +++ b/src/SamTabs.h @@ -40,10 +40,17 @@ unsigned char signInputTable2[] = //loc_9F8C enum { + FLAG_PLOSIVE = 0x0001, + FLAG_STOPCONS = 0x0002, /* stop consonant */ + FLAG_VOICED = 0x0004, + FLAG_DIPTHONG = 0x0010, + FLAG_CONSONANT= 0x0040, + FLAG_VOWEL = 0x0080, FLAG_PUNCT = 0x0100, FLAG_ALVEOLAR = 0x0400, FLAG_NASAL = 0x0800, - FLAG_LIQUIC = 0x1000 /* liquic consonant */ + FLAG_LIQUIC = 0x1000, /* liquic consonant */ + FLAG_FRICATIVE= 0x2000 }; unsigned short flags[]={ diff --git a/src/sam.c b/src/sam.c index ade2d4f1..61ddb23a 100644 --- a/src/sam.c +++ b/src/sam.c @@ -154,7 +154,7 @@ int SAMMain() { Code41240(); do { if (phonemeindex[X] > 80) { - phonemeindex[X] = 255; + phonemeindex[X] = END; break; // error: delete all behind it } } while (++X != 0); @@ -525,29 +525,29 @@ void rule_g(unsigned char pos) { } + + + void Parser2() { - if (debug) printf("Parser2\n"); unsigned char pos = 0; //mem66; + unsigned char p; - // Loop through phonemes - while(1) { - X = pos; - unsigned char p = phonemeindex[pos]; - unsigned char A = p; - - if (p == END) return; + if (debug) printf("Parser2\n"); - if (debug) printf("%d: %c%c\n", X, signInputTable1[p], signInputTable2[p]); + while((p = phonemeindex[pos]) != END) { + if (debug) printf("%d: %c%c\n", pos, signInputTable1[p], signInputTable2[p]); if (p == 0) { // Is phoneme pause? ++pos; continue; } + unsigned char A = p; unsigned char pf = flags[p]; + X = pos; - if ((pf & 16) || p == 78 || p == 79 || p == 80) { - if ((pf & 16)) { // Check for DIPTHONG + if ((pf & FLAG_DIPTHONG) || p == 78 || p == 79 || p == 80) { + if ((pf & FLAG_DIPTHONG)) { // Check for DIPTHONG // RULE: // -> WX // -> YX @@ -572,19 +572,17 @@ void Parser2() { ++pos; continue; - } - - // RULE: - // -> Q - // EXAMPLE: AWAY EIGHT + } else if ((pf & FLAG_VOWEL) && stress[X]) { + // RULE: + // -> Q + // EXAMPLE: AWAY EIGHT - else if ((pf & 128) && stress[X]) { // VOWEL && stressed if (!phonemeindex[X+1]) { // If following phoneme is a pause, get next X+=2; unsigned char Y = phonemeindex[X]; // And VOWEL flag to current phoneme's flags - A = (Y == END) ? 0 : flags[Y] & 128; + A = (Y == END) ? 0 : flags[Y] & FLAG_VOWEL; if (A && stress[X]) { // If following phonemes is not a pause, and is not stressed // Insert a glottal stop and move forward drule("Insert glottal stop between two stressed vowels with space between them"); @@ -601,7 +599,7 @@ void Parser2() { // RULES FOR PHONEMES BEFORE R // Look at prior phoneme X--; - A = prior; + //A = prior; if (prior == pT || prior == pD) { if (prior == pT) { // Example: TRACK @@ -614,14 +612,12 @@ void Parser2() { } A=p; goto pos41812; - } - - // Example: ART - if (flags[prior] & 128) { + } else if (flags[prior] & FLAG_VOWEL) { + // Example: ART drule(" R -> RX"); phonemeindex[pos] = 18; // 'RX' } - } else if (p == 24 && (flags[prior] & 128)) { // 'L' + prior has VOWEL flag set + } else if (p == 24 && (flags[prior] & FLAG_VOWEL)) { // 'L' + prior has VOWEL flag set // Example: ALL drule(" L -> LX"); phonemeindex[X] = 19; // 'LX' @@ -635,12 +631,9 @@ void Parser2() { pos++; continue; - } - - - // K -> KX - // Example: COW - if (A == 72) { // 'K' + } else if (A == 72) { // 'K' + // K -> KX + // Example: COW unsigned char Y = phonemeindex[pos+1]; // If at end, replace current phoneme with KX if ((flags[Y] & 32)==0 || Y==END) { // VOWELS AND DIPTHONGS ENDING WITH IY SOUND flag set? @@ -650,31 +643,24 @@ void Parser2() { } } - // RULE: - // S P -> S B - // S T -> S D - // S K -> S G - // S KX -> S GX - // Examples: SPY, STY, SKY, SCOWL - unsigned char Y = phonemeindex[pos]; // Replace with softer version? if ((flags[Y] & 1) && (prior == 32)) { // 'S' - // Replace with softer version + // RULE: + // S P -> S B + // S T -> S D + // S K -> S G + // S KX -> S GX + // Examples: SPY, STY, SKY, SCOWL + if (debug) printf("RULE: S* %c%c -> S* %c%c\n", signInputTable1[Y], signInputTable2[Y],signInputTable1[Y-12], signInputTable2[Y-12]); phonemeindex[pos] = Y-12; - pos++; - continue; - } - - if (!(flags[Y] & 1)) { + } else if (!(flags[Y] & 1)) { A = phonemeindex[X]; if (A == 53 || A == 42 || A == 44) { if (A == 53) rule_alveolar_uw(X); // Example: NEW, DEW, SUE, ZOO, THOO, TOO else if (A == 42) rule_ch(X,mem59); // Example: CHEW else if (A == 44) rule_j(X,mem59); // Example: JAY - pos++; - continue; } } else { A = Y; @@ -723,7 +709,7 @@ void Parser2() { // - set nasal = 5, consonant = 6 // {optional silence} - shorten both to 1/2 + 1 // - decrease by 2 - +// void AdjustLengths() { // LENGTHEN VOWELS PRECEDING PUNCTUATION // @@ -736,17 +722,14 @@ void AdjustLengths() { unsigned char X = 0; unsigned char index; - // iterate through the phoneme list - unsigned char loopIndex=0; - while((index = phonemeindex[X]) != 255) { + while((index = phonemeindex[X]) != END) { // not punctuation? - if((flags[index] & FLAG_PUNCT) == 0) { // skip + if((flags[index] & FLAG_PUNCT) == 0) { ++X; continue; } - // hold index - loopIndex = X; + unsigned char loopIndex = X; while (--X && !(flags[phonemeindex[X]] & 128)); // back up while not a vowel if (X == 0) break; @@ -755,56 +738,43 @@ void AdjustLengths() { // test for vowel index = phonemeindex[X]; - //if (index != 255)//inserted to prevent access overrun // test for fricative/unvoiced or not voiced - if(((flags[index] & 0x2000) == 0) || ((flags[index] & 4) != 0)) //nochmal überprüfen - { + if(!(flags[index] & FLAG_FRICATIVE) || (flags[index] & FLAG_VOICED)) { //nochmal überprüfen unsigned char A = phonemeLength[X]; - // change phoneme length to (length * 1.5) + 1 - A = (A >> 1) + A + 1; drule_pre("Lengthen or between and by 1.5",X); - phonemeLength[X] = A; + phonemeLength[X] = (A >> 1) + A + 1; drule_post(X); } - // keep moving forward - X++; - } while (X != loopIndex); + } while (++X != loopIndex); X++; } // while // Similar to the above routine, but shorten vowels under some circumstances // Loop throught all phonemes - loopIndex = 0; + unsigned char loopIndex=0; - while((index = phonemeindex[loopIndex]) != 255) { + while((index = phonemeindex[loopIndex]) != END) { unsigned char X = loopIndex; - // vowel? - if (flags[index] & 128) { + if (flags[index] & FLAG_VOWEL) { index = phonemeindex[loopIndex+1]; - - // not a consonant - if ((flags[index] & 64) == 0) { + if (!(flags[index] & FLAG_CONSONANT)) { if ((index == 18) || (index == 19)) { // 'RX', 'LX' index = phonemeindex[loopIndex+2]; - - // next phoneme a consonant? - if ((flags[index] & 64) != 0) { + if ((flags[index] & FLAG_CONSONANT)) { drule_pre(" - decrease length of vowel by 1\n", loopIndex); phonemeLength[loopIndex]--; drule_post(loopIndex); } } - } else { - // Got here if not - - unsigned char flag = (index == 255) ? 65 : flags[index]; // 65 if end marker + } else { // Got here if not + unsigned char flag = (index == END) ? 65 : flags[index]; // 65 if end marker - if (!(flag & 4)) { // Unvoiced + if (!(flag & FLAG_VOICED)) { // Unvoiced // *, .*, ?*, ,*, -*, DX, S*, SH, F*, TH, /H, /X, CH, P*, T*, K*, KX - if((flag & 1)) { // unvoiced plosive + if((flag & FLAG_PLOSIVE)) { // unvoiced plosive // RULE: // drule_pre(" - decrease vowel by 1/8th",loopIndex); @@ -819,43 +789,31 @@ void AdjustLengths() { drule_post(loopIndex); } } - } - - // WH, R*, L*, W*, Y*, M*, N*, NX, Q*, Z*, ZH, V*, DH, J*, B*, D*, G*, GX - - // RULE: - // Set punctuation length to 6 - // Set stop consonant length to 5 - - - else if((flags[index] & FLAG_NASAL) != 0) { // nasal? - // M*, N*, NX, - + } else if((flags[index] & FLAG_NASAL) != 0) { // nasal? + // RULE: + // Set punctuation length to 6 + // Set stop consonant length to 5 index = phonemeindex[++X]; - if (index != 255 && (flags[index] & 2)) { // stop consonant? + if (index != END && (flags[index] & 2)) { // stop consonant? drule(" - set nasal = 5, consonant = 6\n"); phonemeLength[X] = 6; // set stop consonant length to 6 phonemeLength[X-1] = 5; // set nasal length to 5 } - } else if((flags[index] & 2) != 0) { // (voiced) stop consonant? + } else if((flags[index] & FLAG_STOPCONS) != 0) { // (voiced) stop consonant? // RULE: {optional silence} // Shorten both to (length/2 + 1) // move past silence while ((index = phonemeindex[++X]) == 0); - if (index == 255 || (flags[index] & 2) == 0) { - // if end of buffer or another stop consonant, move ahead - loopIndex++; - continue; + if (index != END && (flags[index] & FLAG_STOPCONS)) { + // FIXME, this looks wrong? + // RULE: {optional silence} + drule(" {optional silence} - shorten both to 1/2 + 1"); + phonemeLength[X] = (phonemeLength[X] >> 1) + 1; + phonemeLength[loopIndex] = (phonemeLength[loopIndex] >> 1) + 1; + X = loopIndex; } - - // FIXME, this looks wrong? - // RULE: {optional silence} - if (debug) printf("RULE: {optional silence} - shorten both to 1/2 + 1\n"); - phonemeLength[X] = (phonemeLength[X] >> 1) + 1; - X = loopIndex; - phonemeLength[loopIndex] = (phonemeLength[loopIndex] >> 1) + 1; } else if ((flags[index] & FLAG_LIQUIC) != 0) { // liquic consonant? // WH, R*, L*, W*, Y*, Q*, Z*, ZH, V*, DH, J*, **, @@ -867,7 +825,7 @@ void AdjustLengths() { // FIXME: The debug code here breaks the rule. // prior phoneme a stop consonant> - if((flags[index] & 2) != 0) + if((flags[index] & FLAG_STOPCONS) != 0) drule_pre(" - decrease by 2",X); phonemeLength[X] -= 2; // 20ms From 89d29c95abf2b52024f0bbec9521696551c39917 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sat, 4 Feb 2017 21:32:41 +0000 Subject: [PATCH 095/109] Refactoring --- src/SamTabs.h | 1 + src/sam.c | 220 ++++++++++++++++++++------------------------------ 2 files changed, 87 insertions(+), 134 deletions(-) diff --git a/src/SamTabs.h b/src/SamTabs.h index bd6f8dbd..5761f41c 100644 --- a/src/SamTabs.h +++ b/src/SamTabs.h @@ -44,6 +44,7 @@ enum { FLAG_STOPCONS = 0x0002, /* stop consonant */ FLAG_VOICED = 0x0004, FLAG_DIPTHONG = 0x0010, + FLAG_DIP_YX = 0x0020, /* dipthong ending with YX */ FLAG_CONSONANT= 0x0040, FLAG_VOWEL = 0x0080, FLAG_PUNCT = 0x0100, diff --git a/src/sam.c b/src/sam.c index 61ddb23a..ddfe218e 100644 --- a/src/sam.c +++ b/src/sam.c @@ -83,66 +83,31 @@ void Insert(unsigned char position, unsigned char mem60, unsigned char mem59, un void InsertBreath(unsigned char mem59); void PrepareOutput(); void SetMouthThroat(unsigned char mouth, unsigned char throat); - -// 168=pitches -// 169=frequency1 -// 170=frequency2 -// 171=frequency3 -// 172=amplitude1 -// 173=amplitude2 -// 174=amplitude3 - - -void Init() -{ - int i; - SetMouthThroat( mouth, throat); - - bufferpos = 0; - // TODO, check for free the memory, 10 seconds of output should be more than enough - buffer = malloc(22050*10); - - /* - freq2data = &mem[45136]; - freq1data = &mem[45056]; - freq3data = &mem[45216]; - */ - //pitches = &mem[43008]; - /* - frequency1 = &mem[43264]; - frequency2 = &mem[43520]; - frequency3 = &mem[43776]; - */ - /* - amplitude1 = &mem[44032]; - amplitude2 = &mem[44288]; - amplitude3 = &mem[44544]; - */ - //phoneme = &mem[39904]; - /* - ampl1data = &mem[45296]; - ampl2data = &mem[45376]; - ampl3data = &mem[45456]; - */ - - for(i=0; i<256; i++) - { - stress[i] = 0; - phonemeLength[i] = 0; - } - - for(i=0; i<60; i++) - { - phonemeIndexOutput[i] = 0; - stressOutput[i] = 0; - phonemeLengthOutput[i] = 0; - } - phonemeindex[255] = END; //to prevent buffer overflow // ML : changed from 32 to 255 to stop freezing with long inputs - -} + +void Init() { + int i; + SetMouthThroat( mouth, throat); + + bufferpos = 0; + // TODO, check for free the memory, 10 seconds of output should be more than enough + buffer = malloc(22050*10); + + for(i=0; i<256; i++) { + stress[i] = 0; + phonemeLength[i] = 0; + } + + for(i=0; i<60; i++) { + phonemeIndexOutput[i] = 0; + stressOutput[i] = 0; + phonemeLengthOutput[i] = 0; + } + phonemeindex[255] = END; //to prevent buffer overflow // ML : changed from 32 to 255 to stop freezing with long inputs +} int SAMMain() { Init(); + /* FIXME: At odds with assignment in Init() */ phonemeindex[255] = 32; //to prevent buffer overflow if (!Parser1()) return 0; @@ -517,7 +482,7 @@ void rule_g(unsigned char pos) { unsigned char index = phonemeindex[pos+1]; // If dipthong ending with YX, move continue processing next phoneme - if ((index != 255) && ((flags[index] & 32) == 0)) { + if ((index != 255) && ((flags[index] & FLAG_DIP_YX) == 0)) { // replace G with GX and continue processing next phoneme if (debug) printf("RULE: G -> GX \n"); phonemeindex[pos] = 63; // 'GX' @@ -542,9 +507,10 @@ void Parser2() { continue; } - unsigned char A = p; + unsigned char A = p; unsigned char pf = flags[p]; X = pos; + unsigned char prior = phonemeindex[pos-1]; if ((pf & FLAG_DIPTHONG) || p == 78 || p == 79 || p == 80) { if ((pf & FLAG_DIPTHONG)) { // Check for DIPTHONG @@ -554,7 +520,7 @@ void Parser2() { // Example: OIL, COW // If ends with IY, use YX, else use WX - A = (pf & 32) ? 21 : 20; // 'WX' = 20 'YX' = 21 + A = (pf & FLAG_DIP_YX) ? 21 : 20; // 'WX' = 20 'YX' = 21 // Insert at WX or YX following, copying the stress if (A==20) drule("insert WX following dipthong NOT ending in IY sound"); @@ -569,9 +535,6 @@ void Parser2() { } else if (p == 78) ChangeRule(X, 13, 24, mem59, stress[X],"UL -> AX L"); // Example: MEDDLE else if (p == 79) ChangeRule(X, 13, 27, mem59, stress[X], "UM -> AX M"); // Example: ASTRONOMY else if (p == 80) ChangeRule(X, 13, 28, mem59, stress[X], "UN -> AX N"); // Example: FUNCTION - - ++pos; - continue; } else if ((pf & FLAG_VOWEL) && stress[X]) { // RULE: // -> Q @@ -591,10 +554,7 @@ void Parser2() { continue; } } - } - - unsigned char prior = phonemeindex[pos-1]; - if (p == pR || p == 24 || p == 32 || A == 60) { + } else if (p == pR || p == 24 || p == 32 || p == 60) { if (p == pR) { // 'R' // RULES FOR PHONEMES BEFORE R // Look at prior phoneme @@ -610,8 +570,6 @@ void Parser2() { drule("D R -> J R"); phonemeindex[pos-1] = 44; } - A=p; - goto pos41812; } else if (flags[prior] & FLAG_VOWEL) { // Example: ART drule(" R -> RX"); @@ -628,70 +586,64 @@ void Parser2() { drule("G S -> G Z"); phonemeindex[pos] = 38; // 'Z' } else if (p == 60) rule_g(pos); - - pos++; - continue; - } else if (A == 72) { // 'K' - // K -> KX - // Example: COW - unsigned char Y = phonemeindex[pos+1]; - // If at end, replace current phoneme with KX - if ((flags[Y] & 32)==0 || Y==END) { // VOWELS AND DIPTHONGS ENDING WITH IY SOUND flag set? - if (debug) printf("RULE: K -> KX \n"); - // Replace with KX - phonemeindex[pos] = 75; // 'KX' + } else { + if (A == 72) { // 'K' + // K -> KX + // Example: COW + unsigned char Y = phonemeindex[pos+1]; + // If at end, replace current phoneme with KX + if ((flags[Y] & FLAG_DIP_YX)==0 || Y==END) { // VOWELS AND DIPTHONGS ENDING WITH IY SOUND flag set? + drule("K -> KX "); + phonemeindex[pos] = 75; // 'KX' + } } - } - unsigned char Y = phonemeindex[pos]; - // Replace with softer version? - if ((flags[Y] & 1) && (prior == 32)) { // 'S' - // RULE: - // S P -> S B - // S T -> S D - // S K -> S G - // S KX -> S GX - // Examples: SPY, STY, SKY, SCOWL - - if (debug) printf("RULE: S* %c%c -> S* %c%c\n", signInputTable1[Y], signInputTable2[Y],signInputTable1[Y-12], signInputTable2[Y-12]); - phonemeindex[pos] = Y-12; - } else if (!(flags[Y] & 1)) { - A = phonemeindex[X]; - if (A == 53 || A == 42 || A == 44) { - if (A == 53) rule_alveolar_uw(X); // Example: NEW, DEW, SUE, ZOO, THOO, TOO - else if (A == 42) rule_ch(X,mem59); // Example: CHEW - else if (A == 44) rule_j(X,mem59); // Example: JAY + unsigned char Y = phonemeindex[pos]; + // Replace with softer version? + if ((flags[Y] & FLAG_PLOSIVE) && (prior == 32)) { // 'S' + // RULE: + // S P -> S B + // S T -> S D + // S K -> S G + // S KX -> S GX + // Examples: SPY, STY, SKY, SCOWL + + if (debug) printf("RULE: S* %c%c -> S* %c%c\n", signInputTable1[Y], signInputTable2[Y],signInputTable1[Y-12], signInputTable2[Y-12]); + phonemeindex[pos] = Y-12; + } else if (!(flags[Y] & FLAG_PLOSIVE)) { + A = phonemeindex[X]; + if (A == 53 || A == 42 || A == 44) { + if (A == 53) rule_alveolar_uw(X); // Example: NEW, DEW, SUE, ZOO, THOO, TOO + else if (A == 42) rule_ch(X,mem59); // Example: CHEW + else if (A == 44) rule_j(X,mem59); // Example: JAY + } + } else { + A = Y; } - } else { - A = Y; - } - - // Jump here to continue - pos41812: - // RULE: Soften T following vowel - // NOTE: This rule fails for cases such as "ODD" - // T -> DX - // D -> DX - // Example: PARTY, TARDY - - if (A == 69 || A == 57) { // 'T', 'D' - - // If prior phoneme is not a vowel, continue processing phonemes - if (flags[phonemeindex[X-1]] & 128) { - if ((A = phonemeindex[++X])) { - if (flags[A] & 128) { // pause - // FIXME: How does a pause get stressed? - if (stress[X] == 0) { // unstressed - // Set phonemes to DX - if (debug) printf("RULE: Soften T or D following vowel or ER and preceding a pause -> DX\n"); - phonemeindex[pos] = 30; // 'DX' + + if (A == 69 || A == 57) { // 'T', 'D' + // RULE: Soften T following vowel + // NOTE: This rule fails for cases such as "ODD" + // T -> DX + // D -> DX + // Example: PARTY, TARDY + + if (flags[phonemeindex[X-1]] & FLAG_VOWEL) { + if ((A = phonemeindex[++X])) { + if (flags[A] & FLAG_VOWEL) { // pause + // FIXME: How does a pause get stressed? + if (stress[X] == 0) { // unstressed + // Set phonemes to DX + drule("Soften T or D following vowel or ER and preceding a pause -> DX"); + phonemeindex[pos] = 30; // 'DX' + } + } + } else { + A = phonemeindex[X+1]; + if (A != END && (flags[A] & FLAG_VOWEL)) { // Next phoneme is a vowel or ER + drule("Soften T or D following vowel or ER and preceding a pause -> DX"); + if (A != 0) phonemeindex[pos] = 30; // 'DX' } - } - } else { - A = phonemeindex[X+1]; - if (A != END && (flags[A] & 128)) { // Next phoneme is a vowel or ER - if (debug) printf("RULE: Soften T or D following vowel or ER and preceding a pause -> DX\n"); - if (A != 0) phonemeindex[pos] = 30; // 'DX' } } } @@ -731,7 +683,7 @@ void AdjustLengths() { unsigned char loopIndex = X; - while (--X && !(flags[phonemeindex[X]] & 128)); // back up while not a vowel + while (--X && !(flags[phonemeindex[X]] & FLAG_VOWEL)); // back up while not a vowel if (X == 0) break; do { @@ -794,12 +746,12 @@ void AdjustLengths() { // Set punctuation length to 6 // Set stop consonant length to 5 index = phonemeindex[++X]; - if (index != END && (flags[index] & 2)) { // stop consonant? - drule(" - set nasal = 5, consonant = 6\n"); + if (index != END && (flags[index] & FLAG_STOPCONS)) { + drule(" - set nasal = 5, consonant = 6"); phonemeLength[X] = 6; // set stop consonant length to 6 phonemeLength[X-1] = 5; // set nasal length to 5 } - } else if((flags[index] & FLAG_STOPCONS) != 0) { // (voiced) stop consonant? + } else if((flags[index] & FLAG_STOPCONS)) { // (voiced) stop consonant? // RULE: {optional silence} // Shorten both to (length/2 + 1) @@ -814,7 +766,7 @@ void AdjustLengths() { phonemeLength[loopIndex] = (phonemeLength[loopIndex] >> 1) + 1; X = loopIndex; } - } else if ((flags[index] & FLAG_LIQUIC) != 0) { // liquic consonant? + } else if ((flags[index] & FLAG_LIQUIC)) { // liquic consonant? // WH, R*, L*, W*, Y*, Q*, Z*, ZH, V*, DH, J*, **, // RULE: From 8e32e5c20dcbd0b890e26e65a6a33a2b45bed8db Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sat, 4 Feb 2017 22:35:29 +0000 Subject: [PATCH 096/109] Refactoring --- src/SamTabs.h | 2 + src/sam.c | 130 ++++++++++++++++++++++---------------------------- 2 files changed, 58 insertions(+), 74 deletions(-) diff --git a/src/SamTabs.h b/src/SamTabs.h index 5761f41c..88a39fd3 100644 --- a/src/SamTabs.h +++ b/src/SamTabs.h @@ -43,11 +43,13 @@ enum { FLAG_PLOSIVE = 0x0001, FLAG_STOPCONS = 0x0002, /* stop consonant */ FLAG_VOICED = 0x0004, + /* 0x08 */ FLAG_DIPTHONG = 0x0010, FLAG_DIP_YX = 0x0020, /* dipthong ending with YX */ FLAG_CONSONANT= 0x0040, FLAG_VOWEL = 0x0080, FLAG_PUNCT = 0x0100, + /* 0x200 */ FLAG_ALVEOLAR = 0x0400, FLAG_NASAL = 0x0800, FLAG_LIQUIC = 0x1000, /* liquic consonant */ diff --git a/src/sam.c b/src/sam.c index ddfe218e..fa1a721e 100644 --- a/src/sam.c +++ b/src/sam.c @@ -380,31 +380,25 @@ void SetPhonemeLength() { void Code41240() { unsigned char pos=0; - while(phonemeindex[pos] != 255) { - unsigned char index; //register AC - unsigned char X = pos; - index = phonemeindex[pos]; - if ((flags[index]&2) == 0) { - pos++; - continue; - } else if ((flags[index]&1) == 0) { - Insert(pos+1, index+1, phonemeLengthTable[index+1], stress[pos]); - Insert(pos+2, index+2, phonemeLengthTable[index+2], stress[pos]); - pos += 3; - continue; - } - - unsigned char A; - while(!(A = phonemeindex[++X])); - - if (A != 255) { - if (flags[A] & 8) { ++pos; continue;} - if ((A == 36) || (A == 37)) {++pos; continue;} // '/H' '/X' - } - - Insert(pos+1, index+1, phonemeLengthTable[index+1], stress[pos]); - Insert(pos+2, index+2, phonemeLengthTable[index+2], stress[pos]); - pos += 3; + while(phonemeindex[pos] != END) { + unsigned char index = phonemeindex[pos]; + + if ((flags[index]& FLAG_STOPCONS)) { + if ((flags[index]& FLAG_PLOSIVE)) { + unsigned char A; + unsigned char X = pos; + while(!(A = phonemeindex[++X])); /* Skip pause */ + + if (A != END) { + if ((flags[A] & 8) || (A == 36) || (A == 37)) {++pos; continue;} // '/H' '/X' + } + + } + Insert(pos+1, index+1, phonemeLengthTable[index+1], stress[pos]); + Insert(pos+2, index+2, phonemeLengthTable[index+2], stress[pos]); + pos += 2; + } + ++pos; } } @@ -484,7 +478,7 @@ void rule_g(unsigned char pos) { // If dipthong ending with YX, move continue processing next phoneme if ((index != 255) && ((flags[index] & FLAG_DIP_YX) == 0)) { // replace G with GX and continue processing next phoneme - if (debug) printf("RULE: G -> GX \n"); + drule("G -> GX "); phonemeindex[pos] = 63; // 'GX' } } @@ -554,40 +548,31 @@ void Parser2() { continue; } } - } else if (p == pR || p == 24 || p == 32 || p == 60) { - if (p == pR) { // 'R' - // RULES FOR PHONEMES BEFORE R - // Look at prior phoneme - X--; - //A = prior; - if (prior == pT || prior == pD) { - if (prior == pT) { - // Example: TRACK - drule("T R -> CH R"); - phonemeindex[pos-1] = 42; - } else if (prior == pD) { - // Example: DRY - drule("D R -> J R"); - phonemeindex[pos-1] = 44; - } - } else if (flags[prior] & FLAG_VOWEL) { - // Example: ART - drule(" R -> RX"); - phonemeindex[pos] = 18; // 'RX' - } - } else if (p == 24 && (flags[prior] & FLAG_VOWEL)) { // 'L' + prior has VOWEL flag set - // Example: ALL - drule(" L -> LX"); - phonemeindex[X] = 19; // 'LX' - } else if (prior == 60 && p == 32) { // 'G' 'S' - // Can't get to fire - - // 1. The G -> GX rule intervenes - // 2. Reciter already replaces GS -> GZ - drule("G S -> G Z"); - phonemeindex[pos] = 38; // 'Z' - } else if (p == 60) rule_g(pos); - } else { - if (A == 72) { // 'K' + } else if (p == pR) { // 'R' + // RULES FOR PHONEMES BEFORE R + if (prior == pT) { // Example: TRACK + drule("T R -> CH R"); + phonemeindex[pos-1] = 42; + } else if (prior == pD) { // Example: DRY + drule("D R -> J R"); + phonemeindex[pos-1] = 44; + } else if (flags[prior] & FLAG_VOWEL) { // Example: ART + drule(" R -> RX"); + phonemeindex[pos] = 18; // 'RX' + } + } else if (p == 24 && (flags[prior] & FLAG_VOWEL)) { // 'L' + prior has VOWEL flag set + // Example: ALL + drule(" L -> LX"); + phonemeindex[X] = 19; // 'LX' + } else if (prior == 60 && p == 32) { // 'G' 'S' + // Can't get to fire - + // 1. The G -> GX rule intervenes + // 2. Reciter already replaces GS -> GZ + drule("G S -> G Z"); + phonemeindex[pos] = 38; // 'Z' + } else if (p == 60) rule_g(pos); + else { + if (p == 72) { // 'K' // K -> KX // Example: COW unsigned char Y = phonemeindex[pos+1]; @@ -595,12 +580,13 @@ void Parser2() { if ((flags[Y] & FLAG_DIP_YX)==0 || Y==END) { // VOWELS AND DIPTHONGS ENDING WITH IY SOUND flag set? drule("K -> KX "); phonemeindex[pos] = 75; // 'KX' + p = 75; + pf = flags[p]; } } - unsigned char Y = phonemeindex[pos]; // Replace with softer version? - if ((flags[Y] & FLAG_PLOSIVE) && (prior == 32)) { // 'S' + if ((flags[p] & FLAG_PLOSIVE) && (prior == 32)) { // 'S' // RULE: // S P -> S B // S T -> S D @@ -608,20 +594,16 @@ void Parser2() { // S KX -> S GX // Examples: SPY, STY, SKY, SCOWL - if (debug) printf("RULE: S* %c%c -> S* %c%c\n", signInputTable1[Y], signInputTable2[Y],signInputTable1[Y-12], signInputTable2[Y-12]); - phonemeindex[pos] = Y-12; - } else if (!(flags[Y] & FLAG_PLOSIVE)) { - A = phonemeindex[X]; - if (A == 53 || A == 42 || A == 44) { - if (A == 53) rule_alveolar_uw(X); // Example: NEW, DEW, SUE, ZOO, THOO, TOO - else if (A == 42) rule_ch(X,mem59); // Example: CHEW - else if (A == 44) rule_j(X,mem59); // Example: JAY - } - } else { - A = Y; + if (debug) printf("RULE: S* %c%c -> S* %c%c\n", signInputTable1[p], signInputTable2[p],signInputTable1[p-12], signInputTable2[p-12]); + phonemeindex[pos] = p-12; + } else if (!(pf & FLAG_PLOSIVE)) { + p = phonemeindex[X]; + if (p == 53) rule_alveolar_uw(X); // Example: NEW, DEW, SUE, ZOO, THOO, TOO + else if (p == 42) rule_ch(X,mem59); // Example: CHEW + else if (p == 44) rule_j(X,mem59); // Example: JAY } - if (A == 69 || A == 57) { // 'T', 'D' + if (p == 69 || p == 57) { // 'T', 'D' // RULE: Soften T following vowel // NOTE: This rule fails for cases such as "ODD" // T -> DX From a295faf460487ebf6b3f3a649fd88d2834d36334 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Thu, 9 Feb 2017 00:41:32 +0000 Subject: [PATCH 097/109] Refactoring --- src/createtransitions.c | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/src/createtransitions.c b/src/createtransitions.c index f3da1596..5940246d 100644 --- a/src/createtransitions.c +++ b/src/createtransitions.c @@ -122,6 +122,20 @@ void interpolate(unsigned char width, unsigned char table, unsigned char frame, } } +void interpolate_pitch(unsigned char width, unsigned char pos, unsigned char mem49, unsigned char phase3) { + // unlike the other values, the pitches[] interpolates from + // the middle of the current phoneme to the middle of the + // next phoneme + + // half the width of the current and next phoneme + unsigned char cur_width = phonemeLengthOutput[pos] / 2; + unsigned char next_width = phonemeLengthOutput[pos+1] / 2; + // sum the values + width = cur_width + next_width; + unsigned char pitch = pitches[next_width + mem49] - pitches[mem49- cur_width]; + interpolate(width, 168, phase3, pitch); +} + unsigned char CreateTransitions() { @@ -162,7 +176,9 @@ unsigned char CreateTransitions() unsigned char transition = phase1 + phase2; // total transition? if (((transition - 2) & 128) == 0) { - unsigned table = 168; + + interpolate_pitch(transition, pos, mem49, phase3); + unsigned table = 169; while (table < 175) { // tables: // 168 pitches[] @@ -173,25 +189,8 @@ unsigned char CreateTransitions() // 173 amplitude2 // 174 amplitude3 - // number of frames to interpolate over - unsigned char width = transition; - - unsigned char mem53; - if (table == 168) { // pitch - // unlike the other values, the pitches[] interpolates from - // the middle of the current phoneme to the middle of the - // next phoneme - - // half the width of the current and next phoneme - unsigned char cur_width = phonemeLengthOutput[pos] / 2; - unsigned char next_width = phonemeLengthOutput[pos+1] / 2; - // sum the values - width = cur_width + next_width; - mem53 = pitches[next_width + mem49] - pitches[mem49- cur_width]; - } else { - mem53 = Read(table, speedcounter) - Read(table, phase3); - } - interpolate(width, table, phase3, mem53); + unsigned char value = Read(table, speedcounter) - Read(table, phase3); + interpolate(transition, table, phase3, value); table++; } } From b0f9df49148db07216563e1395c53713ade74667 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Thu, 9 Feb 2017 00:47:16 +0000 Subject: [PATCH 098/109] Refactoring --- src/sam.c | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/src/sam.c b/src/sam.c index fa1a721e..49a35e20 100644 --- a/src/sam.c +++ b/src/sam.c @@ -506,30 +506,29 @@ void Parser2() { X = pos; unsigned char prior = phonemeindex[pos-1]; - if ((pf & FLAG_DIPTHONG) || p == 78 || p == 79 || p == 80) { - if ((pf & FLAG_DIPTHONG)) { // Check for DIPTHONG - // RULE: - // -> WX - // -> YX - // Example: OIL, COW + if ((pf & FLAG_DIPTHONG)) { // Check for DIPTHONG + // RULE: + // -> WX + // -> YX + // Example: OIL, COW - // If ends with IY, use YX, else use WX - A = (pf & FLAG_DIP_YX) ? 21 : 20; // 'WX' = 20 'YX' = 21 + // If ends with IY, use YX, else use WX + A = (pf & FLAG_DIP_YX) ? 21 : 20; // 'WX' = 20 'YX' = 21 - // Insert at WX or YX following, copying the stress - if (A==20) drule("insert WX following dipthong NOT ending in IY sound"); - if (A==21) drule("insert YX following dipthong ending in IY sound"); - Insert(pos+1, A, mem59, stress[pos]); + // Insert at WX or YX following, copying the stress + if (A==20) drule("insert WX following dipthong NOT ending in IY sound"); + if (A==21) drule("insert YX following dipthong ending in IY sound"); + Insert(pos+1, A, mem59, stress[pos]); - if (p == 53 || p == 42 || p == 44) { - if (p == 53) rule_alveolar_uw(pos); // Example: NEW, DEW, SUE, ZOO, THOO, TOO - else if (p == 42) rule_ch(pos,mem59); // Example: CHEW - else if (p == 44) rule_j(pos,mem59); // Example: JAY - } - } else if (p == 78) ChangeRule(X, 13, 24, mem59, stress[X],"UL -> AX L"); // Example: MEDDLE - else if (p == 79) ChangeRule(X, 13, 27, mem59, stress[X], "UM -> AX M"); // Example: ASTRONOMY - else if (p == 80) ChangeRule(X, 13, 28, mem59, stress[X], "UN -> AX N"); // Example: FUNCTION - } else if ((pf & FLAG_VOWEL) && stress[X]) { + if (p == 53 || p == 42 || p == 44) { + if (p == 53) rule_alveolar_uw(pos); // Example: NEW, DEW, SUE, ZOO, THOO, TOO + else if (p == 42) rule_ch(pos,mem59); // Example: CHEW + else if (p == 44) rule_j(pos,mem59); // Example: JAY + } + } else if (p == 78) ChangeRule(X, 13, 24, mem59, stress[X],"UL -> AX L"); // Example: MEDDLE + else if (p == 79) ChangeRule(X, 13, 27, mem59, stress[X], "UM -> AX M"); // Example: ASTRONOMY + else if (p == 80) ChangeRule(X, 13, 28, mem59, stress[X], "UN -> AX N"); // Example: FUNCTION + else if ((pf & FLAG_VOWEL) && stress[X]) { // RULE: // -> Q // EXAMPLE: AWAY EIGHT From 3412ef414f9b978162da1af9f87a7ec7e371e016 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Thu, 9 Feb 2017 00:47:53 +0000 Subject: [PATCH 099/109] Refactoring --- src/sam.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/sam.c b/src/sam.c index 49a35e20..f7861f14 100644 --- a/src/sam.c +++ b/src/sam.c @@ -543,8 +543,6 @@ void Parser2() { // Insert a glottal stop and move forward drule("Insert glottal stop between two stressed vowels with space between them"); Insert(X, 31, mem59, 0); // 31 = 'Q' - pos++; - continue; } } } else if (p == pR) { // 'R' From 45519ea748e3ee76f5e56c7768470fc089478cb9 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Thu, 9 Feb 2017 01:03:00 +0000 Subject: [PATCH 100/109] Refactoring --- src/sam.c | 58 +++++++++++++++++++------------------------------------ 1 file changed, 20 insertions(+), 38 deletions(-) diff --git a/src/sam.c b/src/sam.c index f7861f14..8405bd3a 100644 --- a/src/sam.c +++ b/src/sam.c @@ -484,7 +484,10 @@ void rule_g(unsigned char pos) { } - +void change(unsigned char pos, unsigned char val, const char * rule) { + drule(rule); + phonemeindex[pos] = val; +} void Parser2() { @@ -501,7 +504,6 @@ void Parser2() { continue; } - unsigned char A = p; unsigned char pf = flags[p]; X = pos; unsigned char prior = phonemeindex[pos-1]; @@ -513,7 +515,7 @@ void Parser2() { // Example: OIL, COW // If ends with IY, use YX, else use WX - A = (pf & FLAG_DIP_YX) ? 21 : 20; // 'WX' = 20 'YX' = 21 + unsigned char A = (pf & FLAG_DIP_YX) ? 21 : 20; // 'WX' = 20 'YX' = 21 // Insert at WX or YX following, copying the stress if (A==20) drule("insert WX following dipthong NOT ending in IY sound"); @@ -538,7 +540,7 @@ void Parser2() { unsigned char Y = phonemeindex[X]; // And VOWEL flag to current phoneme's flags - A = (Y == END) ? 0 : flags[Y] & FLAG_VOWEL; + unsigned char A = (Y == END) ? 0 : flags[Y] & FLAG_VOWEL; if (A && stress[X]) { // If following phonemes is not a pause, and is not stressed // Insert a glottal stop and move forward drule("Insert glottal stop between two stressed vowels with space between them"); @@ -547,37 +549,25 @@ void Parser2() { } } else if (p == pR) { // 'R' // RULES FOR PHONEMES BEFORE R - if (prior == pT) { // Example: TRACK - drule("T R -> CH R"); - phonemeindex[pos-1] = 42; - } else if (prior == pD) { // Example: DRY - drule("D R -> J R"); - phonemeindex[pos-1] = 44; - } else if (flags[prior] & FLAG_VOWEL) { // Example: ART - drule(" R -> RX"); - phonemeindex[pos] = 18; // 'RX' - } - } else if (p == 24 && (flags[prior] & FLAG_VOWEL)) { // 'L' + prior has VOWEL flag set - // Example: ALL - drule(" L -> LX"); - phonemeindex[X] = 19; // 'LX' - } else if (prior == 60 && p == 32) { // 'G' 'S' + if (prior == pT) change(pos-1,42, "T R -> CH R"); // Example: TRACK + else if (prior == pD) change(pos-1,44, "D R -> J R"); // Example: DRY + else if (flags[prior] & FLAG_VOWEL) change(pos, 18, " R -> RX"); // Example: ART + } else if (p == 24 && (flags[prior] & FLAG_VOWEL)) change(X, 19, " L -> LX"); // Example: ALL + else if (prior == 60 && p == 32) { // 'G' 'S' // Can't get to fire - // 1. The G -> GX rule intervenes // 2. Reciter already replaces GS -> GZ - drule("G S -> G Z"); - phonemeindex[pos] = 38; // 'Z' + change(pos, 38, "G S -> G Z"); } else if (p == 60) rule_g(pos); else { if (p == 72) { // 'K' - // K -> KX + // K -> KX // Example: COW unsigned char Y = phonemeindex[pos+1]; // If at end, replace current phoneme with KX if ((flags[Y] & FLAG_DIP_YX)==0 || Y==END) { // VOWELS AND DIPTHONGS ENDING WITH IY SOUND flag set? - drule("K -> KX "); - phonemeindex[pos] = 75; // 'KX' - p = 75; + change(pos, 75, "K -> KX "); + p = 75; pf = flags[p]; } } @@ -607,21 +597,17 @@ void Parser2() { // D -> DX // Example: PARTY, TARDY + unsigned char A; if (flags[phonemeindex[X-1]] & FLAG_VOWEL) { if ((A = phonemeindex[++X])) { if (flags[A] & FLAG_VOWEL) { // pause // FIXME: How does a pause get stressed? - if (stress[X] == 0) { // unstressed - // Set phonemes to DX - drule("Soften T or D following vowel or ER and preceding a pause -> DX"); - phonemeindex[pos] = 30; // 'DX' - } + if (stress[X] == 0) change(pos,30, "Soften T or D following vowel or ER and preceding a pause -> DX"); } } else { - A = phonemeindex[X+1]; - if (A != END && (flags[A] & FLAG_VOWEL)) { // Next phoneme is a vowel or ER - drule("Soften T or D following vowel or ER and preceding a pause -> DX"); - if (A != 0) phonemeindex[pos] = 30; // 'DX' + p = phonemeindex[X+1]; + if (p != END && p && (flags[p] & FLAG_VOWEL)) { // Next phoneme is a vowel or ER + change(pos,30, "Soften T or D following vowel or ER and preceding a pause -> DX"); } } } @@ -746,12 +732,8 @@ void AdjustLengths() { X = loopIndex; } } else if ((flags[index] & FLAG_LIQUIC)) { // liquic consonant? - // WH, R*, L*, W*, Y*, Q*, Z*, ZH, V*, DH, J*, **, - // RULE: // Decrease by 2 - // R*, L*, W*, Y* - index = phonemeindex[X-1]; // prior phoneme; // FIXME: The debug code here breaks the rule. From 4c53c43994d43287f6974efd8c2cfdbb9cfad51c Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Thu, 9 Feb 2017 01:29:52 +0000 Subject: [PATCH 101/109] Refactoring --- src/sam.c | 94 +++++++++++++++++++++++-------------------------------- 1 file changed, 39 insertions(+), 55 deletions(-) diff --git a/src/sam.c b/src/sam.c index 8405bd3a..beaf01df 100644 --- a/src/sam.c +++ b/src/sam.c @@ -490,6 +490,26 @@ void change(unsigned char pos, unsigned char val, const char * rule) { } +void rule_dipthong(unsigned char p, unsigned char pf, unsigned char pos, unsigned char mem59) { + // -> WX + // -> YX + // Example: OIL, COW + + // If ends with IY, use YX, else use WX + unsigned char A = (pf & FLAG_DIP_YX) ? 21 : 20; // 'WX' = 20 'YX' = 21 + + // Insert at WX or YX following, copying the stress + if (A==20) drule("insert WX following dipthong NOT ending in IY sound"); + if (A==21) drule("insert YX following dipthong ending in IY sound"); + Insert(pos+1, A, mem59, stress[pos]); + + if (p == 53 || p == 42 || p == 44) { + if (p == 53) rule_alveolar_uw(pos); // Example: NEW, DEW, SUE, ZOO, THOO, TOO + else if (p == 42) rule_ch(pos,mem59); // Example: CHEW + else if (p == 44) rule_j(pos,mem59); // Example: JAY + } +} + void Parser2() { unsigned char pos = 0; //mem66; unsigned char p; @@ -505,54 +525,28 @@ void Parser2() { } unsigned char pf = flags[p]; - X = pos; unsigned char prior = phonemeindex[pos-1]; - if ((pf & FLAG_DIPTHONG)) { // Check for DIPTHONG - // RULE: - // -> WX - // -> YX - // Example: OIL, COW - - // If ends with IY, use YX, else use WX - unsigned char A = (pf & FLAG_DIP_YX) ? 21 : 20; // 'WX' = 20 'YX' = 21 - - // Insert at WX or YX following, copying the stress - if (A==20) drule("insert WX following dipthong NOT ending in IY sound"); - if (A==21) drule("insert YX following dipthong ending in IY sound"); - Insert(pos+1, A, mem59, stress[pos]); - - if (p == 53 || p == 42 || p == 44) { - if (p == 53) rule_alveolar_uw(pos); // Example: NEW, DEW, SUE, ZOO, THOO, TOO - else if (p == 42) rule_ch(pos,mem59); // Example: CHEW - else if (p == 44) rule_j(pos,mem59); // Example: JAY - } - } else if (p == 78) ChangeRule(X, 13, 24, mem59, stress[X],"UL -> AX L"); // Example: MEDDLE - else if (p == 79) ChangeRule(X, 13, 27, mem59, stress[X], "UM -> AX M"); // Example: ASTRONOMY - else if (p == 80) ChangeRule(X, 13, 28, mem59, stress[X], "UN -> AX N"); // Example: FUNCTION - else if ((pf & FLAG_VOWEL) && stress[X]) { + if ((pf & FLAG_DIPTHONG)) rule_dipthong(p, pf, pos, mem59); + else if (p == 78) ChangeRule(pos, 13, 24, mem59, stress[pos],"UL -> AX L"); // Example: MEDDLE + else if (p == 79) ChangeRule(pos, 13, 27, mem59, stress[pos], "UM -> AX M"); // Example: ASTRONOMY + else if (p == 80) ChangeRule(pos, 13, 28, mem59, stress[pos], "UN -> AX N"); // Example: FUNCTION + else if ((pf & FLAG_VOWEL) && stress[pos]) { // RULE: // -> Q // EXAMPLE: AWAY EIGHT - - if (!phonemeindex[X+1]) { // If following phoneme is a pause, get next - X+=2; - unsigned char Y = phonemeindex[X]; - - // And VOWEL flag to current phoneme's flags - unsigned char A = (Y == END) ? 0 : flags[Y] & FLAG_VOWEL; - if (A && stress[X]) { // If following phonemes is not a pause, and is not stressed - // Insert a glottal stop and move forward + if (!phonemeindex[pos+1]) { // If following phoneme is a pause, get next + p = phonemeindex[pos+2]; + if (p!=END && (flags[p] & FLAG_VOWEL) && stress[pos+2]) { drule("Insert glottal stop between two stressed vowels with space between them"); - Insert(X, 31, mem59, 0); // 31 = 'Q' + Insert(pos+2, 31, mem59, 0); // 31 = 'Q' } } - } else if (p == pR) { // 'R' - // RULES FOR PHONEMES BEFORE R + } else if (p == pR) { // RULES FOR PHONEMES BEFORE R if (prior == pT) change(pos-1,42, "T R -> CH R"); // Example: TRACK else if (prior == pD) change(pos-1,44, "D R -> J R"); // Example: DRY else if (flags[prior] & FLAG_VOWEL) change(pos, 18, " R -> RX"); // Example: ART - } else if (p == 24 && (flags[prior] & FLAG_VOWEL)) change(X, 19, " L -> LX"); // Example: ALL + } else if (p == 24 && (flags[prior] & FLAG_VOWEL)) change(pos, 19, " L -> LX"); // Example: ALL else if (prior == 60 && p == 32) { // 'G' 'S' // Can't get to fire - // 1. The G -> GX rule intervenes @@ -584,10 +578,10 @@ void Parser2() { if (debug) printf("RULE: S* %c%c -> S* %c%c\n", signInputTable1[p], signInputTable2[p],signInputTable1[p-12], signInputTable2[p-12]); phonemeindex[pos] = p-12; } else if (!(pf & FLAG_PLOSIVE)) { - p = phonemeindex[X]; - if (p == 53) rule_alveolar_uw(X); // Example: NEW, DEW, SUE, ZOO, THOO, TOO - else if (p == 42) rule_ch(X,mem59); // Example: CHEW - else if (p == 44) rule_j(X,mem59); // Example: JAY + p = phonemeindex[pos]; + if (p == 53) rule_alveolar_uw(pos); // Example: NEW, DEW, SUE, ZOO, THOO, TOO + else if (p == 42) rule_ch(pos,mem59); // Example: CHEW + else if (p == 44) rule_j(pos,mem59); // Example: JAY } if (p == 69 || p == 57) { // 'T', 'D' @@ -596,20 +590,10 @@ void Parser2() { // T -> DX // D -> DX // Example: PARTY, TARDY - - unsigned char A; - if (flags[phonemeindex[X-1]] & FLAG_VOWEL) { - if ((A = phonemeindex[++X])) { - if (flags[A] & FLAG_VOWEL) { // pause - // FIXME: How does a pause get stressed? - if (stress[X] == 0) change(pos,30, "Soften T or D following vowel or ER and preceding a pause -> DX"); - } - } else { - p = phonemeindex[X+1]; - if (p != END && p && (flags[p] & FLAG_VOWEL)) { // Next phoneme is a vowel or ER - change(pos,30, "Soften T or D following vowel or ER and preceding a pause -> DX"); - } - } + if (flags[phonemeindex[pos-1]] & FLAG_VOWEL) { + p = phonemeindex[pos+1]; + if (!p) p = phonemeindex[pos+2]; + if ((flags[p] & FLAG_VOWEL) && !stress[pos+1]) change(pos,30, "Soften T or D following vowel or ER and preceding a pause -> DX"); } } } From 5a4b88b387316309ef7636fc332b5e66906d8694 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sat, 11 Feb 2017 20:33:26 +0000 Subject: [PATCH 102/109] Refactoring --- src/reciter.c | 205 +++++++++++++++++++++++++------------------------- 1 file changed, 102 insertions(+), 103 deletions(-) diff --git a/src/reciter.c b/src/reciter.c index 80cffd4d..55f37a17 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -26,22 +26,55 @@ unsigned int match(const char * str) { return 1; } -unsigned char GetRuleByte(unsigned short mem62, unsigned char Y) -{ - unsigned int address = mem62; - - if (mem62 >= 37541) - { - address -= 37541; - return rules2[address+Y]; - } - address -= 32000; - return rules[address+Y]; -} - -int TextToPhonemes(char *input) -{ - unsigned char mem56; //output position for phonemes +unsigned char GetRuleByte(unsigned short mem62, unsigned char Y) { + unsigned int address = mem62; + if (mem62 >= 37541) { + address -= 37541; + return rules2[address+Y]; + } + address -= 32000; + return rules[address+Y]; +} + +int handle_ch2(unsigned char ch, unsigned char mem) { + if (ch == ' ') { + if(Code37055(mem,128)) return 1; + } else if (ch == '#') { + if(!Code37055(mem, 64)) return 1; + } else if (ch == '.') { + if(!Code37055(mem,8)) return 1; + } else if (ch == '^') { + if(!Code37055(mem,32)) return 1; + } else return -1; + return 0; +} + + +int handle_ch(unsigned char A, unsigned char mem) { + if (A == ' ') { + if (Code37055(mem, 128) != 0) return 1; + } else if (A == '#') { + if (Code37055(mem, 64) == 0) return 1; + } else if (A == '.') { + if(Code37055(mem, 8) == 0) return 1; + } else if (A == '&') { + if(Code37055(mem, 16) == 0) { + if (inputtemp[X] != 72) return 1; + ++X; + } + } else if (A == '^') { + if (Code37055(mem, 32) == 0) return 1; + } else if (A == '+') { + X = mem; + A = inputtemp[X]; + if ((A != 69) && (A != 73) && (A != 89)) return 1; + } else return -1; + return 0; +} + + +int TextToPhonemes(char *input) { + unsigned char mem56; //output position for phonemes unsigned char mem58; unsigned char mem60; unsigned char mem61; @@ -111,8 +144,8 @@ int TextToPhonemes(char *input) pos36700: // find next rule while ((GetRuleByte(++mem62, 0) & 128) == 0); - unsigned char Y = 1; - while(GetRuleByte(mem62, Y) != '(') ++Y; + unsigned char Y = 0; + while(GetRuleByte(mem62, ++Y) != '('); mem66 = Y; while(GetRuleByte(mem62, ++Y) != ')'); mem65 = Y; @@ -150,70 +183,51 @@ int TextToPhonemes(char *input) } unsigned char ch = mem57; - switch(ch) { - case ' ': - if(Code37055(mem59-1,128)) goto pos36700; - break; - - case '#': - if(!Code37055(mem59-1, 64)) goto pos36700; - break; - - case '.': - if(!Code37055(mem59-1,8)) goto pos36700; - break; - - case '&': - if (!Code37055(mem59-1,16)) { - if (inputtemp[X] != 'H') goto pos36700; + + int r = handle_ch2(ch, mem59-1); + if (r == -1) { + switch (ch) { + case '&': + if (!Code37055(mem59-1,16)) { + if (inputtemp[X] != 'H') r = 1; + A = inputtemp[--X]; + if ((A != 'C') && (A != 'S')) r = 1; + } + break; + + case '@': + if(!Code37055(mem59-1,4)) { + A = inputtemp[X]; + if (A != 72) r = 1; + if ((A != 84) && (A != 67) && (A != 83)) r = 1; + } + break; + case '+': + X = mem59; A = inputtemp[--X]; - if ((A != 'C') && (A != 'S')) goto pos36700; - } - break; - - case '@': - if(!Code37055(mem59-1,4)) { - A = inputtemp[X]; - if (A != 72) goto pos36700; - if ((A != 84) && (A != 67) && (A != 83)) goto pos36700; + if ((A != 'E') && (A != 'I') && (A && 'Y')) r = 1; + break; + case ':': + while (Code37055(mem59-1,32)) --mem59; + continue; + default: + return 0; } - break; - - case '^': - if(!Code37055(mem59-1,32)) goto pos36700; - break; - - case '+': - X = mem59; - X--; - A = inputtemp[X]; - if ((A != 'E') && (A != 'I') && (A && 'Y')) goto pos36700; - break; - - case ':': - while (Code37055(mem59-1,32)) --mem59; - continue; - - default: - return 0; } - + + if (r == 1) goto pos36700; + mem59 = X; } do { X = mem58+1; - if (inputtemp[X] == 'E') { if((tab36376[inputtemp[X+1]] & 128) != 0) { A = inputtemp[++X]; - if ((A != 'R') && (A != 'S') && (A != 'D')) { - if (A == 'L') { - if (inputtemp[++X] != 'Y') goto pos36700; - } else { - if (!match("FUL")) goto pos36700; - } - } + if (A == 'L') { + if (inputtemp[++X] != 'Y') goto pos36700; + } else if ((A != 'R') && (A != 'S') && (A != 'D') && !match("FUL")) goto pos36700; } } else { if (!match("ING")) goto pos36700; @@ -221,7 +235,9 @@ int TextToPhonemes(char *input) } pos37184: - while (1) { + X; + int r = 0; + do { unsigned char mem57; while (1) { unsigned char Y = mem65 + 1; @@ -246,43 +262,26 @@ int TextToPhonemes(char *input) } A = mem57; - if (A == ' ') { - if (Code37055(mem58+1, 128) != 0) goto pos36700; - } else if (A == '#') { - if (Code37055(mem58+1, 64) == 0) goto pos36700; - } else if (A == '.') { - if(Code37055(mem58+1, 8) == 0) goto pos36700; - } else if (A == '&') { - if(Code37055(mem58+1, 16) == 0) { - if (inputtemp[X] != 72) goto pos36700; - A = inputtemp[++X]; - if ((A == 67) || (A == 83)) { - mem58 = X; - continue; - } - } - } else if (A == '@') { + r = 0; + if (A == '@') { if(Code37055(mem58+1, 4) == 0) { A = inputtemp[X]; - if (A != 72) goto pos36700; - if ((A != 84) && (A != 67) && (A != 83)) goto pos36700; - mem58 = X; - } - continue; - } else if (A == '^') { - if (Code37055(mem58+1, 32) == 0) goto pos36700; - } else if (A == '+') { - X = mem58 + 1; - A = inputtemp[X]; - if ((A != 69) && (A != 73) && (A != 89)) goto pos36700; + if ((A != 82) && (A != 84) && + (A != 67) && (A != 83)) r = 1; + } + r = -2; } else if (A == ':') { while (Code37055(mem58+1, 32)) mem58 = X; + r = -2; + } else r = handle_ch(A, mem58+1); + + if (r == 1) goto pos36700; + if (r == -2) { + r = 0; continue; - } else { - break; } - mem58 = X; - } + if (r == 0) mem58 = X; + } while (r == 0); } while (A == '%'); return 0; } From 8a8219e2cfef5f4ec5db2af55470e8d402937fea Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 12 Feb 2017 21:45:21 +0000 Subject: [PATCH 103/109] Refactoring --- src/reciter.c | 61 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 25 deletions(-) diff --git a/src/reciter.c b/src/reciter.c index 55f37a17..806a0c2c 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -37,33 +37,37 @@ unsigned char GetRuleByte(unsigned short mem62, unsigned char Y) { } int handle_ch2(unsigned char ch, unsigned char mem) { + X = mem; + unsigned char tmp = tab36376[inputtemp[mem]]; if (ch == ' ') { - if(Code37055(mem,128)) return 1; + if(tmp & 128) return 1; } else if (ch == '#') { - if(!Code37055(mem, 64)) return 1; + if(!(tmp & 64)) return 1; } else if (ch == '.') { - if(!Code37055(mem,8)) return 1; + if(!(tmp & 8)) return 1; } else if (ch == '^') { - if(!Code37055(mem,32)) return 1; + if(!(tmp & 32)) return 1; } else return -1; return 0; } int handle_ch(unsigned char A, unsigned char mem) { + X = mem; + unsigned char tmp = tab36376[inputtemp[X]]; if (A == ' ') { - if (Code37055(mem, 128) != 0) return 1; + if ((tmp & 128) != 0) return 1; } else if (A == '#') { - if (Code37055(mem, 64) == 0) return 1; + if ((tmp & 64) == 0) return 1; } else if (A == '.') { - if(Code37055(mem, 8) == 0) return 1; + if((tmp & 8) == 0) return 1; } else if (A == '&') { - if(Code37055(mem, 16) == 0) { + if((tmp & 16) == 0) { if (inputtemp[X] != 72) return 1; ++X; } } else if (A == '^') { - if (Code37055(mem, 32) == 0) return 1; + if ((tmp & 32) == 0) return 1; } else if (A == '+') { X = mem; A = inputtemp[X]; @@ -190,8 +194,10 @@ int TextToPhonemes(char *input) { case '&': if (!Code37055(mem59-1,16)) { if (inputtemp[X] != 'H') r = 1; - A = inputtemp[--X]; - if ((A != 'C') && (A != 'S')) r = 1; + else { + A = inputtemp[--X]; + if ((A != 'C') && (A != 'S')) r = 1; + } } break; @@ -257,23 +263,28 @@ int TextToPhonemes(char *input) { mem65 = Y; mem57 = GetRuleByte(mem62, Y); if((tab36376[mem57] & 128) == 0) break; - if (inputtemp[mem58+1] != mem57) goto pos36700; + if (inputtemp[mem58+1] != mem57) { + r = 1; + break; + } ++mem58; } - A = mem57; - r = 0; - if (A == '@') { - if(Code37055(mem58+1, 4) == 0) { - A = inputtemp[X]; - if ((A != 82) && (A != 84) && - (A != 67) && (A != 83)) r = 1; - } - r = -2; - } else if (A == ':') { - while (Code37055(mem58+1, 32)) mem58 = X; - r = -2; - } else r = handle_ch(A, mem58+1); + if (r == 0) { + A = mem57; + if (A == '@') { + if(Code37055(mem58+1, 4) == 0) { + A = inputtemp[X]; + if ((A != 82) && (A != 84) && + (A != 67) && (A != 83)) r = 1; + } else { + r = -2; + } + } else if (A == ':') { + while (Code37055(mem58+1, 32)) mem58 = X; + r = -2; + } else r = handle_ch(A, mem58+1); + } if (r == 1) goto pos36700; if (r == -2) { From f5826a37fc37f8f808ce213c581188040ab762ea Mon Sep 17 00:00:00 2001 From: toxieainc Date: Sun, 23 Apr 2017 08:58:32 +0200 Subject: [PATCH 104/109] fix some issues regarding C compliance and added some MSVC handling (_s stupidness) fixed one real refactoring error in reciter.c (line 214), fix potential errors (using multiple declarations of the same variable name globally vs locally, etc) --- src/RenderTabs.h | 3 - src/SamTabs.h | 188 +++--- src/createtransitions.c | 71 +-- src/debug.c | 7 +- src/debug.h | 4 +- src/main.c | 51 +- src/processframes.c | 7 +- src/reciter.c | 600 ++++++++++---------- src/reciter.h | 4 +- src/render.c | 785 +++++++++++++------------ src/sam.c | 1197 +++++++++++++++++++-------------------- src/sam.h | 4 +- 12 files changed, 1450 insertions(+), 1471 deletions(-) diff --git a/src/RenderTabs.h b/src/RenderTabs.h index 06ab4080..10bcdd0d 100755 --- a/src/RenderTabs.h +++ b/src/RenderTabs.h @@ -506,7 +506,4 @@ unsigned char sampleTable[0x500] = , 0xFE , 1 , 0xFC , 3 , 0xE0 ,0xF , 0 , 0xFC }; - - #endif - diff --git a/src/SamTabs.h b/src/SamTabs.h index 88a39fd3..2ba75745 100644 --- a/src/SamTabs.h +++ b/src/SamTabs.h @@ -3,107 +3,107 @@ //tab40672 unsigned char stressInputTable[] = -{ - '*', '1', '2', '3', '4', '5', '6', '7', '8' -}; - -//tab40682 -unsigned char signInputTable1[]={ - ' ', '.', '?', ',', '-', 'I', 'I', 'E', - 'A', 'A', 'A', 'A', 'U', 'A', 'I', 'E', - 'U', 'O', 'R', 'L', 'W', 'Y', 'W', 'R', - 'L', 'W', 'Y', 'M', 'N', 'N', 'D', 'Q', - 'S', 'S', 'F', 'T', '/', '/', 'Z', 'Z', - 'V', 'D', 'C', '*', 'J', '*', '*', '*', - 'E', 'A', 'O', 'A', 'O', 'U', 'B', '*', - '*', 'D', '*', '*', 'G', '*', '*', 'G', - '*', '*', 'P', '*', '*', 'T', '*', '*', - 'K', '*', '*', 'K', '*', '*', 'U', 'U', - 'U' -}; - -//tab40763 -unsigned char signInputTable2[] = -{ - '*', '*', '*', '*', '*', 'Y', 'H', 'H', - 'E', 'A', 'H', 'O', 'H', 'X', 'X', 'R', - 'X', 'H', 'X', 'X', 'X', 'X', 'H', '*', - '*', '*', '*', '*', '*', 'X', 'X', '*', - '*', 'H', '*', 'H', 'H', 'X', '*', 'H', - '*', 'H', 'H', '*', '*', '*', '*', '*', - 'Y', 'Y', 'Y', 'W', 'W', 'W', '*', '*', - '*', '*', '*', '*', '*', '*', '*', 'X', - '*', '*', '*', '*', '*', '*', '*', '*', - '*', '*', '*', 'X', '*', '*', 'L', 'M', - 'N' -}; - -//loc_9F8C -enum { - FLAG_PLOSIVE = 0x0001, - FLAG_STOPCONS = 0x0002, /* stop consonant */ - FLAG_VOICED = 0x0004, - /* 0x08 */ - FLAG_DIPTHONG = 0x0010, - FLAG_DIP_YX = 0x0020, /* dipthong ending with YX */ - FLAG_CONSONANT= 0x0040, - FLAG_VOWEL = 0x0080, - FLAG_PUNCT = 0x0100, - /* 0x200 */ - FLAG_ALVEOLAR = 0x0400, - FLAG_NASAL = 0x0800, - FLAG_LIQUIC = 0x1000, /* liquic consonant */ - FLAG_FRICATIVE= 0x2000 -}; - -unsigned short flags[]={ - 0x8000 , 0xC100 , 0xC100 , 0xC100 , 0xC100 , 0x00A4 , 0x00A4 , 0x00A4 , - 0x00A4 , 0x00A4 , 0x00A4 , 0x0084 , 0x0084 , 0x00A4 , 0x00A4 , 0x0084 , - 0x0084 , 0x0084 , 0x0084 , 0x0084 , 0x0084 , 0x0084 , 0x0044 , 0x1044 , - 0x1044 , 0x1044 , 0x1044 , 0x084C , 0x0C4C , 0x084C , 0x0448 , 0x404C , - - 0x2440 , 0x2040 , 0x2040 , 0x2440 , 0x0040 , 0x0040 , 0x2444 , 0x2044 , - 0x2044 , 0x2444 , 0x2048 , 0x2040 , 0x004C , 0x2044 , 0x0000 , 0x0000 , - 0x00B4 , 0x00B4 , 0x00B4 , 0x0094 , 0x0094 , 0x0094 , 0x004E , 0x004E , - - 0x004E , 0x044E , 0x044E , 0x044E , 0x004E , 0x004E , 0x004E , 0x004E , - 0x004E , 0x004E , 0x004B , 0x004B , 0x004B , 0x044B , 0x044B , 0x044B , - 0x004B , 0x004B , 0x004B , 0x004B , 0x004B , 0x004B , 0x0080 , 0x00C1 , - 0x00C1 -}; - - -//tab45616??? +{ + '*', '1', '2', '3', '4', '5', '6', '7', '8' +}; + +//tab40682 +unsigned char signInputTable1[]={ + ' ', '.', '?', ',', '-', 'I', 'I', 'E', + 'A', 'A', 'A', 'A', 'U', 'A', 'I', 'E', + 'U', 'O', 'R', 'L', 'W', 'Y', 'W', 'R', + 'L', 'W', 'Y', 'M', 'N', 'N', 'D', 'Q', + 'S', 'S', 'F', 'T', '/', '/', 'Z', 'Z', + 'V', 'D', 'C', '*', 'J', '*', '*', '*', + 'E', 'A', 'O', 'A', 'O', 'U', 'B', '*', + '*', 'D', '*', '*', 'G', '*', '*', 'G', + '*', '*', 'P', '*', '*', 'T', '*', '*', + 'K', '*', '*', 'K', '*', '*', 'U', 'U', + 'U' +}; + +//tab40763 +unsigned char signInputTable2[] = +{ + '*', '*', '*', '*', '*', 'Y', 'H', 'H', + 'E', 'A', 'H', 'O', 'H', 'X', 'X', 'R', + 'X', 'H', 'X', 'X', 'X', 'X', 'H', '*', + '*', '*', '*', '*', '*', 'X', 'X', '*', + '*', 'H', '*', 'H', 'H', 'X', '*', 'H', + '*', 'H', 'H', '*', '*', '*', '*', '*', + 'Y', 'Y', 'Y', 'W', 'W', 'W', '*', '*', + '*', '*', '*', '*', '*', '*', '*', 'X', + '*', '*', '*', '*', '*', '*', '*', '*', + '*', '*', '*', 'X', '*', '*', 'L', 'M', + 'N' +}; + +//loc_9F8C +enum { + FLAG_PLOSIVE = 0x0001, + FLAG_STOPCONS = 0x0002, /* stop consonant */ + FLAG_VOICED = 0x0004, + /* 0x08 */ + FLAG_DIPTHONG = 0x0010, + FLAG_DIP_YX = 0x0020, /* dipthong ending with YX */ + FLAG_CONSONANT= 0x0040, + FLAG_VOWEL = 0x0080, + FLAG_PUNCT = 0x0100, + /* 0x200 */ + FLAG_ALVEOLAR = 0x0400, + FLAG_NASAL = 0x0800, + FLAG_LIQUIC = 0x1000, /* liquic consonant */ + FLAG_FRICATIVE= 0x2000 +}; + +unsigned short flags[]={ + 0x8000 , 0xC100 , 0xC100 , 0xC100 , 0xC100 , 0x00A4 , 0x00A4 , 0x00A4 , + 0x00A4 , 0x00A4 , 0x00A4 , 0x0084 , 0x0084 , 0x00A4 , 0x00A4 , 0x0084 , + 0x0084 , 0x0084 , 0x0084 , 0x0084 , 0x0084 , 0x0084 , 0x0044 , 0x1044 , + 0x1044 , 0x1044 , 0x1044 , 0x084C , 0x0C4C , 0x084C , 0x0448 , 0x404C , + + 0x2440 , 0x2040 , 0x2040 , 0x2440 , 0x0040 , 0x0040 , 0x2444 , 0x2044 , + 0x2044 , 0x2444 , 0x2048 , 0x2040 , 0x004C , 0x2044 , 0x0000 , 0x0000 , + 0x00B4 , 0x00B4 , 0x00B4 , 0x0094 , 0x0094 , 0x0094 , 0x004E , 0x004E , + + 0x004E , 0x044E , 0x044E , 0x044E , 0x004E , 0x004E , 0x004E , 0x004E , + 0x004E , 0x004E , 0x004B , 0x004B , 0x004B , 0x044B , 0x044B , 0x044B , + 0x004B , 0x004B , 0x004B , 0x004B , 0x004B , 0x004B , 0x0080 , 0x00C1 , + 0x00C1 +}; + + +//tab45616??? unsigned char phonemeStressedLengthTable[] = -{ - 0x00 , 0x12 , 0x12 , 0x12 , 8 ,0xB , 9 ,0xB , - 0xE ,0xF ,0xB , 0x10 ,0xC , 6 , 6 ,0xE , - 0xC ,0xE ,0xC ,0xB , 8 , 8 ,0xB ,0xA , - 9 , 8 , 8 , 8 , 8 , 8 , 3 , 5 , - 2 , 2 , 2 , 2 , 2 , 2 , 6 , 6 , - 8 , 6 , 6 , 2 , 9 , 4 , 2 , 1 , - 0xE ,0xF ,0xF ,0xF ,0xE ,0xE , 8 , 2 , - 2 , 7 , 2 , 1 , 7 , 2 , 2 , 7 , - 2 , 2 , 8 , 2 , 2 , 6 , 2 , 2 , +{ + 0x00 , 0x12 , 0x12 , 0x12 , 8 ,0xB , 9 ,0xB , + 0xE ,0xF ,0xB , 0x10 ,0xC , 6 , 6 ,0xE , + 0xC ,0xE ,0xC ,0xB , 8 , 8 ,0xB ,0xA , + 9 , 8 , 8 , 8 , 8 , 8 , 3 , 5 , + 2 , 2 , 2 , 2 , 2 , 2 , 6 , 6 , + 8 , 6 , 6 , 2 , 9 , 4 , 2 , 1 , + 0xE ,0xF ,0xF ,0xF ,0xE ,0xE , 8 , 2 , + 2 , 7 , 2 , 1 , 7 , 2 , 2 , 7 , + 2 , 2 , 8 , 2 , 2 , 6 , 2 , 2 , 7 , 2 , 4 , 7 , 1 , 4 , 5 , 5 }; - -//tab45536??? + +//tab45536??? unsigned char phonemeLengthTable[] = -{ - 0 , 0x12 , 0x12 , 0x12 , 8 , 8 , 8 , 8 , - 8 ,0xB , 6 ,0xC ,0xA , 5 , 5 ,0xB , - 0xA ,0xA ,0xA , 9 , 8 , 7 , 9 , 7 , - 6 , 8 , 6 , 7 , 7 , 7 , 2 , 5 , - 2 , 2 , 2 , 2 , 2 , 2 , 6 , 6 , - 7 , 6 , 6 , 2 , 8 , 3 , 1 , 0x1E , - 0xD ,0xC ,0xC ,0xC ,0xE , 9 , 6 , 1 , - 2 , 5 , 1 , 1 , 6 , 1 , 2 , 6 , - 1 , 2 , 8 , 2 , 2 , 4 , 2 , 2 , +{ + 0 , 0x12 , 0x12 , 0x12 , 8 , 8 , 8 , 8 , + 8 ,0xB , 6 ,0xC ,0xA , 5 , 5 ,0xB , + 0xA ,0xA ,0xA , 9 , 8 , 7 , 9 , 7 , + 6 , 8 , 6 , 7 , 7 , 7 , 2 , 5 , + 2 , 2 , 2 , 2 , 2 , 2 , 6 , 6 , + 7 , 6 , 6 , 2 , 8 , 3 , 1 , 0x1E , + 0xD ,0xC ,0xC ,0xC ,0xE , 9 , 6 , 1 , + 2 , 5 , 1 , 1 , 6 , 1 , 2 , 6 , + 1 , 2 , 8 , 2 , 2 , 4 , 2 , 2 , 6 , 1 , 4 , 6 , 1 , 4 , 0xC7 , 0xFF }; - + /* diff --git a/src/createtransitions.c b/src/createtransitions.c index 5940246d..71d3c7f3 100644 --- a/src/createtransitions.c +++ b/src/createtransitions.c @@ -46,9 +46,6 @@ extern unsigned char outBlendLength[]; extern unsigned char inBlendLength[]; extern unsigned char pitches[]; -extern unsigned char Read(unsigned char p, unsigned char Y); -extern void Write(unsigned char p, unsigned char Y, unsigned char value); - extern unsigned char frequency1[256]; extern unsigned char frequency2[256]; extern unsigned char frequency3[256]; @@ -77,34 +74,36 @@ unsigned char Read(unsigned char p, unsigned char Y) case 172: return amplitude1[Y]; case 173: return amplitude2[Y]; case 174: return amplitude3[Y]; + default: + printf("Error reading from tables"); + return 0; } - printf("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; + 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; + default: + printf("Error writing to tables\n"); + return; } - printf("Error writing to tables\n"); } // linearly interpolate values -void interpolate(unsigned char width, unsigned char table, unsigned char frame, unsigned char mem53) +void interpolate(unsigned char width, unsigned char table, unsigned char frame, char mem53) { - unsigned char sign = ((char)(mem53) < 0); - unsigned char remainder = abs((char)mem53) % width; - unsigned char div = (unsigned char)((char)(mem53) / width); + unsigned char sign = (mem53 < 0); + unsigned char remainder = abs(mem53) % width; + unsigned char div = mem53 / width; unsigned char error = 0; unsigned char pos = width; @@ -122,7 +121,7 @@ void interpolate(unsigned char width, unsigned char table, unsigned char frame, } } -void interpolate_pitch(unsigned char width, unsigned char pos, unsigned char mem49, unsigned char phase3) { +void interpolate_pitch(unsigned char pos, unsigned char mem49, unsigned char phase3) { // unlike the other values, the pitches[] interpolates from // the middle of the current phoneme to the middle of the // next phoneme @@ -131,27 +130,33 @@ void interpolate_pitch(unsigned char width, unsigned char pos, unsigned char mem unsigned char cur_width = phonemeLengthOutput[pos] / 2; unsigned char next_width = phonemeLengthOutput[pos+1] / 2; // sum the values - width = cur_width + next_width; - unsigned char pitch = pitches[next_width + mem49] - pitches[mem49- cur_width]; + unsigned char width = cur_width + next_width; + char pitch = pitches[next_width + mem49] - pitches[mem49- cur_width]; interpolate(width, 168, phase3, pitch); } unsigned char CreateTransitions() { - unsigned char phase1; - unsigned char phase2; unsigned char mem49 = 0; unsigned char pos = 0; while(1) { + unsigned char next_rank; + unsigned char rank; + unsigned char speedcounter; + unsigned char phase1; + unsigned char phase2; + unsigned char phase3; + unsigned char transition; + unsigned char phoneme = phonemeIndexOutput[pos]; unsigned char next_phoneme = phonemeIndexOutput[pos+1]; if (next_phoneme == 255) break; // 255 == end_token // get the ranking of each phoneme - unsigned char next_rank = blendRank[next_phoneme]; - unsigned char rank = blendRank[phoneme]; + next_rank = blendRank[next_phoneme]; + rank = blendRank[phoneme]; // compare the rank - lower rank value is stronger if (rank == next_rank) { @@ -171,14 +176,13 @@ unsigned char CreateTransitions() mem49 += phonemeLengthOutput[pos]; - unsigned char speedcounter = mem49 + phase2; - unsigned char phase3 = mem49 - phase1; - unsigned char transition = phase1 + phase2; // total transition? + speedcounter = mem49 + phase2; + phase3 = mem49 - phase1; + transition = phase1 + phase2; // total transition? if (((transition - 2) & 128) == 0) { - - interpolate_pitch(transition, pos, mem49, phase3); - unsigned table = 169; + unsigned char table = 169; + interpolate_pitch(pos, mem49, phase3); while (table < 175) { // tables: // 168 pitches[] @@ -189,7 +193,7 @@ unsigned char CreateTransitions() // 173 amplitude2 // 174 amplitude3 - unsigned char value = Read(table, speedcounter) - Read(table, phase3); + char value = Read(table, speedcounter) - Read(table, phase3); interpolate(transition, table, phase3, value); table++; } @@ -200,6 +204,3 @@ unsigned char CreateTransitions() // add the length of this phoneme return mem49 + phonemeLengthOutput[pos]; } - - - diff --git a/src/debug.c b/src/debug.c index 38941334..e7ff8192 100755 --- a/src/debug.c +++ b/src/debug.c @@ -43,9 +43,9 @@ void PrintOutput( unsigned char *a3, unsigned char *p) { + int i = 0; printf("===========================================\n"); printf("Final data for speech output:\n\n"); - int i = 0; printf(" flags ampl1 freq1 ampl2 freq2 ampl3 freq3 pitch\n"); printf("------------------------------------------------\n"); while(i < 255) @@ -59,9 +59,9 @@ void PrintOutput( extern unsigned char GetRuleByte(unsigned short mem62, unsigned char Y); -void PrintRule(int offset) +void PrintRule(unsigned short offset) { - int i = 1; + unsigned char i = 1; unsigned char A = 0; printf("Applying rule: "); do @@ -72,4 +72,3 @@ void PrintRule(int offset) } while ((A&128)==0); printf("\n"); } - diff --git a/src/debug.h b/src/debug.h index 0ac71e69..8a394eda 100755 --- a/src/debug.h +++ b/src/debug.h @@ -12,6 +12,6 @@ void PrintOutput( unsigned char *a3, unsigned char *p); -void PrintRule(int offset); +void PrintRule(unsigned short offset); -#endif \ No newline at end of file +#endif diff --git a/src/main.c b/src/main.c index 8ab17f3e..9ea9b9ea 100644 --- a/src/main.c +++ b/src/main.c @@ -14,28 +14,31 @@ void WriteWav(char* filename, char* buffer, int bufferlength) { - FILE *file = fopen(filename, "wb"); + unsigned int filesize; + unsigned int fmtlength = 16; + unsigned short int format=1; //PCM + unsigned short int channels=1; + unsigned int samplerate = 22050; + unsigned short int blockalign = 1; + unsigned short int bitspersample=8; + + FILE *file; + fopen_s(&file, filename, "wb"); if (file == NULL) return; //RIFF header fwrite("RIFF", 4, 1,file); - unsigned int filesize=bufferlength + 12 + 16 + 8 - 8; + filesize=bufferlength + 12 + 16 + 8 - 8; fwrite(&filesize, 4, 1, file); fwrite("WAVE", 4, 1, file); //format chunk fwrite("fmt ", 4, 1, file); - unsigned int fmtlength = 16; fwrite(&fmtlength, 4, 1, file); - unsigned short int format=1; //PCM fwrite(&format, 2, 1, file); - unsigned short int channels=1; fwrite(&channels, 2, 1, file); - unsigned int samplerate = 22050; fwrite(&samplerate, 4, 1, file); fwrite(&samplerate, 4, 1, file); // bytes/second - unsigned short int blockalign = 1; fwrite(&blockalign, 2, 1, file); - unsigned short int bitspersample=8; fwrite(&bitspersample, 2, 1, file); //data chunk @@ -154,9 +157,9 @@ int main(int argc, char **argv) int phonetic = 0; char* wavfilename = NULL; - char input[256]; + unsigned char input[256]; - for(i=0; i<256; i++) input[i] = 0; + memset(input, 0, 256); if (argc <= 1) { @@ -169,8 +172,8 @@ int main(int argc, char **argv) { if (argv[i][0] != '-') { - strcat(input, argv[i]); - strcat(input, " "); + strcat_s((char*)input, 256, argv[i]); + strcat_s((char*)input, 256, " "); } else { if (strcmp(&argv[i][1], "wav")==0) @@ -192,22 +195,22 @@ int main(int argc, char **argv) } else if (strcmp(&argv[i][1], "pitch")==0) { - SetPitch(atoi(argv[i+1])); + SetPitch((unsigned char)min(atoi(argv[i+1]),255)); i++; } else if (strcmp(&argv[i][1], "speed")==0) { - SetSpeed(atoi(argv[i+1])); + SetSpeed((unsigned char)min(atoi(argv[i+1]),255)); i++; } else if (strcmp(&argv[i][1], "mouth")==0) { - SetMouth(atoi(argv[i+1])); + SetMouth((unsigned char)min(atoi(argv[i+1]),255)); i++; } else if (strcmp(&argv[i][1], "throat")==0) { - SetThroat(atoi(argv[i+1])); + SetThroat((unsigned char)min(atoi(argv[i+1]),255)); i++; } else { @@ -220,7 +223,7 @@ int main(int argc, char **argv) } //while for(i=0; input[i] != 0; i++) - input[i] = toupper((int)input[i]); + input[i] = (unsigned char)toupper((int)input[i]); if (debug) { @@ -230,11 +233,11 @@ int main(int argc, char **argv) if (!phonetic) { - strcat(input, "["); + strcat_s((char*)input, 256, "["); if (!TextToPhonemes(input)) return 1; if (debug) printf("phonetic input: %s\n", input); - } else strcat(input, "\x9b"); + } else strcat_s((char*)input, 256, "\x9b"); #ifdef USESDL if ( SDL_Init(SDL_INIT_AUDIO) < 0 ) @@ -251,19 +254,11 @@ int main(int argc, char **argv) PrintUsage(); return 1; } - + if (wavfilename != NULL) WriteWav(wavfilename, GetBuffer(), GetBufferLength()/50); else OutputSound(); - return 0; - } - - - - - - diff --git a/src/processframes.c b/src/processframes.c index 7eb20b72..92bb86d8 100644 --- a/src/processframes.c +++ b/src/processframes.c @@ -1,4 +1,3 @@ - #include "render.h" extern unsigned char speed; @@ -45,12 +44,11 @@ static void CombineGlottalAndFormants(unsigned char phase1, unsigned char phase2 // void ProcessFrames(unsigned char mem48) { - unsigned char speedcounter = 72; unsigned char phase1 = 0; unsigned char phase2 = 0; unsigned char phase3 = 0; - unsigned char mem66; + unsigned char mem66 = 0; //!! was not initialized unsigned char Y = 0; @@ -75,7 +73,7 @@ void ProcessFrames(unsigned char mem48) Y++; //go to next amplitude // decrement the frame count mem48--; - if(mem48 == 0) return; + if(mem48 == 0) return; speedcounter = speed; } @@ -112,4 +110,3 @@ void ProcessFrames(unsigned char mem48) phase3 = 0; } } - diff --git a/src/reciter.c b/src/reciter.c index 806a0c2c..5b72d3b3 100644 --- a/src/reciter.c +++ b/src/reciter.c @@ -1,299 +1,303 @@ -#include -#include -#include "reciter.h" -#include "ReciterTabs.h" -#include "debug.h" - -unsigned char A, X, Y; +#include +#include +#include "reciter.h" +#include "ReciterTabs.h" +#include "debug.h" + +unsigned char A, X; extern int debug; - -static unsigned char inputtemp[256]; // secure copy of input tab36096 - -/* Retrieve flags for character at mem59-1 */ -unsigned char Code37055(unsigned char npos, unsigned char mask) -{ - X = npos; - return tab36376[inputtemp[X]] & mask; -} - -unsigned int match(const char * str) { - unsigned char ch; - while ((ch = *str)) { - A = inputtemp[X++]; - if (A != ch) return 0; - ++str; - } - return 1; -} - -unsigned char GetRuleByte(unsigned short mem62, unsigned char Y) { - unsigned int address = mem62; - if (mem62 >= 37541) { - address -= 37541; - return rules2[address+Y]; - } - address -= 32000; - return rules[address+Y]; -} - -int handle_ch2(unsigned char ch, unsigned char mem) { - X = mem; - unsigned char tmp = tab36376[inputtemp[mem]]; - if (ch == ' ') { - if(tmp & 128) return 1; - } else if (ch == '#') { - if(!(tmp & 64)) return 1; - } else if (ch == '.') { - if(!(tmp & 8)) return 1; - } else if (ch == '^') { - if(!(tmp & 32)) return 1; - } else return -1; - return 0; -} - - -int handle_ch(unsigned char A, unsigned char mem) { - X = mem; - unsigned char tmp = tab36376[inputtemp[X]]; - if (A == ' ') { - if ((tmp & 128) != 0) return 1; - } else if (A == '#') { - if ((tmp & 64) == 0) return 1; - } else if (A == '.') { - if((tmp & 8) == 0) return 1; - } else if (A == '&') { - if((tmp & 16) == 0) { - if (inputtemp[X] != 72) return 1; - ++X; - } - } else if (A == '^') { - if ((tmp & 32) == 0) return 1; - } else if (A == '+') { - X = mem; - A = inputtemp[X]; - if ((A != 69) && (A != 73) && (A != 89)) return 1; - } else return -1; - return 0; -} - - -int TextToPhonemes(char *input) { - unsigned char mem56; //output position for phonemes - unsigned char mem58; - unsigned char mem60; - unsigned char mem61; - unsigned short mem62; // memory position of current rule - - unsigned char mem64; // position of '=' or current character - unsigned char mem65; // position of ')' - unsigned char mem66; // position of '(' - - inputtemp[0] = ' '; - - // secure copy of input - // because input will be overwritten by phonemes - X = 0; - do { - A = input[X] & 127; - if ( A >= 112) A = A & 95; - else if ( A >= 96) A = A & 79; - inputtemp[++X] = A; - } while (X < 255); - inputtemp[255] = 27; - mem56 = mem61 = 255; - - unsigned char mem57; -pos36554: - while (1) { - while(1) { - X = ++mem61; - mem64 = inputtemp[X]; - if (mem64 == '[') { - X = ++mem56; - input[X] = 155; - return 1; - } - - if (mem64 != '.') break; - X++; - A = tab36376[inputtemp[X]] & 1; - if(A != 0) break; - mem56++; - X = mem56; - A = '.'; - input[X] = '.'; - } - mem57 = tab36376[mem64]; - if((mem57&2) != 0) { - mem62 = 37541; - goto pos36700; - } - - if(mem57 != 0) break; - inputtemp[X] = ' '; - X = ++mem56; - if (X > 120) { - input[X] = 155; - return 1; - } - input[X] = 32; - } - - if(!(mem57 & 128)) return 0; - - // go to the right rules for this character. - X = mem64 - 'A'; - mem62 = tab37489[X] | (tab37515[X]<<8); - -pos36700: - // find next rule - while ((GetRuleByte(++mem62, 0) & 128) == 0); - unsigned char Y = 0; - while(GetRuleByte(mem62, ++Y) != '('); - mem66 = Y; - while(GetRuleByte(mem62, ++Y) != ')'); - mem65 = Y; - while((GetRuleByte(mem62, ++Y) & 127) != '='); - mem64 = Y; - - - mem60 = X = mem61; - // compare the string within the bracket - Y = mem66 + 1; - - while(1) { - if (GetRuleByte(mem62, Y) != inputtemp[X]) goto pos36700; - if(++Y == mem65) break; - mem60 = ++X; - } - - - // the string in the bracket is correct - - unsigned char mem59 = mem61; - - while(1) { - while(1) { - mem66--; - mem57 = GetRuleByte(mem62, mem66); - if ((mem57 & 128) != 0) { - mem58 = mem60; - goto pos37184; - } - X = mem57 & 127; - if ((tab36376[X] & 128) == 0) break; - if (inputtemp[mem59-1] != mem57) goto pos36700; - --mem59; - } - - unsigned char ch = mem57; - - int r = handle_ch2(ch, mem59-1); - if (r == -1) { - switch (ch) { - case '&': - if (!Code37055(mem59-1,16)) { - if (inputtemp[X] != 'H') r = 1; - else { - A = inputtemp[--X]; - if ((A != 'C') && (A != 'S')) r = 1; - } - } - break; - - case '@': - if(!Code37055(mem59-1,4)) { - A = inputtemp[X]; - if (A != 72) r = 1; - if ((A != 84) && (A != 67) && (A != 83)) r = 1; - } - break; - case '+': - X = mem59; - A = inputtemp[--X]; - if ((A != 'E') && (A != 'I') && (A && 'Y')) r = 1; - break; - case ':': - while (Code37055(mem59-1,32)) --mem59; - continue; - default: - return 0; - } - } - - if (r == 1) goto pos36700; - - mem59 = X; - } - - do { - X = mem58+1; - if (inputtemp[X] == 'E') { - if((tab36376[inputtemp[X+1]] & 128) != 0) { - A = inputtemp[++X]; - if (A == 'L') { - if (inputtemp[++X] != 'Y') goto pos36700; - } else if ((A != 'R') && (A != 'S') && (A != 'D') && !match("FUL")) goto pos36700; - } - } else { - if (!match("ING")) goto pos36700; - mem58 = X; - } - -pos37184: - X; - int r = 0; - do { - unsigned char mem57; - while (1) { - unsigned char Y = mem65 + 1; - if(Y == mem64) { - mem61 = mem60; - - if (debug) PrintRule(mem62); - - while(1) { - mem57 = A = GetRuleByte(mem62, Y); - A = A & 127; - if (A != '=') input[++mem56] = A; - if ((mem57 & 128) != 0) goto pos36554; - Y++; - } - } - mem65 = Y; - mem57 = GetRuleByte(mem62, Y); - if((tab36376[mem57] & 128) == 0) break; - if (inputtemp[mem58+1] != mem57) { - r = 1; - break; - } - ++mem58; - } - - if (r == 0) { - A = mem57; - if (A == '@') { - if(Code37055(mem58+1, 4) == 0) { - A = inputtemp[X]; - if ((A != 82) && (A != 84) && - (A != 67) && (A != 83)) r = 1; - } else { - r = -2; - } - } else if (A == ':') { - while (Code37055(mem58+1, 32)) mem58 = X; - r = -2; - } else r = handle_ch(A, mem58+1); - } - - if (r == 1) goto pos36700; - if (r == -2) { - r = 0; - continue; - } - if (r == 0) mem58 = X; - } while (r == 0); - } while (A == '%'); - return 0; -} - + +static unsigned char inputtemp[256]; // secure copy of input tab36096 + +/* Retrieve flags for character at mem59-1 */ +unsigned char Code37055(unsigned char npos, unsigned char mask) +{ + X = npos; + return tab36376[inputtemp[X]] & mask; +} + +unsigned int match(const char * str) { + while (*str) { + unsigned char ch = *str; + A = inputtemp[X++]; + if (A != ch) return 0; + ++str; + } + return 1; +} + +unsigned char GetRuleByte(unsigned short mem62, unsigned char Y) { + unsigned int address = mem62; + if (mem62 >= 37541) { + address -= 37541; + return rules2[address+Y]; + } + address -= 32000; + return rules[address+Y]; +} + +int handle_ch2(unsigned char ch, unsigned char mem) { + unsigned char tmp; + X = mem; + tmp = tab36376[inputtemp[mem]]; + if (ch == ' ') { + if(tmp & 128) return 1; + } else if (ch == '#') { + if(!(tmp & 64)) return 1; + } else if (ch == '.') { + if(!(tmp & 8)) return 1; + } else if (ch == '^') { + if(!(tmp & 32)) return 1; + } else return -1; + return 0; +} + + +int handle_ch(unsigned char ch, unsigned char mem) { + unsigned char tmp; + X = mem; + tmp = tab36376[inputtemp[X]]; + if (ch == ' ') { + if ((tmp & 128) != 0) return 1; + } else if (ch == '#') { + if ((tmp & 64) == 0) return 1; + } else if (ch == '.') { + if((tmp & 8) == 0) return 1; + } else if (ch == '&') { + if((tmp & 16) == 0) { + if (inputtemp[X] != 72) return 1; + ++X; + } + } else if (ch == '^') { + if ((tmp & 32) == 0) return 1; + } else if (ch == '+') { + X = mem; + ch = inputtemp[X]; + if ((ch != 69) && (ch != 73) && (ch != 89)) return 1; + } else return -1; + return 0; +} + + +int TextToPhonemes(unsigned char *input) { + unsigned char mem56; //output position for phonemes + unsigned char mem57; + unsigned char mem58; + unsigned char mem59; + unsigned char mem60; + unsigned char mem61; + unsigned short mem62; // memory position of current rule + + unsigned char mem64; // position of '=' or current character + unsigned char mem65; // position of ')' + unsigned char mem66; // position of '(' + + unsigned char Y; + + int r; + + inputtemp[0] = ' '; + + // secure copy of input + // because input will be overwritten by phonemes + X = 0; + do { + A = input[X] & 127; + if ( A >= 112) A = A & 95; + else if ( A >= 96) A = A & 79; + inputtemp[++X] = A; + } while (X < 255); + inputtemp[255] = 27; + mem56 = mem61 = 255; + +pos36554: + while (1) { + while(1) { + X = ++mem61; + mem64 = inputtemp[X]; + if (mem64 == '[') { + X = ++mem56; + input[X] = 155; + return 1; + } + + if (mem64 != '.') break; + X++; + A = tab36376[inputtemp[X]] & 1; + if(A != 0) break; + mem56++; + X = mem56; + A = '.'; + input[X] = '.'; + } + mem57 = tab36376[mem64]; + if((mem57&2) != 0) { + mem62 = 37541; + goto pos36700; + } + + if(mem57 != 0) break; + inputtemp[X] = ' '; + X = ++mem56; + if (X > 120) { + input[X] = 155; + return 1; + } + input[X] = 32; + } + + if(!(mem57 & 128)) return 0; + + // go to the right rules for this character. + X = mem64 - 'A'; + mem62 = tab37489[X] | (tab37515[X]<<8); + +pos36700: + // find next rule + while ((GetRuleByte(++mem62, 0) & 128) == 0); + Y = 0; + while(GetRuleByte(mem62, ++Y) != '('); + mem66 = Y; + while(GetRuleByte(mem62, ++Y) != ')'); + mem65 = Y; + while((GetRuleByte(mem62, ++Y) & 127) != '='); + mem64 = Y; + + + mem60 = X = mem61; + // compare the string within the bracket + Y = mem66 + 1; + + while(1) { + if (GetRuleByte(mem62, Y) != inputtemp[X]) goto pos36700; + if(++Y == mem65) break; + mem60 = ++X; + } + + // the string in the bracket is correct + + mem59 = mem61; + + while(1) { + unsigned char ch; + while(1) { + mem66--; + mem57 = GetRuleByte(mem62, mem66); + if ((mem57 & 128) != 0) { + mem58 = mem60; + goto pos37184; + } + X = mem57 & 127; + if ((tab36376[X] & 128) == 0) break; + if (inputtemp[mem59-1] != mem57) goto pos36700; + --mem59; + } + + ch = mem57; + + r = handle_ch2(ch, mem59-1); + if (r == -1) { + switch (ch) { + case '&': + if (!Code37055(mem59-1,16)) { + if (inputtemp[X] != 'H') r = 1; + else { + A = inputtemp[--X]; + if ((A != 'C') && (A != 'S')) r = 1; + } + } + break; + + case '@': + if(!Code37055(mem59-1,4)) { + A = inputtemp[X]; + if (A != 72) r = 1; + if ((A != 84) && (A != 67) && (A != 83)) r = 1; + } + break; + case '+': + X = mem59; + A = inputtemp[--X]; + if ((A != 'E') && (A != 'I') && (A != 'Y')) r = 1; + break; + case ':': + while (Code37055(mem59-1,32)) --mem59; + continue; + default: + return 0; + } + } + + if (r == 1) goto pos36700; + + mem59 = X; + } + + do { + X = mem58+1; + if (inputtemp[X] == 'E') { + if((tab36376[inputtemp[X+1]] & 128) != 0) { + A = inputtemp[++X]; + if (A == 'L') { + if (inputtemp[++X] != 'Y') goto pos36700; + } else if ((A != 'R') && (A != 'S') && (A != 'D') && !match("FUL")) goto pos36700; + } + } else { + if (!match("ING")) goto pos36700; + mem58 = X; + } + +pos37184: + r = 0; + do { + while (1) { + Y = mem65 + 1; + if(Y == mem64) { + mem61 = mem60; + + if (debug) PrintRule(mem62); + + while(1) { + mem57 = A = GetRuleByte(mem62, Y); + A = A & 127; + if (A != '=') input[++mem56] = A; + if ((mem57 & 128) != 0) goto pos36554; + Y++; + } + } + mem65 = Y; + mem57 = GetRuleByte(mem62, Y); + if((tab36376[mem57] & 128) == 0) break; + if (inputtemp[mem58+1] != mem57) { + r = 1; + break; + } + ++mem58; + } + + if (r == 0) { + A = mem57; + if (A == '@') { + if(Code37055(mem58+1, 4) == 0) { + A = inputtemp[X]; + if ((A != 82) && (A != 84) && + (A != 67) && (A != 83)) r = 1; + } else { + r = -2; + } + } else if (A == ':') { + while (Code37055(mem58+1, 32)) mem58 = X; + r = -2; + } else r = handle_ch(A, mem58+1); + } + + if (r == 1) goto pos36700; + if (r == -2) { + r = 0; + continue; + } + if (r == 0) mem58 = X; + } while (r == 0); + } while (A == '%'); + return 0; +} diff --git a/src/reciter.h b/src/reciter.h index 1429ec69..b23ac550 100644 --- a/src/reciter.h +++ b/src/reciter.h @@ -1,9 +1,9 @@ #ifndef RECITER_C #define RECITER_C -//int TextToPhonemes(char *input, char *output); +//int TextToPhonemes(unsigned char *input, unsigned char *output); -int TextToPhonemes(char *input); +int TextToPhonemes(unsigned char *input); #endif diff --git a/src/render.c b/src/render.c index 5468c2f4..9aebeb09 100755 --- a/src/render.c +++ b/src/render.c @@ -1,396 +1,389 @@ - -#include -#include -#include - -#include "render.h" -#include "RenderTabs.h" - -#include "debug.h" -extern int debug; - -unsigned char wait1 = 7; -unsigned char wait2 = 6; - -//extern unsigned char A, X, Y; -//extern unsigned char mem44; - -extern unsigned char speed; -extern unsigned char pitch; -extern int singmode; - - -extern unsigned char phonemeIndexOutput[60]; //tab47296 -extern unsigned char stressOutput[60]; //tab47365 -extern unsigned char phonemeLengthOutput[60]; //tab47416 - -unsigned char pitches[256]; // tab43008 - -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]; // tab44800 - - -void AddInflection(unsigned char mem48, unsigned char phase1, unsigned char X); - -//return = hibyte(mem39212*mem39213) << 1 -unsigned char trans(unsigned char a, unsigned char b) -{ - return ((a * b) >> 8) << 1; -} - - - - -// contains the final soundbuffer -extern int bufferpos; -extern char *buffer; - - - -//timetable for more accurate c64 simulation -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} -}; - -void Output(int index, unsigned char A) -{ - static unsigned oldtimetableindex = 0; - int k; - bufferpos += timetable[oldtimetableindex][index]; - oldtimetableindex = index; - // write a little bit in advance - for(k=0; k<5; k++) - buffer[bufferpos/50 + k] = (A & 15)*16; -} - - -static unsigned char RenderVoicedSample(unsigned short hi, unsigned char off, unsigned char phase1) -{ - do { - unsigned char sample = sampleTable[hi+off]; - unsigned char bit = 8; - 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(unsigned short hi, unsigned char off, unsigned char mem53) -{ - do { - unsigned char bit = 8; - unsigned char 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. - - -void RenderSample(unsigned char *mem66, unsigned char consonantFlag, unsigned char mem49) -{ - // mem49 == current phoneme's index - - // mask low three bits and subtract 1 get value to - // convert 0 bits on unvoiced samples. - unsigned char hibyte = (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 - - unsigned short hi = hibyte*256; - // voiced sample? - unsigned char pitch = consonantFlag & 248; - if(pitch == 0) { - // voiced phoneme: Z*, ZH, V*, DH - pitch = pitches[mem49] >> 4; - *mem66 = RenderVoicedSample(hi, *mem66, pitch ^ 255); - return; - } - RenderUnvoicedSample(hi, pitch^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() -{ - unsigned char phase1 = 0; - - unsigned char X = 0; - unsigned int i = 0; - while(i < 256) { - // get the phoneme at the index - unsigned char phoneme = phonemeIndexOutput[i]; - - // if terminal phoneme, exit the loop - if (phoneme == 255) break; - - if (phoneme == PHONEME_PERIOD) AddInflection(RISING_INFLECTION, phase1,X); - else if (phoneme == PHONEME_QUESTION) AddInflection(FALLING_INFLECTION, phase1,X); - - // get the stress amount (more stress = higher pitch) - phase1 = tab47492[stressOutput[i] + 1]; - - // get number of frames to write - unsigned 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] = pitch + phase1; // pitch - ++X; - } while(--phase2 != 0); - - ++i; - } -} - - -// RESCALE AMPLITUDE -// -// Rescale volume from a linear scale to decibels. -// -void RescaleAmplitude() -{ - int i; - for(i=255; i>=0; i--) - { - amplitude1[i] = amplitudeRescale[amplitude1[i]]; - amplitude2[i] = amplitudeRescale[amplitude2[i]]; - amplitude3[i] = amplitudeRescale[amplitude3[i]]; - } -} - - - -// 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). - -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] -= (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. -void Render() -{ - if (phonemeIndexOutput[0] == 255) return; //exit if no data - - CreateFrames(); - unsigned char t = CreateTransitions(); - - if (!singmode) AssignPitchContour(); - RescaleAmplitude(); - - if (debug) { - PrintOutput(sampledConsonantFlag, frequency1, frequency2, frequency3, amplitude1, amplitude2, amplitude3, pitches); - } - - 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. - -void AddInflection(unsigned char inflection, unsigned char phase1, unsigned char pos) -{ - unsigned char A; - // store the location of the punctuation - unsigned char 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. -*/ -void SetMouthThroat(unsigned char mouth, unsigned char throat) -{ - unsigned char initialFrequency; - unsigned char newFrequency = 0; - - // mouth formants (F1) 5..29 - 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}; - - // throat formants (F2) 5..29 - 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, - }; - - // there must be no zeros in this 2 tables - // formant 1 frequencies (mouth) 48..53 - unsigned char mouthFormants48_53[6] = {19, 27, 21, 27, 18, 13}; - - // formant 2 frequencies (throat) 48..53 - unsigned char throatFormants48_53[6] = {72, 39, 31, 43, 30, 34}; - - unsigned char pos = 5; - - // recalculate formant frequencies 5..29 for the mouth (F1) and throat (F2) - while(pos < 30) - { - // recalculate mouth frequency - 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) - initialFrequency = mouthFormants48_53[pos]; - newFrequency = trans(mouth, initialFrequency); - freq1data[pos+48] = newFrequency; - - // recalculate F2 (throat formant) - initialFrequency = throatFormants48_53[pos]; - newFrequency = trans(throat, initialFrequency); - freq2data[pos+48] = newFrequency; - pos++; - } -} - +#include +#include +#include + +#include "render.h" +#include "RenderTabs.h" + +#include "debug.h" +extern int debug; + +//extern unsigned char A, X, Y; +//extern unsigned char mem44; + +extern unsigned char speed; +extern unsigned char pitch; +extern int singmode; + + +extern unsigned char phonemeIndexOutput[60]; //tab47296 +extern unsigned char stressOutput[60]; //tab47365 +extern unsigned char phonemeLengthOutput[60]; //tab47416 + +unsigned char pitches[256]; // tab43008 + +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]; // tab44800 + + +void AddInflection(unsigned char mem48, unsigned char X); + +//return = hibyte(mem39212*mem39213) << 1 +unsigned char trans(unsigned char a, unsigned char b) +{ + return (((unsigned int)a * b) >> 8) << 1; +} + + + + +// contains the final soundbuffer +extern int bufferpos; +extern char *buffer; + + + +//timetable for more accurate c64 simulation +static const 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} +}; + +void Output(int index, unsigned char A) +{ + static unsigned oldtimetableindex = 0; + int k; + bufferpos += timetable[oldtimetableindex][index]; + oldtimetableindex = index; + // write a little bit in advance + for(k=0; k<5; k++) + buffer[bufferpos/50 + k] = (A & 15)*16; +} + + +static unsigned char RenderVoicedSample(unsigned short hi, unsigned char off, unsigned char phase1) +{ + do { + unsigned char bit = 8; + unsigned char 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(unsigned short hi, unsigned char off, unsigned char mem53) +{ + do { + unsigned char bit = 8; + unsigned char 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. + + +void RenderSample(unsigned char *mem66, unsigned char consonantFlag, unsigned char mem49) +{ + // mem49 == current phoneme's index + + // mask low three bits and subtract 1 get value to + // convert 0 bits on unvoiced samples. + unsigned char hibyte = (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 + + unsigned short hi = hibyte*256; + // voiced sample? + unsigned char pitchl = consonantFlag & 248; + if(pitchl == 0) { + // voiced phoneme: Z*, ZH, V*, DH + pitchl = pitches[mem49] >> 4; + *mem66 = RenderVoicedSample(hi, *mem66, pitchl ^ 255); + } + else + RenderUnvoicedSample(hi, 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() +{ + unsigned char X = 0; + unsigned int i = 0; + while(i < 256) { + // get the phoneme at the index + unsigned char phoneme = phonemeIndexOutput[i]; + unsigned char phase1; + unsigned 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] = pitch + phase1; // pitch + ++X; + } while(--phase2 != 0); + + ++i; + } +} + + +// RESCALE AMPLITUDE +// +// Rescale volume from a linear scale to decibels. +// +void RescaleAmplitude() +{ + int i; + for(i=255; i>=0; i--) + { + amplitude1[i] = amplitudeRescale[amplitude1[i]]; + amplitude2[i] = amplitudeRescale[amplitude2[i]]; + amplitude3[i] = amplitudeRescale[amplitude3[i]]; + } +} + + + +// 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). + +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] -= (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. +void Render() +{ + unsigned char t; + + if (phonemeIndexOutput[0] == 255) return; //exit if no data + + CreateFrames(); + t = CreateTransitions(); + + if (!singmode) AssignPitchContour(); + RescaleAmplitude(); + + if (debug) { + PrintOutput(sampledConsonantFlag, frequency1, frequency2, frequency3, amplitude1, amplitude2, amplitude3, pitches); + } + + 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. + +void AddInflection(unsigned char inflection, unsigned char pos) +{ + unsigned char A; + // store the location of the punctuation + unsigned char 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. +*/ +void SetMouthThroat(unsigned char mouth, unsigned char throat) +{ + // mouth formants (F1) 5..29 + static const 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}; + + // throat formants (F2) 5..29 + static const 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, + }; + + // there must be no zeros in this 2 tables + // formant 1 frequencies (mouth) 48..53 + static const unsigned char mouthFormants48_53[6] = {19, 27, 21, 27, 18, 13}; + + // formant 2 frequencies (throat) 48..53 + static const unsigned char throatFormants48_53[6] = {72, 39, 31, 43, 30, 34}; + + unsigned char newFrequency = 0; + unsigned char pos = 5; + + // recalculate formant frequencies 5..29 for the mouth (F1) and throat (F2) + while(pos < 30) + { + // recalculate mouth frequency + unsigned char 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) + unsigned char 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++; + } +} diff --git a/src/sam.c b/src/sam.c index beaf01df..bce479b1 100644 --- a/src/sam.c +++ b/src/sam.c @@ -1,22 +1,21 @@ #include #include #include + #include "debug.h" #include "sam.h" #include "render.h" #include "SamTabs.h" - -enum { - pR = 23, - pD = 57, - pT = 69, - BREAK = 254, - END = 255 -}; - - - -char input[256]; //tab39445 + +enum { + pR = 23, + pD = 57, + pT = 69, + BREAK = 254, + END = 255 +}; + +unsigned char input[256]; //tab39445 //standard sam sound unsigned char speed = 72; unsigned char pitch = 64; @@ -26,17 +25,6 @@ int singmode = 0; extern int debug; -unsigned char mem39; -unsigned char mem44; -unsigned char mem47; -unsigned char mem49; -unsigned char mem50; -unsigned char mem51; -unsigned char mem53; -unsigned char mem59=0; - -unsigned char X; - unsigned char stress[256]; //numbers from 0 to 8 unsigned char phonemeLength[256]; //tab40160 unsigned char phonemeindex[256]; @@ -45,18 +33,15 @@ unsigned char phonemeIndexOutput[60]; //tab47296 unsigned char stressOutput[60]; //tab47365 unsigned char phonemeLengthOutput[60]; //tab47416 - - - // contains the final soundbuffer int bufferpos=0; char *buffer = NULL; -void SetInput(char *_input) +void SetInput(unsigned char *_input) { int i, l; - l = strlen(_input); + l = strlen((char*)_input); if (l > 254) l = 254; for(i=0; i 80) { - phonemeindex[X] = END; - break; // error: delete all behind it - } - } while (++X != 0); - InsertBreath(mem59); - - if (debug) PrintPhonemes(phonemeindex, phonemeLength, stress); - - PrepareOutput(); - return 1; -} - -void PrepareOutput() { - unsigned char srcpos = 0; // Position in source - unsigned char destpos = 0; // Position in output - - while(1) { - unsigned char A = phonemeindex[srcpos]; - phonemeIndexOutput[destpos] = A; - switch(A) { - case END: - Render(); - return; - case BREAK: - phonemeIndexOutput[destpos] = END; - Render(); - destpos = 0; - break; - case 0: - break; - default: - phonemeLengthOutput[destpos] = phonemeLength[srcpos]; - stressOutput[destpos] = stress[srcpos]; - ++destpos; - } - ++srcpos; - } -} - - -void InsertBreath(unsigned char mem59) { - unsigned char mem54 = 255; - unsigned char len = 0; - unsigned char index; //variable Y - - unsigned char pos = 0; - - while((index = phonemeindex[pos]) != END) { - len += phonemeLength[pos]; - if (len < 232) { - if (index == BREAK) { - } else if (!(flags[index]& FLAG_PUNCT)) { - if (index == 0) mem54 = pos; - } else { - len = 0; - Insert(++pos, BREAK, mem59, 0); - } - } else { - pos = mem54; - phonemeindex[pos] = 31; // 'Q*' glottal stop - phonemeLength[pos] = 4; - stress[pos] = 0; - - len = 0; - Insert(++pos, BREAK, mem59, 0); - } - ++pos; - } -} - - + +void Init() { + int i; + SetMouthThroat( mouth, throat); + + bufferpos = 0; + // TODO, check for free the memory, 10 seconds of output should be more than enough + buffer = malloc(22050*10); + + for(i=0; i<256; i++) { + stress[i] = 0; + phonemeLength[i] = 0; + } + + for(i=0; i<60; i++) { + phonemeIndexOutput[i] = 0; + stressOutput[i] = 0; + phonemeLengthOutput[i] = 0; + } + phonemeindex[255] = END; //to prevent buffer overflow // ML : changed from 32 to 255 to stop freezing with long inputs +} + +int SAMMain() { + unsigned char X = 0; //!! is this intended like this? + Init(); + /* FIXME: At odds with assignment in Init() */ + phonemeindex[255] = 32; //to prevent buffer overflow + + if (!Parser1()) return 0; + if (debug) PrintPhonemes(phonemeindex, phonemeLength, stress); + Parser2(); + CopyStress(); + SetPhonemeLength(); + AdjustLengths(); + Code41240(); + do { + if (phonemeindex[X] > 80) { + phonemeindex[X] = END; + break; // error: delete all behind it + } + } while (++X != 0); + InsertBreath(); + + if (debug) PrintPhonemes(phonemeindex, phonemeLength, stress); + + PrepareOutput(); + return 1; +} + +void PrepareOutput() { + unsigned char srcpos = 0; // Position in source + unsigned char destpos = 0; // Position in output + + while(1) { + unsigned char A = phonemeindex[srcpos]; + phonemeIndexOutput[destpos] = A; + switch(A) { + case END: + Render(); + return; + case BREAK: + phonemeIndexOutput[destpos] = END; + Render(); + destpos = 0; + break; + case 0: + break; + default: + phonemeLengthOutput[destpos] = phonemeLength[srcpos]; + stressOutput[destpos] = stress[srcpos]; + ++destpos; + break; + } + ++srcpos; + } +} + + +void InsertBreath() { + unsigned char mem54 = 255; + unsigned char len = 0; + unsigned char index; //variable Y + + unsigned char pos = 0; + + while((index = phonemeindex[pos]) != END) { + len += phonemeLength[pos]; + if (len < 232) { + if (index == BREAK) { + } else if (!(flags[index] & FLAG_PUNCT)) { + if (index == 0) mem54 = pos; + } else { + len = 0; + Insert(++pos, BREAK, 0, 0); + } + } else { + pos = mem54; + phonemeindex[pos] = 31; // 'Q*' glottal stop + phonemeLength[pos] = 4; + stress[pos] = 0; + + len = 0; + Insert(++pos, BREAK, 0, 0); + } + ++pos; + } +} + + // Iterates through the phoneme buffer, copying the stress value from // the following phoneme under the following circumstance: @@ -204,77 +191,76 @@ void InsertBreath(unsigned char mem59) { // to the L that precedes it. - -void CopyStress() { - // loop thought all the phonemes to be output - unsigned char pos=0; //mem66 - unsigned char Y; - while((Y = phonemeindex[pos]) != END) { - // if CONSONANT_FLAG set, skip - only vowels get stress - if (flags[Y] & 64) { - Y = phonemeindex[pos+1]; - - // if the following phoneme is the end, or a vowel, skip - if (Y != END && (flags[Y] & 128) != 0) { - // get the stress value at the next position - Y = stress[pos+1]; - if (Y && !(Y&128)) { - // if next phoneme is stressed, and a VOWEL OR ER - // copy stress from next phoneme to this one - stress[pos] = Y+1; - } - } - } - - ++pos; - } -} - -void Insert(unsigned char position/*var57*/, unsigned char mem60, unsigned char mem59, unsigned char mem58) -{ - int i; - for(i=253; i >= position; i--) // ML : always keep last safe-guarding 255 - { - phonemeindex[i+1] = phonemeindex[i]; - phonemeLength[i+1] = phonemeLength[i]; - stress[i+1] = stress[i]; - } - - phonemeindex[position] = mem60; - phonemeLength[position] = mem59; - stress[position] = mem58; - return; -} - - -signed int full_match(unsigned char sign1, unsigned char sign2) { - unsigned char Y = 0; - do { - // GET FIRST CHARACTER AT POSITION Y IN signInputTable - // --> should change name to PhonemeNameTable1 - unsigned char A = signInputTable1[Y]; - - if (A == sign1) { - A = signInputTable2[Y]; - // NOT A SPECIAL AND MATCHES SECOND CHARACTER? - if ((A != '*') && (A == sign2)) return Y; - } - } while (++Y != 81); - return -1; -} - -signed int wild_match(unsigned char sign1, unsigned char sign2) { - signed int Y = 0; - do { - if (signInputTable2[Y] == '*') { - if (signInputTable1[Y] == sign1) return Y; - } - } while (++Y != 81); - return -1; -} - - - + +void CopyStress() { + // loop thought all the phonemes to be output + unsigned char pos=0; //mem66 + unsigned char Y; + while((Y = phonemeindex[pos]) != END) { + // if CONSONANT_FLAG set, skip - only vowels get stress + if (flags[Y] & 64) { + Y = phonemeindex[pos+1]; + + // if the following phoneme is the end, or a vowel, skip + if (Y != END && (flags[Y] & 128) != 0) { + // get the stress value at the next position + Y = stress[pos+1]; + if (Y && !(Y&128)) { + // if next phoneme is stressed, and a VOWEL OR ER + // copy stress from next phoneme to this one + stress[pos] = Y+1; + } + } + } + + ++pos; + } +} + +void Insert(unsigned char position/*var57*/, unsigned char mem60, unsigned char mem59, unsigned char mem58) +{ + int i; + for(i=253; i >= position; i--) // ML : always keep last safe-guarding 255 + { + phonemeindex[i+1] = phonemeindex[i]; + phonemeLength[i+1] = phonemeLength[i]; + stress[i+1] = stress[i]; + } + + phonemeindex[position] = mem60; + phonemeLength[position] = mem59; + stress[position] = mem58; +} + + +signed int full_match(unsigned char sign1, unsigned char sign2) { + unsigned char Y = 0; + do { + // GET FIRST CHARACTER AT POSITION Y IN signInputTable + // --> should change name to PhonemeNameTable1 + unsigned char A = signInputTable1[Y]; + + if (A == sign1) { + A = signInputTable2[Y]; + // NOT A SPECIAL AND MATCHES SECOND CHARACTER? + if ((A != '*') && (A == sign2)) return Y; + } + } while (++Y != 81); + return -1; +} + +signed int wild_match(unsigned char sign1) { + signed int Y = 0; + do { + if (signInputTable2[Y] == '*') { + if (signInputTable1[Y] == sign1) return Y; + } + } while (++Y != 81); + return -1; +} + + + // The input[] buffer contains a string of phonemes and stress markers along // the lines of: // @@ -313,119 +299,121 @@ signed int wild_match(unsigned char sign1, unsigned char sign2) { // 1. phonemeIndex[] will contain the index of all the phonemes. // 2. The last index in phonemeIndex[] will be 255. // 3. stress[] will contain the stress value for each phoneme - -// input[] holds the string of phonemes, each two bytes wide -// signInputTable1[] holds the first character of each phoneme -// signInputTable2[] holds te second character of each phoneme -// phonemeIndex[] holds the indexes of the phonemes after parsing input[] -// -// The parser scans through the input[], finding the names of the phonemes -// by searching signInputTable1[] and signInputTable2[]. On a match, it -// copies the index of the phoneme into the phonemeIndexTable[]. -// -// The character <0x9B> marks the end of text in input[]. When it is reached, -// the index 255 is placed at the end of the phonemeIndexTable[], and the -// function returns with a 1 indicating success. -int Parser1() -{ - int i; - unsigned char sign1; - unsigned char sign2; - unsigned char position = 0; - unsigned char srcpos = 0; - - for(i=0; i<256; i++) stress[i] = 0; // Clear the stress table. - - while((sign1 = input[srcpos]) != 155) { // 155 (\233) is end of line marker - sign2 = input[++srcpos]; - signed int match = 0; - if ((match = full_match(sign1, sign2)) != -1) { - // Matched both characters (no wildcards) - phonemeindex[position++] = (unsigned char)match; - ++srcpos; // Skip the second character of the input as we've matched it - } else if ((match=wild_match(sign1,sign2)) != -1) { - // Matched just the first character (with second character matching '*' - phonemeindex[position++] = (unsigned char)match; - } else { - // Should be a stress character. Search through the - // stress table backwards. - match = 8; // End of stress table. FIXME: Don't hardcode. - while( (sign1 != stressInputTable[match]) && (match>0)) --match; - - if (match == 0) return 0; // failure - - stress[position-1] = match; // Set stress for prior phoneme - } - } //while - - phonemeindex[position] = END; - return 1; -} - - -//change phonemelength depedendent on stress -void SetPhonemeLength() { - int position = 0; - while(phonemeindex[position] != 255 ) { - unsigned char A = stress[position]; - if ((A == 0) || ((A&128) != 0)) { - phonemeLength[position] = phonemeLengthTable[phonemeindex[position]]; - } else { - phonemeLength[position] = phonemeStressedLengthTable[phonemeindex[position]]; - } - position++; - } -} - -void Code41240() { - unsigned char pos=0; - - while(phonemeindex[pos] != END) { - unsigned char index = phonemeindex[pos]; - - if ((flags[index]& FLAG_STOPCONS)) { - if ((flags[index]& FLAG_PLOSIVE)) { - unsigned char A; - unsigned char X = pos; - while(!(A = phonemeindex[++X])); /* Skip pause */ - - if (A != END) { - if ((flags[A] & 8) || (A == 36) || (A == 37)) {++pos; continue;} // '/H' '/X' - } - - } - Insert(pos+1, index+1, phonemeLengthTable[index+1], stress[pos]); - Insert(pos+2, index+2, phonemeLengthTable[index+2], stress[pos]); - pos += 2; - } - ++pos; - } -} - - -void ChangeRule(unsigned char position, unsigned char rule,unsigned char mem60, unsigned char mem59, unsigned char stress, const char * descr) -{ - if (debug) printf("RULE: %s\n",descr); - phonemeindex[position] = rule; - Insert(position+1, mem60, mem59, stress); -} - -void drule(const char * str) { - if (debug) printf("RULE: %s\n",str); -} - -void drule_pre(const char *descr, unsigned char X) { - drule(descr); - if (debug) printf("PRE\n"); - if (debug) printf("phoneme %d (%c%c) length %d\n", X, signInputTable1[phonemeindex[X]], signInputTable2[phonemeindex[X]], phonemeLength[X]); -} - -void drule_post(unsigned char X) { - if (debug) printf("POST\n"); - if (debug) printf("phoneme %d (%c%c) length %d\n", X, signInputTable1[phonemeindex[X]], signInputTable2[phonemeindex[X]], phonemeLength[X]); -} - - + +// input[] holds the string of phonemes, each two bytes wide +// signInputTable1[] holds the first character of each phoneme +// signInputTable2[] holds te second character of each phoneme +// phonemeIndex[] holds the indexes of the phonemes after parsing input[] +// +// The parser scans through the input[], finding the names of the phonemes +// by searching signInputTable1[] and signInputTable2[]. On a match, it +// copies the index of the phoneme into the phonemeIndexTable[]. +// +// The character <0x9B> marks the end of text in input[]. When it is reached, +// the index 255 is placed at the end of the phonemeIndexTable[], and the +// function returns with a 1 indicating success. +int Parser1() +{ + unsigned char sign1; + unsigned char position = 0; + unsigned char srcpos = 0; + + memset(stress, 0, 256); // Clear the stress table. + + while((sign1 = input[srcpos]) != 155) { // 155 (\233) is end of line marker + signed int match; + unsigned char sign2 = input[++srcpos]; + if ((match = full_match(sign1, sign2)) != -1) { + // Matched both characters (no wildcards) + phonemeindex[position++] = (unsigned char)match; + ++srcpos; // Skip the second character of the input as we've matched it + } else if ((match = wild_match(sign1)) != -1) { + // Matched just the first character (with second character matching '*' + phonemeindex[position++] = (unsigned char)match; + } else { + // Should be a stress character. Search through the + // stress table backwards. + match = 8; // End of stress table. FIXME: Don't hardcode. + while( (sign1 != stressInputTable[match]) && (match>0) ) --match; + + if (match == 0) return 0; // failure + + stress[position-1] = (unsigned char)match; // Set stress for prior phoneme + } + } //while + + phonemeindex[position] = END; + return 1; +} + + +//change phonemelength depedendent on stress +void SetPhonemeLength() { + int position = 0; + while(phonemeindex[position] != 255) { + unsigned char A = stress[position]; + if ((A == 0) || ((A&128) != 0)) { + phonemeLength[position] = phonemeLengthTable[phonemeindex[position]]; + } else { + phonemeLength[position] = phonemeStressedLengthTable[phonemeindex[position]]; + } + position++; + } +} + +void Code41240() { + unsigned char pos=0; + + while(phonemeindex[pos] != END) { + unsigned char index = phonemeindex[pos]; + + if ((flags[index] & FLAG_STOPCONS)) { + if ((flags[index] & FLAG_PLOSIVE)) { + unsigned char A; + unsigned char X = pos; + while(!phonemeindex[++X]); /* Skip pause */ + A = phonemeindex[X]; + if (A != END) { + if ((flags[A] & 8) || (A == 36) || (A == 37)) {++pos; continue;} // '/H' '/X' + } + + } + Insert(pos+1, index+1, phonemeLengthTable[index+1], stress[pos]); + Insert(pos+2, index+2, phonemeLengthTable[index+2], stress[pos]); + pos += 2; + } + ++pos; + } +} + + +void ChangeRule(unsigned char position, unsigned char mem60, const char * descr) +{ + if (debug) printf("RULE: %s\n",descr); + phonemeindex[position] = 13; //rule; + Insert(position+1, mem60, 0, stress[position]); +} + +void drule(const char * str) { + if (debug) printf("RULE: %s\n",str); +} + +void drule_pre(const char *descr, unsigned char X) { + drule(descr); + if (debug) { + printf("PRE\n"); + printf("phoneme %d (%c%c) length %d\n", X, signInputTable1[phonemeindex[X]], signInputTable2[phonemeindex[X]], phonemeLength[X]); + } +} + +void drule_post(unsigned char X) { + if (debug) { + printf("POST\n"); + printf("phoneme %d (%c%c) length %d\n", X, signInputTable1[phonemeindex[X]], signInputTable2[phonemeindex[X]], phonemeLength[X]); + } +} + + // Rewrites the phonemes using the following rules: // // -> WX @@ -449,286 +437,293 @@ void drule_post(unsigned char X) { // J -> J J' (J requires two phonemes to represent it) // T -> DX // D -> DX - - -void rule_alveolar_uw(unsigned char X) { - // ALVEOLAR flag set? - if (flags[phonemeindex[X-1]] & FLAG_ALVEOLAR) { - drule(" UW -> UX"); - phonemeindex[X] = 16; - } -} - -void rule_ch(unsigned char X, unsigned char mem59) { - drule("CH -> CH CH+1"); - Insert(X+1, 43, mem59, stress[X]); -} - -void rule_j(unsigned char X, unsigned char mem59) { - drule("J -> J J+1"); - Insert(X+1, 45, mem59, stress[X]); -} - -void rule_g(unsigned char pos) { - // G -> GX - // Example: GO - - unsigned char index = phonemeindex[pos+1]; - - // If dipthong ending with YX, move continue processing next phoneme - if ((index != 255) && ((flags[index] & FLAG_DIP_YX) == 0)) { - // replace G with GX and continue processing next phoneme - drule("G -> GX "); - phonemeindex[pos] = 63; // 'GX' - } -} - - -void change(unsigned char pos, unsigned char val, const char * rule) { - drule(rule); - phonemeindex[pos] = val; -} - - -void rule_dipthong(unsigned char p, unsigned char pf, unsigned char pos, unsigned char mem59) { - // -> WX - // -> YX - // Example: OIL, COW - - // If ends with IY, use YX, else use WX - unsigned char A = (pf & FLAG_DIP_YX) ? 21 : 20; // 'WX' = 20 'YX' = 21 - - // Insert at WX or YX following, copying the stress - if (A==20) drule("insert WX following dipthong NOT ending in IY sound"); - if (A==21) drule("insert YX following dipthong ending in IY sound"); - Insert(pos+1, A, mem59, stress[pos]); - - if (p == 53 || p == 42 || p == 44) { - if (p == 53) rule_alveolar_uw(pos); // Example: NEW, DEW, SUE, ZOO, THOO, TOO - else if (p == 42) rule_ch(pos,mem59); // Example: CHEW - else if (p == 44) rule_j(pos,mem59); // Example: JAY - } -} - -void Parser2() { - unsigned char pos = 0; //mem66; - unsigned char p; - - if (debug) printf("Parser2\n"); - - while((p = phonemeindex[pos]) != END) { - if (debug) printf("%d: %c%c\n", pos, signInputTable1[p], signInputTable2[p]); - - if (p == 0) { // Is phoneme pause? - ++pos; - continue; - } - - unsigned char pf = flags[p]; - unsigned char prior = phonemeindex[pos-1]; - - if ((pf & FLAG_DIPTHONG)) rule_dipthong(p, pf, pos, mem59); - else if (p == 78) ChangeRule(pos, 13, 24, mem59, stress[pos],"UL -> AX L"); // Example: MEDDLE - else if (p == 79) ChangeRule(pos, 13, 27, mem59, stress[pos], "UM -> AX M"); // Example: ASTRONOMY - else if (p == 80) ChangeRule(pos, 13, 28, mem59, stress[pos], "UN -> AX N"); // Example: FUNCTION - else if ((pf & FLAG_VOWEL) && stress[pos]) { - // RULE: - // -> Q - // EXAMPLE: AWAY EIGHT - if (!phonemeindex[pos+1]) { // If following phoneme is a pause, get next - p = phonemeindex[pos+2]; - if (p!=END && (flags[p] & FLAG_VOWEL) && stress[pos+2]) { - drule("Insert glottal stop between two stressed vowels with space between them"); - Insert(pos+2, 31, mem59, 0); // 31 = 'Q' - } - } - } else if (p == pR) { // RULES FOR PHONEMES BEFORE R - if (prior == pT) change(pos-1,42, "T R -> CH R"); // Example: TRACK - else if (prior == pD) change(pos-1,44, "D R -> J R"); // Example: DRY - else if (flags[prior] & FLAG_VOWEL) change(pos, 18, " R -> RX"); // Example: ART - } else if (p == 24 && (flags[prior] & FLAG_VOWEL)) change(pos, 19, " L -> LX"); // Example: ALL - else if (prior == 60 && p == 32) { // 'G' 'S' - // Can't get to fire - - // 1. The G -> GX rule intervenes - // 2. Reciter already replaces GS -> GZ - change(pos, 38, "G S -> G Z"); - } else if (p == 60) rule_g(pos); - else { - if (p == 72) { // 'K' - // K -> KX - // Example: COW - unsigned char Y = phonemeindex[pos+1]; - // If at end, replace current phoneme with KX - if ((flags[Y] & FLAG_DIP_YX)==0 || Y==END) { // VOWELS AND DIPTHONGS ENDING WITH IY SOUND flag set? - change(pos, 75, "K -> KX "); - p = 75; - pf = flags[p]; - } - } - - // Replace with softer version? - if ((flags[p] & FLAG_PLOSIVE) && (prior == 32)) { // 'S' - // RULE: - // S P -> S B - // S T -> S D - // S K -> S G - // S KX -> S GX - // Examples: SPY, STY, SKY, SCOWL - - if (debug) printf("RULE: S* %c%c -> S* %c%c\n", signInputTable1[p], signInputTable2[p],signInputTable1[p-12], signInputTable2[p-12]); - phonemeindex[pos] = p-12; - } else if (!(pf & FLAG_PLOSIVE)) { - p = phonemeindex[pos]; - if (p == 53) rule_alveolar_uw(pos); // Example: NEW, DEW, SUE, ZOO, THOO, TOO - else if (p == 42) rule_ch(pos,mem59); // Example: CHEW - else if (p == 44) rule_j(pos,mem59); // Example: JAY - } - - if (p == 69 || p == 57) { // 'T', 'D' - // RULE: Soften T following vowel - // NOTE: This rule fails for cases such as "ODD" - // T -> DX - // D -> DX - // Example: PARTY, TARDY - if (flags[phonemeindex[pos-1]] & FLAG_VOWEL) { - p = phonemeindex[pos+1]; - if (!p) p = phonemeindex[pos+2]; - if ((flags[p] & FLAG_VOWEL) && !stress[pos+1]) change(pos,30, "Soften T or D following vowel or ER and preceding a pause -> DX"); - } - } - } - pos++; - } // while -} - -// Applies various rules that adjust the lengths of phonemes -// -// Lengthen or between and by 1.5 -// - decrease length by 1 -// - decrease vowel by 1/8th -// - increase vowel by 1/2 + 1 -// - set nasal = 5, consonant = 6 -// {optional silence} - shorten both to 1/2 + 1 -// - decrease by 2 -// -void AdjustLengths() { - // LENGTHEN VOWELS PRECEDING PUNCTUATION - // - // Search for punctuation. If found, back up to the first vowel, then - // process all phonemes between there and up to (but not including) the punctuation. - // If any phoneme is found that is a either a fricative or voiced, the duration is - // increased by (length * 1.5) + 1 - - // loop index - unsigned char X = 0; - unsigned char index; - - while((index = phonemeindex[X]) != END) { - // not punctuation? - if((flags[index] & FLAG_PUNCT) == 0) { - ++X; - continue; - } - - unsigned char loopIndex = X; - - while (--X && !(flags[phonemeindex[X]] & FLAG_VOWEL)); // back up while not a vowel - if (X == 0) break; - - do { - // test for vowel - index = phonemeindex[X]; - + + +void rule_alveolar_uw(unsigned char X) { + // ALVEOLAR flag set? + if (flags[phonemeindex[X-1]] & FLAG_ALVEOLAR) { + drule(" UW -> UX"); + phonemeindex[X] = 16; + } +} + +void rule_ch(unsigned char X) { + drule("CH -> CH CH+1"); + Insert(X+1, 43, 0, stress[X]); +} + +void rule_j(unsigned char X) { + drule("J -> J J+1"); + Insert(X+1, 45, 0, stress[X]); +} + +void rule_g(unsigned char pos) { + // G -> GX + // Example: GO + + unsigned char index = phonemeindex[pos+1]; + + // If dipthong ending with YX, move continue processing next phoneme + if ((index != 255) && ((flags[index] & FLAG_DIP_YX) == 0)) { + // replace G with GX and continue processing next phoneme + drule("G -> GX "); + phonemeindex[pos] = 63; // 'GX' + } +} + + +void change(unsigned char pos, unsigned char val, const char * rule) { + drule(rule); + phonemeindex[pos] = val; +} + + +void rule_dipthong(unsigned char p, unsigned short pf, unsigned char pos) { + // -> WX + // -> YX + // Example: OIL, COW + + // If ends with IY, use YX, else use WX + unsigned char A = (pf & FLAG_DIP_YX) ? 21 : 20; // 'WX' = 20 'YX' = 21 + + // Insert at WX or YX following, copying the stress + if (A==20) drule("insert WX following dipthong NOT ending in IY sound"); + else if (A==21) drule("insert YX following dipthong ending in IY sound"); + Insert(pos+1, A, 0, stress[pos]); + + if (p == 53) rule_alveolar_uw(pos); // Example: NEW, DEW, SUE, ZOO, THOO, TOO + else if (p == 42) rule_ch(pos); // Example: CHEW + else if (p == 44) rule_j(pos); // Example: JAY +} + +void Parser2() { + unsigned char pos = 0; //mem66; + unsigned char p; + + if (debug) printf("Parser2\n"); + + while((p = phonemeindex[pos]) != END) { + unsigned short pf; + unsigned char prior; + + if (debug) printf("%d: %c%c\n", pos, signInputTable1[p], signInputTable2[p]); + + if (p == 0) { // Is phoneme pause? + ++pos; + continue; + } + + pf = flags[p]; + prior = phonemeindex[pos-1]; + + if ((pf & FLAG_DIPTHONG)) rule_dipthong(p, pf, pos); + else if (p == 78) ChangeRule(pos, 24, "UL -> AX L"); // Example: MEDDLE + else if (p == 79) ChangeRule(pos, 27, "UM -> AX M"); // Example: ASTRONOMY + else if (p == 80) ChangeRule(pos, 28, "UN -> AX N"); // Example: FUNCTION + else if ((pf & FLAG_VOWEL) && stress[pos]) { + // RULE: + // -> Q + // EXAMPLE: AWAY EIGHT + if (!phonemeindex[pos+1]) { // If following phoneme is a pause, get next + p = phonemeindex[pos+2]; + if (p!=END && (flags[p] & FLAG_VOWEL) && stress[pos+2]) { + drule("Insert glottal stop between two stressed vowels with space between them"); + Insert(pos+2, 31, 0, 0); // 31 = 'Q' + } + } + } else if (p == pR) { // RULES FOR PHONEMES BEFORE R + if (prior == pT) change(pos-1,42, "T R -> CH R"); // Example: TRACK + else if (prior == pD) change(pos-1,44, "D R -> J R"); // Example: DRY + else if (flags[prior] & FLAG_VOWEL) change(pos, 18, " R -> RX"); // Example: ART + } else if (p == 24 && (flags[prior] & FLAG_VOWEL)) change(pos, 19, " L -> LX"); // Example: ALL + else if (prior == 60 && p == 32) { // 'G' 'S' + // Can't get to fire - + // 1. The G -> GX rule intervenes + // 2. Reciter already replaces GS -> GZ + change(pos, 38, "G S -> G Z"); + } else if (p == 60) rule_g(pos); + else { + if (p == 72) { // 'K' + // K -> KX + // Example: COW + unsigned char Y = phonemeindex[pos+1]; + // If at end, replace current phoneme with KX + if ((flags[Y] & FLAG_DIP_YX)==0 || Y==END) { // VOWELS AND DIPTHONGS ENDING WITH IY SOUND flag set? + change(pos, 75, "K -> KX "); + p = 75; + pf = flags[p]; + } + } + + // Replace with softer version? + if ((flags[p] & FLAG_PLOSIVE) && (prior == 32)) { // 'S' + // RULE: + // S P -> S B + // S T -> S D + // S K -> S G + // S KX -> S GX + // Examples: SPY, STY, SKY, SCOWL + + if (debug) printf("RULE: S* %c%c -> S* %c%c\n", signInputTable1[p], signInputTable2[p],signInputTable1[p-12], signInputTable2[p-12]); + phonemeindex[pos] = p-12; + } else if (!(pf & FLAG_PLOSIVE)) { + p = phonemeindex[pos]; + if (p == 53) rule_alveolar_uw(pos); // Example: NEW, DEW, SUE, ZOO, THOO, TOO + else if (p == 42) rule_ch(pos); // Example: CHEW + else if (p == 44) rule_j(pos); // Example: JAY + } + + if (p == 69 || p == 57) { // 'T', 'D' + // RULE: Soften T following vowel + // NOTE: This rule fails for cases such as "ODD" + // T -> DX + // D -> DX + // Example: PARTY, TARDY + if (flags[phonemeindex[pos-1]] & FLAG_VOWEL) { + p = phonemeindex[pos+1]; + if (!p) p = phonemeindex[pos+2]; + if ((flags[p] & FLAG_VOWEL) && !stress[pos+1]) change(pos,30, "Soften T or D following vowel or ER and preceding a pause -> DX"); + } + } + } + pos++; + } // while +} + +// Applies various rules that adjust the lengths of phonemes +// +// Lengthen or between and by 1.5 +// - decrease length by 1 +// - decrease vowel by 1/8th +// - increase vowel by 1/2 + 1 +// - set nasal = 5, consonant = 6 +// {optional silence} - shorten both to 1/2 + 1 +// - decrease by 2 +// +void AdjustLengths() { + // LENGTHEN VOWELS PRECEDING PUNCTUATION + // + // Search for punctuation. If found, back up to the first vowel, then + // process all phonemes between there and up to (but not including) the punctuation. + // If any phoneme is found that is a either a fricative or voiced, the duration is + // increased by (length * 1.5) + 1 + + // loop index + { + unsigned char X = 0; + unsigned char index; + + while((index = phonemeindex[X]) != END) { + unsigned char loopIndex; + + // not punctuation? + if((flags[index] & FLAG_PUNCT) == 0) { + ++X; + continue; + } + + loopIndex = X; + + while (--X && !(flags[phonemeindex[X]] & FLAG_VOWEL)); // back up while not a vowel + if (X == 0) break; + + do { + // test for vowel + index = phonemeindex[X]; + // test for fricative/unvoiced or not voiced - if(!(flags[index] & FLAG_FRICATIVE) || (flags[index] & FLAG_VOICED)) { //nochmal überprüfen - unsigned char A = phonemeLength[X]; - // change phoneme length to (length * 1.5) + 1 - drule_pre("Lengthen or between and by 1.5",X); - phonemeLength[X] = (A >> 1) + A + 1; - drule_post(X); - } - } while (++X != loopIndex); - X++; - } // while - - // Similar to the above routine, but shorten vowels under some circumstances - - // Loop throught all phonemes - unsigned char loopIndex=0; - - while((index = phonemeindex[loopIndex]) != END) { - unsigned char X = loopIndex; - - if (flags[index] & FLAG_VOWEL) { - index = phonemeindex[loopIndex+1]; - if (!(flags[index] & FLAG_CONSONANT)) { - if ((index == 18) || (index == 19)) { // 'RX', 'LX' - index = phonemeindex[loopIndex+2]; - if ((flags[index] & FLAG_CONSONANT)) { - drule_pre(" - decrease length of vowel by 1\n", loopIndex); - phonemeLength[loopIndex]--; - drule_post(loopIndex); - } - } - } else { // Got here if not - unsigned char flag = (index == END) ? 65 : flags[index]; // 65 if end marker - - if (!(flag & FLAG_VOICED)) { // Unvoiced - // *, .*, ?*, ,*, -*, DX, S*, SH, F*, TH, /H, /X, CH, P*, T*, K*, KX - if((flag & FLAG_PLOSIVE)) { // unvoiced plosive - // RULE: - // - drule_pre(" - decrease vowel by 1/8th",loopIndex); - phonemeLength[loopIndex] -= (phonemeLength[loopIndex] >> 3); - drule_post(loopIndex); - } - } else { - drule_pre(" - increase vowel by 1/2 + 1\n",X-1); - // decrease length - unsigned char A = phonemeLength[loopIndex]; - phonemeLength[loopIndex] = (A >> 2) + A + 1; // 5/4*A + 1 - drule_post(loopIndex); - } - } - } else if((flags[index] & FLAG_NASAL) != 0) { // nasal? - // RULE: - // Set punctuation length to 6 - // Set stop consonant length to 5 - index = phonemeindex[++X]; - if (index != END && (flags[index] & FLAG_STOPCONS)) { - drule(" - set nasal = 5, consonant = 6"); - phonemeLength[X] = 6; // set stop consonant length to 6 - phonemeLength[X-1] = 5; // set nasal length to 5 - } - } else if((flags[index] & FLAG_STOPCONS)) { // (voiced) stop consonant? - // RULE: {optional silence} - // Shorten both to (length/2 + 1) - - // move past silence - while ((index = phonemeindex[++X]) == 0); - - if (index != END && (flags[index] & FLAG_STOPCONS)) { - // FIXME, this looks wrong? + if(!(flags[index] & FLAG_FRICATIVE) || (flags[index] & FLAG_VOICED)) { //nochmal überprüfen + unsigned char A = phonemeLength[X]; + // change phoneme length to (length * 1.5) + 1 + drule_pre("Lengthen or between and by 1.5",X); + phonemeLength[X] = (A >> 1) + A + 1; + drule_post(X); + } + } while (++X != loopIndex); + X++; + } // while + } + + // Similar to the above routine, but shorten vowels under some circumstances + + // Loop through all phonemes + unsigned char loopIndex=0; + unsigned char index; + + while((index = phonemeindex[loopIndex]) != END) { + unsigned char X = loopIndex; + + if (flags[index] & FLAG_VOWEL) { + index = phonemeindex[loopIndex+1]; + if (!(flags[index] & FLAG_CONSONANT)) { + if ((index == 18) || (index == 19)) { // 'RX', 'LX' + index = phonemeindex[loopIndex+2]; + if ((flags[index] & FLAG_CONSONANT)) { + drule_pre(" - decrease length of vowel by 1\n", loopIndex); + phonemeLength[loopIndex]--; + drule_post(loopIndex); + } + } + } else { // Got here if not + unsigned short flag = (index == END) ? 65 : flags[index]; // 65 if end marker + + if (!(flag & FLAG_VOICED)) { // Unvoiced + // *, .*, ?*, ,*, -*, DX, S*, SH, F*, TH, /H, /X, CH, P*, T*, K*, KX + if((flag & FLAG_PLOSIVE)) { // unvoiced plosive + // RULE: + // + drule_pre(" - decrease vowel by 1/8th",loopIndex); + phonemeLength[loopIndex] -= (phonemeLength[loopIndex] >> 3); + drule_post(loopIndex); + } + } else { + unsigned char A; + drule_pre(" - increase vowel by 1/2 + 1\n",X-1); + // decrease length + A = phonemeLength[loopIndex]; + phonemeLength[loopIndex] = (A >> 2) + A + 1; // 5/4*A + 1 + drule_post(loopIndex); + } + } + } else if((flags[index] & FLAG_NASAL) != 0) { // nasal? + // RULE: + // Set punctuation length to 6 + // Set stop consonant length to 5 + index = phonemeindex[++X]; + if (index != END && (flags[index] & FLAG_STOPCONS)) { + drule(" - set nasal = 5, consonant = 6"); + phonemeLength[X] = 6; // set stop consonant length to 6 + phonemeLength[X-1] = 5; // set nasal length to 5 + } + } else if((flags[index] & FLAG_STOPCONS)) { // (voiced) stop consonant? + // RULE: {optional silence} + // Shorten both to (length/2 + 1) + + // move past silence + while ((index = phonemeindex[++X]) == 0); + + if (index != END && (flags[index] & FLAG_STOPCONS)) { + // FIXME, this looks wrong? // RULE: {optional silence} - drule(" {optional silence} - shorten both to 1/2 + 1"); - phonemeLength[X] = (phonemeLength[X] >> 1) + 1; - phonemeLength[loopIndex] = (phonemeLength[loopIndex] >> 1) + 1; - X = loopIndex; - } - } else if ((flags[index] & FLAG_LIQUIC)) { // liquic consonant? - // RULE: - // Decrease by 2 - index = phonemeindex[X-1]; // prior phoneme; - - // FIXME: The debug code here breaks the rule. - // prior phoneme a stop consonant> - if((flags[index] & FLAG_STOPCONS) != 0) - drule_pre(" - decrease by 2",X); - - phonemeLength[X] -= 2; // 20ms - drule_post(X); - } - - ++loopIndex; - } -} + drule(" {optional silence} - shorten both to 1/2 + 1"); + phonemeLength[X] = (phonemeLength[X] >> 1) + 1; + phonemeLength[loopIndex] = (phonemeLength[loopIndex] >> 1) + 1; + X = loopIndex; + } + } else if ((flags[index] & FLAG_LIQUIC)) { // liquic consonant? + // RULE: + // Decrease by 2 + index = phonemeindex[X-1]; // prior phoneme; + + // FIXME: The debug code here breaks the rule. + // prior phoneme a stop consonant> + if((flags[index] & FLAG_STOPCONS) != 0) + drule_pre(" - decrease by 2",X); + + phonemeLength[X] -= 2; // 20ms + drule_post(X); + } + + ++loopIndex; + } +} diff --git a/src/sam.h b/src/sam.h index f8a366e4..346c7b3f 100644 --- a/src/sam.h +++ b/src/sam.h @@ -1,13 +1,12 @@ #ifndef SAM_H #define SAM_H -void SetInput(char *_input); +void SetInput(unsigned char *_input); void SetSpeed(unsigned char _speed); void SetPitch(unsigned char _pitch); void SetMouth(unsigned char _mouth); void SetThroat(unsigned char _throat); void EnableSingmode(); -void EnableDebug(); int SAMMain(); @@ -36,4 +35,3 @@ int GetBufferLength(); #endif - From 9190106e427f10f90bd47c38968605160135fcef Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 23 Sep 2018 08:46:27 +0100 Subject: [PATCH 105/109] Strip whitespace --- src/sam.c | 300 +++++++++++++++++++++++++++--------------------------- 1 file changed, 150 insertions(+), 150 deletions(-) diff --git a/src/sam.c b/src/sam.c index beaf01df..4e58a8f4 100644 --- a/src/sam.c +++ b/src/sam.c @@ -1,10 +1,10 @@ -#include -#include -#include -#include "debug.h" -#include "sam.h" -#include "render.h" -#include "SamTabs.h" +#include +#include +#include +#include "debug.h" +#include "sam.h" +#include "render.h" +#include "SamTabs.h" enum { pR = 23, @@ -15,74 +15,74 @@ enum { }; - -char input[256]; //tab39445 -//standard sam sound -unsigned char speed = 72; -unsigned char pitch = 64; -unsigned char mouth = 128; -unsigned char throat = 128; -int singmode = 0; - -extern int debug; - -unsigned char mem39; -unsigned char mem44; -unsigned char mem47; -unsigned char mem49; -unsigned char mem50; -unsigned char mem51; -unsigned char mem53; -unsigned char mem59=0; - + +char input[256]; //tab39445 +//standard sam sound +unsigned char speed = 72; +unsigned char pitch = 64; +unsigned char mouth = 128; +unsigned char throat = 128; +int singmode = 0; + +extern int debug; + +unsigned char mem39; +unsigned char mem44; +unsigned char mem47; +unsigned char mem49; +unsigned char mem50; +unsigned char mem51; +unsigned char mem53; +unsigned char mem59=0; + unsigned char X; - -unsigned char stress[256]; //numbers from 0 to 8 -unsigned char phonemeLength[256]; //tab40160 -unsigned char phonemeindex[256]; - -unsigned char phonemeIndexOutput[60]; //tab47296 -unsigned char stressOutput[60]; //tab47365 -unsigned char phonemeLengthOutput[60]; //tab47416 - - - - -// contains the final soundbuffer -int bufferpos=0; -char *buffer = NULL; - - -void SetInput(char *_input) -{ - int i, l; - l = strlen(_input); - if (l > 254) l = 254; - for(i=0; i 254) l = 254; + for(i=0; i -// -// The byte 0x9B marks the end of the buffer. Some phonemes are 2 bytes -// long, such as "DH" and "AX". Others are 1 byte long, such as "T" and "Z". -// There are also stress markers, such as "5" and ".". -// -// The first character of the phonemes are stored in the table signInputTable1[]. -// The second character of the phonemes are stored in the table signInputTable2[]. -// The stress characters are arranged in low to high stress order in stressInputTable[]. -// -// The following process is used to parse the input[] buffer: -// -// Repeat until the <0x9B> character is reached: -// -// First, a search is made for a 2 character match for phonemes that do not -// end with the '*' (wildcard) character. On a match, the index of the phoneme -// is added to phonemeIndex[] and the buffer position is advanced 2 bytes. -// -// If this fails, a search is made for a 1 character match against all -// phoneme names ending with a '*' (wildcard). If this succeeds, the -// phoneme is added to phonemeIndex[] and the buffer position is advanced -// 1 byte. -// -// If this fails, search for a 1 character match in the stressInputTable[]. -// If this succeeds, the stress value is placed in the last stress[] table -// at the same index of the last added phoneme, and the buffer position is -// advanced by 1 byte. -// -// If this fails, return a 0. -// -// On success: -// -// 1. phonemeIndex[] will contain the index of all the phonemes. -// 2. The last index in phonemeIndex[] will be 255. -// 3. stress[] will contain the stress value for each phoneme +// The input[] buffer contains a string of phonemes and stress markers along +// the lines of: +// +// DHAX KAET IHZ AH5GLIY. <0x9B> +// +// The byte 0x9B marks the end of the buffer. Some phonemes are 2 bytes +// long, such as "DH" and "AX". Others are 1 byte long, such as "T" and "Z". +// There are also stress markers, such as "5" and ".". +// +// The first character of the phonemes are stored in the table signInputTable1[]. +// The second character of the phonemes are stored in the table signInputTable2[]. +// The stress characters are arranged in low to high stress order in stressInputTable[]. +// +// The following process is used to parse the input[] buffer: +// +// Repeat until the <0x9B> character is reached: +// +// First, a search is made for a 2 character match for phonemes that do not +// end with the '*' (wildcard) character. On a match, the index of the phoneme +// is added to phonemeIndex[] and the buffer position is advanced 2 bytes. +// +// If this fails, a search is made for a 1 character match against all +// phoneme names ending with a '*' (wildcard). If this succeeds, the +// phoneme is added to phonemeIndex[] and the buffer position is advanced +// 1 byte. +// +// If this fails, search for a 1 character match in the stressInputTable[]. +// If this succeeds, the stress value is placed in the last stress[] table +// at the same index of the last added phoneme, and the buffer position is +// advanced by 1 byte. +// +// If this fails, return a 0. +// +// On success: +// +// 1. phonemeIndex[] will contain the index of all the phonemes. +// 2. The last index in phonemeIndex[] will be 255. +// 3. stress[] will contain the stress value for each phoneme // input[] holds the string of phonemes, each two bytes wide // signInputTable1[] holds the first character of each phoneme @@ -426,29 +426,29 @@ void drule_post(unsigned char X) { } -// Rewrites the phonemes using the following rules: -// -// -> WX -// -> YX -// UL -> AX L -// UM -> AX M -// -> Q -// T R -> CH R -// D R -> J R -// R -> RX -// L -> LX -// G S -> G Z -// K -> KX -// G -> GX -// S P -> S B -// S T -> S D -// S K -> S G -// S KX -> S GX -// UW -> UX -// CH -> CH CH' (CH requires two phonemes to represent it) -// J -> J J' (J requires two phonemes to represent it) -// T -> DX -// D -> DX +// Rewrites the phonemes using the following rules: +// +// -> WX +// -> YX +// UL -> AX L +// UM -> AX M +// -> Q +// T R -> CH R +// D R -> J R +// R -> RX +// L -> LX +// G S -> G Z +// K -> KX +// G -> GX +// S P -> S B +// S T -> S D +// S K -> S G +// S KX -> S GX +// UW -> UX +// CH -> CH CH' (CH requires two phonemes to represent it) +// J -> J J' (J requires two phonemes to represent it) +// T -> DX +// D -> DX void rule_alveolar_uw(unsigned char X) { @@ -639,7 +639,7 @@ void AdjustLengths() { // test for vowel index = phonemeindex[X]; - // test for fricative/unvoiced or not voiced + // test for fricative/unvoiced or not voiced if(!(flags[index] & FLAG_FRICATIVE) || (flags[index] & FLAG_VOICED)) { //nochmal überprüfen unsigned char A = phonemeLength[X]; // change phoneme length to (length * 1.5) + 1 @@ -709,7 +709,7 @@ void AdjustLengths() { if (index != END && (flags[index] & FLAG_STOPCONS)) { // FIXME, this looks wrong? - // RULE: {optional silence} + // RULE: {optional silence} drule(" {optional silence} - shorten both to 1/2 + 1"); phonemeLength[X] = (phonemeLength[X] >> 1) + 1; phonemeLength[loopIndex] = (phonemeLength[loopIndex] >> 1) + 1; From 55bc9805f51d4bf50e463d8cb437229d7f2e4e20 Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 23 Sep 2018 09:05:25 +0100 Subject: [PATCH 106/109] CR/LF --- src/main.c | 538 ++++++++++++++++++++++++++--------------------------- 1 file changed, 269 insertions(+), 269 deletions(-) diff --git a/src/main.c b/src/main.c index 8ab17f3e..682d254d 100644 --- a/src/main.c +++ b/src/main.c @@ -1,269 +1,269 @@ -#include -#include -#include -#include - -#include "reciter.h" -#include "sam.h" -#include "debug.h" - -#ifdef USESDL -#include -#include -#endif - -void WriteWav(char* filename, char* buffer, int bufferlength) -{ - FILE *file = fopen(filename, "wb"); - if (file == NULL) return; - //RIFF header - fwrite("RIFF", 4, 1,file); - unsigned int filesize=bufferlength + 12 + 16 + 8 - 8; - fwrite(&filesize, 4, 1, file); - fwrite("WAVE", 4, 1, file); - - //format chunk - fwrite("fmt ", 4, 1, file); - unsigned int fmtlength = 16; - fwrite(&fmtlength, 4, 1, file); - unsigned short int format=1; //PCM - fwrite(&format, 2, 1, file); - unsigned short int channels=1; - fwrite(&channels, 2, 1, file); - unsigned int samplerate = 22050; - fwrite(&samplerate, 4, 1, file); - fwrite(&samplerate, 4, 1, file); // bytes/second - unsigned short int blockalign = 1; - fwrite(&blockalign, 2, 1, file); - unsigned short int bitspersample=8; - fwrite(&bitspersample, 2, 1, file); - - //data chunk - fwrite("data", 4, 1, file); - fwrite(&bufferlength, 4, 1, file); - fwrite(buffer, bufferlength, 1, file); - - fclose(file); -} - -void PrintUsage() -{ - printf("usage: sam [options] Word1 Word2 ....\n"); - printf("options\n"); - printf(" -phonetic enters phonetic mode. (see below)\n"); - printf(" -pitch number set pitch value (default=64)\n"); - printf(" -speed number set speed value (default=72)\n"); - printf(" -throat number set throat value (default=128)\n"); - printf(" -mouth number set mouth value (default=128)\n"); - printf(" -wav filename output to wav instead of libsdl\n"); - printf(" -sing special treatment of pitch\n"); - printf(" -debug print additional debug messages\n"); - printf("\n"); - - - printf(" VOWELS VOICED CONSONANTS \n"); - printf("IY f(ee)t R red \n"); - printf("IH p(i)n L allow \n"); - printf("EH beg W away \n"); - printf("AE Sam W whale \n"); - printf("AA pot Y you \n"); - printf("AH b(u)dget M Sam \n"); - printf("AO t(al)k N man \n"); - printf("OH cone NX so(ng) \n"); - printf("UH book B bad \n"); - printf("UX l(oo)t D dog \n"); - printf("ER bird G again \n"); - printf("AX gall(o)n J judge \n"); - printf("IX dig(i)t Z zoo \n"); - printf(" ZH plea(s)ure \n"); - printf(" DIPHTHONGS V seven \n"); - printf("EY m(a)de DH (th)en \n"); - printf("AY h(igh) \n"); - printf("OY boy \n"); - printf("AW h(ow) UNVOICED CONSONANTS \n"); - printf("OW slow S Sam \n"); - printf("UW crew Sh fish \n"); - printf(" F fish \n"); - printf(" TH thin \n"); - printf(" SPECIAL PHONEMES P poke \n"); - printf("UL sett(le) (=AXL) T talk \n"); - printf("UM astron(omy) (=AXM) K cake \n"); - printf("UN functi(on) (=AXN) CH speech \n"); - printf("Q kitt-en (glottal stop) /H a(h)ead \n"); -} - -#ifdef USESDL - -int pos = 0; -void MixAudio(void *unused, Uint8 *stream, int len) -{ - int bufferpos = GetBufferLength(); - char *buffer = GetBuffer(); - int i; - if (pos >= bufferpos) return; - if ((bufferpos-pos) < len) len = (bufferpos-pos); - for(i=0; i +#include +#include +#include + +#include "reciter.h" +#include "sam.h" +#include "debug.h" + +#ifdef USESDL +#include +#include +#endif + +void WriteWav(char* filename, char* buffer, int bufferlength) +{ + FILE *file = fopen(filename, "wb"); + if (file == NULL) return; + //RIFF header + fwrite("RIFF", 4, 1,file); + unsigned int filesize=bufferlength + 12 + 16 + 8 - 8; + fwrite(&filesize, 4, 1, file); + fwrite("WAVE", 4, 1, file); + + //format chunk + fwrite("fmt ", 4, 1, file); + unsigned int fmtlength = 16; + fwrite(&fmtlength, 4, 1, file); + unsigned short int format=1; //PCM + fwrite(&format, 2, 1, file); + unsigned short int channels=1; + fwrite(&channels, 2, 1, file); + unsigned int samplerate = 22050; + fwrite(&samplerate, 4, 1, file); + fwrite(&samplerate, 4, 1, file); // bytes/second + unsigned short int blockalign = 1; + fwrite(&blockalign, 2, 1, file); + unsigned short int bitspersample=8; + fwrite(&bitspersample, 2, 1, file); + + //data chunk + fwrite("data", 4, 1, file); + fwrite(&bufferlength, 4, 1, file); + fwrite(buffer, bufferlength, 1, file); + + fclose(file); +} + +void PrintUsage() +{ + printf("usage: sam [options] Word1 Word2 ....\n"); + printf("options\n"); + printf(" -phonetic enters phonetic mode. (see below)\n"); + printf(" -pitch number set pitch value (default=64)\n"); + printf(" -speed number set speed value (default=72)\n"); + printf(" -throat number set throat value (default=128)\n"); + printf(" -mouth number set mouth value (default=128)\n"); + printf(" -wav filename output to wav instead of libsdl\n"); + printf(" -sing special treatment of pitch\n"); + printf(" -debug print additional debug messages\n"); + printf("\n"); + + + printf(" VOWELS VOICED CONSONANTS \n"); + printf("IY f(ee)t R red \n"); + printf("IH p(i)n L allow \n"); + printf("EH beg W away \n"); + printf("AE Sam W whale \n"); + printf("AA pot Y you \n"); + printf("AH b(u)dget M Sam \n"); + printf("AO t(al)k N man \n"); + printf("OH cone NX so(ng) \n"); + printf("UH book B bad \n"); + printf("UX l(oo)t D dog \n"); + printf("ER bird G again \n"); + printf("AX gall(o)n J judge \n"); + printf("IX dig(i)t Z zoo \n"); + printf(" ZH plea(s)ure \n"); + printf(" DIPHTHONGS V seven \n"); + printf("EY m(a)de DH (th)en \n"); + printf("AY h(igh) \n"); + printf("OY boy \n"); + printf("AW h(ow) UNVOICED CONSONANTS \n"); + printf("OW slow S Sam \n"); + printf("UW crew Sh fish \n"); + printf(" F fish \n"); + printf(" TH thin \n"); + printf(" SPECIAL PHONEMES P poke \n"); + printf("UL sett(le) (=AXL) T talk \n"); + printf("UM astron(omy) (=AXM) K cake \n"); + printf("UN functi(on) (=AXN) CH speech \n"); + printf("Q kitt-en (glottal stop) /H a(h)ead \n"); +} + +#ifdef USESDL + +int pos = 0; +void MixAudio(void *unused, Uint8 *stream, int len) +{ + int bufferpos = GetBufferLength(); + char *buffer = GetBuffer(); + int i; + if (pos >= bufferpos) return; + if ((bufferpos-pos) < len) len = (bufferpos-pos); + for(i=0; i Date: Sun, 23 Sep 2018 09:27:04 +0100 Subject: [PATCH 107/109] Revert "CR/LF" This reverts commit 55bc9805f51d4bf50e463d8cb437229d7f2e4e20. --- src/main.c | 538 ++++++++++++++++++++++++++--------------------------- 1 file changed, 269 insertions(+), 269 deletions(-) diff --git a/src/main.c b/src/main.c index 682d254d..8ab17f3e 100644 --- a/src/main.c +++ b/src/main.c @@ -1,269 +1,269 @@ -#include -#include -#include -#include - -#include "reciter.h" -#include "sam.h" -#include "debug.h" - -#ifdef USESDL -#include -#include -#endif - -void WriteWav(char* filename, char* buffer, int bufferlength) -{ - FILE *file = fopen(filename, "wb"); - if (file == NULL) return; - //RIFF header - fwrite("RIFF", 4, 1,file); - unsigned int filesize=bufferlength + 12 + 16 + 8 - 8; - fwrite(&filesize, 4, 1, file); - fwrite("WAVE", 4, 1, file); - - //format chunk - fwrite("fmt ", 4, 1, file); - unsigned int fmtlength = 16; - fwrite(&fmtlength, 4, 1, file); - unsigned short int format=1; //PCM - fwrite(&format, 2, 1, file); - unsigned short int channels=1; - fwrite(&channels, 2, 1, file); - unsigned int samplerate = 22050; - fwrite(&samplerate, 4, 1, file); - fwrite(&samplerate, 4, 1, file); // bytes/second - unsigned short int blockalign = 1; - fwrite(&blockalign, 2, 1, file); - unsigned short int bitspersample=8; - fwrite(&bitspersample, 2, 1, file); - - //data chunk - fwrite("data", 4, 1, file); - fwrite(&bufferlength, 4, 1, file); - fwrite(buffer, bufferlength, 1, file); - - fclose(file); -} - -void PrintUsage() -{ - printf("usage: sam [options] Word1 Word2 ....\n"); - printf("options\n"); - printf(" -phonetic enters phonetic mode. (see below)\n"); - printf(" -pitch number set pitch value (default=64)\n"); - printf(" -speed number set speed value (default=72)\n"); - printf(" -throat number set throat value (default=128)\n"); - printf(" -mouth number set mouth value (default=128)\n"); - printf(" -wav filename output to wav instead of libsdl\n"); - printf(" -sing special treatment of pitch\n"); - printf(" -debug print additional debug messages\n"); - printf("\n"); - - - printf(" VOWELS VOICED CONSONANTS \n"); - printf("IY f(ee)t R red \n"); - printf("IH p(i)n L allow \n"); - printf("EH beg W away \n"); - printf("AE Sam W whale \n"); - printf("AA pot Y you \n"); - printf("AH b(u)dget M Sam \n"); - printf("AO t(al)k N man \n"); - printf("OH cone NX so(ng) \n"); - printf("UH book B bad \n"); - printf("UX l(oo)t D dog \n"); - printf("ER bird G again \n"); - printf("AX gall(o)n J judge \n"); - printf("IX dig(i)t Z zoo \n"); - printf(" ZH plea(s)ure \n"); - printf(" DIPHTHONGS V seven \n"); - printf("EY m(a)de DH (th)en \n"); - printf("AY h(igh) \n"); - printf("OY boy \n"); - printf("AW h(ow) UNVOICED CONSONANTS \n"); - printf("OW slow S Sam \n"); - printf("UW crew Sh fish \n"); - printf(" F fish \n"); - printf(" TH thin \n"); - printf(" SPECIAL PHONEMES P poke \n"); - printf("UL sett(le) (=AXL) T talk \n"); - printf("UM astron(omy) (=AXM) K cake \n"); - printf("UN functi(on) (=AXN) CH speech \n"); - printf("Q kitt-en (glottal stop) /H a(h)ead \n"); -} - -#ifdef USESDL - -int pos = 0; -void MixAudio(void *unused, Uint8 *stream, int len) -{ - int bufferpos = GetBufferLength(); - char *buffer = GetBuffer(); - int i; - if (pos >= bufferpos) return; - if ((bufferpos-pos) < len) len = (bufferpos-pos); - for(i=0; i +#include +#include +#include + +#include "reciter.h" +#include "sam.h" +#include "debug.h" + +#ifdef USESDL +#include +#include +#endif + +void WriteWav(char* filename, char* buffer, int bufferlength) +{ + FILE *file = fopen(filename, "wb"); + if (file == NULL) return; + //RIFF header + fwrite("RIFF", 4, 1,file); + unsigned int filesize=bufferlength + 12 + 16 + 8 - 8; + fwrite(&filesize, 4, 1, file); + fwrite("WAVE", 4, 1, file); + + //format chunk + fwrite("fmt ", 4, 1, file); + unsigned int fmtlength = 16; + fwrite(&fmtlength, 4, 1, file); + unsigned short int format=1; //PCM + fwrite(&format, 2, 1, file); + unsigned short int channels=1; + fwrite(&channels, 2, 1, file); + unsigned int samplerate = 22050; + fwrite(&samplerate, 4, 1, file); + fwrite(&samplerate, 4, 1, file); // bytes/second + unsigned short int blockalign = 1; + fwrite(&blockalign, 2, 1, file); + unsigned short int bitspersample=8; + fwrite(&bitspersample, 2, 1, file); + + //data chunk + fwrite("data", 4, 1, file); + fwrite(&bufferlength, 4, 1, file); + fwrite(buffer, bufferlength, 1, file); + + fclose(file); +} + +void PrintUsage() +{ + printf("usage: sam [options] Word1 Word2 ....\n"); + printf("options\n"); + printf(" -phonetic enters phonetic mode. (see below)\n"); + printf(" -pitch number set pitch value (default=64)\n"); + printf(" -speed number set speed value (default=72)\n"); + printf(" -throat number set throat value (default=128)\n"); + printf(" -mouth number set mouth value (default=128)\n"); + printf(" -wav filename output to wav instead of libsdl\n"); + printf(" -sing special treatment of pitch\n"); + printf(" -debug print additional debug messages\n"); + printf("\n"); + + + printf(" VOWELS VOICED CONSONANTS \n"); + printf("IY f(ee)t R red \n"); + printf("IH p(i)n L allow \n"); + printf("EH beg W away \n"); + printf("AE Sam W whale \n"); + printf("AA pot Y you \n"); + printf("AH b(u)dget M Sam \n"); + printf("AO t(al)k N man \n"); + printf("OH cone NX so(ng) \n"); + printf("UH book B bad \n"); + printf("UX l(oo)t D dog \n"); + printf("ER bird G again \n"); + printf("AX gall(o)n J judge \n"); + printf("IX dig(i)t Z zoo \n"); + printf(" ZH plea(s)ure \n"); + printf(" DIPHTHONGS V seven \n"); + printf("EY m(a)de DH (th)en \n"); + printf("AY h(igh) \n"); + printf("OY boy \n"); + printf("AW h(ow) UNVOICED CONSONANTS \n"); + printf("OW slow S Sam \n"); + printf("UW crew Sh fish \n"); + printf(" F fish \n"); + printf(" TH thin \n"); + printf(" SPECIAL PHONEMES P poke \n"); + printf("UL sett(le) (=AXL) T talk \n"); + printf("UM astron(omy) (=AXM) K cake \n"); + printf("UN functi(on) (=AXN) CH speech \n"); + printf("Q kitt-en (glottal stop) /H a(h)ead \n"); +} + +#ifdef USESDL + +int pos = 0; +void MixAudio(void *unused, Uint8 *stream, int len) +{ + int bufferpos = GetBufferLength(); + char *buffer = GetBuffer(); + int i; + if (pos >= bufferpos) return; + if ((bufferpos-pos) < len) len = (bufferpos-pos); + for(i=0; i Date: Sun, 23 Sep 2018 09:27:17 +0100 Subject: [PATCH 108/109] Revert "Strip whitespace" This reverts commit 9190106e427f10f90bd47c38968605160135fcef. --- src/sam.c | 300 +++++++++++++++++++++++++++--------------------------- 1 file changed, 150 insertions(+), 150 deletions(-) diff --git a/src/sam.c b/src/sam.c index 4e58a8f4..beaf01df 100644 --- a/src/sam.c +++ b/src/sam.c @@ -1,10 +1,10 @@ -#include -#include -#include -#include "debug.h" -#include "sam.h" -#include "render.h" -#include "SamTabs.h" +#include +#include +#include +#include "debug.h" +#include "sam.h" +#include "render.h" +#include "SamTabs.h" enum { pR = 23, @@ -15,74 +15,74 @@ enum { }; - -char input[256]; //tab39445 -//standard sam sound -unsigned char speed = 72; -unsigned char pitch = 64; -unsigned char mouth = 128; -unsigned char throat = 128; -int singmode = 0; - -extern int debug; - -unsigned char mem39; -unsigned char mem44; -unsigned char mem47; -unsigned char mem49; -unsigned char mem50; -unsigned char mem51; -unsigned char mem53; -unsigned char mem59=0; - + +char input[256]; //tab39445 +//standard sam sound +unsigned char speed = 72; +unsigned char pitch = 64; +unsigned char mouth = 128; +unsigned char throat = 128; +int singmode = 0; + +extern int debug; + +unsigned char mem39; +unsigned char mem44; +unsigned char mem47; +unsigned char mem49; +unsigned char mem50; +unsigned char mem51; +unsigned char mem53; +unsigned char mem59=0; + unsigned char X; - -unsigned char stress[256]; //numbers from 0 to 8 -unsigned char phonemeLength[256]; //tab40160 -unsigned char phonemeindex[256]; - -unsigned char phonemeIndexOutput[60]; //tab47296 -unsigned char stressOutput[60]; //tab47365 -unsigned char phonemeLengthOutput[60]; //tab47416 - - - - -// contains the final soundbuffer -int bufferpos=0; -char *buffer = NULL; - - -void SetInput(char *_input) -{ - int i, l; - l = strlen(_input); - if (l > 254) l = 254; - for(i=0; i 254) l = 254; + for(i=0; i -// -// The byte 0x9B marks the end of the buffer. Some phonemes are 2 bytes -// long, such as "DH" and "AX". Others are 1 byte long, such as "T" and "Z". -// There are also stress markers, such as "5" and ".". -// -// The first character of the phonemes are stored in the table signInputTable1[]. -// The second character of the phonemes are stored in the table signInputTable2[]. -// The stress characters are arranged in low to high stress order in stressInputTable[]. -// -// The following process is used to parse the input[] buffer: -// -// Repeat until the <0x9B> character is reached: -// -// First, a search is made for a 2 character match for phonemes that do not -// end with the '*' (wildcard) character. On a match, the index of the phoneme -// is added to phonemeIndex[] and the buffer position is advanced 2 bytes. -// -// If this fails, a search is made for a 1 character match against all -// phoneme names ending with a '*' (wildcard). If this succeeds, the -// phoneme is added to phonemeIndex[] and the buffer position is advanced -// 1 byte. -// -// If this fails, search for a 1 character match in the stressInputTable[]. -// If this succeeds, the stress value is placed in the last stress[] table -// at the same index of the last added phoneme, and the buffer position is -// advanced by 1 byte. -// -// If this fails, return a 0. -// -// On success: -// -// 1. phonemeIndex[] will contain the index of all the phonemes. -// 2. The last index in phonemeIndex[] will be 255. -// 3. stress[] will contain the stress value for each phoneme +// The input[] buffer contains a string of phonemes and stress markers along +// the lines of: +// +// DHAX KAET IHZ AH5GLIY. <0x9B> +// +// The byte 0x9B marks the end of the buffer. Some phonemes are 2 bytes +// long, such as "DH" and "AX". Others are 1 byte long, such as "T" and "Z". +// There are also stress markers, such as "5" and ".". +// +// The first character of the phonemes are stored in the table signInputTable1[]. +// The second character of the phonemes are stored in the table signInputTable2[]. +// The stress characters are arranged in low to high stress order in stressInputTable[]. +// +// The following process is used to parse the input[] buffer: +// +// Repeat until the <0x9B> character is reached: +// +// First, a search is made for a 2 character match for phonemes that do not +// end with the '*' (wildcard) character. On a match, the index of the phoneme +// is added to phonemeIndex[] and the buffer position is advanced 2 bytes. +// +// If this fails, a search is made for a 1 character match against all +// phoneme names ending with a '*' (wildcard). If this succeeds, the +// phoneme is added to phonemeIndex[] and the buffer position is advanced +// 1 byte. +// +// If this fails, search for a 1 character match in the stressInputTable[]. +// If this succeeds, the stress value is placed in the last stress[] table +// at the same index of the last added phoneme, and the buffer position is +// advanced by 1 byte. +// +// If this fails, return a 0. +// +// On success: +// +// 1. phonemeIndex[] will contain the index of all the phonemes. +// 2. The last index in phonemeIndex[] will be 255. +// 3. stress[] will contain the stress value for each phoneme // input[] holds the string of phonemes, each two bytes wide // signInputTable1[] holds the first character of each phoneme @@ -426,29 +426,29 @@ void drule_post(unsigned char X) { } -// Rewrites the phonemes using the following rules: -// -// -> WX -// -> YX -// UL -> AX L -// UM -> AX M -// -> Q -// T R -> CH R -// D R -> J R -// R -> RX -// L -> LX -// G S -> G Z -// K -> KX -// G -> GX -// S P -> S B -// S T -> S D -// S K -> S G -// S KX -> S GX -// UW -> UX -// CH -> CH CH' (CH requires two phonemes to represent it) -// J -> J J' (J requires two phonemes to represent it) -// T -> DX -// D -> DX +// Rewrites the phonemes using the following rules: +// +// -> WX +// -> YX +// UL -> AX L +// UM -> AX M +// -> Q +// T R -> CH R +// D R -> J R +// R -> RX +// L -> LX +// G S -> G Z +// K -> KX +// G -> GX +// S P -> S B +// S T -> S D +// S K -> S G +// S KX -> S GX +// UW -> UX +// CH -> CH CH' (CH requires two phonemes to represent it) +// J -> J J' (J requires two phonemes to represent it) +// T -> DX +// D -> DX void rule_alveolar_uw(unsigned char X) { @@ -639,7 +639,7 @@ void AdjustLengths() { // test for vowel index = phonemeindex[X]; - // test for fricative/unvoiced or not voiced + // test for fricative/unvoiced or not voiced if(!(flags[index] & FLAG_FRICATIVE) || (flags[index] & FLAG_VOICED)) { //nochmal überprüfen unsigned char A = phonemeLength[X]; // change phoneme length to (length * 1.5) + 1 @@ -709,7 +709,7 @@ void AdjustLengths() { if (index != END && (flags[index] & FLAG_STOPCONS)) { // FIXME, this looks wrong? - // RULE: {optional silence} + // RULE: {optional silence} drule(" {optional silence} - shorten both to 1/2 + 1"); phonemeLength[X] = (phonemeLength[X] >> 1) + 1; phonemeLength[loopIndex] = (phonemeLength[loopIndex] >> 1) + 1; From c86ea395743b8ea4ad071c2167fd1f7f96648f7b Mon Sep 17 00:00:00 2001 From: Vidar Hokstad Date: Sun, 23 Sep 2018 09:45:14 +0100 Subject: [PATCH 109/109] Fix breakage on Linux --- src/main.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/main.c b/src/main.c index 9ea9b9ea..3e8fdde3 100644 --- a/src/main.c +++ b/src/main.c @@ -12,6 +12,20 @@ #include #endif + +// Approximations of some Windows functions to ease portability +#if defined __GNU_LIBRARY__ || defined __GLIBC__ +static int min(int l, int r) { return l < r ? l : r; } +static void strcat_s(char * dest, int size, char * str) { + unsigned int dlen = strlen(dest); + if (dlen >= size-1) return; + strncat(dest+dlen, str, size - dlen - 1); +} +void fopen_s(FILE ** f, const char * filename, const char * mode) { + *f = fopen(filename,mode); +} +#endif + void WriteWav(char* filename, char* buffer, int bufferlength) { unsigned int filesize;