声音多线程

This commit is contained in:
Sch 2023-08-11 15:25:35 +08:00
parent 79887a5dab
commit 3352d0c4c2
12 changed files with 64 additions and 47 deletions

View File

@ -4,11 +4,16 @@
FCriticalSection Mutex;
FSoundThread::FSoundThread() : FRunnable()
FSoundThread::FSoundThread(int32 OutputChannel, int32 SampleRate) : FRunnable()
{
Pa_Initialize();
Pa_OpenDefaultStream(&Stream, 0, OutputChannel, paFloat32, SampleRate, 0, nullptr, nullptr);
Pa_StartStream(Stream);
this->OutputChannel = OutputChannel;
this->SampleRate = SampleRate;
}
bool FSoundThread::Init(int32 OutputChannel, int32 SampleRate)
bool FSoundThread::Init()
{
return FRunnable::Init();
@ -22,22 +27,20 @@ void FSoundThread::Exit()
uint32 FSoundThread::Run()
{
Pa_Initialize();
Pa_OpenDefaultStream(&Stream, 0, 2, paFloat32, 44100, 0, nullptr, nullptr);
Pa_StartStream(Stream);
while(bShouldStop != true)
float i = 0;
while (!bStoped)
{
if (Queue.Num() > 0)
if (SeekedFrame != 0)
{
PaError Error = Pa_GetStreamWriteAvailable(Stream);
if (Error >= 0)
TArray<uint8, TInlineAllocator<11760>> ResultData;
const int32 FrameLength = Audio.Num();
for (int32 i = SeekedFrame * (SampleRate / 27) * 4 * 2; i < (SeekedFrame + 1) * (SampleRate / 27) * 4 * 2 && i < FrameLength; ++i)
{
Pa_WriteStream(Stream, Queue.GetData(), Queue.Num() / 4);
ResultData.Add(Audio[i]);
}
Mutex.Lock();
Queue.Empty();
Mutex.Unlock();
Pa_WriteStream(Stream, ResultData.GetData(), ResultData.Num() / 4 / 2);
SeekedFrame = 0;
i += 1;
}
}
return 0;
@ -48,11 +51,16 @@ void FSoundThread::Stop()
FRunnable::Stop();
}
bool FSoundThread::QueueAudio(const uint8* Data, const int32 Size)
bool FSoundThread::CopyAudio(const uint8* Data, int32 Size)
{
Mutex.Lock();
Queue.Append(Data, Size);
Mutex.Unlock();
delete[] Data;
Audio = TArray<uint8>(Data, Size);
return true;
}
bool FSoundThread::SeekFrame(int32 SeekFrameLoc)
{
SeekedFrame = SeekFrameLoc;
return true;
}

View File

@ -7,15 +7,21 @@ extern "C"{
class FSoundThread : public FRunnable
{
public:
FSoundThread();
virtual bool Init(int32 OutputChannel, int32 SampleRate);
FSoundThread(int32 OutputChannel, int32 SampleRate);
virtual bool Init();
virtual void Exit() override;
virtual uint32 Run() override;
virtual void Stop() override;
bool QueueAudio(const uint8* Data, int32 Size);
bool bShouldStop = false;
PaStream* Stream = nullptr;
TArray<uint8> Queue;
PaStream* Stream;
int32 OutputChannel;
int32 SampleRate;
bool bStoped = false;
bool CopyAudio(const uint8* Data, int32 Size);
bool SeekFrame(int32 SeekFrameLoc);
int32 SeekedFrame = 0;
TArray<uint8> Audio;
};

View File

@ -94,7 +94,7 @@ FString FFFMPEGUtils::LoadMedia(const FString& Path, FTimelinePropertyData* Prop
}
if (AudioStream != -1)
@ -134,6 +134,7 @@ FString FFFMPEGUtils::LoadMedia(const FString& Path, FTimelinePropertyData* Prop
PropertyData->AudioData = DataResult;
PropertyData->AudioCodecContext = AudioCodecContext;
PropertyData->AudioCodec = AudioCodec;
PropertyData->AudioSample = AudioCodecContext->sample_rate;
}

View File

@ -321,6 +321,8 @@ struct CUT5_API FTimelinePropertyData
AVCodec* AudioCodec = nullptr;
int32 VideoStream = -1;
int32 AudioStream = -1;
int32 AudioSample = 0;
// Base Data
FString MoviePath = "";

View File

@ -314,6 +314,7 @@ void SCutMainWindow::Construct(const FArguments& InArgs)
]
]
+ SVerticalBox::Slot()
.SizeParam(FAuto())
.Padding(2.0)
.HAlign(HAlign_Fill)
.VAlign(VAlign_Fill)
@ -330,8 +331,8 @@ void SCutMainWindow::Construct(const FArguments& InArgs)
];
SoundThread = new FSoundThread();
FRunnableThread* Thread = FRunnableThread::Create(SoundThread, TEXT("SoundThread"));
// FRunnableThread* Thread = FRunnableThread::Create(SoundThread, TEXT("SoundThread"));
// OpenProject(FPaths::Combine(FPaths::ProjectSavedDir(), TEXT("DefaultProject")));
// ImportProject("");
@ -513,7 +514,7 @@ void SCutMainWindow::OnRemoveTrack(FGuid Guid)
void SCutMainWindow::OnUpdateSound(uint8* Data, int32 Size)
{
SoundThread->QueueAudio(Data, Size);
}
void SCutMainWindow::SelectClip(const FGuid& Guid)

View File

@ -335,14 +335,14 @@ void SCutTimeline::Tick(const FGeometry& AllottedGeometry, const double InCurren
SCompoundWidget::Tick(AllottedGeometry, InCurrentTime, InDeltaTime);
if (AutoPlaying)
{
// TimeSpace += InDeltaTime;
// if (TimeSpace >= 1.0 / FGlobalData::GlobalFPS)
// {
// UpdateCursorPosition(GetCursorPosition() + 1);
// TimeSpace = 0.0;
// }
TimeSpace += InDeltaTime;
if (TimeSpace >= 1.0 / FGlobalData::GlobalFPS)
{
UpdateCursorPosition(GetCursorPosition() + 1);
TimeSpace = 0.0;
}
UpdateCursorPosition(GetCursorPosition() + 1);
}
}

View File

@ -11,6 +11,7 @@
#include "SlateOptMacros.h"
#include "Commands/TimelineClipCommands.h"
#include "Cut5/WidgetInterface.h"
#include "Cut5/Interface/SoundInterface.h"
#include "Cut5/Utils/Utils.h"
#include "DragDropOperator/DragDropOperator.h"
#include "Engine/Engine.h"
@ -352,25 +353,20 @@ void STimelineClip::Seek(int32 Frame)
break;
case ETrackType::AudioTrack:
{
if (Stream == nullptr)
if (SoundThread == nullptr)
{
Pa_Initialize();
PaError A = Pa_OpenDefaultStream(&Stream, 0, 2, paFloat32, 44100, 3000, nullptr, nullptr);
Pa_StartStream(Stream);
SoundThread = new FSoundThread(2, ClipData->ResourcePropertyDataPtr->AudioSample);
FRunnableThread* Thread = FRunnableThread::Create(SoundThread, TEXT("SoundThread"));
SoundThread->CopyAudio(ClipData->ResourcePropertyDataPtr->AudioData.GetData(), ClipData->ResourcePropertyDataPtr->AudioData.Num());
}
const int32 Offset = Frame - ClipData->ClipStartFrame;
const int32 SeekMovieFrame = ClipData->VideoStartFrame + Offset;
TArray<uint8, TInlineAllocator<11760>> ResultData;
const int32 FrameLength = ClipData->ResourcePropertyDataPtr->AudioData.Num();
for (int32 i = SeekMovieFrame * (44100 / 30) * 4 * 2; i < (SeekMovieFrame + 1) * (44100 / 30) * 4 * 2 && i < FrameLength; ++i)
if (SoundThread)
{
ResultData.Add(ClipData->ResourcePropertyDataPtr->AudioData[i]);
SoundThread->SeekFrame(SeekMovieFrame);
}
Pa_WriteStream(Stream, ResultData.GetData(), ResultData.Num() / 4 / 2);
}
break;

View File

@ -12,6 +12,7 @@
#include <opencv2/core/mat.hpp>
#include "Cut5/Interface/SoundInterface.h"
#include "Widgets/Layout/SBox.h"
extern "C"
{
@ -56,6 +57,8 @@ public:
virtual FReply OnDragOver(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent) override;
TSharedPtr<SOverlay> ClipOverlay;
TSharedPtr<FUICommandList> CommandList;
FSoundThread* SoundThread;
};

BIN
ffmpeg.exe Normal file

Binary file not shown.

BIN
ffplay.exe Normal file

Binary file not shown.

BIN
ffprobe.exe Normal file

Binary file not shown.

BIN
portaudio_x64.dll Normal file

Binary file not shown.