Files
2025-07-14 22:24:27 +08:00

78 lines
2.5 KiB
C++

// ------------------------------------------------
// Copyright Joe Marshall 2024- All Rights Reserved
// ------------------------------------------------
//
// Unreal IAudioOut implementation. This uses a
// USoundWaveProcedural to do the output, and also
// a UAudioComponent object. If given a parent
// actor object which has an existing
// UAudioComponent, it uses that. Otherwise it
// makes a new UAudioComponent and holds a strong
// object pointer to it until this class is
// destroyed.
// ------------------------------------------------
#pragma once
#include "Sound/SoundWaveProcedural.h"
#include <chrono>
#include <cstdint>
#include "IAudioOut.h"
#include "UnrealAudioOut.generated.h"
class USoundWaveProceduralWithTiming;
class UAudioComponent;
class UActorComponent;
UCLASS(MinimalAPI)
class USoundWaveProceduralWithTiming : public USoundWaveProcedural
{
GENERATED_BODY()
public:
virtual int32 GeneratePCMData(uint8 *PCMData, const int32 SamplesNeeded) override;
virtual void ResetAudio();
virtual void QueueSilence(int64_t bytes);
bool paused;
bool hasTiming;
int64_t lastBufSendTime;
};
class UnrealAudioOut : public IAudioOut
{
public:
explicit UnrealAudioOut(UActorComponent *owner);
virtual ~UnrealAudioOut() override;
virtual void init(int sampleRate, int channels) override;
virtual void initSilent() override;
virtual void close() override;
virtual void sendBuffer(uint8_t *buf, int bufSize, int64_t presentationTimeNS,
bool reset = false) override;
virtual int64_t getPresentationTimeNS() override; // current presentation time
virtual IAudioOut::NsTime getWaitTimeForPresentationTime(int64_t presentationTimeNS,
int64_t maxDuration) override;
virtual bool setVolume(float volume) override;
virtual void setPlaying(bool playing) override;
virtual bool setRate(float rate) override;
virtual void onSeek(int64_t newPresentationTimeNS, bool resetAudio) override;
virtual int64_t getQueuedTimeNS() override;
virtual void onHasVideoTime(int64_t newPresentationTimeNS) override;
private:
TObjectPtr<USoundWaveProceduralWithTiming> audioSender;
UActorComponent *owner;
TWeakObjectPtr<UAudioComponent> audioComponent;
TObjectPtr<UAudioComponent> audioComponentWeCreated;
bool hasTimeOffset;
int64_t presentationTimeOffset;
int numChannels;
int sampleRate;
bool isPlaying;
bool afterSeek;
float playbackRate;
int64_t pausedPresentationTime;
};