2020-07-28 11:45:27 -04:00
|
|
|
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include "MetasoundDataReference.h"
|
|
|
|
|
#include "MetasoundDataTypeRegistrationMacro.h"
|
2020-08-13 19:07:41 -04:00
|
|
|
#include "IAudioProxyInitializer.h"
|
|
|
|
|
#include "Sound/SoundWave.h"
|
2021-01-24 16:12:59 -04:00
|
|
|
#include "IAudioCodecRegistry.h"
|
|
|
|
|
#include "IAudioCodec.h"
|
2020-07-28 11:45:27 -04:00
|
|
|
|
2021-01-24 16:12:59 -04:00
|
|
|
|
2020-07-28 11:45:27 -04:00
|
|
|
namespace Metasound
|
|
|
|
|
{
|
2020-07-30 19:14:41 -04:00
|
|
|
// Forward declare ReadRef
|
2020-09-08 18:12:55 -04:00
|
|
|
class FWaveAsset;
|
|
|
|
|
typedef TDataReadReference<FWaveAsset> FWaveAssetReadRef;
|
2020-08-11 16:50:48 -04:00
|
|
|
|
2021-01-24 16:12:59 -04:00
|
|
|
|
2020-09-08 18:12:55 -04:00
|
|
|
// Metasound data type that holds onto a weak ptr. Mostly used as a placeholder until we have a proper proxy type.
|
|
|
|
|
class METASOUNDENGINE_API FWaveAsset
|
2020-08-13 19:07:41 -04:00
|
|
|
{
|
|
|
|
|
public:
|
2021-01-24 16:12:59 -04:00
|
|
|
TUniquePtr<FSoundWaveProxy> SoundWaveProxy;
|
2020-08-13 19:07:41 -04:00
|
|
|
|
|
|
|
|
FWaveAsset() = default;
|
|
|
|
|
|
2021-01-24 16:12:59 -04:00
|
|
|
FWaveAsset& operator=(const FWaveAsset& Other)
|
2020-08-13 19:07:41 -04:00
|
|
|
{
|
2021-01-24 16:12:59 -04:00
|
|
|
SoundWaveProxy = MakeUnique<FSoundWaveProxy>(*Other.SoundWaveProxy);
|
|
|
|
|
return *this;
|
2020-08-13 19:07:41 -04:00
|
|
|
}
|
|
|
|
|
|
2021-01-24 16:12:59 -04:00
|
|
|
FWaveAsset(const TUniquePtr<Audio::IProxyData>& InInitData)
|
2020-08-13 19:07:41 -04:00
|
|
|
{
|
2021-01-24 16:12:59 -04:00
|
|
|
SoundWaveProxy.Reset();
|
|
|
|
|
|
|
|
|
|
if (InInitData.IsValid())
|
|
|
|
|
{
|
|
|
|
|
SoundWaveProxy = MakeUnique<FSoundWaveProxy>(InInitData->GetAs<FSoundWaveProxy>());
|
|
|
|
|
}
|
2020-08-13 19:07:41 -04:00
|
|
|
}
|
|
|
|
|
|
2021-01-24 16:12:59 -04:00
|
|
|
bool IsSoundWaveValid() const
|
|
|
|
|
{
|
|
|
|
|
return SoundWaveProxy.IsValid();
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-13 19:07:41 -04:00
|
|
|
};
|
|
|
|
|
|
2020-09-01 16:35:28 -04:00
|
|
|
DECLARE_METASOUND_DATA_REFERENCE_TYPES(FWaveAsset, METASOUNDENGINE_API, FWaveAssetTypeInfo, FWaveAssetReadRef, FWaveAssetWriteRef)
|
2020-07-28 11:45:27 -04:00
|
|
|
}
|
2021-01-25 06:10:37 -04:00
|
|
|
|
|
|
|
|
namespace Audio
|
|
|
|
|
{
|
|
|
|
|
// Forward declares
|
|
|
|
|
class ICodecRegistry;
|
|
|
|
|
struct IDecoderInput;
|
|
|
|
|
struct IDecoderOutput;
|
|
|
|
|
struct IDecoder;
|
|
|
|
|
|
|
|
|
|
class FSimpleDecoderWrapper
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
struct InitParams
|
|
|
|
|
{
|
|
|
|
|
float OutputSampleRate;
|
|
|
|
|
uint32 OutputBlockSizeInFrames;
|
|
|
|
|
float MaxPitchShiftMagnitudeAllowedInOctaves = 4.f;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
bool CanGenerateAudio() const
|
|
|
|
|
{
|
|
|
|
|
return !bDecoderIsDone && Input.IsValid() && Output.IsValid() && Decoder.IsValid();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Initialize(const InitParams& InInitParams, const FSoundWaveProxy& InWave);
|
|
|
|
|
|
|
|
|
|
// returns number of samples written.
|
|
|
|
|
uint32 GenerateAudio(float* OutputDest, int32 NumOutputFrames, float PitchShiftInCents = 0.f);
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
// actual decoder objects
|
|
|
|
|
TUniquePtr<Audio::IDecoder> Decoder;
|
|
|
|
|
TUniquePtr<Audio::IDecoderOutput> Output;
|
|
|
|
|
TSharedPtr<Audio::IDecoderInput, ESPMode::ThreadSafe> Input;
|
|
|
|
|
|
|
|
|
|
// init helper for decoders
|
|
|
|
|
bool InitializeDecodersInternal(const FSoundWaveProxy& Wave);
|
|
|
|
|
|
|
|
|
|
// SRC object
|
|
|
|
|
Audio::FResampler Resampler;
|
|
|
|
|
|
|
|
|
|
// buffers
|
|
|
|
|
TArray<float> PreSrcBuffer;
|
|
|
|
|
Audio::TCircularAudioBuffer<float> CircularDecoderOutputBuffer;
|
|
|
|
|
|
|
|
|
|
// meta data:
|
|
|
|
|
float InputSampleRate;
|
|
|
|
|
float OutputSampleRate;
|
|
|
|
|
float FsInToFsOutRatio;
|
|
|
|
|
float MaxPitchShiftCents;
|
|
|
|
|
float MaxPitchShiftRatio;
|
|
|
|
|
|
|
|
|
|
uint32 NumChannels;
|
|
|
|
|
uint32 DecodeBlockSizeInFrames;
|
|
|
|
|
uint32 DecodeBlockSizeInSamples;
|
|
|
|
|
|
2021-02-04 13:13:30 -04:00
|
|
|
// cached values
|
|
|
|
|
float LastPitchShiftCents{ 0.f };
|
|
|
|
|
int32 TotalNumFramesOutput{ 0 };
|
|
|
|
|
int32 TotalNumFramesDecoded{ 0 };
|
2021-01-25 06:10:37 -04:00
|
|
|
|
|
|
|
|
bool bDecoderIsDone{ true };
|
|
|
|
|
|
|
|
|
|
}; // class FSimpleDecoderWrapper
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} // namespace Audio
|