Audacity 3.2.0
NoteTrack.h
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 NoteTrack.h
6
7 Dominic Mazzoni
8
9**********************************************************************/
10
11#ifndef __AUDACITY_NOTETRACK__
12#define __AUDACITY_NOTETRACK__
13
14#include <utility>
15#include "Prefs.h"
16#include "PlayableTrack.h"
17
18#if defined(USE_MIDI)
19
20// define this switch to play MIDI during redisplay to sonify run times
21// Note that if SONIFY is defined, the default MIDI device will be opened
22// and may block normal MIDI playback.
23//#define SONIFY 1
24
25#ifdef SONIFY
26
27#define SONFNS(name) \
28 void Begin ## name(); \
29 void End ## name();
30
31SONFNS(NoteBackground)
32SONFNS(NoteForeground)
33SONFNS(Measures)
34SONFNS(Serialize)
35SONFNS(Unserialize)
36SONFNS(ModifyState)
37SONFNS(AutoSave)
38
39#undef SONFNS
40
41#endif
42
43class wxDC;
44class wxRect;
45
46class Alg_seq; // from "allegro.h"
47
49#ifdef EXPERIMENTAL_MIDI_OUT
51#else
53#endif
54 ;
55
56using QuantizedTimeAndBeat = std::pair< double, double >;
57
58class StretchHandle;
59class TimeWarper;
60
61class AUDACITY_DLL_API NoteTrack final
62 : public NoteTrackBase
63{
64public:
65 // Construct and also build all attachments
66 static NoteTrack *New(AudacityProject &project);
67
68 NoteTrack();
70 NoteTrack(const NoteTrack &orig, ProtectedCreationArg &&) = delete;
71 virtual ~NoteTrack();
72
73 using Holder = std::shared_ptr<NoteTrack>;
74
75private:
76 Track::Holder Clone() const override;
77
78public:
79 double GetOffset() const override;
80 double GetStartTime() const override;
81 double GetEndTime() const override;
82
83 Alg_seq &GetSeq() const;
84
85 void WarpAndTransposeNotes(double t0, double t1,
86 const TimeWarper &warper, double semitones);
87
88 static void DrawLabelControls
89 ( const NoteTrack *pTrack, wxDC & dc, const wxRect &rect,
90 int highlightedChannel = -1 );
91 int FindChannel(const wxRect &rect, int mx, int my);
92 bool LabelClick(const wxRect &rect, int x, int y, bool right);
93
94 void SetSequence(std::unique_ptr<Alg_seq> &&seq);
95 void PrintSequence();
96
97 Alg_seq *MakeExportableSeq(std::unique_ptr<Alg_seq> &cleanup) const;
98 bool ExportMIDI(const wxString &f) const;
99 bool ExportAllegro(const wxString &f) const;
100
101 // High-level editing
102 Track::Holder Cut (double t0, double t1) override;
103 Track::Holder Copy (double t0, double t1, bool forClipboard = true) const override;
104 bool Trim (double t0, double t1) /* not override */;
105 void Clear(double t0, double t1) override;
106 void Paste(double t, const Track *src) override;
107 void Silence(double t0, double t1) override;
108 void InsertSilence(double t, double len) override;
109 bool Shift(double t) /* not override */;
110
111#ifdef EXPERIMENTAL_MIDI_OUT
112 float GetVelocity() const {
113 return mVelocity.load(std::memory_order_relaxed); }
114 void SetVelocity(float velocity);
115#endif
116
117 QuantizedTimeAndBeat NearestBeatTime( double time ) const;
118 bool StretchRegion
119 ( QuantizedTimeAndBeat t0, QuantizedTimeAndBeat t1, double newDur );
120
122 int GetBottomNote() const { return mBottomNote; }
124 int GetTopNote() const { return mTopNote; }
126 void SetBottomNote(int note);
128 void SetTopNote(int note);
130 void SetNoteRange(int note1, int note2);
131
133 void ZoomAllNotes();
135 void ZoomMaxExtent() { SetNoteRange(MinPitch, MaxPitch); }
137 void ShiftNoteRange(int offset);
138
140 void ZoomOut(const wxRect &rect, int y) { Zoom(rect, y, 1.0f / ZoomStep, true); }
142 void ZoomIn(const wxRect &rect, int y) { Zoom(rect, y, ZoomStep, true); }
145 void Zoom(const wxRect &rect, int y, float multiplier, bool center);
146 void ZoomTo(const wxRect &rect, int start, int end);
147
148#if 0
149 // Vertical scrolling is performed by dragging the keyboard at
150 // left of track. Protocol is call StartVScroll, then update by
151 // calling VScroll with original and final mouse position.
152 // These functions are not used -- instead, zooming/dragging works like
153 // audio track zooming/dragging. The vertical scrolling is nice however,
154 // so I left these functions here for possible use in the future.
155 void StartVScroll();
156 void VScroll(int start, int end);
157#endif
158
159 bool HandleXMLTag(const std::string_view& tag, const AttributesList& attrs) override;
160 XMLTagHandler *HandleXMLChild(const std::string_view& tag) override;
161 void WriteXML(XMLWriter &xmlFile) const override;
162
163 // channels are numbered as integers 0-15, visible channels
164 // (mVisibleChannels) is a bit set. Channels are displayed as
165 // integers 1-16.
166
167 // Allegro's data structure does not restrict channels to 16.
168 // Since there is not way to select more than 16 channels,
169 // map all channel numbers mod 16. This will have no effect
170 // on MIDI files, but it will allow users to at least select
171 // all channels on non-MIDI event sequence data.
172#define NUM_CHANNELS 16
173 // Bitmask with all NUM_CHANNELS bits set
174#define ALL_CHANNELS (1 << NUM_CHANNELS) - 1
175#define CHANNEL_BIT(c) (1 << (c % NUM_CHANNELS))
176 unsigned GetVisibleChannels() const {
177 return mVisibleChannels.load(std::memory_order_relaxed);
178 }
179 void SetVisibleChannels(unsigned value) {
180 mVisibleChannels.store(value, std::memory_order_relaxed);
181 }
182 bool IsVisibleChan(int c) const {
183 return (GetVisibleChannels() & CHANNEL_BIT(c)) != 0;
184 }
185 void SetVisibleChan(int c) {
186 mVisibleChannels.fetch_or(CHANNEL_BIT(c), std::memory_order_relaxed); }
187 void ClearVisibleChan(int c) {
188 mVisibleChannels.fetch_and(~CHANNEL_BIT(c), std::memory_order_relaxed); }
189 void ToggleVisibleChan(int c) {
190 mVisibleChannels.fetch_xor(CHANNEL_BIT(c), std::memory_order_relaxed); }
191 // Solos the given channel. If it's the only channel visible, all channels
192 // are enabled; otherwise, it is set to the only visible channel.
193 void SoloVisibleChan(int c) {
194 auto visibleChannels = 0u;
195 if (GetVisibleChannels() == CHANNEL_BIT(c))
196 visibleChannels = ALL_CHANNELS;
197 else
198 visibleChannels = CHANNEL_BIT(c);
199 mVisibleChannels.store(visibleChannels, std::memory_order_relaxed);
200 }
201
202 const TypeInfo &GetTypeInfo() const override;
203 static const TypeInfo &ClassTypeInfo();
204
205 Track::Holder PasteInto( AudacityProject & ) const override;
206
207 ConstIntervals GetIntervals() const override;
208 Intervals GetIntervals() override;
209
210 private:
211#ifdef EXPERIMENTAL_MIDI_OUT
212 void DoSetVelocity(float velocity);
213#endif
214
215 void AddToDuration( double delta );
216
217 // These are mutable to allow NoteTrack to switch details of representation
218 // in logically const methods
219 // At most one of the two pointers is not null at any time.
220 // Both are null in a newly constructed NoteTrack.
221 mutable std::unique_ptr<Alg_seq> mSeq;
222 mutable std::unique_ptr<char[]> mSerializationBuffer;
224
225#ifdef EXPERIMENTAL_MIDI_OUT
227 std::atomic<float> mVelocity{ 0.0f }; // velocity offset
228#endif
229
230 int mBottomNote, mTopNote;
231#if 0
232 // Also unused from vertical scrolling
233 int mStartBottomNote;
234#endif
235
236 // Remember continuous variation for zooming,
237 // but it is rounded off whenever drawing:
239
240 enum { MinPitch = 0, MaxPitch = 127 };
241 static const float ZoomStep;
242
244 std::atomic<unsigned> mVisibleChannels{ ALL_CHANNELS };
245
246 std::weak_ptr<StretchHandle> mStretchHandle;
247};
248
251private:
253 // mBottom is the Y offset of pitch 0 (normally off screen)
254 // Used so that mBottomNote is located at
255 // mY + mHeight - (GetNoteMargin() + 1 + GetPitchHeight())
258
259 enum { MinPitchHeight = 1, MaxPitchHeight = 25 };
260public:
261 NoteTrackDisplayData(const NoteTrack* track, const wxRect &r);
262
263 int GetPitchHeight(int factor) const
264 { return std::max(1, (int)(factor * mPitchHeight)); }
265 int GetNoteMargin() const { return mMargin; };
266 int GetOctaveHeight() const { return GetPitchHeight(12) + 2; }
267 // IPitchToY returns Y coordinate of top of pitch p
268 int IPitchToY(int p) const;
269 // compute the window coordinate of the bottom of an octave: This is
270 // the bottom of the line separating B and C.
271 int GetOctaveBottom(int oct) const {
272 return IPitchToY(oct * 12) + GetPitchHeight(1) + 1;
273 }
274 // Y coordinate for given floating point pitch (rounded to int)
275 int PitchToY(double p) const {
276 return IPitchToY((int) (p + 0.5));
277 }
278 // Integer pitch corresponding to a Y coordinate
279 int YToIPitch(int y) const;
280 // map pitch class number (0-11) to pixel offset from bottom of octave
281 // (the bottom of the black line between B and C) to the top of the
282 // note. Note extra pixel separates B(11)/C(0) and E(4)/F(5).
283 int GetNotePos(int p) const
284 { return 1 + GetPitchHeight(p + 1) + (p > 4); }
285 // get pixel offset to top of ith black key note
286 int GetBlackPos(int i) const { return GetNotePos(i * 2 + 1 + (i > 1)); }
287 // GetWhitePos tells where to draw lines between keys as an offset from
288 // GetOctaveBottom. GetWhitePos(0) returns 1, which matches the location
289 // of the line separating B and C
290 int GetWhitePos(int i) const { return 1 + (i * GetOctaveHeight()) / 7; }
291};
292
293extern AUDACITY_DLL_API StringSetting MIDIPlaybackDevice;
294extern AUDACITY_DLL_API StringSetting MIDIRecordingDevice;
295extern AUDACITY_DLL_API IntSetting MIDISynthLatency_ms;
296
298
299#endif // USE_MIDI
300
301#ifndef SONIFY
302// no-ops:
303#define SonifyBeginSonification()
304#define SonifyEndSonification()
305#define SonifyBeginNoteBackground()
306#define SonifyEndNoteBackground()
307#define SonifyBeginNoteForeground()
308#define SonifyEndNoteForeground()
309#define SonifyBeginMeasures()
310#define SonifyEndMeasures()
311#define SonifyBeginSerialize()
312#define SonifyEndSerialize()
313#define SonifyBeginUnserialize()
314#define SonifyEndUnserialize()
315#define SonifyBeginAutoSave()
316#define SonifyEndAutoSave()
317#define SonifyBeginModifyState()
318#define SonifyEndModifyState()
319#endif
320
321
322AUDACITY_DLL_API wxString GetMIDIDeviceInfo();
323
324#endif
AUDACITY_DLL_API IntSetting MIDISynthLatency_ms
Definition: NoteTrack.cpp:1286
AUDACITY_DLL_API wxString GetMIDIDeviceInfo()
Definition: NoteTrack.cpp:1180
#define CHANNEL_BIT(c)
Definition: NoteTrack.h:175
ENUMERATE_TRACK_TYPE(NoteTrack)
AUDACITY_DLL_API StringSetting MIDIRecordingDevice
Definition: NoteTrack.cpp:1285
AUDACITY_DLL_API StringSetting MIDIPlaybackDevice
Definition: NoteTrack.cpp:1284
#define ALL_CHANNELS
Definition: NoteTrack.h:174
std::pair< double, double > QuantizedTimeAndBeat
Definition: NoteTrack.h:56
Extends Track with notions of mute and solo setting.
std::vector< Attribute > AttributesList
Definition: XMLTagHandler.h:40
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:90
Track subclass holding data representing sound (as notes, or samples, or ...)
Definition: PlayableTrack.h:21
static const TypeInfo & ClassTypeInfo()
Specialization of Setting for int.
Definition: Prefs.h:349
Data used to display a note track.
Definition: NoteTrack.h:250
int GetPitchHeight(int factor) const
Definition: NoteTrack.h:263
int GetNotePos(int p) const
Definition: NoteTrack.h:283
int GetOctaveHeight() const
Definition: NoteTrack.h:266
NoteTrackDisplayData(const NoteTrack *track, const wxRect &r)
Definition: NoteTrack.cpp:1118
int PitchToY(double p) const
Definition: NoteTrack.h:275
int GetOctaveBottom(int oct) const
Definition: NoteTrack.h:271
int GetNoteMargin() const
Definition: NoteTrack.h:265
int YToIPitch(int y) const
Definition: NoteTrack.cpp:1159
int GetWhitePos(int i) const
Definition: NoteTrack.h:290
int IPitchToY(int p) const
Definition: NoteTrack.cpp:1156
int GetBlackPos(int i) const
Definition: NoteTrack.h:286
A Track that is used for Midi notes. (Somewhat old code).
Definition: NoteTrack.h:63
std::unique_ptr< char[]> mSerializationBuffer
Definition: NoteTrack.h:222
bool IsVisibleChan(int c) const
Definition: NoteTrack.h:182
void SetVisibleChannels(unsigned value)
Definition: NoteTrack.h:179
void ZoomMaxExtent()
Zooms so that the entire track is visible.
Definition: NoteTrack.h:135
void ZoomIn(const wxRect &rect, int y)
Zooms in a constant factor (subject to zoom limits)
Definition: NoteTrack.h:142
std::unique_ptr< Alg_seq > mSeq
Definition: NoteTrack.h:221
std::shared_ptr< NoteTrack > Holder
Definition: NoteTrack.h:73
void ZoomOut(const wxRect &rect, int y)
Zooms out a constant factor (subject to zoom limits)
Definition: NoteTrack.h:140
int mBottomNote
Definition: NoteTrack.h:230
std::weak_ptr< StretchHandle > mStretchHandle
Definition: NoteTrack.h:246
unsigned GetVisibleChannels() const
Definition: NoteTrack.h:176
void ToggleVisibleChan(int c)
Definition: NoteTrack.h:189
void SoloVisibleChan(int c)
Definition: NoteTrack.h:193
void ClearVisibleChan(int c)
Definition: NoteTrack.h:187
int GetBottomNote() const
Gets the current bottom note (a pitch)
Definition: NoteTrack.h:122
static const float ZoomStep
Definition: NoteTrack.h:241
int GetTopNote() const
Gets the current top note (a pitch)
Definition: NoteTrack.h:124
float mPitchHeight
Definition: NoteTrack.h:238
long mSerializationLength
Definition: NoteTrack.h:223
NoteTrack(const NoteTrack &orig, ProtectedCreationArg &&)=delete
Copy construction hasn't been necessary yet.
void SetVisibleChan(int c)
Definition: NoteTrack.h:185
AudioTrack subclass that can also be audibly replayed by the program.
Definition: PlayableTrack.h:40
Specialization of Setting for strings.
Definition: Prefs.h:363
Transforms one point in time to another point. For example, a time stretching effect might use one to...
Definition: TimeWarper.h:62
Abstract base class for an object holding data associated with points on a time axis.
Definition: Track.h:162
virtual void Paste(double WXUNUSED(t), const Track *WXUNUSED(src))=0
virtual Holder Cut(double WXUNUSED(t0), double WXUNUSED(t1))=0
virtual Holder PasteInto(AudacityProject &) const =0
Find or create the destination track for a paste, maybe in a different project.
virtual void Clear(double WXUNUSED(t0), double WXUNUSED(t1))=0
virtual const TypeInfo & GetTypeInfo() const =0
virtual double GetStartTime() const =0
virtual Holder Clone() const =0
virtual Holder Copy(double WXUNUSED(t0), double WXUNUSED(t1), bool forClipboard=true) const =0
std::shared_ptr< Track > Holder
Definition: Track.h:303
virtual ConstIntervals GetIntervals() const
Report times on the track where important intervals begin and end, for UI to snap to.
Definition: Track.cpp:1171
virtual void WriteXML(XMLWriter &xmlFile) const =0
virtual void Silence(double WXUNUSED(t0), double WXUNUSED(t1))=0
virtual double GetOffset() const =0
virtual double GetEndTime() const =0
virtual void InsertSilence(double WXUNUSED(t), double WXUNUSED(len))=0
This class is an interface which should be implemented by classes which wish to be able to load and s...
Definition: XMLTagHandler.h:42
virtual XMLTagHandler * HandleXMLChild(const std::string_view &tag)=0
virtual bool HandleXMLTag(const std::string_view &tag, const AttributesList &attrs)=0
Base class for XMLFileWriter and XMLStringWriter that provides the general functionality for creating...
Definition: XMLWriter.h:25
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Definition: PackedArray.h:159
Empty argument passed to some public constructors.
Definition: Track.h:169