/**
 * Copyright 2022-2025 Theai, Inc. dba Inworld AI
 */

#include "Audio/InworldAudioBuffer.h"

UInworldAudioBuffer* UInworldAudioBuffer::CreateAudioBuffer(const FInworldAudioBufferConfig& AudioBufferConfig)
{
	UInworldAudioBuffer* AudioBuffer = NewObject<UInworldAudioBuffer>();
	AudioBuffer->AudioBufferConfig = AudioBufferConfig;
	return AudioBuffer;
}

void UInworldAudioBuffer::Add(const FInworldData_Audio& Audio)
{
	if (!ensureMsgf(Audio.SampleRate == AudioBufferConfig.SampleRate,
			TEXT("Attempt to add incompatible Audio to Buffer! Chunk:{SampleRate:%d} Buffer:{SampleRate:%d}"), Audio.SampleRate,
			AudioBufferConfig.SampleRate))
	{
		return;
	}
	FScopeLock InputScopedLock(&AudioBuffer.CriticalSection);
	AudioBuffer.Data.Append(*Audio.Waveform);
}

FInworldData_Audio UInworldAudioBuffer::Flush()
{
	FScopeLock InputScopedLock(&AudioBuffer.CriticalSection);
	const float DataPerSecond{AudioBufferConfig.SampleRate * 8.f};
	if (DataPerSecond > 0.f)
	{
		const float AudioDuration = AudioBuffer.Data.Num() / (DataPerSecond);
		if (AudioDuration < AudioBufferConfig.MinAudioDuration)
		{
			AudioBuffer.Data.Empty();
			return {};
		}
	}

	FInworldData_Audio Audio;
	Audio.Waveform = MakeShared<TArray<uint8>>(AudioBuffer.Data.GetData(), AudioBuffer.Data.Num());
	Audio.SampleRate = AudioBufferConfig.SampleRate;
	OnAudioBufferFlush.Broadcast(this, Audio);
	OnAudioBufferFlushNative.Broadcast(this, Audio);

	AudioBuffer.Data.Empty();

	return Audio;
}
