Audacity 3.2.0
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
12#include "ImportMIDI.h"
13
14#include <wx/defs.h>
15#include <wx/ffile.h>
16#include <wx/frame.h>
17#include <wx/intl.h>
18
19#if defined(USE_MIDI)
20
21
22#include "../lib-src/header-substitutes/allegro.h"
23
24//#include "strparse.h"
25//#include "mfmidi.h"
26
27#include "../NoteTrack.h"
28#include "Project.h"
29#include "../ProjectFileIO.h"
30#include "ProjectHistory.h"
31#include "../ProjectWindow.h"
32#include "../SelectUtilities.h"
33#include "../widgets/AudacityMessageBox.h"
34#include "../widgets/FileHistory.h"
35
36// Given an existing project, try to import into it, return true on success
37bool DoImportMIDI( AudacityProject &project, const FilePath &fileName )
38{
39 auto &projectFileIO = ProjectFileIO::Get( project );
40 auto &tracks = TrackList::Get( project );
41 auto newTrack = std::make_shared<NoteTrack>();
42 bool initiallyEmpty = tracks.empty();
43
44 if (::ImportMIDI(fileName, newTrack.get())) {
45
47 auto pTrack = tracks.Add( newTrack );
48 pTrack->SetSelected(true);
49
50 // Fix the bug 2109.
51 // In case the project had soloed tracks before importing,
52 // the newly imported track is muted.
53 const bool projectHasSolo =
54 !(tracks.Any<PlayableTrack>() + &PlayableTrack::GetSolo).empty();
55#ifdef EXPERIMENTAL_MIDI_OUT
56 if (projectHasSolo)
57 pTrack->SetMute(true);
58#endif
59
60 ProjectHistory::Get( project )
61 .PushState(
62 XO("Imported MIDI from '%s'").Format( fileName ),
63 XO("Import MIDI")
64 );
65
66 ProjectWindow::Get( project ).ZoomAfterImport(pTrack);
67 FileHistory::Global().Append(fileName);
68
69 // If the project was clean and temporary (not permanently saved), then set
70 // the filename to the just imported path.
71 if (initiallyEmpty && projectFileIO.IsTemporary()) {
72 wxFileName fn(fileName);
73 project.SetProjectName(fn.GetName());
74 project.SetInitialImportPath(fn.GetPath());
75 projectFileIO.SetProjectTitle();
76 }
77 return true;
78 }
79 else
80 return false;
81}
82
83bool ImportMIDI(const FilePath &fName, NoteTrack * dest)
84{
85 if (fName.length() <= 4){
87 XO("Could not open file %s: Filename too short.").Format( fName ) );
88 return false;
89 }
90
91 bool is_midi = false;
92 if (fName.Right(4).CmpNoCase(wxT(".mid")) == 0 || fName.Right(5).CmpNoCase(wxT(".midi")) == 0)
93 is_midi = true;
94 else if(fName.Right(4).CmpNoCase(wxT(".gro")) != 0) {
96 XO("Could not open file %s: Incorrect filetype.").Format( fName ) );
97 return false;
98 }
99
100 wxFFile mf(fName, wxT("rb"));
101 if (!mf.IsOpened()) {
103 XO("Could not open file %s.").Format( fName ) );
104 return false;
105 }
106
107 double offset = 0.0;
108 auto new_seq = std::make_unique<Alg_seq>(fName.mb_str(), is_midi, &offset);
109
110 //Should we also check if(seq->tracks() == 0) ?
111 if(new_seq->get_read_error() == alg_error_open){
113 XO("Could not open file %s.").Format( fName ) );
114 mf.Close();
115 return false;
116 }
117
118 dest->SetSequence(std::move(new_seq));
119 dest->SetOffset(offset);
120 wxString trackNameBase = fName.AfterLast(wxFILE_SEP_PATH).BeforeLast('.');
121 dest->SetName(trackNameBase);
122 mf.Close();
123
124 dest->ZoomAllNotes();
125 return true;
126}
127
128#endif
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
bool DoImportMIDI(AudacityProject &project, const FilePath &fileName)
Definition: ImportMIDI.cpp:37
bool ImportMIDI(const FilePath &fName, NoteTrack *dest)
Definition: ImportMIDI.cpp:83
#define XO(s)
Definition: Internat.h:31
wxString FilePath
Definition: Project.h:20
static const auto fn
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:89
void SetInitialImportPath(const FilePath &path)
Definition: Project.cpp:105
void SetProjectName(const wxString &name)
Definition: Project.cpp:95
void Append(const FilePath &file)
Definition: FileHistory.h:42
static FileHistory & Global()
Definition: FileHistory.cpp:37
Abstract base class used in importing a file.
A Track that is used for Midi notes. (Somewhat old code).
Definition: NoteTrack.h:67
void SetSequence(std::unique_ptr< Alg_seq > &&seq)
Definition: NoteTrack.cpp:380
void ZoomAllNotes()
Zooms so that all notes are visible.
Definition: NoteTrack.cpp:1088
AudioTrack subclass that can also be audibly replayed by the program.
Definition: Track.h:909
bool GetSolo() const
Definition: Track.h:918
static ProjectFileIO & Get(AudacityProject &project)
void PushState(const TranslatableString &desc, const TranslatableString &shortDesc)
static ProjectHistory & Get(AudacityProject &project)
void ZoomAfterImport(Track *pTrack)
static ProjectWindow & Get(AudacityProject &project)
virtual void SetOffset(double o)
Definition: Track.h:475
void SetName(const wxString &n)
Definition: Track.cpp:80
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:467
void SelectNone(AudacityProject &project)