comparison data/fileio/MIDIFileReader.cpp @ 392:183ee2a55fc7

* More work to abstract out interactive components used in the data library, so that it does not need to depend on QtGui.
author Chris Cannam
date Fri, 14 Mar 2008 17:14:21 +0000
parents 516819f2b97b
children 2e50d95cf621
comparison
equal deleted inserted replaced
391:5858cc462d0a 392:183ee2a55fc7
34 #include "base/Pitch.h" 34 #include "base/Pitch.h"
35 #include "base/RealTime.h" 35 #include "base/RealTime.h"
36 #include "model/NoteModel.h" 36 #include "model/NoteModel.h"
37 37
38 #include <QString> 38 #include <QString>
39 #include <QMessageBox>
40 #include <QInputDialog>
41 39
42 #include <sstream> 40 #include <sstream>
43 41
44 using std::string; 42 using std::string;
45 using std::ifstream; 43 using std::ifstream;
56 54
57 //#define MIDI_DEBUG 1 55 //#define MIDI_DEBUG 1
58 56
59 57
60 MIDIFileReader::MIDIFileReader(QString path, 58 MIDIFileReader::MIDIFileReader(QString path,
59 MIDIFileImportPreferenceAcquirer *acquirer,
61 size_t mainModelSampleRate) : 60 size_t mainModelSampleRate) :
62 m_timingDivision(0), 61 m_timingDivision(0),
63 m_format(MIDI_FILE_BAD_FORMAT), 62 m_format(MIDI_FILE_BAD_FORMAT),
64 m_numberOfTracks(0), 63 m_numberOfTracks(0),
65 m_trackByteCount(0), 64 m_trackByteCount(0),
66 m_decrementCount(false), 65 m_decrementCount(false),
67 m_path(path), 66 m_path(path),
68 m_midiFile(0), 67 m_midiFile(0),
69 m_fileSize(0), 68 m_fileSize(0),
70 m_mainModelSampleRate(mainModelSampleRate) 69 m_mainModelSampleRate(mainModelSampleRate),
70 m_acquirer(acquirer)
71 { 71 {
72 if (parseFile()) { 72 if (parseFile()) {
73 m_error = ""; 73 m_error = "";
74 } 74 }
75 } 75 }
811 MIDIFileReader::load() const 811 MIDIFileReader::load() const
812 { 812 {
813 if (!isOK()) return 0; 813 if (!isOK()) return 0;
814 814
815 if (m_loadableTracks.empty()) { 815 if (m_loadableTracks.empty()) {
816 QMessageBox::critical(0, tr("No notes in MIDI file"), 816 if (m_acquirer) {
817 tr("MIDI file \"%1\" has no notes in any track") 817 m_acquirer->showError
818 .arg(m_path)); 818 (tr("MIDI file \"%1\" has no notes in any track").arg(m_path));
819 }
819 return 0; 820 return 0;
820 } 821 }
821 822
822 std::set<unsigned int> tracksToLoad; 823 std::set<unsigned int> tracksToLoad;
823 824
825 826
826 tracksToLoad.insert(*m_loadableTracks.begin()); 827 tracksToLoad.insert(*m_loadableTracks.begin());
827 828
828 } else { 829 } else {
829 830
830 QStringList available; 831 QStringList displayNames;
831 QString allTracks = tr("Merge all tracks");
832 QString allNonPercussion = tr("Merge all non-percussion tracks");
833
834 int nonTrackItems = 1;
835
836 available << allTracks;
837
838 if (!m_percussionTracks.empty() &&
839 (m_percussionTracks.size() < m_loadableTracks.size())) {
840 available << allNonPercussion;
841 ++nonTrackItems;
842 }
843 832
844 for (set<unsigned int>::iterator i = m_loadableTracks.begin(); 833 for (set<unsigned int>::iterator i = m_loadableTracks.begin();
845 i != m_loadableTracks.end(); ++i) { 834 i != m_loadableTracks.end(); ++i) {
846 835
847 unsigned int trackNo = *i; 836 unsigned int trackNo = *i;
857 .arg(trackNo).arg(m_trackNames.find(trackNo)->second) 846 .arg(trackNo).arg(m_trackNames.find(trackNo)->second)
858 .arg(perc); 847 .arg(perc);
859 } else { 848 } else {
860 label = tr("Track %1 (untitled)%3").arg(trackNo).arg(perc); 849 label = tr("Track %1 (untitled)%3").arg(trackNo).arg(perc);
861 } 850 }
862 available << label; 851
863 } 852 displayNames << label;
864 853 }
865 bool ok = false; 854
866 QString selected = QInputDialog::getItem 855 QString singleTrack;
867 (0, tr("Select track or tracks to import"), 856
868 tr("<b>Select track to import</b><p>You can only import this file as a single annotation layer, but the file contains more than one track, or notes on more than one channel.<p>Please select the track or merged tracks you wish to import:"), 857 bool haveSomePercussion =
869 available, 0, false, &ok); 858 (!m_percussionTracks.empty() &&
870 859 (m_percussionTracks.size() < m_loadableTracks.size()));
871 if (!ok || selected.isEmpty()) return 0; 860
872 861 MIDIFileImportPreferenceAcquirer::TrackPreference pref;
873 if (selected == allTracks || selected == allNonPercussion) { 862
863 if (m_acquirer) {
864 pref = m_acquirer->getTrackImportPreference(displayNames,
865 haveSomePercussion,
866 singleTrack);
867 } else {
868 pref = MIDIFileImportPreferenceAcquirer::MergeAllTracks;
869 }
870
871 if (pref == MIDIFileImportPreferenceAcquirer::ImportNothing) return 0;
872
873 if (pref == MIDIFileImportPreferenceAcquirer::MergeAllTracks ||
874 pref == MIDIFileImportPreferenceAcquirer::MergeAllNonPercussionTracks) {
875
876 for (set<unsigned int>::iterator i = m_loadableTracks.begin();
877 i != m_loadableTracks.end(); ++i) {
878
879 if (pref == MIDIFileImportPreferenceAcquirer::MergeAllTracks ||
880 m_percussionTracks.find(*i) == m_percussionTracks.end()) {
881
882 tracksToLoad.insert(*i);
883 }
884 }
885
886 } else {
887
888 int j = 0;
874 889
875 for (set<unsigned int>::iterator i = m_loadableTracks.begin(); 890 for (set<unsigned int>::iterator i = m_loadableTracks.begin();
876 i != m_loadableTracks.end(); ++i) { 891 i != m_loadableTracks.end(); ++i) {
877 892
878 if (selected == allTracks || 893 if (singleTrack == displayNames[j]) {
879 m_percussionTracks.find(*i) == m_percussionTracks.end()) {
880
881 tracksToLoad.insert(*i);
882 }
883 }
884
885 } else {
886
887 int j = nonTrackItems;
888
889 for (set<unsigned int>::iterator i = m_loadableTracks.begin();
890 i != m_loadableTracks.end(); ++i) {
891
892 if (selected == available[j]) {
893 tracksToLoad.insert(*i); 894 tracksToLoad.insert(*i);
894 break; 895 break;
895 } 896 }
896 897
897 ++j; 898 ++j;