音频显示轨道

This commit is contained in:
Sch 2023-09-14 22:54:19 +08:00
parent 125c174e2e
commit c85a308d44
11 changed files with 119 additions and 41 deletions

View File

@ -62,7 +62,7 @@ uint32 FSoundThread::Run()
if (Pa_WriteStream(Stream, Audio.GetData() + Offset, Size) == paOutputUnderflowed) if (Pa_WriteStream(Stream, Audio.GetData() + Offset, Size) == paOutputUnderflowed)
{ {
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("Underflowed"));
}; };
SeekedFrame = 0; SeekedFrame = 0;
} }

View File

@ -0,0 +1 @@
#include "SoundWaveformThread.h"

View File

@ -0,0 +1,7 @@
#pragma once
class FSoundWaveformThread : public FRunnable
{
public:
FSoundWaveformThread();
};

View File

@ -252,9 +252,9 @@ bool FUtils::DetectDragTypeCanDrop(const FClipData& DraggingType, const ETrackTy
} }
} }
if (DropTrackType == ETrackType::VideoTrack) if (DropTrackType == ETrackType::VideoTrack || DropTrackType == ETrackType::LightArrayTrack || DropTrackType == ETrackType::LightBarTrack)
{ {
if (DraggingType.ClipType == ETrackType::VideoTrack) if (DraggingType.ClipType == ETrackType::VideoTrack || DraggingType.ClipType == ETrackType::LightArrayTrack || DraggingType.ClipType == ETrackType::LightBarTrack)
{ {
return true; return true;
} }
@ -337,7 +337,7 @@ TArray<FEncodeVideoInfo> FUtils::TrackEncodeVideo(const FTrackData& TrackData, c
FString OutputFile = "\"" + FPaths::ConvertRelativePathToFull(ExportPath + FString::FromInt(i) + TEXT(".mp4")) + "\""; FString OutputFile = "\"" + FPaths::ConvertRelativePathToFull(ExportPath + FString::FromInt(i) + TEXT(".mp4")) + "\"";
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, FString::Printf(TEXT("OutputFile %s"), *OutputFile)); // GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, FString::Printf(TEXT("OutputFile %s"), *OutputFile));
int32 StartFrame = (TempClipData.VideoStartFrame) % static_cast<int>(FGlobalData::GlobalFPS);; int32 StartFrame = (TempClipData.VideoStartFrame) % static_cast<int>(FGlobalData::GlobalFPS);;
int32 EndFrame = (TempClipData.VideoEndFrame) % static_cast<int>(FGlobalData::GlobalFPS); int32 EndFrame = (TempClipData.VideoEndFrame) % static_cast<int>(FGlobalData::GlobalFPS);

View File

@ -370,10 +370,7 @@ struct CUT5_API FClipData : public TSharedFromThis<FClipData>
TArray<FLinearColor> ClipColors; TArray<FLinearColor> ClipColors;
TArray<FStringWithGUID> AudioCurtains; TArray<FStringWithGUID> AudioCurtains;
UE_DEPRECATED(0.0, "Use int32 instead of float, Please just use ClipStartFrame and ClipEndFrame") int32 GetLength() const { return ClipEndFrame - ClipStartFrame; }
int32 GetClipStartFrame() const { return ClipStartTime / FGlobalData::DefaultTimeTickSpace; };
UE_DEPRECATED(0.0, "Use int32 instead of float, Please just use ClipStartFrame and ClipEndFrame")
int32 GetClipEndFrame() const { return ClipEndTime / FGlobalData::DefaultTimeTickSpace; };
int32 GetClipRelativeEndFrame() const { return ClipEndFrame - ClipStartFrame; } int32 GetClipRelativeEndFrame() const { return ClipEndFrame - ClipStartFrame; }
FPresetsCustomData PresetsCustomData; FPresetsCustomData PresetsCustomData;

View File

@ -138,25 +138,6 @@ void DragDropOperator::OnDragOver(const FGeometry& MyGeometry, const FDragDropEv
FSlateApplication::Get().AddWindowAsNativeChild(CurrentShowDragDropWindow.ToSharedRef(), FSlateApplication::Get().GetActiveTopLevelWindow().ToSharedRef(), true); FSlateApplication::Get().AddWindowAsNativeChild(CurrentShowDragDropWindow.ToSharedRef(), FSlateApplication::Get().GetActiveTopLevelWindow().ToSharedRef(), true);
} }
CurrentShowDragDropWindow->MoveWindowTo(FSlateApplication::Get().GetCursorPos()); CurrentShowDragDropWindow->MoveWindowTo(FSlateApplication::Get().GetCursorPos());
// CurrentShowDragDropWidget = DragDropBase->VirtualDraggingShow.ToSharedRef();
// SCutMainWindow* MainWindow = static_cast<SCutMainWindow*>(SavedMainInterface);
// if (MainWindow)
// {
// MainWindow->Overlay->AddSlot()
// .HAlign(HAlign_Left)
// .VAlign(VAlign_Top)
// [
// SNew(SBox)
// .WidthOverride(80)
// .HeightOverride(80)
// .HAlign(HAlign_Fill)
// .VAlign(VAlign_Fill)
// [
// CurrentShowDragDropWidget.ToSharedRef()
// ]
// ];
// }
} }
TSharedPtr<FClipsMoveDragDropOperation> ClipsMoveDragDropBase = StaticCastSharedPtr<FClipsMoveDragDropOperation>(DragDropBase); TSharedPtr<FClipsMoveDragDropOperation> ClipsMoveDragDropBase = StaticCastSharedPtr<FClipsMoveDragDropOperation>(DragDropBase);
if (DragDropBase->DragDropType == FCutDragDropBase::EType::ClipsMove) if (DragDropBase->DragDropType == FCutDragDropBase::EType::ClipsMove)
@ -227,7 +208,7 @@ void DragDropOperator::OnDragOver(const FGeometry& MyGeometry, const FDragDropEv
GEngine->AddOnScreenDebugMessage(-1, 0.1f, FColor::Red, FString::Printf(TEXT("StartPosition:%s"), *ScrollStartPosition.ToString())); // GEngine->AddOnScreenDebugMessage(-1, 0.1f, FColor::Red, FString::Printf(TEXT("StartPosition:%s"), *ScrollStartPosition.ToString()));
if (StartPosition.X < CurrentPosition.X && StartPosition.Y < CurrentPosition.Y) if (StartPosition.X < CurrentPosition.X && StartPosition.Y < CurrentPosition.Y)
{ {
@ -298,10 +279,15 @@ void DragDropOperator::OnDragOver(const FGeometry& MyGeometry, const FDragDropEv
if (TickTimeline->CutTimeline->AutoPlaying == false) if (TickTimeline->CutTimeline->AutoPlaying == false)
{ {
int32 NewFrame = (TickTimeline->GetCachedGeometry().AbsoluteToLocal(DragDropEvent.GetScreenSpacePosition()).X) / FGlobalData::DefaultTimeTickSpace; int32 NewFrame = (TickTimeline->GetCachedGeometry().AbsoluteToLocal(DragDropEvent.GetScreenSpacePosition()).X) / FGlobalData::DefaultTimeTickSpace;
if (LastFrame != NewFrame)
{
for (FSingleTrackGroupInstance& Instance : TickTimeline->CutTimeline->TrackGroupInstances) for (FSingleTrackGroupInstance& Instance : TickTimeline->CutTimeline->TrackGroupInstances)
{ {
Instance.Body->Seek(NewFrame); Instance.Body->Seek(NewFrame);
} }
LastFrame = NewFrame;
}
TickTimeline->CutTimeline->CurrentTimeData->SetText(FText::FromString(FGlobalData::GetTimeData(NewFrame) + " / ")); TickTimeline->CutTimeline->CurrentTimeData->SetText(FText::FromString(FGlobalData::GetTimeData(NewFrame) + " / "));
} }
@ -846,9 +832,41 @@ void DragDropOperator::OnDrop(const FGeometry& MyGeometry, const FDragDropEvent&
if (FUtils::DetectDragTypeCanDrop(NewClipData, TrackHead->TrackData.TrackType)) if (FUtils::DetectDragTypeCanDrop(NewClipData, TrackHead->TrackData.TrackType))
{ {
TrackHead->TrackData.ClipData.Add(NewClipData); TrackHead->TrackData.ClipData.Add(NewClipData);
UpdateClipProcess(TrackHead->MainWidgetInterface, NewClipData);
if (NewClipData.ClipType == ETrackType::AudioTrack)
{
if (TrackHead->TrackData.TrackType == ETrackType::AudioTrack)
{
FTrackData* TrackData = SavedMainInterface->GetCutTimeline()->GetTrackDataByType(ETrackType::AudioTrackR);
if (TrackData)
{
NewClipData.ClipType = ETrackType::AudioTrackR;
NewClipData.ClipGuid = FGuid::NewGuid();
TrackData->ClipData.Add(NewClipData);
UpdateClipProcess(SavedMainInterface, NewClipData);
} }
TrackBody->CallRender(); }
else if (TrackHead->TrackData.TrackType == ETrackType::AudioTrackR)
{
FTrackData* TrackData = SavedMainInterface->GetCutTimeline()->GetTrackDataByType(ETrackType::AudioTrack);
if (TrackData)
{
NewClipData.ClipType = ETrackType::AudioTrack;
NewClipData.ClipGuid = FGuid::NewGuid();
TrackData->ClipData.Add(NewClipData);
UpdateClipProcess(SavedMainInterface, NewClipData);
}
}
}
UpdateClipProcess(TrackHead->MainWidgetInterface, NewClipData);
}
SavedMainInterface->GetCutTimeline()->RenderGroup();
} }

View File

@ -17,6 +17,7 @@ public:
ICutMainWidgetInterface* SavedMainInterface; ICutMainWidgetInterface* SavedMainInterface;
TSharedPtr<SWidget> CurrentShowDragDropWidget; TSharedPtr<SWidget> CurrentShowDragDropWidget;
TSharedPtr<SWindow> CurrentShowDragDropWindow; TSharedPtr<SWindow> CurrentShowDragDropWindow;
int32 LastFrame = 0;
}; };

View File

@ -64,7 +64,7 @@ void SCutTimeline::UpdateTimelineLength()
TimelineTick->TickLengthBox->SetWidthOverride(FGlobalData::TrackLength * FGlobalData::DefaultTimeTickSpace); TimelineTick->TickLengthBox->SetWidthOverride(FGlobalData::TrackLength * FGlobalData::DefaultTimeTickSpace);
} }
void SCutTimeline::UpdateCursorPosition(int32 Frame) void SCutTimeline::UpdateCursorPosition(int32 Frame, bool NeedSeek)
{ {
if (TimelineTick.IsValid()) if (TimelineTick.IsValid())
{ {
@ -72,10 +72,14 @@ void SCutTimeline::UpdateCursorPosition(int32 Frame)
{ {
TimelineTick->UpdateNewCursorPosition(Frame); TimelineTick->UpdateNewCursorPosition(Frame);
MainWidgetInterface->PreSettingBeforeSeek(); MainWidgetInterface->PreSettingBeforeSeek();
if (NeedSeek)
{
for (const FSingleTrackGroupInstance& Interface : TrackGroupInstances) for (const FSingleTrackGroupInstance& Interface : TrackGroupInstances)
{ {
Interface.Body->Seek(Frame); Interface.Body->Seek(Frame);
} }
}
CurrentTimeData->SetText(FText::FromString(FGlobalData::GetTimeData(Frame) + " / ")); CurrentTimeData->SetText(FText::FromString(FGlobalData::GetTimeData(Frame) + " / "));
MaxTimeData->SetText(FText::FromString(FGlobalData::GetTimeData(FGlobalData::TrackLength))); MaxTimeData->SetText(FText::FromString(FGlobalData::GetTimeData(FGlobalData::TrackLength)));
} }
@ -211,8 +215,12 @@ void SCutTimeline::Construct(const FArguments& InArgs)
.OnValueChanged_Lambda([this](float ChangedValue) .OnValueChanged_Lambda([this](float ChangedValue)
{ {
FGlobalData::DefaultTimeTickSpace = FMath::GetMappedRangeValueClamped(FVector2D(0, 1.0), FVector2D(30.0, GetCachedGeometry().GetLocalSize().X / FGlobalData::TrackLength), ChangedValue); FGlobalData::DefaultTimeTickSpace = FMath::GetMappedRangeValueClamped(FVector2D(0, 1.0), FVector2D(30.0, GetCachedGeometry().GetLocalSize().X / FGlobalData::TrackLength), ChangedValue);
UpdateCursorPosition(GetCursorPosition()); UpdateCursorPosition(GetCursorPosition(), false);
// TickScrollBox->SetScrollOffset(TrackBodyHScrollBox->GetScrollOffset());
// TrackBodyHScrollBox->SetScrollOffset(TimelineTick->GetCursorPosition() * FGlobalData::DefaultTimeTickSpace);
TrackBodyHScrollBox->SetScrollOffset(0.0);
TickScrollBox->SetScrollOffset(TrackBodyHScrollBox->GetScrollOffset());
RenderGroup(); RenderGroup();
}) })
@ -312,6 +320,9 @@ void SCutTimeline::Construct(const FArguments& InArgs)
[ [
SAssignNew(TrackBodyHScrollBox, SScrollBox) SAssignNew(TrackBodyHScrollBox, SScrollBox)
.Orientation(EOrientation::Orient_Horizontal) .Orientation(EOrientation::Orient_Horizontal)
.NavigationScrollPadding(100)
.BackPadScrolling(false)
.FrontPadScrolling(false)
.Visibility(EVisibility::SelfHitTestInvisible) .Visibility(EVisibility::SelfHitTestInvisible)
.ScrollBarVisibility(EVisibility::Hidden) .ScrollBarVisibility(EVisibility::Hidden)
.WheelScrollMultiplier(0) .WheelScrollMultiplier(0)
@ -504,7 +515,7 @@ int32 SCutTimeline::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeo
{ {
FSlateDrawElement::MakeBox( FSlateDrawElement::MakeBox(
OutDrawElements, OutDrawElements,
LayerId + 1, LayerId + 99,
AllottedGeometry.ToPaintGeometry(FVector2f(2, GetCachedGeometry().Size.Y), FSlateLayoutTransform(FVector2f(GetCachedGeometry().AbsoluteToLocal(TimelineTick->TickCursor->GetCachedGeometry().GetAbsolutePosition()).X, AllottedGeometry.GetLocalSize().Y - GetCachedGeometry().GetLocalSize().Y))), AllottedGeometry.ToPaintGeometry(FVector2f(2, GetCachedGeometry().Size.Y), FSlateLayoutTransform(FVector2f(GetCachedGeometry().AbsoluteToLocal(TimelineTick->TickCursor->GetCachedGeometry().GetAbsolutePosition()).X, AllottedGeometry.GetLocalSize().Y - GetCachedGeometry().GetLocalSize().Y))),
&Brush, &Brush,
ESlateDrawEffect::None, ESlateDrawEffect::None,

View File

@ -66,7 +66,7 @@ public:
virtual FReply OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override; virtual FReply OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
virtual FReply OnDragOver(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent) override; virtual FReply OnDragOver(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent) override;
void UpdateTimelineLength(); void UpdateTimelineLength();
void UpdateCursorPosition(int32 Frame); void UpdateCursorPosition(int32 Frame, bool NeedSeek = true);
int32 GetCursorPosition() const; int32 GetCursorPosition() const;
/** Constructs this widget with InArgs */ /** Constructs this widget with InArgs */
void Construct(const FArguments& InArgs); void Construct(const FArguments& InArgs);

View File

@ -606,8 +606,51 @@ int32 STimelineClip::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGe
if (ClipData->ClipType == ETrackType::AudioTrack || ClipData->ClipType == ETrackType::AudioTrackR) if (ClipData->ClipType == ETrackType::AudioTrack || ClipData->ClipType == ETrackType::AudioTrackR)
{ {
const FSlateBrush Brush; const FSlateBrush Brush;
int32 NeedDrawCount = ClipData->GetLength() * FGlobalData::DefaultTimeTickSpace;
float DownSample = 4;
// Draw Audio Waveform
const float RangeStart = MainWidgetInterface->GetCutTimeline()->TrackBodyHScrollBox->GetCachedGeometry().LocalToAbsolute(FVector2D(0, 0)).X;
const float RangeEnd = MainWidgetInterface->GetCutTimeline()->TrackBodyHScrollBox->GetCachedGeometry().LocalToAbsolute(FVector2D(MainWidgetInterface->GetCutTimeline()->TrackBodyHScrollBox->GetCachedGeometry().GetLocalSize().X, 0)).X;
const float CurrentStartRange = AllottedGeometry.LocalToAbsolute(FVector2D(0, 0)).X;
const float CurrentEndRange = AllottedGeometry.LocalToAbsolute(FVector2D(AllottedGeometry.GetLocalSize().X, 0)).X;
GEngine->AddOnScreenDebugMessage(-1, 0.0f, FColor::Red, FString::SanitizeFloat(RangeStart));
GEngine->AddOnScreenDebugMessage(-1, 0.0f, FColor::Green, FString::SanitizeFloat(RangeEnd));
GEngine->AddOnScreenDebugMessage(-1, 0.0f, FColor::White, FString::SanitizeFloat(CurrentStartRange));
GEngine->AddOnScreenDebugMessage(-1, 0.0f, FColor::Yellow, FString::SanitizeFloat(CurrentEndRange));
const int32 StartOffset = (ClipData->ResourcePropertyDataPtr->AudioSample / FGlobalData::GlobalFPS)
* ClipData->VideoStartFrame
* FUtils::GetFormatSampleBytesNum(ClipData->ResourcePropertyDataPtr->SampleFormat) * 2 / DownSample;
const int32 EndOffset = (ClipData->ResourcePropertyDataPtr->AudioSample / FGlobalData::GlobalFPS)
* ClipData->VideoEndFrame
* FUtils::GetFormatSampleBytesNum(ClipData->ResourcePropertyDataPtr->SampleFormat) * 2 / DownSample;
const int32 Interval = (EndOffset - StartOffset) / NeedDrawCount;
for (int32 i = 0; i < NeedDrawCount / DownSample; i++)
{
const int32 CurrentIndex = (StartOffset * DownSample) + (i * (Interval * DownSample * 4));
if (CurrentIndex >= ClipData->ResourcePropertyDataPtr->AudioData.Num())
continue;
float NewFloat = *reinterpret_cast<float*>(&ClipData->ResourcePropertyDataPtr->AudioData[CurrentIndex]);
float Y = FMath::GetMappedRangeValueClamped(FVector2D(1.0, 0.0), FVector2D(0.0, AllottedGeometry.GetLocalSize().Y),
FMath::Abs(NewFloat));
TArray<FVector2D> NewLoc;
NewLoc.Add(FVector2D(i * DownSample, AllottedGeometry.GetLocalSize().Y));
NewLoc.Add(FVector2D(i * DownSample, Y));
FSlateDrawElement::MakeLines(OutDrawElements, LayerId + 6, AllottedGeometry.ToPaintGeometry(), NewLoc, ESlateDrawEffect::None,
FColor(45, 214, 153, 255), true, DownSample * 1.2);
}
FSlateDrawElement::MakeBox(OutDrawElements, LayerId + 5, AllottedGeometry.ToPaintGeometry(), FSlateDrawElement::MakeBox(OutDrawElements, LayerId + 5, AllottedGeometry.ToPaintGeometry(),
&Brush, ESlateDrawEffect::None, FLinearColor(1.0, 0.0, 1.0, 1.0)); &Brush, ESlateDrawEffect::None, FColor(22, 105, 78, 255));
} }

View File

@ -171,7 +171,7 @@ FReply STrackBody::OnMouseButtonDown(const FGeometry& MyGeometry, const FPointer
+ Y + Y
); );
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("X:%f,Y:%f"), Y, DragDropOperator->ScrollStartPosition.Y)); // GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("X:%f,Y:%f"), Y, DragDropOperator->ScrollStartPosition.Y));
DragDropOperator->DraggingWidget = TrackHead->CutTimeline; DragDropOperator->DraggingWidget = TrackHead->CutTimeline;
return FReply::Handled().DetectDrag(SharedThis(this), EKeys::LeftMouseButton).BeginDragDrop(DragDropOperator.ToSharedRef()); return FReply::Handled().DetectDrag(SharedThis(this), EKeys::LeftMouseButton).BeginDragDrop(DragDropOperator.ToSharedRef());
} }