Skip to content

Commit

Permalink
Add seq track MIDI track index
Browse files Browse the repository at this point in the history
  • Loading branch information
FangCunWuChang committed May 29, 2024
1 parent 40b2718 commit dd06d11
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 56 deletions.
2 changes: 1 addition & 1 deletion scripts/vcpkg
45 changes: 37 additions & 8 deletions src/audioCore/graph/SeqSourceProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,7 @@ void SeqSourceProcessor::initMIDI() {

/** Update Name */
this->midiName = juce::String{};
this->currentMIDITrack = 0;

/** Set Flag */
this->midiChanged();
Expand Down Expand Up @@ -358,13 +359,15 @@ void SeqSourceProcessor::setAudio(double sampleRate,
}

void SeqSourceProcessor::setMIDI(
const juce::MidiFile& data, const juce::String& name) {
const juce::MidiFile& data, const juce::String& name,
int midiTrack) {
/** Lock */
juce::ScopedWriteLock locker(audioLock::getSourceLock());

/** Create MIDI Data */
this->midiData = std::make_unique<juce::MidiFile>(data);
this->midiName = name;
this->currentMIDITrack = midiTrack;

/** Set Flag */
this->midiChanged();
Expand All @@ -387,7 +390,22 @@ const std::tuple<double, juce::AudioSampleBuffer> SeqSourceProcessor::getAudio()
return { this->audioSampleRate, *(this->audioData.get()) };
}

const juce::MidiFile SeqSourceProcessor::getMIDI() const {
const juce::MidiMessageSequence SeqSourceProcessor::getMIDI() const {
/** Lock */
juce::ScopedReadLock locker(audioLock::getSourceLock());

/** Check Data */
if (this->midiData) {
if (auto track = this->midiData->getTrack(this->currentMIDITrack)) {
return juce::MidiMessageSequence{ *track };
}
}

/** Default Result */
return juce::MidiMessageSequence{};
}

const juce::MidiFile SeqSourceProcessor::getMIDIFile() const {
/** Lock */
juce::ScopedReadLock locker(audioLock::getSourceLock());

Expand Down Expand Up @@ -512,6 +530,17 @@ bool SeqSourceProcessor::isMIDIValid() const {
return (bool)this->midiData;
}

void SeqSourceProcessor::setCurrentMIDITrack(int trackIndex) {
this->currentMIDITrack = trackIndex;

/** Callback */
UICallbackAPI<int>::invoke(UICallbackType::SeqDataRefChanged, this->index);
}

int SeqSourceProcessor::getCurrentMIDITrack() const {
return this->currentMIDITrack;
}

void SeqSourceProcessor::setRecording(bool recording) {
if (recording) {
this->prepareRecord();
Expand Down Expand Up @@ -710,6 +739,7 @@ bool SeqSourceProcessor::parse(const google::protobuf::Message* data) {
.getChildFile(mes->midisrc()).getFullPathName();
this->loadMIDI(path, false);
}
this->setCurrentMIDITrack(mes->miditrack());

this->setRecording(mes->recording());
this->setMute(mes->muted());
Expand Down Expand Up @@ -762,6 +792,7 @@ std::unique_ptr<google::protobuf::Message> SeqSourceProcessor::serialize() const
mes->set_midisrc(name.toStdString());
this->saveMIDI(path);
}
mes->set_miditrack(this->getCurrentMIDITrack());

mes->set_recording(this->getRecording());
mes->set_muted(this->getMute());
Expand Down Expand Up @@ -812,11 +843,9 @@ void SeqSourceProcessor::readMIDIData(

/** Get MIDI Data */
juce::MidiMessageSequence total;
for (int i = 0; i < this->midiData->getNumTracks(); i++) {
if (auto track = this->midiData->getTrack(i)) {
total.addSequence(*track, 0,
startTime / this->getSampleRate(), endTime / this->getSampleRate());
}
if (auto track = this->midiData->getTrack(this->currentMIDITrack)) {
total.addSequence(*track, 0,
startTime / this->getSampleRate(), endTime / this->getSampleRate());
}

/** Copy Data */
Expand Down Expand Up @@ -870,7 +899,7 @@ void SeqSourceProcessor::writeMIDIData(const juce::MidiBuffer& buffer, int offse

/** Write To The Last Track */
if (auto track = const_cast<juce::MidiMessageSequence*>(
this->midiData->getTrack(this->midiData->getNumTracks() - 1))) {
this->midiData->getTrack(this->currentMIDITrack))) {
for (const auto& m : buffer) {
double timeStamp = (m.samplePosition + offset) / this->getSampleRate();
if (timeStamp >= 0) {
Expand Down
8 changes: 6 additions & 2 deletions src/audioCore/graph/SeqSourceProcessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,10 @@ class SeqSourceProcessor final : public juce::AudioProcessorGraph,
void initAudio(double sampleRate, double length);
void initMIDI();
void setAudio(double sampleRate, const juce::AudioSampleBuffer& data, const juce::String& name);
void setMIDI(const juce::MidiFile& data, const juce::String& name);
void setMIDI(const juce::MidiFile& data, const juce::String& name, int midiTrack = 0);
const std::tuple<double, juce::AudioSampleBuffer> getAudio() const;
const juce::MidiFile getMIDI() const;
const juce::MidiMessageSequence getMIDI() const;
const juce::MidiFile getMIDIFile() const;
void saveAudio(const juce::String& path = "") const;
void saveMIDI(const juce::String& path = "") const;
void loadAudio(const juce::String& path);
Expand All @@ -69,6 +70,8 @@ class SeqSourceProcessor final : public juce::AudioProcessorGraph,
bool isMIDISaved() const;
bool isAudioValid() const;
bool isMIDIValid() const;
void setCurrentMIDITrack(int trackIndex);
int getCurrentMIDITrack() const;

void setRecording(bool recording);
bool getRecording() const;
Expand Down Expand Up @@ -137,6 +140,7 @@ class SeqSourceProcessor final : public juce::AudioProcessorGraph,
double audioSampleRate = 0;
juce::String audioName, midiName;
std::atomic_bool audioSavedFlag = true, midiSavedFlag = true;
std::atomic_int currentMIDITrack = 0;

std::atomic_bool recordingFlag = false;
const double recordInitLength = 30;
Expand Down
22 changes: 20 additions & 2 deletions src/audioCore/misc/SourceIO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#include "AudioLock.h"
#include "../Utils.h"

#define TIME_TRACK_NAME "##VS_TIME"

SourceIO::SourceIO()
: Thread("Source IO"),
audioFormatsIn(SourceIO::trimFormat(utils::getAudioFormatsSupported(false))),
Expand Down Expand Up @@ -122,7 +124,7 @@ void SourceIO::run() {
{
juce::ScopedReadLock locker(audioLock::getSourceLock());
if (ptr) {
buffer = ptr->getMIDI();
buffer = ptr->getMIDIFile();
}
}
if (buffer.getNumTracks() <= 0) { continue; }
Expand Down Expand Up @@ -234,6 +236,16 @@ SourceIO::splitMIDI(const juce::MidiFile& data) {
}

if (seqTemp.getNumEvents() > 0) {
/** Exclude Time Track */
if (auto firstEvent = seqTemp.getEventPointer(0)) {
if (firstEvent->message.isTrackNameEvent()) {
if (firstEvent->message.getTextFromTextMetaEvent() == TIME_TRACK_NAME) {
continue;
}
}
}

/** Copy Track */
result.addTrack(seqTemp);
}
}
Expand All @@ -246,12 +258,18 @@ const juce::MidiFile SourceIO::mergeMIDI(const juce::MidiFile& data,
juce::MidiFile result;
SourceIO::copyMIDITimeFormat(result, data);

result.addTrack(timeSeq);
/** MIDI Track */
for (int i = 0; i < data.getNumTracks(); i++) {
auto seq = data.getTrack(i);
result.addTrack(*seq);
}

/** Time Track */
juce::MidiMessageSequence timeSeqTemp;
timeSeqTemp.addEvent(juce::MidiMessage::textMetaEvent(3, TIME_TRACK_NAME));
timeSeqTemp.addSequence(timeSeq, 0);
result.addTrack(timeSeqTemp);

return result;
}

Expand Down
2 changes: 1 addition & 1 deletion src/audioCore/quickAPI/QuickGet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -661,7 +661,7 @@ namespace quickAPI {
return {};
}

const juce::MidiFile getSeqTrackMIDIData(int index) {
const juce::MidiMessageSequence getSeqTrackMIDIData(int index) {
if (auto graph = AudioCore::getInstance()->getGraph()) {
if (auto track = graph->getSourceProcessor(index)) {
return track->getMIDI();
Expand Down
2 changes: 1 addition & 1 deletion src/audioCore/quickAPI/QuickGet.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ namespace quickAPI {
const juce::String getSeqTrackDataRefAudio(int index);
const juce::String getSeqTrackDataRefMIDI(int index);
const std::tuple<double, juce::AudioSampleBuffer> getSeqTrackAudioData(int index);
const juce::MidiFile getSeqTrackMIDIData(int index);
const juce::MidiMessageSequence getSeqTrackMIDIData(int index);

int getMixerTrackNum();
const juce::String getMixerTrackName(int index);
Expand Down
71 changes: 31 additions & 40 deletions src/ui/component/sequencer/SeqTrackContentViewer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ void SeqTrackContentViewer::updateDataRef() {
void SeqTrackContentViewer::updateData() {
/** Clear Temp */
this->audioDataTemp = {};
this->midiDataTemp = juce::MidiFile{};
this->midiDataTemp = juce::MidiMessageSequence{};
//this->audioPointTemp.clear();
//this->midiMinNote = this->midiMaxNote = 0;

Expand Down Expand Up @@ -325,40 +325,35 @@ void SeqTrackContentViewer::paint(juce::Graphics& g) {
maxNoteID = centerNoteID + ((noteAreaHeight / noteHeight + 1) / 2 - 1);
}

/** Paint Each MIDI Track */
/** Paint Each Note */
g.setColour(this->nameColor);
int trackNum = this->midiDataTemp.getNumTracks();
for (int i = 0; i < trackNum; i++) {
auto track = this->midiDataTemp.getTrack(i);

/** Paint Each Note */
std::array<double, 128> noteStartTime{};
for (int i = 0; i < 128; i++) {
noteStartTime[i] = -1;
}

std::array<double, 128> noteStartTime{};
for (int i = 0; i < 128; i++) {
noteStartTime[i] = -1;
}

for (auto event : *track) {
if (event->message.isNoteOn(true)) {
int noteNumber = event->message.getNoteNumber();
if (noteNumber >= 0 && noteNumber < 128) {
noteStartTime[noteNumber] = event->message.getTimeStamp();
}
for (auto event : this->midiDataTemp) {
if (event->message.isNoteOn(true)) {
int noteNumber = event->message.getNoteNumber();
if (noteNumber >= 0 && noteNumber < 128) {
noteStartTime[noteNumber] = event->message.getTimeStamp();
}
else if (event->message.isNoteOff(false)) {
int noteNumber = event->message.getNoteNumber();
if (noteNumber >= 0 && noteNumber < 128) {
double noteStart = noteStartTime[noteNumber];
noteStartTime[noteNumber] = -1;
if (noteStart >= 0) {
double noteEnd = event->message.getTimeStamp();
if (noteStart <= endSec && noteEnd >= startSec) {
juce::Rectangle<float> noteRect(
(noteStart - this->secStart) / (this->secEnd - this->secStart) * this->getWidth(),
notePosY + (maxNoteID - event->message.getNoteNumber()) * noteHeight,
(noteEnd - noteStart) / (this->secEnd - this->secStart) * this->getWidth(),
noteHeight);
g.fillRect(noteRect);
}
}
else if (event->message.isNoteOff(false)) {
int noteNumber = event->message.getNoteNumber();
if (noteNumber >= 0 && noteNumber < 128) {
double noteStart = noteStartTime[noteNumber];
noteStartTime[noteNumber] = -1;
if (noteStart >= 0) {
double noteEnd = event->message.getTimeStamp();
if (noteStart <= endSec && noteEnd >= startSec) {
juce::Rectangle<float> noteRect(
(noteStart - this->secStart) / (this->secEnd - this->secStart) * this->getWidth(),
notePosY + (maxNoteID - event->message.getNoteNumber()) * noteHeight,
(noteEnd - noteStart) / (this->secEnd - this->secStart) * this->getWidth(),
noteHeight);
g.fillRect(noteRect);
}
}
}
Expand Down Expand Up @@ -461,14 +456,10 @@ void SeqTrackContentViewer::setAudioPointTempInternal(
void SeqTrackContentViewer::updateMIDINoteTempInternal() {
/** Get Note Zone */
int minNote = 127, maxNote = 0;
int midiTracks = this->midiDataTemp.getNumTracks();
for (int i = 0; i < midiTracks; i++) {
auto track = this->midiDataTemp.getTrack(i);
for (auto e : (*track)) {
if (e->message.isNoteOn(true)) {
minNote = std::min(minNote, e->message.getNoteNumber());
maxNote = std::max(maxNote, e->message.getNoteNumber());
}
for (auto e : this->midiDataTemp) {
if (e->message.isNoteOn(true)) {
minNote = std::min(minNote, e->message.getNoteNumber());
maxNote = std::max(maxNote, e->message.getNoteNumber());
}
}
if (maxNote < minNote) { maxNote = minNote = 0; }
Expand Down
2 changes: 1 addition & 1 deletion src/ui/component/sequencer/SeqTrackContentViewer.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class SeqTrackContentViewer final : public juce::Component {
juce::OwnedArray<BlockItem> blockTemp;

std::tuple<double, juce::AudioSampleBuffer> audioDataTemp;
juce::MidiFile midiDataTemp;
juce::MidiMessageSequence midiDataTemp;

juce::Array<juce::MemoryBlock> audioPointTemp;
int midiMinNote = 0, midiMaxNote = 0;
Expand Down

0 comments on commit dd06d11

Please sign in to comment.