71#include <wx/mimetype.h>
73#include <wx/textctrl.h>
76#include <rapidjson/document.h>
166 XO(
"220-260 kbps (Best Quality)"),
175 XO(
"45-85 kbps (Smaller files)"),
185 XO(
"Insane, 320 kbps"),
186 XO(
"Extreme, 220-260 kbps"),
187 XO(
"Standard, 170-210 kbps"),
188 XO(
"Medium, 145-185 kbps"),
251 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
283 mValues[option.id] = option.defaultValue;
288 return static_cast<int>(
mOptions.size());
293 if(index >= 0 && index <
static_cast<int>(
mOptions.size()))
303 const auto it =
mValues.find(
id);
306 if(value.index() != it->second.index())
315 const auto mode = *std::get_if<std::string>(&value);
344 const auto it =
mValues.find(
id);
356 int highrate = 48000;
361 if (rmode ==
"ABR") {
366 else if (bitrate < 32 || bitrate == 144) {
370 else if (rmode ==
"CBR") {
376 else if (bitrate < 32 || bitrate == 144) {
384 if(rate >= lowrate && rate <= highrate)
385 result.push_back(rate);
393 if(config.
Read(
wxT(
"/FileFormats/MP3RateModeChoice"), &mode))
399 if(config.
Read(
wxT(
"/FileFormats/MP3RateMode"), &index))
414 config.
Write(
wxT(
"/FileFormats/MP3RateModeChoice"), wxString(*std::get_if<std::string>(&it->second)));
417 config.
Write(
wxT(
"/FileFormats/MP3SetRate"), *std::get_if<int>(&it->second));
419 config.
Write(
wxT(
"/FileFormats/MP3AbrRate"), *std::get_if<int>(&it->second));
421 config.
Write(
wxT(
"/FileFormats/MP3CbrRate"), *std::get_if<int>(&it->second));
423 config.
Write(
wxT(
"/FileFormats/MP3VbrRate"), *std::get_if<int>(&it->second));
437 else if(mode ==
"ABR")
439 else if(mode ==
"CBR")
441 else if(mode ==
"VBR")
450 return (value >= 0 && value < nValues) ? value : defaultValue;
456 iter = std::find( start, finish, value );
457 return ( iter != finish ) ? value : defaultValue;
463 iter = std::find( start, finish, value );
464 return ( iter != finish ) ?
static_cast<int>( iter - start ) : defaultIndex;
473#define ID_BROWSE 5000
480#ifndef DISABLE_DYNAMIC_LOADING_LAME
493 mTypes = std::move( types );
503 S.StartVerticalLay(
true);
506 XO(
"Audacity needs the file %s to create MP3s.")
510 S.StartHorizontalLay(wxALIGN_LEFT,
true);
514 S.EndHorizontalLay();
516 S.StartMultiColumn(2, wxEXPAND);
519 if (
mLibPath.GetFullPath().empty()) {
522 wxString::Format(
_(
"To find %s, click here -->"),
mName), 0);
530 XO(
"To get a free copy of LAME, click here -->"),
true);
532 S.Id(
ID_DLOAD).AddButton(
XXO(
"Download"), wxALIGN_RIGHT);
536 S.AddStandardButtons();
542 SetMinSize(GetSize());
553 auto question =
XO(
"Where is %s?").Format(
mName );
555 wxString path =
SelectFile(FileNames::Operation::_None,
561 wxFD_OPEN | wxRESIZE_BORDER,
583#ifndef DISABLE_DYNAMIC_LOADING_LAME
593 DECLARE_EVENT_TABLE()
596#ifndef DISABLE_DYNAMIC_LOADING_LAME
607#ifndef DISABLE_DYNAMIC_LOADING_LAME
618 unsigned char * mp3buf,
619 const int mp3buf_size);
625 unsigned char * mp3buf,
626 const int mp3buf_size);
630 unsigned char* mp3buf,
653#if defined(__WXMSW__)
687 BYTE btReserved[125];
705#ifndef DISABLE_DYNAMIC_LOADING_LAME
737 int EncodeBuffer(
float inbuffer[],
unsigned char outbuffer[]);
739 unsigned char outbuffer[]);
743 unsigned char outbuffer[]);
748 bool PutInfoTag(wxFFile & f, wxFileOffset off);
753#ifndef DISABLE_DYNAMIC_LOADING_LAME
759#if defined(__WXMSW__)
769#ifndef DISABLE_DYNAMIC_LOADING_LAME
794#if defined(__WXMSW__)
820#ifdef MP3_EXPORT_BUILT_IN
826#ifndef DISABLE_DYNAMIC_LOADING_LAME
832#ifndef DISABLE_DYNAMIC_LOADING_LAME
849#ifndef DISABLE_DYNAMIC_LOADING_LAME
871 if (fd.ShowModal() == wxID_CANCEL) {
877 if (!::wxFileExists(path)) {
894#if defined(__WXMSW__)
905 wxLogMessage(
wxT(
"Attempting to load LAME from previously defined path"));
911 wxLogMessage(
wxT(
"Attempting to load LAME from system search paths"));
918 wxLogMessage(
wxT(
"Attempting to load LAME from builtin path"));
926 wxLogMessage(
wxT(
"(Maybe) ask user for library"));
934#if defined(__WXMSW__)
939 wxLogMessage(
wxT(
"Failed to locate LAME library"));
944 wxLogMessage(
wxT(
"LAME library successfully loaded"));
978 wxLogMessage(
wxT(
"Using internal LAME"));
982#ifdef MP3_EXPORT_BUILT_IN
1011#if defined(__WXMSW__)
1030 wxLogMessage(
wxT(
"Loading LAME from %s"), libpath);
1032#ifndef DISABLE_DYNAMIC_LOADING_LAME
1033 if (!
lame_lib.Load(libpath, wxDL_LAZY)) {
1034 wxLogMessage(
wxT(
"load failed"));
1038 wxLogMessage(
wxT(
"Actual LAME path %s"),
1048 lame_lib.GetSymbol(
wxT(
"lame_encode_buffer_ieee_float"));
1050 lame_lib.GetSymbol(
wxT(
"lame_encode_buffer_interleaved_ieee_float"));
1057 lame_lib.GetSymbol(
wxT(
"lame_set_in_samplerate"));
1059 lame_lib.GetSymbol(
wxT(
"lame_set_out_samplerate"));
1071 lame_lib.GetSymbol(
wxT(
"lame_set_VBR_min_bitrate_kbps"));
1077 lame_lib.GetSymbol(
wxT(
"lame_set_error_protection"));
1079 lame_lib.GetSymbol(
wxT(
"lame_set_disable_reservoir"));
1085 lame_lib.GetSymbol(
wxT(
"lame_get_lametag_frame"));
1088#if defined(__WXMSW__)
1115 wxLogMessage(
wxT(
"Failed to find a required symbol in the LAME library."));
1116#if defined(__WXMSW__)
1122"You are linking to lame_enc.dll v%d.%d. This version is not compatible with Audacity %d.%d.%d.\nPlease download the latest version of 'LAME for Audacity'.")
1152#ifndef DISABLE_DYNAMIC_LOADING_LAME
1161#ifndef DISABLE_DYNAMIC_LOADING_LAME
1172#ifndef DISABLE_DYNAMIC_LOADING_LAME
1249 mode = JOINT_STEREO;
1287 unsigned char outbuffer[])
1308 unsigned char outbuffer[])
1328#if defined(DISABLE_DYNAMIC_LOADING_LAME)
1349 if ( !f.Seek(off, wxFromStart))
1354#if defined(__WXMSW__)
1374#if defined(__WXMSW__)
1379 wxRegKey
reg(
wxT(
"HKEY_LOCAL_MACHINE\\Software\\Lame for Audacity"));
1383 wxLogMessage(
wxT(
"LAME registry key exists."));
1384 reg.QueryValue(
wxT(
"InstallPath"), path);
1387 wxLogMessage(
wxT(
"LAME registry key does not exist."));
1390 wxLogMessage(
wxT(
"Library path is: ") + path);
1397 return wxT(
"lame_enc.dll");
1403 {
XO(
"Only lame_enc.dll"), {
wxT(
"lame_enc.dll") } },
1409#elif defined(__WXMAC__)
1416 path =
wxT(
"/Library/Application Support/audacity/libs");
1422 path =
wxT(
"/usr/local/lib/audacity");
1428 return wxT(
"/Library/Application Support/audacity/libs");
1433 if (
sizeof(
void*) == 8)
1434 return wxT(
"libmp3lame64bit.dylib");
1435 return wxT(
"libmp3lame.dylib");
1441 (
sizeof(
void*) == 8)
1443 XO(
"Only libmp3lame64bit.dylib"), {
wxT(
"libmp3lame64bit.dylib") }
1446 XO(
"Only libmp3lame.dylib"), {
wxT(
"libmp3lame.dylib") }
1454#elif defined(__OpenBSD__)
1464 return wxT(
"libmp3lame.so");
1470 {
XO(
"Only libmp3lame.so"), {
wxT(
"libmp3lame.so") } },
1471 {
XO(
"Primary shared object files"), {
wxT(
"so") },
true },
1472 {
XO(
"Extended libraries"), {
wxT(
"so*") },
true },
1487 return wxT(
"libmp3lame.so.0");
1493 {
XO(
"Only libmp3lame.so.0"), {
wxT(
"libmp3lame.so.0") } },
1494 {
XO(
"Primary shared object files"), {
wxT(
"so") },
true },
1495 {
XO(
"Extended libraries"), {
wxT(
"so*") },
true },
1505 wxPrintf(
wxT(
"\n\nLame_enc configuration options:\n"));
1506 wxPrintf(
wxT(
"==========================================================\n"));
1508 wxPrintf(
wxT(
"version =%d\n"),lame_get_version( gfp ) );
1509 wxPrintf(
wxT(
"Layer =3\n"));
1510 wxPrintf(
wxT(
"mode ="));
1511 switch ( lame_get_mode( gfp ) )
1513 case STEREO: wxPrintf(
wxT(
"Stereo\n" ));
break;
1514 case JOINT_STEREO: wxPrintf(
wxT(
"Joint-Stereo\n" ));
break;
1515 case DUAL_CHANNEL: wxPrintf(
wxT(
"Forced Stereo\n" ));
break;
1516 case MONO: wxPrintf(
wxT(
"Mono\n" ));
break;
1518 default: wxPrintf(
wxT(
"Error (unknown)\n" ));
break;
1521 wxPrintf(
wxT(
"Input sample rate =%.1f kHz\n"), lame_get_in_samplerate( gfp ) /1000.0 );
1522 wxPrintf(
wxT(
"Output sample rate =%.1f kHz\n"), lame_get_out_samplerate( gfp ) /1000.0 );
1524 wxPrintf(
wxT(
"bitrate =%d kbps\n"), lame_get_brate( gfp ) );
1525 wxPrintf(
wxT(
"Quality Setting =%d\n"), lame_get_quality( gfp ) );
1527 wxPrintf(
wxT(
"Low pass frequency =%d\n"), lame_get_lowpassfreq( gfp ) );
1528 wxPrintf(
wxT(
"Low pass width =%d\n"), lame_get_lowpasswidth( gfp ) );
1530 wxPrintf(
wxT(
"High pass frequency =%d\n"), lame_get_highpassfreq( gfp ) );
1531 wxPrintf(
wxT(
"High pass width =%d\n"), lame_get_highpasswidth( gfp ) );
1533 wxPrintf(
wxT(
"No short blocks =%d\n"), lame_get_no_short_blocks( gfp ) );
1534 wxPrintf(
wxT(
"Force short blocks =%d\n"), lame_get_force_short_blocks( gfp ) );
1536 wxPrintf(
wxT(
"de-emphasis =%d\n"), lame_get_emphasis( gfp ) );
1537 wxPrintf(
wxT(
"private flag =%d\n"), lame_get_extension( gfp ) );
1539 wxPrintf(
wxT(
"copyright flag =%d\n"), lame_get_copyright( gfp ) );
1540 wxPrintf(
wxT(
"original flag =%d\n"), lame_get_original( gfp ) );
1541 wxPrintf(
wxT(
"CRC =%s\n"), lame_get_error_protection( gfp ) ?
wxT(
"on") :
wxT(
"off") );
1542 wxPrintf(
wxT(
"Fast mode =%s\n"), ( lame_get_quality( gfp ) )?
wxT(
"enabled") :
wxT(
"disabled") );
1543 wxPrintf(
wxT(
"Force mid/side stereo =%s\n"), ( lame_get_force_ms( gfp ) )?
wxT(
"enabled"):
wxT(
"disabled") );
1544 wxPrintf(
wxT(
"Padding Type =%d\n"), (
int) lame_get_padding_type( gfp ) );
1545 wxPrintf(
wxT(
"Disable Reservoir =%d\n"), lame_get_disable_reservoir( gfp ) );
1546 wxPrintf(
wxT(
"Allow diff-short =%d\n"), lame_get_allow_diff_short( gfp ) );
1547 wxPrintf(
wxT(
"Interchannel masking =%d\n"), lame_get_interChRatio( gfp ) );
1548 wxPrintf(
wxT(
"Strict ISO Encoding =%s\n"), ( lame_get_strict_ISO( gfp ) ) ?
wxT(
"Yes"):
wxT(
"No"));
1549 wxPrintf(
wxT(
"Scale =%5.2f\n"), lame_get_scale( gfp ) );
1551 wxPrintf(
wxT(
"VBR =%s, VBR_q =%d, VBR method ="),
1552 ( lame_get_VBR( gfp ) !=vbr_off ) ?
wxT(
"enabled"):
wxT(
"disabled"),
1553 lame_get_VBR_q( gfp ) );
1555 switch ( lame_get_VBR( gfp ) )
1557 case vbr_off: wxPrintf(
wxT(
"vbr_off\n" ));
break;
1558 case vbr_mt : wxPrintf(
wxT(
"vbr_mt \n" ));
break;
1559 case vbr_rh : wxPrintf(
wxT(
"vbr_rh \n" ));
break;
1560 case vbr_mtrh: wxPrintf(
wxT(
"vbr_mtrh \n" ));
break;
1562 wxPrintf(
wxT(
"vbr_abr (average bitrate %d kbps)\n"), lame_get_VBR_mean_bitrate_kbps( gfp ) );
1565 wxPrintf(
wxT(
"error, unknown VBR setting\n"));
1569 wxPrintf(
wxT(
"Vbr Min bitrate =%d kbps\n"), lame_get_VBR_min_bitrate_kbps( gfp ) );
1570 wxPrintf(
wxT(
"Vbr Max bitrate =%d kbps\n"), lame_get_VBR_max_bitrate_kbps( gfp ) );
1572 wxPrintf(
wxT(
"Write VBR Header =%s\n"), ( lame_get_bWriteVbrTag( gfp ) ) ?
wxT(
"Yes"):
wxT(
"No"));
1573 wxPrintf(
wxT(
"VBR Hard min =%d\n"), lame_get_VBR_hard_min( gfp ) );
1575 wxPrintf(
wxT(
"ATH Only =%d\n"), lame_get_ATHonly( gfp ) );
1576 wxPrintf(
wxT(
"ATH short =%d\n"), lame_get_ATHshort( gfp ) );
1577 wxPrintf(
wxT(
"ATH no =%d\n"), lame_get_noATH( gfp ) );
1578 wxPrintf(
wxT(
"ATH type =%d\n"), lame_get_ATHtype( gfp ) );
1579 wxPrintf(
wxT(
"ATH lower =%f\n"), lame_get_ATHlower( gfp ) );
1580 wxPrintf(
wxT(
"ATH aa =%d\n"), lame_get_athaa_type( gfp ) );
1581 wxPrintf(
wxT(
"ATH aa loudapprox =%d\n"), lame_get_athaa_loudapprox( gfp ) );
1582 wxPrintf(
wxT(
"ATH aa sensitivity =%f\n"), lame_get_athaa_sensitivity( gfp ) );
1584 wxPrintf(
wxT(
"Experimental nspsytune =%d\n"), lame_get_exp_nspsytune( gfp ) );
1585 wxPrintf(
wxT(
"Experimental X =%d\n"), lame_get_experimentalX( gfp ) );
1586 wxPrintf(
wxT(
"Experimental Y =%d\n"), lame_get_experimentalY( gfp ) );
1587 wxPrintf(
wxT(
"Experimental Z =%d\n"), lame_get_experimentalZ( gfp ) );
1613 double t0,
double t1,
bool selectedOnly,
1616 const Tags* tags)
override;
1622 static int AskResample(
int bitrate,
int rate,
int lowrate,
int highrate);
1625 static void AddFrame(
struct id3_tag *tp,
const wxString & n,
const wxString & v,
const char *
name);
1643 std::unique_ptr<ExportOptionsEditor>
1648 std::vector<std::string>
GetMimeTypes(
int)
const override;
1651 int formatIndex,
const rapidjson::Value& document,
1665 wxT(
"MP3"),
XO(
"MP3 Files"), {
wxT(
"mp3") }, 2u,
true
1669std::unique_ptr<ExportOptionsEditor>
1672 return std::make_unique<MP3ExportOptionsEditor>(listener);
1677 return std::make_unique<MP3ExportProcessor>();
1682 return {
"audio/mpeg" };
1686 int formatIndex,
const rapidjson::Value& document,
1689 if (!document.IsObject())
1694 if (document.HasMember(
"mode"))
1696 auto& mode = document[
"mode"];
1697 if (!mode.IsString())
1700 auto value = mode.GetString();
1702 if (value == std::string_view {
"SET" })
1704 else if (value == std::string_view {
"VBR" })
1706 else if (value == std::string_view {
"ABR" })
1708 else if (value == std::string_view {
"CBR" })
1718 if (document.HasMember(
"quality"))
1720 auto& qualityMember = document[
"quality"];
1722 if (!qualityMember.IsInt())
1725 const auto quality = qualityMember.GetInt();
1747 parameters.push_back(std::make_tuple(qualityMode, quality));
1757#ifndef DISABLE_DYNAMIC_LOADING_LAME
1764 .Caption(
XO(
"Error")));
1778 double t0,
double t1,
bool selectionOnly,
1781 const Tags* metadata)
1790#ifdef DISABLE_DYNAMIC_LOADING_LAME
1806 throw ExportException(
_(
"Not a valid or supported MP3 encoding library!"));
1811 int highrate = 48000;
1819 std::string(
"CBR"));
1821 if (rmode ==
"SET") {
1822 quality = ExportPluginHelpers::GetParameterValue<int>(
1829 else if (rmode ==
"VBR") {
1830 quality = ExportPluginHelpers::GetParameterValue<int>(
1837 else if (rmode ==
"ABR") {
1844 if (bitrate > 160) {
1847 else if (bitrate < 32 || bitrate == 144) {
1856 if (bitrate > 160) {
1859 else if (bitrate < 32 || bitrate == 144) {
1866 (rate < lowrate) || (rate > highrate)) {
1870 auto const bestRateIt = std::lower_bound(
sampRates.begin(),
1872 rate = (bestRateIt ==
sampRates.end()) ? highrate : *bestRateIt;
1874 if (rate < lowrate) {
1877 else if (rate > highrate) {
1884 (rate < lowrate) || (rate > highrate)) {
1887 rate =
AskResample(bitrate, rate, lowrate, highrate);
1901 if (metadata ==
nullptr)
1905 if (!
context.outFile.Open(fName.GetFullPath(),
wxT(
"w+b"))) {
1911 if (
context.id3len && !endOfFile) {
1923 if (
context.bufferSize == 0) {
1928 if (rmode ==
"SET") {
1929 context.status = (selectionOnly ?
1930 XO(
"Exporting selected audio with %s preset") :
1931 XO(
"Exporting the audio with %s preset"))
1934 else if (rmode ==
"VBR") {
1935 context.status = (selectionOnly ?
1936 XO(
"Exporting selected audio with VBR quality %s") :
1937 XO(
"Exporting the audio with VBR quality %s"))
1941 context.status = (selectionOnly ?
1942 XO(
"Exporting selected audio at %d Kbps") :
1943 XO(
"Exporting the audio at %d Kbps"))
1968 auto blockLen =
context.mixer->Process();
1972 float *mixed = (
float *)
context.mixer->GetBuffer();
1974 if ((
int)blockLen <
context.inSamples) {
1997 if (bytes > (
int)
context.outFile.Write(buffer.get(), bytes)) {
2017 if (bytes > (
int)
context.outFile.Write(buffer.get(), bytes)) {
2044 return exportResult;
2056 S.StartVerticalLay();
2059 S.StartStatic(
XO(
"Resample"));
2061 S.StartHorizontalLay(wxALIGN_CENTER,
false);
2066"The project sample rate (%d) is not supported by the MP3\nfile format. ")
2069"The project sample rate (%d) and bit rate (%d kbps) combination is not\nsupported by the MP3 file format. ")
2070 .
Format( rate, bitrate ))
2071 +
XO(
"You may resample to one of the rates below.")
2074 S.EndHorizontalLay();
2076 S.StartHorizontalLay(wxALIGN_CENTER,
false);
2078 choice =
S.AddChoice(
XXO(
"Sample Rates"),
2081 for (
size_t ii = 0, nn =
sampRates.size(); ii < nn; ++ii) {
2082 int label = sampRates[ii];
2083 if (label >= lowrate && label <= highrate) {
2084 choices.push_back( Verbatim(
"%d" ).Format( label ) );
2091 std::max( 0, selected )
2094 S.EndHorizontalLay();
2098 S.AddStandardButtons();
2104 d.SetMinSize(d.GetSize());
2107 if (d.ShowModal() == wxID_CANCEL) {
2111 return wxAtoi(choice->GetStringSelection());
2115struct id3_tag_deleter {
2116 void operator () (id3_tag *p)
const {
if (p) id3_tag_delete(p); }
2118using id3_tag_holder = std::unique_ptr<id3_tag, id3_tag_deleter>;
2125 id3_tag_holder tp { id3_tag_new() };
2127 for (
const auto &pair : tags->
GetRange()) {
2128 const auto &n = pair.first;
2129 const auto &v = pair.second;
2130 const char *
name =
"TXXX";
2133 name = ID3_FRAME_TITLE;
2136 name = ID3_FRAME_ARTIST;
2139 name = ID3_FRAME_ALBUM;
2141 else if (n.CmpNoCase(
TAG_YEAR) == 0) {
2144 AddFrame(tp.get(), n, v,
"TYER");
2145 name = ID3_FRAME_YEAR;
2148 name = ID3_FRAME_GENRE;
2151 name = ID3_FRAME_COMMENT;
2154 name = ID3_FRAME_TRACK;
2157 AddFrame(tp.get(), n, v,
name);
2160 tp->options &= (~ID3_TAG_OPTION_COMPRESSION);
2165 #ifdef ID3_TAG_HAS_TAG_OPTION_ID3V2_3
2166 tp->options |= ID3_TAG_OPTION_ID3V2_3;
2173 len = id3_tag_render(tp.get(), 0);
2175 len = id3_tag_render(tp.get(), (id3_byte_t *)buffer.get());
2184void MP3ExportProcessor::AddFrame(
struct id3_tag *tp,
const wxString & n,
const wxString & v,
const char *
name)
2186 struct id3_frame *frame = id3_frame_new(
name);
2188 if (!n.IsAscii() || !v.IsAscii()) {
2189 id3_field_settextencoding(id3_frame_field(frame, 0), ID3_FIELD_TEXTENCODING_UTF_16);
2192 id3_field_settextencoding(id3_frame_field(frame, 0), ID3_FIELD_TEXTENCODING_ISO_8859_1);
2196 id3_utf8_ucs4duplicate((id3_utf8_t *) (
const char *) v.mb_str(wxConvUTF8)) };
2198 if (strcmp(
name, ID3_FRAME_COMMENT) == 0) {
2204 struct id3_frame *frame2 = id3_frame_new(
name);
2205 id3_field_setfullstring(id3_frame_field(frame2, 3), ucs4.get());
2206 id3_field *f2 = id3_frame_field(frame2, 1);
2207 memset(f2->immediate.value, 0,
sizeof(f2->immediate.value));
2208 id3_tag_attachframe(tp, frame2);
2210 id3_field_setfullstring(id3_frame_field(frame, 3), ucs4.get());
2212 else if (strcmp(
name,
"TXXX") == 0) {
2213 id3_field_setstring(id3_frame_field(frame, 2), ucs4.get());
2215 ucs4.reset(id3_utf8_ucs4duplicate((id3_utf8_t *) (
const char *) n.mb_str(wxConvUTF8)));
2217 id3_field_setstring(id3_frame_field(frame, 1), ucs4.get());
2220 auto addr = ucs4.get();
2221 id3_field_setstrings(id3_frame_field(frame, 1), 1, &addr);
2224 id3_tag_attachframe(tp, frame);
2229 []{
return std::make_unique< ExportMP3 >(); }
2239 auto versionString =
XO(
"MP3 export library not found");
2241#ifndef DISABLE_DYNAMIC_LOADING_LAME
2249#ifdef MP3_EXPORT_BUILT_IN
2250 versionString.Join(
XO(
"(Built-in)"),
" " );
2253#ifndef DISABLE_DYNAMIC_LOADING_LAME
2257 return versionString;
Toolkit-neutral facade for basic user interface services.
EVT_BUTTON(wxID_NO, DependencyDialog::OnNo) EVT_BUTTON(wxID_YES
const TranslatableString name
int lame_set_VBR_t(lame_global_flags *, vbr_mode)
static const std::vector< ExportValue > fixRateValues
int lame_set_bWriteVbrTag_t(lame_global_flags *, int)
static const std::vector< int > sampRates
int CDECL lame_encode_buffer_interleaved_ieee_float_t(lame_t gfp, const float pcm[], const int nsamples, unsigned char *mp3buf, const int mp3buf_size)
static const TranslatableStrings varRateNames
static const TranslatableStrings fixRateNames
const char * get_lame_version_t(void)
int lame_set_VBR_q_t(lame_global_flags *, int)
int lame_set_in_samplerate_t(lame_global_flags *, int)
int lame_close_t(lame_global_flags *)
TranslatableString n_kbps(int n)
TranslatableString GetMP3Version(wxWindow *parent, bool prompt)
void lame_mp3_tags_fid_t(lame_global_flags *, FILE *)
int lame_set_VBR_min_bitrate_kbps_t(lame_global_flags *, int)
int CDECL lame_encode_buffer_ieee_float_t(lame_t gfp, const float pcm_l[], const float pcm_r[], const int nsamples, unsigned char *mp3buf, const int mp3buf_size)
static ExportPluginRegistry::RegisteredPlugin sRegisteredPlugin
int lame_set_error_protection_t(lame_global_flags *, int)
unsigned long beWriteInfoTag_t(lame_global_flags *, char *)
static const TranslatableStrings setRateNames
int lame_set_out_samplerate_t(lame_global_flags *, int)
int lame_set_quality_t(lame_global_flags *, int)
const std::initializer_list< ExportOption > MP3Options
void beVersion_t(be_version *)
int lame_set_preset_t(lame_global_flags *, int)
size_t lame_get_lametag_frame_t(const lame_global_flags *, unsigned char *buffer, size_t size)
static const TranslatableStrings setRateNamesShort
int lame_set_disable_reservoir_t(lame_global_flags *, int)
lame_global_flags * lame_init_t(void)
int lame_encode_flush_t(lame_global_flags *gf, unsigned char *mp3buf, int size)
int lame_set_num_channels_t(lame_global_flags *, int)
int lame_set_mode_t(lame_global_flags *, MPEG_mode)
int lame_set_brate_t(lame_global_flags *, int)
int lame_init_params_t(lame_global_flags *)
std::variant< bool, int, double, std::string > ExportValue
A type of option values (parameters) used by exporting plugins.
XXO("&Cut/Copy/Paste Toolbar")
IteratorRange< Iterator > make_iterator_range(const Iterator &i1, const Iterator &i2)
std::unique_ptr< Character[], freer > MallocString
audacity::BasicSettings * gPrefs
EffectReverbSettings preset
FilePath SelectFile(FileNames::Operation op, const TranslatableString &message, const FilePath &default_path, const FilePath &default_filename, const FileExtension &default_extension, const FileTypes &fileTypes, int flags, wxWindow *parent)
declares abstract base class Track, TrackList, and iterators over TrackList
TranslatableString Verbatim(wxString str)
Require calls to the one-argument constructor to go through this distinct global function name.
std::vector< TranslatableString > TranslatableStrings
void reinit(Integral count, bool initialize=false)
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
bool CheckFileName(wxFileName &filename, int format) const override
int GetFormatCount() const override
std::vector< std::string > GetMimeTypes(int) const override
bool ParseConfig(int formatIndex, const rapidjson::Value &document, ExportProcessor::Parameters ¶meters) const override
Attempt to parse configuration JSON object and produce a suitable set of parameters....
std::unique_ptr< ExportProcessor > CreateProcessor(int format) const override
std::unique_ptr< ExportOptionsEditor > CreateOptionsEditor(int, ExportOptionsEditor::Listener *listener) const override
Creates format-dependent options editor, that is used to create a valid set of parameters to be used ...
FormatInfo GetFormatInfo(int) const override
Returns FormatInfo structure for given index if it's valid, or a default one. FormatInfo::format isn'...
Listener object that is used to report on option changes.
virtual void OnExportOptionChangeEnd()=0
Called after OnExportOptionChange
virtual void OnExportOptionChangeBegin()=0
Called before OnExportOptionChange
virtual void OnExportOptionChange(const ExportOption &option)=0
Called when option change.
virtual void OnSampleRateListChange()=0
Editor objects are used to retrieve a set of export options, and configure exporting parameters accor...
std::vector< int > SampleRateList
static T GetParameterValue(const ExportProcessor::Parameters ¶meters, int id, T defaultValue=T())
static ExportResult UpdateProgress(ExportProcessorDelegate &delegate, Mixer &mixer, double t0, double t1)
Sends progress update to delegate and retrieves state update from it. Typically used inside each expo...
static std::unique_ptr< Mixer > CreateMixer(const AudacityProject &project, bool selectionOnly, double startTime, double stopTime, unsigned numOutChannels, size_t outBufferSize, bool outInterleaved, double outRate, sampleFormat outFormat, MixerOptions::Downmix *mixerSpec)
virtual void SetStatusString(const TranslatableString &str)=0
std::vector< std::tuple< ExportOptionID, ExportValue > > Parameters
std::vector< FileType > FileTypes
FILES_API const FileType AllFiles
FILES_API const FileType DynamicLibraries
void OnBrowse(wxCommandEvent &WXUNUSED(event))
FindDialog(wxWindow *parent, wxString path, wxString name, FileNames::FileTypes types)
FileNames::FileTypes mTypes
void PopulateOrExchange(ShuttleGui &S)
void OnDownload(wxCommandEvent &WXUNUSED(event))
static void ShowHelp(wxWindow *parent, const FilePath &localFileName, const URLString &remoteURL, bool bModal=false, bool alwaysDefaultBrowser=false)
int GetOptionsCount() const override
bool GetOption(int index, ExportOption &option) const override
std::unordered_map< int, ExportValue > mValues
void OnModeChange(const std::string &mode)
bool SetValue(int id, const ExportValue &value) override
SampleRateList GetSampleRateList() const override
bool GetValue(int id, ExportValue &value) const override
MP3ExportOptionsEditor(Listener *listener)
void Load(const audacity::BasicSettings &config) override
std::vector< ExportOption > mOptions
void Store(audacity::BasicSettings &config) const override
static int AskResample(int bitrate, int rate, int lowrate, int highrate)
bool Initialize(AudacityProject &project, const Parameters ¶meters, const wxFileNameWrapper &filename, double t0, double t1, bool selectedOnly, double sampleRate, unsigned channels, MixerOptions::Downmix *mixerSpec, const Tags *tags) override
Called before start processing.
static unsigned long AddTags(ArrayOf< char > &buffer, bool *endOfFile, const Tags *tags)
ExportResult Process(ExportProcessorDelegate &delegate) override
struct MP3ExportProcessor::@174 context
ArrayOf< char > id3buffer
std::unique_ptr< Mixer > mixer
TranslatableString status
Class used to export MP3 files.
lame_set_VBR_q_t * lame_set_VBR_q
static const int mOutBufferSize
lame_set_in_samplerate_t * lame_set_in_samplerate
wxString GetLibraryVersion()
bool InitLibraryExternal(wxString libpath)
int EncodeBufferMono(float inbuffer[], unsigned char outbuffer[])
lame_set_disable_reservoir_t * lame_set_disable_reservoir
int EncodeRemainderMono(float inbuffer[], int nSamples, unsigned char outbuffer[])
bool PutInfoTag(wxFFile &f, wxFileOffset off)
lame_mp3_tags_fid_t * lame_mp3_tags_fid
unsigned char mInfoTagBuf[2880]
void SetBitrate(int rate)
bool ValidLibraryLoaded()
lame_set_brate_t * lame_set_brate
lame_encode_buffer_ieee_float_t * lame_encode_buffer_ieee_float
lame_encode_buffer_interleaved_ieee_float_t * lame_encode_buffer_interleaved_ieee_float
lame_get_lametag_frame_t * lame_get_lametag_frame
lame_set_num_channels_t * lame_set_num_channels
int EncodeBuffer(float inbuffer[], unsigned char outbuffer[])
get_lame_version_t * get_lame_version
static const int mSamplesPerChunk
bool FindLibrary(wxWindow *parent)
bool LoadLibrary(wxWindow *parent, AskUser askuser)
wxString GetLibraryName()
lame_set_VBR_t * lame_set_VBR
FileNames::FileTypes GetLibraryTypes()
wxDynamicLibrary lame_lib
bool InitLibrary(wxString libpath)
wxString GetLibraryPath()
lame_close_t * lame_close
int FinishStream(unsigned char outbuffer[])
lame_set_quality_t * lame_set_quality
beWriteInfoTag_t * beWriteInfoTag
lame_encode_flush_t * lame_encode_flush
int InitializeStream(unsigned channels, int sampleRate)
lame_set_error_protection_t * lame_set_error_protection
lame_set_VBR_min_bitrate_kbps_t * lame_set_VBR_min_bitrate_kbps
bool InitLibraryInternal()
int EncodeRemainder(float inbuffer[], int nSamples, unsigned char outbuffer[])
lame_set_out_samplerate_t * lame_set_out_samplerate
lame_set_mode_t * lame_set_mode
TranslatableString mBladeVersion
lame_set_bWriteVbrTag_t * lame_set_bWriteVbrTag
lame_init_params_t * lame_init_params
lame_set_preset_t * lame_set_preset
A matrix of booleans, one row per input channel, column per output.
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Holds a msgid for the translation catalog; may also bind format arguments.
Base class for objects that provide facility to store data persistently, and access it with string ke...
virtual bool Flush() noexcept=0
virtual bool Write(const wxString &key, bool value)=0
virtual bool Read(const wxString &key, bool *value) const =0
struct with zillion of control parameters that control lame export (MP3 Conversion DLL).
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.
FILES_API FilePath PathFromAddr(void *addr)
constexpr auto sampleRate
BuiltinCommandsModule::Registration< CompareAudioCommand > reg
int ValidateIndex(const std::vector< int > &values, int value, int defaultIndex)
int ValidateValue(const std::vector< int > &values, int value, int defaultValue)
A type that provides a description of an exporting option. Isn't allowed to change except non-type re...
@ TypeEnum
List/enum option. values holds items, and names text to be displayed.
@ Hidden
Option is not used and may be hidden from the user.