VoiceRopeServerToVoiceRopeServerSunRPC.mesa
Copyright Ó 1990, 1992 by Xerox Corporation. All rights reserved.
Pier, May 24, 1990 12:51:46 pm PDT
Swinehart, September 16, 1990 9:58:35 pm PDT
Polle Zellweger, December 28, 1990 12:11 pm PST
VoiceRopeServer is a voice service interface. It is exported to $recording service parties to provide access to procedures for recording and playing voice, and for VoiceRope editing activities.
DIRECTORY
RefID USING [ID],
Rope USING [ROPE],
RuntimeError USING [ UNCAUGHT ],
SRPCCalls USING [
Conversation, Error, GetSHandle, Handle, NewRPCConversation, ReleaseConversation, ReportProc, SHandle, TimeoutEnable],
Thrush,
ThrushSunRPC,
ThrushSunRPCConvert,
VoiceRopeServer,
VoiceRopeServerSunImport,
VoiceRopeServerSunRPC,
VoiceRopeServerSunRPCClient
;
VoiceRopeServerToVoiceRopeServerSunRPC: CEDAR PROGRAM
IMPORTS RuntimeError, SRPCCalls, ThrushSunRPCConvert, VoiceRopeServerSunRPCClient
EXPORTS VoiceRopeServer, VoiceRopeServerSunImport
~ {
OPEN ThrushSunRPCConvert;
VoiceRope: TYPE = VoiceRopeServer.VoiceRope;
VoiceRopeInterval: TYPE = VoiceRopeServer.VoiceRopeInterval;
InterestClass: TYPE = VoiceRopeServer.InterestClass;
Users: TYPE = VoiceRopeServer.Users;
The following two definitions are identical to those in Jukebox; they are reproduced here to avoid a dependency on Jukebox
maxEnergy: INTEGER = VoiceRopeServer.maxEnergy;
EnergyRange: TYPE = VoiceRopeServer.EnergyRange;
EnergySequence: TYPE = VoiceRopeServer.EnergySequence;
EnergySequenceRec: TYPE = VoiceRopeServer.EnergySequenceRec;
VoiceSample: TYPE = VoiceRopeServer.VoiceSample;
VoiceBlock: TYPE = VoiceRopeServer.VoiceBlock;
VoiceBlockRec: TYPE = VoiceRopeServer.VoiceBlockRec;
Interval: TYPE = VoiceRopeServer.Interval;
IntervalSpecs: TYPE = VoiceRopeServer.IntervalSpecs;
sunSHHH: CARD32 = 0;
SHandle: TYPE ~ SRPCCalls.SHandle;
Creating and playing voice ropes
Record: PUBLIC PROC[shhh: Thrush.SHHH ¬ Thrush.none, credentials: Thrush.Credentials, serviceID: RefID.ID, recordedParty: Thrush.PartyID ¬ Thrush.nullID, intID: CARD ¬ 0, queueIt: BOOL ¬ TRUE] RETURNS [nb: Thrush.NB, voiceRope: VoiceRope] = {
ENABLE {
SRPCCalls.Error => { nb ¬ ReportError[shhh, errCode, explanation]; CONTINUE; };
RuntimeError.UNCAUGHT => { nb ¬ ReportError[shhh, $unknownError]; CONTINUE; };
};
srNB: ThrushSunRPC.NB;
srVoiceRope: VoiceRopeServerSunRPC.VoiceRope;
[srNB, srVoiceRope] ¬ VoiceRopeServerSunRPCClient.Record[h: GetInfo[shhh], shhh: sunSHHH, credentials: CredentialsToSr[credentials], serviceID: serviceID, recordedParty: recordedParty, intID: intID, queueIt: queueIt];
nb ¬ SrToATOM[srNB];
voiceRope ¬ SrToVoiceRope[srVoiceRope];
};
Play: PUBLIC PROC[shhh: Thrush.SHHH ¬ Thrush.none, voiceRope: VoiceRope, credentials: Thrush.Credentials, serviceID: RefID.ID, intID: CARD ¬ 0, queueIt: BOOL ¬ TRUE] RETURNS [nb: Thrush.NB] = {
ENABLE {
SRPCCalls.Error => { nb ¬ ReportError[shhh, errCode, explanation]; CONTINUE; };
RuntimeError.UNCAUGHT => { nb ¬ ReportError[shhh, $unknownError]; CONTINUE; };
};
srNB: ThrushSunRPC.NB;
srNB ¬ VoiceRopeServerSunRPCClient.Play[h: GetInfo[shhh], shhh: sunSHHH, voiceRope: VoiceRopeToSr[voiceRope], credentials: CredentialsToSr[credentials], serviceID: serviceID, intID: intID, queueIt: queueIt];
nb ¬ SrToATOM[srNB];
};
Stop: PUBLIC PROC[shhh: Thrush.SHHH ¬ Thrush.none, credentials: Thrush.Credentials, serviceID: RefID.ID] RETURNS [nb: Thrush.NB] = {
ENABLE {
SRPCCalls.Error => { nb ¬ ReportError[shhh, errCode, explanation]; CONTINUE; };
RuntimeError.UNCAUGHT => { nb ¬ ReportError[shhh, $unknownError]; CONTINUE; };
};
srNB: ThrushSunRPC.NB;
srNB ¬ VoiceRopeServerSunRPCClient.Stop[h: GetInfo[shhh], shhh: sunSHHH, creentials: CredentialsToSr[credentials], serviceID: serviceID];
nb ¬ SrToATOM[srNB];
};
Pause: PUBLIC PROC[shhh: Thrush.SHHH ¬ Thrush.none, credentials: Thrush.Credentials, serviceID: RefID.ID] RETURNS [nb: Thrush.NB] = {
ENABLE {
SRPCCalls.Error => { nb ¬ ReportError[shhh, errCode, explanation]; CONTINUE; };
RuntimeError.UNCAUGHT => { nb ¬ ReportError[shhh, $unknownError]; CONTINUE; };
};
Pause playing the scheduled intervals. No effect on recording. No reports at present.
srNB: ThrushSunRPC.NB;
srNB ¬ VoiceRopeServerSunRPCClient.Pause[h: GetInfo[shhh], shhh: sunSHHH, cedentials: CredentialsToSr[credentials], serviceID: serviceID];
nb ¬ SrToATOM[srNB];
};
Resume: PUBLIC PROC[shhh: Thrush.SHHH ¬ Thrush.none, credentials: Thrush.Credentials, serviceID: RefID.ID] RETURNS [nb: Thrush.NB] = {
ENABLE {
SRPCCalls.Error => { nb ¬ ReportError[shhh, errCode, explanation]; CONTINUE; };
RuntimeError.UNCAUGHT => { nb ¬ ReportError[shhh, $unknownError]; CONTINUE; };
};
srNB: ThrushSunRPC.NB;
srNB ¬ VoiceRopeServerSunRPCClient.Resume[h: GetInfo[shhh], shhh: sunSHHH, credentials: CredentialsToSr[credentials], serviceID: serviceID];
nb ¬ SrToATOM[srNB];
};
Interests in voice ropes
Retain: PUBLIC PROC [shhh: Thrush.SHHH ¬ Thrush.none, callerRName: Rope.ROPE, vr: VoiceRope, class: InterestClass, refID: Rope.ROPE, other: Rope.ROPE ¬ NIL] RETURNS [nb: Thrush.NB] = {
ENABLE {
SRPCCalls.Error => { nb ¬ ReportError[shhh, errCode, explanation]; CONTINUE; };
RuntimeError.UNCAUGHT => { nb ¬ ReportError[shhh, $unknownError]; CONTINUE; };
};
srNB: ThrushSunRPC.NB;
srNB ¬ VoiceRopeServerSunRPCClient.Retain[h: GetInfo[shhh], shhh: sunSHHH, callerRName: ROPEToSr[callerRName], vr: VoiceRopeToSr[vr], class: ROPEToSr[class], refID: ROPEToSr[refID], other: ROPEToSr[other] ];
nb ¬ SrToATOM[srNB];
};
Forget: PUBLIC PROC [shhh: Thrush.SHHH ¬ Thrush.none, vr: VoiceRope, class: InterestClass, refID: Rope.ROPE] RETURNS [nb: Thrush.NB] = {
ENABLE {
SRPCCalls.Error => { nb ¬ ReportError[shhh, errCode, explanation]; CONTINUE; };
RuntimeError.UNCAUGHT => { nb ¬ ReportError[shhh, $unknownError]; CONTINUE; };
};
srNB: ThrushSunRPC.NB;
srNB ¬ VoiceRopeServerSunRPCClient.Forget[h: GetInfo[shhh], shhh: sunSHHH, vr: VoiceRopeToSr[vr], class: ROPEToSr[class], refID: ROPEToSr[refID] ];
nb ¬ SrToATOM[srNB];
};
GetByInterest: PUBLIC PROC [shhh: Thrush.SHHH ¬ Thrush.none, class: InterestClass, refID: Rope.ROPE] RETURNS [nb: Thrush.NB, voiceRope: VoiceRope] = {
ENABLE {
SRPCCalls.Error => { nb ¬ ReportError[shhh, errCode, explanation]; CONTINUE; };
RuntimeError.UNCAUGHT => { nb ¬ ReportError[shhh, $unknownError]; CONTINUE; };
};
srNB: ThrushSunRPC.NB;
srVoiceRope: VoiceRopeServerSunRPC.VoiceRope;
[srNB, srVoiceRope] ¬ VoiceRopeServerSunRPCClient.GetByInterest[h: GetInfo[shhh], shhh: sunSHHH, class: ROPEToSr[class], refID: ROPEToSr[refID] ];
nb ¬ SrToATOM[srNB];
voiceRope ¬ SrToVoiceRope[srVoiceRope];
};
Editing voice ropes
Cat: PUBLIC PROC [shhh: Thrush.SHHH ¬ Thrush.none, callerRName: Rope.ROPE, vr1, vr2, vr3, vr4, vr5: VoiceRope ¬ NIL] RETURNS [nb: Thrush.NB, new: VoiceRope] = {
ENABLE {
SRPCCalls.Error => { nb ¬ ReportError[shhh, errCode, explanation]; CONTINUE; };
RuntimeError.UNCAUGHT => { nb ¬ ReportError[shhh, $unknownError]; CONTINUE; };
};
srNB: ThrushSunRPC.NB;
srVoiceRope: VoiceRopeServerSunRPC.VoiceRope;
[srNB, srVoiceRope] ¬ VoiceRopeServerSunRPCClient.Cat[h: GetInfo[shhh], shhh: sunSHHH, callerRName: ROPEToSr[callerRName], vr1: VoiceRopeToSr[vr1], vr2: VoiceRopeToSr[vr2], vr3: VoiceRopeToSr[vr3], vr4: VoiceRopeToSr[vr4], vr5: VoiceRopeToSr[vr5]];
nb ¬ SrToATOM[srNB];
new ¬ SrToVoiceRope[srVoiceRope];
};
Substr: PUBLIC PROC [shhh: Thrush.SHHH ¬ Thrush.none, callerRName: Rope.ROPE, vr: VoiceRope, start: INT ¬ 0, len: INT ¬ LAST[INT]] RETURNS [nb: Thrush.NB, new: VoiceRope] = {
ENABLE {
SRPCCalls.Error => { nb ¬ ReportError[shhh, errCode, explanation]; CONTINUE; };
RuntimeError.UNCAUGHT => { nb ¬ ReportError[shhh, $unknownError]; CONTINUE; };
};
srNB: ThrushSunRPC.NB;
srVoiceRope: VoiceRopeServerSunRPC.VoiceRope;
[srNB, srVoiceRope] ¬ VoiceRopeServerSunRPCClient.Substr[h: GetInfo[shhh], shhh: sunSHHH, callerRName: ROPEToSr[callerRName], vr: VoiceRopeToSr[vr], start: start, len: len];
nb ¬ SrToATOM[srNB];
new ¬ SrToVoiceRope[srVoiceRope];
};
Replace: PUBLIC PROC [shhh: Thrush.SHHH ¬ Thrush.none, callerRName: Rope.ROPE, vr: VoiceRope, start: INT ¬ 0, len: INT ¬ LAST[INT], with: VoiceRope ¬ NIL] RETURNS [nb: Thrush.NB, new: VoiceRope] = {
ENABLE {
SRPCCalls.Error => { nb ¬ ReportError[shhh, errCode, explanation]; CONTINUE; };
RuntimeError.UNCAUGHT => { nb ¬ ReportError[shhh, $unknownError]; CONTINUE; };
};
srNB: ThrushSunRPC.NB;
srVoiceRope: VoiceRopeServerSunRPC.VoiceRope;
[srNB, srVoiceRope] ¬ VoiceRopeServerSunRPCClient.Replace[h: GetInfo[shhh], shhh: sunSHHH, callerRName: ROPEToSr[callerRName], vr: VoiceRopeToSr[vr], start: start, len: len, with: VoiceRopeToSr[with]];
nb ¬ SrToATOM[srNB];
new ¬ SrToVoiceRope[srVoiceRope];
};
Information about voice ropes
Length: PUBLIC PROC [shhh: Thrush.SHHH ¬ Thrush.none, vr: VoiceRope] RETURNS [nb: Thrush.NB, len: INT] = {
ENABLE {
SRPCCalls.Error => { nb ¬ ReportError[shhh, errCode, explanation]; CONTINUE; };
RuntimeError.UNCAUGHT => { nb ¬ ReportError[shhh, $unknownError]; CONTINUE; };
};
srNB: ThrushSunRPC.NB;
[srNB, len] ¬ VoiceRopeServerSunRPCClient.Length[h: GetInfo[shhh], shhh: sunSHHH, vr: VoiceRopeToSr[vr]];
nb ¬ SrToATOM[srNB];
};
DescribeRope: PUBLIC PROC [shhh: Thrush.SHHH ¬ Thrush.none, vr: VoiceRope, minSilence: INT ¬ -1] RETURNS [nb: Thrush.NB, length: INT, noise: IntervalSpecs] = {
ENABLE {
SRPCCalls.Error => { nb ¬ ReportError[shhh, errCode, explanation]; CONTINUE; };
RuntimeError.UNCAUGHT => { nb ¬ ReportError[shhh, $unknownError]; CONTINUE; };
};
srNB: ThrushSunRPC.NB;
srIntervalSpecs: VoiceRopeServerSunRPC.IntervalSpecs;
[srNB, length, srIntervalSpecs] ¬ VoiceRopeServerSunRPCClient.DescribeRope[h: GetInfo[shhh], shhh: sunSHHH, vr: VoiceRopeToSr[vr], minSilence: minSilence];
nb ¬ SrToATOM[srNB];
noise ¬ SrToIntervalSpecs[srIntervalSpecs];
};
GetEnergies: PUBLIC PROC [shhh: Thrush.SHHH ¬ Thrush.none, vr: VoiceRope, samplesPerSegment: [1..8000] ¬ 160] RETURNS [nb: Thrush.NB, energies: EnergySequence] = {
ENABLE {
SRPCCalls.Error => { nb ¬ ReportError[shhh, errCode, explanation]; CONTINUE; };
RuntimeError.UNCAUGHT => { nb ¬ ReportError[shhh, $unknownError]; CONTINUE; };
};
srNB: ThrushSunRPC.NB;
srEnergySequence: VoiceRopeServerSunRPC.EnergySequence;
[srNB, srEnergySequence] ¬ VoiceRopeServerSunRPCClient.GetEnergies[h: GetInfo[shhh], shhh: sunSHHH, vr: VoiceRopeToSr[vr], samplesPerSegment: samplesPerSegment];
nb ¬ SrToATOM[srNB];
energies ¬ SrToEnergySequence[srEnergySequence];
};
Retrieval and storage of voice samples
FetchBlock: PUBLIC PROC [shhh: Thrush.SHHH ¬ Thrush.none, vr: VoiceRope, start: INT, len: INT ¬ 8000, decrypt: BOOLEAN ¬ TRUE] RETURNS [nb: Thrush.NB, block: VoiceBlock] = {
ENABLE {
SRPCCalls.Error => { nb ¬ ReportError[shhh, errCode, explanation]; CONTINUE; };
RuntimeError.UNCAUGHT => { nb ¬ ReportError[shhh, $unknownError]; CONTINUE; };
};
srNB: ThrushSunRPC.NB;
srVoiceBlock: VoiceRopeServerSunRPC.VoiceBlock;
[srNB, srVoiceBlock] ¬ VoiceRopeServerSunRPCClient.FetchBlock[h: GetInfo[shhh], shhh: sunSHHH, vr: VoiceRopeToSr[vr], start: start, len: len, decrypt: decrypt];
nb ¬ SrToATOM[srNB];
block ¬ SrToVoiceBlock[srVoiceBlock];
};
StoreBlock: PUBLIC PROC [shhh: Thrush.SHHH ¬ Thrush.none, block: VoiceBlock, key: Thrush.EncryptionKey ¬ Thrush.nullKey] RETURNS [nb: Thrush.NB, voiceRope: VoiceRope] = {
ENABLE {
SRPCCalls.Error => { nb ¬ ReportError[shhh, errCode, explanation]; CONTINUE; };
RuntimeError.UNCAUGHT => { nb ¬ ReportError[shhh, $unknownError]; CONTINUE; };
};
Creates a new voice rope whose contents are the given block.
srNB: ThrushSunRPC.NB;
srVoiceRope: VoiceRopeServerSunRPC.VoiceRope;
[srNB, srVoiceRope] ¬ VoiceRopeServerSunRPCClient.StoreBlock[h: GetInfo[shhh], shhh: sunSHHH, block: VoiceBlockToSr[block], key: EncryptionKeyToSr[key]];
nb ¬ SrToATOM[srNB];
voiceRope ¬ SrToVoiceRope[srVoiceRope];
};
Access control
SetPermissions: PUBLIC PROC [shhh: Thrush.SHHH ¬ Thrush.none, callerRName: Rope.ROPE, vr: VoiceRope, playAccess: Users, editAccess: Users] RETURNS [nb: Thrush.NB] = {
Restricts access to the specified voice rope. Only the creator of a voice rope may change its access control lists, i.e. invoke this operation.
ENABLE {
SRPCCalls.Error => { nb ¬ ReportError[shhh, errCode, explanation]; CONTINUE; };
RuntimeError.UNCAUGHT => { nb ¬ ReportError[shhh, $unknownError]; CONTINUE; };
};
srNB: ThrushSunRPC.NB;
srNB ¬ VoiceRopeServerSunRPCClient.SetPermissions[h: GetInfo[shhh], shhh: sunSHHH, callerRName: ROPEToSr[callerRName], vr: VoiceRopeToSr[vr], playAccess: UsersToSr[playAccess], editAccess: UsersToSr[editAccess]];
nb ¬ SrToATOM[srNB];
};
GetPermissions: PUBLIC PROC [shhh: Thrush.SHHH ¬ Thrush.none, vr: VoiceRope] RETURNS [nb: Thrush.NB, playAccess: Users, editAccess: Users] = {
ENABLE {
SRPCCalls.Error => { nb ¬ ReportError[shhh, errCode, explanation]; CONTINUE; };
RuntimeError.UNCAUGHT => { nb ¬ ReportError[shhh, $unknownError]; CONTINUE; };
};
srNB: ThrushSunRPC.NB;
srPlayAccess, srEditAccess: VoiceRopeServerSunRPC.Users;
[srNB, srPlayAccess, srEditAccess] ¬ VoiceRopeServerSunRPCClient.GetPermissions[h: GetInfo[shhh], shhh: sunSHHH, vr: VoiceRopeToSr[vr]];
nb ¬ SrToATOM[srNB];
playAccess ¬ SrToUsers[srPlayAccess];
editAccess ¬ SrToUsers[srEditAccess];
};
Handles
GetInfo: PROC[shhh: Thrush.SHHH] RETURNS [h: SRPCCalls.Handle] ~ {
sHandle: SHandle;
IF shhh = NIL THEN SRPCCalls.Error[$noConversationSupplied];
sHandle ¬ SRPCCalls.GetSHandle[shhh];
IF sHandle=NIL THEN SRPCCalls.Error[$invalidConversationSupplied];
h ¬ sHandle.handle;
};
Connecting
sunPgm: CARD ¬ 390912; -- decimal program number for VoiceRopeServer
sunPgmVersion: CARD ¬ 1;
sunCallTimeout: INT ¬ 3000;
sunCallRetries: INT ¬ 3;
sunCallTimeoutEnable: SRPCCalls.TimeoutEnable ¬ always;
ReportProblem: TYPE ~ VoiceRopeServerSunImport.ReportProblem;
VRHandle: TYPE ~ REF VRHandleRec;
VRHandleRec: TYPE ~ RECORD [
reportProblem: ReportProblem,
reportData: REF
];
ImportInterface: PUBLIC PROC [instance: Rope.ROPE, reportProblem: ReportProblem¬NIL, reportData: REF¬NIL] RETURNS [shhh: Thrush.SHHH] ~ {
instance should be a SunRPC address, in the form "sun#[1.2.3.4]#5", where [1.2.3.4] is the Arpa address, and 5 is the port.
vrHandle: VRHandle ¬ NEW[VRHandleRec ¬ [reportProblem, reportData]];
shhh ¬ SRPCCalls.NewRPCConversation[serverName: instance, rpcProgram: sunPgm, rpcVersion: sunPgmVersion, timeoutEnable: sunCallTimeoutEnable, timeoutInMs: sunCallTimeout, retries: sunCallRetries, reportProc: ForwardReports, clientData: vrHandle];
SRPCCalls.GetSHandle[shhh].enabled ¬ TRUE;
};
UnImportInterface: PUBLIC PROC [shhh: Thrush.SHHH] ~ {
SRPCCalls.ReleaseConversation[shhh];
};
ReportError: PROC[shhh: Thrush.SHHH, errCode: ATOM, explanation: Rope.ROPE¬NIL]
RETURNS[nb: Thrush.NB] ~ {
sHandle: SHandle ¬ SRPCCalls.GetSHandle[shhh];
IF sHandle=NIL THEN RETURN;
ForwardReports[sHandle, errCode, explanation];
nb ¬ $callFailed;
};
ForwardReports: SRPCCalls.ReportProc ~ {
vrHandle: VRHandle ¬ NARROW[sHandle.clientData];
IF vrHandle=NIL THEN RETURN; -- Can't report, perhaps handle has been released
vrHandle.reportProblem[vrHandle.reportData, ec, expl];
};
}.
Polle Zellweger (PTZ) August 14, 1990 10:45:24 pm PDT
changes to: DIRECTORY, EXPORTS
Polle Zellweger (PTZ) October 29, 1990 5:13:22 pm PST
Allow detection of NIL ropes across a SunRPC connection.
changes to: Retain, Forget, GetByInterest
Polle Zellweger, December 27, 1990 6:15:26 pm PST
Added callerRName field to operations that need to know the caller's name.
changes to: Retain, Cat, Substr, Replace, SetPermissions