/* PROGRAM SPEECH Code conversion by Eugene Klein Produce speech using General Instrument's SPO256 Speech Processor. The chip has 64 address locations each identifying instructions for sounding an allophone. The chip's output should be fed to an audio amplifier. */ #include#include #include #include #include #include #include "My_TPU.h" /* NOTE: The pound sign, "#", in front of a number, tells the Turbo Pascal compiler that the number is an ASCII value to be assigned to the character variable in front of the equal sign. Allophone information based on General Instruments' Data Sheets, and Radio Shack Data sheet packaged with item 276-1784. DATA SHEET DICTIONARY ALLOPHONE PRONUNCIATION SYMBOL SYMBOL NOTES */ #define AA 24 // Д #define AE 26 // a #define AO 23 // Г #define AR 59 // Дr #define AW 32 // ou #define AX 15 // u #define AY 6 // Н #define BB1 28 // b final position // b between vowels, or in clusters #define BB2 63 // b initial position before a vowel #define CH 50 // ch #define DD1 21 // d final position #define DD2 33 // d initial positin #define DH1 18 // th word's initial position #define DH2 54 // th word's final position // th between vowels #define EH 7 // e #define EL 62 // l #define ER1 51 // ar #define ER2 52 // ur #define EY 20 // Е #define FF 40 // silent, use singly in final position #define GG1 36 // g before high front vowels: ir, К, i, Е, e, er #define GG2 61 // g before high back vowels: ХХ, oo, Х, oi, u // g before clusters #define GG3 34 // g before low vowels: a, ou, Н, Дr, Д, Г, Уr, ar, ur // medical clusters // g final position #define HH1 27 // h before front vowels: ir, К, i, К, e, er, a #define HH2 57 // h before back vowels: ХХ, oo, Х, oi, Г, Уr, Дr #define IH 12 // i #define IY 19 // К #define JH 10 // j #define KK1 42 // k before front vowels // ir, К, i, Е, e, er, Н, a, ar, ur, u // k initial clusters #define KK2 41 // k final position #define KK3 8 // k before back vowel:ХХ, oo, Х, oi, Уr, Дr, Г #define LL 45 // L #define MM 16 // m #define NG 44 // ng #define NN1 11 // n before front and central vowels: // ir, К, i, Е, e, er, a, ar, ur, u, ou, Н, Х // n final clusters #define NN2 56 // n before back vowels: oo, Х, oi, Уr, Дr, Г #define ORR 58 // Уr #define OW 53 // Х #define OY 5 // oi #define PP1 9 // P #define RR1 14 // _R initial position beginning of word #define RR2 39 // r initial cluster #define SH 37 // sh #define SS 55 // silent #define TH 29 // silent #define TT1 17 // t final cluster before SS #define TT2 13 // t all other positions #define UH 30 // oo #define UW1 22 // ХХ after y #define UW2 31 // ХХ in one syllable words #define VV 35 // V #define WH 48 // hW #define WW 46 // W #define XR 47 // er #define YR 60 // ir #define YY1 49 // y clusters #define YY2 25 // Y initial position #define ZH 38 // Zh #define ZZ 43 // z #define PA1 0 // pause 10 ms, before BB, DD, GG, and JH #define PA2 1 // pause 30 ms, before BB, DD, GG, and JH #define PA3 2 // pause 50 ms, before PP, TT, KK, and CH, and between words #define PA4 3 // pause 100 ms, between clauses and sentences #define PA5 4 // pause 200 ms, between clauses and sentences // allophones proceeded by "", can be doubled unsigned char E; unsigned int Lpt_Num, Lpt_Port_Address; void Speak(char *Phrase,int Size) { /* Transmit each allophone byte of phrase to SPO256. Procedure will only transmit to LPT1. Similar to using BASIC'S LPRINT, or Pascal's WRITE commands */ unsigned char N; for(N=0;N<Size;N++) { putc(Phrase[N],stdprn); delay(30); // put data on data lines } } void Say(char *Phrase,int Size) { /* Transmit each allophone byte of phrase to SPO256. Will transmit on LPT1, LPT2, or LPT3. */ const int D7 = 128; unsigned char N, Temp; for(N=0;N<Size;N++) { /* Check speech chip's standby line, LRQ, ( D7, at pin 10 on printer port When LRQ is logic high, chip can accept new data. */ while(( inport(Lpt_Port_Address + 1) & D7 ) == 0); // ok to transmit? { /* D0 set HIGH = 0. Why? Because you have to account for inverteed logic All four control lines, at LPT Port Address + 2, are set to inactive logic levels by sending 10, binary 00001010. Remember, Storbe line is inverted. High is 0, Low is 1. */ outport(Lpt_Port_Address + 2,10); // set all control bits to inactive outport(Lpt_Port_Address,Phrase[N]); // put data on data lines outport(Lpt_Port_Address + 2,11); // set strobe, D0, to active LOW outport(Lpt_Port_Address + 2,10); // set strobe, D0, to inactive HIGH } } } void main() { // define words by allophone sounds char Computer[]= {KK1,AX,PA1,MM,PP1,YY1,UW1,TT2,ER1,PA3}; char Talking[]= {TT2,AO,AO,PA3,KK1,IH,NG,PA3}; char Hello[]= {HH1,EH,LL,AX,OW,PA5}; // transmit speech allophones via LPT1 Speak(Computer,sizeof(Computer)); Speak(Talking,sizeof(Talking)); delay(250); Speak(Hello,sizeof(Hello)); // alternete method of sending speech allophones to LPT1, LPT2, or LPT3 Lpt_Num = Select_Printer_Port(); Lpt_Port_Address = Init_Printer_Port(Lpt_Num); Say(Computer,sizeof(Computer)); Say(Talking,sizeof(Talking)); delay(250); Say(Hello,sizeof(Hello)); }