Skip to content

Commit

Permalink
fix bugs in note synthesizer
Browse files Browse the repository at this point in the history
  • Loading branch information
CrSjimo committed Jul 10, 2024
1 parent 2be482f commit c8a83a3
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 20 deletions.
41 changes: 32 additions & 9 deletions src/core/source/NoteSynthesizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,17 +113,28 @@ namespace talcs {
return qFuzzyIsNull(item.vel);
}), d->keys.end());
}
auto it = std::find_if(d->keys.begin(), d->keys.end(), [&](const auto &item) {
return qFuzzyCompare(item.frequency, msg.frequency);
});
if (msg.isNoteOn) {
d->keys.append({d, msg.frequency, msg.velocity, .0, 0, true});
} else {
if (it != d->keys.end())
it->isAttack = false;
}
if (msg.position == -1)
break;
if (qFuzzyIsNull(msg.frequency) && !msg.isNoteOn) { // All notes off
for (auto &key : d->keys) {
key.isAttack = false;
}
} else {
auto it = std::find_if(d->keys.begin(), d->keys.end(), [&](const auto &item) {
return qFuzzyCompare(item.frequency, msg.frequency);
});
if (msg.isNoteOn) {
if (it != d->keys.end()) {
it->velFactor = msg.velocity;
it->isAttack = true;
} else {
d->keys.append({d, msg.frequency, msg.velocity, .0, 0, true});
}
} else {
if (it != d->keys.end())
it->isAttack = false;
}
}
}
return readData.length;
}
Expand All @@ -138,4 +149,16 @@ namespace talcs {
Q_D(const NoteSynthesizer);
return d->detector;
}

void NoteSynthesizer::flush(bool force) {
Q_D(NoteSynthesizer);
QMutexLocker locker(&d->mutex);
if (force) {
d->keys.clear();
} else {
for (auto &key : d->keys)
key.isAttack = false;
}

}
} // talcs
16 changes: 16 additions & 0 deletions src/core/source/NoteSynthesizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,20 @@
namespace talcs {

struct NoteSynthesizerDetectorMessage {
enum SpecialValueNull {
Null,
};
enum SpecialValueAllNotesOff {
AllNotesOff,
};
NoteSynthesizerDetectorMessage(SpecialValueNull null) : position(-1) {
}
NoteSynthesizerDetectorMessage(qint64 position, SpecialValueAllNotesOff allNotesOff) : position(position), frequency(.0), isNoteOn(false) {
}
NoteSynthesizerDetectorMessage(qint64 position, double frequency, bool isNoteOn) : position(position), frequency(frequency), velocity(1.), isNoteOn(isNoteOn) {
}
NoteSynthesizerDetectorMessage(qint64 position, double frequency, double velocity, bool isNoteOn) : position(position), frequency(frequency), velocity(velocity), isNoteOn(isNoteOn) {
}
qint64 position;
double frequency;
double velocity;
Expand Down Expand Up @@ -68,6 +82,8 @@ namespace talcs {
void setDetector(NoteSynthesizerDetector *detector);
NoteSynthesizerDetector *detector() const;

void flush(bool force = false);

protected:
explicit NoteSynthesizer(NoteSynthesizerPrivate &d);
qint64 processReading(const AudioSourceReadData &readData) override;
Expand Down
26 changes: 15 additions & 11 deletions src/midi/integrator/MidiNoteSynthesizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,18 +71,22 @@ namespace talcs {
}

NoteSynthesizerDetectorMessage MidiNoteSynthesizerPrivate::nextMessage() {
while (midiEventsIterator != midiEvents.cend() && !midiEventsIterator->message.isNoteOnOrOff())
while (midiEventsIterator != midiEvents.cend()) {
if (midiEventsIterator->message.isSysEx() && *midiEventsIterator->message.getSysExData() == 0xf7)
return {(midiEventsIterator++)->position, NoteSynthesizerDetectorMessage::AllNotesOff};
if (midiEventsIterator->message.isNoteOnOrOff()) {
NoteSynthesizerDetectorMessage ret = {
midiEventsIterator->position,
MidiMessage::getMidiNoteInHertz(midiEventsIterator->message.getNoteNumber(), frequencyOfA),
midiEventsIterator->message.getFloatVelocity(),
midiEventsIterator->message.isNoteOn(),
};
midiEventsIterator++;
return ret;
}
midiEventsIterator++;
if (midiEventsIterator == midiEvents.cend())
return {-1};
NoteSynthesizerDetectorMessage ret = {
midiEventsIterator->position,
MidiMessage::getMidiNoteInHertz(midiEventsIterator->message.getNoteNumber(), frequencyOfA),
midiEventsIterator->message.getFloatVelocity(),
midiEventsIterator->message.isNoteOn(),
};
midiEventsIterator++;
return ret;
}
return NoteSynthesizerDetectorMessage::Null;
}

qint64 MidiNoteSynthesizer::processReading(const AudioSourceReadData &readData, const QList<IntegratedMidiMessage> &midiEvents) {
Expand Down

0 comments on commit c8a83a3

Please sign in to comment.