Hii,
Packaging my project generates me this error :
Unhandled Exception: EXCEPTION_ACCESS_VIOLATION reading address 0x0000000000000000
UnrealEditor_ImitationLib!UMyCaptureComponent::~UMyCaptureComponent()
UnrealEditor_ImitationLib!UMyCaptureComponent::`vector deleting destructor'()
I’m building a plugin containing a custom capture component :
Here’s it’s header:
#pragma once
#include "CoreMinimal.h"
#include "AudioCaptureComponent.h"
#include "Misc/Paths.h"
#include "HAL/PlatformFilemanager.h"
#include "HAL/FileManager.h"
#include "XmlFile.h"
#include "XmlNode.h"
#include "ImitationLibPCH.h"
#include "MyCaptureComponent.generated.h"
#define AEC_K 10 // Chemin d'écho de AEC_K*8ms avec une trame de AEC de 384 echt
#define AEC_TEMPO 2 // Pour éviter de traiter du signal alors que l'écho arrive forcément après
/**
*
*/
UCLASS(ClassGroup="Custom")
class IMITATIONLIB_API UMyCaptureComponent : public UAudioCaptureComponent, public RingBufferConsumer
{
GENERATED_BODY()
UMyCaptureComponent(const FObjectInitializer& ObjectInitializer);
~UMyCaptureComponent() override;
public:
//---------------------------------Functions---------------------------------
int32 OnGenerateAudio(float* OutAudio, int32 NumSamples) override;
// Function to read XML file and populate target
TArray<FString> ReadXMLFileAndPopulateTargets(const FString& FilePath);
// Function to get the model path
UFUNCTION(BlueprintCallable, Category = "Audio Capture")
FString GetModelPath(FString targetName);
// Function to set the imitation directory
UFUNCTION(BlueprintCallable, Category = "Audio Capture")
void SetImitationDirectory(FString targetName);
//Set sample rate
/*UFUNCTION(BlueprintCallable, Category = "Audio Capture")
void SetSampleRate(int32 sampleRate);*/
int processData(unsigned long readPosition) override {
return 0;
}
//void restartEchoCanceller();
//---------------------------------Variables---------------------------------
// Array to store target names
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Audio Capture")
TArray<FString> mTargets;
// Imitation handle
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Audio Capture")
uint8 m_imiHandle;
//sample rate
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Audio Capture")
int32 mSampleRate;
// Imitation parameters
commandLine m_imiParams;
int _aecDelay;
FCriticalSection _mutex;
bool _reset;
RingBufferNoLock* _outBuffer;
bool _is24Bits;
bool _useEchoCanceller;
MUVOC_AECparam _aecParameters;
MUVOC_AECdata _aecData;
//echoCanceller _aecTemporal;
FEvent* _timer;
And here’s it’s source file :
UMyCaptureComponent::UMyCaptureComponent(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
mTargets = ReadXMLFileAndPopulateTargets("imitation.xml");
_timer = 0;
m_imiHandle = -1;
}
UMyCaptureComponent::~UMyCaptureComponent()
{
delete _outBuffer;
if (_readThread)
{
_doRead = false;
_readThread->WaitForCompletion();
delete _readThread;
_readThread = nullptr;
}
delete _ringBuffer;
}
int32 UMyCaptureComponent::OnGenerateAudio(float* OutAudio, int32 NumSamples)
{
int32 Samples = Super::OnGenerateAudio(OutAudio, NumSamples);
// Multiply the amplitude for each sample by a factor of 10
for (int i = 0; i < Samples; i++)
{
OutAudio[i] = OutAudio[i] * 10.f;
}
return Samples;
}
void UMyCaptureComponent::SetImitationDirectory(FString targetName)
{
UE_LOG(LogTemp, Warning, TEXT("SetImitationDirectory: %s"), *GetModelPath(targetName));
strcpy_s(m_imiParams.voice_dir, TCHAR_TO_ANSI(*GetModelPath(targetName)));
}
It inherits from RingBufferConsumer :
#pragma once
#include "RingBufferReadLock.h"
class RingBufferConsumer {
protected:
public:
RingBufferConsumer(RingBufferReadLock* buffer= new RingBufferReadLock(250), int sizeToRead=0);
virtual ~RingBufferConsumer() {}
void start();
void stop();
void reset();
void waitUntilDone();
RingBufferReadLock* _ringBuffer;
FRunnableThread* _readThread;
bool _doRead;
float* _ringBufferPtr;
int _ringBufferSize;
int _sizeToRead;
virtual int processData(unsigned long readPosition) = 0;
};
class RingBufferConsumerWorker : public FRunnable
{
private:
RingBufferConsumer* _instance;
public:
RingBufferConsumerWorker(RingBufferConsumer* instance) : _instance(instance) {}
virtual ~RingBufferConsumerWorker() {}
virtual bool Init() override {
return true;
}
virtual uint32 Run() override {
int sizeRed = 0;
unsigned long readPosition = 0;
while (_instance->_doRead) {
if (_instance->_ringBuffer->waitToBeginRead(_instance->_sizeToRead, readPosition)) {
if (!_instance->_doRead) {
break;
}
sizeRed = _instance->processData(readPosition);
if (sizeRed < 0) {
continue;
}
_instance->_ringBuffer->endRead(sizeRed);
}
}
return 0;
}
virtual void Stop() override {}
};
RingBufferConsumer::RingBufferConsumer(RingBufferReadLock* buffer, int sizeToRead)
{
_ringBuffer = buffer;
_sizeToRead = sizeToRead;
_ringBufferPtr = _ringBuffer->getBufferPtr();
_ringBufferSize = _ringBuffer->getBufferSize();
}
void RingBufferConsumer::start()
{
_doRead = true;
_readThread = FRunnableThread::Create(new RingBufferConsumerWorker(this), TEXT("RingBufferConsumerThread"), 0U, TPri_Highest);
}
void RingBufferConsumer::stop()
{
_doRead = false;
_readThread->Kill();
}
void RingBufferConsumer::reset()
{
_ringBuffer->resetBuffer();
}
void RingBufferConsumer::waitUntilDone()
{
_readThread->WaitForCompletion();
}