69#include <wx/checkbox.h>
74#include <wx/mimetype.h>
75#include <wx/radiobut.h>
76#include <wx/stattext.h>
77#include <wx/textctrl.h>
87#include "../ProjectSettings.h"
88#include "../ProjectWindow.h"
89#include "../SelectFile.h"
90#include "../ShuttleGui.h"
93#include "../widgets/HelpSystem.h"
94#include "../widgets/AudacityMessageBox.h"
95#include "../widgets/ProgressDialog.h"
101#include <lame/lame.h>
175 XO(
"220-260 kbps (Best Quality)"),
184 XO(
"45-85 kbps (Smaller files)"),
194 XO(
"Insane, 320 kbps"),
195 XO(
"Extreme, 220-260 kbps"),
196 XO(
"Standard, 170-210 kbps"),
197 XO(
"Medium, 145-185 kbps"),
224#define ID_QUALITY 7004
238 void OnSET(wxCommandEvent& evt);
239 void OnVBR(wxCommandEvent& evt);
240 void OnABR(wxCommandEvent& evt);
241 void OnCBR(wxCommandEvent& evt);
243 void OnMono(wxCommandEvent& evt);
264 DECLARE_EVENT_TABLE()
283 mAbrRate =
gPrefs->Read(wxT(
"/FileFormats/MP3AbrRate"), 192);
284 mCbrRate =
gPrefs->Read(wxT(
"/FileFormats/MP3CbrRate"), 192);
287 PopulateOrExchange(
S);
289 TransferDataToWindow();
298 wxT(
"/FileFormats/MP3RateModeChoice"),
300 { wxT(
"SET"),
XXO(
"Preset") },
301 { wxT(
"VBR"),
XXO(
"Variable") },
302 { wxT(
"ABR"),
XXO(
"Average") },
303 { wxT(
"CBR"),
XXO(
"Constant") },
311 wxT(
"/FileFormats/MP3RateMode"),
315 wxT(
"/FileFormats/MP3ChannelModeChoice"),
326 wxT(
"/FileFormats/MP3ChannelMode"),
334 gPrefs->Read(wxT(
"/FileFormats/MP3ForceMono"), &mono, 0);
337 const std::vector< int > *codes =
nullptr;
341 S.StartVerticalLay();
343 S.StartHorizontalLay(wxCENTER);
345 S.StartMultiColumn(2, wxCENTER);
350 S.AddPrompt(
XXO(
"Bit Rate Mode:"));
356 S.StartHorizontalLay();
365 S.EndRadioButtonGroup();
367 S.EndHorizontalLay();
408 { wxT(
"/FileFormats/MP3Bitrate"), defrate },
419 S.AddPrompt(
XXO(
"Channel Mode:"));
420 S.StartMultiColumn(2, wxEXPAND);
426 S.StartHorizontalLay();
435 S.EndRadioButtonGroup();
437 S.EndHorizontalLay();
449 S.EndHorizontalLay();
479 return (value >= 0 && value < nValues) ? value : defaultValue;
485 iter = std::find( start, finish, value );
486 return ( iter != finish ) ? value : defaultValue;
492 iter = std::find( start, finish, value );
493 return ( iter != finish ) ?
static_cast<int>( iter - start ) : defaultIndex;
544 int sel =
mRate->GetSelection();
546 if (
mSET->GetValue()) {
549 else if (
mVBR->GetValue()) {
552 else if (
mABR->GetValue()) {
563 mono =
mMono->GetValue();
567 gPrefs->Write(wxT(
"/FileFormats/MP3ForceMono"), mono);
582#define ID_BROWSE 5000
589#ifndef DISABLE_DYNAMIC_LOADING_LAME
602 mTypes = std::move( types );
612 S.StartVerticalLay(
true);
615 XO(
"Audacity needs the file %s to create MP3s.")
619 S.StartHorizontalLay(wxALIGN_LEFT,
true);
623 S.EndHorizontalLay();
625 S.StartMultiColumn(2, wxEXPAND);
628 if (
mLibPath.GetFullPath().empty()) {
631 wxString::Format(
_(
"To find %s, click here -->"),
mName), 0);
639 XO(
"To get a free copy of LAME, click here -->"),
true);
641 S.Id(
ID_DLOAD).AddButton(
XXO(
"Download"), wxALIGN_RIGHT);
645 S.AddStandardButtons();
651 SetMinSize(GetSize());
662 auto question =
XO(
"Where is %s?").Format(
mName );
664 wxString path =
SelectFile(FileNames::Operation::_None,
670 wxFD_OPEN | wxRESIZE_BORDER,
692#ifndef DISABLE_DYNAMIC_LOADING_LAME
702 DECLARE_EVENT_TABLE()
705#ifndef DISABLE_DYNAMIC_LOADING_LAME
716#ifndef DISABLE_DYNAMIC_LOADING_LAME
727 unsigned char * mp3buf,
728 const int mp3buf_size);
734 unsigned char * mp3buf,
735 const int mp3buf_size);
739 unsigned char* mp3buf,
762#if defined(__WXMSW__)
796 BYTE btReserved[125];
814#ifndef DISABLE_DYNAMIC_LOADING_LAME
847 int EncodeBuffer(
float inbuffer[],
unsigned char outbuffer[]);
849 unsigned char outbuffer[]);
853 unsigned char outbuffer[]);
858 bool PutInfoTag(wxFFile & f, wxFileOffset off);
863#ifndef DISABLE_DYNAMIC_LOADING_LAME
869#if defined(__WXMSW__)
880#ifndef DISABLE_DYNAMIC_LOADING_LAME
905#if defined(__WXMSW__)
931#ifdef MP3_EXPORT_BUILT_IN
937#ifndef DISABLE_DYNAMIC_LOADING_LAME
943#ifndef DISABLE_DYNAMIC_LOADING_LAME
961#ifndef DISABLE_DYNAMIC_LOADING_LAME
983 if (fd.ShowModal() == wxID_CANCEL) {
989 if (!::wxFileExists(path)) {
1006#if defined(__WXMSW__)
1017 wxLogMessage(wxT(
"Attempting to load LAME from previously defined path"));
1023 wxLogMessage(wxT(
"Attempting to load LAME from system search paths"));
1030 wxLogMessage(wxT(
"Attempting to load LAME from builtin path"));
1038 wxLogMessage(wxT(
"(Maybe) ask user for library"));
1046#if defined(__WXMSW__)
1051 wxLogMessage(wxT(
"Failed to locate LAME library"));
1056 wxLogMessage(wxT(
"LAME library successfully loaded"));
1096 wxLogMessage(wxT(
"Using internal LAME"));
1100#ifdef MP3_EXPORT_BUILT_IN
1129#if defined(__WXMSW__)
1148 wxLogMessage(wxT(
"Loading LAME from %s"), libpath);
1150#ifndef DISABLE_DYNAMIC_LOADING_LAME
1151 if (!
lame_lib.Load(libpath, wxDL_LAZY)) {
1152 wxLogMessage(wxT(
"load failed"));
1156 wxLogMessage(wxT(
"Actual LAME path %s"),
1160 lame_lib.GetSymbol(wxT(
"lame_init"));
1162 lame_lib.GetSymbol(wxT(
"get_lame_version"));
1164 lame_lib.GetSymbol(wxT(
"lame_init_params"));
1166 lame_lib.GetSymbol(wxT(
"lame_encode_buffer_ieee_float"));
1168 lame_lib.GetSymbol(wxT(
"lame_encode_buffer_interleaved_ieee_float"));
1170 lame_lib.GetSymbol(wxT(
"lame_encode_flush"));
1172 lame_lib.GetSymbol(wxT(
"lame_close"));
1175 lame_lib.GetSymbol(wxT(
"lame_set_in_samplerate"));
1177 lame_lib.GetSymbol(wxT(
"lame_set_out_samplerate"));
1179 lame_lib.GetSymbol(wxT(
"lame_set_num_channels"));
1181 lame_lib.GetSymbol(wxT(
"lame_set_quality"));
1183 lame_lib.GetSymbol(wxT(
"lame_set_brate"));
1185 lame_lib.GetSymbol(wxT(
"lame_set_VBR"));
1187 lame_lib.GetSymbol(wxT(
"lame_set_VBR_q"));
1189 lame_lib.GetSymbol(wxT(
"lame_set_VBR_min_bitrate_kbps"));
1191 lame_lib.GetSymbol(wxT(
"lame_set_mode"));
1193 lame_lib.GetSymbol(wxT(
"lame_set_preset"));
1195 lame_lib.GetSymbol(wxT(
"lame_set_error_protection"));
1197 lame_lib.GetSymbol(wxT(
"lame_set_disable_reservoir"));
1199 lame_lib.GetSymbol(wxT(
"lame_set_bWriteVbrTag"));
1203 lame_lib.GetSymbol(wxT(
"lame_get_lametag_frame"));
1205 lame_lib.GetSymbol(wxT(
"lame_mp3_tags_fid"));
1206#if defined(__WXMSW__)
1208 lame_lib.GetSymbol(wxT(
"beWriteInfoTag"));
1210 lame_lib.GetSymbol(wxT(
"beVersion"));
1233 wxLogMessage(wxT(
"Failed to find a required symbol in the LAME library."));
1234#if defined(__WXMSW__)
1240"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'.")
1270#ifndef DISABLE_DYNAMIC_LOADING_LAME
1279#ifndef DISABLE_DYNAMIC_LOADING_LAME
1290#ifndef DISABLE_DYNAMIC_LOADING_LAME
1368 mode = JOINT_STEREO;
1409 unsigned char outbuffer[])
1430 unsigned char outbuffer[])
1450#if defined(DISABLE_DYNAMIC_LOADING_LAME)
1471 if ( !f.Seek(off, wxFromStart))
1476#if defined(__WXMSW__)
1496#if defined(__WXMSW__)
1501 wxRegKey
reg(wxT(
"HKEY_LOCAL_MACHINE\\Software\\Lame for Audacity"));
1505 wxLogMessage(wxT(
"LAME registry key exists."));
1506 reg.QueryValue(wxT(
"InstallPath"), path);
1509 wxLogMessage(wxT(
"LAME registry key does not exist."));
1512 wxLogMessage(wxT(
"Library path is: ") + path);
1519 return wxT(
"lame_enc.dll");
1525 {
XO(
"Only lame_enc.dll"), { wxT(
"lame_enc.dll") } },
1531#elif defined(__WXMAC__)
1538 path = wxT(
"/Library/Application Support/audacity/libs");
1544 path = wxT(
"/usr/local/lib/audacity");
1550 return wxT(
"/Library/Application Support/audacity/libs");
1555 if (
sizeof(
void*) == 8)
1556 return wxT(
"libmp3lame64bit.dylib");
1557 return wxT(
"libmp3lame.dylib");
1563 (
sizeof(
void*) == 8)
1565 XO(
"Only libmp3lame64bit.dylib"), { wxT(
"libmp3lame64bit.dylib") }
1568 XO(
"Only libmp3lame.dylib"), { wxT(
"libmp3lame.dylib") }
1586 return wxT(
"libmp3lame.so.0");
1592 {
XO(
"Only libmp3lame.so.0"), { wxT(
"libmp3lame.so.0") } },
1593 {
XO(
"Primary shared object files"), { wxT(
"so") },
true },
1594 {
XO(
"Extended libraries"), { wxT(
"so*") },
true },
1604 wxPrintf(wxT(
"\n\nLame_enc configuration options:\n"));
1605 wxPrintf(wxT(
"==========================================================\n"));
1607 wxPrintf(wxT(
"version =%d\n"),lame_get_version( gfp ) );
1608 wxPrintf(wxT(
"Layer =3\n"));
1609 wxPrintf(wxT(
"mode ="));
1610 switch ( lame_get_mode( gfp ) )
1612 case STEREO: wxPrintf(wxT(
"Stereo\n" ));
break;
1613 case JOINT_STEREO: wxPrintf(wxT(
"Joint-Stereo\n" ));
break;
1614 case DUAL_CHANNEL: wxPrintf(wxT(
"Forced Stereo\n" ));
break;
1615 case MONO: wxPrintf(wxT(
"Mono\n" ));
break;
1617 default: wxPrintf(wxT(
"Error (unknown)\n" ));
break;
1620 wxPrintf(wxT(
"Input sample rate =%.1f kHz\n"), lame_get_in_samplerate( gfp ) /1000.0 );
1621 wxPrintf(wxT(
"Output sample rate =%.1f kHz\n"), lame_get_out_samplerate( gfp ) /1000.0 );
1623 wxPrintf(wxT(
"bitrate =%d kbps\n"), lame_get_brate( gfp ) );
1624 wxPrintf(wxT(
"Quality Setting =%d\n"), lame_get_quality( gfp ) );
1626 wxPrintf(wxT(
"Low pass frequency =%d\n"), lame_get_lowpassfreq( gfp ) );
1627 wxPrintf(wxT(
"Low pass width =%d\n"), lame_get_lowpasswidth( gfp ) );
1629 wxPrintf(wxT(
"High pass frequency =%d\n"), lame_get_highpassfreq( gfp ) );
1630 wxPrintf(wxT(
"High pass width =%d\n"), lame_get_highpasswidth( gfp ) );
1632 wxPrintf(wxT(
"No short blocks =%d\n"), lame_get_no_short_blocks( gfp ) );
1633 wxPrintf(wxT(
"Force short blocks =%d\n"), lame_get_force_short_blocks( gfp ) );
1635 wxPrintf(wxT(
"de-emphasis =%d\n"), lame_get_emphasis( gfp ) );
1636 wxPrintf(wxT(
"private flag =%d\n"), lame_get_extension( gfp ) );
1638 wxPrintf(wxT(
"copyright flag =%d\n"), lame_get_copyright( gfp ) );
1639 wxPrintf(wxT(
"original flag =%d\n"), lame_get_original( gfp ) );
1640 wxPrintf(wxT(
"CRC =%s\n"), lame_get_error_protection( gfp ) ? wxT(
"on") : wxT(
"off") );
1641 wxPrintf(wxT(
"Fast mode =%s\n"), ( lame_get_quality( gfp ) )? wxT(
"enabled") : wxT(
"disabled") );
1642 wxPrintf(wxT(
"Force mid/side stereo =%s\n"), ( lame_get_force_ms( gfp ) )?wxT(
"enabled"):wxT(
"disabled") );
1643 wxPrintf(wxT(
"Padding Type =%d\n"), (
int) lame_get_padding_type( gfp ) );
1644 wxPrintf(wxT(
"Disable Reservoir =%d\n"), lame_get_disable_reservoir( gfp ) );
1645 wxPrintf(wxT(
"Allow diff-short =%d\n"), lame_get_allow_diff_short( gfp ) );
1646 wxPrintf(wxT(
"Interchannel masking =%d\n"), lame_get_interChRatio( gfp ) );
1647 wxPrintf(wxT(
"Strict ISO Encoding =%s\n"), ( lame_get_strict_ISO( gfp ) ) ?wxT(
"Yes"):wxT(
"No"));
1648 wxPrintf(wxT(
"Scale =%5.2f\n"), lame_get_scale( gfp ) );
1650 wxPrintf(wxT(
"VBR =%s, VBR_q =%d, VBR method ="),
1651 ( lame_get_VBR( gfp ) !=vbr_off ) ? wxT(
"enabled"): wxT(
"disabled"),
1652 lame_get_VBR_q( gfp ) );
1654 switch ( lame_get_VBR( gfp ) )
1656 case vbr_off: wxPrintf(wxT(
"vbr_off\n" ));
break;
1657 case vbr_mt : wxPrintf(wxT(
"vbr_mt \n" ));
break;
1658 case vbr_rh : wxPrintf(wxT(
"vbr_rh \n" ));
break;
1659 case vbr_mtrh: wxPrintf(wxT(
"vbr_mtrh \n" ));
break;
1661 wxPrintf(wxT(
"vbr_abr (average bitrate %d kbps)\n"), lame_get_VBR_mean_bitrate_kbps( gfp ) );
1664 wxPrintf(wxT(
"error, unknown VBR setting\n"));
1668 wxPrintf(wxT(
"Vbr Min bitrate =%d kbps\n"), lame_get_VBR_min_bitrate_kbps( gfp ) );
1669 wxPrintf(wxT(
"Vbr Max bitrate =%d kbps\n"), lame_get_VBR_max_bitrate_kbps( gfp ) );
1671 wxPrintf(wxT(
"Write VBR Header =%s\n"), ( lame_get_bWriteVbrTag( gfp ) ) ?wxT(
"Yes"):wxT(
"No"));
1672 wxPrintf(wxT(
"VBR Hard min =%d\n"), lame_get_VBR_hard_min( gfp ) );
1674 wxPrintf(wxT(
"ATH Only =%d\n"), lame_get_ATHonly( gfp ) );
1675 wxPrintf(wxT(
"ATH short =%d\n"), lame_get_ATHshort( gfp ) );
1676 wxPrintf(wxT(
"ATH no =%d\n"), lame_get_noATH( gfp ) );
1677 wxPrintf(wxT(
"ATH type =%d\n"), lame_get_ATHtype( gfp ) );
1678 wxPrintf(wxT(
"ATH lower =%f\n"), lame_get_ATHlower( gfp ) );
1679 wxPrintf(wxT(
"ATH aa =%d\n"), lame_get_athaa_type( gfp ) );
1680 wxPrintf(wxT(
"ATH aa loudapprox =%d\n"), lame_get_athaa_loudapprox( gfp ) );
1681 wxPrintf(wxT(
"ATH aa sensitivity =%f\n"), lame_get_athaa_sensitivity( gfp ) );
1683 wxPrintf(wxT(
"Experimental nspsytune =%d\n"), lame_get_exp_nspsytune( gfp ) );
1684 wxPrintf(wxT(
"Experimental X =%d\n"), lame_get_experimentalX( gfp ) );
1685 wxPrintf(wxT(
"Experimental Y =%d\n"), lame_get_experimentalY( gfp ) );
1686 wxPrintf(wxT(
"Experimental Z =%d\n"), lame_get_experimentalZ( gfp ) );
1705 std::unique_ptr<ProgressDialog> &pDialog,
1712 const Tags *metadata = NULL,
1713 int subformat = 0)
override;
1717 int AskResample(
int bitrate,
int rate,
int lowrate,
int highrate);
1720 void AddFrame(
struct id3_tag *tp,
const wxString & n,
const wxString & v,
const char *
name);
1738#ifndef DISABLE_DYNAMIC_LOADING_LAME
1743 gPrefs->Write(wxT(
"/MP3/MP3LibPath"), wxString(wxT(
"")));
1756 gPrefs->Read(wxT(
"/FileFormats/MP3ForceMono"), &mono, 0);
1758 return (mono)? 1 : -1;
1763 std::unique_ptr<ProgressDialog> &pDialog,
1770 const Tags *metadata,
1771 int WXUNUSED(subformat))
1774#ifndef DISABLE_DYNAMIC_LOADING_LAME
1780#ifdef DISABLE_DYNAMIC_LOADING_LAME
1783 gPrefs->Write(wxT(
"/MP3/MP3LibPath"), wxString(wxT(
"")));
1791 gPrefs->Write(wxT(
"/MP3/MP3LibPath"), wxString(wxT(
"")));
1799 gPrefs->Write(wxT(
"/MP3/MP3LibPath"), wxString(wxT(
"")));
1807 int highrate = 48000;
1814 gPrefs->Read(wxT(
"/FileFormats/MP3Bitrate"), &brate, 128);
1818 gPrefs->Read(wxT(
"/FileFormats/MP3ForceMono"), &forceMono, 0);
1838 if (bitrate > 160) {
1841 else if (bitrate < 32 || bitrate == 144) {
1851 if (bitrate > 160) {
1854 else if (bitrate < 32 || bitrate == 144) {
1861 (rate < lowrate) || (rate > highrate)) {
1865 auto const bestRateIt = std::lower_bound(
sampRates.begin(),
1867 rate = (bestRateIt ==
sampRates.end()) ? highrate : *bestRateIt;
1869 if (rate < lowrate) {
1872 else if (rate > highrate) {
1879 (rate < lowrate) || (rate > highrate)) {
1880 rate =
AskResample(bitrate, rate, lowrate, highrate);
1901 if (((
int)inSamples) < 0) {
1907 if (metadata == NULL)
1911 wxFFile outFile(fName.GetFullPath(), wxT(
"w+b"));
1912 if (!outFile.IsOpened()) {
1919 unsigned long id3len =
AddTags(project, id3buffer, &endOfFile, metadata);
1920 if (id3len && !endOfFile) {
1921 if (id3len > outFile.Write(id3buffer.get(), id3len)) {
1928 wxFileOffset pos = outFile.Tell();
1933 if (bufferSize <= 0) {
1945 channels, inSamples,
true,
1950 title = (selectionOnly ?
1951 XO(
"Exporting selected audio with %s preset") :
1952 XO(
"Exporting the audio with %s preset"))
1956 title = (selectionOnly ?
1957 XO(
"Exporting selected audio with VBR quality %s") :
1958 XO(
"Exporting the audio with VBR quality %s"))
1962 title = (selectionOnly ?
1963 XO(
"Exporting selected audio at %d Kbps") :
1964 XO(
"Exporting the audio at %d Kbps"))
1969 auto &progress = *pDialog;
1972 auto blockLen = mixer->Process(inSamples);
1974 if (blockLen == 0) {
1978 float *mixed = (
float *)mixer->GetBuffer();
1980 if ((
int)blockLen < inSamples) {
1998 auto msg =
XO(
"Error %ld returned from MP3 encoder")
2005 if (bytes > (
int)outFile.Write(buffer.get(), bytes)) {
2012 updateResult = progress.Update(mixer->MixGetCurrentTime() - t0, t1 - t0);
2017 updateResult == ProgressResult::Stopped ) {
2027 if (bytes > (
int)outFile.Write(buffer.get(), bytes)) {
2035 if (id3len > 0 && endOfFile) {
2036 if (bytes > (
int)outFile.Write(id3buffer.get(), id3len)) {
2058 return updateResult;
2075 S.StartVerticalLay();
2078 S.StartStatic(
XO(
"Resample"));
2080 S.StartHorizontalLay(wxALIGN_CENTER,
false);
2085"The project sample rate (%d) is not supported by the MP3\nfile format. ")
2088"The project sample rate (%d) and bit rate (%d kbps) combination is not\nsupported by the MP3 file format. ")
2089 .
Format( rate, bitrate ))
2090 +
XO(
"You may resample to one of the rates below.")
2093 S.EndHorizontalLay();
2095 S.StartHorizontalLay(wxALIGN_CENTER,
false);
2097 choice =
S.AddChoice(
XXO(
"Sample Rates"),
2100 for (
size_t ii = 0, nn =
sampRates.size(); ii < nn; ++ii) {
2101 int label = sampRates[ii];
2102 if (label >= lowrate && label <= highrate) {
2103 choices.push_back( Verbatim(
"%d" ).Format( label ) );
2110 std::max( 0, selected )
2113 S.EndHorizontalLay();
2117 S.AddStandardButtons();
2123 d.SetMinSize(d.GetSize());
2126 if (d.ShowModal() == wxID_CANCEL) {
2130 return wxAtoi(choice->GetStringSelection());
2134struct id3_tag_deleter {
2135 void operator () (id3_tag *p)
const {
if (p) id3_tag_delete(p); }
2137using id3_tag_holder = std::unique_ptr<id3_tag, id3_tag_deleter>;
2144 id3_tag_holder tp { id3_tag_new() };
2146 for (
const auto &pair : tags->
GetRange()) {
2147 const auto &n = pair.first;
2148 const auto &v = pair.second;
2149 const char *
name =
"TXXX";
2152 name = ID3_FRAME_TITLE;
2155 name = ID3_FRAME_ARTIST;
2158 name = ID3_FRAME_ALBUM;
2160 else if (n.CmpNoCase(
TAG_YEAR) == 0) {
2163 AddFrame(tp.get(), n, v,
"TYER");
2164 name = ID3_FRAME_YEAR;
2167 name = ID3_FRAME_GENRE;
2170 name = ID3_FRAME_COMMENT;
2173 name = ID3_FRAME_TRACK;
2176 AddFrame(tp.get(), n, v,
name);
2179 tp->options &= (~ID3_TAG_OPTION_COMPRESSION);
2184 #ifdef ID3_TAG_HAS_TAG_OPTION_ID3V2_3
2185 tp->options |= ID3_TAG_OPTION_ID3V2_3;
2192 len = id3_tag_render(tp.get(), 0);
2194 len = id3_tag_render(tp.get(), (id3_byte_t *)buffer.get());
2203void ExportMP3::AddFrame(
struct id3_tag *tp,
const wxString & n,
const wxString & v,
const char *
name)
2205 struct id3_frame *frame = id3_frame_new(
name);
2207 if (!n.IsAscii() || !v.IsAscii()) {
2208 id3_field_settextencoding(id3_frame_field(frame, 0), ID3_FIELD_TEXTENCODING_UTF_16);
2211 id3_field_settextencoding(id3_frame_field(frame, 0), ID3_FIELD_TEXTENCODING_ISO_8859_1);
2215 id3_utf8_ucs4duplicate((id3_utf8_t *) (
const char *) v.mb_str(wxConvUTF8)) };
2217 if (strcmp(
name, ID3_FRAME_COMMENT) == 0) {
2223 struct id3_frame *frame2 = id3_frame_new(
name);
2224 id3_field_setfullstring(id3_frame_field(frame2, 3), ucs4.get());
2225 id3_field *f2 = id3_frame_field(frame2, 1);
2226 memset(f2->immediate.value, 0,
sizeof(f2->immediate.value));
2227 id3_tag_attachframe(tp, frame2);
2229 id3_field_setfullstring(id3_frame_field(frame, 3), ucs4.get());
2231 else if (strcmp(
name,
"TXXX") == 0) {
2232 id3_field_setstring(id3_frame_field(frame, 2), ucs4.get());
2234 ucs4.reset(id3_utf8_ucs4duplicate((id3_utf8_t *) (
const char *) n.mb_str(wxConvUTF8)));
2236 id3_field_setstring(id3_frame_field(frame, 1), ucs4.get());
2239 auto addr = ucs4.get();
2240 id3_field_setstrings(id3_frame_field(frame, 1), 1, &addr);
2243 id3_tag_attachframe(tp, frame);
2248 []{
return std::make_unique< ExportMP3 >(); }
2258 auto versionString =
XO(
"MP3 export library not found");
2260#ifndef DISABLE_DYNAMIC_LOADING_LAME
2268#ifdef MP3_EXPORT_BUILT_IN
2269 versionString.Join(
XO(
"(Built-in)"),
" " );
2272#ifndef DISABLE_DYNAMIC_LOADING_LAME
2276 return versionString;
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
EVT_BUTTON(wxID_NO, DependencyDialog::OnNo) EVT_BUTTON(wxID_YES
const TranslatableString name
void ShowExportErrorDialog(wxString ErrorCode, TranslatableString message, const TranslatableString &caption, bool allowReporting)
void ShowDiskFullExportErrorDialog(const wxFileNameWrapper &fileName)
int lame_set_VBR_t(lame_global_flags *, vbr_mode)
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)
static const std::vector< int > fixRateValues
int lame_set_in_samplerate_t(lame_global_flags *, int)
int lame_close_t(lame_global_flags *)
TranslatableString n_kbps(int n)
EnumSetting< MP3RateMode > MP3RateModeSetting
TranslatableString GetMP3Version(wxWindow *parent, bool prompt)
static Exporter::RegisteredExportPlugin sRegisteredPlugin
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)
int lame_set_error_protection_t(lame_global_flags *, int)
static EnumSetting< MP3ChannelMode > MP3ChannelModeSetting
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)
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::unique_ptr< Character[], freer > MallocString
IteratorRange< Iterator > make_iterator_range(const Iterator &i1, const Iterator &i2)
an object holding per-project preferred sample rate
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...
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
Adapts EnumSettingBase to a particular enumeration type.
int SetNumExportChannels() override
Exporter plug-ins may override this to specify the number of channels in exported file....
unsigned long AddTags(AudacityProject *project, ArrayOf< char > &buffer, bool *endOfFile, const Tags *tags)
bool CheckFileName(wxFileName &filename, int format) override
int AskResample(int bitrate, int rate, int lowrate, int highrate)
ProgressResult Export(AudacityProject *project, std::unique_ptr< ProgressDialog > &pDialog, unsigned channels, const wxFileNameWrapper &fName, bool selectedOnly, double t0, double t1, MixerSpec *mixerSpec=NULL, const Tags *metadata=NULL, int subformat=0) override
called to export audio into a file.
void OptionsCreate(ShuttleGui &S, int format) override
ExportMP3Options(wxWindow *parent, int format)
virtual ~ExportMP3Options()
void OnVBR(wxCommandEvent &evt)
bool TransferDataToWindow() override
bool TransferDataFromWindow() override
void OnABR(wxCommandEvent &evt)
void OnSET(wxCommandEvent &evt)
void PopulateOrExchange(ShuttleGui &S)
void OnCBR(wxCommandEvent &evt)
void OnQuality(wxCommandEvent &evt)
void LoadNames(const TranslatableStrings &choices)
void OnMono(wxCommandEvent &evt)
void AddExtension(const FileExtension &extension, int index)
int AddFormat()
Add a NEW entry to the list of formats this plug-in can export.
void SetFormat(const wxString &format, int index)
std::unique_ptr< Mixer > CreateMixer(const TrackList &tracks, bool selectionOnly, double startTime, double stopTime, unsigned numOutChannels, size_t outBufferSize, bool outInterleaved, double outRate, sampleFormat outFormat, MixerSpec *mixerSpec)
void SetDescription(const TranslatableString &description, int index)
void SetCanMetaData(bool canmetadata, int index)
static void InitProgress(std::unique_ptr< ProgressDialog > &pDialog, const TranslatableString &title, const TranslatableString &message)
void SetMaxChannels(unsigned maxchannels, unsigned index)
virtual bool Flush(bool bCurrentOnly=false) wxOVERRIDE
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)
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()
void SetChannel(int mode)
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
static ProjectRate & Get(AudacityProject &project)
static ProjectWindow * Find(AudacityProject *pProject)
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
static TrackList & Get(AudacityProject &project)
Holds a msgid for the translation catalog; may also bind format arguments.
wxString Translation() const
struct with zillion of control parameters that control lame export (MP3 Conversion DLL).
void SetName(const TranslatableString &title)
FILES_API FilePath PathFromAddr(void *addr)
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)