VoiceRopeServerToVoiceRopeServerSunRPC.mesa
Copyright Ó 1990 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