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
49 changes: 26 additions & 23 deletions plugins/MidiImport/MidiImport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <QProgressDialog>

#include <sstream>
#include <unordered_map>

#include "MidiImport.h"
#include "TrackContainer.h"
Expand Down Expand Up @@ -305,7 +306,7 @@ class smfMidiChannel

bool MidiImport::readSMF( TrackContainer* tc )
{

const int MIDI_CC_COUNT = 128 + 1; // 0-127 (128) + pitch bend
const int preTrackSteps = 2;
QProgressDialog pd( TrackContainer::tr( "Importing MIDI-file..." ),
TrackContainer::tr( "Cancel" ), 0, preTrackSteps, gui->mainWindow() );
Expand All @@ -315,19 +316,20 @@ bool MidiImport::readSMF( TrackContainer* tc )

pd.setValue( 0 );

std::stringstream stream;
QByteArray arr = readAllData();
stream.str(std::string(arr.constData(), arr.size()));

std::istringstream stream(readAllData().toStdString());
Alg_seq_ptr seq = new Alg_seq(stream, true);
seq->convert_to_beats();

pd.setMaximum( seq->tracks() + preTrackSteps );
pd.setValue( 1 );

// 128 CC + Pitch Bend
smfMidiCC ccs[129];
smfMidiChannel chs[256];
smfMidiCC ccs[MIDI_CC_COUNT];

// channels can be set out of 256 range
// using unordered_map should fix most invalid loads and crashes while loading
std::unordered_map<long, smfMidiChannel> chs;
// NOTE: unordered_map::operator[] creates a new element if none exists

MeterModel & timeSigMM = Engine::getSong()->getTimeSigModel();
AutomationTrack * nt = dynamic_cast<AutomationTrack*>(
Expand Down Expand Up @@ -407,7 +409,7 @@ bool MidiImport::readSMF( TrackContainer* tc )
Alg_track_ptr trk = seq->track( t );
pd.setValue( t + preTrackSteps );

for( int c = 0; c < 129; c++ )
for( int c = 0; c < MIDI_CC_COUNT; c++ )
{
ccs[c].clear();
}
Expand All @@ -423,7 +425,10 @@ bool MidiImport::readSMF( TrackContainer* tc )
if( evt->is_update() )
{
QString attr = evt->get_attribute();
if( attr == "tracknames" && evt->get_update_type() == 's' ) {
// seqnames is a track0 identifier (see allegro code)
if (attr == (t == 0 ? "seqnames" : "tracknames")
&& evt->get_update_type() == 's')
{
trackName = evt->get_string_value();
handled = true;
}
Expand All @@ -444,7 +449,7 @@ bool MidiImport::readSMF( TrackContainer* tc )
printf( "\n" );
}
}
else if( evt->is_note() && evt->chan < 256 )
else if (evt->is_note())
{
smfMidiChannel * ch = chs[evt->chan].create( tc, trackName );
Alg_note_ptr noteEvt = dynamic_cast<Alg_note_ptr>( evt );
Expand Down Expand Up @@ -558,28 +563,26 @@ bool MidiImport::readSMF( TrackContainer* tc )
delete seq;


for( int c=0; c < 256; ++c )
for( auto& c: chs )
{
if (chs[c].hasNotes)
if (c.second.hasNotes)
{
chs[c].splitPatterns();
c.second.splitPatterns();
}
else if (chs[c].it)
else if (c.second.it)
{
printf(" Should remove empty track\n");
// must delete trackView first - but where is it?
//tc->removeTrack( chs[c].it );
//it->deleteLater();
}
}

// Set channel 10 to drums as per General MIDI's orders
if( chs[9].hasNotes && chs[9].it_inst && chs[9].isSF2 )
{
// AFAIK, 128 should be the standard bank for drums in SF2.
// If not, this has to be made configurable.
chs[9].it_inst->childModel( "bank" )->setValue( 128 );
chs[9].it_inst->childModel( "patch" )->setValue( 0 );
// Set channel 10 to drums as per General MIDI's orders
if (c.first % 16l == 9 /* channel 10 */
&& c.second.hasNotes && c.second.it_inst && c.second.isSF2)
{
c.second.it_inst->childModel("bank")->setValue(128);
c.second.it_inst->childModel("patch")->setValue(0);
}
}

return true;
Expand Down
9 changes: 5 additions & 4 deletions plugins/MidiImport/portsmf/algrd_internal.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* algread_internal.h -- interface between allegro.cpp and allegrord.cpp */

Alg_error alg_read(std::istream &file, Alg_seq_ptr new_seq);

/* algread_internal.h -- interface between allegro.cpp and allegrord.cpp */

Alg_error alg_read(std::istream &file, Alg_seq_ptr new_seq,
double *offset_ptr = NULL);

Loading