Audacity 3.2.0
ExportFFmpegDialogs.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 ExportFFmpegDialogs.cpp
6
7 Audacity(R) is copyright (c) 1999-2010 Audacity Team.
8 License: GPL v2 or later. See License.txt.
9
10 LRN
11
12******************************************************************//***************************************************************//***************************************************************//***************************************************************//***************************************************************//***************************************************************//*******************************************************************/
43
44
45#include "ExportFFmpegDialogs.h"
46
47#include "../FFmpeg.h"
48#include "FFmpegFunctions.h"
49
50#include <wx/app.h>
51#include <wx/checkbox.h>
52#include <wx/choice.h>
53#include <wx/intl.h>
54#include <wx/timer.h>
55#include <wx/string.h>
56#include <wx/textctrl.h>
57#include <wx/listbox.h>
58#include <wx/window.h>
59#include <wx/spinctrl.h>
60#include <wx/combobox.h>
61#include <wx/stattext.h>
62
63#include "../widgets/FileDialog/FileDialog.h"
64
65#include "Mix.h"
66#include "../Tags.h"
67#include "../widgets/AudacityMessageBox.h"
68#include "../widgets/HelpSystem.h"
69
70#include "Export.h"
71#include "FFmpeg.h"
72
73#if defined(USE_FFMPEG)
74
79#define FFMPEG_EXPORT_CTRL_ID_ENTRIES \
80 FFMPEG_EXPORT_CTRL_ID_FIRST_ENTRY(FEFirstID, 20000), \
81 FFMPEG_EXPORT_CTRL_ID_ENTRY(FEFormatID), \
82 FFMPEG_EXPORT_CTRL_ID_ENTRY(FECodecID), \
83 FFMPEG_EXPORT_CTRL_ID_ENTRY(FEBitrateID), \
84 FFMPEG_EXPORT_CTRL_ID_ENTRY(FEQualityID), \
85 FFMPEG_EXPORT_CTRL_ID_ENTRY(FESampleRateID), \
86 FFMPEG_EXPORT_CTRL_ID_ENTRY(FELanguageID), \
87 FFMPEG_EXPORT_CTRL_ID_ENTRY(FETagID), \
88 FFMPEG_EXPORT_CTRL_ID_ENTRY(FECutoffID), \
89 FFMPEG_EXPORT_CTRL_ID_ENTRY(FEFrameSizeID), \
90 FFMPEG_EXPORT_CTRL_ID_ENTRY(FEBufSizeID), \
91 FFMPEG_EXPORT_CTRL_ID_ENTRY(FEProfileID), \
92 FFMPEG_EXPORT_CTRL_ID_ENTRY(FECompLevelID), \
93 FFMPEG_EXPORT_CTRL_ID_ENTRY(FEUseLPCID), \
94 FFMPEG_EXPORT_CTRL_ID_ENTRY(FELPCCoeffsID), \
95 FFMPEG_EXPORT_CTRL_ID_ENTRY(FEMinPredID), \
96 FFMPEG_EXPORT_CTRL_ID_ENTRY(FEMaxPredID), \
97 FFMPEG_EXPORT_CTRL_ID_ENTRY(FEPredOrderID), \
98 FFMPEG_EXPORT_CTRL_ID_ENTRY(FEMinPartOrderID), \
99 FFMPEG_EXPORT_CTRL_ID_ENTRY(FEMaxPartOrderID), \
100 FFMPEG_EXPORT_CTRL_ID_ENTRY(FEMuxRateID), \
101 FFMPEG_EXPORT_CTRL_ID_ENTRY(FEPacketSizeID), \
102 FFMPEG_EXPORT_CTRL_ID_ENTRY(FEBitReservoirID), \
103 FFMPEG_EXPORT_CTRL_ID_ENTRY(FEVariableBlockLenID), \
104 FFMPEG_EXPORT_CTRL_ID_ENTRY(FELastID), \
105 \
106 FFMPEG_EXPORT_CTRL_ID_ENTRY(FEFormatLabelID), \
107 FFMPEG_EXPORT_CTRL_ID_ENTRY(FECodecLabelID), \
108 FFMPEG_EXPORT_CTRL_ID_ENTRY(FEFormatNameID), \
109 FFMPEG_EXPORT_CTRL_ID_ENTRY(FECodecNameID), \
110 FFMPEG_EXPORT_CTRL_ID_ENTRY(FEPresetID), \
111 FFMPEG_EXPORT_CTRL_ID_ENTRY(FESavePresetID), \
112 FFMPEG_EXPORT_CTRL_ID_ENTRY(FELoadPresetID), \
113 FFMPEG_EXPORT_CTRL_ID_ENTRY(FEDeletePresetID), \
114 FFMPEG_EXPORT_CTRL_ID_ENTRY(FEAllFormatsID), \
115 FFMPEG_EXPORT_CTRL_ID_ENTRY(FEAllCodecsID), \
116 FFMPEG_EXPORT_CTRL_ID_ENTRY(FEImportPresetsID), \
117 FFMPEG_EXPORT_CTRL_ID_ENTRY(FEExportPresetsID) \
118
119// First the enumeration
120#define FFMPEG_EXPORT_CTRL_ID_FIRST_ENTRY(name, num) name = num
121#define FFMPEG_EXPORT_CTRL_ID_ENTRY(name) name
122
126
127// Now the string representations
128#undef FFMPEG_EXPORT_CTRL_ID_FIRST_ENTRY
129#define FFMPEG_EXPORT_CTRL_ID_FIRST_ENTRY(name, num) wxT(#name)
130#undef FFMPEG_EXPORT_CTRL_ID_ENTRY
131#define FFMPEG_EXPORT_CTRL_ID_ENTRY(name) wxT(#name)
132static const wxChar *FFmpegExportCtrlIDNames[] = {
134};
135
136#undef FFMPEG_EXPORT_CTRL_ID_ENTRIES
137#undef FFMPEG_EXPORT_CTRL_ID_ENTRY
138#undef FFMPEG_EXPORT_CTRL_ID_FIRST_ENTRY
139
140//----------------------------------------------------------------------------
141// ExportFFmpegAC3Options Class
142//----------------------------------------------------------------------------
143
144namespace
145{
146
147// i18n-hint kbps abbreviates "thousands of bits per second"
148inline TranslatableString n_kbps(int n) { return XO("%d kbps").Format( n ); }
149
151 n_kbps( 32 ),
152 n_kbps( 40 ),
153 n_kbps( 48 ),
154 n_kbps( 56 ),
155 n_kbps( 64 ),
156 n_kbps( 80 ),
157 n_kbps( 96 ),
158 n_kbps( 112 ),
159 n_kbps( 128 ),
160 n_kbps( 160 ),
161 n_kbps( 192 ),
162 n_kbps( 224 ),
163 n_kbps( 256 ),
164 n_kbps( 320 ),
165 n_kbps( 384 ),
166 n_kbps( 448 ),
167 n_kbps( 512 ),
168 n_kbps( 576 ),
169 n_kbps( 640 ),
170};
171
172const std::vector< int > AC3BitRateValues{
173 32000,
174 40000,
175 48000,
176 56000,
177 64000,
178 80000,
179 96000,
180 112000,
181 128000,
182 160000,
183 192000,
184 224000,
185 256000,
186 320000,
187 384000,
188 448000,
189 512000,
190 576000,
191 640000,
192};
193
194}
195
196const int ExportFFmpegAC3Options::iAC3SampleRates[] = { 32000, 44100, 48000, 0 };
197
199: wxPanelWrapper(parent, wxID_ANY)
200{
203
205}
206
208{
210}
211
215{
216 S.StartVerticalLay();
217 {
218 S.StartHorizontalLay(wxCENTER);
219 {
220 S.StartMultiColumn(2, wxCENTER);
221 {
222 S.TieNumberAsChoice(
223 XXO("Bit Rate:"),
224 {wxT("/FileFormats/AC3BitRate"),
225 160000},
228 );
229 }
230 S.EndMultiColumn();
231 }
232 S.EndHorizontalLay();
233 }
234 S.EndVerticalLay();
235}
236
240{
241 return true;
242}
243
247{
250
251 gPrefs->Flush();
252
253 return true;
254}
255
256//----------------------------------------------------------------------------
257// ExportFFmpegAACOptions Class
258//----------------------------------------------------------------------------
259
261: wxPanelWrapper(parent, wxID_ANY)
262{
265
267}
268
270{
272}
273
277{
278 S.StartVerticalLay();
279 {
280 S.StartHorizontalLay(wxEXPAND);
281 {
282 S.SetSizerProportion(1);
283 S.StartMultiColumn(2, wxCENTER);
284 {
285 S.SetStretchyCol(1);
286 S.Prop(1).TieSlider(
287 XXO("Quality (kbps):"),
288 {wxT("/FileFormats/AACQuality"), 160},320, 98);
289 }
290 S.EndMultiColumn();
291 }
292 S.EndHorizontalLay();
293 }
294 S.EndVerticalLay();
295}
296
300{
301 return true;
302}
303
307{
310
311 gPrefs->Flush();
312
313 return true;
314}
315
316//----------------------------------------------------------------------------
317// ExportFFmpegAMRNBOptions Class
318//----------------------------------------------------------------------------
319
320namespace {
321
322// i18n-hint kbps abbreviates "thousands of bits per second"
323inline TranslatableString f_kbps( double d ) { return XO("%.2f kbps").Format( d ); }
324
328{
329 f_kbps( 4.75 ),
330 f_kbps( 5.15 ),
331 f_kbps( 5.90 ),
332 f_kbps( 6.70 ),
333 f_kbps( 7.40 ),
334 f_kbps( 7.95 ),
335 f_kbps( 10.20 ),
336 f_kbps( 12.20 ),
337};
338
339const std::vector< int > AMRNBBitRateValues
340{
341 4750,
342 5150,
343 5900,
344 6700,
345 7400,
346 7950,
347 10200,
348 12200,
349};
350
351}
352
354: wxPanelWrapper(parent, wxID_ANY)
355{
358
360}
361
363{
365}
366
370{
371 S.StartVerticalLay();
372 {
373 S.StartHorizontalLay(wxCENTER);
374 {
375 S.StartMultiColumn(2, wxCENTER);
376 {
377 S.TieNumberAsChoice(
378 XXO("Bit Rate:"),
379 {wxT("/FileFormats/AMRNBBitRate"),
380 12200},
383 );
384 }
385 S.EndMultiColumn();
386 }
387 S.EndHorizontalLay();
388 }
389 S.EndVerticalLay();
390}
391
395{
396 return true;
397}
398
402{
405
406 gPrefs->Flush();
407
408 return true;
409}
410
411//----------------------------------------------------------------------------
412// ExportFFmpegOPUSOptions Class
413//----------------------------------------------------------------------------
414
415namespace {
416
419 {
420 wxT("/FileFormats/OPUSBitrate"),
421 {
422 ByColumns,
423 {
424 n_kbps( 6 ),
425 n_kbps( 8 ),
426 n_kbps( 16 ),
427 n_kbps( 24 ),
428 n_kbps( 32 ),
429 n_kbps( 40 ),
430 n_kbps( 48 ),
431 n_kbps( 64 ),
432 n_kbps( 80 ),
433 n_kbps( 96 ),
434 n_kbps( 128 ),
435 n_kbps( 160 ),
436 n_kbps( 192 ),
437 n_kbps( 256 ),
438 },
439 {
440 wxT("6000"),
441 wxT("8000"),
442 wxT("16000"),
443 wxT("24000"),
444 wxT("32000"),
445 wxT("40000"),
446 wxT("48000"),
447 wxT("64000"),
448 wxT("80000"),
449 wxT("96000"),
450 wxT("128000"),
451 wxT("160000"),
452 wxT("192000"),
453 wxT("256000"),
454 }
455 },
456 7 // "128 kbps"
457 };
458
460 {
461 wxT("/FileFormats/OPUSCompression"),
462 {
463 ByColumns,
464 {
465 XO("0"),
466 XO("1"),
467 XO("2"),
468 XO("3"),
469 XO("4"),
470 XO("5"),
471 XO("6"),
472 XO("7"),
473 XO("8"),
474 XO("9"),
475 XO("10"),
476 },
477 {
478 wxT("0"),
479 wxT("1"),
480 wxT("2"),
481 wxT("3"),
482 wxT("4"),
483 wxT("5"),
484 wxT("6"),
485 wxT("7"),
486 wxT("8"),
487 wxT("9"),
488 wxT("10"),
489 }
490 },
491 10 // "10"
492 };
493
494
496 {
497 wxT("/FileFormats/OPUSVbrMode"),
498 {
499 ByColumns,
500 {
501 XO("Off"),
502 XO("On"),
503 XO("Constrained"),
504 },
505 {
506 wxT("off"),
507 wxT("on"),
508 wxT("constrained"),
509 }
510 },
511 1 // "On"
512 };
513
515 {
516 wxT("/FileFormats/OPUSApplication"),
517 {
518 ByColumns,
519 {
520 XO("VOIP"),
521 XO("Audio"),
522 XO("Low Delay"),
523 },
524 {
525 wxT("voip"),
526 wxT("audio"),
527 wxT("lowdelay"),
528 }
529 },
530 1 // "Audio"
531 };
532
534 {
535 wxT("/FileFormats/OPUSFrameDuration"),
536 {
537 ByColumns,
538 {
539 XO("2.5 ms"),
540 XO("5 ms"),
541 XO("10 ms"),
542 XO("20 ms"),
543 XO("40 ms"),
544 XO("60 ms"),
545 },
546 {
547 wxT("2.5"),
548 wxT("5"),
549 wxT("10"),
550 wxT("20"),
551 wxT("40"),
552 wxT("60"),
553 }
554 },
555 3 // "20"
556 };
557
559 {
560 wxT("/FileFormats/OPUSCutoff"),
561 {
562 ByColumns,
563 {
564 XO("Disabled"),
565 XO("Narrowband"),
566 XO("Mediumband"),
567 XO("Wideband"),
568 XO("Super Wideband"),
569 XO("Fullband"),
570 },
571 {
572 wxT("0"),
573 wxT("4000"),
574 wxT("6000"),
575 wxT("8000"),
576 wxT("12000"),
577 wxT("20000"),
578 }
579 },
580 0 // "Disabled"
581 };
582}
583
585: wxPanelWrapper(parent, wxID_ANY)
586{
589
591}
592
594{
596}
597
601{
602 S.SetSizerProportion(1);
603 S.SetBorder(4);
604 S.StartVerticalLay();
605 {
606 S.StartHorizontalLay(wxCENTER);
607 {
608 S.StartMultiColumn(2, wxCENTER);
609 {
610 S.StartMultiColumn(2, wxCENTER);
611 {
612 S.TieChoice(
613 XXO("Bit Rate:"),
615
616 S.TieChoice(
617 XXO("Compression"),
619
620 S.TieChoice(
621 XXO("Frame Duration:"),
623 }
624 S.EndMultiColumn();
625
626 S.StartMultiColumn(2, wxCENTER);
627 {
628 S.TieChoice(
629 XXO("Vbr Mode:"),
631
632 S.TieChoice(
633 XXO("Application:"),
635
636 S.TieChoice(
637 XXO("Cutoff:"),
638 OPUSCutoff);
639
640 }
641 S.EndMultiColumn();
642 }
643 S.EndMultiColumn();
644 }
645 S.EndHorizontalLay();
646 }
647 S.EndVerticalLay();
648}
649
653{
654 return true;
655}
656
660{
663
664 gPrefs->Flush();
665
666 return true;
667}
668
669//----------------------------------------------------------------------------
670// ExportFFmpegWMAOptions Class
671//----------------------------------------------------------------------------
672
674{ 8000, 11025, 16000, 22050, 44100, 0};
675
676namespace {
677
680{
681 n_kbps(24),
682 n_kbps(32),
683 n_kbps(40),
684 n_kbps(48),
685 n_kbps(64),
686 n_kbps(80),
687 n_kbps(96),
688 n_kbps(128),
689 n_kbps(160),
690 n_kbps(192),
691 n_kbps(256),
692 n_kbps(320),
693};
694
695const std::vector< int > WMABitRateValues{
696 24000,
697 32000,
698 40000,
699 48000,
700 64000,
701 80000,
702 96000,
703 128000,
704 160000,
705 192000,
706 256000,
707 320000,
708};
709
710}
711
713: wxPanelWrapper(parent, wxID_ANY)
714{
717
719}
720
722{
724}
725
729{
730 S.StartVerticalLay();
731 {
732 S.StartHorizontalLay(wxCENTER);
733 {
734 S.StartMultiColumn(2, wxCENTER);
735 {
736 S.TieNumberAsChoice(
737 XXO("Bit Rate:"),
738 {wxT("/FileFormats/WMABitRate"),
739 128000},
742 );
743 }
744 S.EndMultiColumn();
745 }
746 S.EndHorizontalLay();
747 }
748 S.EndVerticalLay();
749}
750
754{
755 return true;
756}
757
761{
764
765 gPrefs->Flush();
766
767 return true;
768}
769
770//----------------------------------------------------------------------------
771// ExportFFmpegCustomOptions Class
772//----------------------------------------------------------------------------
773
774#define OpenID 9000
775
779
781: wxPanelWrapper(parent, wxID_ANY),
782 mFormat(NULL),
783 mCodec(NULL)
784{
786 PopulateOrExchange(S);
787
788 TransferDataToWindow();
789}
790
792{
794}
795
799{
800 S.StartHorizontalLay(wxCENTER);
801 {
802 S.StartVerticalLay(wxCENTER, 0);
803 {
804 S.Id(OpenID).AddButton(XXO("Open custom FFmpeg format options"));
805 S.StartMultiColumn(2, wxCENTER);
806 {
807 S.AddPrompt(XXO("Current Format:"));
808 mFormat = S.Style(wxTE_READONLY).AddTextBox({}, wxT(""), 25);
809 S.AddPrompt(XXO("Current Codec:"));
810 mCodec = S.Style(wxTE_READONLY).AddTextBox({}, wxT(""), 25);
811 }
812 S.EndMultiColumn();
813 }
814 S.EndHorizontalLay();
815 }
816 S.EndHorizontalLay();
817}
818
822{
823 if (mFormat)
824 {
825 mFormat->SetValue(gPrefs->Read(wxT("/FileFormats/FFmpegFormat"), wxT("")));
826 mCodec->SetValue(gPrefs->Read(wxT("/FileFormats/FFmpegCodec"), wxT("")));
827 }
828 return true;
829}
830
834{
835 return true;
836}
837
840void ExportFFmpegCustomOptions::OnOpen(wxCommandEvent & WXUNUSED(evt))
841{
842 // Show "Locate FFmpeg" dialog
843 auto ffmpeg = FFmpegFunctions::Load();
844 if (!ffmpeg)
845 {
847 if (!LoadFFmpeg(true))
848 {
849 return;
850 }
851 }
852
853#ifdef __WXMAC__
854 // Bug 2077 Must be a parent window on OSX or we will appear behind.
855 auto pWin = wxGetTopLevelParent( this );
856#else
857 // Use GetTopWindow on windows as there is no hWnd with top level parent.
858 auto pWin = wxTheApp->GetTopWindow();
859#endif
860
861 ExportFFmpegOptions od(pWin);
862 od.ShowModal();
863
865}
866
868{
869 mControlState.resize(FELastID - FEFirstID);
870}
871
873{
874}
875
877{
878 mPreset = NULL;
879 mAbortImport = false;
880
881 XMLFileReader xmlfile;
882 wxFileName xmlFileName(FileNames::DataDir(), wxT("ffmpeg_presets.xml"));
883 xmlfile.Parse(this,xmlFileName.GetFullPath());
884}
885
887{
888 // We're in a destructor! Don't let exceptions out!
889 GuardedCall( [&] {
890 wxFileName xmlFileName{ FileNames::DataDir(), wxT("ffmpeg_presets.xml") };
891 XMLFileWriter writer{
892 xmlFileName.GetFullPath(), XO("Error Saving FFmpeg Presets") };
893 WriteXMLHeader(writer);
894 WriteXML(writer);
895 writer.Commit();
896 } );
897}
898
899void FFmpegPresets::ImportPresets(wxString &filename)
900{
901 mPreset = NULL;
902 mAbortImport = false;
903
904 FFmpegPresetMap savePresets = mPresets;
905
906 XMLFileReader xmlfile;
907 bool success = xmlfile.Parse(this,filename);
908 if (!success || mAbortImport) {
909 mPresets = savePresets;
910 }
911}
912
913void FFmpegPresets::ExportPresets(wxString &filename)
914{
915 GuardedCall( [&] {
916 XMLFileWriter writer{ filename, XO("Error Saving FFmpeg Presets") };
917 WriteXMLHeader(writer);
918 WriteXML(writer);
919 writer.Commit();
920 } );
921}
922
923void FFmpegPresets::GetPresetList(wxArrayString &list)
924{
925 list.clear();
926 FFmpegPresetMap::iterator iter;
927 for (iter = mPresets.begin(); iter != mPresets.end(); ++iter)
928 {
929 list.push_back(iter->second.mPresetName);
930 }
931
932 std::sort( list.begin(), list.end() );
933}
934
936{
937 FFmpegPresetMap::iterator iter = mPresets.find(name);
938 if (iter != mPresets.end())
939 {
940 mPresets.erase(iter);
941 }
942}
943
945{
946 FFmpegPresetMap::iterator iter = mPresets.find(name);
947 if (iter != mPresets.end())
948 {
949 return &iter->second;
950 }
951
952 return NULL;
953}
954
955// return false if overwrite was not allowed.
957{
959 if (preset)
960 {
961 auto query = XO("Overwrite preset '%s'?").Format(name);
962 int action = AudacityMessageBox(
963 query,
964 XO("Confirm Overwrite"),
965 wxYES_NO | wxCENTRE);
966 if (action == wxNO) return false;
967 }
968 return true;
969}
970
971
973{
974 wxString format;
975 wxString codec;
977
978 {
979 wxWindow *wnd;
980 wxListBox *lb;
981
982 wnd = dynamic_cast<wxWindow*>(parent)->FindWindowById(FEFormatID,parent);
983 lb = dynamic_cast<wxListBox*>(wnd);
984 if (lb->GetSelection() < 0)
985 {
986 AudacityMessageBox( XO("Please select format before saving a profile") );
987 return false;
988 }
989 format = lb->GetStringSelection();
990
991 wnd = dynamic_cast<wxWindow*>(parent)->FindWindowById(FECodecID,parent);
992 lb = dynamic_cast<wxListBox*>(wnd);
993 if (lb->GetSelection() < 0)
994 {
995 /* i18n-hint: "codec" is short for a "coder-decoder" algorithm */
996 AudacityMessageBox( XO("Please select codec before saving a profile") );
997 return false;
998 }
999 codec = lb->GetStringSelection();
1000 }
1001
1002 preset = &mPresets[name];
1003 preset->mPresetName = name;
1004
1005 wxSpinCtrl *sc;
1006 wxTextCtrl *tc;
1007 wxCheckBox *cb;
1008 wxChoice *ch;
1009
1010 for (int id = FEFirstID; id < FELastID; id++)
1011 {
1012 wxWindow *wnd = dynamic_cast<wxWindow*>(parent)->FindWindowById(id,parent);
1013 if (wnd != NULL)
1014 {
1015 switch(id)
1016 {
1017 case FEFormatID:
1018 preset->mControlState[id - FEFirstID] = format;
1019 break;
1020 case FECodecID:
1021 preset->mControlState[id - FEFirstID] = codec;
1022 break;
1023 // Spin control
1024 case FEBitrateID:
1025 case FEQualityID:
1026 case FESampleRateID:
1027 case FECutoffID:
1028 case FEFrameSizeID:
1029 case FEBufSizeID:
1030 case FECompLevelID:
1031 case FELPCCoeffsID:
1032 case FEMinPredID:
1033 case FEMaxPredID:
1034 case FEMinPartOrderID:
1035 case FEMaxPartOrderID:
1036 case FEMuxRateID:
1037 case FEPacketSizeID:
1038 sc = dynamic_cast<wxSpinCtrl*>(wnd);
1039 preset->mControlState[id - FEFirstID] = wxString::Format(wxT("%d"),sc->GetValue());
1040 break;
1041 // Text control
1042 case FELanguageID:
1043 case FETagID:
1044 tc = dynamic_cast<wxTextCtrl*>(wnd);
1045 preset->mControlState[id - FEFirstID] = tc->GetValue();
1046 break;
1047 // Choice
1048 case FEProfileID:
1049 case FEPredOrderID:
1050 ch = dynamic_cast<wxChoice*>(wnd);
1051 preset->mControlState[id - FEFirstID] = wxString::Format(wxT("%d"),ch->GetSelection());
1052 break;
1053 // Check box
1054 case FEUseLPCID:
1055 case FEBitReservoirID:
1056 case FEVariableBlockLenID:
1057 cb = dynamic_cast<wxCheckBox*>(wnd);
1058 preset->mControlState[id - FEFirstID] = wxString::Format(wxT("%d"),cb->GetValue());
1059 break;
1060 }
1061 }
1062 }
1063 return true;
1064}
1065
1067{
1069 if (!preset)
1070 {
1071 AudacityMessageBox( XO("Preset '%s' does not exist." ).Format(name));
1072 return;
1073 }
1074
1075 wxListBox *lb;
1076 wxSpinCtrl *sc;
1077 wxTextCtrl *tc;
1078 wxCheckBox *cb;
1079 wxChoice *ch;
1080
1081 for (int id = FEFirstID; id < FELastID; id++)
1082 {
1083 wxWindow *wnd = parent->FindWindowById(id,parent);
1084 if (wnd != NULL)
1085 {
1086 wxString readstr;
1087 long readlong;
1088 bool readbool;
1089 switch(id)
1090 {
1091 // Listbox
1092 case FEFormatID:
1093 case FECodecID:
1094 lb = dynamic_cast<wxListBox*>(wnd);
1095 readstr = preset->mControlState[id - FEFirstID];
1096 readlong = lb->FindString(readstr);
1097 if (readlong > -1) lb->Select(readlong);
1098 break;
1099 // Spin control
1100 case FEBitrateID:
1101 case FEQualityID:
1102 case FESampleRateID:
1103 case FECutoffID:
1104 case FEFrameSizeID:
1105 case FEBufSizeID:
1106 case FECompLevelID:
1107 case FELPCCoeffsID:
1108 case FEMinPredID:
1109 case FEMaxPredID:
1110 case FEMinPartOrderID:
1111 case FEMaxPartOrderID:
1112 case FEMuxRateID:
1113 case FEPacketSizeID:
1114 sc = dynamic_cast<wxSpinCtrl*>(wnd);
1115 preset->mControlState[id - FEFirstID].ToLong(&readlong);
1116 sc->SetValue(readlong);
1117 break;
1118 // Text control
1119 case FELanguageID:
1120 case FETagID:
1121 tc = dynamic_cast<wxTextCtrl*>(wnd);
1122 tc->SetValue(preset->mControlState[id - FEFirstID]);
1123 break;
1124 // Choice
1125 case FEProfileID:
1126 case FEPredOrderID:
1127 ch = dynamic_cast<wxChoice*>(wnd);
1128 preset->mControlState[id - FEFirstID].ToLong(&readlong);
1129 if (readlong > -1) ch->Select(readlong);
1130 break;
1131 // Check box
1132 case FEUseLPCID:
1133 case FEBitReservoirID:
1134 case FEVariableBlockLenID:
1135 cb = dynamic_cast<wxCheckBox*>(wnd);
1136 preset->mControlState[id - FEFirstID].ToLong(&readlong);
1137 if (readlong) readbool = true; else readbool = false;
1138 cb->SetValue(readbool);
1139 break;
1140 }
1141 }
1142 }
1143}
1144
1145bool FFmpegPresets::HandleXMLTag(const std::string_view& tag, const AttributesList &attrs)
1146{
1147 if (mAbortImport)
1148 {
1149 return false;
1150 }
1151
1152 if (tag == "ffmpeg_presets")
1153 {
1154 return true;
1155 }
1156
1157 if (tag == "preset")
1158 {
1159 for (auto pair : attrs)
1160 {
1161 auto attr = pair.first;
1162 auto value = pair.second;
1163
1164 if (attr == "name")
1165 {
1166 wxString strValue = value.ToWString();
1167 mPreset = FindPreset(strValue);
1168
1169 if (mPreset)
1170 {
1171 auto query = XO("Replace preset '%s'?").Format( strValue );
1172 int action = AudacityMessageBox(
1173 query,
1174 XO("Confirm Overwrite"),
1175 wxYES_NO | wxCANCEL | wxCENTRE);
1176 if (action == wxCANCEL)
1177 {
1178 mAbortImport = true;
1179 return false;
1180 }
1181 if (action == wxNO)
1182 {
1183 mPreset = NULL;
1184 return false;
1185 }
1186 *mPreset = FFmpegPreset();
1187 }
1188 else
1189 {
1190 mPreset = &mPresets[strValue];
1191 }
1192
1193 mPreset->mPresetName = strValue;
1194 }
1195 }
1196 return true;
1197 }
1198
1199 if (tag == "setctrlstate" && mPreset)
1200 {
1201 long id = -1;
1202 for (auto pair : attrs)
1203 {
1204 auto attr = pair.first;
1205 auto value = pair.second;
1206
1207 if (attr == "id")
1208 {
1209 for (long i = FEFirstID; i < FELastID; i++)
1210 if (!wxStrcmp(FFmpegExportCtrlIDNames[i - FEFirstID], value.ToWString()))
1211 id = i;
1212 }
1213 else if (attr == "state")
1214 {
1215 if (id > FEFirstID && id < FELastID)
1216 mPreset->mControlState[id - FEFirstID] = value.ToWString();
1217 }
1218 }
1219 return true;
1220 }
1221
1222 return false;
1223}
1224
1226{
1227 if (mAbortImport)
1228 {
1229 return NULL;
1230 }
1231
1232 if (tag == "preset")
1233 {
1234 return this;
1235 }
1236 else if (tag == "setctrlstate")
1237 {
1238 return this;
1239 }
1240 return NULL;
1241}
1242
1244// may throw
1245{
1246 xmlFile.Write(wxT("<?xml "));
1247 xmlFile.Write(wxT("version=\"1.0\" "));
1248 xmlFile.Write(wxT("standalone=\"no\" "));
1249 xmlFile.Write(wxT("?>\n"));
1250
1251 wxString dtdName = wxT("-//audacityffmpegpreset-1.0.0//DTD//EN");
1252 wxString dtdURI =
1253 wxT("http://audacity.sourceforge.net/xml/audacityffmpegpreset-1.0.0.dtd");
1254
1255 xmlFile.Write(wxT("<!DOCTYPE "));
1256 xmlFile.Write(wxT("project "));
1257 xmlFile.Write(wxT("PUBLIC "));
1258 xmlFile.Write(wxT("\"-//audacityffmpegpreset-1.0.0//DTD//EN\" "));
1259 xmlFile.Write(wxT("\"http://audacity.sourceforge.net/xml/audacityffmpegpreset-1.0.0.dtd\" "));
1260 xmlFile.Write(wxT(">\n"));
1261}
1262
1264// may throw
1265{
1266 xmlFile.StartTag(wxT("ffmpeg_presets"));
1267 xmlFile.WriteAttr(wxT("version"),wxT("1.0"));
1268 FFmpegPresetMap::const_iterator iter;
1269 for (iter = mPresets.begin(); iter != mPresets.end(); ++iter)
1270 {
1271 auto preset = &iter->second;
1272 xmlFile.StartTag(wxT("preset"));
1273 xmlFile.WriteAttr(wxT("name"),preset->mPresetName);
1274 for (long i = FEFirstID + 1; i < FELastID; i++)
1275 {
1276 xmlFile.StartTag(wxT("setctrlstate"));
1277 xmlFile.WriteAttr(wxT("id"),wxString(FFmpegExportCtrlIDNames[i - FEFirstID]));
1278 xmlFile.WriteAttr(wxT("state"),preset->mControlState[i - FEFirstID]);
1279 xmlFile.EndTag(wxT("setctrlstate"));
1280 }
1281 xmlFile.EndTag(wxT("preset"));
1282 }
1283 xmlFile.EndTag(wxT("ffmpeg_presets"));
1284}
1285
1286//----------------------------------------------------------------------------
1287// ExportFFmpegOptions Class
1288//----------------------------------------------------------------------------
1289
1290BEGIN_EVENT_TABLE(ExportFFmpegOptions, wxDialogWrapper)
1293 EVT_LISTBOX(FEFormatID,ExportFFmpegOptions::OnFormatList)
1294 EVT_LISTBOX(FECodecID,ExportFFmpegOptions::OnCodecList)
1303
1304
1306CompatibilityEntry ExportFFmpegOptions::CompatibilityList[] =
1307{
1308 { wxT("adts"), AUDACITY_AV_CODEC_ID_AAC },
1309
1310 { wxT("aiff"), AUDACITY_AV_CODEC_ID_PCM_S16BE },
1311 { wxT("aiff"), AUDACITY_AV_CODEC_ID_PCM_S8 },
1312 { wxT("aiff"), AUDACITY_AV_CODEC_ID_PCM_S24BE },
1313 { wxT("aiff"), AUDACITY_AV_CODEC_ID_PCM_S32BE },
1314 { wxT("aiff"), AUDACITY_AV_CODEC_ID_PCM_ALAW },
1315 { wxT("aiff"), AUDACITY_AV_CODEC_ID_PCM_MULAW },
1316 { wxT("aiff"), AUDACITY_AV_CODEC_ID_MACE3 },
1317 { wxT("aiff"), AUDACITY_AV_CODEC_ID_MACE6 },
1318 { wxT("aiff"), AUDACITY_AV_CODEC_ID_GSM },
1319 { wxT("aiff"), AUDACITY_AV_CODEC_ID_ADPCM_G726 },
1320 { wxT("aiff"), AUDACITY_AV_CODEC_ID_PCM_S16LE },
1321 { wxT("aiff"), AUDACITY_AV_CODEC_ID_ADPCM_IMA_QT },
1322 { wxT("aiff"), AUDACITY_AV_CODEC_ID_QDM2 },
1323
1324 { wxT("amr"), AUDACITY_AV_CODEC_ID_AMR_NB },
1325 { wxT("amr"), AUDACITY_AV_CODEC_ID_AMR_WB },
1326
1327 { wxT("asf"), AUDACITY_AV_CODEC_ID_PCM_S16LE },
1328 { wxT("asf"), AUDACITY_AV_CODEC_ID_PCM_U8 },
1329 { wxT("asf"), AUDACITY_AV_CODEC_ID_PCM_S24LE },
1330 { wxT("asf"), AUDACITY_AV_CODEC_ID_PCM_S32LE },
1331 { wxT("asf"), AUDACITY_AV_CODEC_ID_ADPCM_MS },
1332 { wxT("asf"), AUDACITY_AV_CODEC_ID_PCM_ALAW },
1333 { wxT("asf"), AUDACITY_AV_CODEC_ID_PCM_MULAW },
1334 { wxT("asf"), AUDACITY_AV_CODEC_ID_WMAVOICE },
1335 { wxT("asf"), AUDACITY_AV_CODEC_ID_ADPCM_IMA_WAV },
1336 { wxT("asf"), AUDACITY_AV_CODEC_ID_ADPCM_YAMAHA },
1337 { wxT("asf"), AUDACITY_AV_CODEC_ID_TRUESPEECH },
1338 { wxT("asf"), AUDACITY_AV_CODEC_ID_GSM_MS },
1339 { wxT("asf"), AUDACITY_AV_CODEC_ID_ADPCM_G726 },
1340 //{ wxT("asf"), AUDACITY_AV_CODEC_ID_MP2 }, Bug 59
1341 { wxT("asf"), AUDACITY_AV_CODEC_ID_MP3 },
1342#if LIBAVCODEC_VERSION_MAJOR < 58
1343 { wxT("asf"), AUDACITY_AV_CODEC_ID_VOXWARE },
1344#endif
1345 { wxT("asf"), AUDACITY_AV_CODEC_ID_AAC },
1346 { wxT("asf"), AUDACITY_AV_CODEC_ID_WMAV1 },
1347 { wxT("asf"), AUDACITY_AV_CODEC_ID_WMAV2 },
1348 { wxT("asf"), AUDACITY_AV_CODEC_ID_WMAPRO },
1349 { wxT("asf"), AUDACITY_AV_CODEC_ID_ADPCM_CT },
1350 { wxT("asf"), AUDACITY_AV_CODEC_ID_ATRAC3 },
1351 { wxT("asf"), AUDACITY_AV_CODEC_ID_IMC },
1352 { wxT("asf"), AUDACITY_AV_CODEC_ID_AC3 },
1353 { wxT("asf"), AUDACITY_AV_CODEC_ID_DTS },
1354 { wxT("asf"), AUDACITY_AV_CODEC_ID_FLAC },
1355 { wxT("asf"), AUDACITY_AV_CODEC_ID_ADPCM_SWF },
1356 { wxT("asf"), AUDACITY_AV_CODEC_ID_VORBIS },
1357
1358 { wxT("au"), AUDACITY_AV_CODEC_ID_PCM_MULAW },
1359 { wxT("au"), AUDACITY_AV_CODEC_ID_PCM_S8 },
1360 { wxT("au"), AUDACITY_AV_CODEC_ID_PCM_S16BE },
1361 { wxT("au"), AUDACITY_AV_CODEC_ID_PCM_ALAW },
1362
1363 { wxT("avi"), AUDACITY_AV_CODEC_ID_PCM_S16LE },
1364 { wxT("avi"), AUDACITY_AV_CODEC_ID_PCM_U8 },
1365 { wxT("avi"), AUDACITY_AV_CODEC_ID_PCM_S24LE },
1366 { wxT("avi"), AUDACITY_AV_CODEC_ID_PCM_S32LE },
1367 { wxT("avi"), AUDACITY_AV_CODEC_ID_ADPCM_MS },
1368 { wxT("avi"), AUDACITY_AV_CODEC_ID_PCM_ALAW },
1369 { wxT("avi"), AUDACITY_AV_CODEC_ID_PCM_MULAW },
1370 { wxT("avi"), AUDACITY_AV_CODEC_ID_WMAVOICE },
1371 { wxT("avi"), AUDACITY_AV_CODEC_ID_ADPCM_IMA_WAV },
1372 { wxT("avi"), AUDACITY_AV_CODEC_ID_ADPCM_YAMAHA },
1373 { wxT("avi"), AUDACITY_AV_CODEC_ID_TRUESPEECH },
1374 { wxT("avi"), AUDACITY_AV_CODEC_ID_GSM_MS },
1375 { wxT("avi"), AUDACITY_AV_CODEC_ID_ADPCM_G726 },
1376 // { wxT("avi"), AUDACITY_AV_CODEC_ID_MP2 }, //Bug 59
1377 { wxT("avi"), AUDACITY_AV_CODEC_ID_MP3 },
1378#if LIBAVCODEC_VERSION_MAJOR < 58
1379 { wxT("avi"), AUDACITY_AV_CODEC_ID_VOXWARE },
1380#endif
1381 { wxT("avi"), AUDACITY_AV_CODEC_ID_AAC },
1382 { wxT("avi"), AUDACITY_AV_CODEC_ID_WMAV1 },
1383 { wxT("avi"), AUDACITY_AV_CODEC_ID_WMAV2 },
1384 { wxT("avi"), AUDACITY_AV_CODEC_ID_WMAPRO },
1385 { wxT("avi"), AUDACITY_AV_CODEC_ID_ADPCM_CT },
1386 { wxT("avi"), AUDACITY_AV_CODEC_ID_ATRAC3 },
1387 { wxT("avi"), AUDACITY_AV_CODEC_ID_IMC },
1388 { wxT("avi"), AUDACITY_AV_CODEC_ID_AC3 },
1389 { wxT("avi"), AUDACITY_AV_CODEC_ID_DTS },
1390 { wxT("avi"), AUDACITY_AV_CODEC_ID_FLAC },
1391 { wxT("avi"), AUDACITY_AV_CODEC_ID_ADPCM_SWF },
1392 { wxT("avi"), AUDACITY_AV_CODEC_ID_VORBIS },
1393
1394 { wxT("crc"), AUDACITY_AV_CODEC_ID_NONE },
1395
1396 { wxT("dv"), AUDACITY_AV_CODEC_ID_PCM_S16LE },
1397
1398 { wxT("ffm"), AUDACITY_AV_CODEC_ID_NONE },
1399
1400 { wxT("flv"), AUDACITY_AV_CODEC_ID_MP3 },
1401 { wxT("flv"), AUDACITY_AV_CODEC_ID_PCM_S8 },
1402 { wxT("flv"), AUDACITY_AV_CODEC_ID_PCM_S16BE },
1403 { wxT("flv"), AUDACITY_AV_CODEC_ID_PCM_S16LE },
1404 { wxT("flv"), AUDACITY_AV_CODEC_ID_ADPCM_SWF },
1405 { wxT("flv"), AUDACITY_AV_CODEC_ID_AAC },
1406 { wxT("flv"), AUDACITY_AV_CODEC_ID_NELLYMOSER },
1407
1408 { wxT("framecrc"), AUDACITY_AV_CODEC_ID_NONE },
1409
1410 { wxT("gxf"), AUDACITY_AV_CODEC_ID_PCM_S16LE },
1411
1412 { wxT("matroska"), AUDACITY_AV_CODEC_ID_PCM_S16LE },
1413 { wxT("matroska"), AUDACITY_AV_CODEC_ID_PCM_U8 },
1414 { wxT("matroska"), AUDACITY_AV_CODEC_ID_PCM_S24LE },
1415 { wxT("matroska"), AUDACITY_AV_CODEC_ID_PCM_S32LE },
1416 { wxT("matroska"), AUDACITY_AV_CODEC_ID_ADPCM_MS },
1417 { wxT("matroska"), AUDACITY_AV_CODEC_ID_PCM_ALAW },
1418 { wxT("matroska"), AUDACITY_AV_CODEC_ID_PCM_MULAW },
1419 { wxT("matroska"), AUDACITY_AV_CODEC_ID_WMAVOICE },
1420 { wxT("matroska"), AUDACITY_AV_CODEC_ID_ADPCM_IMA_WAV },
1421 { wxT("matroska"), AUDACITY_AV_CODEC_ID_ADPCM_YAMAHA },
1422 { wxT("matroska"), AUDACITY_AV_CODEC_ID_TRUESPEECH },
1423 { wxT("matroska"), AUDACITY_AV_CODEC_ID_GSM_MS },
1424 { wxT("matroska"), AUDACITY_AV_CODEC_ID_ADPCM_G726 },
1425 // { wxT("matroska"), AUDACITY_AV_CODEC_ID_MP2 }, // Bug 59
1426 { wxT("matroska"), AUDACITY_AV_CODEC_ID_MP3 },
1427#if LIBAVCODEC_VERSION_MAJOR < 58
1428 { wxT("matroska"), AUDACITY_AV_CODEC_ID_VOXWARE },
1429#endif
1430 { wxT("matroska"), AUDACITY_AV_CODEC_ID_AAC },
1431 { wxT("matroska"), AUDACITY_AV_CODEC_ID_WMAV1 },
1432 { wxT("matroska"), AUDACITY_AV_CODEC_ID_WMAV2 },
1433 { wxT("matroska"), AUDACITY_AV_CODEC_ID_WMAPRO },
1434 { wxT("matroska"), AUDACITY_AV_CODEC_ID_ADPCM_CT },
1435 { wxT("matroska"), AUDACITY_AV_CODEC_ID_ATRAC3 },
1436 { wxT("matroska"), AUDACITY_AV_CODEC_ID_IMC },
1437 { wxT("matroska"), AUDACITY_AV_CODEC_ID_AC3 },
1438 { wxT("matroska"), AUDACITY_AV_CODEC_ID_DTS },
1439 { wxT("matroska"), AUDACITY_AV_CODEC_ID_FLAC },
1440 { wxT("matroska"), AUDACITY_AV_CODEC_ID_ADPCM_SWF },
1441 { wxT("matroska"), AUDACITY_AV_CODEC_ID_VORBIS },
1442
1443 { wxT("mmf"), AUDACITY_AV_CODEC_ID_ADPCM_YAMAHA },
1444
1445 { wxT("mov"), AUDACITY_AV_CODEC_ID_PCM_S32BE }, //mov
1446 { wxT("mov"), AUDACITY_AV_CODEC_ID_PCM_S32LE },
1447 { wxT("mov"), AUDACITY_AV_CODEC_ID_PCM_S24BE },
1448 { wxT("mov"), AUDACITY_AV_CODEC_ID_PCM_S24LE },
1449 { wxT("mov"), AUDACITY_AV_CODEC_ID_PCM_S16BE },
1450 { wxT("mov"), AUDACITY_AV_CODEC_ID_PCM_S16LE },
1451 { wxT("mov"), AUDACITY_AV_CODEC_ID_PCM_S8 },
1452 { wxT("mov"), AUDACITY_AV_CODEC_ID_PCM_U8 },
1453 { wxT("mov"), AUDACITY_AV_CODEC_ID_PCM_MULAW },
1454 { wxT("mov"), AUDACITY_AV_CODEC_ID_PCM_ALAW },
1455 { wxT("mov"), AUDACITY_AV_CODEC_ID_ADPCM_IMA_QT },
1456 { wxT("mov"), AUDACITY_AV_CODEC_ID_MACE3 },
1457 { wxT("mov"), AUDACITY_AV_CODEC_ID_MACE6 },
1458 { wxT("mov"), AUDACITY_AV_CODEC_ID_MP3 },
1459 { wxT("mov"), AUDACITY_AV_CODEC_ID_AAC },
1460 { wxT("mov"), AUDACITY_AV_CODEC_ID_AMR_NB },
1461 { wxT("mov"), AUDACITY_AV_CODEC_ID_AMR_WB },
1462 { wxT("mov"), AUDACITY_AV_CODEC_ID_GSM },
1463 { wxT("mov"), AUDACITY_AV_CODEC_ID_ALAC },
1464 { wxT("mov"), AUDACITY_AV_CODEC_ID_QCELP },
1465 { wxT("mov"), AUDACITY_AV_CODEC_ID_QDM2 },
1466 { wxT("mov"), AUDACITY_AV_CODEC_ID_DVAUDIO },
1467 { wxT("mov"), AUDACITY_AV_CODEC_ID_WMAV2 },
1468 { wxT("mov"), AUDACITY_AV_CODEC_ID_ALAC },
1469
1470 { wxT("mp4"), AUDACITY_AV_CODEC_ID_AAC },
1471 { wxT("mp4"), AUDACITY_AV_CODEC_ID_QCELP },
1472 { wxT("mp4"), AUDACITY_AV_CODEC_ID_MP3 },
1473 { wxT("mp4"), AUDACITY_AV_CODEC_ID_VORBIS },
1474
1475 { wxT("psp"), AUDACITY_AV_CODEC_ID_AAC },
1476 { wxT("psp"), AUDACITY_AV_CODEC_ID_QCELP },
1477 { wxT("psp"), AUDACITY_AV_CODEC_ID_MP3 },
1478 { wxT("psp"), AUDACITY_AV_CODEC_ID_VORBIS },
1479
1480 { wxT("ipod"), AUDACITY_AV_CODEC_ID_AAC },
1481 { wxT("ipod"), AUDACITY_AV_CODEC_ID_QCELP },
1482 { wxT("ipod"), AUDACITY_AV_CODEC_ID_MP3 },
1483 { wxT("ipod"), AUDACITY_AV_CODEC_ID_VORBIS },
1484
1485 { wxT("3gp"), AUDACITY_AV_CODEC_ID_AAC },
1486 { wxT("3gp"), AUDACITY_AV_CODEC_ID_AMR_NB },
1487 { wxT("3gp"), AUDACITY_AV_CODEC_ID_AMR_WB },
1488
1489 { wxT("3g2"), AUDACITY_AV_CODEC_ID_AAC },
1490 { wxT("3g2"), AUDACITY_AV_CODEC_ID_AMR_NB },
1491 { wxT("3g2"), AUDACITY_AV_CODEC_ID_AMR_WB },
1492
1493 { wxT("mp3"), AUDACITY_AV_CODEC_ID_MP3 },
1494
1495 { wxT("mpeg"), AUDACITY_AV_CODEC_ID_AC3 },
1496 { wxT("mpeg"), AUDACITY_AV_CODEC_ID_DTS },
1497 { wxT("mpeg"), AUDACITY_AV_CODEC_ID_PCM_S16BE },
1498 //{ wxT("mpeg"), AUDACITY_AV_CODEC_ID_MP2 },// Bug 59
1499
1500 { wxT("vcd"), AUDACITY_AV_CODEC_ID_AC3 },
1501 { wxT("vcd"), AUDACITY_AV_CODEC_ID_DTS },
1502 { wxT("vcd"), AUDACITY_AV_CODEC_ID_PCM_S16BE },
1503 //{ wxT("vcd"), AUDACITY_AV_CODEC_ID_MP2 },// Bug 59
1504
1505 { wxT("vob"), AUDACITY_AV_CODEC_ID_AC3 },
1506 { wxT("vob"), AUDACITY_AV_CODEC_ID_DTS },
1507 { wxT("vob"), AUDACITY_AV_CODEC_ID_PCM_S16BE },
1508 //{ wxT("vob"), AUDACITY_AV_CODEC_ID_MP2 },// Bug 59
1509
1510 { wxT("svcd"), AUDACITY_AV_CODEC_ID_AC3 },
1511 { wxT("svcd"), AUDACITY_AV_CODEC_ID_DTS },
1512 { wxT("svcd"), AUDACITY_AV_CODEC_ID_PCM_S16BE },
1513 //{ wxT("svcd"), AUDACITY_AV_CODEC_ID_MP2 },// Bug 59
1514
1515 { wxT("dvd"), AUDACITY_AV_CODEC_ID_AC3 },
1516 { wxT("dvd"), AUDACITY_AV_CODEC_ID_DTS },
1517 { wxT("dvd"), AUDACITY_AV_CODEC_ID_PCM_S16BE },
1518 //{ wxT("dvd"), AUDACITY_AV_CODEC_ID_MP2 },// Bug 59
1519
1520 { wxT("nut"), AUDACITY_AV_CODEC_ID_PCM_S16LE },
1521 { wxT("nut"), AUDACITY_AV_CODEC_ID_PCM_U8 },
1522 { wxT("nut"), AUDACITY_AV_CODEC_ID_PCM_S24LE },
1523 { wxT("nut"), AUDACITY_AV_CODEC_ID_PCM_S32LE },
1524 { wxT("nut"), AUDACITY_AV_CODEC_ID_ADPCM_MS },
1525 { wxT("nut"), AUDACITY_AV_CODEC_ID_PCM_ALAW },
1526 { wxT("nut"), AUDACITY_AV_CODEC_ID_PCM_MULAW },
1527 { wxT("nut"), AUDACITY_AV_CODEC_ID_WMAVOICE },
1528 { wxT("nut"), AUDACITY_AV_CODEC_ID_ADPCM_IMA_WAV },
1529 { wxT("nut"), AUDACITY_AV_CODEC_ID_ADPCM_YAMAHA },
1530 { wxT("nut"), AUDACITY_AV_CODEC_ID_TRUESPEECH },
1531 { wxT("nut"), AUDACITY_AV_CODEC_ID_GSM_MS },
1532 { wxT("nut"), AUDACITY_AV_CODEC_ID_ADPCM_G726 },
1533 //{ wxT("nut"), AUDACITY_AV_CODEC_ID_MP2 },// Bug 59
1534 { wxT("nut"), AUDACITY_AV_CODEC_ID_MP3 },
1535 #if LIBAVCODEC_VERSION_MAJOR < 58
1536 { wxT("nut"), AUDACITY_AV_CODEC_ID_VOXWARE },
1537 #endif
1538 { wxT("nut"), AUDACITY_AV_CODEC_ID_AAC },
1539 { wxT("nut"), AUDACITY_AV_CODEC_ID_WMAV1 },
1540 { wxT("nut"), AUDACITY_AV_CODEC_ID_WMAV2 },
1541 { wxT("nut"), AUDACITY_AV_CODEC_ID_WMAPRO },
1542 { wxT("nut"), AUDACITY_AV_CODEC_ID_ADPCM_CT },
1543 { wxT("nut"), AUDACITY_AV_CODEC_ID_ATRAC3 },
1544 { wxT("nut"), AUDACITY_AV_CODEC_ID_IMC },
1545 { wxT("nut"), AUDACITY_AV_CODEC_ID_AC3 },
1546 { wxT("nut"), AUDACITY_AV_CODEC_ID_DTS },
1547 { wxT("nut"), AUDACITY_AV_CODEC_ID_FLAC },
1548 { wxT("nut"), AUDACITY_AV_CODEC_ID_ADPCM_SWF },
1549 { wxT("nut"), AUDACITY_AV_CODEC_ID_VORBIS },
1550
1551 { wxT("ogg"), AUDACITY_AV_CODEC_ID_VORBIS },
1552 { wxT("ogg"), AUDACITY_AV_CODEC_ID_FLAC },
1553
1554 { wxT("ac3"), AUDACITY_AV_CODEC_ID_AC3 },
1555
1556 { wxT("dts"), AUDACITY_AV_CODEC_ID_DTS },
1557
1558 { wxT("flac"), AUDACITY_AV_CODEC_ID_FLAC },
1559
1560 { wxT("RoQ"), AUDACITY_AV_CODEC_ID_ROQ_DPCM },
1561
1562 { wxT("rm"), AUDACITY_AV_CODEC_ID_AC3 },
1563
1564 { wxT("swf"), AUDACITY_AV_CODEC_ID_MP3 },
1565
1566 { wxT("avm2"), AUDACITY_AV_CODEC_ID_MP3 },
1567
1568 { wxT("voc"), AUDACITY_AV_CODEC_ID_PCM_U8 },
1569
1570 { wxT("wav"), AUDACITY_AV_CODEC_ID_PCM_S16LE },
1571 { wxT("wav"), AUDACITY_AV_CODEC_ID_PCM_U8 },
1572 { wxT("wav"), AUDACITY_AV_CODEC_ID_PCM_S24LE },
1573 { wxT("wav"), AUDACITY_AV_CODEC_ID_PCM_S32LE },
1574 { wxT("wav"), AUDACITY_AV_CODEC_ID_ADPCM_MS },
1575 { wxT("wav"), AUDACITY_AV_CODEC_ID_PCM_ALAW },
1576 { wxT("wav"), AUDACITY_AV_CODEC_ID_PCM_MULAW },
1577 { wxT("wav"), AUDACITY_AV_CODEC_ID_WMAVOICE },
1578 { wxT("wav"), AUDACITY_AV_CODEC_ID_ADPCM_IMA_WAV },
1579 { wxT("wav"), AUDACITY_AV_CODEC_ID_ADPCM_YAMAHA },
1580 { wxT("wav"), AUDACITY_AV_CODEC_ID_TRUESPEECH },
1581 { wxT("wav"), AUDACITY_AV_CODEC_ID_GSM_MS },
1582 { wxT("wav"), AUDACITY_AV_CODEC_ID_ADPCM_G726 },
1583 //{ wxT("wav"), AUDACITY_AV_CODEC_ID_MP2 }, Bug 59 - It crashes.
1584 { wxT("wav"), AUDACITY_AV_CODEC_ID_MP3 },
1585#if LIBAVCODEC_VERSION_MAJOR < 58
1586 { wxT("wav"), AUDACITY_AV_CODEC_ID_VOXWARE },
1587#endif
1588 { wxT("wav"), AUDACITY_AV_CODEC_ID_AAC },
1589 // { wxT("wav"), AUDACITY_AV_CODEC_ID_WMAV1 },
1590 // { wxT("wav"), AUDACITY_AV_CODEC_ID_WMAV2 },
1591 { wxT("wav"), AUDACITY_AV_CODEC_ID_WMAPRO },
1592 { wxT("wav"), AUDACITY_AV_CODEC_ID_ADPCM_CT },
1593 { wxT("wav"), AUDACITY_AV_CODEC_ID_ATRAC3 },
1594 { wxT("wav"), AUDACITY_AV_CODEC_ID_IMC },
1595 { wxT("wav"), AUDACITY_AV_CODEC_ID_AC3 },
1596 //{ wxT("wav"), AUDACITY_AV_CODEC_ID_DTS },
1597 { wxT("wav"), AUDACITY_AV_CODEC_ID_FLAC },
1598 { wxT("wav"), AUDACITY_AV_CODEC_ID_ADPCM_SWF },
1599 { wxT("wav"), AUDACITY_AV_CODEC_ID_VORBIS },
1600
1602};
1603
1605// The FF_PROFILE_* enumeration is defined in the ffmpeg library
1606// PRL: I can't find where this preference is used!
1607ChoiceSetting AACProfiles { wxT("/FileFormats/FFmpegAACProfile"),
1608 {
1609 {wxT("1") /*FF_PROFILE_AAC_LOW*/, XO("LC")},
1610 {wxT("0") /*FF_PROFILE_AAC_MAIN*/, XO("Main")},
1611 // {wxT("2") /*FF_PROFILE_AAC_SSR*/, XO("SSR")}, //SSR is not supported
1612 {wxT("3") /*FF_PROFILE_AAC_LTP*/, XO("LTP")},
1613 },
1614 0, // "1"
1615};
1616
1619{
1620 {FMT_M4A, wxT("M4A"), wxT("m4a"), wxT("ipod"), 48, AV_CANMETA, true, XO("M4A (AAC) Files (FFmpeg)"), AUDACITY_AV_CODEC_ID_AAC, true},
1621 {FMT_AC3, wxT("AC3"), wxT("ac3"), wxT("ac3"), 7, AV_VERSION_INT(0,0,0), false, XO("AC3 Files (FFmpeg)"), AUDACITY_AV_CODEC_ID_AC3, true},
1622 {FMT_AMRNB, wxT("AMRNB"), wxT("amr"), wxT("amr"), 1, AV_VERSION_INT(0,0,0), false, XO("AMR (narrow band) Files (FFmpeg)"), AUDACITY_AV_CODEC_ID_AMR_NB, true},
1623 {FMT_OPUS, wxT("OPUS"), wxT("opus"), wxT("opus"), 255, AV_CANMETA, true, XO("Opus (OggOpus) Files (FFmpeg)"), AUDACITY_AV_CODEC_ID_OPUS, true},
1624 {FMT_WMA2, wxT("WMA"), wxT("wma"), wxT("asf"), 2, AV_VERSION_INT(52,53,0), false, XO("WMA (version 2) Files (FFmpeg)"), AUDACITY_AV_CODEC_ID_WMAV2, true},
1625 {FMT_OTHER, wxT("FFMPEG"), wxT(""), wxT(""), 255, AV_CANMETA, true, XO("Custom FFmpeg Export"), AUDACITY_AV_CODEC_ID_NONE, true}
1626};
1627
1636{
1637 {TRUE,FEQualityID,AUDACITY_AV_CODEC_ID_AAC,"any"},
1638 {TRUE,FEQualityID,AUDACITY_AV_CODEC_ID_MP3,"any"},
1639 {TRUE,FEQualityID,AUDACITY_AV_CODEC_ID_VORBIS,"any"},
1640 {FALSE,FEQualityID,AUDACITY_AV_CODEC_ID_NONE,"any"},
1641
1642 {TRUE,FECutoffID,AUDACITY_AV_CODEC_ID_AC3,"any"},
1643 {TRUE,FECutoffID,AUDACITY_AV_CODEC_ID_AAC,"any"},
1644 {TRUE,FECutoffID,AUDACITY_AV_CODEC_ID_VORBIS,"any"},
1645 {FALSE,FECutoffID,AUDACITY_AV_CODEC_ID_NONE,"any"},
1646
1647 {TRUE,FEFrameSizeID,AUDACITY_AV_CODEC_ID_FLAC,"any"},
1648 {FALSE,FEFrameSizeID,AUDACITY_AV_CODEC_ID_NONE,"any"},
1649
1650 {TRUE,FEProfileID,AUDACITY_AV_CODEC_ID_AAC,"any"},
1651 {FALSE,FEProfileID,AUDACITY_AV_CODEC_ID_NONE,"any"},
1652
1653 {TRUE,FECompLevelID,AUDACITY_AV_CODEC_ID_FLAC,"any"},
1654 {FALSE,FECompLevelID,AUDACITY_AV_CODEC_ID_NONE,"any"},
1655
1656 {TRUE,FEUseLPCID,AUDACITY_AV_CODEC_ID_FLAC,"any"},
1657 {FALSE,FEUseLPCID,AUDACITY_AV_CODEC_ID_NONE,"any"},
1658
1659 {TRUE,FELPCCoeffsID,AUDACITY_AV_CODEC_ID_FLAC,"any"},
1660 {FALSE,FELPCCoeffsID,AUDACITY_AV_CODEC_ID_NONE,"any"},
1661
1662 {TRUE,FEMinPredID,AUDACITY_AV_CODEC_ID_FLAC,"any"},
1663 {FALSE,FEMinPredID,AUDACITY_AV_CODEC_ID_NONE,"any"},
1664
1665 {TRUE,FEMaxPredID,AUDACITY_AV_CODEC_ID_FLAC,"any"},
1666 {FALSE,FEMaxPredID,AUDACITY_AV_CODEC_ID_NONE,"any"},
1667
1668 {TRUE,FEPredOrderID,AUDACITY_AV_CODEC_ID_FLAC,"any"},
1669 {FALSE,FEPredOrderID,AUDACITY_AV_CODEC_ID_NONE,"any"},
1670
1671 {TRUE,FEMinPartOrderID,AUDACITY_AV_CODEC_ID_FLAC,"any"},
1672 {FALSE,FEMinPartOrderID,AUDACITY_AV_CODEC_ID_NONE,"any"},
1673
1674 {TRUE,FEMaxPartOrderID,AUDACITY_AV_CODEC_ID_FLAC,"any"},
1675 {FALSE,FEMaxPartOrderID,AUDACITY_AV_CODEC_ID_NONE,"any"},
1676
1677 {TRUE,FEMuxRateID,AUDACITY_AV_CODEC_ID_NONE,"mpeg"},
1678 {TRUE,FEMuxRateID,AUDACITY_AV_CODEC_ID_NONE,"vcd"},
1679 {TRUE,FEMuxRateID,AUDACITY_AV_CODEC_ID_NONE,"vob"},
1680 {TRUE,FEMuxRateID,AUDACITY_AV_CODEC_ID_NONE,"svcd"},
1681 {TRUE,FEMuxRateID,AUDACITY_AV_CODEC_ID_NONE,"dvd"},
1682 {FALSE,FEMuxRateID,AUDACITY_AV_CODEC_ID_NONE,"any"},
1683
1684 {TRUE,FEPacketSizeID,AUDACITY_AV_CODEC_ID_NONE,"mpeg"},
1685 {TRUE,FEPacketSizeID,AUDACITY_AV_CODEC_ID_NONE,"vcd"},
1686 {TRUE,FEPacketSizeID,AUDACITY_AV_CODEC_ID_NONE,"vob"},
1687 {TRUE,FEPacketSizeID,AUDACITY_AV_CODEC_ID_NONE,"svcd"},
1688 {TRUE,FEPacketSizeID,AUDACITY_AV_CODEC_ID_NONE,"dvd"},
1689 {FALSE,FEPacketSizeID,AUDACITY_AV_CODEC_ID_NONE,"any"},
1690
1691 {TRUE,FELanguageID,AUDACITY_AV_CODEC_ID_NONE,"matroska"},
1692 {TRUE,FELanguageID,AUDACITY_AV_CODEC_ID_NONE,"mov"},
1693 {TRUE,FELanguageID,AUDACITY_AV_CODEC_ID_NONE,"3gp"},
1694 {TRUE,FELanguageID,AUDACITY_AV_CODEC_ID_NONE,"mp4"},
1695 {TRUE,FELanguageID,AUDACITY_AV_CODEC_ID_NONE,"psp"},
1696 {TRUE,FELanguageID,AUDACITY_AV_CODEC_ID_NONE,"3g2"},
1697 {TRUE,FELanguageID,AUDACITY_AV_CODEC_ID_NONE,"ipod"},
1698 {TRUE,FELanguageID,AUDACITY_AV_CODEC_ID_NONE,"mpegts"},
1699 {FALSE,FELanguageID,AUDACITY_AV_CODEC_ID_NONE,"any"},
1700
1701 {TRUE,FEBitReservoirID,AUDACITY_AV_CODEC_ID_MP3,"any"},
1702 {TRUE,FEBitReservoirID,AUDACITY_AV_CODEC_ID_WMAV1,"any"},
1703 {TRUE,FEBitReservoirID,AUDACITY_AV_CODEC_ID_WMAV2,"any"},
1704 {FALSE,FEBitReservoirID,AUDACITY_AV_CODEC_ID_NONE,"any"},
1705
1706 {TRUE,FEVariableBlockLenID,AUDACITY_AV_CODEC_ID_WMAV1,"any"},
1707 {TRUE,FEVariableBlockLenID,AUDACITY_AV_CODEC_ID_WMAV2,"any"},
1708 {FALSE,FEVariableBlockLenID,AUDACITY_AV_CODEC_ID_NONE,"any"},
1709
1711};
1712
1713namespace {
1714
1717 XO("Estimate"),
1718 XO("2-level"),
1719 XO("4-level"),
1720 XO("8-level"),
1721 XO("Full search"),
1722 XO("Log search"),
1723};
1724
1725}
1726
1727
1728
1730{
1731}
1732
1734: wxDialogWrapper(parent, wxID_ANY,
1735 XO("Configure custom FFmpeg options"))
1736{
1737 SetName();
1740 //FFmpegLibsInst()->LoadLibs(NULL,true); //Loaded at startup or from Prefs now
1741
1742 mPresets = std::make_unique<FFmpegPresets>();
1743 mPresets->GetPresetList(mPresetNames);
1744
1745 if (mFFmpeg)
1746 {
1749
1751
1752 //Select the format that was selected last time this dialog was closed
1753 mFormatList->Select(mFormatList->FindString(gPrefs->Read(wxT("/FileFormats/FFmpegFormat"))));
1755
1756 //Select the codec that was selected last time this dialog was closed
1757 auto codec = mFFmpeg->CreateEncoder(gPrefs->Read(wxT("/FileFormats/FFmpegCodec")).ToUTF8());
1758
1759 if (codec != nullptr)
1760 mCodecList->Select(mCodecList->FindString(wxString::FromUTF8(codec->GetName())));
1761
1762 DoOnCodecList();
1763 }
1764
1765}
1766
1770{
1771 if (!mFFmpeg)
1772 return;
1773
1774 // Enumerate all output formats
1775 std::unique_ptr<AVOutputFormatWrapper> ofmt;
1776
1777 while ((ofmt = mFFmpeg->GetNextOutputFormat(ofmt.get()))!=NULL)
1778 {
1779 // Any audio-capable format has default audio codec.
1780 // If it doesn't, then it doesn't supports any audio codecs
1781 if (ofmt->GetAudioCodec() != AUDACITY_AV_CODEC_ID_NONE)
1782 {
1783 mFormatNames.push_back(wxString::FromUTF8(ofmt->GetName()));
1784 mFormatLongNames.push_back(wxString::Format(wxT("%s - %s"),mFormatNames.back(),wxString::FromUTF8(ofmt->GetLongName())));
1785 }
1786 }
1787 // Show all formats
1790}
1791
1795{
1796 if (!mFFmpeg)
1797 return;
1798 // Enumerate all codecs
1799 std::unique_ptr<AVCodecWrapper> codec;
1800 while ((codec = mFFmpeg->GetNextCodec(codec.get()))!=NULL)
1801 {
1802 // We're only interested in audio and only in encoders
1803 if (codec->IsAudio() && mFFmpeg->av_codec_is_encoder(codec->GetWrappedValue()))
1804 {
1805 // MP2 Codec is broken. Don't allow it.
1806 if( codec->GetId() == mFFmpeg->GetAVCodecID(AUDACITY_AV_CODEC_ID_MP2))
1807 continue;
1808
1809 mCodecNames.push_back(wxString::FromUTF8(codec->GetName()));
1810 mCodecLongNames.push_back(wxString::Format(wxT("%s - %s"),mCodecNames.back(),wxString::FromUTF8(codec->GetLongName())));
1811 }
1812 }
1813 // Show all codecs
1816}
1817
1821{
1822 S.StartVerticalLay(1);
1823 S.StartMultiColumn(1, wxEXPAND);
1824 {
1825 S.SetStretchyRow(3);
1826 S.StartMultiColumn(7, wxEXPAND);
1827 {
1828 S.SetStretchyCol(1);
1829 mPresetCombo = S.Id(FEPresetID).AddCombo(XXO("Preset:"), gPrefs->Read(wxT("/FileFormats/FFmpegPreset"),wxEmptyString), mPresetNames);
1830 S.Id(FELoadPresetID).AddButton(XXO("Load Preset"));
1831 S.Id(FESavePresetID).AddButton(XXO("Save Preset"));
1832 S.Id(FEDeletePresetID).AddButton(XXO("Delete Preset"));
1833 S.Id(FEImportPresetsID).AddButton(XXO("Import Presets"));
1834 S.Id(FEExportPresetsID).AddButton(XXO("Export Presets"));
1835 }
1836 S.EndMultiColumn();
1837 S.StartMultiColumn(4, wxALIGN_LEFT);
1838 {
1839 S.SetStretchyCol(1);
1840 S.SetStretchyCol(3);
1841 S.Id(FEFormatLabelID).AddFixedText(XO("Format:"));
1842 mFormatName = S.Id(FEFormatNameID).AddVariableText( {} );
1843 /* i18n-hint: "codec" is short for a "coder-decoder" algorithm */
1844 S.Id(FECodecLabelID).AddFixedText(XO("Codec:"));
1845 mCodecName = S.Id(FECodecNameID).AddVariableText( {} );
1846 }
1847 S.EndMultiColumn();
1848 S.AddVariableText(XO(
1849"Not all formats and codecs are compatible. Nor are all option combinations compatible with all codecs."),
1850 false);
1851 S.StartMultiColumn(2, wxEXPAND);
1852 {
1853 S.StartMultiColumn(2, wxEXPAND);
1854 {
1855 S.SetStretchyRow(1);
1856 S.Id(FEAllFormatsID).AddButton(XXO("Show All Formats"));
1857 S.Id(FEAllCodecsID).AddButton(XXO("Show All Codecs"));
1858 mFormatList = S.Id(FEFormatID).AddListBox(mFormatNames);
1859 mFormatList->DeselectAll();
1860 mCodecList = S.Id(FECodecID).AddListBox(mCodecNames);
1861 mCodecList->DeselectAll();
1862 }
1863 S.EndMultiColumn();
1864 S.StartVerticalLay();
1865 {
1866 //S.StartScroller( );
1867 S.SetBorder( 3 );
1868 S.StartStatic(XO("General Options"), 0);
1869 {
1870 S.StartMultiColumn(8, wxEXPAND);
1871 {
1872 S.Id(FELanguageID)
1873 .ToolTip(XO("ISO 639 3-letter language code\nOptional\nempty - automatic"))
1874 .TieTextBox(XXO("Language:"), {wxT("/FileFormats/FFmpegLanguage"), wxEmptyString}, 9);
1875
1876 S.AddSpace( 20,0 );
1877 S.AddVariableText(XO("Bit Reservoir"));
1878 S.Id(FEBitReservoirID).TieCheckBox( {}, {wxT("/FileFormats/FFmpegBitReservoir"), true});
1879
1880 S.AddSpace( 20,0 );
1881 S.AddVariableText(XO("VBL"));
1882 S.Id(FEVariableBlockLenID).TieCheckBox( {}, {wxT("/FileFormats/FFmpegVariableBlockLen"), true});
1883 }
1884 S.EndMultiColumn();
1885 S.StartMultiColumn(4, wxALIGN_LEFT);
1886 {
1887 S.Id(FETagID)
1888 /* i18n-hint: "codec" is short for a "coder-decoder" algorithm */
1889 .ToolTip(XO("Codec tag (FOURCC)\nOptional\nempty - automatic"))
1890 .TieTextBox(XXO("Tag:"), {wxT("/FileFormats/FFmpegTag"), wxEmptyString}, 4);
1891
1892 S.Id(FEBitrateID)
1893 .ToolTip(XO("Bit Rate (bits/second) - influences the resulting file size and quality\nSome codecs may only accept specific values (128k, 192k, 256k etc)\n0 - automatic\nRecommended - 192000"))
1894 .TieSpinCtrl(XXO("Bit Rate:"), {wxT("/FileFormats/FFmpegBitRate"), 0}, 1000000, 0);
1895
1896 S.Id(FEQualityID)
1897 .ToolTip(XO("Overall quality, used differently by different codecs\nRequired for vorbis\n0 - automatic\n-1 - off (use bitrate instead)"))
1898 .TieSpinCtrl(XXO("Quality:"), {wxT("/FileFormats/FFmpegQuality"), 0}, 500, -1);
1899
1900 S.Id(FESampleRateID)
1901 .ToolTip(XO("Sample rate (Hz)\n0 - don't change sample rate"))
1902 .TieSpinCtrl(XXO("Sample Rate:"), {wxT("/FileFormats/FFmpegSampleRate"), 0}, 200000, 0);
1903
1904 S.Id(FECutoffID)
1905 .ToolTip(XO("Audio cutoff bandwidth (Hz)\nOptional\n0 - automatic"))
1906 .TieSpinCtrl(XXO("Cutoff:"), {wxT("/FileFormats/FFmpegCutOff"), 0}, 10000000, 0);
1907
1908 // PRL: As commented elsewhere, this preference does nothing
1909 S.Id(FEProfileID)
1910 .ToolTip(XO("AAC Profile\nLow Complexity - default\nMost players won't play anything other than LC"))
1911 .MinSize( { 100, -1 } )
1912 .TieChoice(XXO("Profile:"), AACProfiles);
1913 }
1914 S.EndMultiColumn();
1915 }
1916 S.EndStatic();
1917 S.StartStatic(XO("FLAC options"),0);
1918 {
1919 S.StartMultiColumn(4, wxALIGN_LEFT);
1920 {
1921 S
1922 .ToolTip(XO("Compression level\nRequired for FLAC\n-1 - automatic\nmin - 0 (fast encoding, large output file)\nmax - 10 (slow encoding, small output file)"))
1923 .Id(FECompLevelID).TieSpinCtrl(XXO("Compression:"), {wxT("/FileFormats/FFmpegCompLevel"), 0}, 10, -1);
1924
1925 S.Id(FEFrameSizeID)
1926 .ToolTip(XO("Frame size\nOptional\n0 - default\nmin - 16\nmax - 65535"))
1927 .TieSpinCtrl(XXO("Frame:"), {wxT("/FileFormats/FFmpegFrameSize"), 0}, 65535, 0);
1928
1929 S.Id(FELPCCoeffsID)
1930 .ToolTip(XO("LPC coefficients precision\nOptional\n0 - default\nmin - 1\nmax - 15"))
1931 .TieSpinCtrl(XXO("LPC"), {wxT("/FileFormats/FFmpegLPCCoefPrec"), 0}, 15, 0);
1932
1933 S.Id(FEPredOrderID)
1934 .ToolTip(XO("Prediction Order Method\nEstimate - fastest, lower compression\nLog search - slowest, best compression\nFull search - default"))
1935 .MinSize( { 100, -1 } )
1936 .TieNumberAsChoice(
1937 XXO("PdO Method:"),
1938 {wxT("/FileFormats/FFmpegPredOrderMethod"),
1939 4}, // Full search
1941 );
1942
1943 S.Id(FEMinPredID)
1944 .ToolTip(XO("Minimal prediction order\nOptional\n-1 - default\nmin - 0\nmax - 32 (with LPC) or 4 (without LPC)"))
1945 .TieSpinCtrl(XXO("Min. PdO"), {wxT("/FileFormats/FFmpegMinPredOrder"), -1}, 32, -1);
1946
1947 S.Id(FEMaxPredID)
1948 .ToolTip(XO("Maximal prediction order\nOptional\n-1 - default\nmin - 0\nmax - 32 (with LPC) or 4 (without LPC)"))
1949 .TieSpinCtrl(XXO("Max. PdO"), {wxT("/FileFormats/FFmpegMaxPredOrder"), -1}, 32, -1);
1950
1951 S.Id(FEMinPartOrderID)
1952 .ToolTip(XO("Minimal partition order\nOptional\n-1 - default\nmin - 0\nmax - 8"))
1953 .TieSpinCtrl(XXO("Min. PtO"), {wxT("/FileFormats/FFmpegMinPartOrder"), -1}, 8, -1);
1954
1955 S.Id(FEMaxPartOrderID)
1956 .ToolTip(XO("Maximal partition order\nOptional\n-1 - default\nmin - 0\nmax - 8"))
1957 .TieSpinCtrl(XXO("Max. PtO"), {wxT("/FileFormats/FFmpegMaxPartOrder"), -1}, 8, -1);
1958
1959 /* i18n-hint: Abbreviates "Linear Predictive Coding",
1960 but this text needs to be kept very short */
1961 S.AddVariableText(XO("Use LPC"));
1962 // PRL: This preference is not used anywhere!
1963 S.Id(FEUseLPCID).TieCheckBox( {}, {wxT("/FileFormats/FFmpegUseLPC"), true});
1964 }
1965 S.EndMultiColumn();
1966 }
1967 S.EndStatic();
1968 S.StartStatic(XO("MPEG container options"),0);
1969 {
1970 S.StartMultiColumn(4, wxALIGN_LEFT);
1971 {
1972 S.Id(FEMuxRateID)
1973 .ToolTip(XO("Maximum bit rate of the multiplexed stream\nOptional\n0 - default"))
1974 /* i18n-hint: 'mux' is short for multiplexor, a device that selects between several inputs
1975 'Mux Rate' is a parameter that has some bearing on compression ratio for MPEG
1976 it has a hard to predict effect on the degree of compression */
1977 .TieSpinCtrl(XXO("Mux Rate:"), {wxT("/FileFormats/FFmpegMuxRate"), 0}, 10000000, 0);
1978
1979 S.Id(FEPacketSizeID)
1980 /* i18n-hint: 'Packet Size' is a parameter that has some bearing on compression ratio for MPEG
1981 compression. It measures how big a chunk of audio is compressed in one piece. */
1982 .ToolTip(XO("Packet size\nOptional\n0 - default"))
1983 /* i18n-hint: 'Packet Size' is a parameter that has some bearing on compression ratio for MPEG
1984 compression. It measures how big a chunk of audio is compressed in one piece. */
1985 .TieSpinCtrl(XXO("Packet Size:"), {wxT("/FileFormats/FFmpegPacketSize"), 0}, 10000000, 0);
1986 }
1987 S.EndMultiColumn();
1988 }
1989 S.EndStatic();
1990 //S.EndScroller();
1991 S.SetBorder( 5 );
1992 S.AddStandardButtons(eOkButton | eCancelButton | eHelpButton );
1993 }
1994 S.EndVerticalLay();
1995 }
1996 S.EndMultiColumn();
1997 }
1998 S.EndMultiColumn();
1999 S.EndVerticalLay();
2000
2001 Layout();
2002 Fit();
2003 SetMinSize(GetSize());
2004 Center();
2005
2006 return;
2007}
2008
2011void ExportFFmpegOptions::FindSelectedFormat(wxString **name, wxString **longname)
2012{
2013 // Get current selection
2014 wxArrayInt selections;
2015 int n = mFormatList->GetSelections(selections);
2016 if (n <= 0) return;
2017
2018 // Get selected format short name
2019 wxString selfmt = mFormatList->GetString(selections[0]);
2020
2021 // Find its index
2022 int nFormat = make_iterator_range( mFormatNames ).index( selfmt );
2023 if (nFormat == wxNOT_FOUND) return;
2024
2025 // Return short name and description
2026 if (name != NULL) *name = &mFormatNames[nFormat];
2027 if (longname != NULL) *longname = &mFormatLongNames[nFormat];
2028 return;
2029}
2032void ExportFFmpegOptions::FindSelectedCodec(wxString **name, wxString **longname)
2033{
2034 // Get current selection
2035 wxArrayInt selections;
2036 int n = mCodecList->GetSelections(selections);
2037 if (n <= 0) return;
2038
2039 // Get selected codec short name
2040 wxString selcdc = mCodecList->GetString(selections[0]);
2041
2042 // Find its index
2043 int nCodec = make_iterator_range( mCodecNames ).index( selcdc );
2044 if (nCodec == wxNOT_FOUND) return;
2045
2046 // Return short name and description
2047 if (name != NULL) *name = &mCodecNames[nCodec];
2048 if (longname != NULL) *longname = &mCodecLongNames[nCodec];
2049}
2050
2054{
2055 const auto ffmpegId = mFFmpeg->GetAVCodecID(id);
2056
2057 // By default assume that id is not in the list
2058 int index = -1;
2059 // By default no codecs are compatible (yet)
2060 mShownCodecNames.clear();
2061 mShownCodecLongNames.clear();
2062 // Clear the listbox
2063 mCodecList->Clear();
2064 // Zero - format is not found at all
2065 int found = 0;
2066 wxString str(fmt);
2067 for (int i = 0; CompatibilityList[i].fmt != NULL; i++)
2068 {
2069 if (str == CompatibilityList[i].fmt)
2070 {
2071 // Format is found in the list
2072 found = 1;
2073 if (CompatibilityList[i].codec.value == AUDACITY_AV_CODEC_ID_NONE)
2074 {
2075 // Format is found in the list and it is compatible with AUDACITY_AV_CODEC_ID_NONE (means that it is compatible to anything)
2076 found = 2;
2077 break;
2078 }
2079 // Find the codec, that is claimed to be compatible
2080 std::unique_ptr<AVCodecWrapper> codec = mFFmpeg->CreateEncoder(mFFmpeg->GetAVCodecID(CompatibilityList[i].codec));
2081 // If it exists, is audio and has encoder
2082 if (codec != NULL && codec->IsAudio() && mFFmpeg->av_codec_is_encoder(codec->GetWrappedValue()))
2083 {
2084 // If it was selected - remember its NEW index
2085 if ((ffmpegId >= 0) && codec->GetId() == ffmpegId)
2086 index = mShownCodecNames.size();
2087
2088 mShownCodecNames.push_back(wxString::FromUTF8(codec->GetName()));
2089 mShownCodecLongNames.push_back(wxString::Format(wxT("%s - %s"),mShownCodecNames.back(),wxString::FromUTF8(codec->GetLongName())));
2090 }
2091 }
2092 }
2093 // All codecs are compatible with this format
2094 if (found == 2)
2095 {
2096 std::unique_ptr<AVCodecWrapper> codec;
2097 while ((codec = mFFmpeg->GetNextCodec(codec.get()))!=NULL)
2098 {
2099 if (codec->IsAudio() && mFFmpeg->av_codec_is_encoder(codec->GetWrappedValue()))
2100 {
2101 // MP2 is broken.
2102 if( codec->GetId() == mFFmpeg->GetAVCodecID(AUDACITY_AV_CODEC_ID_MP2) )
2103 continue;
2104
2106 .contains( wxString::FromUTF8(codec->GetName()) ) )
2107 {
2108 if ((ffmpegId >= 0) && codec->GetId() == ffmpegId)
2109 index = mShownCodecNames.size();
2110
2111 mShownCodecNames.push_back(wxString::FromUTF8(codec->GetName()));
2112 mShownCodecLongNames.push_back(wxString::Format(wxT("%s - %s"),mShownCodecNames.back(),wxString::FromUTF8(codec->GetLongName())));
2113 }
2114 }
2115 }
2116 }
2117 // Format is not found - find format in libavformat and add its default audio codec
2118 // This allows us to provide limited support for NEW formats without modifying the compatibility list
2119 else if (found == 0)
2120 {
2121 wxCharBuffer buf = str.ToUTF8();
2122 auto format = mFFmpeg->GuessOutputFormat(buf, nullptr, nullptr);
2123
2124 if (format != nullptr)
2125 {
2126 auto codec = mFFmpeg->CreateEncoder(format->GetAudioCodec());
2127
2128 if (
2129 codec != nullptr && codec->IsAudio() && mFFmpeg->av_codec_is_encoder(codec->GetWrappedValue()))
2130 {
2131 if ((ffmpegId >= 0) && codec->GetId() == ffmpegId)
2132 index = mShownCodecNames.size();
2133
2134 mShownCodecNames.push_back(wxString::FromUTF8(codec->GetName()));
2135 mShownCodecLongNames.push_back(wxString::Format(wxT("%s - %s"),mShownCodecNames.back(),wxString::FromUTF8(codec->GetLongName())));
2136 }
2137 }
2138 }
2139 // Show NEW codec list
2141
2142 return index;
2143}
2144
2148 AudacityAVCodecID id, wxString* selfmt)
2149{
2150 int index = -1;
2151 mShownFormatNames.clear();
2152 mShownFormatLongNames.clear();
2153 mFormatList->Clear();
2154 std::unique_ptr<AVOutputFormatWrapper> ofmt;
2155
2156 wxArrayString FromList;
2157 // Find all formats compatible to this codec in compatibility list
2158 for (int i = 0; CompatibilityList[i].fmt != NULL; i++)
2159 {
2160 if (CompatibilityList[i].codec == id || (CompatibilityList[i].codec.value == AUDACITY_AV_CODEC_ID_NONE) )
2161 {
2162 if ((selfmt != NULL) && (*selfmt == CompatibilityList[i].fmt)) index = mShownFormatNames.size();
2163 FromList.push_back(CompatibilityList[i].fmt);
2164 mShownFormatNames.push_back(CompatibilityList[i].fmt);
2165 auto tofmt = mFFmpeg->GuessOutputFormat(
2166 wxString(CompatibilityList[i].fmt).ToUTF8(), nullptr, nullptr);
2167
2168 if (tofmt != NULL)
2169 {
2170 mShownFormatLongNames.push_back(wxString::Format(
2171 wxT("%s - %s"), CompatibilityList[i].fmt,
2172 wxString::FromUTF8(tofmt->GetLongName())));
2173 }
2174 }
2175 }
2176 bool found = false;
2177 if (selfmt != NULL)
2178 {
2179 for (int i = 0; CompatibilityList[i].fmt != NULL; i++)
2180 {
2181 if (*selfmt == CompatibilityList[i].fmt)
2182 {
2183 found = true;
2184 break;
2185 }
2186 }
2187 }
2188 // Format was in the compatibility list
2189 if (found)
2190 {
2191 // Find all formats which have this codec as default and which are not in the list yet and add them too
2192 while ((ofmt = mFFmpeg->GetNextOutputFormat(ofmt.get()))!=NULL)
2193 {
2194 if (ofmt->GetAudioCodec() == mFFmpeg->GetAVCodecID(id))
2195 {
2196 wxString ofmtname = wxString::FromUTF8(ofmt->GetName());
2197 found = false;
2198 for (unsigned int i = 0; i < FromList.size(); i++)
2199 {
2200 if (ofmtname == FromList[i])
2201 {
2202 found = true;
2203 break;
2204 }
2205 }
2206 if (!found)
2207 {
2208 if ((selfmt != NULL) &&
2209 (*selfmt == wxString::FromUTF8(ofmt->GetName())))
2210 index = mShownFormatNames.size();
2211
2212 mShownFormatNames.push_back(wxString::FromUTF8(ofmt->GetName()));
2213
2214 mShownFormatLongNames.push_back(wxString::Format(
2215 wxT("%s - %s"), mShownFormatNames.back(),
2216 wxString::FromUTF8(ofmt->GetLongName())));
2217 }
2218 }
2219 }
2220 }
2222 return index;
2223}
2224
2227void ExportFFmpegOptions::OnDeletePreset(wxCommandEvent& WXUNUSED(event))
2228{
2229 wxComboBox *preset = dynamic_cast<wxComboBox*>(FindWindowById(FEPresetID,this));
2230 wxString presetname = preset->GetValue();
2231 if (presetname.empty())
2232 {
2233 AudacityMessageBox( XO("You can't delete a preset without name") );
2234 return;
2235 }
2236
2237 auto query = XO("Delete preset '%s'?").Format( presetname );
2238 int action = AudacityMessageBox(
2239 query,
2240 XO("Confirm Deletion"),
2241 wxYES_NO | wxCENTRE);
2242 if (action == wxNO) return;
2243
2244 mPresets->DeletePreset(presetname);
2245 long index = preset->FindString(presetname);
2246 preset->SetValue(wxEmptyString);
2247 preset->Delete(index);
2248 mPresetNames.erase(
2249 std::find( mPresetNames.begin(), mPresetNames.end(), presetname )
2250 );
2251}
2252
2255void ExportFFmpegOptions::OnSavePreset(wxCommandEvent& WXUNUSED(event))
2256{ const bool kCheckForOverwrite = true;
2257 SavePreset(kCheckForOverwrite);
2258}
2259
2260// Return false if failed to save.
2261bool ExportFFmpegOptions::SavePreset(bool bCheckForOverwrite)
2262{
2263 wxComboBox *preset = dynamic_cast<wxComboBox*>(FindWindowById(FEPresetID,this));
2264 wxString name = preset->GetValue();
2265 if (name.empty())
2266 {
2267 AudacityMessageBox( XO("You can't save a preset without a name") );
2268 return false;
2269 }
2270 if( bCheckForOverwrite && !mPresets->OverwriteIsOk(name))
2271 return false;
2272 if( !mPresets->SavePreset(this,name) )
2273 return false;
2274 int index = mPresetNames.Index(name,false);
2275 if (index == -1)
2276 {
2277 mPresetNames.push_back(name);
2278 mPresetCombo->Clear();
2279 mPresetCombo->Append(mPresetNames);
2280 mPresetCombo->Select(mPresetNames.Index(name,false));
2281 }
2282 return true;
2283}
2284
2287void ExportFFmpegOptions::OnLoadPreset(wxCommandEvent& WXUNUSED(event))
2288{
2289 wxComboBox *preset = dynamic_cast<wxComboBox*>(FindWindowById(FEPresetID,this));
2290 wxString presetname = preset->GetValue();
2291
2294 mFormatList->Clear();
2295 mFormatList->Append(mFormatNames);
2296
2299 mCodecList->Clear();
2300 mCodecList->Append(mCodecNames);
2301
2302 mPresets->LoadPreset(this,presetname);
2303
2305 DoOnCodecList();
2306}
2307
2309{
2310 static const FileNames::FileTypes result{
2312 return result;
2313};
2314
2317void ExportFFmpegOptions::OnImportPresets(wxCommandEvent& WXUNUSED(event))
2318{
2319 wxString path;
2320 FileDialogWrapper dlg(this,
2321 XO("Select xml file with presets to import"),
2322 gPrefs->Read(wxT("/FileFormats/FFmpegPresetDir")),
2323 wxEmptyString,
2324 FileTypes(),
2325 wxFD_OPEN);
2326 if (dlg.ShowModal() == wxID_CANCEL) return;
2327 path = dlg.GetPath();
2328 mPresets->ImportPresets(path);
2329 mPresets->GetPresetList(mPresetNames);
2330 mPresetCombo->Clear();
2331 mPresetCombo->Append(mPresetNames);
2332}
2333
2336void ExportFFmpegOptions::OnExportPresets(wxCommandEvent& WXUNUSED(event))
2337{
2338 const bool kCheckForOverwrite = true;
2339 // Bug 1180 save any pending preset before exporting the lot.
2340 // If saving fails, don't try to export.
2341 if( !SavePreset(!kCheckForOverwrite) )
2342 return;
2343
2344 wxArrayString presets;
2345 mPresets->GetPresetList( presets);
2346 if( presets.Count() < 1)
2347 {
2348 AudacityMessageBox( XO("No presets to export") );
2349 return;
2350 }
2351
2352 wxString path;
2353 FileDialogWrapper dlg(this,
2354 XO("Select xml file to export presets into"),
2355 gPrefs->Read(wxT("/FileFormats/FFmpegPresetDir")),
2356 wxEmptyString,
2357 FileTypes(),
2358 wxFD_SAVE|wxFD_OVERWRITE_PROMPT);
2359 if (dlg.ShowModal() == wxID_CANCEL) return;
2360 path = dlg.GetPath();
2361 mPresets->ExportPresets(path);
2362}
2363
2366void ExportFFmpegOptions::OnAllFormats(wxCommandEvent& WXUNUSED(event))
2367{
2370 mFormatList->Clear();
2371 mFormatList->Append(mFormatNames);
2372}
2373
2376void ExportFFmpegOptions::OnAllCodecs(wxCommandEvent& WXUNUSED(event))
2377{
2380 mCodecList->Clear();
2381 mCodecList->Append(mCodecNames);
2382}
2383
2392{
2393 wxString *selcdc = nullptr;
2394 wxString* selcdclong = nullptr;
2395
2396 FindSelectedCodec(&selcdc, &selcdclong);
2397
2398 if (selcdc == nullptr)
2399 return false; // unrecognised codec. Treated as OK
2400
2401 auto cdc = mFFmpeg->CreateEncoder(selcdc->ToUTF8());
2402
2403 if (cdc == nullptr)
2404 return false; // unrecognised codec. Treated as OK
2405
2406 wxString* selfmt = nullptr;
2407 wxString* selfmtlong = nullptr;
2408
2409 FindSelectedFormat(&selfmt, &selfmtlong);
2410
2411 if (selfmt == nullptr)
2412 return false; // unrecognised format; Treated as OK
2413
2414 // This is intended to test for illegal combinations.
2415 // However, the list updating now seems to be working correctly
2416 // making it impossible to select illegal combinations
2417 bool bFound = false;
2418 for (int i = 0; CompatibilityList[i].fmt != NULL; i++)
2419 {
2420 if (*selfmt == CompatibilityList[i].fmt)
2421 {
2422 if (CompatibilityList[i].codec == mFFmpeg->GetAudacityCodecID(cdc->GetId()) || (CompatibilityList[i].codec == AUDACITY_AV_CODEC_ID_NONE) ){
2423 bFound = true;
2424 break;
2425 }
2426 }
2427 }
2428
2429 // We can put extra code in here, to disallow combinations
2430 // We could also test for illegal parameters, and deliver
2431 // custom error messages in that case.
2432 // The below would make AAC codec disallowed.
2433 //if( cdc->id == AUDACITY_AV_CODEC_ID_AAC)
2434 // bFound = false;
2435
2436 // Valid combination was found, so no reporting.
2437 if( bFound )
2438 return false;
2439
2441 /* i18n-hint: "codec" is short for a "coder-decoder" algorithm */
2442 XO("Format %s is not compatible with codec %s.")
2443 .Format( *selfmt, *selcdc ),
2444 /* i18n-hint: "codec" is short for a "coder-decoder" algorithm */
2445 XO("Incompatible format and codec"));
2446
2447 return true;
2448}
2449
2450
2451
2453{
2454 int handled = -1;
2455 for (int i = 0; apptable[i].control != 0; i++)
2456 {
2457 if (apptable[i].control != handled)
2458 {
2459 bool codec = false;
2460 bool format = false;
2461 if (apptable[i].codec == AUDACITY_AV_CODEC_ID_NONE)
2462 {
2463 codec = true;
2464 }
2465 else if (
2466 cdc != NULL &&
2467 apptable[i].codec == mFFmpeg->GetAudacityCodecID(cdc->GetId()))
2468 {
2469 codec = true;
2470 }
2471
2472 if (wxString::FromUTF8(apptable[i].format) == wxT("any")) format = true;
2473 else if (selfmt != NULL &&
2474 *selfmt == wxString::FromUTF8(apptable[i].format)) format = true;
2475 if (codec && format)
2476 {
2477 handled = apptable[i].control;
2478 wxWindow *item = FindWindowById(apptable[i].control,this);
2479 if (item != NULL) item->Enable(apptable[i].enable);
2480 }
2481 }
2482 }
2483}
2484
2486{
2487 wxString *selfmt = NULL;
2488 wxString *selfmtlong = NULL;
2489 FindSelectedFormat(&selfmt, &selfmtlong);
2490 if (selfmt == NULL)
2491 {
2492 return;
2493 }
2494
2495 wxString *selcdc = NULL;
2496 wxString *selcdclong = NULL;
2497 FindSelectedCodec(&selcdc, &selcdclong);
2498
2499 auto fmt = mFFmpeg->GuessOutputFormat(selfmt->ToUTF8(),NULL,NULL);
2500 if (fmt == NULL)
2501 {
2502 //This shouldn't really happen
2503 mFormatName->SetLabel(wxString(_("Failed to guess format")));
2504 return;
2505 }
2506 mFormatName->SetLabel(wxString::Format(wxT("%s"), *selfmtlong));
2507
2509
2510 if (selcdc != nullptr)
2511 {
2512 auto cdc = mFFmpeg->CreateEncoder(selcdc->ToUTF8());
2513
2514 if (cdc != nullptr)
2515 {
2516 selcdcid = mFFmpeg->GetAudacityCodecID(cdc->GetId());
2517 }
2518 }
2519 int newselcdc =
2520 FetchCompatibleCodecList(*selfmt, selcdcid);
2521
2522 if (newselcdc >= 0) mCodecList->Select(newselcdc);
2523
2524 std::unique_ptr<AVCodecWrapper> cdc;
2525
2526 if (selcdc != nullptr)
2527 cdc = mFFmpeg->CreateEncoder(selcdc->ToUTF8());
2528
2529 EnableDisableControls(cdc.get(), selfmt);
2530 Layout();
2531 Fit();
2532 return;
2533}
2534
2536{
2537 wxString *selcdc = nullptr;
2538 wxString* selcdclong = nullptr;
2539
2540 FindSelectedCodec(&selcdc, &selcdclong);
2541
2542 if (selcdc == nullptr)
2543 {
2544 return;
2545 }
2546
2547 wxString* selfmt = nullptr;
2548 wxString* selfmtlong = nullptr;
2549
2550 FindSelectedFormat(&selfmt, &selfmtlong);
2551
2552 auto cdc = mFFmpeg->CreateEncoder(selcdc->ToUTF8());
2553 if (cdc == nullptr)
2554 {
2555 //This shouldn't really happen
2556 /* i18n-hint: "codec" is short for a "coder-decoder" algorithm */
2557 mCodecName->SetLabel(wxString(_("Failed to find the codec")));
2558 return;
2559 }
2560
2561 mCodecName->SetLabel(wxString::Format(wxT("[%d] %s"), (int) mFFmpeg->GetAudacityCodecID(cdc->GetId()).value, *selcdclong));
2562
2563 if (selfmt != nullptr)
2564 {
2565 auto fmt = mFFmpeg->GuessOutputFormat(selfmt->ToUTF8(), nullptr, nullptr);
2566 if (fmt == nullptr)
2567 {
2568 selfmt = nullptr;
2569 selfmtlong = nullptr;
2570 }
2571 }
2572
2573 int newselfmt = FetchCompatibleFormatList(
2574 mFFmpeg->GetAudacityCodecID(cdc->GetId()), selfmt);
2575
2576 if (newselfmt >= 0)
2577 mFormatList->Select(newselfmt);
2578
2579 EnableDisableControls(cdc.get(), selfmt);
2580 Layout();
2581 Fit();
2582 return;
2583}
2584
2587void ExportFFmpegOptions::OnFormatList(wxCommandEvent& WXUNUSED(event))
2588{
2590}
2591
2594void ExportFFmpegOptions::OnCodecList(wxCommandEvent& WXUNUSED(event))
2595{
2596 DoOnCodecList();
2597}
2598
2599
2602void ExportFFmpegOptions::OnOK(wxCommandEvent& WXUNUSED(event))
2603{
2605 return;
2606
2607 int selcdc = mCodecList->GetSelection();
2608 int selfmt = mFormatList->GetSelection();
2609 if (selcdc > -1) gPrefs->Write(wxT("/FileFormats/FFmpegCodec"),mCodecList->GetString(selcdc));
2610 if (selfmt > -1) gPrefs->Write(wxT("/FileFormats/FFmpegFormat"),mFormatList->GetString(selfmt));
2611 gPrefs->Flush();
2612
2615
2616 gPrefs->Flush();
2617
2618 EndModal(wxID_OK);
2619
2620 return;
2621}
2622
2623void ExportFFmpegOptions::OnGetURL(wxCommandEvent & WXUNUSED(event))
2624{
2625 HelpSystem::ShowHelp(this, L"Custom_FFmpeg_Export_Options");
2626}
2627
2628
2629#endif
@ AUDACITY_AV_CODEC_ID_GSM_MS
Definition: AVCodecID.h:324
@ AUDACITY_AV_CODEC_ID_IMC
Definition: AVCodecID.h:321
@ AUDACITY_AV_CODEC_ID_QCELP
Definition: AVCodecID.h:318
@ AUDACITY_AV_CODEC_ID_PCM_S16BE
Definition: AVCodecID.h:218
@ AUDACITY_AV_CODEC_ID_ADPCM_G726
Definition: AVCodecID.h:261
@ AUDACITY_AV_CODEC_ID_OPUS
Definition: AVCodecID.h:363
@ AUDACITY_AV_CODEC_ID_ADPCM_IMA_QT
Definition: AVCodecID.h:250
@ AUDACITY_AV_CODEC_ID_QDM2
Definition: AVCodecID.h:313
@ AUDACITY_AV_CODEC_ID_PCM_S24LE
Definition: AVCodecID.h:229
@ AUDACITY_AV_CODEC_ID_ADPCM_YAMAHA
Definition: AVCodecID.h:264
@ AUDACITY_AV_CODEC_ID_AC3
Definition: AVCodecID.h:297
@ AUDACITY_AV_CODEC_ID_MACE3
Definition: AVCodecID.h:303
@ AUDACITY_AV_CODEC_ID_PCM_MULAW
Definition: AVCodecID.h:223
@ AUDACITY_AV_CODEC_ID_PCM_S8
Definition: AVCodecID.h:221
@ AUDACITY_AV_CODEC_ID_VORBIS
Definition: AVCodecID.h:299
@ AUDACITY_AV_CODEC_ID_DVAUDIO
Definition: AVCodecID.h:300
@ AUDACITY_AV_CODEC_ID_PCM_S32BE
Definition: AVCodecID.h:226
@ AUDACITY_AV_CODEC_ID_DTS
Definition: AVCodecID.h:298
@ AUDACITY_AV_CODEC_ID_ALAC
Definition: AVCodecID.h:310
@ AUDACITY_AV_CODEC_ID_PCM_S16LE
Definition: AVCodecID.h:217
@ AUDACITY_AV_CODEC_ID_PCM_S32LE
Definition: AVCodecID.h:225
@ AUDACITY_AV_CODEC_ID_FLAC
Definition: AVCodecID.h:306
@ AUDACITY_AV_CODEC_ID_PCM_ALAW
Definition: AVCodecID.h:224
@ AUDACITY_AV_CODEC_ID_WMAV1
Definition: AVCodecID.h:301
@ AUDACITY_AV_CODEC_ID_NONE
Definition: AVCodecID.h:14
@ AUDACITY_AV_CODEC_ID_ADPCM_SWF
Definition: AVCodecID.h:263
@ AUDACITY_AV_CODEC_ID_VOXWARE
Definition: AVCodecID.h:326
@ AUDACITY_AV_CODEC_ID_NELLYMOSER
Definition: AVCodecID.h:328
@ AUDACITY_AV_CODEC_ID_GSM
Definition: AVCodecID.h:312
@ AUDACITY_AV_CODEC_ID_PCM_U8
Definition: AVCodecID.h:222
@ AUDACITY_AV_CODEC_ID_ROQ_DPCM
Definition: AVCodecID.h:290
@ AUDACITY_AV_CODEC_ID_TRUESPEECH
Definition: AVCodecID.h:315
@ AUDACITY_AV_CODEC_ID_MP2
Definition: AVCodecID.h:294
@ AUDACITY_AV_CODEC_ID_WMAPRO
Definition: AVCodecID.h:332
@ AUDACITY_AV_CODEC_ID_WMAV2
Definition: AVCodecID.h:302
@ AUDACITY_AV_CODEC_ID_AMR_NB
Definition: AVCodecID.h:286
@ AUDACITY_AV_CODEC_ID_MP3
Definition: AVCodecID.h:295
@ AUDACITY_AV_CODEC_ID_PCM_S24BE
Definition: AVCodecID.h:230
@ AUDACITY_AV_CODEC_ID_ATRAC3
Definition: AVCodecID.h:325
@ AUDACITY_AV_CODEC_ID_ADPCM_MS
Definition: AVCodecID.h:256
@ AUDACITY_AV_CODEC_ID_AMR_WB
Definition: AVCodecID.h:287
@ AUDACITY_AV_CODEC_ID_AAC
Definition: AVCodecID.h:296
@ AUDACITY_AV_CODEC_ID_ADPCM_IMA_WAV
Definition: AVCodecID.h:251
@ AUDACITY_AV_CODEC_ID_MACE6
Definition: AVCodecID.h:304
@ AUDACITY_AV_CODEC_ID_WMAVOICE
Definition: AVCodecID.h:331
@ AUDACITY_AV_CODEC_ID_ADPCM_CT
Definition: AVCodecID.h:262
R GuardedCall(const F1 &body, const F2 &handler=F2::Default(), F3 delayedHandler=DefaultDelayedHandlerAction) noexcept(noexcept(handler(std::declval< AudacityException * >())) &&noexcept(handler(nullptr)) &&noexcept(std::function< void(AudacityException *)>{std::move(delayedHandler)}))
Execute some code on any thread; catch any AudacityException; enqueue error report on the main thread...
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
END_EVENT_TABLE()
#define str(a)
EVT_BUTTON(wxID_NO, DependencyDialog::OnNo) EVT_BUTTON(wxID_YES
const TranslatableString name
Definition: Distortion.cpp:82
static const FileNames::FileTypes & FileTypes()
#define FFMPEG_EXPORT_CTRL_ID_ENTRIES
FFmpegExportCtrlID
static const wxChar * FFmpegExportCtrlIDNames[]
ChoiceSetting AACProfiles
AAC profiles.
#define OpenID
#define AV_CANMETA
std::unordered_map< wxString, FFmpegPreset > FFmpegPresetMap
@ FMT_OPUS
@ FMT_M4A
@ FMT_OTHER
@ FMT_AC3
@ FMT_WMA2
@ FMT_AMRNB
TranslatableString n_kbps(int n)
Definition: ExportMP3.cpp:130
int format
Definition: ExportPCM.cpp:56
bool FindFFmpegLibs(wxWindow *parent)
Definition: FFmpeg.cpp:310
bool LoadFFmpeg(bool showerror)
Definition: FFmpeg.cpp:46
#define AV_VERSION_INT(a, b, c)
Definition: FFmpegTypes.h:72
#define XXO(s)
Definition: Internat.h:44
#define XO(s)
Definition: Internat.h:31
#define _(s)
Definition: Internat.h:75
IteratorRange< Iterator > make_iterator_range(const Iterator &i1, const Iterator &i2)
Definition: MemoryX.h:423
FileConfig * gPrefs
Definition: Prefs.cpp:71
ByColumns_t ByColumns
Definition: Prefs.cpp:465
EffectReverbSettings preset
Definition: Reverb.cpp:46
@ eIsCreatingFromPrefs
Definition: ShuttleGui.h:48
@ eIsSavingToPrefs
Definition: ShuttleGui.h:49
@ eOkButton
Definition: ShuttleGui.h:600
@ eCancelButton
Definition: ShuttleGui.h:601
@ eHelpButton
Definition: ShuttleGui.h:604
#define S(N)
Definition: ToChars.cpp:64
std::vector< TranslatableString > TranslatableStrings
std::vector< Attribute > AttributesList
Definition: XMLTagHandler.h:40
virtual AVCodecIDFwd GetId() const noexcept=0
bool TransferDataToWindow() override
bool TransferDataFromWindow() override
ExportFFmpegAACOptions(wxWindow *parent, int format)
void PopulateOrExchange(ShuttleGui &S)
static const int iAC3SampleRates[]
ExportFFmpegAC3Options(wxWindow *parent, int format)
bool TransferDataToWindow() override
bool TransferDataFromWindow() override
void PopulateOrExchange(ShuttleGui &S)
ExportFFmpegAMRNBOptions(wxWindow *parent, int format)
void PopulateOrExchange(ShuttleGui &S)
bool TransferDataFromWindow() override
void OnOpen(wxCommandEvent &evt)
void PopulateOrExchange(ShuttleGui &S)
bool TransferDataToWindow() override
bool TransferDataFromWindow() override
ExportFFmpegOPUSOptions(wxWindow *parent, int format)
void PopulateOrExchange(ShuttleGui &S)
Custom FFmpeg export dialog.
void OnExportPresets(wxCommandEvent &event)
void OnSavePreset(wxCommandEvent &event)
void OnImportPresets(wxCommandEvent &event)
void FindSelectedCodec(wxString **name, wxString **longname)
Finds the codec currently selected and returns its name and description.
wxArrayStringEx mCodecNames
void OnDeletePreset(wxCommandEvent &event)
wxArrayString mShownFormatLongNames
void FetchCodecList()
Retrieves codec list from libavcodec.
static CompatibilityEntry CompatibilityList[]
std::unique_ptr< FFmpegPresets > mPresets
int FetchCompatibleFormatList(AudacityAVCodecID id, wxString *selfmt)
void OnCodecList(wxCommandEvent &event)
void PopulateOrExchange(ShuttleGui &S)
void FindSelectedFormat(wxString **name, wxString **longname)
Finds the format currently selected and returns its name and description.
void OnLoadPreset(wxCommandEvent &event)
wxArrayStringEx mFormatNames
wxArrayString mShownCodecLongNames
wxArrayString mShownCodecNames
int FetchCompatibleCodecList(const wxChar *fmt, AudacityAVCodecID id)
wxArrayString mCodecLongNames
void OnFormatList(wxCommandEvent &event)
void OnAllFormats(wxCommandEvent &event)
wxStaticText * mFormatName
void OnOK(wxCommandEvent &event)
ExportFFmpegOptions(wxWindow *parent)
void OnAllCodecs(wxCommandEvent &event)
bool SavePreset(bool bCheckForOverwrite)
void FetchFormatList()
Retrieves format list from libavformat.
static ExposedFormat fmts[]
List of export types.
static ApplicableFor apptable[]
wxArrayString mShownFormatNames
void OnGetURL(wxCommandEvent &event)
wxArrayStringEx mPresetNames
void EnableDisableControls(AVCodecWrapper *cdc, wxString *selfmt)
std::shared_ptr< FFmpegFunctions > mFFmpeg
wxArrayString mFormatLongNames
bool TransferDataFromWindow() override
void PopulateOrExchange(ShuttleGui &S)
bool TransferDataToWindow() override
static const int iWMASampleRates[]
ExportFFmpegWMAOptions(wxWindow *parent, int format)
wxArrayString mControlState
void LoadPreset(ExportFFmpegOptions *parent, wxString &name)
FFmpegPresetMap mPresets
bool SavePreset(ExportFFmpegOptions *parent, wxString &name)
void ImportPresets(wxString &filename)
bool OverwriteIsOk(wxString &name)
XMLTagHandler * HandleXMLChild(const std::string_view &tag) override
void DeletePreset(wxString &name)
FFmpegPreset * mPreset
bool HandleXMLTag(const std::string_view &tag, const AttributesList &attrs) override
void WriteXMLHeader(XMLWriter &xmlFile) const
void GetPresetList(wxArrayString &list)
void WriteXML(XMLWriter &xmlFile) const
void ExportPresets(wxString &filename)
FFmpegPreset * FindPreset(wxString &name)
virtual bool Flush(bool bCurrentOnly=false) wxOVERRIDE
Definition: FileConfig.cpp:143
virtual wxString GetPath() const
virtual int ShowModal()
FILES_API const FileType XMLFiles
Definition: FileNames.h:74
std::vector< FileType > FileTypes
Definition: FileNames.h:76
FILES_API const FileType AllFiles
Definition: FileNames.h:71
Abstract base class used in importing a file.
static void ShowHelp(wxWindow *parent, const FilePath &localFileName, const URLString &remoteURL, bool bModal=false, bool alwaysDefaultBrowser=false)
Definition: HelpSystem.cpp:237
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:631
Holds a msgid for the translation catalog; may also bind format arguments.
Reads a file and passes the results through an XMLTagHandler.
Definition: XMLFileReader.h:19
bool Parse(XMLTagHandler *baseHandler, const FilePath &fname)
Wrapper to output XML data to files.
Definition: XMLWriter.h:84
This class is an interface which should be implemented by classes which wish to be able to load and s...
Definition: XMLTagHandler.h:42
Base class for XMLFileWriter and XMLStringWriter that provides the general functionality for creating...
Definition: XMLWriter.h:26
FILES_API FilePath DataDir()
Audacity user data directory.
const TranslatableStrings PredictionOrderMethodNames
Prediction order method - names.
ChoiceSetting OPUSBitrate
Bit Rates supported by OPUS encoder. Setting bit rate to other values will not result in different fi...
const TranslatableStrings WMABitRateNames
Bit Rates supported by WMA encoder. Setting bit rate to other values will not result in different fil...
std::string ToUTF8(const std::wstring &wstr)
Entry for the Applicability table.
int control
control ID
Describes format-codec compatibility.
const wxChar * fmt
format, recognizable by guess_format()
AudacityAVCodecID codec
codec ID
Describes export type.
static std::shared_ptr< FFmpegFunctions > Load(bool fromUserPathOnly=false)