Improve meeting audio mixing pipeline
PR and Push Build/Test / build-and-test (push) Successful in 11m22s

This commit is contained in:
2026-05-29 13:47:21 +02:00
parent 9d0f6a1295
commit 740f93f185
18 changed files with 870 additions and 136 deletions
@@ -1,5 +1,4 @@
using System.Threading.Channels;
using Microsoft.Extensions.Options;
using NAudio.CoreAudioApi;
using NAudio.Wave;
@@ -7,23 +6,29 @@ namespace MeetingAssistant.Recording;
public sealed class MicrophoneAudioSource : IMeetingAudioSource
{
private readonly MeetingAssistantOptions options;
private readonly ILogger<MicrophoneAudioSource> logger;
public MicrophoneAudioSource(
IOptions<MeetingAssistantOptions> options,
ILogger<MicrophoneAudioSource> logger)
public MicrophoneAudioSource(ILogger<MicrophoneAudioSource> logger)
{
this.options = options.Value;
this.logger = logger;
}
public IAsyncEnumerable<AudioChunk> CaptureAsync(CancellationToken cancellationToken)
{
return CaptureAsync(new WasapiCapture(), cancellationToken);
return CaptureAsync(new MeetingAssistantOptions(), cancellationToken);
}
private IAsyncEnumerable<AudioChunk> CaptureAsync(IWaveIn capture, CancellationToken cancellationToken)
public IAsyncEnumerable<AudioChunk> CaptureAsync(
MeetingAssistantOptions options,
CancellationToken cancellationToken)
{
return CaptureAsync(new WasapiCapture(), options, cancellationToken);
}
private IAsyncEnumerable<AudioChunk> CaptureAsync(
IWaveIn capture,
MeetingAssistantOptions options,
CancellationToken cancellationToken)
{
capture.WaveFormat = new WaveFormat(options.Recording.SampleRate, 16, options.Recording.Channels);
return CaptureWith(capture, "microphone", logger, cancellationToken);
@@ -94,18 +99,21 @@ public sealed class MicrophoneAudioSource : IMeetingAudioSource
public sealed class SystemAudioSource : IMeetingAudioSource
{
private readonly MeetingAssistantOptions options;
private readonly ILogger<SystemAudioSource> logger;
public SystemAudioSource(
IOptions<MeetingAssistantOptions> options,
ILogger<SystemAudioSource> logger)
public SystemAudioSource(ILogger<SystemAudioSource> logger)
{
this.options = options.Value;
this.logger = logger;
}
public IAsyncEnumerable<AudioChunk> CaptureAsync(CancellationToken cancellationToken)
{
return CaptureAsync(new MeetingAssistantOptions(), cancellationToken);
}
public IAsyncEnumerable<AudioChunk> CaptureAsync(
MeetingAssistantOptions options,
CancellationToken cancellationToken)
{
var capture = new WasapiLoopbackCapture
{