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 visar hur du använder en MediaFrameReader med MediaCapture för att hämta ljuddata från en medieramkälla. Mer information om hur du använder en MediaFrameReader för att hämta bilddata, till exempel från en färg, infraröd eller djupkamera, finns i Bearbeta medieramar med MediaFrameReader. Den artikeln innehåller en allmän översikt över bildruteläsaranvändningsmönstret och beskriver några ytterligare funktioner i klassen MediaFrameReader , till exempel att använda MediaFrameSourceGroup för att hämta bildrutor från flera källor samtidigt.
Note
De funktioner som beskrivs i den här artikeln är endast tillgängliga från och med Windows 10 version 1803.
Konfigurera projektet
Processen för att inhämta ljudramar är i stort sett densamma som för att inhämta andra typer av mediaramar. Precis som med alla appar som använder MediaCapture måste du deklarera att din app använder webbkamerafunktionen innan du försöker komma åt någon kameraenhet. Om appen ska spela in från en ljudenhet bör du även deklarera enhetskapaciteten microphone.
Välj ramkällor och ramkällgrupper
Det första steget i att samla in ljudramar är att initiera en MediaFrameSource som representerar källan för ljuddata, till exempel en mikrofon eller annan ljudinspelningsenhet. För att göra detta måste du skapa en ny instans av MediaCapture-objektet . I det här exemplet är den enda initieringsinställningen för MediaCapture att ställa in StreamingCaptureMode för att indikera att vi vill strömma ljud från inspelningsenheten.
När du har anropat MediaCapture.InitializeAsync kan du hämta listan över tillgängliga medieramkällor med egenskapen FrameSources . Det här exemplet väljer alla ramkällor där MediaFrameSourceInfo som beskriver ramkällan har en MediaStreamType av ljud, vilket indikerar att mediekällan genererar ljuddata.
Om frågan returnerar en eller flera bildrutekällor kan du kontrollera egenskapen CurrentFormat för att se om källan stöder det ljudformat som du önskar – i det här exemplet flytta ljuddata. Kontrollera AudioEncodingProperties för att se till att den ljudkodning du önskar stöds av källan.
m_mediaCapture = new MediaCapture();
MediaCaptureInitializationSettings settings = new MediaCaptureInitializationSettings()
{
StreamingCaptureMode = StreamingCaptureMode.Audio,
};
await m_mediaCapture.InitializeAsync(settings);
var audioFrameSources = m_mediaCapture.FrameSources.Where(x => x.Value.Info.MediaStreamType == MediaStreamType.Audio);
if (audioFrameSources.Count() == 0)
{
Debug.WriteLine("No audio frame source was found.");
return;
}
MediaFrameSource frameSource = audioFrameSources.FirstOrDefault().Value;
MediaFrameFormat format = frameSource.CurrentFormat;
if (format.Subtype != MediaEncodingSubtypes.Float)
{
return;
}
if (format.AudioEncodingProperties.ChannelCount != 2
|| format.AudioEncodingProperties.SampleRate != 48000)
{
return;
}
Skapa och starta MediaFrameReader
Hämta en ny instans av MediaFrameReader genom att anropa MediaCapture.CreateFrameReaderAsync och skicka det MediaFrameSource-objekt som du valde i föregående steg. Som standard hämtas ljudramar i buffrat läge, vilket gör det mindre troligt att ljudramar utelämnas, även om detta fortfarande kan inträffa om du inte bearbetar ljudramar tillräckligt snabbt och gör att systemets tilldelade minnesbuffert fylls.
Registrera en hanterare för händelsen MediaFrameReader.FrameArrived , som genereras av systemet när en ny bildruta med ljuddata är tillgänglig. Anropa StartAsync för att starta insamlingen av ljudrutor. Om bildruteläsaren inte startar har statusvärdet som returneras från anropet ett annat värde än Lyckades.
m_mediaFrameReader = await m_mediaCapture.CreateFrameReaderAsync(frameSource);
// Optionally set acquisition mode. Buffered is the default mode for audio.
m_mediaFrameReader.AcquisitionMode = MediaFrameReaderAcquisitionMode.Buffered;
m_mediaFrameReader.FrameArrived += MediaFrameReader_AudioFrameArrived;
var status = await m_mediaFrameReader.StartAsync();
if (status != MediaFrameReaderStartStatus.Success)
{
Debug.WriteLine("The MediaFrameReader couldn't start.");
}
I FrameArrived-händelsehanteraren anropar du TryAcquireLatestFrame på MediaFrameReader-objektet som skickas som avsändare till hanteraren för att försöka hämta en referens till den senaste medieramen. Observera att det här objektet kan vara null, så du bör alltid kontrollera innan du använder objektet. Vilka typer av mediaramar som kapslas in i MediaFrameReference som returneras från TryAcquireLatestFrame beror på vilken typ av bildrutekälla eller bildrutekällor som du konfigurerade bildruteläsaren att hämta från. Eftersom ramläsaren i det här exemplet konfigurerades för att samla in ljudramar hämtar den den underliggande ramen med egenskapen AudioMediaFrame.
Den här ProcessAudioFrame-hjälpmetoden i exemplet nedan visar hur du hämtar en AudioFrame som innehåller information, till exempel tidsstämpeln för ramen och om den är oavslutade från AudioMediaFrame-objektet . Om du vill läsa eller bearbeta ljudexempeldata måste du hämta AudioBuffer-objektet från AudioMediaFrame-objektet , skapa en IMemoryBufferReference och sedan anropa COM-metoden IMemoryBufferByteAccess::GetBuffer för att hämta data. Mer information om åtkomst till interna buffertar finns i anteckningen nedan.
Dataformatet beror på ramkällan. I det här exemplet, när du väljer en medieramkälla, såg vi uttryckligen till att den valda ramkällan använde två kanaler med flyttaldata. Resten av exempelkoden visar hur du fastställer varaktigheten och antalet exempel för ljuddata i ramen.
private void MediaFrameReader_AudioFrameArrived(MediaFrameReader sender, MediaFrameArrivedEventArgs args)
{
using (MediaFrameReference reference = sender.TryAcquireLatestFrame())
{
if (reference != null)
{
ProcessAudioFrame(reference.AudioMediaFrame);
}
}
}
unsafe private void ProcessAudioFrame(AudioMediaFrame audioMediaFrame)
{
using (AudioFrame audioFrame = audioMediaFrame.GetAudioFrame())
using (AudioBuffer buffer = audioFrame.LockBuffer(AudioBufferAccessMode.Read))
using (IMemoryBufferReference reference = buffer.CreateReference())
{
byte* dataInBytes;
uint capacityInBytes;
float* dataInFloat;
var memoryBuffer = reference.As<IMemoryBufferByteAccess>();
memoryBuffer.GetBuffer(out dataInBytes, out capacityInBytes);
// The requested format was float
dataInFloat = (float*)dataInBytes;
// Get the number of samples by multiplying the duration by sampling rate:
// duration [s] x sampling rate [samples/s] = # samples
// Duration can be gotten off the frame reference OR the audioFrame
TimeSpan duration = audioMediaFrame.FrameReference.Duration;
// frameDurMs is in milliseconds, while SampleRate is given per second.
uint frameDurMs = (uint)duration.TotalMilliseconds;
uint sampleRate = audioMediaFrame.AudioEncodingProperties.SampleRate;
uint sampleCount = (frameDurMs * sampleRate) / 1000;
}
}
Note
För att kunna arbeta med ljuddata måste du komma åt en intern minnesbuffert. För att göra detta måste du använda COM-gränssnittet IMemoryBufferByteAccess genom att inkludera kodlistan nedan. Åtgärder på den interna bufferten måste utföras i en metod som använder nyckelordet osäkert . Du måste också markera kryssrutan för att tillåta osäker kod på fliken Skapa i dialogrutan Project –> Egenskaper.
[ComImport]
[Guid("5B0D3235-4DBA-4D44-865E-8F1D0E4FD04D")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
unsafe interface IMemoryBufferByteAccess
{
void GetBuffer(out byte* buffer, out uint capacity);
}
Ytterligare information om hur du använder MediaFrameReader med ljuddata
Du kan hämta AudioDeviceController som är associerad med ljudramkällan genom att komma åt egenskapen MediaFrameSource.Controller . Det här objektet kan användas för att hämta eller ange strömegenskaperna för avbildningsenheten eller för att kontrollera avbildningsnivån. I följande exempel stängs ljudenheten av så att bildrutor fortsätter att hämtas av bildruteläsaren, men alla exempel har värdet 0.
m_audioDeviceController.Muted = true;
Du kan använda ett AudioFrame-objekt för att skicka ljuddata som samlas in av en medieramkälla till en AudioGraph. Skicka ramen till metoden AddFrame för en AudioFrameInputNode. Mer information om hur du använder ljuddiagram för att avbilda, bearbeta och blanda ljudsignaler finns i Ljuddiagram.
Relaterade ämnen
Windows developer