声音多线程
This commit is contained in:
parent
79887a5dab
commit
3352d0c4c2
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -321,6 +321,8 @@ struct CUT5_API FTimelinePropertyData
|
|||
AVCodec* AudioCodec = nullptr;
|
||||
int32 VideoStream = -1;
|
||||
int32 AudioStream = -1;
|
||||
|
||||
int32 AudioSample = 0;
|
||||
|
||||
// Base Data
|
||||
FString MoviePath = "";
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue