Audacity 3.2.0
Public Member Functions | Static Public Member Functions | List of all members
WaveTrackMenuTable Struct Reference
Inheritance diagram for WaveTrackMenuTable:
[legend]
Collaboration diagram for WaveTrackMenuTable:
[legend]

Public Member Functions

 WaveTrackMenuTable ()
 
void InitUserData (void *pUserData) override
 Called before the menu items are appended. More...
 
 DECLARE_POPUP_MENU (WaveTrackMenuTable)
 
void OnMultiView (wxCommandEvent &event)
 
void OnSetDisplay (wxCommandEvent &event)
 Set the Display mode based on the menu choice in the Track Menu. More...
 
void OnMergeStereo (wxCommandEvent &event)
 Merge two tracks into one stereo track ?? More...
 
void SplitStereo (bool stereo)
 Splits stereo track into two mono tracks, preserving panning if stereo is set. More...
 
void OnSwapChannels (wxCommandEvent &event)
 Swap the left and right channels of a stero track... More...
 
void OnSplitStereo (wxCommandEvent &event)
 Split a stereo track into two tracks... More...
 
void OnSplitStereoMono (wxCommandEvent &event)
 Split a stereo track into two mono tracks... More...
 
- Public Member Functions inherited from WaveTrackPopupMenuTable
WaveTrackFindWaveTrack () const
 
int ReserveId ()
 
 PopupMenuTable (const Identifier &id, const TranslatableString &caption={})
 
- Public Member Functions inherited from PopupMenuTable
 PopupMenuTable (const Identifier &id, const TranslatableString &caption={})
 
const IdentifierId () const
 
const TranslatableStringCaption () const
 
const auto * GetRegistry () const
 
const auto & Get (void *pUserData)
 
void Clear ()
 
- Public Member Functions inherited from PopupMenuHandler
 PopupMenuHandler ()=default
 
 PopupMenuHandler (const PopupMenuHandler &)=delete
 
PopupMenuHandleroperator= (const PopupMenuHandler &)=delete
 
virtual void InitUserData (void *pUserData)=0
 Called before the menu items are appended. More...
 

Static Public Member Functions

static WaveTrackMenuTableInstance ()
 
- Static Public Member Functions inherited from PopupMenuTable
static std::unique_ptr< PopupMenuBuildMenu (PopupMenuTable *pTable, void *pUserData=NULL)
 
static void ExtendMenu (PopupMenu &menu, PopupMenuTable &otherTable)
 
template<typename Table , typename Factory >
static auto Adapt (const Factory &factory)
 

Additional Inherited Members

- Public Types inherited from PopupMenuTable
using Entry = PopupMenuTableEntry
 
- Public Attributes inherited from WaveTrackPopupMenuTable
PlayableTrackControls::InitMenuDatampData {}
 
- Protected Member Functions inherited from PopupMenuTable
virtual void Populate ()=0
 
template<typename Ptr >
void Append (Ptr pItem)
 
void Append (const Identifier &stringId, PopupMenuTableEntry::Type type, int id, const TranslatableString &string, wxCommandEventFunction memFn, const PopupMenuTableEntry::InitFunction &init)
 
void AppendItem (const Identifier &stringId, int id, const TranslatableString &string, wxCommandEventFunction memFn, const PopupMenuTableEntry::InitFunction &init={})
 
void AppendRadioItem (const Identifier &stringId, int id, const TranslatableString &string, wxCommandEventFunction memFn, const PopupMenuTableEntry::InitFunction &init={})
 
void AppendCheckItem (const Identifier &stringId, int id, const TranslatableString &string, wxCommandEventFunction memFn, const PopupMenuTableEntry::InitFunction &init={})
 
void BeginSection (const Identifier &name)
 
void EndSection ()
 
- Static Protected Member Functions inherited from PopupMenuTable
static TranslatableString MakeLabel (const TranslatableString &label, bool useExtra, const TranslatableString &extra)
 
- Protected Attributes inherited from WaveTrackPopupMenuTable
int mNextId = 0
 
- Protected Attributes inherited from PopupMenuTable
std::shared_ptr< PopupSubMenumTop
 
std::vector< PopupMenuGroupItem * > mStack
 
Identifier mId
 
TranslatableString mCaption
 
std::unique_ptr< PopupMenuGroupItemmRegistry
 

Detailed Description

Definition at line 502 of file WaveTrackControls.cpp.

Constructor & Destructor Documentation

◆ WaveTrackMenuTable()

WaveTrackMenuTable::WaveTrackMenuTable ( )
inline

Member Function Documentation

◆ DECLARE_POPUP_MENU()

WaveTrackMenuTable::DECLARE_POPUP_MENU ( WaveTrackMenuTable  )

◆ InitUserData()

void WaveTrackMenuTable::InitUserData ( void *  pUserData)
overridevirtual

Called before the menu items are appended.

Store context data, if needed. May be called more than once before the menu opens. Pointer remains valid for the duration of any callback, if PopupMenuTable::BuildMenu() is called and the result's Popup() is called before any other menus are built.

Implements PopupMenuHandler.

Definition at line 538 of file WaveTrackControls.cpp.

539{
540 mpData = static_cast<PlayableTrackControls::InitMenuData*>(pUserData);
541}
PlayableTrackControls::InitMenuData * mpData

References WaveTrackPopupMenuTable::mpData.

◆ Instance()

WaveTrackMenuTable & WaveTrackMenuTable::Instance ( )
static

Definition at line 532 of file WaveTrackControls.cpp.

533{
534 static WaveTrackMenuTable instance;
535 return instance;
536}

Referenced by WaveTrackControls::GetMenuExtension(), and GetWaveTrackMenuTable().

Here is the caller graph for this function:

◆ OnMergeStereo()

void WaveTrackMenuTable::OnMergeStereo ( wxCommandEvent &  event)

Merge two tracks into one stereo track ??

Definition at line 752 of file WaveTrackControls.cpp.

753{
755 auto &tracks = TrackList::Get( *project );
756
757 const auto first = tracks.Any<WaveTrack>().find(mpData->pTrack);
758 const auto left = *first;
759 const auto right = *std::next(first);
760
761 const auto checkAligned = [](const WaveTrack& left, const WaveTrack& right)
762 {
763 auto eqTrims = [](double a, double b)
764 {
765 return std::abs(a - b) <=
766 std::numeric_limits<double>::epsilon() * std::max(a, b);
767 };
768 const auto eps = 0.5 / left.GetRate();
769 const auto rightIntervals = right.Intervals();
770 for(const auto& a : left.Intervals())
771 {
772 auto it = std::find_if(
773 rightIntervals.begin(),
774 rightIntervals.end(),
775 [&](const auto& b)
776 {
777 //Start() and End() are always snapped to a sample grid
778 return std::abs(a->Start() - b->Start()) < eps &&
779 std::abs(a->End() - b->End()) < eps &&
780 eqTrims(a->GetTrimLeft(), b->GetTrimLeft()) &&
781 eqTrims(a->GetTrimRight(), b->GetTrimRight()) &&
782 a->StretchRatioEquals(b->GetStretchRatio());
783 });
784 if(it == rightIntervals.end())
785 return false;
786 }
787 return true;
788 };
789
790 if(RealtimeEffectList::Get(*left).GetStatesCount() != 0 ||
792 !checkAligned(*left, *right))
793 {
794 const auto answer = BasicUI::ShowMessageBox(
795 XO(
796"The tracks you are attempting to merge to stereo contain clips at\n"
797"different positions, or otherwise mismatching clips. Merging them\n"
798"will render the tracks.\n\n"
799"This causes any realtime effects to be applied to the waveform and\n"
800"hidden data to be removed. Additionally, the entire track will\n"
801"become one large clip.\n\n"
802"Do you wish to continue?"
803 ),
806 .Caption(XO("Combine mono to stereo")));
808 return;
809 }
810
811 const auto viewMinimized =
812 ChannelView::Get(*left->GetChannel(0)).GetMinimized() &&
813 ChannelView::Get(*right->GetChannel(0)).GetMinimized();
814 const auto averageViewHeight =
816 WaveChannelView::Get(*right).GetHeight()) / 2;
817
818 left->SetPan(-1.0f);
819 right->SetPan(1.0f);
820 auto mix = MixAndRender(
822 tracks.Any<const WaveTrack>().find(left),
823 ++tracks.Any<const WaveTrack>().find(right)
824 },
825 Mixer::WarpOptions{ tracks.GetOwner() },
826 (*first)->GetName(),
828 //use highest sample rate
829 std::max(left->GetRate(), right->GetRate()),
830 //use widest sample format
831 std::max(left->GetSampleFormat(), right->GetSampleFormat()),
832 0.0, 0.0);
833
834 const auto newTrack = *mix->begin();
835
836 tracks.Insert(*first, std::move(*mix));
837 tracks.Remove(*left);
838 tracks.Remove(*right);
839
840 for(const auto& channel : newTrack->Channels())
841 {
842 // Set NEW track heights and minimized state
843 auto& view = ChannelView::Get(*channel);
844 view.SetMinimized(viewMinimized);
845 view.SetExpandedHeight(averageViewHeight);
846 }
847 ProjectHistory::Get( *project ).PushState(
848 /* i18n-hint: The string names a track */
849 XO("Made '%s' a stereo track").Format( newTrack->GetName() ),
850 XO("Make Stereo"));
851
852 using namespace RefreshCode;
854}
XO("Cut/Copy/Paste")
TrackListHolder MixAndRender(const TrackIterRange< const WaveTrack > &trackRange, const Mixer::WarpOptions &warpOptions, const wxString &newTrackName, WaveTrackFactory *trackFactory, double rate, sampleFormat format, double startTime, double endTime)
Mixes together all input tracks, applying any envelopes, amplitude gain, panning, and real-time effec...
const auto tracks
const auto project
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:90
static ChannelView & Get(Channel &channel)
bool GetMinimized() const
Definition: ChannelView.h:68
int GetHeight() const
Abstract base class used in importing a file.
const TranslatableString & Caption() const
void PushState(const TranslatableString &desc, const TranslatableString &shortDesc)
static ProjectHistory & Get(AudacityProject &project)
static RealtimeEffectList & Get(AudacityProject &project)
size_t GetStatesCount() const noexcept
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:347
static WaveChannelView & Get(WaveChannel &channel)
static WaveTrackFactory & Get(AudacityProject &project)
Definition: WaveTrack.cpp:4476
A Track that contains audio waveform data.
Definition: WaveTrack.h:222
@ YesNo
Two buttons.
MessageBoxResult ShowMessageBox(const TranslatableString &message, MessageBoxOptions options={})
Show a modal message box with either Ok or Yes and No, and optionally Cancel.
Definition: BasicUI.h:277
Namespace containing an enum 'what to do on a refresh?'.
Definition: RefreshCode.h:16
MessageBoxOptions && ButtonStyle(Button style) &&
Definition: BasicUI.h:107
Immutable structure is an argument to Mixer's constructor.
Definition: MixerOptions.h:56
Range between two TrackIters, usable in range-for statements, and with Visit member functions.
Definition: Track.h:807

References BasicUI::MessageBoxOptions::ButtonStyle(), PopupMenuTable::Caption(), RefreshCode::FixScrollbars, ProjectHistory::Get(), RealtimeEffectList::Get(), TrackList::Get(), WaveTrackFactory::Get(), ChannelView::Get(), WaveChannelView::Get(), ChannelView::GetHeight(), ChannelView::GetMinimized(), RealtimeEffectList::GetStatesCount(), MixAndRender(), WaveTrackPopupMenuTable::mpData, project, CommonTrackControls::InitMenuData::project, CommonTrackControls::InitMenuData::pTrack, ProjectHistory::PushState(), RefreshCode::RefreshAll, CommonTrackControls::InitMenuData::result, BasicUI::ShowMessageBox(), tracks, XO(), BasicUI::Yes, and BasicUI::YesNo.

Here is the call graph for this function:

◆ OnMultiView()

void WaveTrackMenuTable::OnMultiView ( wxCommandEvent &  event)

Definition at line 698 of file WaveTrackControls.cpp.

699{
700 const auto pTrack = static_cast<WaveTrack*>(mpData->pTrack);
701 auto &view = WaveChannelView::Get(*pTrack);
702 bool multi = !view.GetMultiView();
703 const auto &displays = view.GetDisplays();
704 const auto display = displays.empty()
705 ? WaveChannelViewConstants::Waveform : displays.begin()->id;
706 view.SetMultiView(multi);
707
708 // Whichever sub-view was on top stays on top
709 // If going into Multi-view, it will be 1/nth the height.
710 // If exiting multi-view, it will be full height.
711 view.SetDisplay(display, !multi);
712}

References WaveChannelView::Get(), and WaveChannelViewConstants::Waveform.

Here is the call graph for this function:

◆ OnSetDisplay()

void WaveTrackMenuTable::OnSetDisplay ( wxCommandEvent &  event)

Set the Display mode based on the menu choice in the Track Menu.

Definition at line 715 of file WaveTrackControls.cpp.

716{
717 int idInt = event.GetId();
718 wxASSERT(idInt >= OnSetDisplayId &&
719 idInt <= lastDisplayId);
720 const auto pTrack = static_cast<WaveTrack*>(mpData->pTrack);
721
722 auto id = AllTypes()[ idInt - OnSetDisplayId ].id;
723
724 auto &view = WaveChannelView::Get(*pTrack);
725 if (view.GetMultiView()) {
726 if (!WaveChannelView::Get(*pTrack)
727 .ToggleSubView(WaveChannelView::Display{ id } )) {
728 // Trying to toggle off the last sub-view. It was refused.
729 // Decide what to do here. Turn off multi-view instead?
730 // PRL: I don't agree that it makes sense
731 }
732 else
734 }
735 else {
736 const auto displays = view.GetDisplays();
737 const bool wrongType =
738 !(displays.size() == 1 && displays[0].id == id);
739 if (wrongType) {
741
743 ProjectHistory::Get( *project ).ModifyState(true);
744
745 using namespace RefreshCode;
747 }
748 }
749}
@ lastDisplayId
@ OnSetDisplayId
static std::vector< WaveChannelSubViewType > AllTypes()
int id
void ModifyState(bool bWantsAutoSave)
void SetDisplay(Display display, bool exclusive=true)

References AllTypes(), ProjectHistory::Get(), WaveChannelView::Get(), id, lastDisplayId, ProjectHistory::ModifyState(), WaveTrackPopupMenuTable::mpData, OnSetDisplayId, project, CommonTrackControls::InitMenuData::project, CommonTrackControls::InitMenuData::pTrack, RefreshCode::RefreshAll, CommonTrackControls::InitMenuData::result, WaveChannelView::SetDisplay(), and RefreshCode::UpdateVRuler.

Here is the call graph for this function:

◆ OnSplitStereo()

void WaveTrackMenuTable::OnSplitStereo ( wxCommandEvent &  event)

Split a stereo track into two tracks...

Definition at line 921 of file WaveTrackControls.cpp.

922{
923 SplitStereo(true);
924 WaveTrack *const pTrack = static_cast<WaveTrack*>(mpData->pTrack);
926 ProjectHistory::Get( *project ).PushState(
927 /* i18n-hint: The string names a track */
928 XO("Split stereo track '%s'").Format( pTrack->GetName() ),
929 XO("Split"));
930
931 using namespace RefreshCode;
933}
const wxString & GetName() const
Name is always the same for all channels of a group.
Definition: Track.cpp:56
void SplitStereo(bool stereo)
Splits stereo track into two mono tracks, preserving panning if stereo is set.

References RefreshCode::FixScrollbars, ProjectHistory::Get(), Track::GetName(), WaveTrackPopupMenuTable::mpData, project, CommonTrackControls::InitMenuData::project, CommonTrackControls::InitMenuData::pTrack, ProjectHistory::PushState(), RefreshCode::RefreshAll, CommonTrackControls::InitMenuData::result, SplitStereo(), and XO().

Here is the call graph for this function:

◆ OnSplitStereoMono()

void WaveTrackMenuTable::OnSplitStereoMono ( wxCommandEvent &  event)

Split a stereo track into two mono tracks...

Definition at line 936 of file WaveTrackControls.cpp.

937{
938 SplitStereo(false);
939 WaveTrack *const pTrack = static_cast<WaveTrack*>(mpData->pTrack);
941 ProjectHistory::Get( *project ).PushState(
942 /* i18n-hint: The string names a track */
943 XO("Split Stereo to Mono '%s'").Format( pTrack->GetName() ),
944 XO("Split to Mono"));
945
946 using namespace RefreshCode;
948}

References RefreshCode::FixScrollbars, ProjectHistory::Get(), Track::GetName(), WaveTrackPopupMenuTable::mpData, project, CommonTrackControls::InitMenuData::project, CommonTrackControls::InitMenuData::pTrack, ProjectHistory::PushState(), RefreshCode::RefreshAll, CommonTrackControls::InitMenuData::result, SplitStereo(), and XO().

Here is the call graph for this function:

◆ OnSwapChannels()

void WaveTrackMenuTable::OnSwapChannels ( wxCommandEvent &  event)

Swap the left and right channels of a stero track...

Definition at line 892 of file WaveTrackControls.cpp.

893{
894 // Fix assertion violation in `TrackPanel::OnEnsureVisible` by
895 // dispatching any queued event
896 // TODO wide wave tracks -- remove this when there is no "leader" distinction
897 // any more
898 wxTheApp->Yield();
899
901
902 auto &trackFocus = TrackFocus::Get( *project );
903 const auto pTrack = mpData->pTrack;
904 const bool hasFocus = trackFocus.Get() == pTrack;
905 static_cast<WaveTrack*>(pTrack)->CopyClipEnvelopes();
906 if (auto track = TrackList::SwapChannels(*pTrack))
907 {
908 if (hasFocus)
909 trackFocus.Set(track);
910
911 ProjectHistory::Get( *project ).PushState(
912 /* i18n-hint: The string names a track */
913 XO("Swapped Channels in '%s'").Format( track->GetName() ),
914 XO("Swap Channels"));
915 }
916
918}
Subclass & Get(const RegisteredFactory &key)
Get reference to an attachment, creating on demand if not present, down-cast it to Subclass.
Definition: ClientData.h:317
Track * Get()
Definition: TrackFocus.cpp:156
static Track * SwapChannels(Track &track)
Definition: Track.cpp:527
bool Set(constSamplePtr buffer, sampleFormat format, sampleCount start, size_t len, sampleFormat effectiveFormat=widestSampleFormat)
Random-access assignment of a range of samples.
Definition: WaveTrack.cpp:3506

References TrackFocus::Get(), ProjectHistory::Get(), ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::Get(), Track::GetName(), WaveTrackPopupMenuTable::mpData, project, CommonTrackControls::InitMenuData::project, CommonTrackControls::InitMenuData::pTrack, ProjectHistory::PushState(), RefreshCode::RefreshAll, CommonTrackControls::InitMenuData::result, WaveChannel::Set(), TrackList::SwapChannels(), and XO().

Here is the call graph for this function:

◆ SplitStereo()

void WaveTrackMenuTable::SplitStereo ( bool  stereo)

Splits stereo track into two mono tracks, preserving panning if stereo is set.

Split a stereo track (or more-than-stereo?) into two (or more) tracks...

Definition at line 857 of file WaveTrackControls.cpp.

858{
860
861 int totalHeight = 0;
862 int nChannels = 0;
863
864 const auto pTrack = mpData->pTrack;
865 static_cast<WaveTrack*>(pTrack)->CopyClipEnvelopes();
866 auto unlinkedTracks = TrackList::Get(*project).UnlinkChannels(*pTrack);
867 assert(unlinkedTracks.size() == 2);
868 if(stereo)
869 {
870 static_cast<WaveTrack*>(unlinkedTracks[0])->SetPan(-1.0f);
871 static_cast<WaveTrack*>(unlinkedTracks[1])->SetPan(1.0f);
872 }
873
874 for (const auto track : unlinkedTracks) {
875 auto &view = ChannelView::Get(*track->GetChannel(0));
876
877 //make sure no channel is smaller than its minimum height
878 if (view.GetHeight() < view.GetMinimizedHeight())
879 view.SetExpandedHeight(view.GetMinimizedHeight());
880 totalHeight += view.GetHeight();
881 ++nChannels;
882 }
883
884 int averageHeight = totalHeight / nChannels;
885
886 for (const auto track : unlinkedTracks)
887 // Make tracks the same height
888 ChannelView::Get(*track->GetChannel(0)).SetExpandedHeight(averageHeight);
889}
void SetExpandedHeight(int height)
std::vector< Track * > UnlinkChannels(Track &track)
Removes linkage if track belongs to a group.
Definition: Track.cpp:691

References TrackList::Get(), ChannelView::Get(), WaveTrack::GetChannel(), WaveTrackPopupMenuTable::mpData, project, CommonTrackControls::InitMenuData::project, CommonTrackControls::InitMenuData::pTrack, ChannelView::SetExpandedHeight(), and TrackList::UnlinkChannels().

Referenced by OnSplitStereo(), and OnSplitStereoMono().

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

The documentation for this struct was generated from the following file: