Skip to content

Commit

Permalink
Merge pull request #1 from Amir-BK/WithoutBadCommit
Browse files Browse the repository at this point in the history
Without bad commit
  • Loading branch information
Amir-BK authored Sep 3, 2024
2 parents 4ad1754 + 7afd183 commit 21aadb3
Show file tree
Hide file tree
Showing 8 changed files with 492 additions and 281 deletions.
1 change: 1 addition & 0 deletions Source/BkMovieSequencerMidi/BkMovieSequencerMidi.Build.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public BkMovieSequencerMidi(ReadOnlyTargetRules Target) : base(Target)
"LevelSequence",
"MovieScene",
"MovieSceneTracks",
"HarmonixMetasound"

// ... add other public dependencies that you statically link with here ...
}
Expand Down
186 changes: 65 additions & 121 deletions Source/BkMovieSequencerMidi/Private/BkMovieSceneMidiTrack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,125 +6,35 @@
#include "BkMovieSceneMidiTrackSection.h"


UBkMovieSceneMidiTrackSection* UBkMovieSceneMidiTrack::AddNewMidiTrackOnRow(FSequencerMidiNotesTrack& InMidiDataPtr, FFrameNumber Time, int32 RowIndex, UMidiFile* InMidiFile)
UBkMovieSceneMidiTrackSection* UBkMovieSceneMidiTrack::AddNewMidiTrackOnRow(FFrameNumber Time, int32 RowIndex, UMidiFile* InMidiFile)
{

//check(DAWData);
check(InMidiFile);

//MidiData = InMidiDataPtr;
FSequencerMidiNotesTrack& NewSectionMidiData = MidiTracks[RowIndex];
MidiFile = InMidiFile;

FFrameRate FrameRate = GetTypedOuter<UMovieScene>()->GetTickResolution();
FFrameTime DurationToUse = 1.f * FrameRate; // if all else fails, use 1 second duration



//const float Duration = DAWData->SequenceDuration * .001f;
const float Duration = MidiFile->GetSongMaps()->GetSongLengthMs() * .001f;
const float Duration = InMidiFile->GetSongMaps()->GetSongLengthMs() * .001f;

DurationToUse = Duration * FrameRate;



//add the section
UBkMovieSceneMidiTrackSection* NewEvaluationSection = Cast<UBkMovieSceneMidiTrackSection>(CreateNewSection());
NewEvaluationSection->ParentTrack = this;
NewEvaluationSection->MidiData = NewSectionMidiData;
NewEvaluationSection->Midi = MidiFile;

NewEvaluationSection->ParseRawMidiEventsIntoNotesAndChannels(InMidiFile);

NewEvaluationSection->InitialPlacementOnRow(MidiSections, Time, DurationToUse.FrameNumber.Value, RowIndex);
//NewEvaluationSection->DAWSequencerData = DAWData;
NewEvaluationSection->TrackIndexInParentSession = RowIndex;


MidiSections.Add(NewEvaluationSection);

return NewEvaluationSection;
};

void UBkMovieSceneMidiTrack::ParseRawMidiEventsIntoNotesAndTracks(UMidiFile* InMidiFile)
{
TArray<TTuple<int32, int32>> DiscoveredVoices; // for our purposes we want to clean the midi representation and place every unique combo of track/channel into a single track, which can be considered a voice

int VoiceIndex = 0;
//we discover the unique voices in the midi file as we're traversing it to tuild the note representation

TMap<int32, FMidiEvent> UnlinkedNoteOns; // we store the note ons that have not been linked to a note off yet

for (const auto& Track : InMidiFile->GetTracks())
{
const int InternalTrackIndex = VoiceIndex++;
for (const auto& MidiEvent : Track.GetEvents())
{
switch (MidiEvent.GetMsg().Type)
{
case FMidiMsg::EType::Std:

const int32 NoteNumber = MidiEvent.GetMsg().GetStdData1();

if (MidiEvent.GetMsg().IsNoteOn())
{
//unlinkedNotes.Add(MidiEvent.GetMsg().GetStdData1(), MidiEvent);
UnlinkedNoteOns.Add(NoteNumber, MidiEvent);
}
else
{
if (UnlinkedNoteOns.Contains(NoteNumber))
{

//we check that they're the same channel
if (UnlinkedNoteOns[NoteNumber].GetMsg().GetStdChannel() == MidiEvent.GetMsg().GetStdChannel())
{
//if we're here we have a valid note on and note off pair
// remove the note on from the unlinked notes
FMidiEvent NoteOn = UnlinkedNoteOns[NoteNumber];
UnlinkedNoteOns.Remove(NoteNumber);

//create a new note
const float StartTick = NoteOn.GetTick();
const float EndTick = MidiEvent.GetTick();

const FSequencerMidiNote NewNote = { NoteNumber, StartTick, EndTick };

//so we have an event, but we need to find the voice it belongs to
const int32 VoiceHash = DiscoveredVoices.AddUnique(TTuple<int32, int32>(InternalTrackIndex, MidiEvent.GetMsg().GetStdChannel()));

if(MidiTracks.Contains(VoiceHash))
{
MidiTracks[VoiceHash].Notes.Add(NewNote);
}
else
{
FSequencerMidiNotesTrack NewTrack;
FString TrackName = *InMidiFile->GetTrack(InternalTrackIndex)->GetName();
NewTrack.TrackName = FName(FString::Printf(TEXT("%d : %s"), VoiceHash, *TrackName)); //TODO
NewTrack.Notes.Add(NewNote);
NewTrack.TrackIndexInMidiFile = InternalTrackIndex;
NewTrack.ChannelIndexInMidiFile = MidiEvent.GetMsg().GetStdChannel();
MidiTracks.Add(VoiceHash, NewTrack);
}

}

}
}



}

}
}

}

void UBkMovieSceneMidiTrack::CreateSectionsFromMidiTracks()
{
for (const auto& Track : MidiTracks)
{
//print the name or something
UE_LOG(LogTemp, Warning, TEXT("Track Name: %s"), *Track.Value.TrackName.ToString());
}
}

UMovieSceneSection* UBkMovieSceneMidiTrack::CreateNewSection()
{
Expand Down Expand Up @@ -173,30 +83,64 @@ bool UBkMovieSceneMidiTrack::SupportsMultipleRows() const
{
return true;
}

#if WITH_EDITOR
inline EMovieSceneSectionMovedResult UBkMovieSceneMidiTrack::OnSectionMoved(UMovieSceneSection& Section, const FMovieSceneSectionMovedParams& Params)
{


auto MovedSectionNewOffset = Section.GetInclusiveStartFrame();
auto MovedSectionNewEnd = Section.GetExclusiveEndFrame();

UE_LOG(LogTemp, Warning, TEXT("MovedSectionNewOffset: %d"), MovedSectionNewOffset.Value);

for (auto& MidiSection : MidiSections)
{
if (MidiSection != &Section)
{
MidiSection->SetStartFrame(MovedSectionNewOffset);
MidiSection->SetEndFrame(MovedSectionNewEnd);
}

}

return EMovieSceneSectionMovedResult::None;
}
#endif
//
//#if WITH_EDITOR
//inline EMovieSceneSectionMovedResult UBkMovieSceneMidiTrack::OnSectionMoved(UMovieSceneSection& Section, const FMovieSceneSectionMovedParams& Params)
//{
//
//
// auto MovedSectionNewOffset = Section.GetInclusiveStartFrame();
// auto MovedSectionNewEnd = Section.GetExclusiveEndFrame();
//
// FString MoveType;
//
// switch (Params.MoveType)
// {
// case EPropertyChangeType::ArrayAdd:
// MoveType = "ArrayAdd";
// break;
// case EPropertyChangeType::ArrayRemove:
// MoveType = "ArrayRemove";
// break;
// case EPropertyChangeType::ArrayMove:
// MoveType = "ArrayMove";
// break;
// case EPropertyChangeType::Duplicate:
// MoveType = "Duplicate";
// break;
// case EPropertyChangeType::ValueSet:
// MoveType = "ValueSet";
// break;
// case EPropertyChangeType::Interactive:
// MoveType = "Interactive";
// break;
// case EPropertyChangeType::Redirected:
// MoveType = "Redirected";
// break;
// case EPropertyChangeType::ToggleEditable:
// MoveType = "ToggleEditable";
// break;
// default:
// MoveType = "Unknown";
// break;
//
// }
//
// UE_LOG(LogTemp, Log, TEXT("MovedSectionNewOffset: %d, MoveType: %s"), MovedSectionNewOffset.Value, *MoveType);
//
// for (auto& MidiSection : MidiSections)
// {
// if (MidiSection != &Section)
// {
// MidiSection->SetStartFrame(MovedSectionNewOffset);
// MidiSection->SetEndFrame(MovedSectionNewEnd);
// }
//
// }
//
// return EMovieSceneSectionMovedResult::None;
//}
//#endif



Expand Down
Loading

0 comments on commit 21aadb3

Please sign in to comment.