Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Den här artikeln beskriver hur du skapar en Windows Runtime komponent som implementerar gränssnittet IBasicAudioEffect för att skapa anpassade effekter för ljudströmmar. Du kan använda anpassade effekter med AudioGraph, MediaCapture och MediaComposition.
Note
Gränssnittet IBasicAudioEffect är ett Windows Runtime API i Windows.Media.Effects namnområdet. Dessa API:er fungerar på samma sätt i WinUI 3-skrivbordsappar som i UWP. Den största skillnaden är hur du konfigurerar projektet och refererar till effektkomponenten.
Lägg till en Windows Runtime komponent för ljudeffekten
I Visual Studio lägger du till ett Windows Runtime komponentprojekt (C#) i din WinUI 3-lösning:
- Högerklicka på lösningen i Prieskumník riešení och välj Lägg till>ny Project.
- Välj projektmallen Windows Runtime Komponent.
- Ge projektet namnet AudioEffectComponent.
- Lägg till en projektreferens från din huvudsakliga WinUI 3-app i det här komponentprojektet.
- Byt namn på standardklassfilen till ExampleAudioEffect.cs.
Implementera gränssnittet IBasicAudioEffect
Ljudeffekten måste implementera alla metoder och egenskaper för gränssnittet IBasicAudioEffect .
using System.Collections.Generic;
using Windows.Media;
using Windows.Media.Effects;
using Windows.Media.MediaProperties;
using Windows.Foundation.Collections;
namespace AudioEffectComponent;
public sealed class ExampleAudioEffect : IBasicAudioEffect
{
private AudioEncodingProperties _currentEncodingProperties;
private IPropertySet _propertySet;
private float _echoDelay = 0.5f; // delay in seconds
private float _echoMix = 0.5f; // mix level (0-1)
public bool UseInputFrameForOutput => true;
public IReadOnlyList<AudioEncodingProperties> SupportedEncodingProperties
{
get
{
var supportedProperties = new List<AudioEncodingProperties>();
AudioEncodingProperties encodingProps1 =
AudioEncodingProperties.CreatePcm(44100, 1, 32);
encodingProps1.Subtype = MediaEncodingSubtypes.Float;
supportedProperties.Add(encodingProps1);
AudioEncodingProperties encodingProps2 =
AudioEncodingProperties.CreatePcm(48000, 1, 32);
encodingProps2.Subtype = MediaEncodingSubtypes.Float;
supportedProperties.Add(encodingProps2);
return supportedProperties;
}
}
public void SetEncodingProperties(
AudioEncodingProperties encodingProperties)
{
_currentEncodingProperties = encodingProperties;
}
public void SetProperties(IPropertySet configuration)
{
_propertySet = configuration;
// Read custom properties if provided
if (configuration != null &&
configuration.TryGetValue("EchoDelay", out object delay))
{
_echoDelay = (float)delay;
}
if (configuration != null &&
configuration.TryGetValue("EchoMix", out object mix))
{
_echoMix = (float)mix;
}
}
public void ProcessFrame(ProcessAudioFrameContext context)
{
// Audio processing logic goes here.
// See the echo effect example below.
}
public void Close(MediaEffectClosedReason reason)
{
// Clean up resources
}
public void DiscardQueuedFrames()
{
// Discard any cached frames
}
}
Skapa en ekoeffekt
I följande exempel visas en ProcessFrame implementering som skapar en ekoeffekt. Effekten lagrar tidigare ljuddata i en buffert och blandar dem med aktuella ljuddata efter en konfigurerbar fördröjning.
För att komma åt den råa ljudbufferten behöver du COM-gränssnittet IMemoryBufferByteAccess . Lägg till följande definition i ditt effektnamnområde:
using System.Runtime.InteropServices;
[ComImport]
[System.Runtime.InteropServices.Guid("5B0D3235-4DBA-4D44-865E-8F1D0E4FD04D")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
unsafe interface IMemoryBufferByteAccess
{
void GetBuffer(out byte* buffer, out uint capacity);
}
Important
Den här tekniken har åtkomst till en intern, ohanterad ljudbuffert. Du måste lägga till <AllowUnsafeBlocks>true</AllowUnsafeBlocks> i projektets .csproj fil för att aktivera osäker kod.
private float[] _echoBuffer;
private int _echoBufferPosition;
private float _echoDelay = 0.5f; // delay in seconds
private float _echoMix = 0.5f; // mix level (0-1)
private Windows.Media.MediaProperties.AudioEncodingProperties _currentEncodingProperties;
public unsafe void ProcessFrame(ProcessAudioFrameContext context)
{
AudioFrame inputFrame = context.InputFrame;
using (AudioBuffer inputBuffer =
inputFrame.LockBuffer(AudioBufferAccessMode.ReadWrite))
using (IMemoryBufferReference inputReference =
inputBuffer.CreateReference())
{
byte* dataInBytes;
uint capacityInBytes;
((IMemoryBufferByteAccess)inputReference).GetBuffer(
out dataInBytes, out capacityInBytes);
float* dataInFloat = (float*)dataInBytes;
int dataInFloatLength =
(int)capacityInBytes / sizeof(float);
// Initialize echo buffer on first call
if (_echoBuffer == null)
{
int delaySamples = (int)(
_currentEncodingProperties.SampleRate * _echoDelay);
_echoBuffer = new float[delaySamples];
}
for (int i = 0; i < dataInFloatLength; i++)
{
float input = dataInFloat[i];
float echo = _echoBuffer[_echoBufferPosition];
// Mix the original signal with the echo
dataInFloat[i] = input + (echo * _echoMix);
// Store the current sample in the echo buffer
_echoBuffer[_echoBufferPosition] = input;
_echoBufferPosition =
(_echoBufferPosition + 1) % _echoBuffer.Length;
}
}
}
Lägg till effekten i ett ljuddiagram
Om du vill använda den anpassade effekten med en AudioGraph skapar du en instans av effektdefinitionen och lägger till den i en nod:
using Windows.Media.Audio;
using Windows.Media.Effects;
var effectDefinition = new AudioEffectDefinition(
typeof(AudioEffectComponent.ExampleAudioEffect).FullName);
audioFileInputNode.EffectDefinitions.Add(effectDefinition);
Skicka konfigurationen till effekten
Du kan skicka konfigurationsvärden till din effekt med hjälp av en PropertySet:
var properties = new PropertySet();
properties["EchoDelay"] = 0.3f;
properties["EchoMix"] = 0.6f;
var effectDefinition = new AudioEffectDefinition(
typeof(AudioEffectComponent.ExampleAudioEffect).FullName,
properties);
I effektens SetProperties-metod (visas tidigare) läser du dessa värden från egenskapsuppsättningen för att konfigurera effekten vid körning.
Lägg till effekten i MediaCapture
Du kan också lägga till den anpassade ljudeffekten i en MediaCapture-ljudström :
var effectDefinition = new AudioEffectDefinition(
typeof(AudioEffectComponent.ExampleAudioEffect).FullName);
await _mediaCapture.AddAudioEffectAsync(effectDefinition);
Relaterat innehåll
Windows developer