Streaming Sound Wave
Für Voice Activity Detection (VAD) siehe diese Seite.
Eine Streaming-Sound-Wave ist eine Art importierter Sound-Wave, der das dynamische Hinzufügen von Audiodaten unterstützt, sogar während der Wiedergabe. Sie bietet die gleiche Funktionalität wie eine importierte Sound-Wave, z.B. Zurückspulen, und kann in SoundCues usw. verwendet werden.
Erstellen einer Streaming-Sound-Wave
Zuerst sollten Sie eine Streaming-Sound-Wave erstellen. Bitte beachten Sie, dass Sie sie als starke Referenz behandeln sollten, um eine vorzeitige Zerstörung zu verhindern (z.B. durch Zuweisung zu einer separaten Variable in Blueprints oder Verwendung von UPROPERTY()
in C++).
- Blueprint
- C++
UStreamingSoundWave* StreamingSoundWave = UStreamingSoundWave::CreateStreamingSoundWave();
Abspielen der Schallwelle
Sie können dann diese Schallwelle abspielen. Dies ist jedoch nicht notwendig, um es jetzt zu tun, Sie können mit dem Abspielen der Schallwelle später beginnen.
Vorabzuweisung von Audiodaten
Optional können Sie Audiodaten (Bytes) vorab zuweisen, um eine Neuzuweisung des gesamten PCM-Puffers bei jeder Anfügung neuer Audiodaten zu vermeiden.
- Blueprint
- C++
// Assuming StreamingSoundWave is a UE reference to a UStreamingSoundWave object (or its derived type, such as UCapturableSoundWave)
StreamingSoundWave->PreAllocateAudioData(12582912, FOnPreAllocateAudioDataResultNative::CreateWeakLambda(this, [StreamingSoundWave](bool bSucceeded)
{
// Handle the result
}));
Anhängen von Audiodaten
Um Audiodaten an das Ende des vorhandenen Puffers anzuhängen, verwenden Sie die entsprechenden Funktionen zum dynamischen Anhängen von Audiodaten. Die Wiedergabe folgt der Warteschlangenreihenfolge dieser Anhänge.
- Blueprint
- C++
// Assuming StreamingSoundWave is a UE reference to a UStreamingSoundWave object (or its derived type, such as UCapturableSoundWave)
// Example of appending encoded audio data
TArray<uint8> AudioData = ...; // Fill with audio data
StreamingSoundWave->AppendAudioDataFromEncoded(AudioData, ERuntimeAudioFormat::Auto);
// Or, if you have raw audio data
TArray<uint8> RawAudioData = ...; // Fill with raw audio data
StreamingSoundWave->AppendAudioDataFromRAW(RawAudioData, ERuntimeRAWAudioFormat::Float32, 44100, 2);
Vermeidung von beschleunigter oder verzerrter Audiowiedergabe
Beim Streamen von Audiodaten während die Soundwelle abgespielt wird, kann es in bestimmten Szenarien zu beschleunigter oder verzerrter Audiowiedergabe kommen. Dieses Problem tritt typischerweise auf, wenn:
- Die Soundwellenwiedergabe sich dem Ende/am Ende des aktuellen Puffers befindet
- Neue Audiodaten kontinuierlich in die streaming Soundwelle eingereiht werden
- Die Wiedergabe den eingehenden Datenstrom einholt
Sie können die Audiodaten jederzeit ohne Probleme stoppen. Für Szenarien, die kontinuierliches Streaming erfordern (wie Echtzeit-Audiostreaming), gibt es jedoch zwei Ansätze, abhängig von der Zuverlässigkeit Ihres Audiodaten-Streamings:
Für zuverlässiges, konsistentes Streaming: Verwenden Sie den OnPopulateAudioState-Delegaten, um die Wiedergabe unmittelbar nach Empfang des ersten Datenblocks zu starten.
Für unzuverlässiges Streaming (Netzwerkprobleme, unterbrochene Daten): Fügen Sie eine zusätzliche Verzögerung hinzu, selbst nachdem OnPopulateAudioState ausgelöst wurde, um einen größeren Puffer aufzubauen, bevor die Wiedergabe beginnt.
- Blueprint
- C++
// Approach 1: For reliable streaming - start immediately after first chunk
bool bHasStartedPlayback = false;
StreamingSoundWave->OnPopulateAudioStateNative.AddWeakLambda(this, [this, &bHasStartedPlayback]()
{
if (!bHasStartedPlayback)
{
UGameplayStatics::PlaySound2D(GetWorld(), StreamingSoundWave);
bHasStartedPlayback = true;
}
});
// Approach 2: For unreliable streaming - add delay after first chunk
bool bHasStartedPlayback = false;
StreamingSoundWave->OnPopulateAudioStateNative.AddWeakLambda(this, [this, &bHasStartedPlayback]()
{
if (!bHasStartedPlayback)
{
// Add delay to build up buffer for unreliable streaming
GetWorld()->GetTimerManager().SetTimer(PlaybackDelayTimer, [this]()
{
UGameplayStatics::PlaySound2D(GetWorld(), StreamingSoundWave);
}, 0.5f, false); // Half-second delay
bHasStartedPlayback = true;
}
});
Hinweis: Sie können die Bereitstellung von Audiodaten jederzeit beenden, ohne dass dies zu Wiedergabeproblemen führt. Der genaue Ansatz hängt von der Zuverlässigkeit Ihres Audiodaten-Streamings ab - verwenden Sie sofortige Wiedergabe für konsistente Streams oder fügen Sie zusätzliche Pufferverzögerung für unzuverlässige Streams hinzu (z.B. bei Netzwerkverbindungsproblemen).
Beispielverwendung
Schließlich könnte Ihre Implementierung wie folgt aussehen:
- Blueprint
- C++
Dies ist ein grundlegendes Codebeispiel zum Anhängen von Audiodaten an einen Streaming-Sound-Wave.
Das Beispiel verwendet die Funktion AppendAudioExample
in der Klasse UAppendAudioClassExample
innerhalb des Moduls EXAMPLEMODULE
.
Hinweis: Um das Beispiel erfolgreich auszuführen, stellen Sie sicher, dass Sie das RuntimeAudioImporter
-Modul entweder zu PublicDependencyModuleNames
oder PrivateDependencyModuleNames
in der .Build.cs-Datei sowie zu Ihrer Projektdatei .uproject hinzufügen.
#pragma once
#include "CoreMinimal.h"
#include "UObject/Object.h"
#include "AppendAudioClassExample.generated.h"
UCLASS(BlueprintType)
class EXAMPLEMODULE_API UAppendAudioClassExample : public UObject
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable)
void AppendAudioExample();
private:
// Please pay attention to making the StreamingSoundWave a hard reference, such as using UPROPERTY(), to prevent it from being prematurely garbage collected
UPROPERTY()
class UStreamingSoundWave* StreamingSoundWave;
};
#include "AppendAudioClassExample.h"
#include "Sound/StreamingSoundWave.h"
void UAppendAudioClassExample::AppendAudioExample()
{
// Create a streaming sound wave
StreamingSoundWave = UStreamingSoundWave::CreateStreamingSoundWave();
// Append audio data
TArray<uint8> StreamedAudioDataToAdd = ...; // Fill with audio data
StreamingSoundWave->AppendAudioDataFromEncoded(StreamedAudioDataToAdd, ERuntimeAudioFormat::Auto);
// Play the sound wave
UGameplayStatics::PlaySound2D(GetWorld(), StreamingSoundWave);
}
On Populate Audio State
Der OnPopulateAudioState-Delegate funktioniert ähnlich wie OnPopulateAudioData, überträgt jedoch nicht die befüllten Audiodaten. Dies kann nützlich sein, wenn Sie verfolgen möchten, wann die Audiodaten befüllt werden, ohne ein Array der befüllten Audiodaten zu übergeben, was die Leistung verbessern kann.
- Blueprint
- C++
// Assuming StreamingSoundWave is a UE reference to a UStreamingSoundWave object (or its derived type, such as UCapturableSoundWave)
StreamingSoundWave->OnPopulateAudioStateNative.AddWeakLambda(this, [this]()
{
// Handle the result
});
Arbeiten mit PCM-Daten
Für den Echtzeitzugriff auf PCM-Daten während der Wiedergabe siehe PCM Data Handling.