Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Artikel ini menjelaskan cara membuat komponen Windows Runtime yang mengimplementasikan antarmuka IBasicAudioEffect untuk membuat efek kustom untuk aliran audio. Anda dapat menggunakan efek kustom dengan AudioGraph, MediaCapture, dan MediaComposition.
Note
Antarmuka IBasicAudioEffect adalah API Windows Runtime dalam namespace Windows.Media.Effects. API ini bekerja dengan cara yang sama di aplikasi desktop WinUI 3 seperti di UWP. Perbedaan utamanya adalah bagaimana Anda menyiapkan proyek dan mereferensikan komponen efek.
Menambahkan komponen Windows Runtime untuk efek audio Anda
Di Visual Studio, tambahkan proyek Windows Runtime Component (C#) ke solusi WinUI 3 Anda:
- Klik kanan solusi Anda di Penjelajah Solusi dan pilih Tambahkan>Project Baru.
- Pilih templat proyek komponen Windows Runtime.
- Beri nama proyek AudioEffectComponent.
- Tambahkan referensi proyek dari aplikasi WinUI 3 utama Anda ke proyek komponen ini.
- Ganti nama file kelas default menjadi ExampleAudioEffect.cs.
Menerapkan antarmuka IBasicAudioEffect
Efek audio Anda harus mengimplementasikan semua metode dan properti antarmuka 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
}
}
Buat efek gema
Contoh berikut menunjukkan implementasi ProcessFrame yang menghasilkan efek gema. Efek menyimpan data audio sebelumnya dalam buffer dan mencampurnya dengan data audio saat ini setelah penundaan yang dapat dikonfigurasi.
Untuk mengakses buffer audio mentah, Anda memerlukan antarmuka IMemoryBufferByteAccess COM. Tambahkan definisi berikut di namespace efek Anda:
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
Teknik ini mengakses buffer audio asli yang tidak dikelola. Anda harus menambahkan <AllowUnsafeBlocks>true</AllowUnsafeBlocks> ke file proyek .csproj Anda untuk mengaktifkan kode yang tidak aman.
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;
}
}
}
Menambahkan efek ke grafik audio
Untuk menggunakan efek kustom dengan AudioGraph, buat instans definisi efek dan tambahkan ke simpul:
using Windows.Media.Audio;
using Windows.Media.Effects;
var effectDefinition = new AudioEffectDefinition(
typeof(AudioEffectComponent.ExampleAudioEffect).FullName);
audioFileInputNode.EffectDefinitions.Add(effectDefinition);
Teruskan konfigurasi ke efek
Anda dapat meneruskan nilai konfigurasi ke efek Anda dengan menggunakan PropertySet:
var properties = new PropertySet();
properties["EchoDelay"] = 0.3f;
properties["EchoMix"] = 0.6f;
var effectDefinition = new AudioEffectDefinition(
typeof(AudioEffectComponent.ExampleAudioEffect).FullName,
properties);
Dalam metode SetProperties efek Anda (ditunjukkan sebelumnya), baca nilai-nilai ini dari kumpulan properti untuk mengonfigurasi efek saat runtime.
Menambahkan efek ke MediaCapture
Anda juga dapat menambahkan efek audio kustom ke aliran audio MediaCapture :
var effectDefinition = new AudioEffectDefinition(
typeof(AudioEffectComponent.ExampleAudioEffect).FullName);
await _mediaCapture.AddAudioEffectAsync(effectDefinition);
Konten terkait
Windows developer