4#include <wx/stattext.h>
7#include <wx/textctrl.h>
8#include <wx/radiobut.h>
10#include <wx/wupdlock.h>
24#if wxUSE_ACCESSIBILITY
68 CustomSampleRateID = wxID_HIGHEST
72 :
wxDialogWrapper(parent, wxID_ANY,
XO(
"Custom Sample Rate"), wxDefaultPosition, {-1, 160})
73 , mSampleRate(defaultSampleRate)
77 S.StartHorizontalLay(wxEXPAND);
79 S.StartMultiColumn(2, wxALIGN_CENTER_VERTICAL);
81 S.Id(CustomSampleRateID).AddNumericTextBox(
XO(
"New sample rate (Hz):"), wxString::Format(
"%d", mSampleRate), 0);
87 S.AddStandardButtons();
100 if(event.GetString().ToLong(&rate))
101 mSampleRate =
static_cast<int>(rate);
114 EVT_TEXT(CustomSampleRateID, CustomSampleRateDialog::OnSampleRateChange)
137 , mMonoStereoMode(monoStereoMode)
141 PopulateOrExchange(
S);
153 auto formatInfo = plugin->GetFormatInfo(formatIndex);
154 formats.push_back(formatInfo.description);
159 S.StartMultiColumn(3, wxEXPAND);
167 mFolder =
S.AddTextBox(
XO(
"Fo&lder:"), {}, 0);
176 S.StartStatic(
XO(
"Audio options"));
180 if(
auto prompt =
S.AddPrompt(
XO(
"Channels")))
181 prompt->SetMinSize({140, -1});
183 S.StartHorizontalLay(wxALIGN_LEFT);
187 const int channels = 2;
197 .Name(
XO(
"Configure custom mapping"))
198 .AddButton(
XO(
"Configure"));
199#if wxUSE_ACCESSIBILITY
204 S.EndHorizontalLay();
208 if(
auto prompt =
S.AddPrompt(
XO(
"Sample &Rate")))
209 prompt->SetMinSize({140, -1});
211 S.StartHorizontalLay(wxALIGN_LEFT);
215 S.EndHorizontalLay();
235 mFolder->SetValue(filename.GetPath());
236 mFullName->SetValue(filename.GetFullName());
239 auto selectedFormatIndex = 0;
245 if(plugin->GetFormatInfo(formatIndex).format.IsSameAs(
format))
247 selectedFormatIndex = counter;
254 if(mixerSpec !=
nullptr)
262 int numChannels = channels;
266 const auto waveTracks =
270 for(
const auto track : waveTracks)
272 if(track->NChannels() >= 2 || track->GetPan() != .0f)
280 mMono->SetValue(
true);
285 mFormat->SetSelection(selectedFormatIndex);
289 if(!parameters.empty())
313 mMono->SetValue(
true);
356 return mMono->GetValue() ? 1 : 2;
370 if(formatInfo.extensions.empty())
374 filename.SetFullName(
mFullName->GetValue());
375 const auto desiredExt = filename.GetExt().Trim();
380 if(wxRegEx{R
"(^[^ ]+$)"}.Matches(desiredExt))
382 auto it = std::find_if(
383 formatInfo.extensions.begin(),
384 formatInfo.extensions.end(),
387 [&](
const auto& ext) { return desiredExt.IsSameAs(ext, false); });
389 if(it == formatInfo.extensions.end())
390 it = formatInfo.extensions.begin();
392 if(!it->empty() && !it->IsSameAs(filename.GetExt()))
394 filename.SetExt(*it);
395 mFullName->SetValue(filename.GetFullName());
398 else if(!formatInfo.extensions.front().empty())
400 auto fullname = filename.GetFullName();
401 if(!fullname.EndsWith(
"."))
402 fullname.Append(
".");
403 fullname.Append(formatInfo.extensions.front());
404 filename.SetFullName(fullname);
405 mFullName->SetValue(filename.GetFullName());
427 const auto clientData =
event.GetClientData();
428 if(clientData ==
nullptr)
431 if(dialog.ShowModal() == wxID_OK &&
432 dialog.GetSampleRate() > 0)
439 mSampleRate = *
reinterpret_cast<const int*
>(&clientData);
448 const auto formatInfo = plugin->GetFormatInfo(formatIndex);
449 fileTypes.emplace_back(formatInfo.description, formatInfo.extensions);
451 wxFileDialog fd(
this,
_(
"Choose a location to save the exported files"),
456 fd.SetFilterIndex(
mFormat->GetSelection());
458 if(fd.ShowModal() == wxID_OK)
460 wxFileName filepath (fd.GetPath());
461 mFolder->SetValue(filepath.GetPath());
462 mFullName->SetValue(filepath.GetFullName());
463 const auto selectedFormat = fd.GetFilterIndex();
464 if(selectedFormat !=
mFormat->GetSelection())
466 mFormat->SetSelection(selectedFormat);
484 auto mixerSpec = std::make_unique<MixerOptions::Downmix>(*
mMixerSpec);
490 XO(
"Advanced Mixing Options"));
491 if(md.ShowModal() == wxID_OK)
502 auto formatCounter = 0;
506 if(formatCounter != index)
523 mOptionsHandler = std::make_unique<ExportOptionsHandler>(
S, *plugin, formatIndex);
526 const auto formatInfo = plugin->GetFormatInfo(formatIndex);
533 wxPostEvent(GetParent(), wxCommandEvent { AUDACITY_EXPORT_FORMAT_CHANGE_EVENT, GetId() });
558 if(maxChannels < 2 && mStereo->GetValue())
559 mMono->SetValue(
true);
560 mStereo->Enable(maxChannels > 1);
563 const auto mixerMaxChannels = std::clamp(
576 mMixerSpec = std::make_unique<MixerOptions::Downmix>(
577 waveTracks.sum([](
const auto track) { return track->NChannels(); }),
586 std::sort(availableRates.begin(), availableRates.end());
588 const auto* rates = availableRates.empty() ? &
DefaultRates : &availableRates;
594 int selectedItemIndex = 0;
598 int preferredRate = rates->back();
599 int preferredItemIndex = rates->size() - 1;
600 for(
auto rate : *rates)
602 *
reinterpret_cast<int*
>(&clientData) = rate;
603 const auto itemIndex =
605 XO(
"%d Hz").Format(rate).Translation(),
610 selectedItemIndex = itemIndex;
614 preferredItemIndex = itemIndex;
615 preferredRate = rate;
623 *
reinterpret_cast<int*
>(&clientData) = customRate;
626 XO(
"%d Hz (custom)").Format(customRate).Translation(),
631 else if(customRate != 0)
633 auto selectedRate = (*rates)[preferredItemIndex];
635 selectedItemIndex = preferredItemIndex;
637 mRates->SetSelection(selectedItemIndex);
EVT_BUTTON(wxID_NO, DependencyDialog::OnNo) EVT_BUTTON(wxID_YES
wxDEFINE_EVENT(AUDACITY_EXPORT_FORMAT_CHANGE_EVENT, wxCommandEvent)
an object holding per-project preferred sample rate
std::vector< TranslatableString > TranslatableStrings
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
const ExportPlugin * GetPlugin() const
std::unique_ptr< MixerOptions::Downmix > mMixerSpec
void UpdateSampleRateList()
void OnFullNameFocusKill(wxFocusEvent &event)
std::unique_ptr< ExportOptionsHandler > mOptionsHandler
void OnSampleRateChange(wxCommandEvent &event)
const ExportPlugin * mSelectedPlugin
int GetSampleRate() const
~ExportFilePanel() override
AudacityProject & mProject
void SetCustomMappingEnabled(bool enabled)
static constexpr auto MaxExportChannels
MixerOptions::Downmix * GetMixerSpec() const
void ChangeFormat(int index)
void OnFormatChange(wxCommandEvent &event)
wxWindow * mAudioOptionsPanel
wxRadioButton * mCustomMapping
void OnFolderBrowse(wxCommandEvent &event)
void OnChannelsConfigure(wxCommandEvent &event)
std::optional< ExportProcessor::Parameters > GetParameters() const
void OnOptionsHandlerEvent(const ExportOptionsHandlerEvent &e)
Observer::Subscription mOptionsChangeSubscription
void UpdateMaxChannels(unsigned maxChannels)
void Init(const wxFileName &filename, int sampleRate, const wxString &format=wxEmptyString, int channels=0, const ExportProcessor::Parameters ¶meters={}, const MixerOptions::Downmix *mixerSpec=nullptr)
Initializes panel with export settings provided as arguments. Call is required.
void PopulateOrExchange(ShuttleGui &S)
void OnChannelsChange(wxCommandEvent &event)
wxButton * mCustomizeChannels
Dialog for advanced mixing.
std::vector< int > SampleRateList
virtual FormatInfo GetFormatInfo(int index) const =0
Returns FormatInfo structure for given index if it's valid, or a default one. FormatInfo::format isn'...
static ExportPluginRegistry & Get()
std::vector< std::tuple< ExportOptionID, ExportValue > > Parameters
static TrackIterRange< const WaveTrack > FindExportWaveTracks(const TrackList &tracks, bool selectedOnly)
std::vector< FileType > FileTypes
A matrix of booleans, one row per input channel, column per output.
void Reset() noexcept
Breaks the connection (constant time)
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
auto Any() -> TrackIterRange< TrackType >
static TrackList & Get(AudacityProject &project)
A Track that contains audio waveform data.
An alternative to using wxWindowAccessible, which in wxWidgets 3.1.1 contained GetParent() which was ...
int GetSampleRate() const noexcept
CustomSampleRateDialog(wxWindow *parent, int defaultSampleRate=44100)
void OnSampleRateChange(wxCommandEvent &event)
FILES_API wxString FormatWildcard(const FileTypes &fileTypes)
constexpr auto sampleRate
const ExportOptionsEditor::SampleRateList DefaultRates
@ AudioChannelsConfigureID
enum ExportOptionsHandlerEvent::@34 type