Audacity 3.2.0
Public Types | Public Member Functions | Static Public Member Functions | Private Types | Private Member Functions | Private Attributes | Static Private Attributes | List of all members
NoteTrack Class Referencefinal

A Track that is used for Midi notes. (Somewhat old code). More...

#include <NoteTrack.h>

Inheritance diagram for NoteTrack:
[legend]
Collaboration diagram for NoteTrack:
[legend]

Public Types

using Holder = std::shared_ptr< NoteTrack >
 
- Public Types inherited from Track
enum class  LinkType : int { None = 0 , Group = 2 , Aligned }
 For two tracks describes the type of the linkage. More...
 
enum  ChannelType { LeftChannel = 0 , RightChannel = 1 , MonoChannel = 2 }
 
using ChannelGroupAttachments = ClientData::Site< ChannelGroupData, ClientData::Cloneable<>, ClientData::DeepCopying >
 Hosting of objects attached by higher level code. More...
 
using AttachedObjects = ::AttachedTrackObjects
 Alias for my base type. More...
 
using IntervalData = TrackIntervalData
 
using Interval = TrackInterval
 
using Intervals = std::vector< Interval >
 
using ConstInterval = ConstTrackInterval
 
using ConstIntervals = std::vector< ConstInterval >
 
using Holder = std::shared_ptr< Track >
 
template<typename R = void>
using Continuation = std::function< R() >
 Type of arguments passed as optional second parameter to TypeSwitch() cases. More...
 
using Fallthrough = Continuation<>
 Type of arguments passed as optional second parameter to TypeSwitch<void>() cases. More...
 
- Public Types inherited from ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >
using DataType = ClientData
 
using DataPointer = Pointer< ClientData >
 
using DataFactory = std::function< DataPointer(Host &) >
 Type of function from which RegisteredFactory is constructed; it builds attachments. More...
 

Public Member Functions

 NoteTrack ()
 
virtual ~NoteTrack ()
 
double GetOffset () const override
 
double GetStartTime () const override
 
double GetEndTime () const override
 
Alg_seq & GetSeq () const
 
void WarpAndTransposeNotes (double t0, double t1, const TimeWarper &warper, double semitones)
 
int FindChannel (const wxRect &rect, int mx, int my)
 
bool LabelClick (const wxRect &rect, int x, int y, bool right)
 
void SetSequence (std::unique_ptr< Alg_seq > &&seq)
 
void PrintSequence ()
 
Alg_seq * MakeExportableSeq (std::unique_ptr< Alg_seq > &cleanup) const
 
bool ExportMIDI (const wxString &f) const
 
bool ExportAllegro (const wxString &f) const
 
Track::Holder Cut (double t0, double t1) override
 
Track::Holder Copy (double t0, double t1, bool forClipboard=true) const override
 
bool Trim (double t0, double t1)
 
void Clear (double t0, double t1) override
 
void Paste (double t, const Track *src) override
 
void Silence (double t0, double t1) override
 
void InsertSilence (double t, double len) override
 
bool Shift (double t)
 
QuantizedTimeAndBeat NearestBeatTime (double time) const
 
bool StretchRegion (QuantizedTimeAndBeat t0, QuantizedTimeAndBeat t1, double newDur)
 
int GetBottomNote () const
 Gets the current bottom note (a pitch) More...
 
int GetTopNote () const
 Gets the current top note (a pitch) More...
 
void SetBottomNote (int note)
 Sets the bottom note (a pitch), making sure that it is never greater than the top note. More...
 
void SetTopNote (int note)
 Sets the top note (a pitch), making sure that it is never less than the bottom note. More...
 
void SetNoteRange (int note1, int note2)
 Sets the top and bottom note (both pitches) automatically, swapping them if needed. More...
 
void ZoomAllNotes ()
 Zooms so that all notes are visible. More...
 
void ZoomMaxExtent ()
 Zooms so that the entire track is visible. More...
 
void ShiftNoteRange (int offset)
 Shifts all notes vertically by the given pitch. More...
 
void ZoomOut (const wxRect &rect, int y)
 Zooms out a constant factor (subject to zoom limits) More...
 
void ZoomIn (const wxRect &rect, int y)
 Zooms in a constant factor (subject to zoom limits) More...
 
void Zoom (const wxRect &rect, int y, float multiplier, bool center)
 
void ZoomTo (const wxRect &rect, int start, int end)
 
bool HandleXMLTag (const std::string_view &tag, const AttributesList &attrs) override
 
XMLTagHandlerHandleXMLChild (const std::string_view &tag) override
 
void WriteXML (XMLWriter &xmlFile) const override
 
unsigned GetVisibleChannels () const
 
void SetVisibleChannels (unsigned value)
 
bool IsVisibleChan (int c) const
 
void SetVisibleChan (int c)
 
void ClearVisibleChan (int c)
 
void ToggleVisibleChan (int c)
 
void SoloVisibleChan (int c)
 
const TypeInfoGetTypeInfo () const override
 
Track::Holder PasteInto (AudacityProject &) const override
 Find or create the destination track for a paste, maybe in a different project. More...
 
ConstIntervals GetIntervals () const override
 Report times on the track where important intervals begin and end, for UI to snap to. More...
 
Intervals GetIntervals () override
 
- Public Member Functions inherited from AudioTrack
 AudioTrack ()
 
 AudioTrack (const Track &orig)
 
void WriteXMLAttributes (XMLWriter &WXUNUSED(xmlFile)) const
 
bool HandleXMLAttribute (const std::string_view &, const XMLAttributeValueView &)
 
- Public Member Functions inherited from Track
TrackId GetId () const
 
template<typename Subclass = Track>
std::shared_ptr< Subclass > SharedPointer ()
 
template<typename Subclass = const Track>
auto SharedPointer () const -> std::enable_if_t< std::is_const_v< Subclass >, std::shared_ptr< Subclass > >
 
std::shared_ptr< TrackSubstitutePendingChangedTrack ()
 
std::shared_ptr< const TrackSubstitutePendingChangedTrack () const
 
std::shared_ptr< const TrackSubstituteOriginalTrack () const
 
virtual const TypeInfoGetTypeInfo () const =0
 
virtual const TypeNamesGetTypeNames () const
 
virtual bool SupportsBasicEditing () const
 Whether this track type implements cut-copy-paste; by default, true. More...
 
virtual Holder PasteInto (AudacityProject &) const =0
 Find or create the destination track for a paste, maybe in a different project. More...
 
virtual ConstIntervals GetIntervals () const
 Report times on the track where important intervals begin and end, for UI to snap to. More...
 
virtual Intervals GetIntervals ()
 
int GetIndex () const
 
void SetIndex (int index)
 
virtual bool LinkConsistencyFix (bool doFix=true, bool completeList=true)
 Check consistency of channel groups, and maybe fix it. More...
 
bool LinkConsistencyCheck (bool completeList)
 Do the non-mutating part of consistency fix only and return status. More...
 
bool HasOwner () const
 
std::shared_ptr< TrackListGetOwner () const
 
LinkType GetLinkType () const noexcept
 
bool IsAlignedWithLeader () const
 Returns true if the leader track has link type LinkType::Aligned. More...
 
ChannelGroupDataGetGroupData ()
 
const ChannelGroupDataGetGroupData () const
 
 Track ()
 
 Track (const Track &orig)
 
virtual ~Track ()
 
void Init (const Track &orig)
 
virtual Holder Duplicate () const
 
virtual void Merge (const Track &orig)
 
wxString GetName () const
 
void SetName (const wxString &n)
 
bool GetSelected () const
 
virtual void SetSelected (bool s)
 
void EnsureVisible (bool modifyState=false)
 
virtual ChannelType GetChannel () const
 
virtual double GetOffset () const =0
 
void Offset (double t)
 
virtual void SetOffset (double o)
 
virtual void SetPan (float)
 
virtual void SetPanFromChannelType ()
 
virtual Holder Cut (double WXUNUSED(t0), double WXUNUSED(t1))=0
 
virtual Holder Copy (double WXUNUSED(t0), double WXUNUSED(t1), bool forClipboard=true) const =0
 
virtual void Clear (double WXUNUSED(t0), double WXUNUSED(t1))=0
 
virtual void Paste (double WXUNUSED(t), const Track *WXUNUSED(src))=0
 
virtual void SyncLockAdjust (double oldT1, double newT1)
 
virtual void Silence (double WXUNUSED(t0), double WXUNUSED(t1))=0
 
virtual void InsertSilence (double WXUNUSED(t), double WXUNUSED(len))=0
 
bool SameKindAs (const Track &track) const
 
template<typename R = void, typename ... Functions>
TypeSwitch (const Functions &...functions)
 Use this function rather than testing track type explicitly and making down-casts. More...
 
template<typename R = void, typename ... Functions>
TypeSwitch (const Functions &...functions) const
 Use this function rather than testing track type explicitly and making down-casts. More...
 
virtual void WriteXML (XMLWriter &xmlFile) const =0
 
virtual bool GetErrorOpening ()
 
virtual double GetStartTime () const =0
 
virtual double GetEndTime () const =0
 
void Notify (int code=-1)
 
bool Any () const
 
bool IsSelected () const
 
bool IsLeader () const
 
bool IsSelectedLeader () const
 
void AdjustPositions ()
 
void WriteCommonXMLAttributes (XMLWriter &xmlFile, bool includeNameAndSelected=true) const
 
bool HandleCommonXMLAttribute (const std::string_view &attr, const XMLAttributeValueView &valueView)
 
- Public Member Functions inherited from XMLTagHandler
 XMLTagHandler ()
 
virtual ~XMLTagHandler ()
 
virtual bool HandleXMLTag (const std::string_view &tag, const AttributesList &attrs)=0
 
virtual void HandleXMLEndTag (const std::string_view &WXUNUSED(tag))
 
virtual void HandleXMLContent (const std::string_view &WXUNUSED(content))
 
virtual XMLTagHandlerHandleXMLChild (const std::string_view &tag)=0
 
void ReadXMLEndTag (const char *tag)
 
void ReadXMLContent (const char *s, int len)
 
XMLTagHandlerReadXMLChild (const char *tag)
 
- Public Member Functions inherited from ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >
 ~Site ()
 
 Site ()
 
 Site (const Site &other)
 
Siteoperator= (const Site &other)
 
 Site (Site &&other)
 
Siteoperator= (Site &&other)
 
size_t size () const
 How many attachment pointers are in the Site. More...
 
template<typename Subclass = ClientData>
Subclass & Get (const RegisteredFactory &key)
 Get reference to an attachment, creating on demand if not present, down-cast it to Subclass. More...
 
template<typename Subclass = const ClientData>
auto Get (const RegisteredFactory &key) const -> std::enable_if_t< std::is_const< Subclass >::value, Subclass & >
 Get reference to an attachment, creating on demand if not present, down-cast it to Subclass. More...
 
template<typename Subclass = ClientData>
Subclass * Find (const RegisteredFactory &key)
 Get a (bare) pointer to an attachment, or null, down-cast it to Subclass *; will not create on demand. More...
 
template<typename Subclass = const ClientData>
auto Find (const RegisteredFactory &key) const -> std::enable_if_t< std::is_const< Subclass >::value, Subclass * >
 Get a (bare) pointer to an attachment, or null, down-cast it to Subclass *; will not create on demand. More...
 
template<typename ReplacementPointer >
void Assign (const RegisteredFactory &key, ReplacementPointer &&replacement)
 Reassign Site's pointer to ClientData. More...
 

Static Public Member Functions

static NoteTrackNew (AudacityProject &project)
 
static void DrawLabelControls (const NoteTrack *pTrack, wxDC &dc, const wxRect &rect, int highlightedChannel=-1)
 
static const TypeInfoClassTypeInfo ()
 
- Static Public Member Functions inherited from AudioTrack
static const TypeInfoClassTypeInfo ()
 
- Static Public Member Functions inherited from Track
template<typename Subclass = Track>
static std::shared_ptr< Subclass > SharedPointer (Track *pTrack)
 
template<typename Subclass = const Track>
static std::shared_ptr< Subclass > SharedPointer (const Track *pTrack)
 
static const TypeInfoClassTypeInfo ()
 
static void FinishCopy (const Track *n, Track *dest)
 
template<typename TrackType >
static void checkTrackType ()
 
template<typename R , typename TrackType , typename... Functions>
static R CallExecutor (R *, std::tuple<> *, TrackType &, const Functions &...)
 
template<typename R , typename TrackType , typename... Functions, typename Executor , typename... Executors>
static R CallExecutor (R *, std::tuple< Executor, Executors... > *, TrackType &track, const Functions &...functions)
 
template<typename ... Executors>
static constexpr unsigned UsedCases (std::tuple< Executors... > *)
 
template<typename Tag , bool IsConst, typename R , typename ... TrackTypes, typename ... Functions>
static R DoTypeSwitch (std::conditional_t< IsConst, const Track, Track > &track, std::tuple< TrackTypes... > *, const Functions &...functions)
 
- Static Public Member Functions inherited from ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >
static size_t slots ()
 How many static factories have been registered with this specialization of Site. More...
 

Private Types

enum  { MinPitch = 0 , MaxPitch = 127 }
 

Private Member Functions

Track::Holder Clone () const override
 
void AddToDuration (double delta)
 

Private Attributes

std::unique_ptr< Alg_seq > mSeq
 
std::unique_ptr< char[]> mSerializationBuffer
 
long mSerializationLength
 
int mBottomNote
 
int mTopNote
 
float mPitchHeight
 
std::atomic< unsigned > mVisibleChannels { ALL_CHANNELS }
 A bit set; atomic because it may be read by worker threads in playback. More...
 
std::weak_ptr< StretchHandlemStretchHandle
 

Static Private Attributes

static const float ZoomStep = powf( 2.0f, 0.25f )
 

Additional Inherited Members

- Public Attributes inherited from Track
std::pair< int, int > vrulerSize
 
- Protected Member Functions inherited from Track
void SetLinkType (LinkType linkType, bool completeList=true)
 
void SetChannel (ChannelType c) noexcept
 
- Protected Member Functions inherited from ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >
template<typename Function >
void ForEach (const Function &function)
 Invoke function on each ClientData object that has been created in this. More...
 
template<typename Function >
void ForEach (const Function &function) const
 Invoke function on each ClientData object that has been created in this. More...
 
template<typename Function >
ClientData * FindIf (const Function &function)
 Return pointer to first attachment in this that is not null and satisfies a predicate, or nullptr. More...
 
template<typename Function >
const ClientData * FindIf (const Function &function) const
 Return pointer to first attachment in this that is not null and satisfies a predicate, or nullptr. More...
 
void BuildAll ()
 For each RegisteredFactory, if the corresponding attachment is absent in this, build and store it. More...
 
- Protected Attributes inherited from Track
std::weak_ptr< TrackListmList
 
TrackNodePointer mNode {}
 Holds iterator to self, so that TrackList::Find can be constant-time. More...
 
int mIndex
 0-based position of this track in its TrackList More...
 
wxString mName
 
ChannelType mChannel
 
double mOffset
 

Detailed Description

A Track that is used for Midi notes. (Somewhat old code).

Definition at line 65 of file NoteTrack.h.

Member Typedef Documentation

◆ Holder

using NoteTrack::Holder = std::shared_ptr<NoteTrack>

Definition at line 75 of file NoteTrack.h.

Member Enumeration Documentation

◆ anonymous enum

anonymous enum
private
Enumerator
MinPitch 
MaxPitch 

Definition at line 242 of file NoteTrack.h.

242{ MinPitch = 0, MaxPitch = 127 };

Constructor & Destructor Documentation

◆ NoteTrack()

NoteTrack::NoteTrack ( )

Definition at line 123 of file NoteTrack.cpp.

124 : NoteTrackBase()
125{
126 SetName(_("Note Track"));
127
128 mSeq = NULL;
130
133}
#define _(s)
Definition: Internat.h:75
AudioTrack NoteTrackBase
Definition: NoteTrack.h:58
int mTopNote
Definition: NoteTrack.h:232
std::unique_ptr< Alg_seq > mSeq
Definition: NoteTrack.h:223
int mBottomNote
Definition: NoteTrack.h:232
long mSerializationLength
Definition: NoteTrack.h:225
void SetName(const wxString &n)
Definition: Track.cpp:80

References _, MaxPitch, mBottomNote, MinPitch, mSeq, mSerializationLength, mTopNote, and Track::SetName().

Here is the call graph for this function:

◆ ~NoteTrack()

NoteTrack::~NoteTrack ( )
virtual

Definition at line 135 of file NoteTrack.cpp.

136{
137}

Member Function Documentation

◆ AddToDuration()

void NoteTrack::AddToDuration ( double  delta)
private

Definition at line 727 of file NoteTrack.cpp.

728{
729 auto &seq = GetSeq();
730#if 0
731 // PRL: Would this be better ?
732 seq.set_real_dur( seq.get_real_dur() + delta );
733#else
734 seq.convert_to_seconds();
735 seq.set_dur( seq.get_dur() + delta );
736#endif
737}
Alg_seq & GetSeq() const
Definition: NoteTrack.cpp:139

References GetSeq().

Referenced by Paste(), and StretchRegion().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ClassTypeInfo()

auto NoteTrack::ClassTypeInfo ( )
static

Definition at line 700 of file NoteTrack.cpp.

701{
702 return typeInfo();
703}
static const Track::TypeInfo & typeInfo()
Definition: NoteTrack.cpp:687

References typeInfo().

Here is the call graph for this function:

◆ Clear()

void NoteTrack::Clear ( double  t0,
double  t1 
)
override

Definition at line 521 of file NoteTrack.cpp.

522{
523 if (t1 < t0)
525
526 double len = t1-t0;
527
528 auto &seq = GetSeq();
529
530 auto offset = GetOffset();
531 auto start = t0 - offset;
532 if (start < 0.0) {
533 // AlgSeq::clear will shift the cleared interval, not changing len, if
534 // start is negative. That's not what we want to happen.
535 if (len > -start) {
536 seq.clear(0, len + start, false);
537 SetOffset(t0);
538 }
539 else
540 SetOffset(offset - len);
541 }
542 else {
543 //auto delta = -(
544 //( std::min( t1, GetEndTime() ) ) - ( std::max( t0, GetStartTime() ) )
545 //);
546 seq.clear(start, len, false);
547
548 // Not needed
549 // Alg_seq::clear seems to handle this
550 // AddToDuration( delta );
551 }
552}
#define THROW_INCONSISTENCY_EXCEPTION
Throw InconsistencyException, using C++ preprocessor to identify the source code location.
double GetOffset() const override
Definition: NoteTrack.cpp:202
virtual void SetOffset(double o)
Definition: Track.h:475

References GetOffset(), GetSeq(), Track::SetOffset(), and THROW_INCONSISTENCY_EXCEPTION.

Referenced by EditActions::Handler::OnCut().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ClearVisibleChan()

void NoteTrack::ClearVisibleChan ( int  c)
inline

Definition at line 189 of file NoteTrack.h.

189 {
190 mVisibleChannels.fetch_and(~CHANNEL_BIT(c), std::memory_order_relaxed); }
#define CHANNEL_BIT(c)
Definition: NoteTrack.h:177
std::atomic< unsigned > mVisibleChannels
A bit set; atomic because it may be read by worker threads in playback.
Definition: NoteTrack.h:246

References CHANNEL_BIT.

◆ Clone()

Track::Holder NoteTrack::Clone ( ) const
overrideprivatevirtual

Implements Track.

Definition at line 161 of file NoteTrack.cpp.

162{
163 auto duplicate = std::make_shared<NoteTrack>();
164 duplicate->Init(*this);
165 // The duplicate begins life in serialized state. Often the duplicate is
166 // pushed on the Undo stack. Then we want to un-serialize it (or a further
167 // copy) only on demand after an Undo.
168 if (mSeq) {
170 wxASSERT(!mSerializationBuffer);
171 // serialize from this to duplicate's mSerializationBuffer
172 void *buffer;
173 mSeq->serialize(&buffer,
174 &duplicate->mSerializationLength);
175 duplicate->mSerializationBuffer.reset( (char*)buffer );
177 }
178 else if (mSerializationBuffer) {
179 // Copy already serialized data.
180 wxASSERT(!mSeq);
181 duplicate->mSerializationLength = this->mSerializationLength;
182 duplicate->mSerializationBuffer.reset
183 ( safenew char[ this->mSerializationLength ] );
184 memcpy( duplicate->mSerializationBuffer.get(),
185 this->mSerializationBuffer.get(), this->mSerializationLength );
186 }
187 else {
188 // We are duplicating a default-constructed NoteTrack, and that's okay
189 }
190 // copy some other fields here
191 duplicate->SetBottomNote(mBottomNote);
192 duplicate->SetTopNote(mTopNote);
193 duplicate->SetVisibleChannels(GetVisibleChannels());
194 duplicate->SetOffset(GetOffset());
195#ifdef EXPERIMENTAL_MIDI_OUT
196 duplicate->SetVelocity(GetVelocity());
197#endif
198 return duplicate;
199}
#define safenew
Definition: MemoryX.h:10
#define SonifyEndSerialize()
Definition: NoteTrack.h:314
#define SonifyBeginSerialize()
Definition: NoteTrack.h:313
std::unique_ptr< char[]> mSerializationBuffer
Definition: NoteTrack.h:224
unsigned GetVisibleChannels() const
Definition: NoteTrack.h:178

References GetOffset(), GetVisibleChannels(), mBottomNote, mSeq, mSerializationBuffer, mSerializationLength, mTopNote, safenew, SonifyBeginSerialize, and SonifyEndSerialize.

Here is the call graph for this function:

◆ Copy()

Track::Holder NoteTrack::Copy ( double  t0,
double  t1,
bool  forClipboard = true 
) const
override

Definition at line 474 of file NoteTrack.cpp.

475{
476 if (t1 < t0)
478
479 double len = t1-t0;
480
481 auto newTrack = std::make_shared<NoteTrack>();
482
483 newTrack->Init(*this);
484
485 auto &seq = GetSeq();
486 seq.convert_to_seconds();
487 newTrack->mSeq.reset(seq.copy(t0 - GetOffset(), len, false));
488 newTrack->SetOffset(0);
489
490 // What should be done with the rest of newTrack's members?
491 // (mBottomNote, mSerializationBuffer,
492 // mSerializationLength, mVisibleChannels)
493
494 return newTrack;
495}

References GetOffset(), GetSeq(), and THROW_INCONSISTENCY_EXCEPTION.

Referenced by EditActions::Handler::OnCut().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Cut()

Track::Holder NoteTrack::Cut ( double  t0,
double  t1 
)
override

Definition at line 444 of file NoteTrack.cpp.

445{
446 if (t1 < t0)
448
449 double len = t1-t0;
450 //auto delta = -(
451 //( std::min( t1, GetEndTime() ) ) - ( std::max( t0, GetStartTime() ) )
452 //);
453
454 auto newTrack = std::make_shared<NoteTrack>();
455
456 newTrack->Init(*this);
457
458 auto &seq = GetSeq();
459 seq.convert_to_seconds();
460 newTrack->mSeq.reset(seq.cut(t0 - GetOffset(), len, false));
461 newTrack->SetOffset(0);
462
463 // Not needed
464 // Alg_seq::cut seems to handle this
465 //AddToDuration( delta );
466
467 // What should be done with the rest of newTrack's members?
468 //(mBottomNote,
469 // mSerializationBuffer, mSerializationLength, mVisibleChannels)
470
471 return newTrack;
472}

References GetOffset(), GetSeq(), and THROW_INCONSISTENCY_EXCEPTION.

Referenced by EditActions::Handler::OnCut().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ DrawLabelControls()

void NoteTrack::DrawLabelControls ( const NoteTrack pTrack,
wxDC &  dc,
const wxRect &  rect,
int  highlightedChannel = -1 
)
static

Definition at line 255 of file NoteTrack.cpp.

257{
258 dc.SetTextForeground(theTheme.Colour(clrLabelTrackText));
259 wxASSERT_MSG(rect.width % 4 == 0, "Midi channel control rect width must be divisible by 4");
260 wxASSERT_MSG(rect.height % 4 == 0, "Midi channel control rect height must be divisible by 4");
261
262 auto cellWidth = rect.width / 4;
263 auto cellHeight = rect.height / 4;
264
265 wxRect box;
266 for (int row = 0; row < 4; row++) {
267 for (int col = 0; col < 4; col++) {
268 // chanName is the "external" channel number (1-16)
269 // used by AColor and button labels
270 int chanName = row * 4 + col + 1;
271
272 box.x = rect.x + col * cellWidth;
273 box.y = rect.y + row * cellHeight;
274 box.width = cellWidth;
275 box.height = cellHeight;
276
277 bool visible = pTrack ? pTrack->IsVisibleChan(chanName - 1) : true;
278 if (visible) {
279 // highlightedChannel counts 0 based
280 if ( chanName == highlightedChannel + 1 )
281 AColor::LightMIDIChannel(&dc, chanName);
282 else
283 AColor::MIDIChannel(&dc, chanName);
284 dc.DrawRectangle(box);
285// two choices: channel is enabled (to see and play) when button is in
286// "up" position (original Audacity style) or in "down" position
287//
288#define CHANNEL_ON_IS_DOWN 1
289#if CHANNEL_ON_IS_DOWN
290 AColor::DarkMIDIChannel(&dc, chanName);
291#else
292 AColor::LightMIDIChannel(&dc, chanName);
293#endif
294 AColor::Line(dc, box.x, box.y, box.x + box.width - 1, box.y);
295 AColor::Line(dc, box.x, box.y, box.x, box.y + box.height - 1);
296
297#if CHANNEL_ON_IS_DOWN
298 AColor::LightMIDIChannel(&dc, chanName);
299#else
300 AColor::DarkMIDIChannel(&dc, chanName);
301#endif
302 AColor::Line(dc,
303 box.x + box.width - 1, box.y,
304 box.x + box.width - 1, box.y + box.height - 1);
305 AColor::Line(dc,
306 box.x, box.y + box.height - 1,
307 box.x + box.width - 1, box.y + box.height - 1);
308 } else {
309 if ( chanName == highlightedChannel + 1 )
310 AColor::LightMIDIChannel(&dc, chanName);
311 else
312 AColor::MIDIChannel(&dc, 0);
313 dc.DrawRectangle(box);
314#if CHANNEL_ON_IS_DOWN
316#else
318#endif
319 AColor::Line(dc, box.x, box.y, box.x + box.width - 1, box.y);
320 AColor::Line(dc, box.x, box.y, box.x, box.y + box.height - 1);
321
322#if CHANNEL_ON_IS_DOWN
324#else
326#endif
327 AColor::Line(dc,
328 box.x + box.width - 1, box.y,
329 box.x + box.width - 1, box.y + box.height - 1);
330 AColor::Line(dc,
331 box.x, box.y + box.height - 1,
332 box.x + box.width - 1, box.y + box.height - 1);
333
334 }
335
336 wxString text;
337 wxCoord w;
338 wxCoord h;
339
340 text.Printf(wxT("%d"), chanName);
341 dc.GetTextExtent(text, &w, &h);
342
343 dc.DrawText(text, box.x + (box.width - w) / 2, box.y + (box.height - h) / 2);
344 }
345 }
346 dc.SetTextForeground(theTheme.Colour(clrTrackPanelText));
347 AColor::MIDIChannel(&dc, 0); // always return with gray color selected
348}
THEME_API Theme theTheme
Definition: Theme.cpp:82
static void Line(wxDC &dc, wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
Definition: AColor.cpp:187
static void LightMIDIChannel(wxDC *dc, int channel)
Definition: AColor.cpp:658
static void MIDIChannel(wxDC *dc, int channel)
Definition: AColor.cpp:642
static void DarkMIDIChannel(wxDC *dc, int channel)
Definition: AColor.cpp:676
bool IsVisibleChan(int c) const
Definition: NoteTrack.h:184
wxColour & Colour(int iIndex)

References ThemeBase::Colour(), AColor::DarkMIDIChannel(), IsVisibleChan(), AColor::LightMIDIChannel(), AColor::Line(), AColor::MIDIChannel(), and theTheme.

Referenced by anonymous_namespace{NoteTrackControls.cpp}::MidiControlsDrawFunction().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ExportAllegro()

bool NoteTrack::ExportAllegro ( const wxString &  f) const

Definition at line 892 of file NoteTrack.cpp.

893{
894 double offset = GetOffset();
896 auto &seq = GetSeq();
897 if (in_seconds) {
898 seq.convert_to_seconds();
899 } else {
900 seq.convert_to_beats();
901 }
902 return seq.write(f.mb_str(), offset);
903}
Enum ReadEnum() const
Definition: Prefs.h:524
static EnumSetting< bool > AllegroStyleSetting

References ImportExportPrefs::AllegroStyleSetting, GetOffset(), GetSeq(), and EnumSetting< Enum >::ReadEnum().

Here is the call graph for this function:

◆ ExportMIDI()

bool NoteTrack::ExportMIDI ( const wxString &  f) const

Definition at line 884 of file NoteTrack.cpp.

885{
886 std::unique_ptr<Alg_seq> cleanup;
887 auto seq = MakeExportableSeq(cleanup);
888 bool rslt = seq->smf_write(f.mb_str());
889 return rslt;
890}
Alg_seq * MakeExportableSeq(std::unique_ptr< Alg_seq > &cleanup) const
Definition: NoteTrack.cpp:761

References MakeExportableSeq().

Here is the call graph for this function:

◆ FindChannel()

int NoteTrack::FindChannel ( const wxRect &  rect,
int  mx,
int  my 
)

Definition at line 350 of file NoteTrack.cpp.

351{
352 wxASSERT_MSG(rect.width % 4 == 0, "Midi channel control rect width must be divisible by 4");
353 wxASSERT_MSG(rect.height % 4 == 0, "Midi channel control rect height must be divisible by 4");
354
355 auto cellWidth = rect.width / 4;
356 auto cellHeight = rect.height / 4;
357
358 int col = (mx - rect.x) / cellWidth;
359 int row = (my - rect.y) / cellHeight;
360
361 return row * 4 + col;
362}

Referenced by LabelClick().

Here is the caller graph for this function:

◆ GetBottomNote()

int NoteTrack::GetBottomNote ( ) const
inline

Gets the current bottom note (a pitch)

Definition at line 124 of file NoteTrack.h.

124{ return mBottomNote; }

Referenced by NoteTrackDisplayData::NoteTrackDisplayData().

Here is the caller graph for this function:

◆ GetEndTime()

double NoteTrack::GetEndTime ( ) const
overridevirtual

Implements Track.

Definition at line 212 of file NoteTrack.cpp.

213{
214 return GetStartTime() + GetSeq().get_real_dur();
215}
double GetStartTime() const override
Definition: NoteTrack.cpp:207

References GetSeq(), and GetStartTime().

Referenced by GetIntervals(), and Paste().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetIntervals() [1/2]

auto NoteTrack::GetIntervals ( ) const
overridevirtual

Report times on the track where important intervals begin and end, for UI to snap to.

Some intervals may be empty, and no ordering of the intervals is assumed.

Reimplemented from Track.

Definition at line 713 of file NoteTrack.cpp.

714{
715 ConstIntervals results;
716 results.emplace_back( GetStartTime(), GetEndTime() );
717 return results;
718}
double GetEndTime() const override
Definition: NoteTrack.cpp:212
std::vector< ConstInterval > ConstIntervals
Definition: Track.h:330

References GetEndTime(), and GetStartTime().

Here is the call graph for this function:

◆ GetIntervals() [2/2]

auto NoteTrack::GetIntervals ( )
overridevirtual

This overload exposes the extra data of the intervals as non-const This overload exposes the extra data of the intervals as non-const

Reimplemented from Track.

Definition at line 720 of file NoteTrack.cpp.

721{
722 Intervals results;
723 results.emplace_back( GetStartTime(), GetEndTime() );
724 return results;
725}
std::vector< Interval > Intervals
Definition: Track.h:328

◆ GetOffset()

double NoteTrack::GetOffset ( ) const
overridevirtual

Implements Track.

Definition at line 202 of file NoteTrack.cpp.

203{
204 return mOffset;
205}
double mOffset
Definition: Track.h:440

References Track::mOffset.

Referenced by Clear(), Clone(), Copy(), Cut(), anonymous_namespace{NoteTrackView.cpp}::DrawNoteBackground(), anonymous_namespace{NoteTrackView.cpp}::DrawNoteTrack(), ExportAllegro(), GetStartTime(), InsertSilence(), MakeExportableSeq(), NearestBeatTime(), Paste(), Silence(), Trim(), WarpAndTransposeNotes(), and WriteXML().

Here is the caller graph for this function:

◆ GetSeq()

Alg_seq & NoteTrack::GetSeq ( ) const

Definition at line 139 of file NoteTrack.cpp.

140{
141 if (!mSeq) {
143 mSeq = std::make_unique<Alg_seq>();
144 else {
145 std::unique_ptr<Alg_track> alg_track
146 { Alg_seq::unserialize
148 wxASSERT(alg_track->get_type() == 's');
149 mSeq.reset( static_cast<Alg_seq*>(alg_track.release()) );
150
151 // Preserve the invariant that at most one of the representations is
152 // valid
153 mSerializationBuffer.reset();
155 }
156 }
157 wxASSERT(mSeq);
158 return *mSeq;
159}

References mSeq, mSerializationBuffer, and mSerializationLength.

Referenced by AddToDuration(), Clear(), Copy(), Cut(), anonymous_namespace{NoteTrackView.cpp}::DrawNoteBackground(), anonymous_namespace{NoteTrackView.cpp}::DrawNoteTrack(), ExportAllegro(), GetEndTime(), InsertSilence(), MakeExportableSeq(), NearestBeatTime(), Paste(), Shift(), Silence(), StretchRegion(), Trim(), WarpAndTransposeNotes(), WriteXML(), and ZoomAllNotes().

Here is the caller graph for this function:

◆ GetStartTime()

double NoteTrack::GetStartTime ( ) const
overridevirtual

Implements Track.

Definition at line 207 of file NoteTrack.cpp.

208{
209 return GetOffset();
210}

References GetOffset().

Referenced by GetEndTime(), and GetIntervals().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetTopNote()

int NoteTrack::GetTopNote ( ) const
inline

Gets the current top note (a pitch)

Definition at line 126 of file NoteTrack.h.

126{ return mTopNote; }

Referenced by NoteTrackDisplayData::NoteTrackDisplayData().

Here is the caller graph for this function:

◆ GetTypeInfo()

auto NoteTrack::GetTypeInfo ( ) const
overridevirtual

Implements Track.

Definition at line 695 of file NoteTrack.cpp.

696{
697 return typeInfo();
698}

References typeInfo().

Here is the call graph for this function:

◆ GetVisibleChannels()

unsigned NoteTrack::GetVisibleChannels ( ) const
inline

Definition at line 178 of file NoteTrack.h.

178 {
179 return mVisibleChannels.load(std::memory_order_relaxed);
180 }

Referenced by Clone(), and WriteXML().

Here is the caller graph for this function:

◆ HandleXMLChild()

XMLTagHandler * NoteTrack::HandleXMLChild ( const std::string_view &  tag)
overridevirtual

Implements XMLTagHandler.

Definition at line 954 of file NoteTrack.cpp.

955{
956 return NULL;
957}

◆ HandleXMLTag()

bool NoteTrack::HandleXMLTag ( const std::string_view &  tag,
const AttributesList attrs 
)
overridevirtual

Implements XMLTagHandler.

Definition at line 913 of file NoteTrack.cpp.

914{
915 if (tag == "notetrack") {
916 for (auto pair : attrs)
917 {
918 auto attr = pair.first;
919 auto value = pair.second;
920
921 long nValue;
922 double dblValue;
923 if (this->Track::HandleCommonXMLAttribute(attr, value))
924 ;
925 else if (this->NoteTrackBase::HandleXMLAttribute(attr, value))
926 {}
927 else if (attr == "offset" && value.TryGet(dblValue))
928 SetOffset(dblValue);
929 else if (attr == "visiblechannels") {
930 if (!value.TryGet(nValue) ||
931 !IsValidVisibleChannels(nValue))
932 return false;
933 SetVisibleChannels(nValue);
934 }
935#ifdef EXPERIMENTAL_MIDI_OUT
936 else if (attr == "velocity" && value.TryGet(dblValue))
937 DoSetVelocity(static_cast<float>(dblValue));
938#endif
939 else if (attr == "bottomnote" && value.TryGet(nValue))
940 SetBottomNote(nValue);
941 else if (attr == "topnote" && value.TryGet(nValue))
942 SetTopNote(nValue);
943 else if (attr == "data") {
944 std::string s(value.ToWString());
945 std::istringstream data(s);
946 mSeq = std::make_unique<Alg_seq>(data, false);
947 }
948 } // while
949 return true;
950 }
951 return false;
952}
bool HandleXMLAttribute(const std::string_view &, const XMLAttributeValueView &)
Definition: Track.h:901
void SetVisibleChannels(unsigned value)
Definition: NoteTrack.h:181
void SetTopNote(int note)
Sets the top note (a pitch), making sure that it is never less than the bottom note.
Definition: NoteTrack.cpp:1001
void SetBottomNote(int note)
Sets the bottom note (a pitch), making sure that it is never greater than the top note.
Definition: NoteTrack.cpp:989
bool HandleCommonXMLAttribute(const std::string_view &attr, const XMLAttributeValueView &valueView)
Definition: Track.cpp:1265
bool IsValidVisibleChannels(const int nValue)
Definition: NoteTrack.cpp:907

References Track::HandleCommonXMLAttribute(), AudioTrack::HandleXMLAttribute(), anonymous_namespace{NoteTrack.cpp}::IsValidVisibleChannels(), mSeq, SetBottomNote(), Track::SetOffset(), SetTopNote(), and SetVisibleChannels().

Here is the call graph for this function:

◆ InsertSilence()

void NoteTrack::InsertSilence ( double  t,
double  len 
)
override

Definition at line 619 of file NoteTrack.cpp.

620{
621 if (len < 0)
623
624 auto &seq = GetSeq();
625 seq.convert_to_seconds();
626 seq.insert_silence(t - GetOffset(), len);
627
628 // is this needed?
629 // AddToDuration( len );
630}

References GetOffset(), GetSeq(), and THROW_INCONSISTENCY_EXCEPTION.

Referenced by Paste().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ IsVisibleChan()

bool NoteTrack::IsVisibleChan ( int  c) const
inline

Definition at line 184 of file NoteTrack.h.

184 {
185 return (GetVisibleChannels() & CHANNEL_BIT(c)) != 0;
186 }

References CHANNEL_BIT.

Referenced by DrawLabelControls(), anonymous_namespace{NoteTrackView.cpp}::DrawNoteTrack(), and anonymous_namespace{MIDIPlay.h}::Iterator::Unmuted().

Here is the caller graph for this function:

◆ LabelClick()

bool NoteTrack::LabelClick ( const wxRect &  rect,
int  x,
int  y,
bool  right 
)

Definition at line 369 of file NoteTrack.cpp.

370{
371 auto channel = FindChannel(rect, mx, my);
372 if (right)
373 SoloVisibleChan(channel);
374 else
375 ToggleVisibleChan(channel);
376
377 return true;
378}
int FindChannel(const wxRect &rect, int mx, int my)
Definition: NoteTrack.cpp:350
void ToggleVisibleChan(int c)
Definition: NoteTrack.h:191
void SoloVisibleChan(int c)
Definition: NoteTrack.h:195

References FindChannel(), SoloVisibleChan(), and ToggleVisibleChan().

Here is the call graph for this function:

◆ MakeExportableSeq()

Alg_seq * NoteTrack::MakeExportableSeq ( std::unique_ptr< Alg_seq > &  cleanup) const

Definition at line 761 of file NoteTrack.cpp.

762{
763 cleanup.reset();
764 double offset = GetOffset();
765 if (offset == 0)
766 return &GetSeq();
767 // make a copy, deleting events that are shifted before time 0
768 double start = -offset;
769 if (start < 0) start = 0;
770 // notes that begin before "start" are not included even if they
771 // extend past "start" (because "all" parameter is set to false)
772 cleanup.reset( GetSeq().copy(start, GetSeq().get_dur() - start, false) );
773 auto seq = cleanup.get();
774 if (offset > 0) {
775 {
776 // swap cleanup and mSeq so that Shift operates on the NEW copy
777 swap( this->mSeq, cleanup );
778 auto cleanup2 = finally( [&] { swap( this->mSeq, cleanup ); } );
779
780 const_cast< NoteTrack *>( this )->Shift(offset);
781 }
782#ifdef OLD_CODE
783 // now shift events by offset. This must be done with an integer
784 // number of measures, so first, find the beats-per-measure
785 double beats_per_measure = 4.0;
786 Alg_time_sig_ptr tsp = NULL;
787 if (seq->time_sig.length() > 0 && seq->time_sig[0].beat < ALG_EPS) {
788 // there is an initial time signature
789 tsp = &(seq->time_sig[0]);
790 beats_per_measure = (tsp->num * 4) / tsp->den;
791 }
792 // also need the initial tempo
793 double bps = ALG_DEFAULT_BPM / 60;
794 Alg_time_map_ptr map = seq->get_time_map();
795 Alg_beat_ptr bp = &(map->beats[0]);
796 if (bp->time < ALG_EPS) { // tempo change at time 0
797 if (map->beats.len > 1) { // compute slope to get tempo
798 bps = (map->beats[1].beat - map->beats[0].beat) /
799 (map->beats[1].time - map->beats[0].time);
800 } else if (seq->get_time_map()->last_tempo_flag) {
801 bps = seq->get_time_map()->last_tempo;
802 }
803 }
804 // find closest number of measures to fit in the gap
805 // number of measures is offset / measure_time
806 double measure_time = beats_per_measure / bps; // seconds per measure
807 int n = ROUND(offset / measure_time);
808 if (n == 0) n = 1;
809 // we will insert n measures. Compute the desired duration of each.
810 measure_time = offset / n;
811 bps = beats_per_measure / measure_time;
812 // insert integer multiple of measures at beginning
813 seq->convert_to_beats();
814 seq->insert_silence(0, beats_per_measure * n);
815 // make sure time signature at 0 is correct
816 if (tsp) {
817 seq->set_time_sig(0, tsp->num, tsp->den);
818 }
819 // adjust tempo to match offset
820 seq->set_tempo(bps * 60.0, 0, beats_per_measure * n);
821#endif
822 } else {
823 auto &mySeq = GetSeq();
824 // if offset is negative, it might not be a multiple of beats, but
825 // we want to preserve the relative positions of measures. I.e. we
826 // should shift barlines and time signatures as well as notes.
827 // Insert a time signature at the first bar-line if necessary.
828
829 // Translate start from seconds to beats and call it beat:
830 double beat = mySeq.get_time_map()->time_to_beat(start);
831 // Find the time signature in mySeq in effect at start (beat):
832 int i = mySeq.time_sig.find_beat(beat);
833 // i is where you would insert a NEW time sig at beat,
834 // Case 1: beat coincides with a time sig at i. Time signature
835 // at beat means that there is a barline at beat, so when beat
836 // is shifted to 0, the relative barline positions are preserved
837 if (mySeq.time_sig.length() > 0 &&
838 within(beat, mySeq.time_sig[i].beat, ALG_EPS)) {
839 // beat coincides with time signature change, so offset must
840 // be a multiple of beats
841 /* do nothing */ ;
842 // Case 2: there is no time signature before beat.
843 } else if (i == 0 && (mySeq.time_sig.length() == 0 ||
844 mySeq.time_sig[i].beat > beat)) {
845 // If beat does not fall on an implied barline, we need to
846 // insert a time signature.
847 double measures = beat / 4.0;
848 double imeasures = ROUND(measures);
849 if (!within(measures, imeasures, ALG_EPS)) {
850 double bar_offset = ((int)(measures) + 1) * 4.0 - beat;
851 seq->set_time_sig(bar_offset, 4, 4);
852 }
853 // This case should never be true because if i == 0, either there
854 // are no time signatures before beat (Case 2),
855 // or there is one time signature at beat (Case 1)
856 } else if (i == 0) {
857 /* do nothing (might be good to assert(false)) */ ;
858 // Case 3: i-1 must be the effective time sig position
859 } else {
860 i -= 1; // index the time signature in effect at beat
861 Alg_time_sig_ptr tsp = &(mySeq.time_sig[i]);
862 double beats_per_measure = (tsp->num * 4) / tsp->den;
863 double measures = (beat - tsp->beat) / beats_per_measure;
864 int imeasures = ROUND(measures);
865 if (!within(measures, imeasures, ALG_EPS)) {
866 // beat is not on a measure, so we need to insert a time sig
867 // to force a bar line at the first measure location after
868 // beat
869 double bar = tsp->beat + beats_per_measure * ((int)(measures) + 1);
870 double bar_offset = bar - beat;
871 // insert NEW time signature at bar_offset in NEW sequence
872 // It will have the same time signature, but the position will
873 // force a barline to match the barlines in mSeq
874 seq->set_time_sig(bar_offset, tsp->num, tsp->den);
875 }
876 // else beat coincides with a barline, so no need for an extra
877 // time signature to force barline alignment
878 }
879 }
880 return seq;
881}
#define ROUND(x)
Definition: NoteTrack.cpp:33
bool within(A a, B b, DIST d)
Definition: TrackPanel.cpp:166
A Track that is used for Midi notes. (Somewhat old code).
Definition: NoteTrack.h:67
bool Shift(double t)
Definition: NoteTrack.cpp:649
void swap(std::unique_ptr< Alg_seq > &a, std::unique_ptr< Alg_seq > &b)
Definition: NoteTrack.cpp:753

References GetOffset(), GetSeq(), mSeq, ROUND, Shift(), anonymous_namespace{NoteTrack.cpp}::swap(), and within().

Referenced by ExportMIDI().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ NearestBeatTime()

QuantizedTimeAndBeat NoteTrack::NearestBeatTime ( double  time) const

Definition at line 676 of file NoteTrack.cpp.

677{
678 // Alg_seq knows nothing about offset, so remove offset time
679 double seq_time = time - GetOffset();
680 double beat;
681 auto &seq = GetSeq();
682 seq_time = seq.nearest_beat_time(seq_time, &beat);
683 // add the offset back in to get "actual" audacity track time
684 return { seq_time + GetOffset(), beat };
685}

References GetOffset(), and GetSeq().

Here is the call graph for this function:

◆ New()

NoteTrack * NoteTrack::New ( AudacityProject project)
static

Definition at line 115 of file NoteTrack.cpp.

116{
117 auto &tracks = TrackList::Get( project );
118 auto result = tracks.Add( std::make_shared<NoteTrack>());
119 result->AttachedTrackObjects::BuildAll();
120 return result;
121}
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:468

References TrackList::Get().

Here is the call graph for this function:

◆ Paste()

void NoteTrack::Paste ( double  t,
const Track src 
)
override

Definition at line 554 of file NoteTrack.cpp.

555{
556 // Paste inserts src at time t. If src has a positive offset,
557 // the offset is treated as silence which is also inserted. If
558 // the offset is negative, the offset is ignored and the ENTIRE
559 // src is inserted (otherwise, we would either lose data from
560 // src by not inserting things at negative times, or inserting
561 // things at negative times could overlap things already in
562 // the destination track).
563
564 //Check that src is a non-NULL NoteTrack
565 bool bOk = src && src->TypeSwitch< bool >( [&](const NoteTrack *other) {
566
567 auto myOffset = this->GetOffset();
568 if (t < myOffset) {
569 // workaround strange behavior described at
570 // http://bugzilla.audacityteam.org/show_bug.cgi?id=1735#c3
571 SetOffset(t);
572 InsertSilence(t, myOffset - t);
573 }
574
575 double delta = 0.0;
576 auto &seq = GetSeq();
577 auto offset = other->GetOffset();
578 if ( offset > 0 ) {
579 seq.convert_to_seconds();
580 seq.insert_silence( t - GetOffset(), offset );
581 t += offset;
582 // Is this needed or does Alg_seq::insert_silence take care of it?
583 //delta += offset;
584 }
585
586 // This seems to be needed:
587 delta += std::max( 0.0, t - GetEndTime() );
588
589 // This, not:
590 //delta += other->GetSeq().get_real_dur();
591
592 seq.paste(t - GetOffset(), &other->GetSeq());
593
594 AddToDuration( delta );
595
596 return true;
597 });
598
599 if ( !bOk )
600 // THROW_INCONSISTENCY_EXCEPTION; // ?
601 (void)0;// intentionally do nothing
602}
void AddToDuration(double delta)
Definition: NoteTrack.cpp:727
void InsertSilence(double t, double len) override
Definition: NoteTrack.cpp:619
R TypeSwitch(const Functions &...functions)
Use this function rather than testing track type explicitly and making down-casts.
Definition: Track.h:824

References AddToDuration(), GetEndTime(), GetOffset(), GetSeq(), InsertSilence(), Track::SetOffset(), and Track::TypeSwitch().

Here is the call graph for this function:

◆ PasteInto()

Track::Holder NoteTrack::PasteInto ( AudacityProject ) const
overridevirtual

Find or create the destination track for a paste, maybe in a different project.

Returns
A smart pointer to the track; its use_count() can tell whether it is new

Implements Track.

Definition at line 705 of file NoteTrack.cpp.

706{
707 auto pNewTrack = std::make_shared<NoteTrack>();
708 pNewTrack->Init(*this);
709 pNewTrack->Paste(0.0, this);
710 return pNewTrack;
711}

◆ PrintSequence()

void NoteTrack::PrintSequence ( )

Definition at line 385 of file NoteTrack.cpp.

386{
387 FILE *debugOutput;
388
389 debugOutput = fopen("debugOutput.txt", "wt");
390 wxFprintf(debugOutput, "Importing MIDI...\n");
391
392 // This is called for debugging purposes. Do not compute mSeq on demand
393 // with GetSeq()
394 if (mSeq) {
395 int i = 0;
396
397 while(i < mSeq->length()) {
398 wxFprintf(debugOutput, "--\n");
399 wxFprintf(debugOutput, "type: %c\n",
400 ((Alg_event_ptr)mSeq->track_list.tracks[i])->get_type());
401 wxFprintf(debugOutput, "time: %f\n",
402 ((Alg_event_ptr)mSeq->track_list.tracks[i])->time);
403 wxFprintf(debugOutput, "channel: %li\n",
404 ((Alg_event_ptr)mSeq->track_list.tracks[i])->chan);
405
406 if(((Alg_event_ptr)mSeq->track_list.tracks[i])->get_type() == wxT('n'))
407 {
408 wxFprintf(debugOutput, "pitch: %f\n",
409 ((Alg_note_ptr)mSeq->track_list.tracks[i])->pitch);
410 wxFprintf(debugOutput, "duration: %f\n",
411 ((Alg_note_ptr)mSeq->track_list.tracks[i])->dur);
412 wxFprintf(debugOutput, "velocity: %f\n",
413 ((Alg_note_ptr)mSeq->track_list.tracks[i])->loud);
414 }
415 else if(((Alg_event_ptr)mSeq->track_list.tracks[i])->get_type() == wxT('n'))
416 {
417 wxFprintf(debugOutput, "key: %li\n", ((Alg_update_ptr)mSeq->track_list.tracks[i])->get_identifier());
418 wxFprintf(debugOutput, "attribute type: %c\n", ((Alg_update_ptr)mSeq->track_list.tracks[i])->parameter.attr_type());
419 wxFprintf(debugOutput, "attribute: %s\n", ((Alg_update_ptr)mSeq->track_list.tracks[i])->parameter.attr_name());
420
421 if(((Alg_update_ptr)mSeq->track_list.tracks[i])->parameter.attr_type() == wxT('r'))
422 {
423 wxFprintf(debugOutput, "value: %f\n", ((Alg_update_ptr)mSeq->track_list.tracks[i])->parameter.r);
424 }
425 else if(((Alg_update_ptr)mSeq->track_list.tracks[i])->parameter.attr_type() == wxT('i')) {
426 wxFprintf(debugOutput, "value: %li\n", ((Alg_update_ptr)mSeq->track_list.tracks[i])->parameter.i);
427 }
428 else if(((Alg_update_ptr)mSeq->track_list.tracks[i])->parameter.attr_type() == wxT('s')) {
429 wxFprintf(debugOutput, "value: %s\n", ((Alg_update_ptr)mSeq->track_list.tracks[i])->parameter.s);
430 }
431 else {}
432 }
433
434 i++;
435 }
436 }
437 else {
438 wxFprintf(debugOutput, "No sequence defined!\n");
439 }
440
441 fclose(debugOutput);
442}

References mSeq.

◆ SetBottomNote()

void NoteTrack::SetBottomNote ( int  note)

Sets the bottom note (a pitch), making sure that it is never greater than the top note.

Definition at line 989 of file NoteTrack.cpp.

990{
991 if (note < MinPitch)
992 note = MinPitch;
993 else if (note > 96)
994 note = 96;
995
996 wxCHECK(note <= mTopNote, );
997
998 mBottomNote = note;
999}

References mBottomNote, MinPitch, and mTopNote.

Referenced by HandleXMLTag().

Here is the caller graph for this function:

◆ SetNoteRange()

void NoteTrack::SetNoteRange ( int  note1,
int  note2 
)

Sets the top and bottom note (both pitches) automatically, swapping them if needed.

Definition at line 1011 of file NoteTrack.cpp.

1012{
1013 // Bounds check
1014 if (note1 > MaxPitch)
1015 note1 = MaxPitch;
1016 else if (note1 < MinPitch)
1017 note1 = MinPitch;
1018 if (note2 > MaxPitch)
1019 note2 = MaxPitch;
1020 else if (note2 < MinPitch)
1021 note2 = MinPitch;
1022 // Swap to ensure ordering
1023 if (note2 < note1) { auto tmp = note1; note1 = note2; note2 = tmp; }
1024
1025 mBottomNote = note1;
1026 mTopNote = note2;
1027}

References MaxPitch, mBottomNote, MinPitch, and mTopNote.

Referenced by Zoom(), ZoomAllNotes(), and ZoomTo().

Here is the caller graph for this function:

◆ SetSequence()

void NoteTrack::SetSequence ( std::unique_ptr< Alg_seq > &&  seq)

Definition at line 380 of file NoteTrack.cpp.

381{
382 mSeq = std::move(seq);
383}

References mSeq.

Referenced by ImportMIDI().

Here is the caller graph for this function:

◆ SetTopNote()

void NoteTrack::SetTopNote ( int  note)

Sets the top note (a pitch), making sure that it is never less than the bottom note.

Definition at line 1001 of file NoteTrack.cpp.

1002{
1003 if (note > MaxPitch)
1004 note = MaxPitch;
1005
1006 wxCHECK(note >= mBottomNote, );
1007
1008 mTopNote = note;
1009}

References MaxPitch, mBottomNote, and mTopNote.

Referenced by HandleXMLTag().

Here is the caller graph for this function:

◆ SetVisibleChan()

void NoteTrack::SetVisibleChan ( int  c)
inline

Definition at line 187 of file NoteTrack.h.

187 {
188 mVisibleChannels.fetch_or(CHANNEL_BIT(c), std::memory_order_relaxed); }

References CHANNEL_BIT.

◆ SetVisibleChannels()

void NoteTrack::SetVisibleChannels ( unsigned  value)
inline

Definition at line 181 of file NoteTrack.h.

181 {
182 mVisibleChannels.store(value, std::memory_order_relaxed);
183 }

Referenced by HandleXMLTag().

Here is the caller graph for this function:

◆ Shift()

bool NoteTrack::Shift ( double  t)

Definition at line 649 of file NoteTrack.cpp.

650{
651 if (t > 0) {
652 auto &seq = GetSeq();
653 // insert an even number of measures
654 seq.convert_to_beats();
655 // get initial tempo
656 double tempo = seq.get_tempo(0.0);
657 double beats_per_measure = seq.get_bar_len(0.0);
658 int m = ROUND(t * tempo / beats_per_measure);
659 // need at least 1 measure, so if we rounded down to zero, fix it
660 if (m == 0) m = 1;
661 // compute NEW tempo so that m measures at NEW tempo take t seconds
662 tempo = beats_per_measure * m / t; // in beats per second
663 seq.insert_silence(0.0, beats_per_measure * m);
664 seq.set_tempo(tempo * 60.0 /* bpm */, 0.0, beats_per_measure * m);
665 seq.write("afterShift.gro");
666 } else if (t < 0) {
667 auto &seq = GetSeq();
668 seq.convert_to_seconds();
669 seq.clear(0, t, true);
670 } else { // offset is zero, no modifications
671 return false;
672 }
673 return true;
674}

References GetSeq(), and ROUND.

Referenced by MakeExportableSeq().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ShiftNoteRange()

void NoteTrack::ShiftNoteRange ( int  offset)

Shifts all notes vertically by the given pitch.

Definition at line 1029 of file NoteTrack.cpp.

1030{
1031 // Ensure everything stays in bounds
1032 if (mBottomNote + offset < MinPitch || mTopNote + offset > MaxPitch)
1033 return;
1034
1035 mBottomNote += offset;
1036 mTopNote += offset;
1037}

References MaxPitch, mBottomNote, and mTopNote.

Referenced by NoteTrackMenuTable::OnChangeOctave().

Here is the caller graph for this function:

◆ Silence()

void NoteTrack::Silence ( double  t0,
double  t1 
)
override

Definition at line 604 of file NoteTrack.cpp.

605{
606 if (t1 < t0)
608
609 auto len = t1 - t0;
610
611 auto &seq = GetSeq();
612 seq.convert_to_seconds();
613 // XXX: do we want to set the all param?
614 // If it's set, then it seems like notes are silenced if they start or end in the range,
615 // otherwise only if they start in the range. --Poke
616 seq.silence(t0 - GetOffset(), len, false);
617}

References GetOffset(), GetSeq(), and THROW_INCONSISTENCY_EXCEPTION.

Here is the call graph for this function:

◆ SoloVisibleChan()

void NoteTrack::SoloVisibleChan ( int  c)
inline

Definition at line 195 of file NoteTrack.h.

195 {
196 auto visibleChannels = 0u;
198 visibleChannels = ALL_CHANNELS;
199 else
200 visibleChannels = CHANNEL_BIT(c);
201 mVisibleChannels.store(visibleChannels, std::memory_order_relaxed);
202 }
#define ALL_CHANNELS
Definition: NoteTrack.h:176

References ALL_CHANNELS, and CHANNEL_BIT.

Referenced by LabelClick().

Here is the caller graph for this function:

◆ StretchRegion()

bool NoteTrack::StretchRegion ( QuantizedTimeAndBeat  t0,
QuantizedTimeAndBeat  t1,
double  newDur 
)

Definition at line 739 of file NoteTrack.cpp.

741{
742 auto &seq = GetSeq();
743 bool result = seq.stretch_region( t0.second, t1.second, newDur );
744 if (result) {
745 const auto oldDur = t1.first - t0.first;
746 AddToDuration( newDur - oldDur );
747 }
748 return result;
749}

References AddToDuration(), and GetSeq().

Referenced by StretchHandle::Stretch().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ToggleVisibleChan()

void NoteTrack::ToggleVisibleChan ( int  c)
inline

Definition at line 191 of file NoteTrack.h.

191 {
192 mVisibleChannels.fetch_xor(CHANNEL_BIT(c), std::memory_order_relaxed); }

References CHANNEL_BIT.

Referenced by LabelClick().

Here is the caller graph for this function:

◆ Trim()

bool NoteTrack::Trim ( double  t0,
double  t1 
)

Definition at line 497 of file NoteTrack.cpp.

498{
499 if (t1 < t0)
500 return false;
501 auto &seq = GetSeq();
502 //auto delta = -(
503 //( GetEndTime() - std::min( GetEndTime(), t1 ) ) +
504 //( std::max(t0, GetStartTime()) - GetStartTime() )
505 //);
506 seq.convert_to_seconds();
507 // DELETE way beyond duration just in case something is out there:
508 seq.clear(t1 - GetOffset(), seq.get_dur() + 10000.0, false);
509 // Now that stuff beyond selection is cleared, clear before selection:
510 seq.clear(0.0, t0 - GetOffset(), false);
511 // want starting time to be t0
512 SetOffset(t0);
513
514 // Not needed
515 // Alg_seq::clear seems to handle this
516 //AddToDuration( delta );
517
518 return true;
519}

References GetOffset(), GetSeq(), and Track::SetOffset().

Here is the call graph for this function:

◆ WarpAndTransposeNotes()

void NoteTrack::WarpAndTransposeNotes ( double  t0,
double  t1,
const TimeWarper warper,
double  semitones 
)

Definition at line 217 of file NoteTrack.cpp.

220{
221 double offset = this->GetOffset(); // track is shifted this amount
222 auto &seq = GetSeq();
223 seq.convert_to_seconds(); // make sure time units are right
224 t1 -= offset; // adjust time range to compensate for track offset
225 t0 -= offset;
226 if (t1 > seq.get_dur()) { // make sure t0, t1 are within sequence
227 t1 = seq.get_dur();
228 if (t0 >= t1) return;
229 }
230 Alg_iterator iter(mSeq.get(), false);
231 iter.begin();
232 Alg_event_ptr event;
233 while (0 != (event = iter.next()) && event->time < t1) {
234 if (event->is_note() && event->time >= t0) {
235 event->set_pitch(event->get_pitch() + semitones);
236 }
237 }
238 iter.end();
239 // now, use warper to warp the tempo map
240 seq.convert_to_beats(); // beats remain the same
241 Alg_time_map_ptr map = seq.get_time_map();
242 map->insert_beat(t0, map->time_to_beat(t0));
243 map->insert_beat(t1, map->time_to_beat(t1));
244 int i, len = map->length();
245 for (i = 0; i < len; i++) {
246 Alg_beat &beat = map->beats[i];
247 beat.time = warper.Warp(beat.time + offset) - offset;
248 }
249 // about to redisplay, so might as well convert back to time now
250 seq.convert_to_seconds();
251}
virtual double Warp(double originalTime) const =0

References GetOffset(), GetSeq(), mSeq, and TimeWarper::Warp().

Here is the call graph for this function:

◆ WriteXML()

void NoteTrack::WriteXML ( XMLWriter xmlFile) const
overridevirtual

Implements Track.

Definition at line 959 of file NoteTrack.cpp.

961{
962 std::ostringstream data;
963 Track::Holder holder;
964 const NoteTrack *saveme = this;
965 if (!mSeq) {
966 // replace saveme with an (unserialized) duplicate, which is
967 // destroyed at end of function.
968 holder = Clone();
969 saveme = static_cast<NoteTrack*>(holder.get());
970 }
971 saveme->GetSeq().write(data, true);
972 xmlFile.StartTag(wxT("notetrack"));
973 saveme->Track::WriteCommonXMLAttributes( xmlFile );
975 xmlFile.WriteAttr(wxT("offset"), saveme->GetOffset());
976 xmlFile.WriteAttr(wxT("visiblechannels"),
977 static_cast<int>(saveme->GetVisibleChannels()));
978
979#ifdef EXPERIMENTAL_MIDI_OUT
980 xmlFile.WriteAttr(wxT("velocity"),
981 static_cast<double>(saveme->GetVelocity()));
982#endif
983 xmlFile.WriteAttr(wxT("bottomnote"), saveme->mBottomNote);
984 xmlFile.WriteAttr(wxT("topnote"), saveme->mTopNote);
985 xmlFile.WriteAttr(wxT("data"), wxString(data.str().c_str(), wxConvUTF8));
986 xmlFile.EndTag(wxT("notetrack"));
987}
void WriteXMLAttributes(XMLWriter &WXUNUSED(xmlFile)) const
Definition: Track.h:898
Track::Holder Clone() const override
Definition: NoteTrack.cpp:161
std::shared_ptr< Track > Holder
Definition: Track.h:361
virtual void StartTag(const wxString &name)
Definition: XMLWriter.cpp:80
void WriteAttr(const wxString &name, const Identifier &value)
Definition: XMLWriter.h:37
virtual void EndTag(const wxString &name)
Definition: XMLWriter.cpp:103

References GetOffset(), GetSeq(), GetVisibleChannels(), mBottomNote, mTopNote, and AudioTrack::WriteXMLAttributes().

Here is the call graph for this function:

◆ Zoom()

void NoteTrack::Zoom ( const wxRect &  rect,
int  y,
float  multiplier,
bool  center 
)

Zoom the note track around y. If center is true, the result will be centered at y.

Definition at line 1053 of file NoteTrack.cpp.

1054{
1055 NoteTrackDisplayData data = NoteTrackDisplayData(this, rect);
1056 int clickedPitch = data.YToIPitch(y);
1057 int extent = mTopNote - mBottomNote + 1;
1058 int newExtent = (int) (extent / multiplier);
1059 float position;
1060 if (center) {
1061 // center the pitch that the user clicked on
1062 position = .5;
1063 } else {
1064 // align to keep the pitch that the user clicked on in the same place
1065 position = extent / (clickedPitch - mBottomNote);
1066 }
1067 int newBottomNote = clickedPitch - (newExtent * position);
1068 int newTopNote = clickedPitch + (newExtent * (1 - position));
1069 SetNoteRange(newBottomNote, newTopNote);
1070}
Data used to display a note track.
Definition: NoteTrack.h:252
int YToIPitch(int y) const
Definition: NoteTrack.cpp:1160
void SetNoteRange(int note1, int note2)
Sets the top and bottom note (both pitches) automatically, swapping them if needed.
Definition: NoteTrack.cpp:1011

References mBottomNote, mTopNote, SetNoteRange(), and NoteTrackDisplayData::YToIPitch().

Referenced by ZoomTo().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ZoomAllNotes()

void NoteTrack::ZoomAllNotes ( )

Zooms so that all notes are visible.

Definition at line 1088 of file NoteTrack.cpp.

1089{
1090 Alg_iterator iterator( &GetSeq(), false );
1091 iterator.begin();
1092 Alg_event_ptr evt;
1093
1094 // Go through all of the notes, finding the minimum and maximum value pitches.
1095 bool hasNotes = false;
1096 int minPitch = MaxPitch;
1097 int maxPitch = MinPitch;
1098
1099 while (NULL != (evt = iterator.next())) {
1100 if (evt->is_note()) {
1101 int pitch = (int) evt->get_pitch();
1102 hasNotes = true;
1103 if (pitch < minPitch)
1104 minPitch = pitch;
1105 if (pitch > maxPitch)
1106 maxPitch = pitch;
1107 }
1108 }
1109
1110 if (!hasNotes) {
1111 // Semi-arbitrary default values:
1112 minPitch = 48;
1113 maxPitch = 72;
1114 }
1115
1116 SetNoteRange(minPitch, maxPitch);
1117}

References GetSeq(), MaxPitch, MinPitch, and SetNoteRange().

Referenced by ImportMIDI().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ZoomIn()

void NoteTrack::ZoomIn ( const wxRect &  rect,
int  y 
)
inline

Zooms in a constant factor (subject to zoom limits)

Definition at line 144 of file NoteTrack.h.

144{ Zoom(rect, y, ZoomStep, true); }
void Zoom(const wxRect &rect, int y, float multiplier, bool center)
Definition: NoteTrack.cpp:1053
static const float ZoomStep
Definition: NoteTrack.h:243

Referenced by NoteTrackVRulerControls::HandleWheelRotation().

Here is the caller graph for this function:

◆ ZoomMaxExtent()

void NoteTrack::ZoomMaxExtent ( )
inline

Zooms so that the entire track is visible.

Definition at line 137 of file NoteTrack.h.

◆ ZoomOut()

void NoteTrack::ZoomOut ( const wxRect &  rect,
int  y 
)
inline

Zooms out a constant factor (subject to zoom limits)

Definition at line 142 of file NoteTrack.h.

142{ Zoom(rect, y, 1.0f / ZoomStep, true); }

◆ ZoomTo()

void NoteTrack::ZoomTo ( const wxRect &  rect,
int  start,
int  end 
)

Definition at line 1073 of file NoteTrack.cpp.

1074{
1075 wxRect trackRect(0, rect.GetY(), 1, rect.GetHeight());
1076 NoteTrackDisplayData data = NoteTrackDisplayData(this, trackRect);
1077 int pitch1 = data.YToIPitch(start);
1078 int pitch2 = data.YToIPitch(end);
1079 if (pitch1 == pitch2) {
1080 // Just zoom in instead of zooming to show only one note
1081 Zoom(rect, start, 1, true);
1082 return;
1083 }
1084 // It's fine for this to be in either order
1085 SetNoteRange(pitch1, pitch2);
1086}
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Definition: PackedArray.h:159

References PackedArray::end(), SetNoteRange(), NoteTrackDisplayData::YToIPitch(), and Zoom().

Here is the call graph for this function:

Member Data Documentation

◆ mBottomNote

int NoteTrack::mBottomNote
private

◆ mPitchHeight

float NoteTrack::mPitchHeight
private

Definition at line 240 of file NoteTrack.h.

◆ mSeq

std::unique_ptr<Alg_seq> NoteTrack::mSeq
mutableprivate

◆ mSerializationBuffer

std::unique_ptr<char[]> NoteTrack::mSerializationBuffer
mutableprivate

Definition at line 224 of file NoteTrack.h.

Referenced by Clone(), and GetSeq().

◆ mSerializationLength

long NoteTrack::mSerializationLength
mutableprivate

Definition at line 225 of file NoteTrack.h.

Referenced by Clone(), GetSeq(), and NoteTrack().

◆ mStretchHandle

std::weak_ptr<StretchHandle> NoteTrack::mStretchHandle
private

Definition at line 248 of file NoteTrack.h.

◆ mTopNote

int NoteTrack::mTopNote
private

◆ mVisibleChannels

std::atomic<unsigned> NoteTrack::mVisibleChannels { ALL_CHANNELS }
private

A bit set; atomic because it may be read by worker threads in playback.

Definition at line 246 of file NoteTrack.h.

◆ ZoomStep

const float NoteTrack::ZoomStep = powf( 2.0f, 0.25f )
staticprivate

Definition at line 243 of file NoteTrack.h.


The documentation for this class was generated from the following files: