feat(tci): receive audio over the TCI WebSocket (experimental)
A SunSDR already carries its receive audio on the same WebSocket as its commands, so a virtual audio cable and a second sound card are two pieces of plumbing an operator installs for no reason. This is the receive half: what the QSO recorder and the CW decoder need. The reader now looks at the frame type. It used to ignore it and split every frame on ';' -- harmless only for as long as no stream was ever opened, since audio bytes would otherwise have been handed to the command parser a hundred times a second. NOTHING HERE IS CONFIRMED ON A RADIO. The header layout comes from the TCI documentation, and the stream-type numbers are exactly the sort of detail a document gets right and a memory of it does not -- so the first forty frames of a session are logged verbatim, and a test bench in Preferences > Audio reports the sample rate the radio chose, the frames arriving and the peak level of the last second. 'The stream is open' and 'audio is arriving' are different claims and only the second is worth anything to whoever tries this first. Transmit (the voice keyer) is the other half and is deliberately absent: it has to answer the radio's chrono packets at the right pace, and that is worth doing once the format is settled on real hardware.
This commit is contained in:
Vendored
+6
@@ -575,6 +575,8 @@ export function GetStationSettings():Promise<main.StationSettings>;
|
||||
|
||||
export function GetStationStatus():Promise<Array<main.StationDeviceStatus>>;
|
||||
|
||||
export function GetTCIAudioStatus():Promise<cat.TCIAudioStatus>;
|
||||
|
||||
export function GetTelemetryEnabled():Promise<boolean>;
|
||||
|
||||
export function GetTrackedAwards():Promise<Array<string>>;
|
||||
@@ -1207,10 +1209,14 @@ export function SetYaesuVOX(arg1:boolean):Promise<void>;
|
||||
|
||||
export function StartCWDecoder():Promise<void>;
|
||||
|
||||
export function StartTCIAudio(arg1:number,arg2:number):Promise<void>;
|
||||
|
||||
export function StationSetRelay(arg1:string,arg2:number,arg3:boolean):Promise<void>;
|
||||
|
||||
export function StopCWDecoder():Promise<void>;
|
||||
|
||||
export function StopTCIAudio():Promise<void>;
|
||||
|
||||
export function SwitchCATRig(arg1:number):Promise<void>;
|
||||
|
||||
export function SyncFolderNow():Promise<number>;
|
||||
|
||||
@@ -1090,6 +1090,10 @@ export function GetStationStatus() {
|
||||
return window['go']['main']['App']['GetStationStatus']();
|
||||
}
|
||||
|
||||
export function GetTCIAudioStatus() {
|
||||
return window['go']['main']['App']['GetTCIAudioStatus']();
|
||||
}
|
||||
|
||||
export function GetTelemetryEnabled() {
|
||||
return window['go']['main']['App']['GetTelemetryEnabled']();
|
||||
}
|
||||
@@ -2354,6 +2358,10 @@ export function StartCWDecoder() {
|
||||
return window['go']['main']['App']['StartCWDecoder']();
|
||||
}
|
||||
|
||||
export function StartTCIAudio(arg1, arg2) {
|
||||
return window['go']['main']['App']['StartTCIAudio'](arg1, arg2);
|
||||
}
|
||||
|
||||
export function StationSetRelay(arg1, arg2, arg3) {
|
||||
return window['go']['main']['App']['StationSetRelay'](arg1, arg2, arg3);
|
||||
}
|
||||
@@ -2362,6 +2370,10 @@ export function StopCWDecoder() {
|
||||
return window['go']['main']['App']['StopCWDecoder']();
|
||||
}
|
||||
|
||||
export function StopTCIAudio() {
|
||||
return window['go']['main']['App']['StopTCIAudio']();
|
||||
}
|
||||
|
||||
export function SwitchCATRig(arg1) {
|
||||
return window['go']['main']['App']['SwitchCATRig'](arg1);
|
||||
}
|
||||
|
||||
@@ -1208,6 +1208,28 @@ export namespace cat {
|
||||
this.fixed = source["fixed"];
|
||||
}
|
||||
}
|
||||
export class TCIAudioStatus {
|
||||
running: boolean;
|
||||
sample_rate: number;
|
||||
frames: number;
|
||||
samples: number;
|
||||
peak_db: number;
|
||||
last_err?: string;
|
||||
|
||||
static createFrom(source: any = {}) {
|
||||
return new TCIAudioStatus(source);
|
||||
}
|
||||
|
||||
constructor(source: any = {}) {
|
||||
if ('string' === typeof source) source = JSON.parse(source);
|
||||
this.running = source["running"];
|
||||
this.sample_rate = source["sample_rate"];
|
||||
this.frames = source["frames"];
|
||||
this.samples = source["samples"];
|
||||
this.peak_db = source["peak_db"];
|
||||
this.last_err = source["last_err"];
|
||||
}
|
||||
}
|
||||
export class YaesuTXState {
|
||||
available: boolean;
|
||||
model?: string;
|
||||
|
||||
Reference in New Issue
Block a user