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: BOOLTRUE] 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.ROPENIL] 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: INTLAST[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: INTLAST[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: BOOLEANTRUE] 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: REFNIL] 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