Skip to content

Commit 18980cd

Browse files
committed
mixer model and signals
1 parent 5fa3d69 commit 18980cd

File tree

3 files changed

+105
-23
lines changed

3 files changed

+105
-23
lines changed

src/app/model/camilla-dsp.model.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ export interface CamillaDspConfig {
22
title: string | null;
33
description: string | null;
44
devices: Devices;
5-
mixers: any;
5+
mixers: { [key: string]: Mixer };
66
filters: { [key: string]: Filter };
77
processors: any;
88
pipeline: Pipeline[];
@@ -68,3 +68,28 @@ export interface SignalLevels {
6868
capture_peak: number[];
6969
}
7070

71+
export interface Mixer {
72+
description: string | null;
73+
channels: MixerChannels;
74+
mapping: MixerMapping[];
75+
}
76+
77+
export interface MixerChannels {
78+
in: number;
79+
out: number;
80+
}
81+
82+
export interface MixerMapping {
83+
dest: number;
84+
sources: MixerSource[];
85+
mute: boolean | null;
86+
}
87+
88+
export interface MixerSource {
89+
channel: number;
90+
gain: number;
91+
inverted: boolean | null;
92+
mute: boolean;
93+
scale: string | null;
94+
}
95+

src/app/pages/camilla-dsp/camilla-dsp.page.html

Lines changed: 53 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,30 @@
1616

1717
<div class="p-4">
1818
<h1 class="text-2xl font-bold mb-4">CamillaDSP Control</h1>
19+
<ion-input placeholder="WebSocket URL" [(ngModel)]="CAMILLA_URL"></ion-input>
1920
<p class="mb-2">Connection Status: <strong>{{ connectionStatus }}</strong></p>
20-
<ion-button (click)="connect()" >Connect</ion-button>
21+
<ion-button (click)="connect()">Connect</ion-button>
2122
<ion-button (click)="disconnect()">Disconnect</ion-button>
22-
<ion-button (click)="getState()" >Get State</ion-button>
23+
<ion-button (click)="getState()">Get State</ion-button>
2324
<ion-button (click)="getConfigJson()">Get Config JSON</ion-button>
24-
<ion-button (click)="getConfigYaml()" >Get Config YAML</ion-button>
25-
<ion-button (click)="getUpdateInterval()" >Get Update Interval</ion-button>
26-
<ion-button (click)="getCaptureSignalLevels()" >Get Capture Signal Levels</ion-button>
27-
<ion-button (click)="setUpdateInterval(100)" >Set update Interval</ion-button>
28-
25+
<ion-button (click)="getConfigYaml()">Get Config YAML</ion-button>
26+
<ion-button (click)="getUpdateInterval()">Get Update Interval</ion-button>
27+
<ion-button (click)="getCaptureSignalLevels()">Get Capture Signal Levels</ion-button>
28+
<ion-button (click)="setUpdateInterval(100)">Set update Interval</ion-button>
29+
<ion-button (click)="getVolume()">Get Volume</ion-button>
30+
<ion-range min="-150" max="50" step="1" [(ngModel)]="currentVolume" (ionChange)="setVolume(currentVolume)">
31+
<ion-label slot="start">Volume: {{ currentVolume }}</ion-label>
32+
</ion-range>
33+
"
34+
2935
<pre class="bg-gray-100 p-4 rounded mt-4 overflow-auto">{{ lastMessage | json }}</pre>
3036
<pre class="bg-gray-100 p-4 rounded mt-4 overflow-auto">{{ parsedConfig | json }}</pre>
3137
</div>
38+
3239
<div *ngIf="levels" class="ion-margin">
3340
<h2 class="text-xl font-bold mb-2">Signal Levels</h2>
3441
<div *ngIf="levels" class="ion-margin">
35-
<h2>Capture (Snapcast Signal)</h2>
42+
<h2>Capture (Snapcast Signal)</h2>
3643
<p>Capture RMS 0{{ levels.capture_rms[0] }} dB</p>
3744
<div class="bar" [style.width]="levels.capture_rms[0] + 600+ 'px'"></div>
3845
<p>Capture RMS 1{{ levels.capture_rms[1] }} dB</p>
@@ -41,7 +48,7 @@ <h2>Capture (Snapcast Signal)</h2>
4148
<div class="bar" [style.width]="levels.capture_peak[0] + 600+ 'px'"></div>
4249
<p>Capture Peak 1 {{ levels.capture_peak[1] }} dB</p>
4350
<div class="bar" [style.width]="levels.capture_peak[1] + 600+ 'px'"></div>
44-
51+
4552
<h2>Playback</h2>
4653

4754
<p>Playback RMS 0{{ levels.playback_rms[0] }} dB</p>
@@ -56,24 +63,50 @@ <h2>Playback</h2>
5663
</div>
5764
<div *ngIf="parsedConfig" class="ion-margin">
5865
<h2 class="text-xl font-bold mb-2">Parsed Configuration</h2>
59-
<div *ngFor="let filter of parsedConfig.filters | keyvalue" >
60-
{{ filter.key }}:
61-
<ion-item>
66+
<div *ngFor="let filter of parsedConfig.filters | keyvalue">
67+
{{ filter.key }}:
68+
<ion-item>
6269
Type: {{ filter.value.type }}
63-
</ion-item>
64-
<ion-item>
70+
</ion-item>
71+
<ion-item>
6572
Gain: {{ filter.value.parameters.gain }}
66-
<ion-range min="-24" max="24" step="0.1" [(ngModel)]="filter.value.parameters.gain" (ionChange)="updateFilterParameter(filter.key, 'gain', filter.value.parameters.gain)"></ion-range>
67-
</ion-item>
73+
<ion-range min="-24" max="24" step="0.1" [(ngModel)]="filter.value.parameters.gain"
74+
(ionChange)="updateFilterParameter(filter.key, 'gain', filter.value.parameters.gain)"></ion-range>
75+
</ion-item>
6876
<ion-item>
69-
Frequency: {{ filter.value.parameters.freq }}
77+
Frequency: {{ filter.value.parameters.freq }}
7078
</ion-item>
7179
<ion-item>
72-
Q: {{ filter.value.parameters.q }}
80+
Q: {{ filter.value.parameters.q }}
7381
</ion-item>
74-
<!-- <ion-item *ngFor="let param of filter.value.parameters | keyvalue">
82+
<!-- <ion-item *ngFor="let param of filter.value.parameters | keyvalue">
7583
{{ param.key }}: {{ param.value }}
7684
<ion-range min="0" max="1" step="0.01" [(ngModel)]="param.value" (ionChange)="updateFilterParameter(filter.key, param.key, param.value)"></ion-range>
7785
<ion-input type="number" [(ngModel)]="param.value" (ionChange)="updateFilterParameter(filter.key, param.key, param.value)"></ion-input>
7886
</ion-item> -->
79-
</div>
87+
</div>
88+
<div *ngFor="let mixer of parsedConfig.mixers | keyvalue">
89+
{{ mixer.key }}:
90+
<ion-item>
91+
Channels: {{ mixer.value.channels }}
92+
</ion-item>
93+
<div *ngFor="let mapping of mixer.value.mapping, let i = index">
94+
<p>Destination {{ mapping.dest }}
95+
<span *ngIf="i === 0"> (Left)</span>
96+
<span *ngIf="i === 1"> (Right)</span>
97+
</p>
98+
<div *ngFor="let source of mapping.sources">
99+
<p>Source {{ source.channel }} - Gain: {{ source.gain }}</p>
100+
<ion-range min="-24" max="24" step="0.1" [(ngModel)]="source.gain"
101+
(ionChange)="updateMixerMapping(source, mixer.key)"></ion-range>
102+
<p>Inverted: {{ source.inverted}}</p>
103+
<ion-toggle [(ngModel)]="source.inverted" (ionChange)="updateMixerMapping(source, mixer.key)"></ion-toggle>
104+
<p>Muted: {{ source.mute}}</p>
105+
<ion-toggle [(ngModel)]="source.mute" (ionChange)="updateMixerMapping(source, mixer.key)"></ion-toggle>
106+
</div>
107+
108+
</div>
109+
</div>
110+
111+
112+
</div>

src/app/pages/camilla-dsp/camilla-dsp.page.ts

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Component, OnDestroy, OnInit } from '@angular/core';
22
import { set } from 'lodash-es';
33
import { Subscription } from 'rxjs';
4-
import { CamillaDspConfig, SignalLevels } from 'src/app/model/camilla-dsp.model';
4+
import { CamillaDspConfig, MixerSource, SignalLevels } from 'src/app/model/camilla-dsp.model';
55
import { CamillaDspService, ConnectionStatus } from 'src/app/services/camilla-dsp.service';
66

77
@Component({
@@ -18,8 +18,9 @@ export class CamillaDspPage implements OnInit, OnDestroy {
1818
private configJson: any = null;
1919
parsedConfig: CamillaDspConfig | null = null;
2020
// Your CamillaDSP URL
21-
private readonly CAMILLA_URL = 'ws://beatnik-client-amp.local:1234';
21+
CAMILLA_URL = 'ws://beatnik-server.local:1234';
2222
levels: SignalLevels | null = null;
23+
currentVolume: number = 0;
2324

2425
private levelSubscription: Subscription | undefined;
2526

@@ -110,6 +111,19 @@ export class CamillaDspPage implements OnInit, OnDestroy {
110111

111112
}
112113

114+
updateMixerMapping(mixerSource:MixerSource, mixerKey: string) {
115+
if (!this.parsedConfig) {
116+
console.error('No configuration loaded.');
117+
return;
118+
}
119+
120+
121+
// Send the full configJson back to CamillaDSP
122+
this.camillaService.sendCommand('SetConfigJson', JSON.stringify(this.parsedConfig));
123+
124+
125+
}
126+
113127
getUpdateInterval() {
114128
this.camillaService.sendCommand('GetUpdateInterval');
115129
}
@@ -125,6 +139,16 @@ export class CamillaDspPage implements OnInit, OnDestroy {
125139
this.camillaService.startLevelUpdates(interval);
126140
}
127141

142+
getVolume() {
143+
this.camillaService.sendCommand('GetVolume');
144+
this.currentVolume = this.lastMessage.GetVolume?.value ?? this.currentVolume;
145+
console.log('Current volume:', this.currentVolume);
146+
}
147+
148+
setVolume(volume: number) {
149+
this.camillaService.sendCommand('SetVolume', volume);
150+
}
151+
128152
ngOnDestroy() {
129153
// Clean up subscriptions to prevent memory leaks
130154
this.subscriptions.unsubscribe();

0 commit comments

Comments
 (0)