Streaming Sound Wave
Pour la détection d'activité vocale (VAD), consultez cette page.
Une streaming sound wave est un type de son importé qui permet d'ajouter des données audio dynamiquement, même pendant la lecture. Elle offre les mêmes fonctionnalités qu'un son importé standard, comme la remise à zéro, et peut être utilisée dans des SoundCues, etc.
Création d'une streaming sound wave
Vous devez d'abord créer une streaming sound wave. Notez que vous devez la traiter comme une référence forte pour éviter sa destruction prématurée (par exemple en l'assignant à une variable séparée dans Blueprints ou en utilisant UPROPERTY()
en C++).
- Blueprint
- C++
UStreamingSoundWave* StreamingSoundWave = UStreamingSoundWave::CreateStreamingSoundWave();
Lecture de l'onde sonore
Vous pouvez ensuite lire cette onde sonore. Cependant, ce n'est pas nécessaire de le faire maintenant, vous pouvez commencer à lire l'onde sonore plus tard.
Pré-allocation des données audio
Optionnellement, vous pouvez pré-allouer les données audio (en octets) pour éviter de réallouer tout le tampon PCM à chaque fois que de nouvelles données audio sont ajoutées.
- 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
}));
Ajout de données audio
Pour ajouter des données audio à la fin du tampon existant, utilisez les fonctions appropriées pour ajouter dynamiquement des données audio. La lecture suivra la séquence de file d'attente de ces ajouts.
- 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);
Éviter une lecture audio accélérée ou déformée
Lors de la diffusion de données audio pendant la lecture de l'onde sonore, vous pouvez rencontrer une lecture audio accélérée ou déformée dans des scénarios spécifiques. Ce problème se produit généralement lorsque :
- La lecture de l'onde sonore est proche/à la fin du tampon actuel
- De nouvelles données audio sont continuellement ajoutées à l'onde sonore en streaming
- La lecture rattrape le flux de données entrant
Vous pouvez arrêter de peupler les données audio à tout moment sans problème. Cependant, pour les scénarios nécessitant un streaming continu (comme le streaming audio en temps réel), il existe deux approches selon la fiabilité de votre streaming de données audio :
Pour un streaming fiable et constant : Utilisez le délégué OnPopulateAudioState pour démarrer la lecture immédiatement après la réception du premier morceau.
Pour un streaming peu fiable (problèmes réseau, données intermittentes) : Ajoutez un délai supplémentaire même après le déclenchement de OnPopulateAudioState pour constituer un tampon plus important avant de démarrer la lecture.
- 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;
}
});
Remarque : Vous pouvez arrêter de peupler les données audio à tout moment sans causer de problèmes de lecture. L'approche exacte dépend de la fiabilité de votre flux de données audio - utilisez une lecture immédiate pour des flux constants, ou ajoutez un délai de tampon supplémentaire pour des flux peu fiables (par exemple, problèmes de connectivité réseau).
Exemple d'utilisation
Finalement, votre implémentation pourrait ressembler à ceci :
- Blueprint
- C++
Voici un exemple de code basique pour ajouter des données audio à une onde sonore en streaming.
L'exemple utilise la fonction AppendAudioExample
située dans la classe UAppendAudioClassExample
au sein du module EXAMPLEMODULE
.
Note : Pour exécuter l'exemple avec succès, assurez-vous d'ajouter le module RuntimeAudioImporter
soit à PublicDependencyModuleNames
ou à PrivateDependencyModuleNames
dans le fichier .Build.cs, ainsi qu'au fichier .uproject de votre projet.
#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
Le délégué OnPopulateAudioState fonctionne de manière similaire à OnPopulateAudioData mais ne diffuse pas les données audio peuplées. Cela peut être utile lorsque vous souhaitez suivre quand les données audio sont peuplées sans transmettre un tableau des données audio peuplées, ce qui peut améliorer les performances.
- 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
});
Travailler avec des données PCM
Pour un accès en temps réel aux données PCM pendant la lecture, consultez Gestion des données PCM.