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 "AudioIOSequences.h"
16#include "Prefs.h"
17#include "PlayableTrack.h"
18
19#if defined(USE_MIDI)
20
21// define this switch to play MIDI during redisplay to sonify run times
22// Note that if SONIFY is defined, the default MIDI device will be opened
23// and may block normal MIDI playback.
24//#define SONIFY 1
25
26#ifdef SONIFY
27
28#define SONFNS(name) \
29 void Begin ## name(); \
30 void End ## name();
31
32SONFNS(NoteBackground)
33SONFNS(NoteForeground)
34SONFNS(Measures)
35SONFNS(Serialize)
36SONFNS(Unserialize)
37SONFNS(ModifyState)
38SONFNS(AutoSave)
39
40#undef SONFNS
41
42#endif
43
44class wxDC;
45class wxRect;
46
47class Alg_seq; // from "allegro.h"
48
50#ifdef EXPERIMENTAL_MIDI_OUT
52#else
54#endif
55 ;
56
57using QuantizedTimeAndBeat = std::pair< double, double >;
58
59class StretchHandle;
60class TimeWarper;
61
62class AUDACITY_DLL_API NoteTrack final
63 : public UniqueChannelTrack<NoteTrackBase>
65{
66public:
67 // Construct and also build all attachments
68 static NoteTrack *New(AudacityProject &project);
69
70 NoteTrack();
72 NoteTrack(const NoteTrack &orig, ProtectedCreationArg &&) = delete;
73 virtual ~NoteTrack();
74
75 using Holder = std::shared_ptr<NoteTrack>;
76
77private:
78 TrackListHolder Clone() const override;
79
80public:
81 void MoveTo(double origin) override { mOrigin = origin; }
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 TrackListHolder Cut(double t0, double t1) override;
103 TrackListHolder Copy(double t0, double t1, bool forClipboard = true)
104 const override;
105 bool Trim (double t0, double t1) /* not override */;
106 void Clear(double t0, double t1) override;
107 void Paste(double t, const Track &src) override;
108 void
109 Silence(double t0, double t1, ProgressReporter reportProgress = {}) override;
110 void InsertSilence(double t, double len) override;
111 bool Shift(double t) /* not override */;
112
113#ifdef EXPERIMENTAL_MIDI_OUT
114 float GetVelocity() const {
115 return mVelocity.load(std::memory_order_relaxed); }
116 void SetVelocity(float velocity);
117#endif
118
119 QuantizedTimeAndBeat NearestBeatTime( double time ) const;
120 bool StretchRegion
121 ( QuantizedTimeAndBeat t0, QuantizedTimeAndBeat t1, double newDur );
122
124 int GetBottomNote() const { return mBottomNote; }
126 int GetTopNote() const { return mTopNote; }
128 void SetBottomNote(int note);
130 void SetTopNote(int note);
132 void SetNoteRange(int note1, int note2);
133
135 void ZoomAllNotes();
137 void ZoomMaxExtent() { SetNoteRange(MinPitch, MaxPitch); }
139 void ShiftNoteRange(int offset);
140
142 void ZoomOut(const wxRect &rect, int y) { Zoom(rect, y, 1.0f / ZoomStep, true); }
144 void ZoomIn(const wxRect &rect, int y) { Zoom(rect, y, ZoomStep, true); }
147 void Zoom(const wxRect &rect, int y, float multiplier, bool center);
148 void ZoomTo(const wxRect &rect, int start, int end);
149
150#if 0
151 // Vertical scrolling is performed by dragging the keyboard at
152 // left of track. Protocol is call StartVScroll, then update by
153 // calling VScroll with original and final mouse position.
154 // These functions are not used -- instead, zooming/dragging works like
155 // audio track zooming/dragging. The vertical scrolling is nice however,
156 // so I left these functions here for possible use in the future.
157 void StartVScroll();
158 void VScroll(int start, int end);
159#endif
160
161 bool HandleXMLTag(const std::string_view& tag, const AttributesList& attrs) override;
162 XMLTagHandler *HandleXMLChild(const std::string_view& tag) override;
163 void WriteXML(XMLWriter &xmlFile) const override;
164
165 // channels are numbered as integers 0-15, visible channels
166 // (mVisibleChannels) is a bit set. Channels are displayed as
167 // integers 1-16.
168
169 // Allegro's data structure does not restrict channels to 16.
170 // Since there is not way to select more than 16 channels,
171 // map all channel numbers mod 16. This will have no effect
172 // on MIDI files, but it will allow users to at least select
173 // all channels on non-MIDI event sequence data.
174#define NUM_CHANNELS 16
175 // Bitmask with all NUM_CHANNELS bits set
176#define ALL_CHANNELS (1 << NUM_CHANNELS) - 1
177#define CHANNEL_BIT(c) (1 << (c % NUM_CHANNELS))
178 unsigned GetVisibleChannels() const {
179 return mVisibleChannels.load(std::memory_order_relaxed);
180 }
181 void SetVisibleChannels(unsigned value) {
182 mVisibleChannels.store(value, std::memory_order_relaxed);
183 }
184 bool IsVisibleChan(int c) const {
185 return (GetVisibleChannels() & CHANNEL_BIT(c)) != 0;
186 }
187 void SetVisibleChan(int c) {
188 mVisibleChannels.fetch_or(CHANNEL_BIT(c), std::memory_order_relaxed); }
189 void ClearVisibleChan(int c) {
190 mVisibleChannels.fetch_and(~CHANNEL_BIT(c), std::memory_order_relaxed); }
191 void ToggleVisibleChan(int c) {
192 mVisibleChannels.fetch_xor(CHANNEL_BIT(c), std::memory_order_relaxed); }
193 // Solos the given channel. If it's the only channel visible, all channels
194 // are enabled; otherwise, it is set to the only visible channel.
195 void SoloVisibleChan(int c) {
196 auto visibleChannels = 0u;
197 if (GetVisibleChannels() == CHANNEL_BIT(c))
198 visibleChannels = ALL_CHANNELS;
199 else
200 visibleChannels = CHANNEL_BIT(c);
201 mVisibleChannels.store(visibleChannels, std::memory_order_relaxed);
202 }
203
204 const TypeInfo &GetTypeInfo() const override;
205 static const TypeInfo &ClassTypeInfo();
206
208 const override;
209
210 size_t NIntervals() const override;
211
214 ~Interval() override;
215 std::shared_ptr<ChannelInterval> DoGetChannel(size_t iChannel) override;
216 };
217
218private:
219 std::shared_ptr<WideChannelGroupInterval> DoGetInterval(size_t iInterval)
220 override;
221
222#ifdef EXPERIMENTAL_MIDI_OUT
223 void DoSetVelocity(float velocity);
224#endif
225
226 void AddToDuration( double delta );
228 const std::optional<double>& oldTempo, double newTempo) override;
229
230 // These are mutable to allow NoteTrack to switch details of representation
231 // in logically const methods
232 // At most one of the two pointers is not null at any time.
233 // Both are null in a newly constructed NoteTrack.
234 mutable std::unique_ptr<Alg_seq> mSeq;
235 mutable std::unique_ptr<char[]> mSerializationBuffer;
237
238#ifdef EXPERIMENTAL_MIDI_OUT
240 std::atomic<float> mVelocity{ 0.0f }; // velocity offset
241#endif
242
243 int mBottomNote, mTopNote;
244#if 0
245 // Also unused from vertical scrolling
246 int mStartBottomNote;
247#endif
248
249 // Remember continuous variation for zooming,
250 // but it is rounded off whenever drawing:
252
253 enum { MinPitch = 0, MaxPitch = 127 };
254 static const float ZoomStep;
255
257 std::atomic<unsigned> mVisibleChannels{ ALL_CHANNELS };
258
259 std::weak_ptr<StretchHandle> mStretchHandle;
260 double mOrigin{ 0.0 };
261};
262
265private:
267 // mBottom is the Y offset of pitch 0 (normally off screen)
268 // Used so that mBottomNote is located at
269 // mY + mHeight - (GetNoteMargin() + 1 + GetPitchHeight())
272
273 enum { MinPitchHeight = 1, MaxPitchHeight = 25 };
274public:
275 NoteTrackDisplayData(const NoteTrack* track, const wxRect &r);
276
277 int GetPitchHeight(int factor) const
278 { return std::max(1, (int)(factor * mPitchHeight)); }
279 int GetNoteMargin() const { return mMargin; };
280 int GetOctaveHeight() const { return GetPitchHeight(12) + 2; }
281 // IPitchToY returns Y coordinate of top of pitch p
282 int IPitchToY(int p) const;
283 // compute the window coordinate of the bottom of an octave: This is
284 // the bottom of the line separating B and C.
285 int GetOctaveBottom(int oct) const {
286 return IPitchToY(oct * 12) + GetPitchHeight(1) + 1;
287 }
288 // Y coordinate for given floating point pitch (rounded to int)
289 int PitchToY(double p) const {
290 return IPitchToY((int) (p + 0.5));
291 }
292 // Integer pitch corresponding to a Y coordinate
293 int YToIPitch(int y) const;
294 // map pitch class number (0-11) to pixel offset from bottom of octave
295 // (the bottom of the black line between B and C) to the top of the
296 // note. Note extra pixel separates B(11)/C(0) and E(4)/F(5).
297 int GetNotePos(int p) const
298 { return 1 + GetPitchHeight(p + 1) + (p > 4); }
299 // get pixel offset to top of ith black key note
300 int GetBlackPos(int i) const { return GetNotePos(i * 2 + 1 + (i > 1)); }
301 // GetWhitePos tells where to draw lines between keys as an offset from
302 // GetOctaveBottom. GetWhitePos(0) returns 1, which matches the location
303 // of the line separating B and C
304 int GetWhitePos(int i) const { return 1 + (i * GetOctaveHeight()) / 7; }
305};
306
307extern AUDACITY_DLL_API StringSetting MIDIPlaybackDevice;
308extern AUDACITY_DLL_API StringSetting MIDIRecordingDevice;
309extern AUDACITY_DLL_API IntSetting MIDISynthLatency_ms;
310
312
313#endif // USE_MIDI
314
315#ifndef SONIFY
316// no-ops:
317#define SonifyBeginSonification()
318#define SonifyEndSonification()
319#define SonifyBeginNoteBackground()
320#define SonifyEndNoteBackground()
321#define SonifyBeginNoteForeground()
322#define SonifyEndNoteForeground()
323#define SonifyBeginMeasures()
324#define SonifyEndMeasures()
325#define SonifyBeginSerialize()
326#define SonifyEndSerialize()
327#define SonifyBeginUnserialize()
328#define SonifyEndUnserialize()
329#define SonifyBeginAutoSave()
330#define SonifyEndAutoSave()
331#define SonifyBeginModifyState()
332#define SonifyEndModifyState()
333#endif
334
335
336AUDACITY_DLL_API wxString GetMIDIDeviceInfo();
337
338#endif
AUDACITY_DLL_API IntSetting MIDISynthLatency_ms
Definition: NoteTrack.cpp:1305
AUDACITY_DLL_API wxString GetMIDIDeviceInfo()
Definition: NoteTrack.cpp:1199
#define CHANNEL_BIT(c)
Definition: NoteTrack.h:177
ENUMERATE_TRACK_TYPE(NoteTrack)
AUDACITY_DLL_API StringSetting MIDIRecordingDevice
Definition: NoteTrack.cpp:1304
AUDACITY_DLL_API StringSetting MIDIPlaybackDevice
Definition: NoteTrack.cpp:1303
#define ALL_CHANNELS
Definition: NoteTrack.h:176
std::pair< double, double > QuantizedTimeAndBeat
Definition: NoteTrack.h:57
Extends Track with notions of mute and solo setting.
const auto project
std::function< void(double)> ProgressReporter
Definition: Track.h:54
std::shared_ptr< TrackList > TrackListHolder
Definition: Track.h:43
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
virtual std::shared_ptr< Interval > DoGetInterval(size_t iInterval)=0
Retrieve an interval.
size_t NIntervals() const
Report the number of intervals.
Definition: Channel.h:608
Specialization of Setting for int.
Definition: Prefs.h:354
Data used to display a note track.
Definition: NoteTrack.h:264
int GetPitchHeight(int factor) const
Definition: NoteTrack.h:277
int GetNotePos(int p) const
Definition: NoteTrack.h:297
int GetOctaveHeight() const
Definition: NoteTrack.h:280
NoteTrackDisplayData(const NoteTrack *track, const wxRect &r)
Definition: NoteTrack.cpp:1137
int PitchToY(double p) const
Definition: NoteTrack.h:289
int GetOctaveBottom(int oct) const
Definition: NoteTrack.h:285
int GetNoteMargin() const
Definition: NoteTrack.h:279
int YToIPitch(int y) const
Definition: NoteTrack.cpp:1178
int GetWhitePos(int i) const
Definition: NoteTrack.h:304
int IPitchToY(int p) const
Definition: NoteTrack.cpp:1175
int GetBlackPos(int i) const
Definition: NoteTrack.h:300
A Track that is used for Midi notes. (Somewhat old code).
Definition: NoteTrack.h:65
std::unique_ptr< char[]> mSerializationBuffer
Definition: NoteTrack.h:235
bool IsVisibleChan(int c) const
Definition: NoteTrack.h:184
void MoveTo(double origin) override
Change start time to given time point.
Definition: NoteTrack.h:81
void SetVisibleChannels(unsigned value)
Definition: NoteTrack.h:181
void ZoomMaxExtent()
Zooms so that the entire track is visible.
Definition: NoteTrack.h:137
void ZoomIn(const wxRect &rect, int y)
Zooms in a constant factor (subject to zoom limits)
Definition: NoteTrack.h:144
std::unique_ptr< Alg_seq > mSeq
Definition: NoteTrack.h:234
std::shared_ptr< NoteTrack > Holder
Definition: NoteTrack.h:75
void ZoomOut(const wxRect &rect, int y)
Zooms out a constant factor (subject to zoom limits)
Definition: NoteTrack.h:142
int mBottomNote
Definition: NoteTrack.h:243
std::weak_ptr< StretchHandle > mStretchHandle
Definition: NoteTrack.h:259
unsigned GetVisibleChannels() const
Definition: NoteTrack.h:178
void ToggleVisibleChan(int c)
Definition: NoteTrack.h:191
void SoloVisibleChan(int c)
Definition: NoteTrack.h:195
void ClearVisibleChan(int c)
Definition: NoteTrack.h:189
int GetBottomNote() const
Gets the current bottom note (a pitch)
Definition: NoteTrack.h:124
static const float ZoomStep
Definition: NoteTrack.h:254
int GetTopNote() const
Gets the current top note (a pitch)
Definition: NoteTrack.h:126
float mPitchHeight
Definition: NoteTrack.h:251
long mSerializationLength
Definition: NoteTrack.h:236
NoteTrack(const NoteTrack &orig, ProtectedCreationArg &&)=delete
Copy construction hasn't been necessary yet.
void SetVisibleChan(int c)
Definition: NoteTrack.h:187
This is defined just to enable dynamic_cast on it.
AudioTrack subclass that can also be audibly replayed by the program.
Definition: PlayableTrack.h:40
Specialization of Setting for strings.
Definition: Prefs.h:368
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:123
virtual TrackListHolder Clone() const =0
virtual void Paste(double t, const Track &src)=0
Weak precondition allows overrides to replicate one channel into many.
virtual Holder PasteInto(AudacityProject &project, TrackList &list) const =0
virtual const TypeInfo & GetTypeInfo() const =0
virtual void InsertSilence(double t, double len)=0
static const TypeInfo & ClassTypeInfo()
Definition: Track.cpp:1223
virtual TrackListHolder Copy(double t0, double t1, bool forClipboard=true) const =0
Create new tracks and don't modify this track.
virtual void DoOnProjectTempoChange(const std::optional< double > &oldTempo, double newTempo)=0
virtual void Clear(double t0, double t1)=0
std::shared_ptr< Track > Holder
Definition: Track.h:226
virtual void WriteXML(XMLWriter &xmlFile) const =0
virtual void Silence(double t0, double t1, ProgressReporter reportProgress={})=0
virtual TrackListHolder Cut(double t0, double t1)=0
Create tracks and modify this track.
A flat linked list of tracks supporting Add, Remove, Clear, and Contains, serialization of the list o...
Definition: Track.h:987
Generates overrides of channel-related functions.
Definition: Track.h:499
WideChannelGroupInterval(const ChannelGroup &group, double start, double end)
Definition: Channel.cpp:21
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
~Interval() override
Empty argument passed to some public constructors.
Definition: Track.h:130