diff --git a/packages/mixer-connection/README.md b/packages/mixer-connection/README.md index 93e7411..962eb2e 100644 --- a/packages/mixer-connection/README.md +++ b/packages/mixer-connection/README.md @@ -561,6 +561,18 @@ This can be used to process all information at once, e.g. for a VU meter dashboa conn.vuProcessor.vuData$; ``` +### VU values in dB + +All VU values are linear values between `0` and `1`. To express the level in dB you need to project the value to the dB range of the meter (`-80..0 dB`). +The exported utility function `vuValueToDB()` helps with that task and can be used as follows: + +```ts +conn.vuProcessor + .master() + .pipe(map(data => vuValueToDB(data.vuPostFaderL))) + .subscribe(/* ... */); +``` + ## Working with raw messages and state The `MixerStore` object exposes raw streams with messages and state data. You can use them for debugging purposes or for integration in other services: diff --git a/packages/mixer-connection/src/index.ts b/packages/mixer-connection/src/index.ts index 0a06ab5..985ba19 100644 --- a/packages/mixer-connection/src/index.ts +++ b/packages/mixer-connection/src/index.ts @@ -7,3 +7,4 @@ export { Easings } from './lib/utils/transitions/easings'; export * from './lib/vu/vu-processor'; export * from './lib/vu/vu.types'; +export { vuValueToDB } from './lib/vu/vu.utils'; diff --git a/packages/mixer-connection/src/lib/vu/vu.utils.ts b/packages/mixer-connection/src/lib/vu/vu.utils.ts index d84c01c..ad2e73e 100644 --- a/packages/mixer-connection/src/lib/vu/vu.utils.ts +++ b/packages/mixer-connection/src/lib/vu/vu.utils.ts @@ -1,5 +1,19 @@ +import { linearMappingValueToRange } from '../utils/value-converters/value-converters'; import { VuData } from './vu.types'; +/** convert linear VU value (between `0`..`1`) to dB (between `-80`..`0`) + * + * ```ts + * // Example + * conn.vuProcessor.master().pipe( + * map(data => vuValueToDB(data.vuPostFaderL)) + * ); + * ``` + */ +export function vuValueToDB(linearValue: number) { + return linearMappingValueToRange(linearValue, -80, 0); +} + /** convert base64 VU data to array */ export function vuMessageToArray(vuMessage: string): Uint8Array { /** diff --git a/packages/testbed/src/app/pages/vu/vu.component.html b/packages/testbed/src/app/pages/vu/vu.component.html index 798dc90..1a667cd 100644 --- a/packages/testbed/src/app/pages/vu/vu.component.html +++ b/packages/testbed/src/app/pages/vu/vu.component.html @@ -15,6 +15,8 @@

{{ c.label }}


+

Master Post Fader L: {{ masterPostFaderLDB$ | async }} dB

+ @for (c of stereoChannels; track c) {

{{ c.label }}

diff --git a/packages/testbed/src/app/pages/vu/vu.component.ts b/packages/testbed/src/app/pages/vu/vu.component.ts index ed67807..6061112 100644 --- a/packages/testbed/src/app/pages/vu/vu.component.ts +++ b/packages/testbed/src/app/pages/vu/vu.component.ts @@ -2,6 +2,8 @@ import { AsyncPipe, JsonPipe } from '@angular/common'; import { ChangeDetectionStrategy, Component, inject, signal } from '@angular/core'; import { ConnectionService } from '../../connection.service'; import { VuMeterComponent } from '../../ui/vu-meter/vu-meter.component'; +import { map } from 'rxjs'; +import { vuValueToDB } from 'soundcraft-ui-connection'; @Component({ selector: 'sui-vu', @@ -38,4 +40,6 @@ export class VuComponent { { vuData: this.vuProcessor.sub(1), label: 'Sub group 1', type: 'stereo' }, { vuData: this.vuProcessor.sub(2), label: 'Sub group 2', type: 'stereo' }, ]; + + masterPostFaderLDB$ = this.vuProcessor.master().pipe(map(data => vuValueToDB(data.vuPostFaderL))); }