DIRECTORY
Commander USING [ CommandProc, Register ],
IO,
LarkSynthesizer USING [ AddText, SynthFlush ],
RefID USING [ ID, nullID ],
LarkSmartsMonitorImpl,
Rope USING [ ROPE ],
RPC USING [ EncryptionKey, ExportFailed ],
Synthesizer USING [ ActionID, SynthSpec, SynthSpecBody ],
SynthesizerServer,
SynthesizerServerRpcControl USING [ ExportInterface ],
ThParty USING [ RegisterServiceInterface, ReportAction ],
Thrush USING [ ActionType, Credentials, InterfaceSpec, NB, noAddress, SHHH, PartyID, SmartsID ],
ThSmartsPrivate USING [ ConvDesc, GetConv, GetSmartsInfo, LarkInfo, RegisterServiceProvider, SmartsInfo ],
VoiceUtils USING [ CmdOrToken, CurrentPasskey, MakeRName, Problem, ReportFR ]
;
LarkSmartsSynthImpl:
CEDAR MONITOR
LOCKS root
IMPORTS Commander, IO, LarkSynthesizer, root: LarkSmartsMonitorImpl, RPC, SynthesizerServerRpcControl, ThParty, ThSmartsPrivate, VoiceUtils
EXPORTS LarkSynthesizer, SynthesizerServer
SHARES LarkSmartsMonitorImpl= {
OPEN IO;
Types and Values
LarkInfo: TYPE = ThSmartsPrivate.LarkInfo;
RequestClientData: TYPE = REF RequestClientDataBody;
RequestClientDataBody:
TYPE =
RECORD [
cDesc: ThSmartsPrivate.ConvDesc,
requestingParty: Thrush.PartyID
];
synthesizerServerSpec: Thrush.InterfaceSpec ← [interfaceName: [type: "SynthesizerServer"], serviceID: RefID.nullID];
synthesizerServerUser: Rope.ROPE;
synthesizerServerPassword: RPC.EncryptionKey;
New request from service to Lark:
TextToSpeech:
PUBLIC
ENTRY
PROC
--
TAKES -- [
shhh: Thrush.SHHH,
credentials: Thrush.Credentials, -- authenticates caller
serviceID: RefID.ID, -- identifies particular service
textToSpeak: Rope.ROPE,
actionID: Synthesizer.ActionID,
filter: BOOL,
queueIt: BOOL
]
RETURNS [nb: Thrush.NB] = {
ENABLE UNWIND => NULL;
larkInfo: LarkInfo;
cDesc: ThSmartsPrivate.ConvDesc;
synthSpec: Synthesizer.SynthSpec;
[nb, larkInfo, cDesc] ← SynthVerify[credentials, serviceID];
IF nb # $success THEN RETURN;
synthSpec ←
NEW[Synthesizer.SynthSpecBody ← [
textToSpeak: textToSpeak, actionID: actionID,
clientData: NEW[RequestClientDataBody ← [cDesc, credentials.partyID]]
]];
LarkSynthesizer.AddText[
info: larkInfo,
synthSpec: synthSpec,
filter: filter,
queueIt: queueIt
];
SynthReport[synthSpec, $scheduled];
};
StopSpeech:
PUBLIC ENTRY PROC
--
TAKES -- [
shhh: Thrush.SHHH,
credentials: Thrush.Credentials,
serviceID: RefID.ID,
reset: BOOL
]
RETURNS [nb: Thrush.NB] = {
ENABLE UNWIND => NULL;
larkInfo: LarkInfo;
[nb, larkInfo] ← SynthVerify[credentials, serviceID];
IF nb=$success THEN LarkSynthesizer.SynthFlush[larkInfo];
};
GetSynthesizerSpecifications:
PUBLIC PROC
--
TAKES -- [
shhh: Thrush.SHHH,
serviceID: RefID.ID
]
RETURNS [ nb: Thrush.NB, synthesizerModel: ATOM, synthesizerVersion: ATOM ] = {
RETURN[$success, $DecTalk, $unspecified]
};
LarkSynthesizerInit: Commander.CommandProc = {
synthesizerServerSpec.interfaceName.instance ← NIL;
synthesizerServerSpec.hostHint ← Thrush.noAddress;
synthesizerServerUser ← VoiceUtils.MakeRName[style: rName, name:
VoiceUtils.CmdOrToken[cmd: cmd, key: "ThrushServerInstance", default: "Strowger.Lark"]];
synthesizerServerPassword ← VoiceUtils.CurrentPasskey[VoiceUtils.CmdOrToken[
cmd: cmd, key: "ThrushServerPassword", default: "MFLFLX"]];
ThSmartsPrivate.RegisterServiceProvider[LarkSynthesizerRegister];
VoiceUtils.ReportFR["Initialize[SynthesizerServer.Lark, %s]", $System, NIL, rope[synthesizerServerUser]];
};
LarkSynthesizerRegister:
PROC[
credentials: Thrush.Credentials, smartsInfo: ThSmartsPrivate.SmartsInfo] = {
ENABLE {
RPC.ExportFailed => { VoiceUtils.Problem["LarkSynthesizer export failed", $System]; GOTO CantExportSynthesizerServer; };
};
exportRequired: BOOL ← synthesizerServerSpec.interfaceName.instance = NIL;
nb: Thrush.NB;
IF ~smartsInfo.larkInfo.textToSpeech THEN RETURN;
synthesizerServerSpec.serviceID ← credentials.smartsID; -- identify self.
[nb, synthesizerServerSpec] ← ThParty.RegisterServiceInterface[credentials: credentials,
interfaceSpecPattern: synthesizerServerSpec];
SELECT nb
FROM $success, $stateMismatch =>
NULL;
ENDCASE => GOTO CantExportSynthesizerServer;
IF exportRequired
THEN SynthesizerServerRpcControl.ExportInterface[
synthesizerServerSpec.interfaceName, synthesizerServerUser, synthesizerServerPassword!
RPC.ExportFailed => GOTO CantExportSynthesizerServer];
EXITS
CantExportSynthesizerServer => {
VoiceUtils.Problem["Couldn't export SynthesizerServer"]; RETURN; };
};
LarkSynthReport:
PUBLIC
ENTRY
PROC
[sS: Synthesizer.SynthSpec, actionType: Thrush.ActionType] = {
ENABLE UNWIND => NULL;
SynthReport[sS, actionType]
};
SynthReport:
INTERNAL
PROC
[sS: Synthesizer.SynthSpec, actionType: Thrush.ActionType] = {
requestClientData: RequestClientData = NARROW[sS.clientData];
cDesc: ThSmartsPrivate.ConvDesc ← requestClientData.cDesc;
nb: Thrush.
NB ← ThParty.ReportAction[
report: [
self: cDesc.situation.self, -- placeholder
other: cDesc.situation.self,
requestingParty: requestClientData.requestingParty,
actionID: sS.actionID,
actionClass: $synthesizer,
actionType: actionType
],
reportToAll: FALSE
].nb;
IF nb#$success THEN NULL; -- Complain?
};
SynthVerify:
INTERNAL
PROC[credentials: Thrush.Credentials, serviceID: Thrush.SmartsID]
RETURNS[
nb: Thrush.NB←$success,
larkInfo: LarkInfo←NIL,
cDesc: ThSmartsPrivate.ConvDesc←NIL
] = {
The kinds of things one needs to get from the client-supplied values. Not much authentication is done here; that would require access to ThParty.Verify.
smartsInfo: ThSmartsPrivate.SmartsInfo ← ThSmartsPrivate.GetSmartsInfo[serviceID];
IF smartsInfo=NIL THEN RETURN[nb: $noSuchSmarts];
larkInfo ← smartsInfo.larkInfo;
cDesc ← ThSmartsPrivate.GetConv[smartsInfo, credentials.convID, FALSE];
IF cDesc=NIL THEN RETURN[nb: $noSuchConv];
};
Commander.Register["LarkSynthesizer", LarkSynthesizerInit, "LarkSynthesizer <ExportInstance[Strowger]> <ServerPassword[...]>\nInitialize and Export Lark Synthesizer Implementation."];