I did some editing and at least got the IDE to stop complaining with design-time errors.
There are a zillion things to fix and figure out before it's working though, but it's a step closer.
I leave this is the capable hands of anyone looking for a challenge! LOL
The original C project this is attempting to recreate: which is a fork of
Earlier posts:
The latest code is below. Attached ZIP file contains some assets (text files) some of the test routines use (haven't figured that part out yet).
There are a zillion things to fix and figure out before it's working though, but it's a step closer.
I leave this is the capable hands of anyone looking for a challenge! LOL
The original C project this is attempting to recreate: which is a fork of
Earlier posts:
- attempt 1 (v0.01), ai recreated SAM based on C (not module-by-module recreation)
- attempt 1 (v0.15, now runs, sound doesn't work)
- Cry for help with generating sounds
- attempt 2 (v0.20), ai converted full code to QB64PE
The latest code is below. Attached ZIP file contains some assets (text files) some of the test routines use (haven't figured that part out yet).
Code: (Select All)
' ################################################################################################################################################################
' SAM "SOFTWARE AUTOMATIC MOUTH"
' A native speech synthesizer for QB64PE
' version 0.2.1
' Translated by from C to QB64, from the bit-hack project at:
'
' https://github.com/bit-hack/SAM
'
' which is a fork of Sebastian Macke's project at:
'
' https://github.com/s-macke/SAM
' TO DO:
' * Initial translation was done by free ai, so lots of errors and bugs to fix!
' * Replace sound generation code with QB64PE sound commands
' * Get it working (TBD?)
' ################################################################################################################################################################
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' FROM sam.c
' Global variables (equivalent to C globals)
'Declare arrays - Need to determine actual sizes from original C code or context
Const cMaxPhonemes = 256 ' Example size, adjust as needed
Dim Shared m_ProgramPath$: m_ProgramPath$ = Left$(Command$(0), _InStrRev(Command$(0), "\"))
Dim Shared m_ProgramName$: m_ProgramName$ = Mid$(Command$(0), _InStrRev(Command$(0), "\") + 1)
Dim Shared A As _Unsigned _Byte ' or is it _BYTE ?
Dim Shared X As _Byte
Dim Shared Y As _Byte
' TODO: NEED TO RECONCILE inputtemp() vs TempInput$
' BECAUSE NOT SURE IF Gemini CONVERTED CORRECTLY
' IN SOME PLACES WE HAVE inputtemp LOOKING LIKE A STRING:
' A = ASC(MID$(inputtemp, X + 1, 1)) ' Corrected index
' inputtemp = SPACE$(256) ' Assuming inputtemp is a string, adjust size as needed
' inputtemp = " " + inputtemp[0] = 0x20; // '
' SO WE REPLACED inputtemp WITH TempInput$
' IT IS REFERENCED IN
' FUNCTION TextToPhonemes& (sInput AS STRING, max_size AS LONG)
' WHICH CALLS ROUTINE
' Function TestFlagDec~% (mem59 As Integer, mask As Long)
' WHICH REFERENCES IT
' A = ASC(MID$(TempInput$, X + 1, 1)) 'QB64: Access char in string, ASC gets ASCII value
' BUT IT'S NOT A PARAMETER OR DECLARED, SO DO WE ASSUME GLOBAL?
' BUT THEN IN OTHER PLACES WE HAVE
' A = inputtemp(X)
' WHICH LOOKS LIKE inputtemp IS A NUMERIC ARRAY ?
' SO TOTALLY CONFUSED ABOUT
' - WHAT TYPE IT IS
' - WHETHER IT'S ONE VARIABLE OR 2 OR MORE DIFFERENT VARIABLES
' - WHETHER IT'S GLOBAL OR LOCAL IN SCOPE
Dim Shared TempInput$
Dim Shared bDebug As Integer ' FROM debug.h, int32_t becomes INTEGER in QB64
ReDim arrAmp1Data(78) As _Byte
ReDim arrAmp2Data(78) As _Byte
ReDim arrAmp3Data(78) As _Byte
ReDim arrAmplitudeRescale As _Byte ' Equivalent to uint8_t[]
ReDim arrBlendRank As _Byte ' Equivalent to uint8_t[]
ReDim arrFlags1(0 To 66) As _Unsigned _Byte
ReDim arrFlags2(0 To 61) As _Unsigned _Byte
ReDim arrFreq1Data(71) As _Unsigned _Byte ' ReDim arrFreq1Data(53) As _Byte
ReDim arrFreq2Data(79) As _Unsigned _Byte ' ReDim arrFreq2Data(53) As _Byte
ReDim arrFreq3Data(62) As _Unsigned _Byte
ReDim arrInBlendLength(95) As _Unsigned _Byte
ReDim arrInput1(256) As _Byte ' [256] 'int8_t becomes _BYTE in QB64
ReDim arrMouthFormants48_53(5) As _Byte
ReDim arrMouthFormants5_29(29) As _Byte
ReDim arrMultTable(255) As _Byte ' QB64 uses byte for unsigned 8-bit
ReDim arrOutBlendLength(95) As _Unsigned _Byte
ReDim arrPhoIndexOutput(59) As _Byte ' [60] 'uint8_t to _BYTE
ReDim arrPhoLengthOutput(59) As _Byte ' [60] 'uint8_t to _BYTE
ReDim arrPhoLengthTable(0 To 61) As _Unsigned _Byte
ReDim arrPhonemeIndex(cMaxPhonemes) As _Unsigned _Byte ' DIM arrPhonemeIndex[256] AS _BYTE ' uint8_t to _BYTE
ReDim arrPhonemeLength(cMaxPhonemes) As _Byte ' [256] 'uint8_t to _BYTE
ReDim arrPhoStressedLengthTable(0 To 61) As _Unsigned _Byte
ReDim arrPitches(255) As _Byte ' Assuming a maximum size of 255 for pitches
ReDim arrRectangle(143) As _Unsigned _Byte
ReDim arrRules(0 To 150) As String
ReDim arrRuleTab(0 To 27) As Integer
ReDim arrSampledConsonantFlags(79) As _Unsigned _Byte
ReDim arrSampleTable(0 To 1279) As _Byte '0x500 = 1280
ReDim arrSignInputTable1(89) As String ' _Unsigned _Byte
ReDim arrSignInputTable2(55) As String ' _Unsigned _Byte
ReDim arrSinus(180) As _Unsigned _Byte
ReDim arrStress1(cMaxPhonemes) As _Unsigned _Byte ' DIM arrStress1 AS _BYTE ' [256] 'uint8_t to _BYTE
ReDim arrStressInputTable(9) As String ' DIM stressInputTable AS STRING * 9 ' Fixed-length string to hold the characters
ReDim arrStressOutput(59) As _Byte ' [60] 'uint8_t to _BYTE
ReDim arrTab36376(0 To 288) As _Unsigned _Byte
ReDim arrTab47492 As _Byte ' Equivalent to uint8_t[]
ReDim arrTab48426(4) As _Byte ' Equivalent to uint8_t[5]
ReDim arrThroatFormants48_53(5) As _Byte
ReDim arrThroatFormants5_29(29) As _Byte
Dim buffer As _Offset ' Final sound buffer, int8_t* to _OFFSET (pointer)
Dim bufferPos As Integer ' Final sound buffer, int32_t to Integer
Dim iIndex As Long
Dim iSize As Integer
Dim mem39 As _Byte
Dim mem44 As _Byte
Dim mem47 As _Byte
Dim mem48 As _Byte
Dim mem49 As _Byte 'uint8_t to _BYTE
Dim mem50 As _Byte
Dim mem51 As _Byte
Dim mem53 As _Byte
Dim mem56 As _Byte 'uint8_t to _BYTE
Dim mem59 As _Byte 'uint8_t to _BYTE
Dim mouth As _Byte 'uint8_t becomes _BYTE
Dim phase1 As _Byte
Dim pitch As _Byte 'uint8_t becomes _BYTE
Dim singmode As Integer 'int32_t becomes Integer
Dim speed As _Byte 'uint8_t becomes _BYTE
Dim tab40682$
Dim tab40763$
Dim throat As _Byte 'uint8_t becomes _BYTE
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' BEGIN reciter_tabs.h
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' Some flags
'
' 0x01 numeric
' 0x02 rule set 2
' 0x04 D J L N
' 0x08 B D G J L M N R V W Z
' 0x10 C G J S X Z R S T Z
' 0x20 B C D F G H J K L M N P Q R S T V X Y Z
' 0x40 is vowel + Y
' 0x80 alpha or '
' Not sure this was converted right,
' the values assigned to array arrTab36376()
' in the original C code are below,
' not sure what notation that is
' or what the equivalent in QB64 should be?
' Value | ASCII character
' ------------------------------------ | ---------------
' 0 | (none?)
' 0 | (none?)
' 0 | (none?)
' 0 | (none?)
' 0 | (none?)
' 0 | (none?)
' 0 | (none?)
' 0 | (none?)
' 0 | (none?)
' 0 | (none?)
' 0 | (none?)
' 0 | (none?)
' 0 | (none?)
' 0 | (none?)
' 0 | (none?)
' 0 | (none?)
' 0 | (none?)
' 0 | (none?)
' 0 | (none?)
' 0 | (none?)
' 0 | (none?)
' 0 | (none?)
' 0 | (none?)
' 0 | (none?)
' 0 | (none?)
' 0 | (none?)
' 0 | (none?)
' 0 | (none?)
' 0 | (none?)
' 0 | (none?)
' 0 | (none?)
' 0 | (none?)
' 0 | (space char)
' 0 | 0x02 | !
' 0 | 0x02 | "
' 0 | 0x02 | #
' 0 | 0x02 | $
' 0 | 0x02 | %
' 0 | 0x02 | &
' 0 | 0x80 | 0x02 | '
' 0 | (
' 0 | )
' 0 | 0x02 | *
' 0 | 0x02 | +
' 0 | 0x02 | ,
' 0 | 0x02 | -
' 0 | 0x02 | .
' 0 | 0x02 | /
' 0 | 0x02 | 0x01 | 0
' 0 | 0x02 | 0x01 | 1
' 0 | 0x02 | 0x01 | 2
' 0 | 0x02 | 0x01 | 3
' 0 | 0x02 | 0x01 | 4
' 0 | 0x02 | 0x01 | 5
' 0 | 0x02 | 0x01 | 6
' 0 | 0x02 | 0x01 | 7
' 0 | 0x02 | 0x01 | 8
' 0 | 0x02 | 0x01 | 9
' 0 | 0x02 | :
' 0 | 0x02 | ;
' 0 | 0x02 | <
' 0 | 0x02 | =
' 0 | 0x02 | >
' 0 | 0x02 | ?
' 0 | 0x02 | @
' 0 | 0x80 | 0x40 | A
' 0 | 0x80 | 0x20 | 0x08 | B
' 0 | 0x80 | 0x20 | 0x10 | C
' 0 | 0x80 | 0x20 | 0x08 | 0x04 | D
' 0 | 0x80 | 0x40 | E
' 0 | 0x80 | 0x20 | F
' 0 | 0x80 | 0x20 | 0x10 | 0x08 | G
' 0 | 0x80 | 0x20 | H
' 0 | 0x80 | 0x40 | I
' 0 | 0x80 | 0x20 | 0x10 | 0x08 | 0x04 | J
' 0 | 0x80 | 0x20 | K
' 0 | 0x80 | 0x20 | 0x08 | 0x04 | L
' 0 | 0x80 | 0x20 | 0x08 | M
' 0 | 0x80 | 0x20 | 0x08 | 0x04 | N
' 0 | 0x80 | 0x40 | O
' 0 | 0x80 | 0x20 | P
' 0 | 0x80 | 0x20 | Q
' 0 | 0x80 | 0x20 | 0x08 | 0x04 | R
' 0 | 0x80 | 0x20 | 0x10 | 0x04 | S
' 0 | 0x80 | 0x20 | 0x04 | T
' 0 | 0x80 | 0x40 | U
' 0 | 0x80 | 0x20 | 0x08 | V
' 0 | 0x80 | 0x20 | 0x08 | W
' 0 | 0x80 | 0x20 | 0x10 | X
' 0 | 0x80 | 0x40 | Y
' 0 | 0x80 | 0x20 | 0x10 | 0x08 | 0x04 | Z
' 0 | [
' 0 | \
' 0 | ]
' 0 | 0x02 | ^
' 0 | _
' 0 | 0x20 | 0x02 | `
Data 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
Data 0,0,0,0,0,0,0,0,2,0,2,0,2,0,2,0,2,130,0,0,2,0,2,0
Data 2,0,2,2,1,2,1,2,1,2,1,2,1,2,2,0,2,0,2,0,2,0,2,0
Data 130,64,130,32,8,130,32,16,130,32,8,4,130,64,130,32,130
Data 32,16,8,130,64,130,32,8,4,130,64,130,32,16,8,4,130,32,4
Data 130,32,8,130,32,8,4,130,64,130,32,130,32,4,130,32,8,4
Data 130,32,16,4,130,64,130,32,130,32,8,130,32,8,130,32,4,130
Data 64,130,32,8,4,130,32,16,4,130,64,130,32,16,8,4,130,64,130
Data 32,8,4,130,32,4,130,64,130,32,8,130,32,8,130,32,16,130,64
Data 130,32,16,8,4,130,64,130,32,16,8,4,130,32,4,130,64,130,32
Data 8,130,32,8,130,32,16,130,64,130,32,16,8,4,130,0,0,0,2,0
Data 32,2
For iIndex = 0 To 288
'redim _preserve arrTab36376( ubound(tab36376)+1 )
Read arrTab36376(iIndex)
Next iIndex
ReDim arrRules(0 To 150) As String
arrRules(0) = "]\xc1" ' "]A"
arrRules(1) = " (A.)=EH4Y.\xa0" ' " (A.)=EH4Y. "
arrRules(2) = "(A) =A\xc8" ' "(A) =AH"
arrRules(3) = " (ARE) =AA\xd2" ' " (ARE) =AAR"
arrRules(4) = " (AR)O=AX\xd2" ' " (AR)O=AXR"
arrRules(5) = "(AR)#=EH4\xd2" ' "(AR)#=EH4R"
arrRules(6) = " ^(AS)#=EY4\xd3" ' " ^(AS)#=EY4S"
arrRules(7) = "(A)WA=A\xd8" ' "(A)WA=AX"
arrRules(8) = "(AW)=AO\xb5" ' "(AW)=AO5"
arrRules(9) = " :(ANY)=EH4NI\xd9" ' " :(ANY)=EH4NIY"
arrRules(10) = "(A)^+#=EY\xb5" ' "(A)^+#=EY5"
arrRules(11) = "#:(ALLY)=ULI\xd9" ' "#:(ALLY)=ULIY"
arrRules(12) = " (AL)#=U\xcc" ' " (AL)#=UL"
arrRules(13) = "(AGAIN)=AXGEH4\xce" ' "(AGAIN)=AXGEH4N"
arrRules(14) = "#:(AG)E=IH\xca" ' "#:(AG)E=IHJ"
arrRules(15) = "(A)^%=E\xd9" ' "(A)^%=EY"
arrRules(16) = "(A)^+:#=A\xc5" ' "(A)^+:#=AE"
arrRules(17) = " :(A)^+ =EY\xb4" ' " :(A)^+ =EY4"
arrRules(18) = " (ARR)=AX\xd2" ' " (ARR)=AXR"
arrRules(19) = "(ARR)=AE4\xd2" ' "(ARR)=AE4R"
arrRules(20) = " ^(AR) =AA5\xd2" ' " ^(AR) =AA5R"
arrRules(21) = "(AR)=AA5\xd2" ' "(AR)=AA5R"
arrRules(22) = "(AIR)=EH4\xd2" ' "(AIR)=EH4R"
arrRules(23) = "(AI)=EY\xb4" ' "(AI)=EY4"
arrRules(24) = "(AY)=EY\xb5" ' "(AY)=EY5"
arrRules(25) = "(AU)=AO\xb4" ' "(AU)=AO4"
arrRules(26) = "#:(AL) =U\xcc" ' "#:(AL) =UL"
arrRules(27) = "#:(ALS) =UL\xda" ' "#:(ALS) =ULZ"
arrRules(28) = "(ALK)=AO4\xcb" ' "(ALK)=AO4K"
arrRules(29) = "(AL)^=AO\xcc" ' "(AL)^=AOL"
arrRules(30) = " :(ABLE)=EY4BU\xcc" ' " :(ABLE)=EY4BUL"
arrRules(31) = "(ABLE)=AXBU\xcc" ' "(ABLE)=AXBUL"
arrRules(32) = "(A)VO=EY\xb4" ' "(A)VO=EY4"
arrRules(33) = "(ANG)+=EY4N\xca" ' "(ANG)+=EY4NJ"
arrRules(34) = "(ATARI)=AHTAA4RI\xd9" ' "(ATARI)=AHTAA4RIY"
arrRules(35) = "(A)TOM=A\xc5" ' "(A)TOM=AE"
arrRules(36) = "(A)TTI=A\xc5" ' "(A)TTI=AE"
arrRules(37) = " (AT) =AE\xd4" ' " (AT) =AET"
arrRules(38) = " (A)T=A\xc8" ' " (A)T=AH"
arrRules(39) = "(A)=A\xc5" ' "(A)=AE"
arrRules(40) = "]\xc2" ' "]B"
arrRules(41) = " (B) =BIY\xb4" ' " (B) =BIY4"
arrRules(42) = " (BE)^#=BI\xc8" ' " (BE)^#=BIH"
arrRules(43) = "(BEING)=BIY4IHN\xd8" ' "(BEING)=BIY4IHNX"
arrRules(44) = " (BOTH) =BOW4T\xc8" ' " (BOTH) =BOW4TH"
arrRules(45) = " (BUS)#=BIH4\xda" ' " (BUS)#=BIH4Z"
arrRules(46) = "(BREAK)=BREY5\xcb" ' "(BREAK)=BREY5K"
arrRules(47) = "(BUIL)=BIH4\xcc" ' "(BUIL)=BIH4L"
arrRules(48) = "(B)=\xc2" ' "(B)=B"
arrRules(49) = "]\xc3" ' "]C"
arrRules(50) = " (C) =SIY\xb4" ' " (C) =SIY4"
arrRules(51) = " (CH)^=\xcb" ' " (CH)^=K"
arrRules(52) = "^E(CH)=\xcb" ' "^E(CH)=K"
arrRules(53) = "(CHA)R#=KEH\xb5" ' "(CHA)R#=KEH5"
arrRules(54) = "(CH)=C\xc8" ' "(CH)=CH"
arrRules(55) = " S(CI)#=SAY\xb4" ' " S(CI)#=SAY4"
arrRules(56) = "(CI)A=S\xc8" ' "(CI)A=SH"
arrRules(57) = "(CI)O=S\xc8" ' "(CI)O=SH"
arrRules(58) = "(CI)EN=S\xc8" ' "(CI)EN=SH"
arrRules(59) = "(CITY)=SIHTI\xd9" ' "(CITY)=SIHTIY"
arrRules(60) = "(C)+=\xd3" ' "(C)+=S"
arrRules(61) = "(CK)=\xcb" ' "(CK)=K"
arrRules(62) = "(COMMODORE)=KAA4MAHDOH\xd2" ' "(COMMODORE)=KAA4MAHDOHR"
arrRules(63) = "(COM)=KAH\xcd" ' "(COM)=KAHM"
arrRules(64) = "(CUIT)=KIH\xd4" ' "(CUIT)=KIHT"
arrRules(65) = "(CREA)=KRIYE\xd9" ' "(CREA)=KRIYEY"
arrRules(66) = "(C)=\xcb" ' "(C)=K"
arrRules(67) = "]\xc4" ' "]D"
arrRules(68) = " (D) =DIY\xb4" ' " (D) =DIY4"
arrRules(69) = " (DR.) =DAA4KTE\xd2" ' " (DR.) =DAA4KTER"
arrRules(70) = "#:(DED) =DIH\xc4" ' "#:(DED) =DIHD"
arrRules(71) = ".E(D) =\xc4" ' ".E(D) =D"
arrRules(72) = "#:^E(D) =\xd4" ' "#:^E(D) =T"
arrRules(73) = " (DE)^#=DI\xc8" ' " (DE)^#=DIH"
arrRules(74) = " (DO) =DU\xd7" ' " (DO) =DUW"
arrRules(75) = " (DOES)=DAH\xda" ' " (DOES)=DAHZ"
arrRules(76) = "(DONE) =DAH5\xce" ' "(DONE) =DAH5N"
arrRules(77) = "(DOING)=DUW4IHN\xd8" ' "(DOING)=DUW4IHNX"
arrRules(78) = " (DOW)=DA\xd7" ' " (DOW)=DAW"
arrRules(79) = "#(DU)A=JU\xd7" ' "#(DU)A=JUW"
arrRules(80) = "#(DU)^#=JA\xd8" ' "#(DU)^#=JAX"
arrRules(81) = "(D)=\xc4" ' "(D)=D"
arrRules(82) = "]\xc5" ' "]E"
arrRules(83) = " (E) =IYIY\xb4" ' " (E) =IYIY4"
arrRules(84) = "#:(E) \xbd" ' "#:(E) ="
arrRules(85) = "\\':^(E) \xbd" ' "\\':^(E) ="
arrRules(86) = " :(E) =I\xd9" ' " :(E) =IY"
arrRules(87) = "#(ED) =\xc4" ' "#(ED) =D"
arrRules(88) = "#:(E)D \xbd" ' "#:(E)D ="
arrRules(89) = "(EV)ER=EH4\xd6" ' "(EV)ER=EH4V"
arrRules(90) = "(E)^%=IY\xb4" ' "(E)^%=IY4"
arrRules(91) = "(ERI)#=IY4RI\xd9" ' "(ERI)#=IY4RIY"
arrRules(92) = "(ERI)=EH4RI\xc8" ' "(ERI)=EH4RIH"
arrRules(93) = "#:(ER)#=E\xd2" ' "#:(ER)#=ER"
arrRules(94) = "(ERROR)=EH4ROH\xd2" ' "(ERROR)=EH4ROHR"
arrRules(95) = "(ERASE)=IHREY5\xd3" ' "(ERASE)=IHREY5S"
arrRules(96) = "(ER)#=EH\xd2" ' "(ER)#=EHR"
arrRules(97) = "(ER)=E\xd2" ' "(ER)=ER"
arrRules(98) = " (EVEN)=IYVEH\xce" ' " (EVEN)=IYVEHN"
arrRules(99) = "#:(E)W\xbd" ' "#:(E)W="
arrRules(100) = "@(EW)=U\xd7" ' "@(EW)=UW"
arrRules(101) = "(EW)=YU\xd7" ' "(EW)=YUW"
arrRules(102) = "(E)O=I\xd9" ' "(E)O=IY"
arrRules(103) = "#:&(ES) =IH\xda" ' "#:&(ES) =IHZ"
arrRules(104) = "#:(E)S \xbd" ' "#:(E)S ="
arrRules(105) = "#:(ELY) =LI\xd9" ' "#:(ELY) =LIY"
arrRules(106) = "#:(EMENT)=MEHN\xd4" ' "#:(EMENT)=MEHNT"
arrRules(107) = "(EFUL)=FUH\xcc" ' "(EFUL)=FUHL"
arrRules(108) = "(EE)=IY\xb4" ' "(EE)=IY4"
arrRules(109) = "(EARN)=ER5\xce" ' "(EARN)=ER5N"
arrRules(110) = " (EAR)^=ER\xb5" ' " (EAR)^=ER5"
arrRules(111) = "(EAD)=EH\xc4" ' "(EAD)=EHD"
arrRules(112) = "#:(EA) =IYA\xd8" ' "#:(EA) =IYAX"
arrRules(113) = "(EA)SU=EH\xb5" ' "(EA)SU=EH5"
arrRules(114) = "(EA)=IY\xb5" ' "(EA)=IY5"
arrRules(115) = "(EIGH)=EY\xb4" ' "(EIGH)=EY4"
arrRules(116) = "(EI)=IY\xb4" ' "(EI)=IY4"
arrRules(117) = " (EYE)=AY\xb4" ' " (EYE)=AY4"
arrRules(118) = "(EY)=I\xd9" ' "(EY)=IY"
arrRules(119) = "(EU)=YUW\xb5" ' "(EU)=YUW5"
arrRules(120) = "(EQUAL)=IY4KWU\xcc" ' "(EQUAL)=IY4KWUL"
arrRules(121) = "(E)=E\xc8" ' "(E)=EH"
arrRules(122) = "]\xc6" ' "]F"
arrRules(123) = " (F) =EH4\xc6" ' " (F) =EH4F"
arrRules(124) = "(FUL)=FUH\xcc" ' "(FUL)=FUHL"
arrRules(125) = "(FRIEND)=FREH5N\xc4" ' "(FRIEND)=FREH5ND"
arrRules(126) = "(FATHER)=FAA4DHE\xd2" ' "(FATHER)=FAA4DHER"
arrRules(127) = "(F)F\xbd" ' "(F)F="
arrRules(128) = "(F)=\xc6" ' "(F)=F"
arrRules(129) = "]\xc7" ' "]G"
arrRules(130) = " (G) =JIY\xb4" ' " (G) =JIY4"
arrRules(131) = "(GIV)=GIH5\xd6" ' "(GIV)=GIH5V"
arrRules(132) = " (G)I^=\xc7" ' " (G)I^=G"
arrRules(133) = "(GE)T=GEH\xb5" ' "(GE)T=GEH5"
arrRules(134) = "SU(GGES)=GJEH4\xd3" ' "SU(GGES)=GJEH4S"
arrRules(135) = "(GG)=\xc7" ' "(GG)=G"
arrRules(136) = " B#(G)=\xc7" ' " B#(G)=G"
arrRules(137) = "(G)+=\xca" ' "(G)+=J"
arrRules(138) = "(GREAT)=GREY4\xd4" ' "(GREAT)=GREY4T"
arrRules(139) = "(GON)E=GAO5\xce" ' "(GON)E=GAO5N"
arrRules(140) = "#(GH)\xbd" ' "#(GH)="
arrRules(141) = " (GN)=\xce" ' " (GN)=N"
arrRules(142) = "(G)=\xc7" ' "(G)=G"
arrRules(143) = "]\xc8" ' "]H"
arrRules(144) = " (H) =EY4C\xc8" ' " (H) =EY4CH"
arrRules(145) = " (HAV)=/HAE6\xd6" ' " (HAV)=/HAE6V"
arrRules(146) = " (HERE)=/HIY\xd2" ' " (HERE)=/HIYR"
arrRules(147) = " (HOUR)=AW5E\xd2" ' " (HOUR)=AW5ER"
arrRules(148) = "(HOW)=/HA\xd7" ' "(HOW)=/HAW"
arrRules(149) = "(H)#=/\xc8" ' "(H)#=/H"
arrRules(150) = "(H)\xbd" ' "(H)="
arrRules(151) = "]\xc9" ' "]I"
arrRules(152) = " (IN)=IH\xce" ' " (IN)=IHN"
arrRules(153) = " (I) =AY\xb4" ' " (I) =AY4"
arrRules(154) = "(I) =A\xd9" ' "(I) =AY"
arrRules(155) = "(IN)D=AY5\xce" ' "(IN)D=AY5N"
arrRules(156) = "SEM(I)=I\xd9" ' "SEM(I)=IY"
arrRules(157) = " ANT(I)=A\xd9" ' " ANT(I)=AY"
arrRules(158) = "(IER)=IYE\xd2" ' "(IER)=IYER"
arrRules(159) = "#:R(IED) =IY\xc4" ' "#:R(IED) =IYD"
arrRules(160) = "(IED) =AY5\xc4" ' "(IED) =AY5D"
arrRules(161) = "(IEN)=IYEH\xce" ' "(IEN)=IYEHN"
arrRules(162) = "(IE)T=AY4E\xc8" ' "(IE)T=AY4EH"
arrRules(163) = "(I\\')=AY\xb5" ' "(I\\')=AY5"
arrRules(164) = " :(I)^%=AY\xb5" ' " :(I)^%=AY5"
arrRules(165) = " :(IE) =AY\xb4" ' " :(IE) =AY4"
arrRules(166) = "(I)%=I\xd9" ' "(I)%=IY"
arrRules(167) = "(IE)=IY\xb4" ' "(IE)=IY4"
arrRules(168) = " (IDEA)=AYDIY5A\xc8" ' " (IDEA)=AYDIY5AH"
arrRules(169) = "(I)^+:#=I\xc8" ' "(I)^+:#=IH"
arrRules(170) = "(IR)#=AY\xd2" ' "(IR)#=AYR"
arrRules(171) = "(IZ)%=AY\xda" ' "(IZ)%=AYZ"
arrRules(172) = "(IS)%=AY\xda" ' "(IS)%=AYZ"
arrRules(173) = "I^(I)^#=I\xc8" ' "I^(I)^#=IH"
arrRules(174) = "+^(I)^+=A\xd9" ' "+^(I)^+=AY"
arrRules(175) = "#:^(I)^+=I\xc8" ' "#:^(I)^+=IH"
arrRules(176) = "(I)^+=A\xd9" ' "(I)^+=AY"
arrRules(177) = "(IR)=E\xd2" ' "(IR)=ER"
arrRules(178) = "(IGH)=AY\xb4" ' "(IGH)=AY4"
arrRules(179) = "(ILD)=AY5L\xc4" ' "(ILD)=AY5LD"
arrRules(180) = " (IGN)=IHG\xce" ' " (IGN)=IHGN"
arrRules(181) = "(IGN) =AY4\xce" ' "(IGN) =AY4N"
arrRules(182) = "(IGN)^=AY4\xce" ' "(IGN)^=AY4N"
arrRules(183) = "(IGN)%=AY4\xce" ' "(IGN)%=AY4N"
arrRules(184) = "(ICRO)=AY4KRO\xc8" ' "(ICRO)=AY4KROH"
arrRules(185) = "(IQUE)=IY4\xcb" ' "(IQUE)=IY4K"
arrRules(186) = "(I)=I\xc8" ' "(I)=IH"
arrRules(187) = "]\xca" ' "]J"
arrRules(188) = " (J) =JEY\xb4" ' " (J) =JEY4"
arrRules(189) = "(J)=\xca" ' "(J)=J"
arrRules(190) = "]\xcb" ' "]K"
arrRules(191) = " (K) =KEY\xb4" ' " (K) =KEY4"
arrRules(192) = " (K)N\xbd" ' " (K)N="
arrRules(193) = "(K)=\xcb" ' "(K)=K"
arrRules(194) = "]\xcc" ' "]L"
arrRules(195) = " (L) =EH4\xcc" ' " (L) =EH4L"
arrRules(196) = "(LO)C#=LO\xd7" ' "(LO)C#=LOW"
arrRules(197) = "L(L)\xbd" ' "L(L)="
arrRules(198) = "#:^(L)%=U\xcc" ' "#:^(L)%=UL"
arrRules(199) = "(LEAD)=LIY\xc4" ' "(LEAD)=LIYD"
arrRules(200) = " (LAUGH)=LAE4\xc6" ' " (LAUGH)=LAE4F"
arrRules(201) = "(L)=\xcc" ' "(L)=L"
arrRules(202) = "]\xcd" ' "]M"
arrRules(203) = " (M) =EH4\xcd" ' " (M) =EH4M"
arrRules(204) = " (MR.) =MIH4STE\xd2" ' " (MR.) =MIH4STER"
arrRules(205) = " (MS.)=MIH5\xda" ' " (MS.)=MIH5Z"
arrRules(206) = " (MRS.) =MIH4SIX\xda" ' " (MRS.) =MIH4SIXZ"
arrRules(207) = "(MOV)=MUW4\xd6" ' "(MOV)=MUW4V"
arrRules(208) = "(MACHIN)=MAHSHIY5\xce" ' "(MACHIN)=MAHSHIY5N"
arrRules(209) = "M(M)\xbd" ' "M(M)="
arrRules(210) = "(M)=\xcd" ' "(M)=M"
arrRules(211) = "]\xce" ' "]N"
arrRules(212) = " (N) =EH4\xce" ' " (N) =EH4N"
arrRules(213) = "E(NG)+=N\xca" ' "E(NG)+=NJ"
arrRules(214) = "(NG)R=NX\xc7" ' "(NG)R=NXG"
arrRules(215) = "(NG)#=NX\xc7" ' "(NG)#=NXG"
arrRules(216) = "(NGL)%=NXGU\xcc" ' "(NGL)%=NXGUL"
arrRules(217) = "(NG)=N\xd8" ' "(NG)=NX"
arrRules(218) = "(NK)=NX\xcb" ' "(NK)=NXK"
arrRules(219) = " (NOW) =NAW\xb4" ' " (NOW) =NAW4"
arrRules(220) = "N(N)\xbd" ' "N(N)="
arrRules(221) = "(NON)E=NAH4\xce" ' "(NON)E=NAH4N"
arrRules(222) = "(N)=\xce" ' "(N)=N"
arrRules(223) = "]\xcf" ' "]O"
arrRules(224) = " (O) =OH4\xd7" ' " (O) =OH4W"
arrRules(225) = "(OF) =AH\xd6" ' "(OF) =AHV"
arrRules(226) = " (OH) =OW\xb5" ' " (OH) =OW5"
arrRules(227) = "(OROUGH)=ER4O\xd7" ' "(OROUGH)=ER4OW"
arrRules(228) = "#:(OR) =E\xd2" ' "#:(OR) =ER"
arrRules(229) = "#:(ORS) =ER\xda" ' "#:(ORS) =ERZ"
arrRules(230) = "(OR)=AO\xd2" ' "(OR)=AOR"
arrRules(231) = " (ONE)=WAH\xce" ' " (ONE)=WAHN"
arrRules(232) = "#(ONE) =WAH\xce" ' "#(ONE) =WAHN"
arrRules(233) = "(OW)=O\xd7" ' "(OW)=OW"
arrRules(234) = " (OVER)=OW5VE\xd2" ' " (OVER)=OW5VER"
arrRules(235) = "PR(O)V=UW\xb4" ' "PR(O)V=UW4"
arrRules(236) = "(OV)=AH4\xd6" ' "(OV)=AH4V"
arrRules(237) = "(O)^%=OW\xb5" ' "(O)^%=OW5"
arrRules(238) = "(O)^EN=O\xd7" ' "(O)^EN=OW"
arrRules(239) = "(O)^I#=OW\xb5" ' "(O)^I#=OW5"
arrRules(240) = "(OL)D=OW4\xcc" ' "(OL)D=OW4L"
arrRules(241) = "(OUGHT)=AO5\xd4" ' "(OUGHT)=AO5T"
arrRules(242) = "(OUGH)=AH5\xc6" ' "(OUGH)=AH5F"
arrRules(243) = " (OU)=A\xd7" ' " (OU)=AW"
arrRules(244) = "H(OU)S#=AW\xb4" ' "H(OU)S#=AW4"
arrRules(245) = "(OUS)=AX\xd3" ' "(OUS)=AXS"
arrRules(246) = "(OUR)=OH\xd2" ' "(OUR)=OHR"
arrRules(247) = "(OULD)=UH5\xc4" ' "(OULD)=UH5D"
arrRules(248) = "(OU)^L=AH\xb5" ' "(OU)^L=AH5"
arrRules(249) = "(OUP)=UW5\xd0" ' "(OUP)=UW5P"
arrRules(250) = "(OU)=A\xd7" ' "(OU)=AW"
arrRules(251) = "(OY)=O\xd9" ' "(OY)=OY"
arrRules(252) = "(OING)=OW4IHN\xd8" ' "(OING)=OW4IHNX"
arrRules(253) = "(OI)=OY\xb5" ' "(OI)=OY5"
arrRules(254) = "(OOR)=OH5\xd2" ' "(OOR)=OH5R"
arrRules(255) = "(OOK)=UH5\xcb" ' "(OOK)=UH5K"
arrRules(256) = "F(OOD)=UW5\xc4" ' "F(OOD)=UW5D"
arrRules(257) = "L(OOD)=AH5\xc4" ' "L(OOD)=AH5D"
arrRules(258) = "M(OOD)=UW5\xc4" ' "M(OOD)=UW5D"
arrRules(259) = "(OOD)=UH5\xc4" ' "(OOD)=UH5D"
arrRules(260) = "F(OOT)=UH5\xd4" ' "F(OOT)=UH5T"
arrRules(261) = "(OO)=UW\xb5" ' "(OO)=UW5"
arrRules(262) = "(O\\')=O\xc8" ' "(O\\')=OH"
arrRules(263) = "(O)E=O\xd7" ' "(O)E=OW"
arrRules(264) = "(O) =O\xd7" ' "(O) =OW"
arrRules(265) = "(OA)=OW\xb4" ' "(OA)=OW4"
arrRules(266) = " (ONLY)=OW4NLI\xd9" ' " (ONLY)=OW4NLIY"
arrRules(267) = " (ONCE)=WAH4N\xd3" ' " (ONCE)=WAH4NS"
arrRules(268) = "(ON\\'T)=OW4N\xd4" ' "(ON\\'T)=OW4NT"
arrRules(269) = "C(O)N=A\xc1" ' "C(O)N=AA"
arrRules(270) = "(O)NG=A\xcf" ' "(O)NG=AO"
arrRules(271) = " :^(O)N=A\xc8" ' " :^(O)N=AH"
arrRules(272) = "I(ON)=U\xce" ' "I(ON)=UN"
arrRules(273) = "#:(ON)=U\xce" ' "#:(ON)=UN"
arrRules(274) = "#^(ON)=U\xce" ' "#^(ON)=UN"
arrRules(275) = "(O)ST=O\xd7" ' "(O)ST=OW"
arrRules(276) = "(OF)^=AO4\xc6" ' "(OF)^=AO4F"
arrRules(277) = "(OTHER)=AH5DHE\xd2" ' "(OTHER)=AH5DHER"
arrRules(278) = "R(O)B=RA\xc1" ' "R(O)B=RAA"
arrRules(279) = "^R(O):#=OW\xb5" ' "^R(O):#=OW5"
arrRules(280) = "(OSS) =AO5\xd3" ' "(OSS) =AO5S"
arrRules(281) = "#:^(OM)=AH\xcd" ' "#:^(OM)=AHM"
arrRules(282) = "(O)=A\xc1" ' "(O)=AA"
arrRules(283) = "]\xd0" ' "]P"
arrRules(284) = " (P) =PIY\xb4" ' " (P) =PIY4"
arrRules(285) = "(PH)=\xc6" ' "(PH)=F"
arrRules(286) = "(PEOPL)=PIY5PU\xcc" ' "(PEOPL)=PIY5PUL"
arrRules(287) = "(POW)=PAW\xb4" ' "(POW)=PAW4"
arrRules(288) = "(PUT) =PUH\xd4" ' "(PUT) =PUHT"
arrRules(289) = "(P)P\xbd" ' "(P)P="
arrRules(290) = "(P)S\xbd" ' "(P)S="
arrRules(291) = "(P)N\xbd" ' "(P)N="
arrRules(292) = "(PROF.)=PROHFEH4SE\xd2" ' "(PROF.)=PROHFEH4SER"
arrRules(293) = "(P)=\xd0" ' "(P)=P"
arrRules(294) = "]\xd1" ' "]Q"
arrRules(295) = " (Q) =KYUW\xb4" ' " (Q) =KYUW4"
arrRules(296) = "(QUAR)=KWOH5\xd2" ' "(QUAR)=KWOH5R"
arrRules(297) = "(QU)=K\xd7" ' "(QU)=KW"
arrRules(298) = "(Q)=\xcb" ' "(Q)=K"
arrRules(299) = "]\xd2" ' "]R"
arrRules(300) = " (R) =AA5\xd2" ' " (R) =AA5R"
arrRules(301) = " (RE)^#=RI\xd9" ' " (RE)^#=RIY"
arrRules(302) = "(R)R\xbd" ' "(R)R="
arrRules(303) = "(R)=\xd2" ' "(R)=R"
arrRules(304) = "]\xd3" ' "]S"
arrRules(305) = " (S) =EH4\xd3" ' " (S) =EH4S"
arrRules(306) = "(SH)=S\xc8" ' "(SH)=SH"
arrRules(307) = "#(SION)=ZHU\xce" ' "#(SION)=ZHUN"
arrRules(308) = "(SOME)=SAH\xcd" ' "(SOME)=SAHM"
arrRules(309) = "#(SUR)#=ZHE\xd2" ' "#(SUR)#=ZHER"
arrRules(310) = "(SUR)#=SHE\xd2" ' "(SUR)#=SHER"
arrRules(311) = "#(SU)#=ZHU\xd7" ' "#(SU)#=ZHUW"
arrRules(312) = "#(SSU)#=SHU\xd7" ' "#(SSU)#=SHUW"
arrRules(313) = "#(SED)=Z\xc4" ' "#(SED)=ZD"
arrRules(314) = "#(S)#=\xda" ' "#(S)#=Z"
arrRules(315) = "(SAID)=SEH\xc4" ' "(SAID)=SEHD"
arrRules(316) = "^(SION)=SHU\xce" ' "^(SION)=SHUN"
arrRules(317) = "(S)S\xbd" ' "(S)S="
arrRules(318) = ".(S) =\xda" ' ".(S) =Z"
arrRules(319) = "#:.E(S) =\xda" ' "#:.E(S) =Z"
arrRules(320) = "#:^#(S) =\xd3" ' "#:^#(S) =S"
arrRules(321) = "U(S) =\xd3" ' "U(S) =S"
arrRules(322) = " :#(S) =\xda" ' " :#(S) =Z"
arrRules(323) = "##(S) =\xda" ' "##(S) =Z"
arrRules(324) = " (SCH)=S\xcb" ' " (SCH)=SK"
arrRules(325) = "(S)C+\xbd" ' "(S)C+="
arrRules(326) = "#(SM)=ZU\xcd" ' "#(SM)=ZUM"
arrRules(327) = "#(SN)\\'=ZU\xcd" ' "#(SN)\\'=ZUM"
arrRules(328) = "(STLE)=SU\xcc" ' "(STLE)=SUL"
arrRules(329) = "(S)=\xd3" ' "(S)=S"
arrRules(330) = "]\xd4" ' "]T"
arrRules(331) = " (T) =TIY\xb4" ' " (T) =TIY4"
arrRules(332) = " (THE) #=DHI\xd9" ' " (THE) #=DHIY"
arrRules(333) = " (THE) =DHA\xd8" ' " (THE) =DHAX"
arrRules(334) = "(TO) =TU\xd8" ' "(TO) =TUX"
arrRules(335) = " (THAT)=DHAE\xd4" ' " (THAT)=DHAET"
arrRules(336) = " (THIS) =DHIH\xd3" ' " (THIS) =DHIHS"
arrRules(337) = " (THEY)=DHE\xd9" ' " (THEY)=DHEY"
arrRules(338) = " (THERE)=DHEH\xd2" ' " (THERE)=DHEHR"
arrRules(339) = "(THER)=DHE\xd2" ' "(THER)=DHER"
arrRules(340) = "(THEIR)=DHEH\xd2" ' "(THEIR)=DHEHR"
arrRules(341) = " (THAN) =DHAE\xce" ' " (THAN) =DHAEN"
arrRules(342) = " (THEM) =DHAE\xce" ' " (THEM) =DHAEN"
arrRules(343) = "(THESE) =DHIY\xda" ' "(THESE) =DHIYZ"
arrRules(344) = " (THEN)=DHEH\xce" ' " (THEN)=DHEHN"
arrRules(345) = "(THROUGH)=THRUW\xb4" ' "(THROUGH)=THRUW4"
arrRules(346) = "(THOSE)=DHOH\xda" ' "(THOSE)=DHOHZ"
arrRules(347) = "(THOUGH) =DHO\xd7" ' "(THOUGH) =DHOW"
arrRules(348) = "(TODAY)=TUXDE\xd9" ' "(TODAY)=TUXDEY"
arrRules(349) = "(TOMO)RROW=TUMAA\xb5" ' "(TOMO)RROW=TUMAA5"
arrRules(350) = "(TO)TAL=TOW\xb5" ' "(TO)TAL=TOW5"
arrRules(351) = " (THUS)=DHAH4\xd3" ' " (THUS)=DHAH4S"
arrRules(352) = "(TH)=T\xc8" ' "(TH)=TH"
arrRules(353) = "#:(TED)=TIX\xc4" ' "#:(TED)=TIXD"
arrRules(354) = "S(TI)#N=C\xc8" ' "S(TI)#N=CH"
arrRules(355) = "(TI)O=S\xc8" ' "(TI)O=SH"
arrRules(356) = "(TI)A=S\xc8" ' "(TI)A=SH"
arrRules(357) = "(TIEN)=SHU\xce" ' "(TIEN)=SHUN"
arrRules(358) = "(TUR)#=CHE\xd2" ' "(TUR)#=CHER"
arrRules(359) = "(TU)A=CHU\xd7" ' "(TU)A=CHUW"
arrRules(360) = " (TWO)=TU\xd7" ' " (TWO)=TUW"
arrRules(361) = "&(T)EN \xbd" ' "&(T)EN ="
arrRules(362) = "(T)=\xd4" ' "(T)=T"
arrRules(363) = "]\xd5" ' "]U"
arrRules(364) = " (U) =YUW\xb4" ' " (U) =YUW4"
arrRules(365) = " (UN)I=YUW\xce" ' " (UN)I=YUWN"
arrRules(366) = " (UN)=AH\xce" ' " (UN)=AHN"
arrRules(367) = " (UPON)=AXPAO\xce" ' " (UPON)=AXPAON"
arrRules(368) = "@(UR)#=UH4\xd2" ' "@(UR)#=UH4R"
arrRules(369) = "(UR)#=YUH4\xd2" ' "(UR)#=YUH4R"
arrRules(370) = "(UR)=E\xd2" ' "(UR)=ER"
arrRules(371) = "(U)^ =A\xc8" ' "(U)^ =AH"
arrRules(372) = "(U)^^=AH\xb5" ' "(U)^^=AH5"
arrRules(373) = "(UY)=AY\xb5" ' "(UY)=AY5"
arrRules(374) = " G(U)#\xbd" ' " G(U)#="
arrRules(375) = "G(U)%\xbd" ' "G(U)%="
arrRules(376) = "G(U)#=\xd7" ' "G(U)#=W"
arrRules(377) = "#N(U)=YU\xd7" ' "#N(U)=YUW"
arrRules(378) = "@(U)=U\xd7" ' "@(U)=UW"
arrRules(379) = "(U)=YU\xd7" ' "(U)=YUW"
arrRules(380) = "]\xd6" ' "]V"
arrRules(381) = " (V) =VIY\xb4" ' " (V) =VIY4"
arrRules(382) = "(VIEW)=VYUW\xb5" ' "(VIEW)=VYUW5"
arrRules(383) = "(V)=\xd6" ' "(V)=V"
arrRules(384) = "]\xd7" ' "]W"
arrRules(385) = " (W) =DAH4BULYU\xd7" ' " (W) =DAH4BULYUW"
arrRules(386) = " (WERE)=WE\xd2" ' " (WERE)=WER"
arrRules(387) = "(WA)SH=WA\xc1" ' "(WA)SH=WAA"
arrRules(388) = "(WA)ST=WE\xd9" ' "(WA)ST=WEY"
arrRules(389) = "(WA)S=WA\xc8" ' "(WA)S=WAH"
arrRules(390) = "(WA)T=WA\xc1" ' "(WA)T=WAA"
arrRules(391) = "(WHERE)=WHEH\xd2" ' "(WHERE)=WHEHR"
arrRules(392) = "(WHAT)=WHAH\xd4" ' "(WHAT)=WHAHT"
arrRules(393) = "(WHOL)=/HOW\xcc" ' "(WHOL)=/HOWL"
arrRules(394) = "(WHO)=/HU\xd7" ' "(WHO)=/HUW"
arrRules(395) = "(WH)=W\xc8" ' "(WH)=WH"
arrRules(396) = "(WAR)#=WEH\xd2" ' "(WAR)#=WEHR"
arrRules(397) = "(WAR)=WAO\xd2" ' "(WAR)=WAOR"
arrRules(398) = "(WOR)^=WE\xd2" ' "(WOR)^=WER"
arrRules(399) = "(WR)=\xd2" ' "(WR)=R"
arrRules(400) = "(WOM)A=WUH\xcd" ' "(WOM)A=WUHM"
arrRules(401) = "(WOM)E=WIH\xcd" ' "(WOM)E=WIHM"
arrRules(402) = "(WEA)R=WE\xc8" ' "(WEA)R=WEH"
arrRules(403) = "(WANT)=WAA5N\xd4" ' "(WANT)=WAA5NT"
arrRules(404) = "ANS(WER)=E\xd2" ' "ANS(WER)=ER"
arrRules(405) = "(W)=\xd7" ' "(W)=W"
arrRules(406) = "]\xd8" ' "]X"
arrRules(407) = " (X) =EH4K\xd2" ' " (X) =EH4KR"
arrRules(408) = " (X)=\xda" ' " (X)=Z"
arrRules(409) = "(X)=K\xd3" ' "(X)=KS"
arrRules(410) = "]\xd9" ' "]Y"
arrRules(411) = " (Y) =WAY\xb4" ' " (Y) =WAY4"
arrRules(412) = "(YOUNG)=YAHN\xd8" ' "(YOUNG)=YAHNX"
arrRules(413) = " (YOUR)=YOH\xd2" ' " (YOUR)=YOHR"
arrRules(414) = " (YOU)=YU\xd7" ' " (YOU)=YUW"
arrRules(415) = " (YES)=YEH\xd3" ' " (YES)=YEHS"
arrRules(416) = " (Y)=\xd9" ' " (Y)=Y"
arrRules(417) = "F(Y)=A\xd9" ' "F(Y)=AY"
arrRules(418) = "PS(YCH)=AY\xcb" ' "PS(YCH)=AYK"
arrRules(419) = "#:^(Y)=I\xd9" ' "#:^(Y)=IY"
arrRules(420) = "#:^(Y)I=I\xd9" ' "#:^(Y)I=IY"
arrRules(421) = " :(Y) =A\xd9" ' " :(Y) =AY"
arrRules(422) = " :(Y)#=A\xd9" ' " :(Y)#=AY"
arrRules(423) = " :(Y)^+:#=I\xc8" ' " :(Y)^+:#=IH"
arrRules(424) = " :(Y)^#=A\xd9" ' " :(Y)^#=AY"
arrRules(425) = "(Y)=I\xc8" ' "(Y)=IH"
arrRules(426) = "]\xda" ' "]Z"
arrRules(427) = " (Z) =ZIY\xb4" ' " (Z) =ZIY4"
arrRules(428) = "(Z)=\xda" ' "(Z)=Z"
arrRules(429) = "]\xb0" ' "]0"
arrRules(430) = "(A)\xbd" ' "(A)="
arrRules(431) = "(!)=\xae" ' "(!)=."
arrRules(432) = "(\" + Chr$(34) + ") =-AH5NKWOWT\xad" ' "(\") =-AH5NKWOWT-"
arrRules(433) = "(\" + Chr$(34) + ")=KWOW4T\xad" ' "(\")=KWOW4T-"
arrRules(434) = "(#)= NAH4MBE\xd2" ' "(#)= NAH4MBER"
arrRules(435) = "($)= DAA4LE\xd2" ' "($)= DAA4LER"
arrRules(436) = "(%)= PERSEH4N\xd4" ' "(%)= PERSEH4NT"
arrRules(437) = "(&)= AEN\xc4" ' "(&)= AEND"
arrRules(438) = "(\\)\xbd" ' "(\\)="
arrRules(439) = "(*)= AE4STERIHS\xcb" ' "(*)= AE4STERIHSK"
arrRules(440) = "(+)= PLAH4\xd3" ' "(+)= PLAH4S"
arrRules(441) = "(,)=\xac" ' "(,)=,"
arrRules(442) = " (-) =\xad" ' " (-) =-"
arrRules(443) = "(-)\xbd" ' "(-)="
arrRules(444) = "(.)= POYN\xd4" ' "(.)= POYNT"
arrRules(445) = "(/)= SLAE4S\xc8" ' "(/)= SLAE4SH"
arrRules(446) = "(0)= ZIY4RO\xd7" ' "(0)= ZIY4ROW"
arrRules(447) = " (1ST)=FER4S\xd4" ' " (1ST)=FER4ST"
arrRules(448) = " (10TH)=TEH4NT\xc8" ' " (10TH)=TEH4NTH"
arrRules(449) = "(1)= WAH4\xce" ' "(1)= WAH4N"
arrRules(450) = " (2ND)=SEH4KUN\xc4" ' " (2ND)=SEH4KUND"
arrRules(451) = "(2)= TUW\xb4" ' "(2)= TUW4"
arrRules(452) = " (3RD)=THER4\xc4" ' " (3RD)=THER4D"
arrRules(453) = "(3)= THRIY\xb4" ' "(3)= THRIY4"
arrRules(454) = "(4)= FOH4\xd2" ' "(4)= FOH4R"
arrRules(455) = " (5TH)=FIH4FT\xc8" ' " (5TH)=FIH4FTH"
arrRules(456) = "(5)= FAY4\xd6" ' "(5)= FAY4V"
arrRules(457) = " (64) =SIH4KSTIY FOH\xd2" ' " (64) =SIH4KSTIY FOHR"
arrRules(458) = "(6)= SIH4K\xd3" ' "(6)= SIH4KS"
arrRules(459) = "(7)= SEH4VU\xce" ' "(7)= SEH4VUN"
arrRules(460) = " (8TH)=EY4T\xc8" ' " (8TH)=EY4TH"
arrRules(461) = "(8)= EY4\xd4" ' "(8)= EY4T"
arrRules(462) = "(9)= NAY4\xce" ' "(9)= NAY4N"
arrRules(463) = "(:)=\xae" ' "(:)=."
arrRules(464) = "(;)=\xae" ' "(;)=."
arrRules(465) = "(<)= LEH4S DHAE\xce" ' "(<)= LEH4S DHAEN"
arrRules(466) = "(=)= IY4KWUL\xda" ' "(=)= IY4KWULZ"
arrRules(467) = "(>)= GREY4TER DHAE\xce" ' "(>)= GREY4TER DHAEN"
arrRules(468) = "(?)=\xbf" ' "(?)=?"
arrRules(469) = "(@)= AE6\xd4" ' "(@)= AE6T"
arrRules(470) = "(^)= KAE4RIX\xd4" ' "(^)= KAE4RIXT"
arrRules(471) = "(')\xbd" ' "(')="
arrRules(472) = "(`)\xbd" ' "(`)="
arrRules(473) = "]\xb1" ' "]1'
ReDim arrRuleTab(0 To 27) As Integer
arrRuleTab(0) = &H00
arrRuleTab(1) = &H195
arrRuleTab(2) = &H1F7
arrRuleTab(3) = &H2A2
arrRuleTab(4) = &H33F
arrRuleTab(5) = &H4C6
arrRuleTab(6) = &H507
arrRuleTab(7) = &H57F
arrRuleTab(8) = &H5C8
arrRuleTab(9) = &H728
arrRuleTab(10) = &H739
arrRuleTab(11) = &H750
arrRuleTab(12) = &H793
arrRuleTab(13) = &H7F3
arrRuleTab(14) = &H857
arrRuleTab(15) = &HAA5
arrRuleTab(16) = &HB02
arrRuleTab(17) = &HB28
arrRuleTab(18) = &HB49
arrRuleTab(19) = &HC32
arrRuleTab(20) = &HDAC
arrRuleTab(21) = &HE3B
arrRuleTab(22) = &HE58
arrRuleTab(23) = &HF33
arrRuleTab(24) = &HF4C
arrRuleTab(25) = &HFDF
arrRuleTab(26) = &HFF0
arrRuleTab(27) = &H11B7
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' END reciter_tabs.h
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' BEGIN sam_tabs.h
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
'tab40672
arrStressInputTable(0) = "*"
arrStressInputTable(1) = "1"
arrStressInputTable(2) = "2"
arrStressInputTable(3) = "3"
arrStressInputTable(4) = "4"
arrStressInputTable(5) = "5"
arrStressInputTable(6) = "6"
arrStressInputTable(7) = "7"
arrStressInputTable(8) = "8"
' BEGIN tab40682
'arrSignInputTable1 = " .?,--IIEAAAAUAIEOURLWYWR LWYMNNNDQSSFT//ZZVDC*J* *EAOAOUB* *D* *G* *GP* *T* *K* *K* *UUU" ' Initialize the string directly
tab40682$ = " .?,--IIEAAAAUAIEOURLWYWR LWYMNNNDQSSFT//ZZVDC*J* *EAOAOUB* *D* *G* *GP* *T* *K* *K* *UUU" ' Initialize the string directly
iSize = Len(tab40682$)
ReDim arrSignInputTable1(0 To iSize - 1) As String ' _Unsigned _Byte
For iIndex = 0 To iSize - 1
arrSignInputTable1(iIndex) = Mid$(tab40682$, iIndex + 1, 1)
Next iIndex
' END tab40682
' BEGIN tab40763
'arrSignInputTable2 = "**** *YHH EAHOHXXRXHXXXXH* *****XXX* H*HHHX* HHH* *YYYYWWW* ***** * * *X* * *LMN" ' Initialize the string directly
tab40763$ = "**** *YHH EAHOHXXRXHXXXXH* *****XXX* H*HHHX* HHH* *YYYYWWW* ***** * * *X* * *LMN" ' Initialize the string directly
iSize = Len(tab40763$)
ReDim arrSignInputTable2(0 To iSize - 1) As String ' _Unsigned _Byte
For iIndex = 0 To iSize - 1
arrSignInputTable2(iIndex) = Mid$(tab40763$, iIndex + 1, 1)
Next iIndex
' END tab40763
' BEGIN loc_9F8C
ReDim arrFlags1(0 To 66) As _Unsigned _Byte
Data &H00,&H00,&H00,&H00,&H00,&HA4,&HA4,&HA4
Data &HA4,&HA4,&HA4,&H84,&H84,&HA4,&HA4,&H84
Data &H84,&H84,&H84,&H84,&H84,&H84,&H44,&H44
Data &H44,&H44,&H44,&H4C,&H4C,&H4C,&H48,&H4C
Data &H40,&H40,&H40,&H40,&H40,&H40,&H44,&H44
Data &H44,&H44,&H48,&H40,&H4C,&H44,&H00,&H00
Data &HB4,&HB4,&HB4,&H94,&H94,&H94,&H4E,&H4E
Data &H4E,&H4E,&H4E,&H4E,&H4E,&H4E,&H4E,&H4E
Data &H4E,&H4E,&H4B,&H4B,&H4B,&H4B,&H4B,&H4B
Data &H4B,&H4B,&H4B,&H4B,&H4B,&H4B,&H80,&HC1
Data &HC1
For iIndex = 0 To 66
Read arrFlags1(iIndex)
Next iIndex
'END loc_9F8C
'??? flags overlap arrFlags2 'Comment retained from original code
'loc_9FDA
ReDim arrFlags2(0 To 61) As _Unsigned _Byte
Data &H80,&HC1,&HC1,&HC1,&HC1,&H00,&H00,&H00
Data &H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00
Data &H00,&H00,&H00,&H00,&H00,&H00,&H00,&H10
Data &H10,&H10,&H10,&H08,&H0C,&H08,&H04,&H40
Data &H24,&H20,&H20,&H24,&H00,&H00,&H24,&H20
Data &H20,&H24,&H20,&H20,&H00,&H20,&H00,&H00
Data &H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00
Data &H00,&H04,&H04,&H04,&H00,&H00,&H00,&H00
Data &H00,&H00,&H00,&H00,&H00,&H04,&H04,&H04
Data &H00,&H00,&H00,&H00,&H00,&H00
For iIndex = 0 To 61
Read arrFlags2(iIndex)
Next iIndex
'tab45616???
ReDim arrPhoStressedLengthTable(0 To 61) As _Unsigned _Byte
Data &H00,&H12,&H12,&H12,8,&HB,9,&HB
Data &HE,&HF,&HB,&H10,&HC,6,6,&HE
Data &HC,&HE,&HC,&HB,8,8,&HB,&HA
Data 9,8,8,8,8,8,3,5
Data 2,2,2,2,2,2,6,6
Data 8,6,6,2,9,4,2,1
Data &HE,&HF,&HF,&HF,&HE,&HE,8,2
Data 2,7,2,1,7,2,2,7
Data 2,2,8,2
Data 2,6,2,2
Data 7,2,4,7,1,4,5,5
For iIndex = 0 To 61
Read arrPhoStressedLengthTable(iIndex)
Next iIndex
'tab45536???
ReDim arrPhoLengthTable(0 To 61) As _Unsigned _Byte
Data 0,&H12,&H12,&H12,8,8,8,8
Data 8,&HB,6,&HC,&HA,5,5,&HB
Data &HA,&HA,&HA,9,8,7,9,7
Data 6,8,6,7,7,7,2,5
Data 2,2,2,2,2,2,6,6
Data 7,6,6,2,8,3,1,&H1E
Data &HD,&HC,&HC,&HC,&HE,9,6,1
Data 2,5,1,1,6,1,2,6
Data 1,2,8,2
Data 2,4,2,2
Data 6,1,4,6,1,4,&HC7,&HFF
For iIndex = 0 To 61
Read arrPhoLengthTable(iIndex)
Next iIndex
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' END sam_tabs.h
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' BEGIN render_tabs.h
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' The following constants are defined as byte arrays:
' uint8_t tab48426[5]
' uint8_t tab47492[]
' uint8_t amplitudeRescale[]
' uint8_t blendRank[]
' Initialize tab48426
ReDim arrTab48426(4) As _Byte ' Equivalent to uint8_t[5]
arrTab48426(0) = &H18
arrTab48426(1) = &H1A
arrTab48426(2) = &H17
arrTab48426(3) = &H17
arrTab48426(4) = &H17
' Initialize tab47492
ReDim arrTab47492(10) ' 11 elements
arrTab47492(0) = 0
arrTab47492(1) = 0
arrTab47492(2) = &HE0
arrTab47492(3) = &HE6
arrTab47492(4) = &HEC
arrTab47492(5) = &HF3
arrTab47492(6) = &HF9
arrTab47492(7) = 0
arrTab47492(8) = 6
arrTab47492(9) = &HC
arrTab47492(10) = 6
' Initialize amplitudeRescale
ReDim arrAmplitudeRescale(16) ' 17 elements
arrAmplitudeRescale(0) = 0
arrAmplitudeRescale(1) = 1
arrAmplitudeRescale(2) = 2
arrAmplitudeRescale(3) = 2
arrAmplitudeRescale(4) = 2
arrAmplitudeRescale(5) = 3
arrAmplitudeRescale(6) = 3
arrAmplitudeRescale(7) = 4
arrAmplitudeRescale(8) = 4
arrAmplitudeRescale(9) = 5
arrAmplitudeRescale(10) = 6
arrAmplitudeRescale(11) = 8
arrAmplitudeRescale(12) = 9
arrAmplitudeRescale(13) = &HB
arrAmplitudeRescale(14) = &HD
arrAmplitudeRescale(15) = &HF
arrAmplitudeRescale(16) = 0
' Initialize blendRank
ReDim arrBlendRank(62) ' 63 elements
arrBlendRank(0) = 0
arrBlendRank(1) = &H1F
arrBlendRank(2) = &H1F
arrBlendRank(3) = &H1F
arrBlendRank(4) = &H1F
arrBlendRank(5) = 2
arrBlendRank(6) = 2
arrBlendRank(7) = 2
arrBlendRank(8) = 2
arrBlendRank(9) = 2
arrBlendRank(10) = 2
arrBlendRank(11) = 2
arrBlendRank(12) = 2
arrBlendRank(13) = 2
arrBlendRank(14) = 5
arrBlendRank(15) = 5
arrBlendRank(16) = 2
arrBlendRank(17) = &HA
arrBlendRank(18) = 2
arrBlendRank(19) = 8
arrBlendRank(20) = 5
arrBlendRank(21) = 5
arrBlendRank(22) = &HB
arrBlendRank(23) = &HA
arrBlendRank(24) = 9
arrBlendRank(25) = 8
arrBlendRank(26) = 8
arrBlendRank(27) = &HA0
arrBlendRank(28) = 8
arrBlendRank(29) = 8
arrBlendRank(30) = &H17
arrBlendRank(31) = &H1F
arrBlendRank(32) = &H12
arrBlendRank(33) = &H12
arrBlendRank(34) = &H12
arrBlendRank(35) = &H12
arrBlendRank(36) = &H1E
arrBlendRank(37) = &H1E
arrBlendRank(38) = &H14
arrBlendRank(39) = &H14
arrBlendRank(40) = &H14
arrBlendRank(41) = &H14
arrBlendRank(42) = &H17
arrBlendRank(43) = &H17
arrBlendRank(44) = &H1A
arrBlendRank(45) = &H1A
arrBlendRank(46) = &H1D
arrBlendRank(47) = &H1D
arrBlendRank(48) = 2
arrBlendRank(49) = 2
arrBlendRank(50) = 2
arrBlendRank(51) = 2
arrBlendRank(52) = 2
arrBlendRank(53) = 2
arrBlendRank(54) = &H1A
arrBlendRank(55) = &H1D
arrBlendRank(56) = &H1B
arrBlendRank(57) = &H1A
arrBlendRank(58) = &H1D
arrBlendRank(59) = &H1B
arrBlendRank(60) = &H1A
arrBlendRank(61) = &H1D
arrBlendRank(62) = &H1B
arrBlendRank(63) = &H1A ' Note: There's an extra element in the C code
arrBlendRank(64) = &H1D
arrBlendRank(65) = &H1B
arrBlendRank(66) = &H17
arrBlendRank(67) = &H1D
arrBlendRank(68) = &H17
arrBlendRank(69) = &H17
arrBlendRank(70) = &H1D
arrBlendRank(71) = &H17
arrBlendRank(72) = &H17
arrBlendRank(73) = &H1D
arrBlendRank(74) = &H17
arrBlendRank(75) = &H17
arrBlendRank(76) = &H1D
arrBlendRank(77) = &H17
arrBlendRank(78) = &H17
arrBlendRank(79) = &H17
' Example of accessing the arrays:
' PRINT arrTab48426(0)
' PRINT arrTab47492(5)
' PRINT arrAmplitudeRescale(10)
' PRINT arrBlendRank(25)
'BEGIN PART 1a2
ReDim arrOutBlendLength(95) As _Unsigned _Byte
Data 0,2,2,2,2,4,4,4,4,4,4,4,4,4,4,4,4,4,3,2,4,4,2,2
Data 2,2,2,1,1,1,1,1,1,1,1,1,1,1,2,2,2,1,0,1,0,1,0,5
Data 5,5,5,5,4,4,2,0,1,2,0,1,2,0,1,2,0,1,2,0,2,2,0,1
Data 3,0,2,3,0,2,160,160 '0xA0 = 160
For iIndex = 0 To 95
Read arrOutBlendLength(iIndex)
Next iIndex
' Number of frames at beginning of a phoneme devoted to interpolating to phoneme's final value
' tab45776
ReDim arrInBlendLength(95) As _Unsigned _Byte
Data 0,2,2,2,2,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,4,4,3,3
Data 3,3,3,1,2,3,2,1,3,3,3,3,1,1,3,3,3,2,2,3,2,3,0,0
Data 5,5,5,5,4,4,2,0,2,2,0,3,2,0,4,2,0,3,2,0,2,2,0,2
Data 3,0,3,3,0,3,176,160 '0xB0 = 176,&HA0 = 160
For iIndex = 0 To 95
Read arrInBlendLength(iIndex)
Next iIndex
ReDim arrSampledConsonantFlags(79) As _Unsigned _Byte
Data 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
Data 0,0,0,0,0,0,0,0,241,226,211,187,124,149,1,2,3,3,0,114,0,2,0,0
Data 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27
Data 0,0,25,0,0,0,0,0,0,0,0,0
For iIndex = 0 To 79
Read arrSampledConsonantFlags(iIndex)
Next iIndex
'tab45056
'note: non const
ReDim arrFreq1Data(71) As _Unsigned _Byte
Data &H00,&H13,&H13,&H13,&H13,&HA,&HE,&H12,&H18,&H1A,&H16,&H14,&H10,&H14,&HE,&H12,&HE,&H12,&H12,&H10,&HC,&HE,&HA,&H12,&HE,&HA,8,6,6,6,6,&H11,6,6,6,6,&HE,&H10,9,&HA,8,&HA,6,6,6,5,6,0,&H12,&H1A,&H14,&H1A,&H12,&HC,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,&HA,&HA,6,6,6,&H2C,&H13
For iIndex = 0 To 71
Read arrFreq1Data(iIndex)
Next iIndex
'tab451356
' note: non const
ReDim arrFreq2Data(79) As _Unsigned _Byte
Data &H00,&H43,&H43,&H43,&H43,&H54,&H48,&H42,&H3E,&H28,&H2C,&H1E,&H24,&H2C,&H48,&H30,&H24,&H1E,&H32,&H24,&H1C,&H44,&H18,&H32,&H1E,&H18,&H52,&H2E,&H36,&H56,&H36,&H43,&H49,&H4F,&H1A,&H42,&H49,&H25,&H33,&H42,&H28,&H2F,&H4F,&H4F,&H42,&H4F,&H6E,&H00,&H48,&H26,&H1E,&H2A,&H1E,&H22,&H1A,&H1A,&H1A,&H42,&H42,&H42,&H6E,&H6E,&H6E,&H54,&H54,&H54
For iIndex = 0 To 59
Read arrFreq2Data(iIndex)
Next iIndex
Data &H1A,&H1A,&H1A,&H42,&H42,&H42,&H6D,&H56,&H6D,&H54,&H54,&H54,&H7F,&H7F
For iIndex = 60 To 79
Read arrFreq2Data(iIndex)
Next iIndex
'tab45216
ReDim arrFreq3Data(62) As _Unsigned _Byte
Data &H00,&H5B,&H5B,&H5B,&H5B,&H6E,&H5D,&H5B,&H58,&H59,&H57,&H58,&H52,&H59,&H5D,&H3E,&H52,&H58,&H3E,&H6E,&H50,&H5D,&H5A,&H3C,&H6E,&H5A,&H6E,&H51,&H79,&H65,&H79,&H5B,&H63,&H6A,&H51,&H79,&H5D,&H52,&H5D,&H67,&H4C,&H5D,&H65,&H65,&H79,&H65,&H79,&H00,&H5A,&H58,&H58,&H58,&H58,&H52,&H51,&H51,&H51,&H79,&H79,&H79,&H70,&H6E,&H6E,&H5E,&H5E,&H5E,&H51,&H51
For iIndex = 0 To 59
Read arrFreq3Data(iIndex)
Next iIndex
Data &H51,&H79,&H79,&H79,&H65,&H65,&H70,&H5E,&H5E,&H5E,&H08,&H01
For iIndex = 60 To 61
Read arrFreq3Data(iIndex)
Next iIndex
ReDim arrAmp1Data(78) As _Byte
Data 0,0,0,0,0,&HD,&HD,&HE,&HF,&HF,&HF,&HF,&HF,&HC,&HD,&HC
Data &HF,&HF,&HD,&HD,&HD,&HE,&HD,&HC,&HD,&HD,&HD,&HC,9,9,0,0
Data 0,0,0,0,0,0,&HB,&HB,&HB,&HB,0,0,1,&HB,0,2
Data &HE,&HF,&HF,&HF,&HF,&HD,2,4,0,2,4,0,1,4,0,1
Data 4,0,0,0,0,0,0,0,0,&HC,0,0,0,0,&HF,&HF
ReDim arrAmp2Data(78) As _Byte
Data 0,0,0,0,0,&HA,&HB,&HD,&HE,&HD,&HC,&HC,&HB,9,&HB,&HB
Data &HC,&HC,&HC,8,8,&HC,8,&HA,8,8,&HA,3,9,6,0,0
Data 0,0,0,0,0,0,3,5,3,4,0,0,0,5,&HA,2
Data &HE,&HD,&HC,&HD,&HC,8,0,1,0,0,1,0,0,1,0,0
Data 1,0,0,0,0,0,0,0,0,&HA,0,0,&HA,0,0,0
ReDim arrAmp3Data(78) As _Byte
Data 0,0,0,0,0,8,7,8,8,1,1,0,1,0,7,5
Data 1,0,6,1,0,7,0,5,1,0,8,0,0,3,0,0
Data 0,0,0,0,0,0,0,1,0,0,0,0,0,1,&HE,1
Data 9,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0
Data 0,0,0,0,0,0,0,0,0,7,0,0,5,0,&H13,&H10
ReDim arrSinus(180) As _Unsigned _Byte
' Initialize the sinus array with the given values
Data 0,0,0,16,16,16,16,16,16,32,32,32,32,32,32,48,48,48,48,48,48,48,64,64,64,64,64,64,64,80,80,80,80,80,80,80,80,96,96,96,96,96,96,96,96,96,96,96,96,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,96,96,96,96,96,96,96,96,96,96,96,96,80,80,80,80,80,80,80,80,64,64,64,64,64,64,64,48,48,48,48,48,48,48,32,32,32,32,32,32,16,16,16,16,16,16,0,0,0,240,240,240,240,240,240,224,224,224,224,224,224,208,208,208,208,208,208,208,192,192,192,192,192,192,192,176,176,176,176,176,176,176,176,160,160,160,160,160,160,160,160,160,160,160,160,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,160,160,160,160,160,160,160,160,160,160,160,160,176,176,176,176,176,176,176,176,192,192,192,192,192,192,192,208,208,208,208,208,208,208,224,224,224,224,224,224,240,240,240,240,240,240,0,0
For iIndex = 1 To 181
Read arrSinus(iIndex)
Next iIndex
ReDim arrRectangle(143) As _Unsigned _Byte
' Initialize the array with the given values
Data &H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90
Data &H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90
Data &H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90
Data &H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90
Data &H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90
Data &H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90
Data &H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90
Data &H90,&H90,&H90,&H90,&H90,&H90,&H90,&H90,&H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70
Data &H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70
Data &H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70
Data &H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70
Data &H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70
Data &H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70,&H70
For iIndex = 0 To 143
Read arrRectangle(iIndex)
Next iIndex
ReDim arrMultTable(255) As _Byte ' QB64 uses byte for unsigned 8-bit
Data 0,0,0,0,0,0,0,0
Data 0,0,0,0,0,0,0,0
Data 0,0,1,1,2,2,3,3
Data 4,4,5,5,6,6,7,7
Data 0,1,2,3,4,5,6,7
Data 8,9,10,11,12,13,14,15 '0xA to 0xF
Data 0,1,3,4,6,7,9,10 '0xA
Data 12,13,15,16,18,19,21,22 '0x10 to 0x16
Data 0,2,4,6,8,10,12,14 '0xA,&HC,&HE
Data 16,18,20,22,24,26,28,30 '0x10 to 0x1E
Data 0,2,5,7,10,12,15,17 '0xA,&HC,&HF,&H11
Data 20,22,25,27,30,32,35,37 '0x14 to 0x25
Data 0,3,6,9,12,15,18,21 '0xC,&HF,&H12,&H15
Data 24,27,30,33,36,39,42,45 '0x18 to 0x2D
Data 0,3,7,10,14,17,21,24 '0x03 to 0x18
Data 28,31,35,38,42,45,49,52 '0x1C to 0x34
Data 0,252,248,244,240,236,232,228 '0xFC to 0xE4
Data 224,220,216,212,208,204,200,196 '0xE0 to 0xC4
Data 0,252,249,245,242,238,235,231 '0xFC to 0xE7
Data 228,224,221,217,214,210,207,203 '0xE4 to 0xCB
Data 0,253,250,247,244,241,238,235 '0xFD to 0xEB
Data 232,229,226,223,220,217,214,211 '0xE8 to 0xD3
Data 0,253,251,248,246,243,241,238 '0xFD to 0xEE
Data 236,233,231,228,226,223,221,218 '0xEC to 0xDA
Data 0,254,252,250,248,246,244,242 '0xFE to 0xF2
Data 240,238,236,234,232,230,228,226 '0xF0 to 0xE2
Data 0,254,253,251,250,248,247,245 '0xFE to 0xF5
Data 244,242,241,239,238,236,235,233 '0xF4 to 0xE9
Data 0,255,254,253,252,251,250,249 '0xFF to 0xF9
Data 248,247,246,245,244,243,242,241 '0xF8 to 0xF1
Data 0,255,255,254,254,253,253,252 '0xFF to 0xFC
Data 252,251,251,250,250,249,249,248 '0xFC to 0xF8
For iIndex = 0 To 255
Read arrMultTable(iIndex)
Next iIndex
'END PART 3 (Comment in original file)
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
'Converted from render_tabs.h.4.txt
ReDim arrSampleTable(0 To 1279) As _Byte '0x500 = 1280
' Initialize the sample table
' SAMPLE DATA
Restore SampleTableData
For iIndex = 0 To 1279
Read arrSampleTable(iIndex)
Next iIndex
SampleTableData:
' 00
Data &H38,&H84,&H6B,&H19,&HC6,&H63,&H18,&H86,&H73,&H98,&HC6,&HB1,&H1C,&HCA,&H31,&H8C,&HC7,&H31,&H88,&HC2,&H30,&H98,&H46,&H31,&H18,&HC6,&H35,&HC,&HCA,&H31,&HC,&HC6
' 20
Data &H21,&H10,&H24,&H69,&H12,&HC2,&H31,&H14,&HC4,&H71,&H08,&H4A,&H22,&H49,&HAB,&H6A,&HA8,&HAC,&H49,&H51,&H32,&HD5,&H52,&H88,&H93,&H6C,&H94,&H22,&H15,&H54,&HD2,&H25
' 40
Data &H96,&HD4,&H50,&HA5,&H46,&H21,&H08,&H85,&H6B,&H18,&HC4,&H63,&H10,&HCE,&H6B,&H18,&H8C,&H71,&H19,&H8C,&H63,&H35,&HC,&HC6,&H33,&H99,&HCC,&H6C,&HB5,&H4E,&HA2,&H99
' 60
Data &H46,&H21,&H28,&H82,&H95,&H2E,&HE3,&H30,&H9C,&HC5,&H30,&H9C,&HA2,&HB1,&H9C,&H67,&H31,&H88,&H66,&H59,&H2C,&H53,&H18,&H84,&H67,&H50,&HCA,&HE3,&HA,&HAC,&HAB,&H30
' 80
Data &HAC,&H62,&H30,&H8C,&H63,&H10,&H94,&H62,&HB1,&H8C,&H82,&H28,&H96,&H33,&H98,&HD6,&HB5,&H4C,&H62,&H29,&HA5,&H4A,&HB5,&H9C,&HC6,&H31,&H14,&HD6,&H38,&H9C,&H4B,&HB4
' A0
Data &H86,&H65,&H18,&HAE,&H67,&H1C,&HA6,&H63,&H19,&H96,&H23,&H19,&H84,&H13,&H08,&HA6,&H52,&HAC,&HCA,&H22,&H89,&H6E,&HAB,&H19,&H8C,&H62,&H34,&HC4,&H62,&H19,&H86,&H63
' C0
Data &H18,&HC4,&H23,&H58,&HD6,&HA3,&H50,&H42,&H54,&H4A,&HAD,&H4A,&H25,&H11,&H6B,&H64,&H89,&H4A,&H63,&H39,&H8A,&H23,&H31,&H2A,&HEA,&HA2,&HA9,&H44,&HC5,&H12,&HCD,&H42
' E0
Data &H34,&H8C,&H62,&H18,&H8C,&H63,&H11,&H48,&H66,&H31,&H9D,&H44,&H33,&H1D,&H46,&H31,&H9C,&HC6,&HB1,&HC,&HCD,&H32,&H88,&HC4,&H73,&H18,&H86,&H73,&H08,&HD6,&H63,&H58
' 100
Data &H07,&H81,&HE0,&HF0,&H3C,&H07,&H87,&H90,&H3C,&H7C,&HF,&HC7,&HC0,&HC0,&HF0,&H7C,&H1E,&H07,&H80,&H80,&H00,&H1C,&H78,&H70,&HF1,&HC7,&H1F,&HC0,&HC,&HFE,&H1C,&H1F
' 120
Data &H1F,&HE,&HA,&H7A,&HC0,&H71,&HF2,&H83,&H8F,&H03,&HF,&HF,&HC,&H00,&H79,&HF8,&H61,&HE0,&H43,&HF,&H83,&HE7,&H18,&HF9,&HC1,&H13,&HDA,&HE9,&H63,&H8F,&HF,&H83
' 140
Data &H83,&H87,&HC3,&H1F,&H3C,&H70,&HF0,&HE1,&HE1,&HE3,&H87,&HB8,&H71,&HE,&H20,&HE3,&H8D,&H48,&H78,&H1C,&H93,&H87,&H30,&HE1,&HC1,&HC1,&HE4,&H78,&H21,&H83,&H83,&HC3
' 160
Data &H87,&H06,&H39,&HE5,&HC3,&H87,&H07,&HE,&H1C,&H1C,&H70,&HF4,&H71,&H9C,&H60,&H36,&H32,&HC3,&H1E,&H3C,&HF3,&H8F,&HE,&H3C,&H70,&HE3,&HC7,&H8F,&HF,&HF,&HE,&H3C
' 180
Data &H78,&HF0,&HE3,&H87,&H06,&HF0,&HE3,&H07,&HC1,&H99,&H87,&HF,&H18,&H78,&H70,&H70,&HFC,&HF3,&H10,&HB1,&H8C,&H8C,&H31,&H7C,&H70,&HE1,&H86,&H3C,&H64,&H6C,&HB0,&HE1
' 1A0
Data &HE3,&HF,&H23,&H8F,&HF,&H1E,&H3E,&H38,&H3C,&H38,&H7B,&H8F,&H07,&HE,&H3C,&HF4,&H17,&H1E,&H3C,&H78,&HF2,&H9E,&H72,&H49,&HE3,&H25,&H36,&H38,&H58,&H39,&HE2,&HDE
' 1C0
Data &H3C,&H78,&H78,&HE1,&HC7,&H61,&HE1,&HE1,&HB0,&HF0,&HF0,&HC3,&HC7,&HE,&H38,&HC0,&HF0,&HCE,&H73,&H73,&H18,&H34,&HB0,&HE1,&HC7,&H8E,&H1C,&H3C,&HF8,&H38,&HF0,&HE1
' 1E0
Data &HC1,&H8B,&H86,&H8F,&H1C,&H78,&H70,&HF0,&H78,&HAC,&HB1,&H8F,&H39,&H31,&HDB,&H38,&H61,&HC3,&HE,&HE,&H38,&H78,&H73,&H17,&H1E,&H39,&H1E,&H38,&H64,&HE1,&HF1,&HC1
' 200
Data &H4E,&HF,&H40,&HA2,&H02,&HC5,&H8F,&H81,&HA1,&HFC,&H12,&H08,&H64,&HE0,&H3C,&H22,&HE0,&H45,&H07,&H8E,&HC,&H32,&H90,&HF0,&H1F,&H20,&H49,&HE0,&HF8,&HC,&H60,&HF0
' 220
Data &H17,&H1A,&H41,&HAA,&HA4,&HD0,&H8D,&H12,&H82,&H1E,&H1E,&H03,&HF8,&H3E,&H03,&HC,&H73,&H80,&H70,&H44,&H26,&H03,&H24,&HE1,&H3E,&H04,&H4E,&H04,&H1C,&HC1,&H09,&HCC
' 240
Data &H9E,&H90,&H21,&H07,&H90,&H43,&H64,&HC0,&HF,&HC6,&H90,&H9C,&HC1,&H5B,&H03,&HE2,&H1D,&H81,&HE0,&H5E,&H1D,&H03,&H84,&HB8,&H2C,&HF,&H80,&HB1,&H83,&HE0,&H30,&H41
' 260
Data &H1E,&H43,&H89,&H83,&H50,&HFC,&H24,&H2E,&H13,&H83,&HF1,&H7C,&H4C,&H2C,&HC9,&HD,&H83,&HB0,&HB5,&H82,&HE4,&HE8,&H06,&H9C,&H07,&HA0,&H99,&H1D,&H07,&H3E,&H82,&H8F
' 280
Data &H70,&H30,&H74,&H40,&HCA,&H10,&HE4,&HE8,&HF,&H92,&H14,&H3F,&H06,&HF8,&H84,&H88,&H43,&H81,&HA,&H34,&H39,&H41,&HC6,&HE3,&H1C,&H47,&H03,&HB0,&HB8,&H13,&HA,&HC2
' 2A0
Data &H64,&HF8,&H18,&HF9,&H60,&HB3,&HC0,&H65,&H20,&H60,&HA6,&H8C,&HC3,&H81,&H20,&H30,&H26,&H1E,&H1C,&H38,&HD3,&H01,&HB0,&H26,&H40,&HF4,&HB,&HC3,&H42,&H1F,&H85,&H32
' 2C0
Data &H26,&H60,&H40,&HC9,&HCB,&H01,&HEC,&H11,&H28,&H40,&HFA,&H04,&H34,&HE0,&H70,&H4C,&H8C,&H1D,&H07,&H69,&H03,&H16,&HC8,&H04,&H23,&HE8,&HC6,&H9A,&HB,&H1A,&H03,&HE0
' 2E0
Data &H76,&H06,&H05,&HCF,&H1E,&HBC,&H58,&H31,&H71,&H66,&H00,&HF8,&H3F,&H04,&HFC,&HC,&H74,&H27,&H8A,&H80,&H71,&HC2,&H3A,&H26,&H06,&HC0,&H1F,&H05,&HF,&H98,&H40,&HAE
' 300
Data &H01,&H7F,&HC0,&H07,&HFF,&H00,&HE,&HFE,&H00,&H03,&HDF,&H80,&H03,&HEF,&H80,&H1B,&HF1,&HC2,&H00,&HE7,&HE0,&H18,&HFC,&HE0,&H21,&HFC,&H80,&H3C,&HFC,&H40,&HE,&H7E
' 320
Data &H00,&H3F,&H3E,&H00,&HF,&HFE,&H00,&H1F,&HFF,&H00,&H3E,&HF0,&H07,&HFC,&H00,&H7E,&H10,&H3F,&HFF,&H00,&H3F,&H38,&HE,&H7C,&H01,&H87,&HC,&HFC,&HC7,&H00,&H3E,&H04
' 340
Data &HF,&H3E,&H1F,&HF,&HF,&H1F,&HF,&H02,&H83,&H87,&HCF,&H03,&H87,&HF,&H3F,&HC0,&H07,&H9E,&H60,&H3F,&HC0,&H03,&HFE,&H00,&H3F,&HE0,&H77,&HE1,&HC0,&HFE,&HE0,&HC3
' 360
Data &HE0,&H01,&HDF,&HF8,&H03,&H07,&H00,&H7E,&H70,&H00,&H7C,&H38,&H18,&HFE,&HC,&H1E,&H78,&H1C,&H7C,&H3E,&HE,&H1F,&H1E,&H1E,&H3E,&H00,&H7F,&H83,&H07,&HDB,&H87,&H83
' 380
Data &H07,&HC7,&H07,&H10,&H71,&HFF,&H00,&H3F,&HE2,&H01,&HE0,&HC1,&HC3,&HE1,&H00,&H7F,&HC0,&H05,&HF0,&H20,&HF8,&HF0,&H70,&HFE,&H78,&H79,&HF8,&H02,&H3F,&HC,&H8F,&H03
' 3a0
Data &HF,&H9F,&HE0,&HC1,&HC7,&H87,&H03,&HC3,&HC3,&HB0,&HE1,&HE1,&HC1,&HE3,&HE0,&H71,&HF0,&H00,&HFC,&H70,&H7C,&HC,&H3E,&H38,&HE,&H1C,&H70,&HC3,&HC7,&H03,&H81,&HC1
' 3c0
Data &HC7,&HE7,&H00,&HF,&HC7,&H87,&H19,&H09,&HEF,&HC4,&H33,&HE0,&HC1,&HFC,&HF8,&H70,&HF0,&H78,&HF8,&HF0,&H61,&HC7,&H00,&H1F,&HF8,&H01,&H7C,&HF8,&HF0,&H78,&H70,&H3C
' 3e0
Data &H7C,&HCE,&HE,&H21,&H83,&HCF,&H08,&H07,&H8F,&H08,&HC1,&H87,&H8F,&H80,&HC7,&HE3,&H00,&H07,&HF8,&HE0,&HEF,&H00,&H39,&HF7,&H80,&HE,&HF8,&HE1,&HE3,&HF8,&H21,&H9F
' 400
Data &HC0,&HFF,&H03,&HF8,&H07,&HC0,&H1F,&HF8,&HC4,&H04,&HFC,&HC4,&HC1,&HBC,&H87,&HF0,&HF,&HC0,&H7F,&H05,&HE0,&H25,&HEC,&HC0,&H3E,&H84,&H47,&HF0,&H8E,&H03,&HF8,&H03
' 420
Data &HFB,&HC0,&H19,&HF8,&H07,&H9C,&HC,&H17,&HF8,&H07,&HE0,&H1F,&HA1,&HFC,&HF,&HFC,&H01,&HF0,&H3F,&H00,&HFE,&H03,&HF0,&H1F,&H00,&HFD,&H00,&HFF,&H88,&HD,&HF9,&H01
' 440
Data &HFF,&H00,&H70,&H07,&HC0,&H3E,&H42,&HF3,&HD,&HC4,&H7F,&H80,&HFC,&H07,&HF0,&H5E,&HC0,&H3F,&H00,&H78,&H3F,&H81,&HFF,&H01,&HF8,&H01,&HC3,&HE8,&HC,&HE4,&H64,&H8F
' 460
Data &HE4,&HF,&HF0,&H07,&HF0,&HC2,&H1F,&H00,&H7F,&HC0,&H6F,&H80,&H7E,&H03,&HF8,&H07,&HF0,&H3F,&HC0,&H78,&HF,&H82,&H07,&HFE,&H22,&H77,&H70,&H02,&H76,&H03,&HFE,&H00
' 480
Data &HFE,&H67,&H00,&H7C,&HC7,&HF1,&H8E,&HC6,&H3B,&HE0,&H3F,&H84,&HF3,&H19,&HD8,&H03,&H99,&HFC,&H09,&HB8,&HF,&HF8,&H00,&H9D,&H24,&H61,&HF9,&HD,&H00,&HFD,&H03,&HF0
' 4a0
Data &H1F,&H90,&H3F,&H01,&HF8,&H1F,&HD0,&HF,&HF8,&H37,&H01,&HF8,&H07,&HF0,&HF,&HC0,&H3F,&H00,&HFE,&H03,&HF8,&HF,&HC0,&H3F,&H00,&HFA,&H03,&HF0,&HF,&H80,&HFF,&H01
' 4c0
Data &HB8,&H07,&HF0,&H01,&HFC,&H01,&HBC,&H80,&H13,&H1E,&H00,&H7F,&HE1,&H40,&H7F,&HA0,&H7F,&HB0,&H00,&H3F,&HC0,&H1F,&HC0,&H38,&HF,&HF0,&H1F,&H80,&HFF,&H01,&HFC,&H03
' 4e0
Data &HF1,&H7E,&H01,&HFE,&H01,&HF0,&HFF,&H00,&H7F,&HC0,&H1D,&H07,&HF0,&HF,&HC0,&H7E,&H06,&HE0,&H07,&HE0,&HF,&HF8,&H06,&HC1,&HFE,&H01,&HFC,&H03,&HE0,&HF,&H00,&HFC
' END PART 4
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' END render_tabs.h
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' BEGIN render.c
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' Initialize arrays
' mouth formants (F1) 5..29
Data 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
For iIndex = 5 To 29
Read arrMouthFormants5_29(iIndex)
Next iIndex
' throat formants (F2) 5..29
Data 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
For iIndex = 5 To 29
Read arrThroatFormants5_29(iIndex)
Next iIndex
' formant 1 frequencies (mouth) 48..53
Data 19,27,21,27,18,13
For iIndex = 0 To 5
Read arrMouthFormants48_53(iIndex)
Next iIndex
' formant 2 frequencies (throat) 48..53
Data 72,39,31,43,30,34
For iIndex = 0 To 5
Read arrThroatFormants48_53(iIndex)
Next iIndex
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' END render.c
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' *** HERE IS WHERE THE MAIN EXECUTION (MENU ETC.) WOULD GO #MAIN
' For now we'll hardcode the test routines to run...
TestHello
TestPhonemes
' *** END MAIN EXECUTION @MAIN
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' Begin test_hello.c
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' Main program
Sub TestHello
Dim in$
Input "Enter text to speak (all caps, include phonemes like '[')", in$
' Set the input (assuming SetInput$ function exists)
' in$ = "HELLO WORLD [" ' Hardcoded input replaced by user input
' SetInput in$
' Simulate SetInput (replace with actual QB64 implementation if available)
Print "Setting input to: "; in$
' Run SAMMain (assuming SAMMain function exists and returns 0 for false, non-zero for true)
' samResult = SAMMain()
' IF samResult = 0 THEN
' PRINT "SAMMain failed"
' SYSTEM
' END IF
'Simulate SAMMain (replace with actual QB64 implementation)
Print "Simulating SAMMain..."
samResult = -1 ' Simulate success
If samResult = 0 Then
Print "SAMMain failed"
End
End If
' Get the buffer and its length (assuming these functions exist)
' buffer$ = GetBuffer$()
' bufferLength = GetBufferLength()
'Simulate GetBuffer and GetBufferLength
buffer$ = "Simulated speech data"
bufferLength = 1000
' Call WriteWav
wavResult = WriteWav(buffer$, bufferLength \ 50) ' Integer division in QB64 is '\'
Print "WriteWav returned: "; wavResult
Print "Done!"
Sleep
'END
End Sub ' TestHello
' Stub for WriteWav (since the C version just returns 0)
Function WriteWav% (buffer As String, bufferlength As Integer)
WriteWav = 0
End Function
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' End test_hello.c
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' Begin test_phonemes.c
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Sub TestPhonemes
'Constants
Const END_MARKER = "0,0" ' Using a string to represent the end marker
Const C_SIZE = 1024
'Test State
Type TestState
fails As Long
passes As Long
End Type
'Data Structure
Type TestCase
testInput As String
expected As String
End Type
Dim sTemp As String ' * C_SIZE ' Fixed-length string
Dim test_case(1 To 20) As TestCase ' Adjust size as needed based on your test data
Dim test_state As TestState
Dim state As TestState
Dim iIndex As Integer
Dim bResult As Integer
' *** NOTE
' PROBABLY NEED TO CALL Init BEFORE ANYTHING ?
' Initialize test cases (manually, since we can't directly translate C's array initialization)
'------------------------------------------------------------------------------------------
' Manually populate the test cases. This is tedious, but necessary in QB64.
' Note: The index in QB64 starts at 1 by default, so adjust accordingly.
' Also, QB64 doesn't have direct equivalent for C's string literals with embedded newlines.
' We'll use multiline strings (might need QB64PE specific syntax) or concatenation.
test_case(1).testInput = "HELLO"
test_case(1).expected = " /HEHLOW"
test_case(2).testInput = "WIZARD"
test_case(2).expected = " WIHZAA5RD"
test_case(3).testInput = "TWO THINGS"
test_case(3).expected = " TUW THIHNXZ"
test_case(4).testInput = "ANOTHER TRAVELER"
test_case(4).expected = " AENAH5DHER TRAEVIY4LER"
test_case(5).testInput = "HELLO, MY NAME IS SAM."
test_case(5).expected = " /HEHLOW, MAY NEYM IHZ SAEM."
test_case(6).testInput = "THE SKY ABOVE THE PORT WAS THE COLOR OF TELEVISION, TUNED TO A DEAD CHANNEL."
test_case(6).expected = " DHAX SKAY AEBAH4V DHAX PAORT WAHZ DHAX KAALER AHV TEHLEHVIHZHUN, TUWND TUX AH DEHDCHAENEHL."
test_case(7).testInput = "IT'S NOT LIKE I'M USING, CASE HEARD SOMEONE SAY, AS HE SHOULDERED HIS WAY THROUGH THE CROWD AROUND THE DOOR OF THE CHAT."
test_case(7).expected = " IHTS NAAT LAY5K IHM YUWZIHNX, KEY4S /HIY5RD SAHMWAHN SEY5, AEZ /HIY SHUH5DIY4RD /HIHSWEY5 THRUW4 DHAX KROWD AXRAWND DHAX DOH5R AHV DHAX CHAET."
test_case(8).testInput = "ITS LIKE MY BODYS DEVELOPED THIS MASSIVE DRUG DEFICIENCY."
test_case(8).expected = " IHTS LAY5K MAY BAADIYS DIHVEHLOW5PT DHIHS MAESIHV DRAHG DIHFIHSHEHNSIY."
test_case(9).testInput = "IT WAS A SPRAWL VOICE AND A SPRAWL JOKE."
test_case(9).expected = " IHT WAHZ AH SPRAO5L VOY5S AEND AH SPRAO5L JOW5K."
test_case(10).testInput = "THE CHATSUBO WAS A BAR FOR PROFESSIONAL EXPATRIATES YOU COULD DRINK THERE FOR A WEEK AND NEVER HEAR TWO WORDS IN JAPANESE."
test_case(10).expected = " DHAX CHAETSUWBOW WAHZ AH BAA5R FAOR PROW5FEHSHUNUL EHKSPAETRIHEYTS YUW KUH5D DRIHNXK DHEHRFER AH WIY4K AEND NEH4VER /HIY5R TUW WERDZ IHN JAEPEYNIY4Z."
test_case(11).testInput = "RATZ WAS TENDING BAR, HIS PROSTHETIC ARM JERKING MONOTONOUSLY AS HE FILLED A TRAY OF GLASSES WITH DRAFT KIRIN."
test_case(11).expected = " RAETZ WAHZ TEHNDIHNX BAA5R, /HIHZ PROWSTHEHTIHK AA5RM JERKIHNX MAHNAATUNAXSLIY AEZ /HIY FIHLEHDAH TREY5 AHV GLAESIHZ WIHTH"
test_case(12).testInput = "HE SAW CASE AND SMILED, HIS TEETH A WEB WORK OF EAST EUROPEAN STEEL AND BROWN DECAY."
test_case(12).expected = " /HIY SAO5 KEY4S AEND SMAY5LD, /HIHZ TIY4TH AH WEHB WERK AHV IY5ST YUW5RAAPIY5N STIY4L AENDBROWN DIHKEY5."
test_case(13).testInput = "CASE FOUND A PLACE AT THE BAR, BETWEEN THE UNLIKELY TAN ON ONE OF LONNY ZONE'S WHORES AND THE CRISP NAVAL UNIFORM OF A TALL AFRICAN WHOSE CHEEKBONES WERE RIDGED WITH PRECISE ROWS OF TRIBAL SCARS."
test_case(13).expected = " KEY4S FAWND AH PLEYS AET DHAX BAA5R, BEHTWIY4N DHIY AHNLIHKLIY TAEN AAN WAHN AHV LAHNIYZUNEHS /HUWRZ AEND DHAX KRIHSP NAEVUL YUWNIHFAORM AHV AH TAOL AEFRIHKAEN /HUWZEHKIY4KBOW5NZ WER RIHDJD WIHTH PREHSAYZ ROWZ AHV TRIHBUL SKAA5RZ."
test_case(14).testInput = "WAGE WAS IN HERE EARLY, WITH TWO JOE BOYS, RATZ SAID, SHOVING A DRAFT ACROSS THE BAR WITH HIS GOOD HAND."
test_case(14).expected = " WEYJ WAHZ IHN /HIYR ER5LIY, WIHTH TUW JOW BOYZ, RAETZ SEHD, SHAH4VIHNX AH DRAEFTAEKRAO5S DHAX BAA5R WIHTH /HIHZ GUH5D /HAEND."
test_case(15).testInput = "MAYBE SOME BUSINESS WITH YOU, CASE. CASE SHRUGGED."
test_case(15).expected = " MEY5B SAHM BIH4ZIHNEHS WIHTH YUW, KEY4S. KEY4S SHRAH5GD."
test_case(16).testInput = "THE GIRL TO HIS RIGHT GIGGLED AND NUDGED HIM."
test_case(16).expected = " DHAX GERL TUX /HIHZ RAY4T GIHGULD AEND NAH5DJD /HIHM."
' Assuming END is a sentinel value, find the end of the data.
last_test_case = 16 'Hardcoded for now, find a better way if possible
'Main Program
'No direct equivalent to C's main, so the following code is the main logic
For iIndex = 1 To last_test_case
' call sam to process input, store in sTemp
' MOCKING sam and reciter calls for now
sTemp = "MOCKED OUTPUT FOR: " + test_case(iIndex).testInput ' Replace with actual SAM and reciter calls
'trim ' Remove any trailing garbage from sTemp
sTemp = _Trim$(sTemp)
If compare%(sTemp, test_case(iIndex).expected) Then
test_state.passes = test_state.passes + 1
Print "PASS: "; test_case(iIndex).testInput
Else
test_state.fails = test_state.fails + 1
Print "FAIL: "; test_case(iIndex).testInput
Print " Expected: "; test_case(iIndex).expected
Print " Actual: "; sTemp
End If
Next iIndex
Print
Print "--- SUMMARY ---"
Print "Passes: "; test_state.passes
Print "Fails: "; test_state.fails
'END 'End of main program
' Main program starts here
' Initialize state
state.fails = 0
state.passes = 0
' Verify reciter tables
ReciterVerify
' Test cases (need to be adapted based on how test_case is structured)
' Example data - adjust as needed:
Data "test1","expected1","test2","expected2",""
Read test_case1$, test_case2$
Do While Len(test_case1$) > 0
If try_test$(test_case1$, test_case2$) = "0" Then
Print "x";
state.fails = state.fails + 1
Else
Print ".";
state.passes = state.passes + 1
End If
Read test_case1$, test_case2$
Loop
' Input test files (assuming SAM_TEST_DIR is a constant)
' *** NOT SURE WHAT file_test$ IS OR DOES ??? ***
bResult = file_test%(m_ProgramPath$ + "words.txt", state) ' Need to adjust path as needed
If bResult = _FALSE Then Print "File " + Chr$(34) + "words.txt" + Chr$(34) + " not found."
bResult = file_test%(m_ProgramPath$ + "sentences.txt", state) ' Need to adjust path as needed
If bResult = _FALSE Then Print "File " + Chr$(34) + "sentences.txt" + Chr$(34) + " not found."
' Print summary
Print
Print "total : "; state.fails + state.passes
Print "failed: "; state.fails
Print "passed: "; state.passes
If state.fails > 0 Then
Input "Press Enter to continue", a$
End If
'SYSTEM ' End program
End Sub ' TestPhonemes
'Function Definitions
Function compare% (sVal1 As String, sVal2 As String)
Dim iPos1 As Integer
Dim iPos2 As Integer
Dim iLen1 As Integer
Dim iLen2 As Integer
compare% = _TRUE ' Default to true
iLen1 = Len(sVal1)
iLen2 = Len(sVal2)
iPos1 = 1
iPos2 = 1
Do While iPos1 <= iLen1 And iPos2 <= iLen2
If Mid$(sVal2, iPos2, 1) > Chr$(127) Then 'Simulate checking for 0x80 (not directly possible)
Exit Do
End If
If Mid$(sVal1, iPos1, 1) <> Mid$(sVal2, iPos2, 1) Then
compare% = _FALSE
Exit Function
End If
iPos1 = iPos1 + 1
iPos2 = iPos2 + 1
Loop
If iPos1 <= iLen1 Or (iPos2 <= iLen2 And Asc(Mid$(sVal2, iPos2, 1)) < 128) Then ' Check if either string has leftover
compare% = _FALSE
End If
End Function ' compare%
'SUB trim
' FOR i = 1 TO LEN(temp)
' IF ASC(MID$(temp, i, 1)) > 127 THEN 'Simulate checking for 0x80
' temp = LEFT$(temp, i - 1)
' EXIT SUB
' END IF
' NEXT i
'END SUB
' Function: try_test
' Tests a given input string against an expected phoneme output.
' Parameters:
' in$ - The input string to convert to phonemes.
' match$ - The expected phoneme output.
' Returns:
' 1 if the actual output matches the expected output, 0 otherwise.
Function try_test$ (in$, match$)
' Assuming C_SIZE is defined as a constant elsewhere (e.g., CONST C_SIZE = 256)
Dim sTemp As String ' * 256 ' Adjust size as needed, using a fixed-length string
sTemp = String$(256, 128) ' Initialize with ASCII 128 (0x80) - QBasic/QB64 doesn't have memset like C
sTemp = in$
sTemp = sTemp + "["
'max_size = 250
If TextToPhonemes(sTemp, 250) < 1 Then
try_test$ = "0"
Exit Function
End If
sTemp = Left$(sTemp, 255) ' QB64 string length is limited; ensure null termination isn't an issue
sTemp = _Trim$(sTemp) ' Need to implement a trim$ function in QB64
'IF StrComp(match$, sTemp, 0) <> 0 THEN
If compare%(match$, sTemp) <> 0 Then
Print
Print "sent"
Print "'" + in$ + "'"
Print "expected"
Print "'" + match$ + "'"
Print "got"
Print "'" + sTemp + "'"
try_test$ = "0"
Exit Function
End If
try_test$ = "1"
End Function ' try_test$
' Function: read_line
' Reads a line from a file.
' Parameters:
' fd - The file handle.
' dst$ - The string to store the read line.
' max_len - The maximum number of characters to read. Not directly used in QB64 implementation
' Returns:
' The length of the read line.
Function read_line% (fd As Long, dst$) ' QB64 doesn't have size_t, using INTEGER
Dim ptr As Long
Dim size As Integer
Dim ch As String * 1
size = 0
Do
If EOF(fd) Then
read_line% = 0
Exit Function
End If
Get #fd, , ch
If Len(ch) = 0 Then
read_line% = 0
Exit Function
End If
If ch = Chr$(10) Then
Exit Do
End If
If ch = Chr$(13) Then
Else
dst$ = dst$ + UCase$(ch) ' QB64 UCASE$ for toupper
size = size + 1
End If
Loop
read_line% = size
End Function
' Function: file_test
' Tests phoneme conversion on lines from a file.
' Parameters:
' path$ - The path to the test file.
' state - A structure to track test results. Must be adapted for QB64
' Returns:
' 1 if the test completes successfully, 0 otherwise.
Function file_test% (path$, state As TestState)
Dim fd As Long
Dim sTemp1 As String
Dim sTemp2 As String
Dim iLen As Integer
Open path$ For Binary As #fd
If LOF(fd) = 0 Then ' Instead of fd = 0
file_test% = _FALSE
Exit Function
End If
Do
iLen = read_line%(fd, sTemp1)
If iLen = 0 Then
Exit Do
End If
sTemp1 = sTemp1 + "["
sTemp2 = sTemp1
'max_size = 250
If TextToPhonemes(sTemp1, 250) > 0 Then
Print ".";
state.passes = state.passes + 1
Else
Print "x";
Print
Print sTemp2
state.fails = state.fails + 1
End If
sTemp1 = "" ' Reset sTemp1 for next loop
Loop
Close #fd
file_test% = _TRUE
End Function ' file_test%
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' End test_phonemes.c
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' BEGIN sam.c
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Sub Init
Dim i As Integer
Call SetMouthThroat(mouth, throat)
bufferPos = 0
'Allocate memory - QB64 uses _NEW for this (similar to malloc)
'Note: _NEW returns a pointer, and we need to allocate enough space for bytes (_BYTE)
'TODO: do we need to do _MEM stuff here?
'buffer = _NEW _BYTE[22050 * 10]
'The original C code had commented-out assignments to memory locations.
'It's likely these are related to how the original C code interfaced with memory.
'We'll leave them commented out in QB64, as we don't have the context to translate them directly.
'If you have more information on what these memory locations represent, we can refine this.
'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 To 255
arrStress1(i) = 0
arrPhonemeLength(i) = 0
Next i
For i = 0 To 59
arrPhoIndexOutput(i) = 0
arrStressOutput(i) = 0
arrPhoLengthOutput(i) = 0
Next i
arrPhonemeIndex(255) = 255 'Prevent buffer overflow
End Sub
Function Main% ()
Init
arrPhonemeIndex(255) = 32 '//to prevent buffer overflow
If Parser1% = _FALSE Then
Main% = _FALSE
Exit Function
End If
If (bDebug) Then
PrintPhonemes arrPhonemeIndex(), arrPhonemeLength(), arrStress1()
End If
Parser2
CopyStress
SetPhonemeLength
AdjustLengths
Code41240
Do
A = arrPhonemeIndex(X)
If (A > 80) Then
arrPhonemeIndex(X) = 255
Exit Do '// error: delete all behind it
End If
X = X + 1
Loop Until X = 0
'//pos39848:
InsertBreath
'//mem(40158) = 255
If (bDebug) Then
PrintPhonemes arrPhonemeIndex(), arrPhonemeLength(), arrStress1()
End If
PrepareOutput
Main% = _TRUE
End Function ' Main
Sub SetInput (inputString As String)
'Converts a QB64 String to a _BYTE array
Dim i As Integer
Dim l As Integer
l = Len(inputString)
If l > 254 Then l = 254
For i = 1 To l
arrInput1(i - 1) = Asc(Mid$(inputString, i, 1))
Next i
arrInput1(l) = 0 'Null terminate (C-style strings)
End Sub
Sub SetSpeed (inputSpeed As _Byte)
speed = inputSpeed
End Sub
Sub SetPitch (inputPitch As _Byte)
pitch = inputPitch
End Sub
Sub SetMouth (inputMouth As _Byte)
mouth = inputMouth
End Sub
Sub SetThroat (inputThroat As _Byte)
throat = inputThroat
End Sub
Sub EnableSingmode
singmode = 1
End Sub
Function GetBuffer$ ()
'Need to convert the _OFFSET to a QB64 String
Dim result As String
If buffer = 0 Then Exit Function 'Handle null pointer
For i = 0 To bufferPos - 1
result = result + Chr$(buffer(i))
Next i
GetBuffer$ = result
End Function
Function GetBufferLength% ()
GetBufferLength = bufferPos
End Function
Sub PrepareOutput ()
Dim iTemp As Integer
A = 0
X = 0
Y = 0
'//pos48551:
Do While -1 '// Infinite loop, equivalent to while(1)
A = arrPhonemeIndex(X)
If (A = 255) Then
A = 255
arrPhoIndexOutput(Y) = 255
Render
Exit Sub
End If
If (A = 254) Then
X = X + 1
iTemp = X '// Local variable to mimic C's temp
'//mem(48546) = X
arrPhoIndexOutput(Y) = 255
Render
'//X = mem(48546)
X = iTemp
Y = 0
_Continue
End If
If (A = 0) Then
X = X + 1
_Continue
End If
arrPhoIndexOutput(Y) = A
arrPhoLengthOutput(Y) = arrPhonemeLength(X)
arrStressOutput(Y) = arrStress1(X)
X = X + 1
Y = Y + 1
Loop
End Sub ' PrepareOutput
Sub InsertBreath ()
Dim mem54 As _Byte
Dim mem55 As _Byte
Dim index As _Byte 'variable Y
Dim mem66 As _Byte
mem54 = 255
X = X + 1
mem55 = 0
mem66 = 0
Do
'pos48440:
X = mem66
index = arrPhonemeIndex(X)
If index = 255 Then
Exit Sub
End If
mem55 = mem55 + arrPhonemeLength(X)
If mem55 < 232 Then
If index <> 254 Then ' ML : Prevents an index out of bounds problem
A = arrFlags2(index) And 1
If A <> 0 Then
X = X + 1
mem55 = 0
Call Insert(X, 254, mem59, 0)
mem66 = mem66 + 1
mem66 = mem66 + 1
_Continue
End If
End If
If index = 0 Then
mem54 = X
End If
mem66 = mem66 + 1
Else
X = mem54
arrPhonemeIndex(X) = 31 ' 'Q*' glottal stop
arrPhonemeLength(X) = 4
arrStress1(X) = 0
X = X + 1
mem55 = 0
Call Insert(X, 254, mem59, 0)
X = X + 1
mem66 = X
End If
Loop
End Sub ' InsertBreath
Sub CopyStress ()
' loop thought all the phonemes to be output
Dim iPos As Integer ' _BYTE
iPos = 0 'mem66
Do
' get the phomene
Y = arrPhonemeIndex(iPos)
' exit at end of buffer
If Y = 255 Then
Exit Sub
End If
' if CONSONANT_FLAG set, skip - only vowels get stress
If (arrFlags1(Y) And 64) = 0 Then
iPos = iPos + 1
_Continue
End If
' get the next phoneme
Y = arrPhonemeIndex(iPos + 1)
If Y = 255 Then 'prevent buffer overflow
iPos = iPos + 1
_Continue
Else
' if the following phoneme is a vowel, skip
If (arrFlags1(Y) And 128) = 0 Then
iPos = iPos + 1
_Continue
End If
End If
' get the stress value at the next position
Y = arrStress1(iPos + 1)
' if next phoneme is not stressed, skip
If Y = 0 Then
iPos = iPos + 1
_Continue
End If
' if next phoneme is not a VOWEL OR ER, skip
If (Y And 128) <> 0 Then
iPos = iPos + 1
_Continue
End If
' copy stress from prior phoneme to this one
arrStress1(iPos) = Y + 1
' advance pointer
iPos = iPos + 1
Loop
End Sub ' CopyStress
Sub Insert (position As _Byte, mem60 As _Byte, mem59 As _Byte, mem58 As _Byte)
Dim i As Integer
For i = 253 To position Step -1 ' ML : always keep last safe-guarding 255
arrPhonemeIndex(i + 1) = arrPhonemeIndex(i)
arrPhonemeLength(i + 1) = arrPhonemeLength(i)
arrStress1(i + 1) = arrStress1(i)
Next i
arrPhonemeIndex(position) = mem60
arrPhonemeLength(position) = mem59
arrStress1(position) = mem58
End Sub ' Insert
'--------------------------------------------------------------------------------------------------------------------
' Parser1 Function
'--------------------------------------------------------------------------------------------------------------------
Function Parser1% ()
Dim iIndex As Integer
Dim sign1 As _Unsigned _Byte
Dim sign2 As _Unsigned _Byte
Dim position As _Unsigned _Byte
position = 0
X = 0
A = 0
Y = 0
' CLEAR THE STRESS TABLE
For iIndex = 0 To 255
arrStress1(iIndex) = 0
Next iIndex
' THIS CODE MATCHES THE PHONEME LETTERS TO THE TABLE
Do
' GET THE FIRST CHARACTER FROM THE PHONEME BUFFER
sign1 = arrInput1(X) ' Assuming arrInput1 is 1-based array
' TEST FOR 155 () END OF LINE MARKER
If sign1 = 155 Then
' MARK ENDPOINT AND RETURN
arrPhonemeIndex(position) = 255
'mark endpoint
' REACHED END OF PHONEMES, SO EXIT
Parser1% = _TRUE ' all ok
Exit Function
End If
' GET THE NEXT CHARACTER FROM THE BUFFER
X = X + 1
sign2 = arrInput1(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
Do
' GET FIRST CHARACTER AT POSITION Y IN signInputTable
' --> should change name to PhonemeNameTable1
A = arrSignInputTable1(Y) ' Assuming arrSignInputTable1 is 0-based
' FIRST CHARACTER MATCHES?
If A = sign1 Then
' GET THE CHARACTER FROM THE PhonemeSecondLetterTable
A = arrSignInputTable2(Y)
' NOT A SPECIAL AND MATCHES SECOND CHARACTER?
If (A <> Asc("*")) And (A = sign2) Then 'QB64 uses ASC() for character to ASCII
' STORE THE INDEX OF THE PHONEME INTO THE phomeneIndexTable
arrPhonemeIndex(position) = Y
' ADVANCE THE POINTER TO THE phonemeIndexTable
position = position + 1
' ADVANCE THE POINTER TO the phonemeInputBuffer
X = X + 1
' CONTINUE PARSING
_Continue
End If
End If
' NO MATCH, TRY TO MATCH ON FIRST CHARACTER TO WILDCARD NAMES (ENDING WITH '*')
' ADVANCE TO THE NEXT POSITION
Y = Y + 1
' IF NOT END OF TABLE, CONTINUE
If Y <> 81 Then
'GOTO pos41095 ' QB64 doesn't encourage GOTO, using DO...LOOP
_Continue
End If
' 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
Do
' DOES THE PHONEME IN THE TABLE END WITH '*'?
If arrSignInputTable2(Y) = Asc("*") Then
' DOES THE FIRST CHARACTER MATCH THE FIRST LETTER OF THE PHONEME
If arrSignInputTable1(Y) = sign1 Then
' SAVE THE POSITION AND MOVE AHEAD
arrPhonemeIndex(position) = Y
' ADVANCE THE POINTER
position = position + 1
' CONTINUE THROUGH THE LOOP
_Continue
End If
End If
Y = Y + 1
If Y <> 81 Then
'GOTO pos41134
_Continue
End If
Loop
'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
Do While (sign1 <> arrStressInputTable(Y)) And (Y > 0)
' DECREMENT INDEX
Y = Y - 1
Loop
' REACHED THE END OF THE SEARCH WITHOUT BREAKING OUT OF LOOP?
If Y = 0 Then
'mem[39444] = X
'41181: JSR 42043 //Error
' FAILED TO MATCH ANYTHING, RETURN 0 ON FAILURE
Parser1% = _FALSE
Exit Function
End If
' SET THE STRESS FOR THE PRIOR PHONEME
arrStress1(position - 1) = Y
Loop
Loop
End Function ' Parser1%
'--------------------------------------------------------------------------------------------------------------------
' SetPhonemeLength Subroutine
'--------------------------------------------------------------------------------------------------------------------
Sub SetPhonemeLength
Dim A As _Unsigned _Byte
Dim position As Integer
position = 0
Do While arrPhonemeIndex(position) <> 255
A = arrStress1(position)
'41218: BMI 41229 ' BMI is Branch if Minus (negative) - QB64 doesn't have direct BMI, emulate with sign check
If (A = 0) Or ((A And 128) <> 0) Then 'bitwise AND to check high bit (sign)
arrPhonemeLength(position) = arrPhoLengthTable(arrPhonemeIndex(position))
Else
arrPhonemeLength(position) = arrPhoStressedLengthTable(arrPhonemeIndex(position))
End If
position = position + 1
Loop
End Sub
'--------------------------------------------------------------------------------------------------------------------
' Code41240 Subroutine
'--------------------------------------------------------------------------------------------------------------------
Sub Code41240
Dim iPos As Integer ' _UNSIGNED _BYTE
iPos = 0
Do While arrPhonemeIndex(iPos) <> 255
Dim index As _Unsigned _Byte 'register AC
X = iPos
index = arrPhonemeIndex(iPos)
If (arrFlags1(index) And 2) = 0 Then ' Bitwise AND
iPos = iPos + 1
_Continue
ElseIf (arrFlags1(index) And 1) = 0 Then ' Bitwise AND
Insert iPos + 1, index + 1, arrPhoLengthTable(index + 1), arrStress1(iPos)
Insert iPos + 2, index + 2, arrPhoLengthTable(index + 2), arrStress1(iPos)
iPos = iPos + 3
_Continue
End If
Do
X = X + 1
A = arrPhonemeIndex(X)
Loop Until A <> 0
If A <> 255 Then
If (arrFlags1(A) And 8) <> 0 Then
iPos = iPos + 1
_Continue
End If
If (A = 36) Or (A = 37) Then
iPos = iPos + 1
_Continue
End If ' '/H' '/X'
End If
Insert iPos + 1, index + 1, arrPhoLengthTable(index + 1), arrStress1(iPos)
Insert iPos + 2, index + 2, arrPhoLengthTable(index + 2), arrStress1(iPos)
iPos = iPos + 3
Loop
End Sub
' BEGIN Parser2 PART 1
Sub Parser2 ()
Dim iPos As Integer
'void Parser2()
' {
' if (debug)
' printf("Parser2\n");
If bDebug Then
Print "Parser2"
End If
' uint8_t pos = 0; //mem66;
iPos = 0
' uint8_t mem58 = 0;
mem58 = 0
' Loop through phonemes
Do
' SET X TO THE CURRENT POSITION
X = iPos ' Assuming X is an integer
' GET THE PHONEME AT THE CURRENT POSITION
A = arrPhonemeIndex(iPos) ' Assuming A and arrPhonemeIndex are integers
' DEBUG: Print phoneme and index
If bDebug And A <> 255 Then
Print X; ": "; arrSignInputTable1(A); arrSignInputTable2(A) ' Assuming arrSignInputTable1 and arrSignInputTable2 are string arrays
End If
' Is phoneme pause?
If A = 0 Then ' Assuming 0 represents a pause
' Move ahead to the
iPos = iPos + 1
_Continue ' QB64 equivalent of continue
End If
' If end of phonemes flag reached, exit routine
If A = 255 Then
Exit Do ' QB64 equivalent of return
End If
' Copy the current phoneme index to Y
Y = A ' Assuming Y is an integer
' Check for DIPHTONG
If (arrFlags1(A) And 16) = 0 Then ' Assuming flags is an integer array
GoTo pos41457
End If
' Not a diphthong. Get the stress
mem58 = arrStress1(iPos) ' Assuming stress is an integer array
' End in IY sound?
A = arrFlags1(Y) And 32
' If ends with IY, use YX, else use WX
If A = 0 Then
A = 20
Else
A = 21
End If ' 'WX' = 20 'YX' = 21
'pos41443:
' Insert at WX or YX following, copying the stress
If bDebug Then
If A = 20 Then
Print "RULE: insert WX following diphtong NOT ending in IY sound"
End If
End If
If bDebug Then
If A = 21 Then
Print "RULE: insert YX following diphtong ending in IY sound"
End If
End If
Insert iPos + 1, A, mem59, mem58 ' Assuming Insert is a SUB and mem59 is an integer
X = iPos
' Jump to ???
GoTo pos41749
pos41457:
' Get phoneme
A = arrPhonemeIndex(X)
' Skip this rule if phoneme is not UL
If A <> 78 Then ' Assuming 78 is the value for UL
GoTo pos41487
End If
' 'UL'
A = 24 ' Assuming 24 is the value for 'L
' 'L' 'change 'UL' to 'AX L'
If bDebug Then
Print "RULE: UL -> AX L"
End If
pos41466:
' Get current phoneme stress
mem58 = arrStress1(X)
' Change UL to AX
arrPhonemeIndex(X) = 13 ' Assuming 13 is the value for AX
' 'AX'
' Perform insert. Note code below may jump up here with different values
Insert X + 1, A, mem59, mem58
iPos = iPos + 1
' Move to next phoneme
_Continue
pos41487:
' Skip rule if phoneme != UM
If A <> 79 Then ' Assuming 79 is the value for UM
GoTo pos41495
End If
' 'UM'
' Jump up to branch - replaces current phoneme with AX and continues
A = 27 ' Assuming 27 is the value for M
' 'M' 'change 'UM' to 'AX M'
If bDebug Then
Print "RULE: UM -> AX M"
End If
GoTo pos41466
pos41495:
' Skip rule if phoneme != UN
If A <> 80 Then ' Assuming 80 is the value for UN
GoTo pos41503
End If
' 'UN'
' Jump up to branch - replaces current phoneme with AX and continues
A = 28 ' Assuming 28 is the value for N
' 'N' 'change UN to 'AX N'
If bDebug Then
Print "RULE: UN -> AX N"
End If
GoTo pos41466
pos41503:
Y = A
' VOWEL set?
A = arrFlags1(A) And 128 'Assumes flags is an array
' Skip if not a vowel
If A <> 0 Then
' Get the stress
A = arrStress1(X) ' Assumes stress is an array
' If stressed...
If A <> 0 Then
' Get the following phoneme
X = X + 1
A = arrPhonemeIndex(X) ' Assumes arrPhonemeIndex is an array
' If following phoneme is a pause
If A = 0 Then
' Get the phoneme following pause
X = X + 1
Y = arrPhonemeIndex(X)
' Check for end of buffer flag
If Y = 255 Then 'buffer overflow
' ??? Not sure about these flags
A = 65 And 128
Else
' And VOWEL flag to current phoneme's flags
A = arrFlags1(Y) And 128
End If
' If following phonemes is not a pause
If A <> 0 Then
' If the following phoneme is not stressed
A = arrStress1(X)
If A <> 0 Then
' Insert a glottal stop and move forward
If bDebug Then 'Assumes debug is a variable
Print "RULE: Insert glottal stop between two stressed vowels with space between them"
End If
' 31 = 'Q'
Call Insert(X, 31, mem59, 0) ' Assumes Insert is a SUB
iPos = iPos + 1
_Continue
End If
End If
End If
End If
End If
' RULES FOR PHONEMES BEFORE R
' T R -> CH R
' Example: TRACK
' Get current position and phoneme
X = iPos
A = arrPhonemeIndex(iPos)
If A <> 23 Then GoTo pos41611 ' 'R'
' Look at prior phoneme
X = X - 1
A = arrPhonemeIndex(iPos - 1)
'pos41567:
If A = 69 Then ' 'T'
' Change T to CH
If bDebug Then
Print "RULE: T R -> CH R"
End If
arrPhonemeIndex(iPos - 1) = 42
GoTo pos41779
End If
' RULES FOR PHONEMES BEFORE R
' D R -> J R
' Example: DRY
' Prior phonemes D?
If A = 57 Then ' 'D'
' Change D to J
arrPhonemeIndex(iPos - 1) = 44
If bDebug Then
Print "RULE: D R -> J R"
End If
GoTo pos41788
End If
' RULES FOR PHONEMES BEFORE R
' <VOWEL> R -> <VOWEL> RX
' Example: ART
' If vowel flag is set change R to RX
A = arrFlags1(A) And 128
If bDebug Then
Print "RULE: R -> RX"
End If
If A <> 0 Then
arrPhonemeIndex(iPos) = 18 ' 'RX'
End If
' continue to next phoneme
iPos = iPos + 1
pos41611:
' Is phoneme L?
If A = 24 Then '// 'L'
' If prior phoneme does not have VOWEL flag set, move to next phoneme
If (arrFlags1(arrPhonemeIndex(iPos - 1)) And 128) = 0 Then
iPos = iPos + 1
'goto pos41611
_Continue
End If
' Prior phoneme has VOWEL flag set, so change L to LX and move to next phoneme
If bDebug Then
Print "RULE: <VOWEL> L -> <VOWEL> LX"
End If
arrPhonemeIndex(X) = 19 '// 'LX'
iPos = iPos + 1
'goto pos41611
_Continue
End If
' Is current phoneme S?
If A = 32 Then '// 'S'
' If prior phoneme is not G, move to next phoneme
If arrPhonemeIndex(iPos - 1) <> 60 Then
iPos = iPos + 1
'goto pos41611
_Continue
End If
' Replace S with Z and move on
If bDebug Then
Print "RULE: G S -> G Z"
End If
arrPhonemeIndex(iPos) = 38 '// 'Z'
iPos = iPos + 1
'goto pos41611
_Continue
End If
' Is current phoneme K?
If A = 72 Then '// 'K'
' Get next phoneme
Y = arrPhonemeIndex(iPos + 1)
' If at end, replace current phoneme with KX
If Y = 255 Then
arrPhonemeIndex(iPos) = 75
' ML : prevents an index out of bounds problem
Else
' VOWELS AND DIPHTONGS ENDING WITH IY SOUND flag set?
A = arrFlags1(Y) And 32
If bDebug Then
If A = 0 Then
Print "RULE: K <VOWEL OR DIPHTONG NOT ENDING WITH IY> -> KX <VOWEL OR DIPHTONG NOT ENDING WITH IY>"
End If
End If
' Replace with KX
If A = 0 Then
arrPhonemeIndex(iPos) = 75
End If
' 'KX'
End If
Else
' Is int8_tacter a G?
If A = 60 Then '// 'G'
' Get the following int8_tacter
Dim index As _Byte
index = arrPhonemeIndex(iPos + 1)
' At end of buffer?
If index = 255 Then '//prevent buffer overflow
iPos = iPos + 1
'goto pos41611
_Continue
Else
' If diphtong ending with YX, move continue processing next phoneme
If (arrFlags1(index) And 32) <> 0 Then
iPos = iPos + 1
'goto pos41611
_Continue
End If
' replace G with GX and continue processing next phoneme
If bDebug Then
Print "RULE: G <VOWEL OR DIPHTONG NOT ENDING WITH IY> -> GX <VOWEL OR DIPHTONG NOT ENDING WITH IY>"
End If
arrPhonemeIndex(iPos) = 63 '// 'GX'
iPos = iPos + 1
'goto pos41611
_Continue
End If
End If
End If
Y = arrPhonemeIndex(iPos)
'pos41719:
' Replace with softer version?
A = arrFlags1(Y) And 1
If A = 0 Then
GoTo pos41749
End If
A = arrPhonemeIndex(iPos - 1)
If A <> 32 Then '// 'S'
A = Y
GoTo pos41812
End If
' Replace with softer version
If bDebug Then
Print "RULE: S* "; Chr$(arrSignInputTable1(Y)); Chr$(arrSignInputTable2(Y)); " -> S* "; Chr$(arrSignInputTable1(Y - 12)); Chr$(arrSignInputTable2(Y - 12))
End If
arrPhonemeIndex(iPos) = Y - 12
iPos = iPos + 1
'goto pos41611
_Continue
pos41749:
' UW -> UX
A = arrPhonemeIndex(X)
If A = 53 Then '// 'UW'
' ALVEOLAR flag set?
Y = arrPhonemeIndex(X - 1)
A = arrFlags2(Y) And 4
' If not set, continue processing next phoneme
If A = 0 Then
iPos = iPos + 1
'goto pos41611
_Continue
End If
If bDebug Then
Print "RULE: <ALVEOLAR> UW -> <ALVEOLAR> UX"
End If
arrPhonemeIndex(X) = 16
iPos = iPos + 1
'goto pos41611
_Continue
End If
pos41779:
If A = 42 Then '// 'CH'
' pos41783:
If bDebug Then
Print "CH -> CH CH+1"
End If
Call Insert(X + 1, A + 1, mem59, arrStress1(X))
iPos = iPos + 1
_Continue
End If
pos41788:
If A = 44 Then '// 'J'
If bDebug Then
Print "J -> J J+1"
End If
Call Insert(X + 1, A + 1, mem59, arrStress1(X))
iPos = iPos + 1
_Continue
End If
' Jump here to continue
pos41812:
' Past this point, only process if phoneme is T or D
If A <> 69 Then '// 'T'
If A <> 57 Then
iPos = iPos + 1
_Continue
End If '// 'D'
End If
'pos41825:
' If prior phoneme is not a vowel, continue processing phonemes
If (arrFlags1(arrPhonemeIndex(X - 1)) And 128) = 0 Then
iPos = iPos + 1
_Continue
End If
' Get next phoneme
X = X + 1
A = arrPhonemeIndex(X)
'pos41841
' Is the next phoneme a pause?
If A <> 0 Then
' If next phoneme is not a pause, continue processing phonemes
If (arrFlags1(A) And 128) = 0 Then
iPos = iPos + 1
_Continue
End If
' If next phoneme is stressed, continue processing phonemes
' FIXME: How does a pause get stressed?
If arrStress1(X) <> 0 Then
iPos = iPos + 1
_Continue
End If
'pos41856:
' Set phonemes to DX
If bDebug Then
Print "RULE: Soften T or D following vowel or ER and preceding a pause -> DX"
End If
arrPhonemeIndex(iPos) = 30 '// 'DX'
Else
A = arrPhonemeIndex(X + 1)
If A = 255 Then '//prevent buffer overflow
A = 65 And 128
Else
' Is next phoneme a vowel or ER?
A = arrFlags1(A) And 128
End If
If bDebug Then
If A <> 0 Then
Print "RULE: Soften T or D following vowel or ER and preceding a pause -> DX"
End If
End If
If A <> 0 Then
arrPhonemeIndex(iPos) = 30
End If '// 'DX'
End If
iPos = iPos + 1
Loop '// while
End Sub ' Parser2
Sub AdjustLengths ()
' loop index
Dim X As Integer
Dim index As _Byte
Dim A As Integer
Dim loopIndex As _Byte
Dim mem56 As Integer
Dim debugX As Integer
' iterate through the phoneme list
loopIndex = 0
Do
' get a phoneme
X = loopIndex
index = arrPhonemeIndex(X)
' exit loop if end on buffer token
If index = 255 Then
Exit Do
End If
' not punctuation?
If (arrFlags2(index) And 1) = 0 Then
' skip
X = X + 1
_Continue
End If
' hold index
loopIndex = X
' Loop backwards from this point
pos48644:
' back up one phoneme
X = X - 1
' stop once the beginning is reached
If X = 0 Then
Exit Do
End If
' get the preceding phoneme
index = arrPhonemeIndex(X)
If index <> 255 Then 'inserted to prevent access overrun
If (arrFlags1(index) And 128) = 0 Then
GoTo pos48644 ' if not a vowel, continue looping
End If
End If
'pos48657:
Do
' test for vowel
index = arrPhonemeIndex(X)
If index <> 255 Then 'inserted to prevent access overrun
' test for fricative/unvoiced or not voiced
If ((arrFlags2(index) And 32) = 0) Or ((arrFlags1(index) And 4) <> 0) Then 'nochmal berprfen
'A = arrFlags1(Y) & 4;
'if(A == 0) goto pos48688;
' get the phoneme length
A = arrPhonemeLength(X)
' change phoneme length to (length * 1.5) + 1
A = (A \ 2) + A + 1
If bDebug Then
Print "RULE: Lengthen <FRICATIVE> or <VOICED> between <VOWEL> and <PUNCTUATION> by 1.5"
End If
If bDebug Then
Print "PRE"
End If
If bDebug Then
Print "phoneme"; X; "("; Chr$(arrSignInputTable1(arrPhonemeIndex(X))); Chr$(arrSignInputTable2(arrPhonemeIndex(X))); ") length"; arrPhonemeLength(X)
End If
arrPhonemeLength(X) = A
If bDebug Then
Print "POST"
End If
If bDebug Then
Print "phoneme"; X; "("; Chr$(arrSignInputTable1(arrPhonemeIndex(X))); Chr$(arrSignInputTable2(arrPhonemeIndex(X))); ") length"; arrPhonemeLength(X)
End If
End If
End If
' keep moving forward
X = X + 1
Loop Until X = loopIndex
' if (X != loopIndex) goto pos48657;
X = X + 1
Loop
' Similar to the above routine, but shorten vowels under some circumstances
' Loop throught all phonemes
loopIndex = 0
'pos48697
Do
' get a phoneme
X = loopIndex
index = arrPhonemeIndex(X)
' exit routine at end token
If index = 255 Then
Exit Sub
End If
' vowel?
A = arrFlags1(index) And 128
If A <> 0 Then
' get next phoneme
X = X + 1
index = arrPhonemeIndex(X)
' get flags
If index = 255 Then
mem56 = 65
Else
mem56 = arrFlags1(index)
End If
' use if end marker
' not a consonant
If (arrFlags1(index) And 64) = 0 Then
' RX or LX?
If (index = 18) Or (index = 19) Then ' 'RX' & 'LX'
' get the next phoneme
X = X + 1
index = arrPhonemeIndex(X)
' next phoneme a consonant?
If (arrFlags1(index) And 64) <> 0 Then
If bDebug Then
Print "RULE: <VOWEL> <RX | LX> <CONSONANT> - decrease length by 1"
End If
If bDebug Then
Print "PRE"
End If
If bDebug Then
Print "phoneme"; loopIndex; "("; Chr$(arrSignInputTable1(arrPhonemeIndex(loopIndex))); Chr$(arrSignInputTable2(arrPhonemeIndex(loopIndex))); ") length"; arrPhonemeLength(loopIndex)
End If
' decrease length of vowel by 1 frame
arrPhonemeLength(loopIndex) = arrPhonemeLength(loopIndex) - 1
If bDebug Then
Print "POST"
End If
If bDebug Then
Print "phoneme"; loopIndex; "("; Chr$(arrSignInputTable1(arrPhonemeIndex(loopIndex))); Chr$(arrSignInputTable2(arrPhonemeIndex(loopIndex))); ") length"; arrPhonemeLength(loopIndex)
End If
End If
' move ahead
loopIndex = loopIndex + 1
_Continue
End If
' move ahead
loopIndex = loopIndex + 1
_Continue
End If
' Got here if not <VOWEL>
' not voiced
If (mem56 And 4) = 0 Then
' Unvoiced
' *, .*, ?*, ,*, -*, DX, S*, SH, F*, TH, /H, /X, CH, P*, T*, K*,
' KX
' not an unvoiced plosive?
If (mem56 And 1) = 0 Then
' move ahead
loopIndex = loopIndex + 1
_Continue
End If
' P*, T*, K*, KX
' move back
X = X - 1
If bDebug Then
Print "RULE: <VOWEL> <UNVOICED PLOSIVE> - decrease vowel by 1/8th"
End If
If bDebug Then
Print "PRE"
End If
If bDebug Then
Print "phoneme"; X; "("; Chr$(arrSignInputTable1(arrPhonemeIndex(X))); Chr$(arrSignInputTable2(arrPhonemeIndex(X))); ") length"; arrPhonemeLength(X)
End If
' decrease length by 1/8th
mem56 = arrPhonemeLength(X) \ 8
arrPhonemeLength(X) = arrPhonemeLength(X) - mem56
If bDebug Then
Print "POST"
End If
If bDebug Then
Print "phoneme"; X; "("; Chr$(arrSignInputTable1(arrPhonemeIndex(X))); Chr$(arrSignInputTable2(arrPhonemeIndex(X))); ") length"; arrPhonemeLength(X)
End If
' move ahead
loopIndex = loopIndex + 1
_Continue
End If
If bDebug Then
Print "RULE: <VOWEL> <VOICED CONSONANT> - increase vowel by 1/2 + 1"
End If
If bDebug Then
Print "PRE"
End If
If bDebug Then
Print "phoneme"; X - 1; "("; Chr$(arrSignInputTable1(arrPhonemeIndex(X - 1))); Chr$(arrSignInputTable2(arrPhonemeIndex(X - 1))); ") length"; arrPhonemeLength(X - 1)
End If
' decrease length
A = arrPhonemeLength(X - 1)
arrPhonemeLength(X - 1) = (A \ 2) + A + 1
' 5/4*A + 1
If bDebug Then
Print "POST"
End If
If bDebug Then
Print "phoneme"; X - 1; "("; Chr$(arrSignInputTable1(arrPhonemeIndex(X - 1))); Chr$(arrSignInputTable2(arrPhonemeIndex(X - 1))); ") length"; arrPhonemeLength(X - 1)
End If
' move ahead
loopIndex = loopIndex + 1
_Continue
End If
' WH, R*, L*, W*, Y*, Q*, Z*, ZH, V*, DH, J*, **,
'pos48821:
' nasal?
If (arrFlags2(index) And 8) <> 0 Then
' M*, N*, NX,
' get the next phoneme
X = X + 1
index = arrPhonemeIndex(X)
' end of buffer?
If index = 255 Then
A = 65 And 2
Else
A = arrFlags1(index) And 2
End If
'prevent buffer overflow
' check for stop consonant
' is next phoneme a stop consonant?
If A <> 0 Then
' B*, D*, G*, GX, P*, T*, K*, KX
If bDebug Then
Print "RULE: <NASAL> <STOP CONSONANT> - set nasal = 5, consonant = 6"
End If
If bDebug Then
Print "POST"
End If
If bDebug Then
Print "phoneme"; X; "("; Chr$(arrSignInputTable1(arrPhonemeIndex(X))); Chr$(arrSignInputTable2(arrPhonemeIndex(X))); ") length"; arrPhonemeLength(X)
End If
If bDebug Then
Print "phoneme"; X - 1; "("; Chr$(arrSignInputTable1(arrPhonemeIndex(X - 1))); Chr$(arrSignInputTable2(arrPhonemeIndex(X - 1))); ") length"; arrPhonemeLength(X - 1)
End If
' set stop consonant length to 6
arrPhonemeLength(X) = 6
' set nasal length to 5
arrPhonemeLength(X - 1) = 5
If bDebug Then
Print "POST"
End If
If bDebug Then
Print "phoneme"; X; "("; Chr$(arrSignInputTable1(arrPhonemeIndex(X))); Chr$(arrSignInputTable2(arrPhonemeIndex(X))); ") length"; arrPhonemeLength(X)
End If
If bDebug Then
Print "phoneme"; X - 1; "("; Chr$(arrSignInputTable1(arrPhonemeIndex(X - 1))); Chr$(arrSignInputTable2(arrPhonemeIndex(X - 1))); ") length"; arrPhonemeLength(X - 1)
End If
End If
' move to next phoneme
loopIndex = loopIndex + 1
_Continue
End If
If (arrFlags1(index) And 2) <> 0 Then
' B*, D*, G*, GX
' move past silence
Do
' move ahead
X = X + 1
index = arrPhonemeIndex(X)
Loop Until index = 0
' check for end of buffer
If index = 255 Then 'buffer overflow
' ignore, overflow code
If (65 And 2) = 0 Then
loopIndex = loopIndex + 1
_Continue
End If
ElseIf (arrFlags1(index) And 2) = 0 Then
' if another stop consonant, move ahead
loopIndex = loopIndex + 1
_Continue
End If
If bDebug Then
Print "RULE: <UNVOICED STOP CONSONANT> {optional silence} <STOP CONSONANT> - shorten both to 1/2 + 1"
End If
If bDebug Then
Print "PRE"
End If
If bDebug Then
Print "phoneme"; X; "("; Chr$(arrSignInputTable1(arrPhonemeIndex(X))); Chr$(arrSignInputTable2(arrPhonemeIndex(X))); ") length"; arrPhonemeLength(X)
End If
If bDebug Then
Print "phoneme"; X - 1; "("; Chr$(arrSignInputTable1(arrPhonemeIndex(X - 1))); Chr$(arrSignInputTable2(arrPhonemeIndex(X - 1))); ") length"; arrPhonemeLength(X - 1)
End If
' X gets overwritten, so hold prior X value for debug statement
debugX = X
' shorten the prior phoneme length to (length/2 + 1)
arrPhonemeLength(X) = (arrPhonemeLength(X) \ 2) + 1
X = loopIndex
' also shorten this phoneme length to (length/2 +1)
arrPhonemeLength(loopIndex) = (arrPhonemeLength(loopIndex) \ 2) + 1
If bDebug Then
Print "POST"
End If
If bDebug Then
Print "phoneme"; debugX; "("; Chr$(arrSignInputTable1(arrPhonemeIndex(debugX))); Chr$(arrSignInputTable2(arrPhonemeIndex(debugX))); ") length"; arrPhonemeLength(debugX)
End If
If bDebug Then
Print "phoneme"; debugX - 1; "("; Chr$(arrSignInputTable1(arrPhonemeIndex(debugX - 1))); Chr$(arrSignInputTable2(arrPhonemeIndex(debugX - 1))); ") length"; arrPhonemeLength(debugX - 1)
End If
' move ahead
loopIndex = loopIndex + 1
_Continue
End If
' WH, R*, L*, W*, Y*, Q*, Z*, ZH, V*, DH, J*, **,
' liquic consonant?
If (arrFlags2(index) And 16) <> 0 Then
' R*, L*, W*, Y*
' get the prior phoneme
index = arrPhonemeIndex(X - 1)
' prior phoneme a stop consonant>
If (arrFlags1(index) And 2) <> 0 Then
If bDebug Then
Print "RULE: <LIQUID CONSONANT> <DIPHTONG> - decrease by 2"
End If
If bDebug Then
Print "PRE"
End If
If bDebug Then
Print "phoneme"; X; "("; Chr$(arrSignInputTable1(arrPhonemeIndex(X))); Chr$(arrSignInputTable2(arrPhonemeIndex(X))); ") length"; arrPhonemeLength(X)
End If
' decrease the phoneme length by 2 frames (20 ms)
arrPhonemeLength(X) = arrPhonemeLength(X) - 2
If bDebug Then
Print "POST"
End If
If bDebug Then
Print "phoneme"; X; "("; Chr$(arrSignInputTable1(arrPhonemeIndex(X))); Chr$(arrSignInputTable2(arrPhonemeIndex(X))); ") length"; arrPhonemeLength(X)
End If
End If
End If
' move to next phoneme
loopIndex = loopIndex + 1
_Continue
Loop
End Sub
' -------------------------------------------------------------------------
' ML : Code47503 is division with remainder, and mem50 gets the sign
Sub Code47503 (mem52 As _Byte)
Dim iTemp As Integer
Y = 0
If ((mem53 And 128) <> 0) Then
mem53 = -mem53
Y = 128
End If
mem50 = Y
A = 0
For X = 8 To 1 Step -1
iTemp = mem53
mem53 = mem53 * 2 ' QB64PE uses * for left bit shift
A = A * 2 ' QB64PE uses * for left bit shift
If (iTemp >= 128) Then
A = A + 1
End If
If (A >= mem52) Then
A = A - mem52
mem53 = mem53 + 1
End If
Next X
mem51 = A
If ((mem50 And 128) <> 0) Then
mem53 = -mem53
End If
End Sub
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' END sam.c
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' BEGIN reciter.c
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' test the flag bits for a specific char
' this is non ascii layout, but tests ascii chars
'uint32_t TestFlag(uint8_t in, uint8_t mask)
' {
' assert(in<sizeof(tab36376));
' const uint8_t val = tab36376[in];
' return val & mask;
' }
Function TestFlag~% (in As _Unsigned _Byte, mask As _Unsigned _Byte)
If in > UBound(tab36376) Then Stop 'QB64: Replace assert with STOP
' val = arrTab36376(in) 'Not needed, can use array element directly
TestFlag = arrTab36376(in) And mask 'QB64: AND is bitwise AND
End Function
' test the flag bits for the pervious char in the stream
'uint32_t TestFlagDec(uint8_t mem59, uint8_t mask)
'{
' X = mem59;
' X--;
' A = inputtemp[X];
' Y = A;
' assert(Y<sizeof(tab36376));
' A = tab36376[Y];
' return A & mask;
'}
Function TestFlagDec~% (mem59 As Integer, mask As Long)
X = mem59
X = X - 1
A = Asc(Mid$(TempInput$, X + 1, 1)) 'QB64: Access char in string, ASC gets ASCII value
Y = A
If Y > UBound(tab36376) Then Stop
A = arrTab36376(Y)
TestFlagDec = A And mask
End Function
' test the flag bits for the next char in the stream
'uint32_t TestFlagInc(uint8_t mem58, uint8_t mask)
'{
' X = mem58;
' X++;
' A = inputtemp[X];
' Y = A;
' assert(Y<sizeof(tab36376));
' A = tab36376[Y];
' return A & mask;
'}
Function TestFlagInc~% (mem58 As _Unsigned _Byte, mask As _Unsigned _Byte)
X = mem58
X = X + 1
A = Asc(Mid$(TempInput$, X + 1, 1)) 'QB64: Access char in string, ASC gets ASCII value
Y = A
If Y > UBound(tab36376) Then Stop
A = arrTab36376(Y)
TestFlagInc = A And mask
End Function
' verify that the reciter tables are well formed
Sub ReciterVerify ()
Dim iIndex As Integer
Dim iPos As Integer
For iIndex = 0 To 27 ' Assuming rule_tab is 0-based index and has 28 elements
iPos = arrRuleTab(iIndex)
' Assuming rules is an array and QB64PE arrays are 0-based
If arrRules(iPos) <> 93 Then ' 93 is the ASCII code for ']'
Print "Assertion failed: arrRules(" + _Trim$(Str$(iPos)) + ") <> ']'"
Stop
End If
Next iIndex
End Sub
' lookup a byte for a specific rule in the table
Function GetRuleByte% (rule_index As Integer, Y As Integer)
' Assuming rules is an array of integers (since C uses uint8_t)
Dim iEnd As Integer
Dim index As Integer
iEnd = UBound(rules) 'UBOUND gives the highest index
index = rule_index + Y
If index >= iEnd Then
Print "Assertion failed: index < iEnd"
Stop
End If
GetRuleByte = arrRules(index)
End Function
Sub SecureCopyInput (sInput As String, max_size As Integer)
' secure copy of sInput because sInput will be overwritten by phonemes
X = 1
Y = 0
Do While Y < max_size
A = Asc(Mid$(sInput, Y + 1, 1)) ' QB64PE strings are 1-based index
Y = Y + 1
If A < 32 Then '0x20 = 32
_Continue
End If
If A = 96 Then '0x60 = 96
_Continue
End If
If A = 39 Then '0x27 = 39
_Continue
End If
If A >= 126 Then '0x7E = 126
_Continue
End If
TempInput$(X) = Chr$(A)
X = X + 1
Loop
' Null-terminate the input string (important for C compatibility)
sInput = String$(max_size, 0) ' Fills the string with null characters (ASCII 0)
End Sub ' SecureCopyInput
Function TextToPhonemes& (sInput As String, max_size As Long)
Const end_token = 155 ' ESC | 0x80
'THIS IS REFERENCED IN OTHER FUNCTIONS, DO WE DIM AS GLOBAL?
'dim TempInput$
Dim out_pos As Long ' output position for phonemes
Dim mem57 As Long
Dim mem58 As Long ' current pos, used mostly in rhs match
Dim mem59 As Long
Dim mem60 As Long
Dim mem61 As Long
Dim rule_index As Long ' memory position of current rule
Dim mem64 As Long ' position of '=' or current character
Dim pos_rparen As Long ' position of ')
Dim pos_lparen As Long ' position of '(
Dim mem36653 As Long
'max_size = 250
' NOT SURE WHAT THIS STUFF IS FOR,
' IF WE ONLY OVERWRITE IT WITH sInput ?
TempInput$ = Space$(256) ' Assuming TempInput$ is a string, adjust size as needed
TempInput$ = " " + TempInput$ 'inputtemp[0] = 0x20; // '
'SECURECOPYINPUT in$, sInput, max_size 'Need to implement SecureCopyInput (see below)
'For simplicity, assuming a direct copy for now. Adjust as needed for QB64 string handling
TempInput$ = sInput ' Assuming direct copy; implement SecureCopyInput for safety
Y = 255
X = 255
TempInput$ = Left$(TempInput$, X) + Chr$(27) + Mid$(TempInput$, X + 2) 'inputtemp[X] = 27; // ESC
mem61 = 255
A = 255
out_pos = 255
' ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
' START PARSE
' ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
L_start_parse:
Do
mem61 = mem61 + 1
X = mem61
' if end of input marker
A = Asc(Mid$(TempInput$, X + 1, 1)) 'A = inputtemp[X];
mem64 = A
If A = Asc("[") Then
out_pos = out_pos + 1
X = out_pos
A = end_token
'arrInput1(X] = A ' Cannot directly assign to input string like this
' Assuming input is passed by reference and we modify it. Need to convert A back to character
sInput = Left$(sInput, X) + Chr$(A) + Mid$(sInput, X + 2) ' Modify sInput string
' success
TextToPhonemes = 1
Exit Function
End If
If A = Asc(".") Then
' check a flag for next input char?
X = X + 1
Y = Asc(Mid$(TempInput$, X + 1, 1)) 'Y = inputtemp[X];
'A = TestFlag(Y, 1) ' Need to implement TestFlag (see below)
' Assuming TestFlag checks bit 0; using bitwise AND for now
A = (Y And 1) ' Simple bit check, replace with actual TestFlag if needed
If A = 0 Then
' output a '.'
out_pos = out_pos + 1
X = out_pos
A = Asc(".")
'arrInput1(X] = A
sInput = Left$(sInput, X) + Chr$(A) + Mid$(sInput, X + 2) ' Modify sInput string
Else
Exit Do
End If
Else
Exit Do
End If
Loop 'while
' if this character is non alpha
A = mem64
Y = A
'A = TestFlag(A, 255) ' Need to implement TestFlag
' Assuming TestFlag checks for non-alpha; QB64's ASCII range for A-Z is 65-90
If (A >= 65 And A <= 90) Then
mem57 = 0 ' If it's A-Z, flag is 0 (not non-alpha)
Else
mem57 = 2 ' Otherwise, set flag bit 1 (0x02)
End If 'Simplified, replace with actual TestFlag
If (mem57 And 2) Then 'if (A & 0x02)
rule_index = arrRuleTab(27) ' Assuming rule_tab is an array, and we have 27 elements
GoTo L_nextrule ' Use GOTO with caution, consider refactoring
End If
' what be this ???
A = mem57 ' flag for A
If A = 0 Then
A = Asc(" ")
TempInput$ = Left$(TempInput$, X) + Chr$(A) + Mid$(TempInput$, X + 2) 'inputtemp[X] = A;
out_pos = out_pos + 1
X = out_pos
' hard exit on too long?
If X > max_size Then
'arrInput1(max_size - 1] = end_token
sInput = Left$(sInput, max_size) + Chr$(end_token) + Mid$(sInput, max_size + 2)
A = mem61
mem36653 = A
TextToPhonemes = 0
Exit Function
Else
'arrInput1(X] = A
sInput = Left$(sInput, X) + Chr$(A) + Mid$(sInput, X + 2)
GoTo L_start_parse
End If
End If
' what is A at this point?
A = mem57 And 128 '0x80 in decimal
If A = 0 Then
' error
TextToPhonemes = 0
Exit Function
End If
' go to the right rules for this character.
X = mem64 - Asc("A")
'assert(X<26); ' QB64 doesn't have assert; can add a check if needed
If X < 0 Or X > 25 Then
' Handle out-of-bounds, e.g., PRINT "Error: Invalid character"; RETURN
Print "Error: Invalid character";
TextToPhonemes = 0
Exit Function
End If
rule_index = arrRuleTab(X + 1) ' QB64 arrays are 1-based
'// ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
'// TRY MATCHING NEXT RULE
'// ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
L_nextrule:
'// find next rule
'// skip to next rule byte with 0x80 mask
Y = 0
Do
rule_index = rule_index + 1
A = GetRuleByte(rule_index, Y) '//Need to define GetRuleByte function
Loop While (A And &H80) = 0 '// (A&0x80)==0
Y = Y + 1
'// if there are no more rules in this set
If GetRuleByte(rule_index, Y) = Asc("]") Then '// GetRuleByte(rule_index, Y)==']'
TextToPhonemes& = 0
Exit Function
End If
'// identify key points in this rule
'// find '('
Do
'// fixme: fix infinite loop here with ' chars
A = GetRuleByte(rule_index, Y)
' assert((A & 0x80)==0); '// QB64 doesn't have assert, consider a conditional check
If (A And &H80) <> 0 Then Stop '// If assert fails, stop execution
If A = Asc("(") Then Exit Do '// if (A == '(')
Y = Y + 1
Loop
pos_lparen = Y
'// find ')'
Do
Y = Y + 1
A = GetRuleByte(rule_index, Y)
Loop While A <> Asc(")") '// A != ')'
pos_rparen = Y
'// find '='
Do
Y = Y + 1
A = GetRuleByte(rule_index, Y)
A = A And &H7F '// A = A & 0x7F;
Loop While A <> Asc("=") '// A != '='
mem64 = Y
X = mem61
mem60 = X
'// ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
'// MATCH EXPRESSION IN PARENTHESIS
'// ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
Y = pos_lparen
Y = Y + 1
'// pos36759:
Do
mem57 = Asc(Mid$(TempInput$, X + 1, 1)) '// mem57 = inputtemp[X];
A = GetRuleByte(rule_index, Y)
If A <> mem57 Then '// if (A!=mem57)
'// no match lets apply next rule
GoTo L_nextrule
End If
Y = Y + 1
If Y = pos_rparen Then Exit Do '// if (Y==pos_rparen)
X = X + 1
mem60 = X
Loop
'// the string in the bracket is correct
'// pos36787:
A = mem61
mem59 = mem61
'---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
'MATCH TO LEFT OF ( IN RULE
'---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
L_match_left:
' scan back to find start?
Do
pos_lparen = pos_lparen - 1
Y = pos_lparen
A = GetRuleByte(rule_index, Y) 'Need equivalent QB64 function. See below
mem57 = A
' if end of lhs pattern
If (A And &H80) Then ' Check if the most significant bit is set
A = mem60
mem58 = A
GoTo L_match_right ' QB64 uses GOTO
End If
'
X = A And &H7F ' all but msb
A = TestFlag(X, &H80) 'Need equivalent QB64 function. See below
If (A = 0) Then
' parse special escape rule
Exit Do ' QB64 uses EXIT DO to exit a DO loop
End If
X = mem59 - 1
A = inputtemp(X) ' TODO: NEED TO RECONCILE inputtemp() vs TempInput$ ?
If (A <> mem57) Then
GoTo L_nextrule ' QB64 uses GOTO
End If
mem59 = X
Loop
' test for special escape chars
A = mem57
Select Case A
Case 32 ' " "
GoTo pos36895
Case 35 ' "#"
GoTo pos36910
Case 46 ' "."
GoTo pos36920
Case 38 ' "&"
GoTo pos36935
Case 64 ' "@"
GoTo pos36967
Case 94 ' "^"
GoTo pos37004
Case 43 ' "+"
GoTo pos37019
Case 58 ' ":"
GoTo pos37040
Case Else
' error
TextToPhonemes& = 0
Exit Function
End Select
'---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
pos36895: ' handle " "
A = TestFlagDec(mem59, &H80)
If (A = 0) Then
mem59 = X
GoTo L_match_left
End If
GoTo L_nextrule
'---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
pos36910: ' handle "#"
A = TestFlagDec(mem59, &H40) 'Need equivalent QB64 function. See below
If (A <> 0) Then
mem59 = X
GoTo L_match_left
End If
GoTo L_nextrule
'---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
pos36920: ' handle "."
A = TestFlagDec(mem59, &H08) 'Need equivalent QB64 function. See below
If (A <> 0) Then
mem59 = X
GoTo L_match_left
End If
GoTo L_nextrule
' ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
pos36935: ' handle '&
A = TestFlagDec(mem59, 16) '0x10
If A <> 0 Then
mem59 = X
GoTo L_match_left
End If
A = Asc(Mid$(TempInput$, X + 1, 1))
If A = Asc("H") Then
X = X - 1
A = Asc(Mid$(TempInput$, X + 1, 1))
If (A = Asc("C")) Or (A = Asc("S")) Then
mem59 = X
GoTo L_match_left
End If
End If
GoTo L_nextrule
' ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
pos36967: ' handle '@
A = TestFlagDec(mem59, 4) '0x04
If A <> 0 Then
mem59 = X
GoTo L_match_left
End If
A = Asc(Mid$(TempInput$, X + 1, 1))
If (A <> Asc("H")) And (A <> Asc("T")) And (A <> Asc("C")) And (A <> Asc("S")) Then
GoTo L_nextrule
End If
mem59 = X
GoTo L_match_left
' ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
pos37004: ' handle '^
A = TestFlagDec(mem59, 32) '0x20
If A <> 0 Then
mem59 = X
GoTo L_match_left
End If
GoTo L_nextrule
' ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
pos37019: ' handle '+
X = mem59
X = X - 1
A = Asc(Mid$(TempInput$, X, 1)) ' Assuming TempInput$ is a string version
If (A = Asc("E")) Or (A = Asc("I")) Or (A = Asc("Y")) Then
mem59 = X
GoTo L_match_left
End If
GoTo L_nextrule
' ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
pos37040: ' handle ':
A = TestFlagDec(mem59, &H20) ' Assuming TestFlagDec is a QB64 FUNCTION
If A <> 0 Then
mem59 = X
GoTo pos37040
End If
GoTo L_match_left
' ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
pos37077: ' handle '%
X = mem58 + 1
A = Asc(Mid$(TempInput$, X, 1))
If A <> Asc("E") Then
GoTo L_match_ing
End If
X = X + 1
Y = Asc(Mid$(TempInput$, X, 1))
X = X - 1
A = TestFlag(Y, &H80) ' Assuming TestFlag is a QB64 FUNCTION
If A <> 0 Then
X = X + 1
A = Asc(Mid$(TempInput$, X, 1))
If A <> Asc("R") Then
GoTo pos37113
End If
End If
mem58 = X
GoTo L_match_right
'
'// ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
'pos37113: // unknown ???
pos37113:
If (A = Asc("S")) Or (A = Asc("D")) Then
mem58 = X
GoTo L_match_right
End If
If A <> Asc("L") Then
GoTo pos37135
End If
X = X + 1
A = Asc(Mid$(TempInput$, X + 1, 1))
If A <> Asc("Y") Then
GoTo L_nextrule
End If
mem58 = X
GoTo L_match_right
'pos37135: // match FUV
pos37135:
If A <> Asc("F") Then
GoTo L_nextrule
End If
X = X + 1
A = Asc(Mid$(TempInput$, X + 1, 1))
If A <> Asc("U") Then
GoTo L_nextrule
End If
X = X + 1
A = Asc(Mid$(TempInput$, X + 1, 1))
If A <> Asc("V") Then
GoTo L_nextrule
End If
mem58 = X
GoTo L_match_right
'L_match_ing: // match 'ING'
L_match_ing:
If A <> Asc("I") Then
GoTo L_nextrule
End If
X = X + 1
A = Asc(Mid$(TempInput$, X + 1, 1))
If A <> Asc("N") Then
GoTo L_nextrule
End If
X = X + 1
A = Asc(Mid$(TempInput$, X + 1, 1))
If A <> Asc("G") Then
GoTo L_nextrule
End If
mem58 = X
GoTo L_match_right
'// ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
'// MATCH RIGHT OF ) IN RULE
'// ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
L_match_right:
Y = pos_rparen + 1
If Y = mem64 Then
GoTo L_emitrule
End If
pos_rparen = Y
'A = GetRuleByte(rule_index, Y);
'Need to define GetRuleByte function
'A = GetRuleByte(rule_index, Y)
'For now, placeholder:
A = 0 ' Placeholder
mem57 = A
X = A
'A = TestFlag(X, 0x80);
'Need to define TestFlag function
'A = TestFlag(X, &H80)
'For now, placeholder:
A = 0 'Placeholder
If A = 0 Then
A = mem57
Select Case A
Case Asc(" "): GoTo pos37295
Case Asc("#"): GoTo pos37310
Case Asc("."): GoTo pos37320
Case Asc("&"): GoTo pos37335
Case Asc("@"): GoTo pos37367
Case Asc("^"): GoTo pos37404
Case Asc("+"): GoTo pos37419
Case Asc(":"): GoTo pos37440
Case Asc("%"): GoTo pos37077
Case Else
'// error
' return 0;
'PRINT "Error"
'END 'Instead of return, you might want to handle this differently
'GOTO ExitSub ' Add an exit label
TextToPhonemes& = -1
End Select
Else
'// what this does ??
X = mem58 + 1
A = Asc(Mid$(TempInput$, X + 1, 1))
If A <> mem57 Then
GoTo L_nextrule
End If
mem58 = X
GoTo L_match_right
End If
' ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
pos37295: ' handle '
A = TestFlagInc(mem58, &H80)
If A <> 0 Then
GoTo L_nextrule
End If
mem58 = X
GoTo L_match_right
' ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
pos37310: ' handle '#
A = TestFlagInc(mem58, &H40)
If A <> 0 Then
mem58 = X
GoTo L_match_right
End If
GoTo L_nextrule
' ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
pos37320: ' handle '.
A = TestFlagInc(mem58, &H08)
If A = 0 Then
GoTo L_nextrule
End If
mem58 = X
GoTo L_match_right
' ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
pos37335: ' handle '&
A = TestFlagInc(mem58, &H10)
If A <> 0 Then
mem58 = X
GoTo L_match_right
End If
A = Asc(Mid$(TempInput$, X + 1, 1)) ' Corrected index
If A <> Asc("H") Then
GoTo L_nextrule
End If
' is this really x++ not x--?
X = X + 1
A = Asc(Mid$(TempInput$, X + 1, 1)) ' Corrected index
If (A = Asc("C")) Or (A = Asc("S")) Then
mem58 = X
GoTo L_match_right
End If
GoTo L_nextrule
' ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
pos37367: ' handle '@'
A = TestFlagInc(mem58, 4) ' 0x04
If A <> 0 Then
mem58 = X
GoTo L_match_right
End If
A = inputtemp(X)
If (A <> Asc("H")) And (A <> Asc("T")) And (A <> Asc("C")) And (A <> Asc("S")) Then
GoTo L_nextrule
End If
mem58 = X
GoTo L_match_right
' ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
pos37404: ' handle '^'
A = TestFlagInc(mem58, 32) ' 0x20
If A = 0 Then
GoTo L_nextrule
End If
mem58 = X
GoTo L_match_right
' ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
pos37419: ' handle '+'
X = mem58
X = X + 1
A = inputtemp(X)
If (A = Asc("E")) Or (A = Asc("I")) Or (A = Asc("Y")) Then
mem58 = X
GoTo L_match_right
End If
GoTo L_nextrule
' ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
pos37440: ' handle ':'
Do
A = TestFlagInc(mem58, 32) ' 0x20
If A = 0 Then
GoTo L_match_right
End If
mem58 = X
Loop
GoTo L_emitrule
'// ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
'// EMIT RULE
'// ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
L_emitrule:
Y = mem64
mem61 = mem60
'if bDebug then ' Assuming 'debug' is a global variable.
' PrintRule rule_index ' Assuming PrintRule is a function.
'end if
Do
Y = Y + 1
'A = GetRuleByte(rule_index, Y) ' Assuming GetRuleByte is a function.
' Placeholder for GetRuleByte
' A = GetRuleByte(rule_index, Y) ' Needs QB64 Implementation
' Need to know how GetRuleByte works
mem57 = A
' mask out parity
A = A And 127 '// 0x7f
If A <> Asc("=") Then
out_pos = out_pos + 1
X = out_pos
'arrInput1(X] = A ' Since 'input' is a string, we can't directly assign an integer to an index.
Mid$(sInput, X + 1, 1) = Chr$(A) ' QB64 strings are 1-based index, C arrays are 0-based.
End If
' if has parity set
If (mem57 And 128) <> 0 Then ' //0x80
GoTo L_start_parse
End If
Loop
TextToPhonemes = out_pos
End Function ' TextToPhonemes&
' RENDER THE PHONEMES IN THE LIST
'
' The phoneme list is converted into sound through the steps:
'
' 1. Copy each phoneme <length> 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.
Sub Render
Dim phase1 As _Unsigned _Byte ' mem43
Dim phase2 As _Unsigned _Byte
Dim phase3 As _Unsigned _Byte
Dim mem66 As _Unsigned _Byte
Dim mem38 As _Unsigned _Byte
Dim mem40 As _Unsigned _Byte
Dim speedcounter As _Unsigned _Byte ' mem45
Dim mem48 As _Unsigned _Byte
Dim i As Integer
Dim carry As Integer
If arrPhoIndexOutput(0) = 255 Then
Exit Sub 'exit if no data
End If
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.
Do
' get the index
Y = mem44
' get the phoneme at the index
A = arrPhoIndexOutput(mem44)
mem56 = A
' if terminal phoneme, exit the loop
If A = 255 Then Exit Do
' period phoneme *.
If A = 1 Then
' add rising inflection
A = 1
mem48 = 1
'goto pos48376;
AddInflection mem48, phase1
End If
'question mark phoneme?
If A = 2 Then
' create falling inflection
mem48 = 255
AddInflection mem48, phase1
End If
' pos47615:
' get the stress amount (more stress = higher pitch)
phase1 = arrTab47492(arrStressOutput(Y) + 1)
' get number of frames to write
phase2 = arrPhoLengthOutput(Y)
Y = mem56
' copy from the source to the frames list
Do
frequency1(X) = arrFreq1Data(Y) ' F1 frequency
frequency2(X) = arrFreq2Data(Y) ' F2 frequency
frequency3(X) = arrFreq3Data(Y) ' F3 frequency
amplitude1(X) = arrAmp1Data(Y) ' F1 amplitude
amplitude2(X) = arrAmp2Data(Y) ' F2 amplitude
amplitude3(X) = arrAmp3Data(Y) ' F3 amplitude
sampledConsonantFlag(X) = arrSampledConsonantFlags(Y) ' phoneme data for sampled consonants
arrPitches(X) = pitch + phase1 ' pitch
X = X + 1
phase2 = phase2 - 1
Loop Until phase2 = 0
mem44 = mem44 + 1
Loop Until mem44 = 0
'// -------------------
'//pos47694:
'// CREATE TRANSITIONS
'{here}
A = 0
mem44 = 0
mem49 = 0 '// mem49 starts at as 0
X = 0
While -1 '//while No. 1
'// get the current and following phoneme
Y = arrPhoIndexOutput(X)
A = arrPhoIndexOutput(X + 1)
X = X + 1
'// exit loop at end token
If A = 255 Then
Exit While
End If
'//goto pos47970;
'// get the ranking of each phoneme
X = A
mem56 = arrBlendRank(A)
A = arrBlendRank(Y)
'// compare the rank - lower rank value is stronger
If A = mem56 Then
'// same rank, so use out blend lengths from each phoneme
phase1 = arrOutBlendLength(Y)
phase2 = arrOutBlendLength(X)
ElseIf A < mem56 Then
'// first phoneme is stronger, so us it's blend lengths
phase1 = arrInBlendLength(X)
phase2 = arrOutBlendLength(X)
Else
'// second phoneme is stronger, so use it's blend lengths
'// note the out/in are swapped
phase1 = arrOutBlendLength(Y)
phase2 = arrInBlendLength(Y)
End If
Y = mem44
A = mem49 + arrPhoLengthOutput(mem44)
'// A is mem49 + length
mem49 = A
'// mem49 now holds length + position
A = A + phase2
'//Maybe Problem because of carry flag
'//47776: ADC 42
speedcounter = A
mem47 = 168
phase3 = mem49 - phase1 '// what is mem49
A = phase1 + phase2
'// total transition?
mem38 = A
X = A
X = X - 2
If (X And 128) = 0 Then
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 Then '// pitch
'// unlike the other values, the pitches[] interpolates from
'// the middle of the current phoneme to the middle of the
'// next phoneme
Dim mem36 As _Unsigned Integer, mem37 As _Unsigned Integer
'// half the width of the current phoneme
mem36 = arrPhoLengthOutput(mem44) \ 2
'// half the width of the next phoneme
mem37 = arrPhoLengthOutput(mem44 + 1) \ 2
'// sum the values
mem40 = mem36 + mem37
'// length of both halves
mem37 = mem37 + mem49
'// center of next phoneme
mem36 = mem49 - mem36
'// center index of current phoneme
' ****************************************************************************************************************************************************************
' *** NOT SURE WHAT THIS IS:
'A = Read(mem47, mem37)
' ****************************************************************************************************************************************************************
'// value at center of next phoneme - end interpolation value
'//A = mem[address];
Y = mem36 '// start index of interpolation
' ****************************************************************************************************************************************************************
' *** NOT SURE WHAT THIS IS:
'mem53 = A - Read(mem47, mem36)
' ****************************************************************************************************************************************************************
'// value to center of current phoneme
Else
'// value to interpolate to
' ****************************************************************************************************************************************************************
' *** NOT SURE WHAT THIS IS:
'A = Read(mem47, speedcounter)
' ****************************************************************************************************************************************************************
'// position to start interpolation from
Y = phase3
'// value to interpolate from
' ****************************************************************************************************************************************************************
' *** NOT SURE WHAT THIS IS:
'mem53 = A - Read(mem47, phase3)
' ****************************************************************************************************************************************************************
End If
'//Code47503(mem40);
'// ML : Code47503 is division with remainder, and mem50 gets the sign
'// calculate change per frame
mem50 = IIf(Sgn(mem53) = -1, 128, 0)
mem51 = Abs(mem53) Mod mem40
mem53 = 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
' ****************************************************************************************************************************************************************
' *** NOT SURE WHAT THIS IS:
'A = Read(mem47, Y) + mem53
' ****************************************************************************************************************************************************************
'//carry alway cleared
mem48 = A
Y = Y + 1
X = X - 1
If X = 0 Then
Exit While
End If
mem56 = mem56 + mem51
If mem56 >= mem40 Then '//???
mem56 = mem56 - mem40
'//carry? is set
'//if ((mem56 & 128)=0)
If (mem50 And 128) = 0 Then
'//47935: BIT 50
'//47937: BMI 47943
If mem48 <> 0 Then
mem48 = mem48 + 1
End If
Else
mem48 = mem48 - 1
End If
End If
'//pos47945:
Write mem47, Y, mem48
Wend '//while No. 3
'//pos47952:
mem47 = mem47 + 1
'//if (mem47 != 175) goto pos47810;
Loop Until mem47 = 175 '//while No. 2
End If
'//pos47963:
mem44 = mem44 + 1
X = mem44
Wend '//while No. 1
'//goto pos47701;
'//pos47970:
' add the length of this phoneme
mem48 = mem49 + arrPhoLengthOutput(mem44)
' 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).
' don't adjust pitch if in sing mode
If singmode = 0 Then
' iterate through the buffer
For i = 0 To 255
' subtract half the frequency of the formant 1.
' this adds variety to the voice
arrPitches(i) = arrPitches(i) - (frequency1(i) \ 2)
Next i
End If
phase1 = 0
phase2 = 0
phase3 = 0
mem49 = 0
speedcounter = 72 'sam standard speed
' RESCALE AMPLITUDE
'
' Rescale volume from a linear scale to decibels.
'
'amplitude rescaling
For i = 255 To 0 Step -1
amplitude1(i) = arrAmplitudeRescale(amplitude1(i))
amplitude2(i) = arrAmplitudeRescale(amplitude2(i))
amplitude3(i) = arrAmplitudeRescale(amplitude3(i))
Next i
Y = 0
A = arrPitches(0)
mem44 = A
X = A
mem38 = A - (A \ 4) ' 3/4*A ???
If bDebug Then
PrintOutput sampledConsonantFlag, frequency1, frequency2, frequency3, amplitude1, amplitude2, amplitude3, pitches
End If
' 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:
Do
' get the sampled information on the phoneme
A = sampledConsonantFlag(Y)
mem39 = A
' unvoiced sampled phoneme?
A = A And 248
If A <> 0 Then
' render the sample for the phoneme
RenderSample mem66
' skip ahead two in the phoneme buffer
Y = Y + 2
mem48 = mem48 - 2
Else
' simulate the glottal pulse and formants
mem56 = arrMultTable(BINAND(arrSinus(phase1), amplitude1(Y)))
carry = 0
If (mem56 + arrMultTable(BINAND(arrSinus(phase2), amplitude2(Y)))) > 255 Then
carry = 1
End If
mem56 = mem56 + arrMultTable(BINAND(arrSinus(phase2), amplitude2(Y)))
A = mem56 + arrMultTable(BINAND(arrRectangle(phase3), amplitude3(Y))) + (IIf(carry = 1, 1, 0))
A = ((A + 136) And 255) \ 16 'there must be also a carry
'mem[54296] = A;
' output the accumulated value
' ****************************************************************************************************************************************************************
' *** NOT SURE WHAT THIS IS:
'Output 0, A
' ****************************************************************************************************************************************************************
speedcounter = speedcounter - 1
If speedcounter <> 0 Then
GoTo pos48155
End If
Y = Y + 1 'go to next amplitude
' decrement the frame count
mem48 = mem48 - 1
End If
' if the frame count is zero, exit the loop
If mem48 = 0 Then
Exit Do
End If
speedcounter = speed
pos48155:
' decrement the remaining length of the glottal pulse
mem44 = mem44 - 1
' finished with a glottal pulse?
If mem44 = 0 Then
pos48159:
' fetch the next glottal pulse length
A = arrPitches(Y)
mem44 = A
A = A - (A \ 4)
mem38 = A
' reset the formant wave generators to keep them in
' sync with the glottal pulse
phase1 = 0
phase2 = 0
phase3 = 0
_Continue
End If
' decrement the count
mem38 = mem38 - 1
' is the count non-zero and the sampled flag is zero?
If (mem38 <> 0) Or (mem39 = 0) Then
' reset the phase of the formants to match the pulse
phase1 = phase1 + frequency1(Y)
phase2 = phase2 + frequency2(Y)
phase3 = phase3 + frequency3(Y)
_Continue
End If
' 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
Loop 'while
'#IF 0
' 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();
'#ENDIF
'pos48315:
' DIM tempA AS Integer
' phase1 = A XOR 255
' Y = mem66
' DO
'pos48321:
'
' mem56 = 8
' A = Read(mem47, Y)
'
'pos48327:
' DO
' '48327: ASL A
' '48328: BCC 48337
' tempA = A
' A = A SHL 1
' IF (tempA AND 128) <> 0 THEN
' X = 26
' ' mem[54296] = X;
' bufferPos = bufferPos + 150
' buffer(bufferPos / 50) = (X AND 15) * 16
' ELSE
' 'mem[54296] = 6;
' X = 6
' bufferPos = bufferPos + 150
' buffer(bufferPos / 50) = (X AND 15) * 16
' END IF
'
' FOR X = wait2 TO 1 STEP -1
' 'wait
' NEXT X
' mem56 = mem56 - 1
' LOOP WHILE mem56 <> 0
'
' Y = Y + 1
' phase1 = phase1 + 1
' LOOP WHILE phase1 <> 0
' ' IF phase1 <> 0 GOTO pos48321
' A = 1
' mem44 = 1
' mem66 = Y
' Y = mem49
' RETURN
'#IF 0
'END IF
End Sub ' Render
' SUBROUTINES and FUNCTIONS
Sub AddInflection (mem48 As _Byte, phase1 As _Byte)
' store the location of the punctuation
mem49 = X
A = X
Atemp = A
' backup 30 frames
A = A - 30
' if index is before buffer, point to start of buffer
If Atemp <= 30 Then
A = 0
End If
X = A
' FIXME: Explain this fix better, it's not obvious
' ML : A =, fixes a problem with invalid pitch with '.'
Do While arrPitches(X) = 127
X = X + 1
Loop
' add the inflection direction
A = A + mem48
phase1 = A
' set the inflection
arrPitches(X) = A
' increment the position
X = X + 1
' exit if the punctuation has been reached
If X = mem49 Then
Exit Sub
End If
'goto pos47615;
If arrPitches(X) = 255 Then
GoTo pos48406
End If
A = phase1
GoTo pos48398
pos48406:
pos48398:
'48398: CLC (Carry flag is handled implicitly in QB64 addition)
'48399: ADC 48
' QB64 doesn't have direct carry flag manipulation like assembly,
' so addition handles carries naturally.
End Sub ' AddInflection
Sub SetMouthThroat (mouth As _Byte, throat As _Byte)
Dim initialFrequency As _Byte, newFrequency As _Byte
Dim posV As _Byte ' *** original variable name "pos" is reserved in QB64
' mouth formants (F1) 5..29 (Data already initialized)
' throat formants (F2) 5..29 (Data already initialized)
' formant 1 frequencies (mouth) 48..53 (Data already initialized)
' formant 2 frequencies (throat) 48..53 (Data already initialized)
posV = 5
'pos38942:
' recalculate formant frequencies 5..29 for the mouth (F1) and throat (F2)
Do While posV <> 30
' recalculate mouth frequency
initialFrequency = arrMouthFormants5_29(posV)
If initialFrequency <> 0 Then
newFrequency = trans(mouth, initialFrequency)
End If
arrFreq1Data(posV) = newFrequency
' recalculate throat frequency
initialFrequency = arrThroatFormants5_29(posV)
If initialFrequency <> 0 Then
newFrequency = trans(throat, initialFrequency)
End If
arrFreq2Data(posV) = newFrequency
posV = posV + 1
Loop
'pos39059:
' recalculate formant frequencies 48..53
posV = 48
Y = 0
Do While posV <> 54
' recalculate F1 (mouth formant)
initialFrequency = arrMouthFormants48_53(Y)
newFrequency = trans(mouth, initialFrequency)
arrFreq1Data(posV) = newFrequency
' recalculate F2 (throat formant)
initialFrequency = arrThroatFormants48_53(Y)
newFrequency = trans(throat, initialFrequency)
arrFreq2Data(posV) = newFrequency
Y = Y + 1
posV = posV + 1
Loop
End Sub ' SetMouthThroat
'return = (mem39212*mem39213) >> 1
Function trans% (mem39212 As _Byte, mem39213 As _Byte)
'pos39008:
Dim carry As _Byte
Dim temp As Integer ' Using INTEGER for intermediate calculations to avoid overflow
Dim mem39214 As _Byte, mem39215 As _Byte
A = 0
mem39215 = 0
mem39214 = 0
X = 8
Do
carry = mem39212 And 1
mem39212 = mem39212 \ 2 ' Integer division for right shift
If carry <> 0 Then
carry = 0
A = mem39215
temp = A + mem39213
A = A + mem39213
If temp > 255 Then
carry = 1
End If
mem39215 = A
End If
temp = mem39215 And 1
mem39215 = (mem39215 \ 2) Or (carry * 128)
carry = temp
X = X - 1
Loop Until X = 0
temp = mem39214 And 128
mem39214 = (mem39214 * 2) Or carry
carry = temp
temp = mem39215 And 128
mem39215 = (mem39215 * 2) Or carry
carry = temp
trans% = mem39215
End Function ' trans%
' TODO: SOMETHING CALLED RenderSample IS CALLED SEVERAL TIMES IN THE APP
' BUT THE ACTUAL ROUTINE IS MISSING, SO EITHER Gemini DIDN'T CONVERT IT
' OR WE MISSED THE C FILE THAT CONTAINS IT AND NEVER CONVERTED IT?
' SO WE'LL NEED TO FIND & CONVERT THIS:
Sub RenderSample (mem66 As _Byte)
End Sub
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' END render.c
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' BEGIN debug.c
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Sub PrintPhonemes (phonemeindex As _Unsigned _Byte, arrPhonemeLength As _Unsigned _Byte, stress As _Unsigned _Byte)
Dim i As Integer
i = 0
Print "==========================================="
Print "Internal Phoneme presentation:"
Print
Print " idx phoneme length stress"
Print "------------------------------"
Do While (phonemeindex(i) <> 255) And (i < 255) 'UBYTE arrays are indexed from 0 in QB64
If phonemeindex(i) < 81 Then
' Assuming arrSignInputTable1 and arrSignInputTable2 are available
' and are also UBYTE arrays
Print Using " ### \ \ ### #"; i; Chr$(arrSignInputTable1(phonemeindex(i))); Chr$(arrSignInputTable2(phonemeindex(i))); arrPhonemeLength(i); arrStress1(i) 'Format output
Else
Print Using " ### ?? ### #"; phonemeindex(i); arrPhonemeLength(i); arrStress1(i)
End If
i = i + 1
Loop
Print "==========================================="
Print
End Sub ' PrintPhonemes
Sub PrintOutput (flag As _Unsigned _Byte, f1 As _Unsigned _Byte, f2 As _Unsigned _Byte, f3 As _Unsigned _Byte, a1 As _Unsigned _Byte, a2 As _Unsigned _Byte, a3 As _Unsigned _Byte, p As _Unsigned _Byte)
Print "==========================================="
Print "Final data for speech output:"
Print
Print " flags ampl1 freq1 ampl2 freq2 ampl3 freq3 pitch"
Print "------------------------------------------------"
Dim i As Integer
i = 0
Do While i < 255
Print Using " ##### ##### ##### ##### ##### ##### ##### #####"; flag(i); a1(i); f1(i); a2(i); f2(i); a3(i); f3(i); p(i)
i = i + 1
Loop
Print "==========================================="
End Sub ' PrintOutput
'extern uint8_t GetRuleByte(uint16_t mem62, uint8_t Y); => Needs declaration if used
' Assuming GetRuleByte is in another module.
' TODO: Add actual DECLARE FUNCTION if this function is needed in this module
Sub PrintRule (offset As Integer)
Dim i As Integer
Dim A As _Unsigned _Byte
i = 1
Print "Applying rule: ";
Do
' Assuming GetRuleByte returns a UBYTE
A = GetRuleByte(offset, i) 'Need to ensure GetRuleByte is available
If (A And 127) = Asc("=") Then 'Bitwise AND and character comparison
Print " -> ";
Else
Print Chr$(A And 127);
End If
i = i + 1
Loop While (A And 128) = 0
Print
End Sub ' PrintRule
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' END debug.c
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++