Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions include/InstrumentTrack.h
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,9 @@ class LMMS_EXPORT InstrumentTrack : public Track, public MidiEventProcessor

void autoAssignMidiDevice( bool );

//! Returns a non-owning pointer to the model for the knob at the given index in the track's MIDI CC rack
FloatModel* midiCCModel(int index) const { return m_midiCCModel[index].get(); }

signals:
void instrumentChanged();
void midiNoteOn( const lmms::Note& );
Expand Down
42 changes: 23 additions & 19 deletions plugins/MidiImport/MidiImport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,9 @@ bool MidiImport::readSMF(TrackContainer* tc)
}
else if (evt->is_note())
{
smfMidiChannel* ch = chs[evt->chan].create(tc, trackName);
// LMMS does not currently support specifying the channel of a single note
// To be safe, put the notes from different channels on separate tracks so that no information is lost
smfMidiChannel* ch = chs[evt->chan + 16 * t].create(tc, trackName);
auto noteEvt = dynamic_cast<Alg_note_ptr>(evt);
tick_t ticks = noteEvt->get_duration() * ticksPerBeat;
Note n(
Expand All @@ -419,7 +421,7 @@ bool MidiImport::readSMF(TrackContainer* tc)
}
else if (evt->is_update())
{
smfMidiChannel* ch = chs[evt->chan].create(tc, trackName);
smfMidiChannel* ch = chs[evt->chan + 16 * t].create(tc, trackName);

double time = evt->time*ticksPerBeat;
QString update(evt->get_attribute());
Expand Down Expand Up @@ -457,55 +459,57 @@ bool MidiImport::readSMF(TrackContainer* tc)
if (ccid <= 128)
{
double cc = evt->get_real_value();
AutomatableModel* objModel = nullptr;

AutomatableModel* modelObject = nullptr;
// Some CC knobs correspond to specific things like pitch and volume, so in that case, set the lmms pitch/volume/etc knobs.
// Otherwise, set the knob in the instrument track CC rack
switch (ccid)
{
case 0:
if (ch->isSF2 && ch->it_inst)
{
objModel = ch->it_inst->childModel("bank");
modelObject = ch->it_inst->childModel("bank");
printf("BANK SELECT %f %d\n", cc, static_cast<int>(cc * 127));
cc *= 127.0f;
}
break;

case 7:
objModel = ch->it->volumeModel();
modelObject = ch->it->volumeModel();
cc *= 100.0f;
break;

case 10:
objModel = ch->it->panningModel();
modelObject = ch->it->panningModel();
cc = cc * 200.f - 100.0f;
break;

case 128:
objModel = ch->it->pitchModel();
modelObject = ch->it->pitchModel();
cc = cc * 100.0f;
break;

default:
//TODO: something useful for other CCs
if (ccid >= 0 && ccid < 128)
{
modelObject = ch->it->midiCCModel(ccid);
cc = cc * 127.0f;
}
break;
}

if (objModel)
if (modelObject)
{
if (time == 0 && objModel)
if (time == 0)
{
objModel->setInitValue(cc);
modelObject->setInitValue(cc);
}
else
{
if (ccs[ccid].at == nullptr) {
ccs[ccid].create(tc, trackName + " > " +
// This is inside if (objModel), so objModel should never be nullptr
// (objModel != nullptr ? objModel->displayName() : QString("CC %1").arg(ccid))
objModel->displayName()
);
if (ccs[ccid].at == nullptr)
{
ccs[ccid].create(tc, trackName + " > " + modelObject->displayName());
}
ccs[ccid].putValue(time, objModel, cc);
ccs[ccid].putValue(time, modelObject, cc);
}
}
}
Expand Down
Loading