14#include "../../ui/PlayableTrackButtonHandles.h"
20#include "../../../../CellularPanel.h"
24#include "../../../../ProjectWindows.h"
25#include "../../../../RefreshCode.h"
29#include "../../../../TrackArtist.h"
30#include "../../../../TrackPanel.h"
32#include "../../../../TrackPanelMouseEvent.h"
37#include "../../../../prefs/PrefsDialog.h"
38#include "../../../../prefs/ThemePrefs.h"
45#include <wx/combobox.h>
58 const wxMouseState &state = st.
state;
59 const wxRect &rect = st.
rect;
60 if (state.ButtonIsDown(wxMOUSE_BTN_LEFT)) {
62 std::vector<UIHandlePtr> results;
88 results.push_back(result);
148template<
typename Table >
152 auto pData =
static_cast<Table&
>(
handler ).mpData;
153 auto &track =
static_cast<WaveTrack&
>(pData->track);
154 auto &
project = pData->project;
158 menu.Enable(
id, !unsafe );
199 return IdOfFormat( track.GetSampleFormat() );
234 int id =
event.GetId();
255 if (newFormat == track.GetSampleFormat())
261 XO(
"Processing... 0%%"),
274 auto progressUpdate = [&progress, &totalSamples, &processedSamples]
275 (
size_t newlyProcessedCount)->
void
277 processedSamples += newlyProcessedCount;
278 double d_processed = processedSamples.
as_double();
279 double d_total = totalSamples.
as_double();
280 int percentage{
static_cast<int>((d_processed / d_total) * 100) };
282 auto progressStatus = progress.Update(d_processed, d_total,
283 XO(
"Processing... %i%%").Format(percentage));
289 track.ConvertToSampleFormat(newFormat, progressUpdate);
295 XO(
"Format Change"));
340 static const auto fn = initFn< RateMenuTable >(
342 return IdOfRate( (
int)track.
GetRate() );
366static
int gRates[
nRates] = { 8000, 11025, 16000, 22050, 44100, 48000, 88200, 96000,
367176400, 192000, 352800, 384000 };
372 for (
int i = 0; i<
nRates; i++) {
387 if (pLocked != &track)
388 pLocked->SyncLockAdjust(end1, end2);
393 wxString rateString = wxString::Format(
wxT(
"%.3f"), rate);
405 int id =
event.GetId();
448 S.StartVerticalLay(
true);
451 S.StartHorizontalLay(wxEXPAND,
false);
453 cb =
S.AddCombo(
XXO(
"New sample rate (Hz):"),
456#if defined(__WXMAC__)
462 S.EndHorizontalLay();
463 S.AddStandardButtons();
467 dlg.SetClientSize(dlg.GetSizer()->CalcMin());
470 if (dlg.ShowModal() != wxID_OK)
476 if (cb->GetValue().ToLong(&lrate) && lrate >= 1 && lrate <= 1000000)
478 newRate = (int)lrate;
483 XO(
"The entered value is invalid"),
540static std::vector<WaveChannelSubViewType>
AllTypes()
573 ? std::make_unique<Entry>(
579 auto &track = table.FindWaveTrack();
581 menu.Check(
id, view.GetMultiView());
590 static const auto initFn = [](
bool radio ){
return
596 const auto IdForType =
598 const auto begin = allTypes.begin();
600 (std::find(
begin, allTypes.end(), type) -
begin);
604 auto &track = table.FindWaveTrack();
608 const auto displays = view.GetDisplays();
609 const auto end = displays.end();
611 std::find_if(displays.begin(),
end,
613 return id == IdForType(type); }));
614 menu.Check(
id, check );
618 if ( !radio && displays.size() == 1 && check )
619 menu.Enable(
id,
false );
622 Append(Adapt<My>([type,
id](My &table) {
623 const auto pTrack = &table.FindWaveTrack();
625 const auto itemType =
626 view.GetMultiView() ? Entry::CheckItem : Entry::RadioItem;
627 return std::make_unique<Entry>( type.name.Internal(), itemType,
628 id, type.name.Msgid(),
630 initFn( !view.GetMultiView() ) );
643 if ( canMakeStereo ) {
648 auto &track = table.FindWaveTrack();
649 auto next = * ++
tracks.Find(&track);
652 next->NChannels() == 1 &&
653 track_cast<WaveTrack*>(next));
655 menu.Enable(
id, canMakeStereo );
694 auto &track =
static_cast<WaveTrack&
>(mpData->track);
696 bool multi = !view.GetMultiView();
697 const auto &displays = view.GetDisplays();
698 const auto display = displays.empty()
700 view.SetMultiView(multi);
705 view.SetDisplay(display, !multi);
711 int idInt =
event.GetId();
719 if (view.GetMultiView()) {
730 const auto displays = view.GetDisplays();
731 const bool wrongType =
732 !(displays.size() == 1 && displays[0].id ==
id);
752 const auto left = *first;
753 const auto right = *std::next(first);
757 auto eqTrims = [](
double a,
double b)
759 return std::abs(a - b) <=
760 std::numeric_limits<double>::epsilon() * std::max(a, b);
762 const auto eps = 0.5 / left.
GetRate();
763 const auto &rightIntervals = right.Intervals();
765 auto it = std::find_if(
766 rightIntervals.begin(),
767 rightIntervals.end(),
771 return std::abs(a->Start() - b->Start()) < eps &&
772 std::abs(a->End() - b->End()) < eps &&
773 eqTrims(a->GetTrimLeft(), b->GetTrimLeft()) &&
774 eqTrims(a->GetTrimRight(), b->GetTrimRight()) &&
775 a->HasEqualPitchAndSpeed(*b);
777 if(it == rightIntervals.end())
785 !checkAligned(*left, *right))
789"The tracks you are attempting to merge to stereo contain clips at\n"
790"different positions, or otherwise mismatching clips. Merging them\n"
791"will render the tracks.\n\n"
792"This causes any realtime effects to be applied to the waveform and\n"
793"hidden data to be removed. Additionally, the entire track will\n"
794"become one large clip.\n\n"
795"Do you wish to continue?"
804 const auto viewMinimized =
807 const auto averageViewHeight =
822 std::max(left->
GetRate(), right->GetRate()),
827 tracks.Insert(*first, mix);
831 for(
const auto& channel : mix->Channels())
835 view.SetMinimized(viewMinimized);
836 view.SetExpandedHeight(averageViewHeight);
840 XO(
"Made '%s' a stereo track").
Format(mix->GetName()),
856 const std::vector<WaveTrack::Holder> unlinkedTracks = track.
SplitChannels();
858 unlinkedTracks[0]->SetPan(-1.0f);
859 unlinkedTracks[1]->SetPan(1.0f);
862 for (
const auto track : unlinkedTracks) {
866 if (view.GetHeight() < view.GetMinimizedHeight())
867 view.SetExpandedHeight(view.GetMinimizedHeight());
868 totalHeight += view.GetHeight();
872 int averageHeight = totalHeight / nChannels;
874 for (
const auto track : unlinkedTracks)
890 XO(
"Swap Channels"));
919 XO(
"Split to Mono"));
930 {
wxT(
"/SubViews/Extra"),
wxT(
"WaveColor,SpectrogramSettings")},
944#include "../../../../widgets/ASlider.h"
945#include "../../../ui/CommonTrackInfo.h"
946#include "../../../../TrackPanelDrawingContext.h"
953 (
const wxRect &sliderRect,
const WaveTrack *t,
bool captured, wxWindow*),
954 wxDC *dc,
const wxRect &rect,
const Track *pTrack,
956 bool captured,
bool highlight )
958 wxRect sliderRect = rect;
960 auto wt =
static_cast<const WaveTrack*
>( pTrack );
961 Selector( sliderRect, wt, captured, pParent )->OnPaint(*dc, highlight);
966 const wxRect &rect,
const Track *pTrack )
969 auto dc = &context.
dc;
970 bool hit = target && target->GetTrack().get() == pTrack;
971 bool captured = hit && target->IsDragging();
978 pParent, captured, hit);
983 const wxRect &rect,
const Track *pTrack )
986 auto dc = &context.
dc;
987 bool hit = target && target->GetTrack().get() == pTrack;
990 bool captured = hit && target->IsDragging();
997 pParent, captured, hit);
1024 dest.y = rect.y + results.first;
1025 dest.height = results.second;
1033 dest.y = rect.y + results.first;
1034 dest.height = results.second;
1049std::unique_ptr<LWSlider>
1067(
const wxRect &sliderRect,
const WaveTrack *t,
bool captured, wxWindow *pParent)
1069 static std::once_flag
flag;
1073 wxPoint pos = sliderRect.GetPosition();
1074 float volume = t ? t->
GetVolume() : 1.0;
1082 slider->SetParent( pParent );
1095 gVolume = std::make_unique<LWSlider>(
nullptr,
XO(
"Volume"),
1096 wxPoint(sliderRect.x, sliderRect.y),
1097 wxSize(sliderRect.width, sliderRect.height),
1099 gVolume->SetDefaultValue(defPos);
1102 wxPoint(sliderRect.x, sliderRect.y),
1103 wxSize(sliderRect.width, sliderRect.height),
1112 auto rect = panel.
FindRect( controls );
1115 return PanSlider( sliderRect, &wt,
false, &panel );
1119(
const wxRect &sliderRect,
const WaveTrack *t,
bool captured, wxWindow *pParent)
1121 static std::once_flag
flag;
1125 wxPoint pos = sliderRect.GetPosition();
1126 float pan = t ? t->
GetPan() : 0.0;
1134 slider->SetParent( pParent );
1147 gPan = std::make_unique<LWSlider>(
nullptr,
XO(
"Pan"),
1148 wxPoint(sliderRect.x, sliderRect.y),
1149 wxSize(sliderRect.width, sliderRect.height),
1151 gPan->SetDefaultValue(defPos);
1154 wxPoint(sliderRect.x, sliderRect.y),
1155 wxSize(sliderRect.width, sliderRect.height),
1163 return std::make_shared<WaveTrackControls>( track.
SharedPointer() );
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
std::shared_ptr< UIHandle > UIHandlePtr
std::vector< TrackInfo::TCPLine > TCPLines
XXO("&Cut/Copy/Paste Toolbar")
Track::Holder 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, per-track real-time effects,...
wxFrame * FindProjectFrame(AudacityProject *project)
Get a pointer to the window associated with a project, or null if the given pointer is null,...
An AudacityException with no visible message.
DEFINE_ATTACHED_VIRTUAL_OVERRIDE(DoGetWaveTrackControls)
AppendCheckItem("8000", OnRate8ID, XXO("8000 Hz"), POPUP_MENU_FN(OnRateChange), fn)
Append(Adapt< My >([](My &table) { return(WaveChannelSubViews::numFactories() > 1) ? std::make_unique< Entry >("MultiView", Entry::CheckItem, OnMultiViewID, XXO("&Multi-view"), POPUP_MENU_FN(OnMultiView), table, [](PopupMenuHandler &handler, wxMenu &menu, int id){ auto &table=static_cast< WaveTrackMenuTable & >(handler);auto &track=table.FindWaveTrack();const auto &view=WaveChannelView::GetFirst(track);menu.Check(id, view.GetMultiView());}) :nullptr;}))
static std::vector< WaveChannelSubViewType > AllTypes()
TrackInfo::TCPLine TCPLine
static const auto enableSplitStereo
static int gRates[nRates]
WaveTrackTCPLines waveTrackTCPLines
AppendRadioItem("16Bit", On16BitID, GetSampleFormatStr(int16Sample), POPUP_MENU_FN(OnFormatChange), fn)
AppendItem("MakeStereo", OnMergeStereoID, XXO("Ma&ke Stereo Track"), POPUP_MENU_FN(OnMergeStereo), [](PopupMenuHandler &handler, wxMenu &menu, int id){ bool canMakeStereo=!isUnsafe(handler) &&isMono(handler);if(canMakeStereo) { AudacityProject &project=static_cast< WaveTrackMenuTable & >(handler).mpData->project;auto &tracks=TrackList::Get(project);auto &table=static_cast< WaveTrackMenuTable & >(handler);auto &track=table.FindWaveTrack();auto next= *++tracks.Find(&track);canMakeStereo=(next &&next->NChannels()==1 &&track_cast< WaveTrack * >(next));} menu.Enable(id, canMakeStereo);})
WaveTrackPopupMenuTable & GetWaveTrackMenuTable()
static const auto MenuPathStart
static const auto isUnsafe
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Formerly part of TrackPanel, this abstract base class has no special knowledge of Track objects and i...
wxRect FindRect(const TrackPanelCell &cell)
static ChannelView & Get(Channel &channel)
bool GetMinimized() const
void SetExpandedHeight(int height)
static size_t numFactories()
How many static factories have been registered with this specialization of Site.
virtual std::vector< UIHandlePtr > HitTest(const TrackPanelMouseState &state, const AudacityProject *) override=0
std::shared_ptr< Track > FindTrack()
Lightweight version of ASlider. In other words it does not have a window permanently associated with ...
Subscription Subscribe(Callback callback)
Connect a callback to the Publisher; later-connected are called earlier.
static UIHandlePtr HitTest(std::weak_ptr< PanSliderHandle > &holder, const wxMouseState &state, const wxRect &rect, const std::shared_ptr< Track > &pTrack)
static const TCPLines & StaticWaveTCPLines()
bool IsAudioActive() const
static ProjectAudioIO & Get(AudacityProject &project)
void PushState(const TranslatableString &desc, const TranslatableString &shortDesc)
void ModifyState(bool bWantsAutoSave)
static ProjectHistory & Get(AudacityProject &project)
static RealtimeEffectList & Get(AudacityProject &project)
size_t GetStatesCount() const noexcept
static RealtimeEffectManager & Get(AudacityProject &project)
bool IsActive() const noexcept
To be called only from main thread.
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
static TrackIterRange< Track > Group(Track &track)
bool IsSyncLocked() const
static SyncLockState & Get(AudacityProject &project)
static TrackArtist * Get(TrackPanelDrawingContext &)
static TrackControls & Get(Track &track)
Abstract base class for an object holding data associated with points on a time axis.
std::shared_ptr< Subclass > SharedPointer()
const wxString & GetName() const
Name is always the same for all channels of a group.
static TrackList & Get(AudacityProject &project)
Can be thrown when user cancels operations, as with a progress dialog. Delayed handler does nothing.
static UIHandlePtr HitTest(std::weak_ptr< VolumeSliderHandle > &holder, const wxMouseState &state, const wxRect &rect, const std::shared_ptr< Track > &pTrack)
void SetDisplay(Display display, bool exclusive=true)
static WaveChannelView & GetFirst(WaveTrack &wt)
Get the view of the first channel.
PopupMenuTable * GetMenuExtension(Track *pTrack) override
static void GetVolumeRect(const wxRect &rect, wxRect &dest)
std::weak_ptr< MuteButtonHandle > mMuteHandle
static unsigned DefaultWaveTrackHeight()
std::weak_ptr< VolumeSliderHandle > mVolumeHandle
~WaveTrackControls() override
std::weak_ptr< PanSliderHandle > mPanHandle
static void GetPanRect(const wxRect &rect, wxRect &dest)
std::weak_ptr< EffectsButtonHandle > mEffectsHandle
const TCPLines & GetTCPLines() const override
static LWSlider * VolumeSlider(CellularPanel &panel, const WaveTrack &wt)
static LWSlider * PanSlider(CellularPanel &panel, const WaveTrack &wt)
std::weak_ptr< SoloButtonHandle > mSoloHandle
static void ReCreatePanSlider(struct ThemeChangeMessage)
std::vector< UIHandlePtr > HitTest(const TrackPanelMouseState &state, const AudacityProject *pProject) override
static void ReCreateVolumeSlider(struct ThemeChangeMessage)
static WaveTrackFactory & Get(AudacityProject &project)
A Track that contains audio waveform data.
void SetRate(double newRate)
!brief Sets the new rate for the track without resampling it
std::vector< Holder > SplitChannels()
sampleFormat GetSampleFormat() const override
void SetPan(float newPan)
double GetEndTime() const override
Implement WideSampleSequence.
double GetRate() const override
size_t NChannels() const override
A constant property.
auto GetChannel(size_t iChannel)
Positions or offsets within audio files need a wide type.
Extend wxArrayString with move operations and construction and insertion fromstd::initializer_list.
void SetName(const TranslatableString &title)
MessageBoxResult ShowMessageBox(const TranslatableString &message, MessageBoxOptions options={})
Show a modal message box with either Ok or Yes and No, and optionally Cancel.
AUDACITY_DLL_API void GetSliderHorizontalBounds(const wxRect &rect, wxRect &dest)
static constexpr auto Margin
AUDACITY_DLL_API unsigned DefaultTrackHeight(const TCPLines &topLines)
Namespace containing an enum 'what to do on a refresh?'.
AUDACITY_DLL_API std::pair< int, int > CalcItemY(const TCPLines &lines, unsigned iItem)
WAVE_TRACK_API sampleCount GetSequenceSamplesCount(const WaveTrack &track)
static float findValue(const float *spectrum, float bin0, float bin1, unsigned nBins, bool autocorrelation, int gain, int range)
std::unique_ptr< LWSlider > gVolumeCaptured
void VolumeSliderDrawFunction(TrackPanelDrawingContext &context, const wxRect &rect, const Track *pTrack)
void SliderDrawFunction(LWSlider *(*Selector)(const wxRect &sliderRect, const WaveTrack *t, bool captured, wxWindow *), wxDC *dc, const wxRect &rect, const Track *pTrack, wxWindow *pParent, bool captured, bool highlight)
std::unique_ptr< LWSlider > gPanCaptured
std::function< int(WaveTrack &) > ValueFinder
std::unique_ptr< LWSlider > gVolume
void PanSliderDrawFunction(TrackPanelDrawingContext &context, const wxRect &rect, const Track *pTrack)
PopupMenuTableEntry::InitFunction initFn(const ValueFinder &findValue)
std::unique_ptr< LWSlider > gPan
AuthorizationHandler handler
const char * end(const char *str) noexcept
const char * begin(const char *str) noexcept
For defining overrides of the method.
MessageBoxOptions && ButtonStyle(Button style) &&
Immutable structure is an argument to Mixer's constructor.
std::optional< PreferredSystemAppearance > appearance
Range between two TrackIters, usable in range-for statements, and with Visit member functions.
static const std::vector< WaveChannelSubViewType > & All()
Discover all registered types.