Audacity  2.2.2
ImportMIDI.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3  Audacity: A Digital Audio Editor
4 
5  ImportMIDI.cpp
6 
7  Dominic Mazzoni
8 
9 **********************************************************************/
10 
11 #include "../Audacity.h"
12 #include "ImportMIDI.h"
13 
14 #include <wx/defs.h>
15 #include <wx/ffile.h>
16 #include <wx/intl.h>
17 
18 #if defined(USE_MIDI)
19 
20 //#include "allegro.h"
21 //#include "strparse.h"
22 //#include "mfmidi.h"
23 
24 #include "../Internat.h"
25 #include "../NoteTrack.h"
26 #include "../widgets/ErrorDialog.h"
27 
28 bool ImportMIDI(const wxString &fName, NoteTrack * dest)
29 {
30  if (fName.Length() <= 4){
31  AudacityMessageBox( wxString::Format(
32  _("Could not open file %s: Filename too short."), fName
33  ) );
34  return false;
35  }
36 
37  bool is_midi = false;
38  if (fName.Right(4).CmpNoCase(wxT(".mid")) == 0 || fName.Right(5).CmpNoCase(wxT(".midi")) == 0)
39  is_midi = true;
40  else if(fName.Right(4).CmpNoCase(wxT(".gro")) != 0) {
41  AudacityMessageBox( wxString::Format(
42  _("Could not open file %s: Incorrect filetype."), fName
43  ) );
44  return false;
45  }
46 
47  wxFFile mf(fName, wxT("rb"));
48  if (!mf.IsOpened()) {
49  AudacityMessageBox( wxString::Format(
50  _("Could not open file %s."), fName
51  ) );
52  return false;
53  }
54 
55  double offset = 0.0;
56  auto new_seq = std::make_unique<Alg_seq>(fName.mb_str(), is_midi, &offset);
57 
58  //Should we also check if(seq->tracks() == 0) ?
59  if(new_seq->get_read_error() == alg_error_open){
60  AudacityMessageBox( wxString::Format(
61  _("Could not open file %s."), fName
62  ) );
63  mf.Close();
64  return false;
65  }
66 
67  dest->SetSequence(std::move(new_seq));
68  dest->SetOffset(offset);
69  wxString trackNameBase = fName.AfterLast(wxFILE_SEP_PATH).BeforeLast('.');
70  dest->SetName(trackNameBase);
71  mf.Close();
72  // the mean pitch should be somewhere in the middle of the display
73  Alg_iterator iterator( &dest->GetSeq(), false );
74  iterator.begin();
75  // for every event
76  Alg_event_ptr evt;
77  int note_count = 0;
78  int pitch_sum = 0;
79  while (NULL != (evt = iterator.next())) {
80  // if the event is a note
81  if (evt->get_type() == 'n') {
82  Alg_note_ptr note = (Alg_note_ptr) evt;
83  pitch_sum += (int) note->pitch;
84  note_count++;
85  }
86  }
87  int mean_pitch = (note_count > 0 ? pitch_sum / note_count : 60);
88  // initial track is about 27 half-steps high; if bottom note is C,
89  // then middle pitch class is D. Round mean_pitch to the nearest D:
90  int mid_pitch = ((mean_pitch - 2 + 6) / 12) * 12 + 2;
91  dest->SetBottomNote(mid_pitch - 14);
92  return true;
93 }
94 
95 #endif
int AudacityMessageBox(const wxString &message, const wxString &caption=AudacityMessageBoxCaptionStr(), long style=wxOK|wxCENTRE, wxWindow *parent=NULL, int x=wxDefaultCoord, int y=wxDefaultCoord)
Definition: ErrorDialog.h:92
_("Move Track &Down")+wxT("\t")+(GetActiveProject() -> GetCommandManager() ->GetKeyFromName(wxT("TrackMoveDown")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveTopID, _("Move Track to &Top")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveTop")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveBottomID, _("Move Track to &Bottom")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveBottom")).Raw()), OnMoveTrack)#define SET_TRACK_NAME_PLUGIN_SYMBOLclass SetTrackNameCommand:public AudacityCommand
A Track that is used for Midi notes. (Somewhat old code).