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)"),
184 XO(
"Excessive, 320 kbps"),
185 XO(
"Extreme, 220-260 kbps"),
186 XO(
"Standard, 170-210 kbps"),
187 XO(
"Medium, 145-185 kbps"),
249 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
281 mValues[option.id] = option.defaultValue;
286 return static_cast<int>(
mOptions.size());
291 if(index >= 0 && index <
static_cast<int>(
mOptions.size()))
301 const auto it =
mValues.find(
id);
304 if(value.index() != it->second.index())
313 const auto mode = *std::get_if<std::string>(&value);
342 const auto it =
mValues.find(
id);
354 int highrate = 48000;
359 if (rmode ==
"ABR") {
364 else if (bitrate < 32 || bitrate == 144) {
368 else if (rmode ==
"CBR") {
374 else if (bitrate < 32 || bitrate == 144) {
382 if(rate >= lowrate && rate <= highrate)
383 result.push_back(rate);
391 if(config.
Read(
wxT(
"/FileFormats/MP3RateModeChoice"), &mode))
397 if(config.
Read(
wxT(
"/FileFormats/MP3RateMode"), &index))
412 config.
Write(
wxT(
"/FileFormats/MP3RateModeChoice"), wxString(*std::get_if<std::string>(&it->second)));
415 config.
Write(
wxT(
"/FileFormats/MP3SetRate"), *std::get_if<int>(&it->second));
417 config.
Write(
wxT(
"/FileFormats/MP3AbrRate"), *std::get_if<int>(&it->second));
419 config.
Write(
wxT(
"/FileFormats/MP3CbrRate"), *std::get_if<int>(&it->second));
421 config.
Write(
wxT(
"/FileFormats/MP3VbrRate"), *std::get_if<int>(&it->second));
435 else if(mode ==
"ABR")
437 else if(mode ==
"CBR")
439 else if(mode ==
"VBR")
448 return (value >= 0 && value < nValues) ? value : defaultValue;
454 iter = std::find( start, finish, value );
455 return ( iter != finish ) ? value : defaultValue;
461 iter = std::find( start, finish, value );
462 return ( iter != finish ) ?
static_cast<int>( iter - start ) : defaultIndex;
471#define ID_BROWSE 5000
478#ifndef DISABLE_DYNAMIC_LOADING_LAME
491 mTypes = std::move( types );
501 S.StartVerticalLay(
true);
504 XO(
"Audacity needs the file %s to create MP3s.")
508 S.StartHorizontalLay(wxALIGN_LEFT,
true);
512 S.EndHorizontalLay();
514 S.StartMultiColumn(2, wxEXPAND);
517 if (
mLibPath.GetFullPath().empty()) {
520 wxString::Format(
_(
"To find %s, click here -->"),
mName), 0);
528 XO(
"To get a free copy of LAME, click here -->"),
true);
530 S.Id(
ID_DLOAD).AddButton(
XXO(
"Download"), wxALIGN_RIGHT);
534 S.AddStandardButtons();
540 SetMinSize(GetSize());
551 auto question =
XO(
"Where is %s?").Format(
mName );
553 wxString path =
SelectFile(FileNames::Operation::_None,
559 wxFD_OPEN | wxRESIZE_BORDER,
581#ifndef DISABLE_DYNAMIC_LOADING_LAME
591 DECLARE_EVENT_TABLE()
594#ifndef DISABLE_DYNAMIC_LOADING_LAME
605#ifndef DISABLE_DYNAMIC_LOADING_LAME
616 unsigned char * mp3buf,
617 const int mp3buf_size);
623 unsigned char * mp3buf,
624 const int mp3buf_size);
628 unsigned char* mp3buf,
651#if defined(__WXMSW__)
685 BYTE btReserved[125];
703#ifndef DISABLE_DYNAMIC_LOADING_LAME
735 int EncodeBuffer(
float inbuffer[],
unsigned char outbuffer[]);
737 unsigned char outbuffer[]);
741 unsigned char outbuffer[]);
746 bool PutInfoTag(wxFFile & f, wxFileOffset off);
751#ifndef DISABLE_DYNAMIC_LOADING_LAME
757#if defined(__WXMSW__)
767#ifndef DISABLE_DYNAMIC_LOADING_LAME
792#if defined(__WXMSW__)
818#ifdef MP3_EXPORT_BUILT_IN
824#ifndef DISABLE_DYNAMIC_LOADING_LAME
830#ifndef DISABLE_DYNAMIC_LOADING_LAME
847#ifndef DISABLE_DYNAMIC_LOADING_LAME
869 if (fd.ShowModal() == wxID_CANCEL) {
875 if (!::wxFileExists(path)) {
892#if defined(__WXMSW__)
903 wxLogMessage(
wxT(
"Attempting to load LAME from previously defined path"));
909 wxLogMessage(
wxT(
"Attempting to load LAME from system search paths"));
916 wxLogMessage(
wxT(
"Attempting to load LAME from builtin path"));
924 wxLogMessage(
wxT(
"(Maybe) ask user for library"));
932#if defined(__WXMSW__)
937 wxLogMessage(
wxT(
"Failed to locate LAME library"));
942 wxLogMessage(
wxT(
"LAME library successfully loaded"));
976 wxLogMessage(
wxT(
"Using internal LAME"));
980#ifdef MP3_EXPORT_BUILT_IN
1009#if defined(__WXMSW__)
1028 wxLogMessage(
wxT(
"Loading LAME from %s"), libpath);
1030#ifndef DISABLE_DYNAMIC_LOADING_LAME
1031 if (!
lame_lib.Load(libpath, wxDL_LAZY)) {
1032 wxLogMessage(
wxT(
"load failed"));
1036 wxLogMessage(
wxT(
"Actual LAME path %s"),
1046 lame_lib.GetSymbol(
wxT(
"lame_encode_buffer_ieee_float"));
1048 lame_lib.GetSymbol(
wxT(
"lame_encode_buffer_interleaved_ieee_float"));
1055 lame_lib.GetSymbol(
wxT(
"lame_set_in_samplerate"));
1057 lame_lib.GetSymbol(
wxT(
"lame_set_out_samplerate"));
1069 lame_lib.GetSymbol(
wxT(
"lame_set_VBR_min_bitrate_kbps"));
1075 lame_lib.GetSymbol(
wxT(
"lame_set_error_protection"));
1077 lame_lib.GetSymbol(
wxT(
"lame_set_disable_reservoir"));
1083 lame_lib.GetSymbol(
wxT(
"lame_get_lametag_frame"));
1086#if defined(__WXMSW__)
1113 wxLogMessage(
wxT(
"Failed to find a required symbol in the LAME library."));
1114#if defined(__WXMSW__)
1120"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'.")
1150#ifndef DISABLE_DYNAMIC_LOADING_LAME
1159#ifndef DISABLE_DYNAMIC_LOADING_LAME
1170#ifndef DISABLE_DYNAMIC_LOADING_LAME
1247 mode = JOINT_STEREO;
1285 unsigned char outbuffer[])
1306 unsigned char outbuffer[])
1326#if defined(DISABLE_DYNAMIC_LOADING_LAME)
1347 if ( !f.Seek(off, wxFromStart))
1352#if defined(__WXMSW__)
1372#if defined(__WXMSW__)
1377 wxRegKey
reg(
wxT(
"HKEY_LOCAL_MACHINE\\Software\\Lame for Audacity"));
1381 wxLogMessage(
wxT(
"LAME registry key exists."));
1382 reg.QueryValue(
wxT(
"InstallPath"), path);
1385 wxLogMessage(
wxT(
"LAME registry key does not exist."));
1388 wxLogMessage(
wxT(
"Library path is: ") + path);
1395 return wxT(
"lame_enc.dll");
1401 {
XO(
"Only lame_enc.dll"), {
wxT(
"lame_enc.dll") } },
1407#elif defined(__WXMAC__)
1414 path =
wxT(
"/Library/Application Support/audacity/libs");
1420 path =
wxT(
"/usr/local/lib/audacity");
1426 return wxT(
"/Library/Application Support/audacity/libs");
1431 if (
sizeof(
void*) == 8)
1432 return wxT(
"libmp3lame64bit.dylib");
1433 return wxT(
"libmp3lame.dylib");
1439 (
sizeof(
void*) == 8)
1441 XO(
"Only libmp3lame64bit.dylib"), {
wxT(
"libmp3lame64bit.dylib") }
1444 XO(
"Only libmp3lame.dylib"), {
wxT(
"libmp3lame.dylib") }
1452#elif defined(__OpenBSD__)
1462 return wxT(
"libmp3lame.so");
1468 {
XO(
"Only libmp3lame.so"), {
wxT(
"libmp3lame.so") } },
1469 {
XO(
"Primary shared object files"), {
wxT(
"so") },
true },
1470 {
XO(
"Extended libraries"), {
wxT(
"so*") },
true },
1485 return wxT(
"libmp3lame.so.0");
1491 {
XO(
"Only libmp3lame.so.0"), {
wxT(
"libmp3lame.so.0") } },
1492 {
XO(
"Primary shared object files"), {
wxT(
"so") },
true },
1493 {
XO(
"Extended libraries"), {
wxT(
"so*") },
true },
1503 wxPrintf(
wxT(
"\n\nLame_enc configuration options:\n"));
1504 wxPrintf(
wxT(
"==========================================================\n"));
1506 wxPrintf(
wxT(
"version =%d\n"),lame_get_version( gfp ) );
1507 wxPrintf(
wxT(
"Layer =3\n"));
1508 wxPrintf(
wxT(
"mode ="));
1509 switch ( lame_get_mode( gfp ) )
1511 case STEREO: wxPrintf(
wxT(
"Stereo\n" ));
break;
1512 case JOINT_STEREO: wxPrintf(
wxT(
"Joint-Stereo\n" ));
break;
1513 case DUAL_CHANNEL: wxPrintf(
wxT(
"Forced Stereo\n" ));
break;
1514 case MONO: wxPrintf(
wxT(
"Mono\n" ));
break;
1516 default: wxPrintf(
wxT(
"Error (unknown)\n" ));
break;
1519 wxPrintf(
wxT(
"Input sample rate =%.1f kHz\n"), lame_get_in_samplerate( gfp ) /1000.0 );
1520 wxPrintf(
wxT(
"Output sample rate =%.1f kHz\n"), lame_get_out_samplerate( gfp ) /1000.0 );
1522 wxPrintf(
wxT(
"bitrate =%d kbps\n"), lame_get_brate( gfp ) );
1523 wxPrintf(
wxT(
"Quality Setting =%d\n"), lame_get_quality( gfp ) );
1525 wxPrintf(
wxT(
"Low pass frequency =%d\n"), lame_get_lowpassfreq( gfp ) );
1526 wxPrintf(
wxT(
"Low pass width =%d\n"), lame_get_lowpasswidth( gfp ) );
1528 wxPrintf(
wxT(
"High pass frequency =%d\n"), lame_get_highpassfreq( gfp ) );
1529 wxPrintf(
wxT(
"High pass width =%d\n"), lame_get_highpasswidth( gfp ) );
1531 wxPrintf(
wxT(
"No short blocks =%d\n"), lame_get_no_short_blocks( gfp ) );
1532 wxPrintf(
wxT(
"Force short blocks =%d\n"), lame_get_force_short_blocks( gfp ) );
1534 wxPrintf(
wxT(
"de-emphasis =%d\n"), lame_get_emphasis( gfp ) );
1535 wxPrintf(
wxT(
"private flag =%d\n"), lame_get_extension( gfp ) );
1537 wxPrintf(
wxT(
"copyright flag =%d\n"), lame_get_copyright( gfp ) );
1538 wxPrintf(
wxT(
"original flag =%d\n"), lame_get_original( gfp ) );
1539 wxPrintf(
wxT(
"CRC =%s\n"), lame_get_error_protection( gfp ) ?
wxT(
"on") :
wxT(
"off") );
1540 wxPrintf(
wxT(
"Fast mode =%s\n"), ( lame_get_quality( gfp ) )?
wxT(
"enabled") :
wxT(
"disabled") );
1541 wxPrintf(
wxT(
"Force mid/side stereo =%s\n"), ( lame_get_force_ms( gfp ) )?
wxT(
"enabled"):
wxT(
"disabled") );
1542 wxPrintf(
wxT(
"Padding Type =%d\n"), (
int) lame_get_padding_type( gfp ) );
1543 wxPrintf(
wxT(
"Disable Reservoir =%d\n"), lame_get_disable_reservoir( gfp ) );
1544 wxPrintf(
wxT(
"Allow diff-short =%d\n"), lame_get_allow_diff_short( gfp ) );
1545 wxPrintf(
wxT(
"Interchannel masking =%d\n"), lame_get_interChRatio( gfp ) );
1546 wxPrintf(
wxT(
"Strict ISO Encoding =%s\n"), ( lame_get_strict_ISO( gfp ) ) ?
wxT(
"Yes"):
wxT(
"No"));
1547 wxPrintf(
wxT(
"Scale =%5.2f\n"), lame_get_scale( gfp ) );
1549 wxPrintf(
wxT(
"VBR =%s, VBR_q =%d, VBR method ="),
1550 ( lame_get_VBR( gfp ) !=vbr_off ) ?
wxT(
"enabled"):
wxT(
"disabled"),
1551 lame_get_VBR_q( gfp ) );
1553 switch ( lame_get_VBR( gfp ) )
1555 case vbr_off: wxPrintf(
wxT(
"vbr_off\n" ));
break;
1556 case vbr_mt : wxPrintf(
wxT(
"vbr_mt \n" ));
break;
1557 case vbr_rh : wxPrintf(
wxT(
"vbr_rh \n" ));
break;
1558 case vbr_mtrh: wxPrintf(
wxT(
"vbr_mtrh \n" ));
break;
1560 wxPrintf(
wxT(
"vbr_abr (average bitrate %d kbps)\n"), lame_get_VBR_mean_bitrate_kbps( gfp ) );
1563 wxPrintf(
wxT(
"error, unknown VBR setting\n"));
1567 wxPrintf(
wxT(
"Vbr Min bitrate =%d kbps\n"), lame_get_VBR_min_bitrate_kbps( gfp ) );
1568 wxPrintf(
wxT(
"Vbr Max bitrate =%d kbps\n"), lame_get_VBR_max_bitrate_kbps( gfp ) );
1570 wxPrintf(
wxT(
"Write VBR Header =%s\n"), ( lame_get_bWriteVbrTag( gfp ) ) ?
wxT(
"Yes"):
wxT(
"No"));
1571 wxPrintf(
wxT(
"VBR Hard min =%d\n"), lame_get_VBR_hard_min( gfp ) );
1573 wxPrintf(
wxT(
"ATH Only =%d\n"), lame_get_ATHonly( gfp ) );
1574 wxPrintf(
wxT(
"ATH short =%d\n"), lame_get_ATHshort( gfp ) );
1575 wxPrintf(
wxT(
"ATH no =%d\n"), lame_get_noATH( gfp ) );
1576 wxPrintf(
wxT(
"ATH type =%d\n"), lame_get_ATHtype( gfp ) );
1577 wxPrintf(
wxT(
"ATH lower =%f\n"), lame_get_ATHlower( gfp ) );
1578 wxPrintf(
wxT(
"ATH aa =%d\n"), lame_get_athaa_type( gfp ) );
1579 wxPrintf(
wxT(
"ATH aa loudapprox =%d\n"), lame_get_athaa_loudapprox( gfp ) );
1580 wxPrintf(
wxT(
"ATH aa sensitivity =%f\n"), lame_get_athaa_sensitivity( gfp ) );
1582 wxPrintf(
wxT(
"Experimental nspsytune =%d\n"), lame_get_exp_nspsytune( gfp ) );
1583 wxPrintf(
wxT(
"Experimental X =%d\n"), lame_get_experimentalX( gfp ) );
1584 wxPrintf(
wxT(
"Experimental Y =%d\n"), lame_get_experimentalY( gfp ) );
1585 wxPrintf(
wxT(
"Experimental Z =%d\n"), lame_get_experimentalZ( gfp ) );
1611 double t0,
double t1,
bool selectedOnly,
1614 const Tags* tags)
override;
1620 static int AskResample(
int bitrate,
int rate,
int lowrate,
int highrate);
1623 static void AddFrame(
struct id3_tag *tp,
const wxString & n,
const wxString & v,
const char *
name);
1641 std::unique_ptr<ExportOptionsEditor>
1646 std::vector<std::string>
GetMimeTypes(
int)
const override;
1649 int formatIndex,
const rapidjson::Value& document,
1663 wxT(
"MP3"),
XO(
"MP3 Files"), {
wxT(
"mp3") }, 2u,
true
1667std::unique_ptr<ExportOptionsEditor>
1670 return std::make_unique<MP3ExportOptionsEditor>(listener);
1675 return std::make_unique<MP3ExportProcessor>();
1680 return {
"audio/mpeg" };
1684 int formatIndex,
const rapidjson::Value& document,
1687 if (!document.IsObject())
1692 if (document.HasMember(
"mode"))
1694 auto& mode = document[
"mode"];
1695 if (!mode.IsString())
1698 auto value = mode.GetString();
1700 if (value == std::string_view {
"SET" })
1702 else if (value == std::string_view {
"VBR" })
1704 else if (value == std::string_view {
"ABR" })
1706 else if (value == std::string_view {
"CBR" })
1716 if (document.HasMember(
"quality"))
1718 auto& qualityMember = document[
"quality"];
1720 if (!qualityMember.IsInt())
1723 const auto quality = qualityMember.GetInt();
1745 parameters.push_back(std::make_tuple(qualityMode, quality));
1755#ifndef DISABLE_DYNAMIC_LOADING_LAME
1762 .Caption(
XO(
"Error")));
1776 double t0,
double t1,
bool selectionOnly,
1779 const Tags* metadata)
1788#ifdef DISABLE_DYNAMIC_LOADING_LAME
1804 throw ExportException(
_(
"Not a valid or supported MP3 encoding library!"));
1809 int highrate = 48000;
1817 std::string(
"CBR"));
1819 if (rmode ==
"SET") {
1820 quality = ExportPluginHelpers::GetParameterValue<int>(
1827 else if (rmode ==
"VBR") {
1828 quality = ExportPluginHelpers::GetParameterValue<int>(
1835 else if (rmode ==
"ABR") {
1842 if (bitrate > 160) {
1845 else if (bitrate < 32 || bitrate == 144) {
1854 if (bitrate > 160) {
1857 else if (bitrate < 32 || bitrate == 144) {
1864 (rate < lowrate) || (rate > highrate)) {
1868 auto const bestRateIt = std::lower_bound(
sampRates.begin(),
1870 rate = (bestRateIt ==
sampRates.end()) ? highrate : *bestRateIt;
1872 if (rate < lowrate) {
1875 else if (rate > highrate) {
1882 (rate < lowrate) || (rate > highrate)) {
1885 rate =
AskResample(bitrate, rate, lowrate, highrate);
1899 if (metadata ==
nullptr)
1903 if (!
context.outFile.Open(fName.GetFullPath(),
wxT(
"w+b"))) {
1909 if (
context.id3len && !endOfFile) {
1921 if (
context.bufferSize == 0) {
1926 if (rmode ==
"SET") {
1927 context.status = (selectionOnly ?
1928 XO(
"Exporting selected audio with %s preset") :
1929 XO(
"Exporting the audio with %s preset"))
1932 else if (rmode ==
"VBR") {
1933 context.status = (selectionOnly ?
1934 XO(
"Exporting selected audio with VBR quality %s") :
1935 XO(
"Exporting the audio with VBR quality %s"))
1939 context.status = (selectionOnly ?
1940 XO(
"Exporting selected audio at %d Kbps") :
1941 XO(
"Exporting the audio at %d Kbps"))
1966 auto blockLen =
context.mixer->Process();
1970 float *mixed = (
float *)
context.mixer->GetBuffer();
1972 if ((
int)blockLen <
context.inSamples) {
1995 if (bytes > (
int)
context.outFile.Write(buffer.get(), bytes)) {
2015 if (bytes > (
int)
context.outFile.Write(buffer.get(), bytes)) {
2042 return exportResult;
2054 S.StartVerticalLay();
2057 S.StartStatic(
XO(
"Resample"));
2059 S.StartHorizontalLay(wxALIGN_CENTER,
false);
2064"The project sample rate (%d) is not supported by the MP3\nfile format. ")
2067"The project sample rate (%d) and bit rate (%d kbps) combination is not\nsupported by the MP3 file format. ")
2068 .
Format( rate, bitrate ))
2069 +
XO(
"You may resample to one of the rates below.")
2072 S.EndHorizontalLay();
2074 S.StartHorizontalLay(wxALIGN_CENTER,
false);
2076 choice =
S.AddChoice(
XXO(
"Sample Rates"),
2079 for (
size_t ii = 0, nn =
sampRates.size(); ii < nn; ++ii) {
2080 int label = sampRates[ii];
2081 if (label >= lowrate && label <= highrate) {
2082 choices.push_back( Verbatim(
"%d" ).Format( label ) );
2089 std::max( 0, selected )
2092 S.EndHorizontalLay();
2096 S.AddStandardButtons();
2102 d.SetMinSize(d.GetSize());
2105 if (d.ShowModal() == wxID_CANCEL) {
2109 return wxAtoi(choice->GetStringSelection());
2113struct id3_tag_deleter {
2114 void operator () (id3_tag *p)
const {
if (p) id3_tag_delete(p); }
2116using id3_tag_holder = std::unique_ptr<id3_tag, id3_tag_deleter>;
2123 id3_tag_holder tp { id3_tag_new() };
2125 for (
const auto &pair : tags->
GetRange()) {
2126 const auto &n = pair.first;
2127 const auto &v = pair.second;
2128 const char *
name =
"TXXX";
2131 name = ID3_FRAME_TITLE;
2134 name = ID3_FRAME_ARTIST;
2137 name = ID3_FRAME_ALBUM;
2139 else if (n.CmpNoCase(
TAG_YEAR) == 0) {
2142 AddFrame(tp.get(), n, v,
"TYER");
2143 name = ID3_FRAME_YEAR;
2146 name = ID3_FRAME_GENRE;
2149 name = ID3_FRAME_COMMENT;
2152 name = ID3_FRAME_TRACK;
2155 AddFrame(tp.get(), n, v,
name);
2158 tp->options &= (~ID3_TAG_OPTION_COMPRESSION);
2163 #ifdef ID3_TAG_HAS_TAG_OPTION_ID3V2_3
2164 tp->options |= ID3_TAG_OPTION_ID3V2_3;
2171 len = id3_tag_render(tp.get(), 0);
2173 len = id3_tag_render(tp.get(), (id3_byte_t *)buffer.get());
2182void MP3ExportProcessor::AddFrame(
struct id3_tag *tp,
const wxString & n,
const wxString & v,
const char *
name)
2184 struct id3_frame *frame = id3_frame_new(
name);
2186 if (!n.IsAscii() || !v.IsAscii()) {
2187 id3_field_settextencoding(id3_frame_field(frame, 0), ID3_FIELD_TEXTENCODING_UTF_16);
2190 id3_field_settextencoding(id3_frame_field(frame, 0), ID3_FIELD_TEXTENCODING_ISO_8859_1);
2194 id3_utf8_ucs4duplicate((id3_utf8_t *) (
const char *) v.mb_str(wxConvUTF8)) };
2196 if (strcmp(
name, ID3_FRAME_COMMENT) == 0) {
2202 struct id3_frame *frame2 = id3_frame_new(
name);
2203 id3_field_setfullstring(id3_frame_field(frame2, 3), ucs4.get());
2204 id3_field *f2 = id3_frame_field(frame2, 1);
2205 memset(f2->immediate.value, 0,
sizeof(f2->immediate.value));
2206 id3_tag_attachframe(tp, frame2);
2208 id3_field_setfullstring(id3_frame_field(frame, 3), ucs4.get());
2210 else if (strcmp(
name,
"TXXX") == 0) {
2211 id3_field_setstring(id3_frame_field(frame, 2), ucs4.get());
2213 ucs4.reset(id3_utf8_ucs4duplicate((id3_utf8_t *) (
const char *) n.mb_str(wxConvUTF8)));
2215 id3_field_setstring(id3_frame_field(frame, 1), ucs4.get());
2218 auto addr = ucs4.get();
2219 id3_field_setstrings(id3_frame_field(frame, 1), 1, &addr);
2222 id3_tag_attachframe(tp, frame);
2227 []{
return std::make_unique< ExportMP3 >(); }
2237 auto versionString =
XO(
"MP3 export library not found");
2239#ifndef DISABLE_DYNAMIC_LOADING_LAME
2247#ifdef MP3_EXPORT_BUILT_IN
2248 versionString.Join(
XO(
"(Built-in)"),
" " );
2251#ifndef DISABLE_DYNAMIC_LOADING_LAME
2255 return versionString;
Toolkit-neutral facade for basic user interface services.
EVT_BUTTON(wxID_NO, DependencyDialog::OnNo) EVT_BUTTON(wxID_YES
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
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
ArrayOf< char > id3buffer
std::unique_ptr< Mixer > mixer
TranslatableString status
struct MP3ExportProcessor::@175 context
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.