Streaming Sound Wave
Streaming Sound Wave là một loại sóng âm thanh được nhập hỗ trợ thêm dữ liệu âm thanh một cách động, ngay cả trong khi phát. Nó cung cấp chức năng tương tự như sóng âm thanh được nhập, ví dụ: tua lại và có thể được sử dụng trong SoundCues, v.v.
Để phát hiện hoạt động giọng nói (VAD), hãy tham khảo trang này.
Tạo một streaming sound wave
Trước tiên, bạn nên tạo một streaming sound wave. Xin lưu ý rằng bạn nên coi nó như một tham chiếu mạnh để ngăn chặn việc hủy sớm (ví dụ: bằng cách gán nó cho một biến riêng trong Blueprints hoặc sử dụng UPROPERTY() trong C++).
- Blueprint
- C++

UStreamingSoundWave* StreamingSoundWave = UStreamingSoundWave::CreateStreamingSoundWave();
Phát lại sóng âm thanh
Sau đó, bạn có thể phát lại sóng âm thanh đó. Tuy nhiên, không cần thiết phải làm điều này ngay bây giờ, bạn có thể bắt đầu phát sóng âm thanh sau.

Phân bổ trước dữ liệu âm thanh
Tùy chọn, bạn có thể phân bổ trước dữ liệu âm thanh (bytes) để tránh việc cấp phát lại toàn bộ bộ đệm PCM mỗi khi dữ liệu âm thanh mới được thêm vào.
- 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
}));
Thêm dữ liệu âm thanh
Để thêm dữ liệu âm thanh vào cuối bộ đệm hiện có, hãy sử dụng các hàm thích hợp để thêm dữ liệu âm thanh một cách động. Việc phát lại sẽ tuân theo trình tự hàng đợi của các lần thêm này.
- 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);
Tránh phát lại âm thanh bị tăng tốc hoặc méo tiếng
Khi truyền phát dữ liệu âm thanh trong khi sóng âm đang phát, bạn có thể gặp phải tình trạng phát lại âm thanh bị tăng tốc hoặc méo tiếng trong một số trường hợp cụ thể. Vấn đề này thường xảy ra khi:
- Quá trình phát sóng âm gần/kết thúc bộ đệm hiện tại
- Dữ liệu âm thanh mới liên tục được xếp hàng đợi vào sóng âm truyền phát
- Quá trình phát bắt kịp luồng dữ liệu đến
Bạn có thể dừng việc điền dữ liệu âm thanh bất kỳ lúc nào mà không gặp vấn đề. Tuy nhiên, đối với các tình huống yêu cầu truyền phát liên tục (chẳng hạn như truyền phát âm thanh thời gian thực), có hai cách tiếp cận tùy thuộc vào độ tin cậy của việc truyền phát dữ liệu âm thanh của bạn:
Đối với truyền phát đáng tin cậy, nhất quán: Sử dụng ủy quyền OnPopulateAudioState để bắt đầu phát lại ngay sau khi chunk dữ liệu đầu tiên được nhận.
Đối với truyền phát không đáng tin cậy (sự cố mạng, dữ liệu không liên tục): Thêm một độ trễ bổ sung ngay cả sau khi OnPopulateAudioState được kích hoạt để xây dựng một bộ đệm lớn hơn trước khi bắt đầu phát lại.
- 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;
}
});
Lưu ý: Bạn có thể ngừng thêm dữ liệu âm thanh bất kỳ lúc nào mà không gây ra sự cố phát lại. Cách tiếp cận chính xác phụ thuộc vào độ tin cậy của luồng dữ liệu âm thanh của bạn - sử dụng phát lại ngay lập tức cho các luồng ổn định hoặc thêm độ trễ đệm bổ sung cho các luồng không đáng tin cậy (ví dụ: sự cố kết nối mạng).
Ví dụ sử dụng
Cuối cùng, quá trình triển khai của bạn có thể trông như thế này:
- Blueprint
- C++

Đây là một ví dụ mã cơ bản để thêm dữ liệu âm thanh vào sóng âm thanh phát trực tuyến.
Ví dụ sử dụng hàm AppendAudioExample nằm trong lớp UAppendAudioClassExample thuộc module EXAMPLEMODULE.
Lưu ý: Để chạy ví dụ thành công, hãy đảm bảo thêm module RuntimeAudioImporter vào PublicDependencyModuleNames hoặc PrivateDependencyModuleNames trong tệp .Build.cs, cũng như vào tệp .uproject của dự án của bạn.
#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
Delegate OnPopulateAudioState hoạt động tương tự như OnPopulateAudioData nhưng không phát sóng dữ liệu âm thanh đã được điền. Điều này có thể hữu ích khi bạn muốn theo dõi thời điểm dữ liệu âm thanh được điền mà không cần truyền một mảng dữ liệu âm thanh đã được điền, giúp cải thiện hiệu suất.
- 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
});
Làm việc với Dữ liệu PCM
Để truy cập dữ liệu PCM theo thời gian thực trong quá trình phát lại, hãy xem Xử lý Dữ liệu PCM.