Audacity  3.0.3
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  LinkType : int { LinkType::None = 0, LinkType::Group = 2, LinkType::Aligned }
 For two tracks describes the type of the linkage. More...
 
enum  ChannelType { LeftChannel = 0, RightChannel = 1, MonoChannel = 2 }
 
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 wxChar *tag, const wxChar **attrs) override
 
XMLTagHandlerHandleXMLChild (const wxChar *tag) override
 
void WriteXML (XMLWriter &xmlFile) const override
 
bool IsVisibleChan (int c) const
 
void SetVisibleChan (int c)
 
void ClearVisibleChan (int c)
 
void ToggleVisibleChan (int c)
 
void SoloVisibleChan (int c)
 
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 wxChar *, const wxChar *)
 
- 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 -> typename std::enable_if< std::is_const< Subclass >::value, std::shared_ptr< Subclass > >::type
 
std::shared_ptr< TrackSubstitutePendingChangedTrack ()
 
std::shared_ptr< const TrackSubstitutePendingChangedTrack () const
 
std::shared_ptr< const TrackSubstituteOriginalTrack () const
 
virtual bool SupportsBasicEditing () const
 Whether this track type implements cut-copy-paste; by default, true. More...
 
const std::shared_ptr< CommonTrackCell > & GetTrackView ()
 
void SetTrackView (const std::shared_ptr< CommonTrackCell > &pView)
 
const std::shared_ptr< CommonTrackCell > & GetTrackControls ()
 
void SetTrackControls (const std::shared_ptr< CommonTrackCell > &pControls)
 
int GetIndex () const
 
void SetIndex (int index)
 
virtual bool LinkConsistencyCheck ()
 
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...
 
 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)
 
wxString GetDefaultName () const
 
void SetDefaultName (const wxString &n)
 
bool GetSelected () const
 
virtual void SetSelected (bool s)
 
void EnsureVisible (bool modifyState=false)
 
virtual ChannelType GetChannel () const
 
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 bool GetErrorOpening ()
 
bool IsSyncLockSelected () const
 
void Notify (int code=-1)
 
bool Any () const
 
bool IsSelected () const
 
bool IsSelectedOrSyncLockSelected () const
 
bool IsLeader () const
 
bool IsSelectedLeader () const
 
void AdjustPositions ()
 
void WriteCommonXMLAttributes (XMLWriter &xmlFile, bool includeNameAndSelected=true) const
 
bool HandleCommonXMLAttribute (const wxChar *attr, const wxChar *value)
 
- Public Member Functions inherited from XMLTagHandler
 XMLTagHandler ()
 
virtual ~XMLTagHandler ()
 
virtual void HandleXMLEndTag (const wxChar *WXUNUSED(tag))
 
virtual void HandleXMLContent (const wxString &WXUNUSED(content))
 
bool ReadXMLTag (const char *tag, const char **attrs)
 
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 -> typename std::enable_if< std::is_const< Subclass >::value, Subclass & >::type
 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 -> typename std::enable_if< std::is_const< Subclass >::value, Subclass * >::type
 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 void DrawLabelControls (const NoteTrack *pTrack, wxDC &dc, const wxRect &rect, int highlightedChannel=-1)
 
- 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 void FinishCopy (const Track *n, Track *dest)
 
- 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
 
TrackKind GetKind () 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
 
int mVisibleChannels
 
std::weak_ptr< StretchHandlemStretchHandle
 

Static Private Attributes

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

Additional Inherited Members

- Public Attributes inherited from Track
wxSize vrulerSize
 
- Protected Member Functions inherited from Track
void SetLinkType (LinkType linkType)
 
void DoSetLinkType (LinkType linkType) noexcept
 
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
 
wxString mDefaultName
 
ChannelType mChannel
 
double mOffset
 
std::shared_ptr< CommonTrackCellmpView
 
std::shared_ptr< CommonTrackCellmpControls
 

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 72 of file NoteTrack.h.

Member Enumeration Documentation

◆ anonymous enum

anonymous enum
private
Enumerator
MinPitch 
MaxPitch 

Definition at line 222 of file NoteTrack.h.

222 { MinPitch = 0, MaxPitch = 127 };

Constructor & Destructor Documentation

◆ NoteTrack()

NoteTrack::NoteTrack ( )

Definition at line 123 of file NoteTrack.cpp.

124  : NoteTrackBase()
125 {
126  SetDefaultName(_("Note Track"));
128 
129  mSeq = NULL;
131 
132 #ifdef EXPERIMENTAL_MIDI_OUT
133  mVelocity = 0;
134 #endif
136  mTopNote = MaxPitch;
137 
139 }

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

Here is the call graph for this function:

◆ ~NoteTrack()

NoteTrack::~NoteTrack ( )
virtual

Definition at line 141 of file NoteTrack.cpp.

142 {
143 }

Member Function Documentation

◆ AddToDuration()

void NoteTrack::AddToDuration ( double  delta)
private

Definition at line 709 of file NoteTrack.cpp.

710 {
711  auto &seq = GetSeq();
712 #if 0
713  // PRL: Would this be better ?
714  seq.set_real_dur( seq.get_real_dur() + delta );
715 #else
716  seq.convert_to_seconds();
717  seq.set_dur( seq.get_dur() + delta );
718 #endif
719 }

References GetSeq().

Referenced by Paste(), and StretchRegion().

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

◆ Clear()

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

Definition at line 527 of file NoteTrack.cpp.

528 {
529  if (t1 < t0)
531 
532  double len = t1-t0;
533 
534  auto &seq = GetSeq();
535 
536  auto offset = GetOffset();
537  auto start = t0 - offset;
538  if (start < 0.0) {
539  // AlgSeq::clear will shift the cleared interval, not changing len, if
540  // start is negative. That's not what we want to happen.
541  if (len > -start) {
542  seq.clear(0, len + start, false);
543  SetOffset(t0);
544  }
545  else
546  SetOffset(offset - len);
547  }
548  else {
549  //auto delta = -(
550  //( std::min( t1, GetEndTime() ) ) - ( std::max( t0, GetStartTime() ) )
551  //);
552  seq.clear(start, len, false);
553 
554  // Not needed
555  // Alg_seq::clear seems to handle this
556  // AddToDuration( delta );
557  }
558 }

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 178 of file NoteTrack.h.

178 { mVisibleChannels &= ~CHANNEL_BIT(c); }

References CHANNEL_BIT.

◆ Clone()

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

Implements Track.

Definition at line 167 of file NoteTrack.cpp.

168 {
169  auto duplicate = std::make_shared<NoteTrack>();
170  duplicate->Init(*this);
171  // The duplicate begins life in serialized state. Often the duplicate is
172  // pushed on the Undo stack. Then we want to un-serialize it (or a further
173  // copy) only on demand after an Undo.
174  if (mSeq) {
176  wxASSERT(!mSerializationBuffer);
177  // serialize from this to duplicate's mSerializationBuffer
178  void *buffer;
179  mSeq->serialize(&buffer,
180  &duplicate->mSerializationLength);
181  duplicate->mSerializationBuffer.reset( (char*)buffer );
183  }
184  else if (mSerializationBuffer) {
185  // Copy already serialized data.
186  wxASSERT(!mSeq);
187  duplicate->mSerializationLength = this->mSerializationLength;
188  duplicate->mSerializationBuffer.reset
189  ( safenew char[ this->mSerializationLength ] );
190  memcpy( duplicate->mSerializationBuffer.get(),
191  this->mSerializationBuffer.get(), this->mSerializationLength );
192  }
193  else {
194  // We are duplicating a default-constructed NoteTrack, and that's okay
195  }
196  // copy some other fields here
197  duplicate->SetBottomNote(mBottomNote);
198  duplicate->SetTopNote(mTopNote);
199  duplicate->mVisibleChannels = mVisibleChannels;
200  duplicate->SetOffset(GetOffset());
201 #ifdef EXPERIMENTAL_MIDI_OUT
202  duplicate->SetVelocity(GetVelocity());
203 #endif
204  return duplicate;
205 }

References GetOffset(), mBottomNote, mSeq, mSerializationBuffer, mSerializationLength, mTopNote, mVisibleChannels, 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 480 of file NoteTrack.cpp.

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

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 450 of file NoteTrack.cpp.

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

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 261 of file NoteTrack.cpp.

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

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 874 of file NoteTrack.cpp.

875 {
876  double offset = GetOffset();
878  auto &seq = GetSeq();
879  if (in_seconds) {
880  seq.convert_to_seconds();
881  } else {
882  seq.convert_to_beats();
883  }
884  return seq.write(f.mb_str(), offset);
885 }

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 866 of file NoteTrack.cpp.

867 {
868  std::unique_ptr<Alg_seq> cleanup;
869  auto seq = MakeExportableSeq(cleanup);
870  bool rslt = seq->smf_write(f.mb_str());
871  return rslt;
872 }

References MakeExportableSeq().

Here is the call graph for this function:

◆ FindChannel()

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

Definition at line 356 of file NoteTrack.cpp.

357 {
358  wxASSERT_MSG(rect.width % 4 == 0, "Midi channel control rect width must be divisible by 4");
359  wxASSERT_MSG(rect.height % 4 == 0, "Midi channel control rect height must be divisible by 4");
360 
361  auto cellWidth = rect.width / 4;
362  auto cellHeight = rect.height / 4;
363 
364  int col = (mx - rect.x) / cellWidth;
365  int row = (my - rect.y) / cellHeight;
366 
367  return row * 4 + col;
368 }

Referenced by NoteTrackButtonHandle::HitTest(), and 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 120 of file NoteTrack.h.

120 { 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 218 of file NoteTrack.cpp.

219 {
220  return GetStartTime() + GetSeq().get_real_dur();
221 }

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 695 of file NoteTrack.cpp.

696 {
697  ConstIntervals results;
698  results.emplace_back( GetStartTime(), GetEndTime() );
699  return results;
700 }

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 702 of file NoteTrack.cpp.

703 {
704  Intervals results;
705  results.emplace_back( GetStartTime(), GetEndTime() );
706  return results;
707 }

◆ GetKind()

TrackKind NoteTrack::GetKind ( ) const
inlineoverrideprivatevirtual

Reimplemented from Track.

Definition at line 196 of file NoteTrack.h.

196 { return TrackKind::Note; }

References Note.

◆ GetOffset()

double NoteTrack::GetOffset ( ) const
overridevirtual

Implements Track.

Definition at line 208 of file NoteTrack.cpp.

209 {
210  return mOffset;
211 }

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(), anonymous_namespace{MIDIPlay.h}::MIDIPlay::PrepareMidiIterator(), Silence(), Trim(), WarpAndTransposeNotes(), and WriteXML().

Here is the caller graph for this function:

◆ GetSeq()

Alg_seq & NoteTrack::GetSeq ( ) const

Definition at line 145 of file NoteTrack.cpp.

146 {
147  if (!mSeq) {
149  mSeq = std::make_unique<Alg_seq>();
150  else {
151  std::unique_ptr<Alg_track> alg_track
152  { Alg_seq::unserialize
154  wxASSERT(alg_track->get_type() == 's');
155  mSeq.reset( static_cast<Alg_seq*>(alg_track.release()) );
156 
157  // Preserve the invariant that at most one of the representations is
158  // valid
159  mSerializationBuffer.reset();
161  }
162  }
163  wxASSERT(mSeq);
164  return *mSeq;
165 }

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 213 of file NoteTrack.cpp.

214 {
215  return GetOffset();
216 }

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 122 of file NoteTrack.h.

122 { return mTopNote; }

Referenced by NoteTrackDisplayData::NoteTrackDisplayData().

Here is the caller graph for this function:

◆ HandleXMLChild()

XMLTagHandler * NoteTrack::HandleXMLChild ( const wxChar *  tag)
overridevirtual

Implements XMLTagHandler.

Definition at line 944 of file NoteTrack.cpp.

945 {
946  return NULL;
947 }

◆ HandleXMLTag()

bool NoteTrack::HandleXMLTag ( const wxChar *  tag,
const wxChar **  attrs 
)
overridevirtual

Implements XMLTagHandler.

Definition at line 895 of file NoteTrack.cpp.

896 {
897  if (!wxStrcmp(tag, wxT("notetrack"))) {
898  while (*attrs) {
899  const wxChar *attr = *attrs++;
900  const wxChar *value = *attrs++;
901  if (!value)
902  break;
903  const wxString strValue = value;
904  long nValue;
905  double dblValue;
906  if (this->Track::HandleCommonXMLAttribute(attr, strValue))
907  ;
908  else if (this->NoteTrackBase::HandleXMLAttribute(attr, value))
909  {}
910  else if (!wxStrcmp(attr, wxT("offset")) &&
911  XMLValueChecker::IsGoodString(strValue) &&
912  Internat::CompatibleToDouble(strValue, &dblValue))
913  SetOffset(dblValue);
914  else if (!wxStrcmp(attr, wxT("visiblechannels"))) {
915  if (!XMLValueChecker::IsGoodInt(strValue) ||
916  !strValue.ToLong(&nValue) ||
917  !IsValidVisibleChannels(nValue))
918  return false;
919  mVisibleChannels = nValue;
920  }
921 #ifdef EXPERIMENTAL_MIDI_OUT
922  else if (!wxStrcmp(attr, wxT("velocity")) &&
923  XMLValueChecker::IsGoodString(strValue) &&
924  Internat::CompatibleToDouble(strValue, &dblValue))
925  mVelocity = (float) dblValue;
926 #endif
927  else if (!wxStrcmp(attr, wxT("bottomnote")) &&
928  XMLValueChecker::IsGoodInt(strValue) && strValue.ToLong(&nValue))
929  SetBottomNote(nValue);
930  else if (!wxStrcmp(attr, wxT("topnote")) &&
931  XMLValueChecker::IsGoodInt(strValue) && strValue.ToLong(&nValue))
932  SetTopNote(nValue);
933  else if (!wxStrcmp(attr, wxT("data"))) {
934  std::string s(strValue.mb_str(wxConvUTF8));
935  std::istringstream data(s);
936  mSeq = std::make_unique<Alg_seq>(data, false);
937  }
938  } // while
939  return true;
940  }
941  return false;
942 }

References Internat::CompatibleToDouble(), Track::HandleCommonXMLAttribute(), AudioTrack::HandleXMLAttribute(), XMLValueChecker::IsGoodInt(), XMLValueChecker::IsGoodString(), anonymous_namespace{NoteTrack.cpp}::IsValidVisibleChannels(), mSeq, mVisibleChannels, SetBottomNote(), Track::SetOffset(), and SetTopNote().

Here is the call graph for this function:

◆ InsertSilence()

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

Definition at line 625 of file NoteTrack.cpp.

626 {
627  if (len < 0)
629 
630  auto &seq = GetSeq();
631  seq.convert_to_seconds();
632  seq.insert_silence(t - GetOffset(), len);
633 
634  // is this needed?
635  // AddToDuration( len );
636 }

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 174 of file NoteTrack.h.

174  {
175  return (mVisibleChannels & CHANNEL_BIT(c)) != 0;
176  }

References CHANNEL_BIT.

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

Here is the caller graph for this function:

◆ LabelClick()

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

Definition at line 375 of file NoteTrack.cpp.

376 {
377  auto channel = FindChannel(rect, mx, my);
378  if (right)
379  SoloVisibleChan(channel);
380  else
381  ToggleVisibleChan(channel);
382 
383  return true;
384 }

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 743 of file NoteTrack.cpp.

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

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 677 of file NoteTrack.cpp.

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

References GetOffset(), and GetSeq().

Referenced by StretchHandle::HitTest().

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

◆ Paste()

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

Definition at line 560 of file NoteTrack.cpp.

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

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 688 of file NoteTrack.cpp.

689 {
690  auto pNewTrack = std::make_shared<NoteTrack>();
691  pNewTrack->Paste(0.0, this);
692  return pNewTrack;
693 }

◆ PrintSequence()

void NoteTrack::PrintSequence ( )

Definition at line 391 of file NoteTrack.cpp.

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

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 977 of file NoteTrack.cpp.

978 {
979  if (note < MinPitch)
980  note = MinPitch;
981  else if (note > 96)
982  note = 96;
983 
984  wxCHECK(note <= mTopNote, );
985 
986  mBottomNote = note;
987 }

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 999 of file NoteTrack.cpp.

1000 {
1001  // Bounds check
1002  if (note1 > MaxPitch)
1003  note1 = MaxPitch;
1004  else if (note1 < MinPitch)
1005  note1 = MinPitch;
1006  if (note2 > MaxPitch)
1007  note2 = MaxPitch;
1008  else if (note2 < MinPitch)
1009  note2 = MinPitch;
1010  // Swap to ensure ordering
1011  if (note2 < note1) { auto tmp = note1; note1 = note2; note2 = tmp; }
1012 
1013  mBottomNote = note1;
1014  mTopNote = note2;
1015 }

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 386 of file NoteTrack.cpp.

387 {
388  mSeq = std::move(seq);
389 }

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 989 of file NoteTrack.cpp.

990 {
991  if (note > MaxPitch)
992  note = MaxPitch;
993 
994  wxCHECK(note >= mBottomNote, );
995 
996  mTopNote = note;
997 }

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 177 of file NoteTrack.h.

177 { mVisibleChannels |= CHANNEL_BIT(c); }

References CHANNEL_BIT.

◆ Shift()

bool NoteTrack::Shift ( double  t)

Definition at line 650 of file NoteTrack.cpp.

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

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 1017 of file NoteTrack.cpp.

1018 {
1019  // Ensure everything stays in bounds
1020  if (mBottomNote + offset < MinPitch || mTopNote + offset > MaxPitch)
1021  return;
1022 
1023  mBottomNote += offset;
1024  mTopNote += offset;
1025 }

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 610 of file NoteTrack.cpp.

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

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 182 of file NoteTrack.h.

182  {
183  if (mVisibleChannels == CHANNEL_BIT(c))
185  else
187  }

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 721 of file NoteTrack.cpp.

723 {
724  auto &seq = GetSeq();
725  bool result = seq.stretch_region( t0.second, t1.second, newDur );
726  if (result) {
727  const auto oldDur = t1.first - t0.first;
728  AddToDuration( newDur - oldDur );
729  }
730  return result;
731 }

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 179 of file NoteTrack.h.

179 { mVisibleChannels ^= CHANNEL_BIT(c); }

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 503 of file NoteTrack.cpp.

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

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 223 of file NoteTrack.cpp.

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

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 949 of file NoteTrack.cpp.

951 {
952  std::ostringstream data;
953  Track::Holder holder;
954  const NoteTrack *saveme = this;
955  if (!mSeq) {
956  // replace saveme with an (unserialized) duplicate, which is
957  // destroyed at end of function.
958  holder = Clone();
959  saveme = static_cast<NoteTrack*>(holder.get());
960  }
961  saveme->GetSeq().write(data, true);
962  xmlFile.StartTag(wxT("notetrack"));
963  saveme->Track::WriteCommonXMLAttributes( xmlFile );
964  this->NoteTrackBase::WriteXMLAttributes(xmlFile);
965  xmlFile.WriteAttr(wxT("offset"), saveme->GetOffset());
966  xmlFile.WriteAttr(wxT("visiblechannels"), saveme->mVisibleChannels);
967 
968 #ifdef EXPERIMENTAL_MIDI_OUT
969  xmlFile.WriteAttr(wxT("velocity"), (double) saveme->mVelocity);
970 #endif
971  xmlFile.WriteAttr(wxT("bottomnote"), saveme->mBottomNote);
972  xmlFile.WriteAttr(wxT("topnote"), saveme->mTopNote);
973  xmlFile.WriteAttr(wxT("data"), wxString(data.str().c_str(), wxConvUTF8));
974  xmlFile.EndTag(wxT("notetrack"));
975 }

References GetOffset(), GetSeq(), mBottomNote, mTopNote, mVisibleChannels, 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 1041 of file NoteTrack.cpp.

1042 {
1043  NoteTrackDisplayData data = NoteTrackDisplayData(this, rect);
1044  int clickedPitch = data.YToIPitch(y);
1045  int extent = mTopNote - mBottomNote + 1;
1046  int newExtent = (int) (extent / multiplier);
1047  float position;
1048  if (center) {
1049  // center the pitch that the user clicked on
1050  position = .5;
1051  } else {
1052  // align to keep the pitch that the user clicked on in the same place
1053  position = extent / (clickedPitch - mBottomNote);
1054  }
1055  int newBottomNote = clickedPitch - (newExtent * position);
1056  int newTopNote = clickedPitch + (newExtent * (1 - position));
1057  SetNoteRange(newBottomNote, newTopNote);
1058 }

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 1076 of file NoteTrack.cpp.

1077 {
1078  Alg_iterator iterator( &GetSeq(), false );
1079  iterator.begin();
1080  Alg_event_ptr evt;
1081 
1082  // Go through all of the notes, finding the minimum and maximum value pitches.
1083  bool hasNotes = false;
1084  int minPitch = MaxPitch;
1085  int maxPitch = MinPitch;
1086 
1087  while (NULL != (evt = iterator.next())) {
1088  if (evt->is_note()) {
1089  int pitch = (int) evt->get_pitch();
1090  hasNotes = true;
1091  if (pitch < minPitch)
1092  minPitch = pitch;
1093  if (pitch > maxPitch)
1094  maxPitch = pitch;
1095  }
1096  }
1097 
1098  if (!hasNotes) {
1099  // Semi-arbitrary default values:
1100  minPitch = 48;
1101  maxPitch = 72;
1102  }
1103 
1104  SetNoteRange(minPitch, maxPitch);
1105 }

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 140 of file NoteTrack.h.

140 { Zoom(rect, y, ZoomStep, true); }

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 133 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 138 of file NoteTrack.h.

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

◆ ZoomTo()

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

Definition at line 1061 of file NoteTrack.cpp.

1062 {
1063  wxRect trackRect(0, rect.GetY(), 1, rect.GetHeight());
1064  NoteTrackDisplayData data = NoteTrackDisplayData(this, trackRect);
1065  int pitch1 = data.YToIPitch(start);
1066  int pitch2 = data.YToIPitch(end);
1067  if (pitch1 == pitch2) {
1068  // Just zoom in instead of zooming to show only one note
1069  Zoom(rect, start, 1, true);
1070  return;
1071  }
1072  // It's fine for this to be in either order
1073  SetNoteRange(pitch1, pitch2);
1074 }

References 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 220 of file NoteTrack.h.

◆ mSeq

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

◆ mSerializationBuffer

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

Definition at line 205 of file NoteTrack.h.

Referenced by Clone(), and GetSeq().

◆ mSerializationLength

long NoteTrack::mSerializationLength
mutableprivate

Definition at line 206 of file NoteTrack.h.

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

◆ mStretchHandle

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

Definition at line 227 of file NoteTrack.h.

◆ mTopNote

int NoteTrack::mTopNote
private

◆ mVisibleChannels

int NoteTrack::mVisibleChannels
private

Definition at line 225 of file NoteTrack.h.

Referenced by Clone(), HandleXMLTag(), NoteTrack(), and WriteXML().

◆ ZoomStep

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

Definition at line 223 of file NoteTrack.h.


The documentation for this class was generated from the following files:
XMLWriter::EndTag
virtual void EndTag(const wxString &name)
Definition: XMLWriter.cpp:99
Track::GetDefaultName
wxString GetDefaultName() const
Definition: Track.h:428
Track::mOffset
double mOffset
Definition: Track.h:408
NoteTrack::MakeExportableSeq
Alg_seq * MakeExportableSeq(std::unique_ptr< Alg_seq > &cleanup) const
Definition: NoteTrack.cpp:743
NoteTrack::GetOffset
double GetOffset() const override
Definition: NoteTrack.cpp:208
XMLValueChecker::IsGoodInt
static bool IsGoodInt(const wxString &strInt)
Check that the supplied string can be converted to a long (32bit) integer.
Definition: XMLTagHandler.cpp:157
Track::ConstIntervals
std::vector< ConstInterval > ConstIntervals
Definition: Track.h:331
NoteTrack::InsertSilence
void InsertSilence(double t, double len) override
Definition: NoteTrack.cpp:625
AColor::Line
static void Line(wxDC &dc, wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
Definition: AColor.cpp:109
NoteTrack::ToggleVisibleChan
void ToggleVisibleChan(int c)
Definition: NoteTrack.h:179
ALL_CHANNELS
#define ALL_CHANNELS
Definition: NoteTrack.h:172
AudioTrack::HandleXMLAttribute
bool HandleXMLAttribute(const wxChar *, const wxChar *)
Definition: Track.h:848
Track::SetOffset
virtual void SetOffset(double o)
Definition: Track.h:445
AColor::MIDIChannel
static void MIDIChannel(wxDC *dc, int channel)
Definition: AColor.cpp:573
Track::HandleCommonXMLAttribute
bool HandleCommonXMLAttribute(const wxChar *attr, const wxChar *value)
Definition: Track.cpp:1269
XMLValueChecker::IsGoodString
static bool IsGoodString(const wxString &str)
Definition: XMLTagHandler.cpp:38
NoteTrack::SetTopNote
void SetTopNote(int note)
Sets the top note (a pitch), making sure that it is never less than the bottom note.
Definition: NoteTrack.cpp:989
NoteTrack::IsVisibleChan
bool IsVisibleChan(int c) const
Definition: NoteTrack.h:174
ImportExportPrefs::AllegroStyleSetting
static EnumSetting< bool > AllegroStyleSetting
Definition: ImportExportPrefs.h:31
NoteTrack::ZoomStep
static const float ZoomStep
Definition: NoteTrack.h:223
AudioTrack::WriteXMLAttributes
void WriteXMLAttributes(XMLWriter &WXUNUSED(xmlFile)) const
Definition: Track.h:845
AColor::DarkMIDIChannel
static void DarkMIDIChannel(wxDC *dc, int channel)
Definition: AColor.cpp:607
NoteTrackDisplayData
Data used to display a note track.
Definition: NoteTrack.h:231
CHANNEL_BIT
#define CHANNEL_BIT(c)
Definition: NoteTrack.h:173
Track::Holder
std::shared_ptr< Track > Holder
Definition: Track.h:336
NoteTrack::mTopNote
int mTopNote
Definition: NoteTrack.h:212
Track::SetDefaultName
void SetDefaultName(const wxString &n)
Definition: Track.h:429
AColor::LightMIDIChannel
static void LightMIDIChannel(wxDC *dc, int channel)
Definition: AColor.cpp:589
NoteTrackDisplayData::YToIPitch
int YToIPitch(int y) const
Definition: NoteTrack.cpp:1148
NoteTrack::mBottomNote
int mBottomNote
Definition: NoteTrack.h:212
NoteTrack::Clone
Track::Holder Clone() const override
Definition: NoteTrack.cpp:167
THROW_INCONSISTENCY_EXCEPTION
#define THROW_INCONSISTENCY_EXCEPTION
Throw InconsistencyException, using C++ preprocessor to identify the source code location.
Definition: InconsistencyException.h:79
NoteTrack::Zoom
void Zoom(const wxRect &rect, int y, float multiplier, bool center)
Definition: NoteTrack.cpp:1041
NoteTrack::GetStartTime
double GetStartTime() const override
Definition: NoteTrack.cpp:213
anonymous_namespace{NoteTrack.cpp}::swap
void swap(std::unique_ptr< Alg_seq > &a, std::unique_ptr< Alg_seq > &b)
Definition: NoteTrack.cpp:735
anonymous_namespace{NoteTrack.cpp}::IsValidVisibleChannels
bool IsValidVisibleChannels(const int nValue)
Definition: NoteTrack.cpp:889
NoteTrack::AddToDuration
void AddToDuration(double delta)
Definition: NoteTrack.cpp:709
NoteTrack::mSerializationLength
long mSerializationLength
Definition: NoteTrack.h:206
TimeWarper::Warp
virtual double Warp(double originalTime) const =0
theTheme
THEME_API Theme theTheme
Definition: Theme.cpp:79
Track::Intervals
std::vector< Interval > Intervals
Definition: Track.h:329
SonifyBeginSerialize
#define SonifyBeginSerialize()
Definition: NoteTrack.h:290
NoteTrack::SoloVisibleChan
void SoloVisibleChan(int c)
Definition: NoteTrack.h:182
Track::TypeSwitch
R TypeSwitch(const Functions &...functions)
Use this function rather than testing track type explicitly and making down-casts.
Definition: Track.h:709
EnumSetting::ReadEnum
Enum ReadEnum() const
Definition: Prefs.h:373
Track::SetName
void SetName(const wxString &n)
Definition: Track.cpp:82
NoteTrack::MinPitch
@ MinPitch
Definition: NoteTrack.h:222
_
#define _(s)
Definition: Internat.h:75
SonifyEndSerialize
#define SonifyEndSerialize()
Definition: NoteTrack.h:291
NoteTrack::mVisibleChannels
int mVisibleChannels
Definition: NoteTrack.h:225
XMLWriter::WriteAttr
void WriteAttr(const wxString &name, const Identifier &value)
Definition: XMLWriter.h:34
NoteTrackBase
AudioTrack NoteTrackBase
Definition: NoteTrack.h:58
ThemeBase::Colour
wxColour & Colour(int iIndex)
Definition: Theme.cpp:1189
NoteTrack::SetBottomNote
void SetBottomNote(int note)
Sets the bottom note (a pitch), making sure that it is never greater than the top note.
Definition: NoteTrack.cpp:977
NoteTrack::GetSeq
Alg_seq & GetSeq() const
Definition: NoteTrack.cpp:145
NoteTrack::GetEndTime
double GetEndTime() const override
Definition: NoteTrack.cpp:218
ROUND
#define ROUND(x)
Definition: NoteTrack.cpp:33
NoteTrack::mSerializationBuffer
std::unique_ptr< char[]> mSerializationBuffer
Definition: NoteTrack.h:205
safenew
#define safenew
Definition: MemoryX.h:10
NoteTrack::FindChannel
int FindChannel(const wxRect &rect, int mx, int my)
Definition: NoteTrack.cpp:356
within
bool within(A a, B b, DIST d)
Definition: TrackPanel.cpp:163
NoteTrack::MaxPitch
@ MaxPitch
Definition: NoteTrack.h:222
XMLWriter::StartTag
virtual void StartTag(const wxString &name)
Definition: XMLWriter.cpp:76
NoteTrack::mSeq
std::unique_ptr< Alg_seq > mSeq
Definition: NoteTrack.h:204
NoteTrack::SetNoteRange
void SetNoteRange(int note1, int note2)
Sets the top and bottom note (both pitches) automatically, swapping them if needed.
Definition: NoteTrack.cpp:999
NoteTrack
A Track that is used for Midi notes. (Somewhat old code).
Definition: NoteTrack.h:67
TrackKind::Note
@ Note
Internat::CompatibleToDouble
static bool CompatibleToDouble(const wxString &stringToConvert, double *result)
Convert a string to a number.
Definition: Internat.cpp:134
NoteTrack::Shift
bool Shift(double t)
Definition: NoteTrack.cpp:650