adds mono-mode
This commit is contained in:
@@ -20,3 +20,4 @@ lerna-debug.log
|
||||
/certs/localhost-key.pem
|
||||
/packages/app/soundfont/public/soundfonts/
|
||||
/packages/studio/scripting/src/api.declaration.d.ts
|
||||
tsconfig.tsbuildinfo
|
||||
|
||||
+19
-14
@@ -28,7 +28,7 @@ type Construct = {
|
||||
}
|
||||
|
||||
export const AudioUnitChannelControls = ({lifecycle, service, adapter}: Construct) => {
|
||||
const {project, audioContext} = service
|
||||
const {project} = service
|
||||
const {captureDevices, editing, midiLearning} = project
|
||||
const {volume, panning, mute, solo} = adapter.namedParameter
|
||||
const volumeControl = (
|
||||
@@ -77,20 +77,20 @@ export const AudioUnitChannelControls = ({lifecycle, service, adapter}: Construc
|
||||
attachParameterContextMenu(editing, midiLearning, adapter.tracks, panning, panningControl),
|
||||
attachParameterContextMenu(editing, midiLearning, adapter.tracks, mute, muteControl),
|
||||
attachParameterContextMenu(editing, midiLearning, adapter.tracks, solo, soloControl),
|
||||
captureOption.ifSome(capture => {
|
||||
if (!isInstanceOf(capture, CaptureAudio)) {return}
|
||||
const streamLifeCycle = lifecycle.own(new Terminator())
|
||||
capture.stream.catchupAndSubscribe(optStream => {
|
||||
captureOption.match({
|
||||
none: () => Terminable.Empty,
|
||||
some: capture => {
|
||||
if (!isInstanceOf(capture, CaptureAudio)) {return Terminable.Empty}
|
||||
const meterLifeCycle = lifecycle.own(new Terminator())
|
||||
const connectMeter = () => {
|
||||
streamRunning = false
|
||||
streamLifeCycle.terminate()
|
||||
return optStream.ifSome(stream => {
|
||||
const numberOfChannels = stream.getAudioTracks().at(0)?.getSettings().channelCount ?? 2
|
||||
meterLifeCycle.terminate()
|
||||
capture.outputNode.ifSome(outputNode => {
|
||||
const numberOfChannels = capture.effectiveChannelCount
|
||||
const meterWorklet = service.audioWorklets.createMeter(numberOfChannels)
|
||||
const streamSource = audioContext.createMediaStreamSource(stream)
|
||||
streamSource.connect(meterWorklet)
|
||||
outputNode.connect(meterWorklet)
|
||||
streamRunning = true
|
||||
streamLifeCycle.ownAll(
|
||||
Terminable.create(() => streamSource.disconnect()),
|
||||
meterLifeCycle.ownAll(
|
||||
meterWorklet.subscribe(({peak}) => {
|
||||
peaksInDb[0] = gainToDb(peak[0])
|
||||
peaksInDb[1] = gainToDb(peak[1] ?? peak[0])
|
||||
@@ -98,8 +98,13 @@ export const AudioUnitChannelControls = ({lifecycle, service, adapter}: Construc
|
||||
meterWorklet
|
||||
)
|
||||
})
|
||||
})
|
||||
}) ?? Terminable.Empty,
|
||||
}
|
||||
return Terminable.many(
|
||||
capture.stream.catchupAndSubscribe(() => connectMeter()),
|
||||
capture.captureBox.requestChannels.subscribe(() => connectMeter())
|
||||
)
|
||||
}
|
||||
}),
|
||||
project.liveStreamReceiver.subscribeFloats(adapter.address, values => {
|
||||
if (streamRunning) {return}
|
||||
peaksInDb[0] = gainToDb(values[0])
|
||||
|
||||
@@ -25,7 +25,6 @@ export class CaptureAudio extends Capture<CaptureAudioBox> {
|
||||
#isMonitoring: boolean = false
|
||||
#requestChannels: Option<1 | 2> = Option.None
|
||||
#gainDb: number = 0.0
|
||||
|
||||
#audioChain: Nullable<{
|
||||
sourceNode: MediaStreamAudioSourceNode
|
||||
gainNode: GainNode
|
||||
@@ -78,9 +77,7 @@ export class CaptureAudio extends Capture<CaptureAudioBox> {
|
||||
}
|
||||
get gainDb(): number {return this.#gainDb}
|
||||
get requestChannels(): Option<1 | 2> {return this.#requestChannels}
|
||||
set requestChannels(value: 1 | 2) {
|
||||
this.captureBox.requestChannels.setValue(value)
|
||||
}
|
||||
set requestChannels(value: 1 | 2) {this.captureBox.requestChannels.setValue(value)}
|
||||
get stream(): MutableObservableOption<MediaStream> {return this.#stream}
|
||||
get streamDeviceId(): Option<string> {
|
||||
return this.streamMediaTrack.map(settings => settings.getSettings().deviceId ?? "")
|
||||
@@ -90,6 +87,8 @@ export class CaptureAudio extends Capture<CaptureAudioBox> {
|
||||
get streamMediaTrack(): Option<MediaStreamTrack> {
|
||||
return this.#stream.flatMap(stream => Option.wrap(stream.getAudioTracks().at(0)))
|
||||
}
|
||||
get outputNode(): Option<AudioNode> {return Option.wrap(this.#audioChain?.gainNode)}
|
||||
get effectiveChannelCount(): number {return this.#audioChain?.gainNode.channelCount ?? 1}
|
||||
|
||||
async prepareRecording(): Promise<void> {
|
||||
const {project} = this.manager
|
||||
@@ -157,8 +156,8 @@ export class CaptureAudio extends Capture<CaptureAudioBox> {
|
||||
const gotDeviceId = settings?.deviceId
|
||||
console.debug(`new stream. device requested: ${deviceId ?? "default"}, got: ${gotDeviceId ?? "unknown"}. channelCount requested: ${channelCount}, got: ${settings?.channelCount}`)
|
||||
if (isUndefined(deviceId) || deviceId === gotDeviceId) {
|
||||
this.#stream.wrap(stream)
|
||||
this.#rebuildAudioChain(stream)
|
||||
this.#stream.wrap(stream)
|
||||
} else {
|
||||
stream.getAudioTracks().forEach(track => track.stop())
|
||||
return Errors.warn(`Could not find audio device with id: '${deviceId}' (got: '${gotDeviceId}')`)
|
||||
@@ -209,7 +208,8 @@ export class CaptureAudio extends Capture<CaptureAudioBox> {
|
||||
|
||||
#disconnectMonitoring(): void {
|
||||
if (isDefined(this.#audioChain)) {
|
||||
this.#audioChain.gainNode.disconnect()
|
||||
const {audioContext} = this.manager.project.env
|
||||
this.#audioChain.gainNode.disconnect(audioContext.destination)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user