Audacity  2.2.2
Public Member Functions | Private Member Functions | List of all members
ExportMP3 Class Referencefinal
Inheritance diagram for ExportMP3:
ExportPlugin

Public Member Functions

 ExportMP3 ()
 
bool CheckFileName (wxFileName &filename, int format) override
 
wxWindow * OptionsCreate (wxWindow *parent, int format) override
 
ProgressResult Export (AudacityProject *project, std::unique_ptr< ProgressDialog > &pDialog, unsigned channels, const wxString &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. More...
 
- Public Member Functions inherited from ExportPlugin
 ExportPlugin ()
 
virtual ~ExportPlugin ()
 
int AddFormat ()
 Add a NEW entry to the list of formats this plug-in can export. More...
 
void SetFormat (const wxString &format, int index)
 
void SetDescription (const wxString &description, int index)
 
void AddExtension (const wxString &extension, int index)
 
void SetExtensions (const wxArrayString &extensions, int index)
 
void SetMask (const wxString &mask, int index)
 
void SetMaxChannels (unsigned maxchannels, unsigned index)
 
void SetCanMetaData (bool canmetadata, int index)
 
virtual int GetFormatCount ()
 
virtual wxString GetFormat (int index)
 
virtual wxString GetDescription (int index)
 
virtual wxString GetExtension (int index=0)
 Return the (first) file name extension for the sub-format. More...
 
virtual wxArrayString GetExtensions (int index=0)
 Return all the file name extensions used for the sub-format. More...
 
virtual wxString GetMask (int index)
 
virtual unsigned GetMaxChannels (int index)
 
virtual bool GetCanMetaData (int index)
 
virtual bool IsExtension (const wxString &ext, int index)
 
virtual bool DisplayOptions (wxWindow *parent, int format=0)
 

Private Member Functions

int FindValue (CHOICES *choices, int cnt, int needle, int def)
 
wxString FindName (CHOICES *choices, int cnt, int needle)
 
int AskResample (int bitrate, int rate, int lowrate, int highrate)
 
id3_length_t AddTags (AudacityProject *project, ArrayOf< char > &buffer, bool *endOfFile, const Tags *tags)
 
int SetNumExportChannels () override
 Exporter plug-ins may override this to specify the number of channels in exported file. -1 for unspecified. More...
 

Additional Inherited Members

- Protected Member Functions inherited from ExportPlugin
std::unique_ptr< MixerCreateMixer (const WaveTrackConstArray &inputTracks, const TimeTrack *timeTrack, double startTime, double stopTime, unsigned numOutChannels, size_t outBufferSize, bool outInterleaved, double outRate, sampleFormat outFormat, bool highQuality=true, MixerSpec *mixerSpec=NULL)
 
- Static Protected Member Functions inherited from ExportPlugin
static void InitProgress (std::unique_ptr< ProgressDialog > &pDialog, const wxString &title, const wxString &message)
 

Detailed Description

Definition at line 1597 of file ExportMP3.cpp.

Constructor & Destructor Documentation

ExportMP3::ExportMP3 ( )

Definition at line 1630 of file ExportMP3.cpp.

References _(), ExportPlugin::AddExtension(), ExportPlugin::AddFormat(), InitMP3_Statics(), ExportPlugin::SetCanMetaData(), ExportPlugin::SetDescription(), ExportPlugin::SetFormat(), and ExportPlugin::SetMaxChannels().

1631 : ExportPlugin()
1632 {
1633  InitMP3_Statics();
1634  AddFormat();
1635  SetFormat(wxT("MP3"),0);
1636  AddExtension(wxT("mp3"),0);
1637  SetMaxChannels(2,0);
1638  SetCanMetaData(true,0);
1639  SetDescription(_("MP3 Files"),0);
1640 }
void SetDescription(const wxString &description, int index)
Definition: Export.cpp:118
void SetFormat(const wxString &format, int index)
Definition: Export.cpp:113
static void InitMP3_Statics()
Definition: ExportMP3.cpp:234
void SetMaxChannels(unsigned maxchannels, unsigned index)
Definition: Export.cpp:138
ExportPlugin()
Definition: Export.cpp:77
_("Move Track &Down")+wxT("\t")+(GetActiveProject() -> GetCommandManager() ->GetKeyFromName(wxT("TrackMoveDown")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveTopID, _("Move Track to &Top")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveTop")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveBottomID, _("Move Track to &Bottom")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveBottom")).Raw()), OnMoveTrack)#define SET_TRACK_NAME_PLUGIN_SYMBOLclass SetTrackNameCommand:public AudacityCommand
int AddFormat()
Add a NEW entry to the list of formats this plug-in can export.
Definition: Export.cpp:97
void SetCanMetaData(bool canmetadata, int index)
Definition: Export.cpp:143
void AddExtension(const wxString &extension, int index)
Definition: Export.cpp:123

Member Function Documentation

id3_length_t ExportMP3::AddTags ( AudacityProject project,
ArrayOf< char > &  buffer,
bool *  endOfFile,
const Tags tags 
)
private

Definition at line 2055 of file ExportMP3.cpp.

References Tags::GetRange(), name, ArrayOf< X >::reinit(), TAG_ALBUM, TAG_ARTIST, TAG_COMMENTS, TAG_GENRE, TAG_TITLE, TAG_TRACK, and TAG_YEAR.

Referenced by Export().

2056 {
2057 #ifdef USE_LIBID3TAG
2058  id3_tag_holder tp { id3_tag_new() };
2059 
2060  for (const auto &pair : tags->GetRange()) {
2061  const auto &n = pair.first;
2062  const auto &v = pair.second;
2063  const char *name = "TXXX";
2064 
2065  if (n.CmpNoCase(TAG_TITLE) == 0) {
2066  name = ID3_FRAME_TITLE;
2067  }
2068  else if (n.CmpNoCase(TAG_ARTIST) == 0) {
2069  name = ID3_FRAME_ARTIST;
2070  }
2071  else if (n.CmpNoCase(TAG_ALBUM) == 0) {
2072  name = ID3_FRAME_ALBUM;
2073  }
2074  else if (n.CmpNoCase(TAG_YEAR) == 0) {
2075  // LLL: Some apps do not like the newer frame ID (ID3_FRAME_YEAR),
2076  // so we add old one as well.
2077  AddFrame(tp.get(), n, v, "TYER");
2078  name = ID3_FRAME_YEAR;
2079  }
2080  else if (n.CmpNoCase(TAG_GENRE) == 0) {
2081  name = ID3_FRAME_GENRE;
2082  }
2083  else if (n.CmpNoCase(TAG_COMMENTS) == 0) {
2084  name = ID3_FRAME_COMMENT;
2085  }
2086  else if (n.CmpNoCase(TAG_TRACK) == 0) {
2087  name = ID3_FRAME_TRACK;
2088  }
2089 
2090  AddFrame(tp.get(), n, v, name);
2091  }
2092 
2093  tp->options &= (~ID3_TAG_OPTION_COMPRESSION); // No compression
2094 
2095  // If this version of libid3tag supports it, use v2.3 ID3
2096  // tags instead of the newer, but less well supported, v2.4
2097  // that libid3tag uses by default.
2098  #ifdef ID3_TAG_HAS_TAG_OPTION_ID3V2_3
2099  tp->options |= ID3_TAG_OPTION_ID3V2_3;
2100  #endif
2101 
2102  *endOfFile = false;
2103 
2104  id3_length_t len;
2105 
2106  len = id3_tag_render(tp.get(), 0);
2107  buffer.reinit(len);
2108  len = id3_tag_render(tp.get(), (id3_byte_t *)buffer.get());
2109 
2110  return len;
2111 #else //ifdef USE_LIBID3TAG
2112  return 0;
2113 #endif
2114 }
#define TAG_TRACK
Definition: Tags.h:65
void reinit(Integral count, bool initialize=false)
Definition: MemoryX.h:519
#define TAG_TITLE
Definition: Tags.h:62
#define TAG_ARTIST
Definition: Tags.h:63
const wxChar * name
Definition: Distortion.cpp:94
#define TAG_COMMENTS
Definition: Tags.h:68
#define TAG_GENRE
Definition: Tags.h:67
Iterators GetRange() const
Definition: Tags.cpp:444
#define TAG_ALBUM
Definition: Tags.h:64
#define TAG_YEAR
Definition: Tags.h:66
int ExportMP3::AskResample ( int  bitrate,
int  rate,
int  lowrate,
int  highrate 
)
private

Definition at line 1978 of file ExportMP3.cpp.

References _(), ShuttleGuiBase::AddChoice(), ShuttleGui::AddStandardButtons(), ShuttleGuiBase::AddTitle(), eIsCreating, ShuttleGuiBase::EndHorizontalLay(), ShuttleGuiBase::EndStatic(), ShuttleGuiBase::EndVerticalLay(), CHOICES::label, label, name, CHOICES::name, ShuttleGuiBase::SetBorder(), ShuttleGuiBase::StartHorizontalLay(), ShuttleGuiBase::StartStatic(), and ShuttleGuiBase::StartVerticalLay().

Referenced by Export().

1979 {
1980  wxDialogWrapper d(nullptr, wxID_ANY, wxString(_("Invalid sample rate")));
1981  d.SetName(d.GetTitle());
1982  wxChoice *choice;
1983  ShuttleGui S(&d, eIsCreating);
1984  wxString text;
1985 
1986  S.StartVerticalLay();
1987  {
1988  S.SetBorder(10);
1989  S.StartStatic(_("Resample"));
1990  {
1991  S.StartHorizontalLay(wxALIGN_CENTER, false);
1992  {
1993  if (bitrate == 0) {
1994  text.Printf(_("The project sample rate (%d) is not supported by the MP3\nfile format. "), rate);
1995  }
1996  else {
1997  text.Printf(_("The project sample rate (%d) and bit rate (%d kbps) combination is not\nsupported by the MP3 file format. "), rate, bitrate);
1998  }
1999 
2000  text += _("You may resample to one of the rates below.");
2001  S.AddTitle(text);
2002  }
2003  S.EndHorizontalLay();
2004 
2005  wxArrayString choices;
2006  wxString selected = wxT("");
2007  for (size_t i = 0; i < WXSIZEOF(sampRates); i++) {
2008  int label = sampRates[i].label;
2009  if (label >= lowrate && label <= highrate) {
2010  choices.Add(sampRates[i].name);
2011  if (label <= rate) {
2012  selected = sampRates[i].name;
2013  }
2014  }
2015  }
2016 
2017  if (selected.IsEmpty()) {
2018  selected = choices[0];
2019  }
2020 
2021  S.StartHorizontalLay(wxALIGN_CENTER, false);
2022  {
2023  choice = S.AddChoice(_("Sample Rates"),
2024  selected,
2025  &choices);
2026  }
2027  S.EndHorizontalLay();
2028  }
2029  S.EndStatic();
2030 
2031  S.AddStandardButtons();
2032  }
2033  S.EndVerticalLay();
2034 
2035  d.Layout();
2036  d.Fit();
2037  d.SetMinSize(d.GetSize());
2038  d.Center();
2039 
2040  if (d.ShowModal() == wxID_CANCEL) {
2041  return 0;
2042  }
2043 
2044  return wxAtoi(choice->GetStringSelection());
2045 }
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI...
Definition: ShuttleGui.h:409
wxString label
Definition: Tags.cpp:727
static CHOICES sampRates[]
Definition: ExportMP3.cpp:214
_("Move Track &Down")+wxT("\t")+(GetActiveProject() -> GetCommandManager() ->GetKeyFromName(wxT("TrackMoveDown")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveTopID, _("Move Track to &Top")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveTop")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveBottomID, _("Move Track to &Bottom")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveBottom")).Raw()), OnMoveTrack)#define SET_TRACK_NAME_PLUGIN_SYMBOLclass SetTrackNameCommand:public AudacityCommand
const wxChar * name
Definition: Distortion.cpp:94
wxString name
Definition: ExportMP3.cpp:144
int label
Definition: ExportMP3.cpp:145
bool ExportMP3::CheckFileName ( wxFileName &  filename,
int  format 
)
overridevirtual

Reimplemented from ExportPlugin.

Definition at line 1642 of file ExportMP3.cpp.

References _(), AudacityMessageBox(), gPrefs, MP3Exporter::LoadLibrary(), and MP3Exporter::Maybe.

1643 {
1644 #ifndef DISABLE_DYNAMIC_LOADING_LAME
1645  MP3Exporter exporter;
1646 
1647  if (!exporter.LoadLibrary(wxTheApp->GetTopWindow(), MP3Exporter::Maybe)) {
1648  AudacityMessageBox(_("Could not open MP3 encoding library!"));
1649  gPrefs->Write(wxT("/MP3/MP3LibPath"), wxString(wxT("")));
1650  gPrefs->Flush();
1651 
1652  return false;
1653  }
1654 #endif // DISABLE_DYNAMIC_LOADING_LAME
1655 
1656  return true;
1657 }
AudacityPrefs * gPrefs
Definition: Prefs.cpp:73
bool LoadLibrary(wxWindow *parent, AskUser askuser)
Definition: ExportMP3.cpp:981
int AudacityMessageBox(const wxString &message, const wxString &caption=AudacityMessageBoxCaptionStr(), long style=wxOK|wxCENTRE, wxWindow *parent=NULL, int x=wxDefaultCoord, int y=wxDefaultCoord)
Definition: ErrorDialog.h:92
_("Move Track &Down")+wxT("\t")+(GetActiveProject() -> GetCommandManager() ->GetKeyFromName(wxT("TrackMoveDown")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveTopID, _("Move Track to &Top")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveTop")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveBottomID, _("Move Track to &Bottom")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveBottom")).Raw()), OnMoveTrack)#define SET_TRACK_NAME_PLUGIN_SYMBOLclass SetTrackNameCommand:public AudacityCommand
Class used to export MP3 files.
Definition: ExportMP3.cpp:797
ProgressResult ExportMP3::Export ( AudacityProject project,
std::unique_ptr< ProgressDialog > &  pDialog,
unsigned  channels,
const wxString &  fName,
bool  selectedOnly,
double  t0,
double  t1,
MixerSpec mixerSpec = NULL,
const Tags metadata = NULL,
int  subformat = 0 
)
overridevirtual

called to export audio into a file.

Parameters
pDialogTo be initialized with pointer to a NEW ProgressDialog if it was null, otherwise gives an existing dialog to be reused (working around a problem in wxWidgets for Mac; see bug 1600)
selectedOnlySet to true if all tracks should be mixed, to false if only the selected tracks should be mixed and exported.
metadataA Tags object that will over-ride the one in *project and be used to tag the file that is exported.
subformatControl which of the multiple formats this exporter is capable of exporting should be used. Used where a single export plug-in handles a number of related formats, but they have separate entries in the Format drop-down list box. For example, the options to export to "Other PCM", "AIFF 16 Bit" and "WAV 16 Bit" are all the same libsndfile export plug-in, but with subformat set to 0, 1, and 2 respectively.
Returns
ProgressResult::Failed or ProgressResult::Cancelled if export fails to complete for any reason, in which case this function is responsible for alerting the user. Otherwise ProgressResult::Success or ProgressResult::Stopped

Implements ExportPlugin.

Definition at line 1668 of file ExportMP3.cpp.

References _(), AddTags(), AskResample(), AudacityMessageBox(), Cancelled, CHANNEL_JOINT, CHANNEL_MONO, CHANNEL_STEREO, ExportPlugin::CreateMixer(), MP3Exporter::EncodeBuffer(), MP3Exporter::EncodeBufferMono(), MP3Exporter::EncodeRemainder(), MP3Exporter::EncodeRemainderMono(), FindName(), FindValue(), MP3Exporter::FinishStream(), MP3Exporter::GetOutBufferSize(), AudacityProject::GetRate(), AudacityProject::GetTags(), TrackList::GetTimeTrack(), AudacityProject::GetTracks(), TrackList::GetWaveTrackConstArray(), gPrefs, MP3Exporter::InitializeStream(), MP3Exporter::InitLibrary(), ExportPlugin::InitProgress(), int16Sample, MP3Exporter::LoadLibrary(), lrint, MP3Exporter::Maybe, MODE_ABR, MODE_CBR, MODE_SET, MODE_VBR, PRESET_STANDARD, MP3Exporter::PutInfoTag(), QUALITY_2, ROUTINE_FAST, MP3Exporter::SetBitrate(), MP3Exporter::SetChannel(), MP3Exporter::SetMode(), MP3Exporter::SetQuality(), Stopped, Success, and MP3Exporter::ValidLibraryLoaded().

1678 {
1679  int rate = lrint(project->GetRate());
1680 #ifndef DISABLE_DYNAMIC_LOADING_LAME
1681  wxWindow *parent = project;
1682 #endif // DISABLE_DYNAMIC_LOADING_LAME
1683  const TrackList *tracks = project->GetTracks();
1684  MP3Exporter exporter;
1685 
1686 #ifdef DISABLE_DYNAMIC_LOADING_LAME
1687  if (!exporter.InitLibrary(wxT(""))) {
1688  AudacityMessageBox(_("Could not initialize MP3 encoding library!"));
1689  gPrefs->Write(wxT("/MP3/MP3LibPath"), wxString(wxT("")));
1690  gPrefs->Flush();
1691 
1693  }
1694 #else
1695  if (!exporter.LoadLibrary(parent, MP3Exporter::Maybe)) {
1696  AudacityMessageBox(_("Could not open MP3 encoding library!"));
1697  gPrefs->Write(wxT("/MP3/MP3LibPath"), wxString(wxT("")));
1698  gPrefs->Flush();
1699 
1701  }
1702 
1703  if (!exporter.ValidLibraryLoaded()) {
1704  AudacityMessageBox(_("Not a valid or supported MP3 encoding library!"));
1705  gPrefs->Write(wxT("/MP3/MP3LibPath"), wxString(wxT("")));
1706  gPrefs->Flush();
1707 
1709  }
1710 #endif // DISABLE_DYNAMIC_LOADING_LAME
1711 
1712  // Retrieve preferences
1713  int highrate = 48000;
1714  int lowrate = 8000;
1715  int bitrate = 0;
1716  int brate;
1717  int rmode;
1718  int vmode;
1719  int cmode;
1720  bool forceMono;
1721 
1722  gPrefs->Read(wxT("/FileFormats/MP3Bitrate"), &brate, 128);
1723  gPrefs->Read(wxT("/FileFormats/MP3RateMode"), &rmode, MODE_CBR);
1724  gPrefs->Read(wxT("/FileFormats/MP3VarMode"), &vmode, ROUTINE_FAST);
1725  gPrefs->Read(wxT("/FileFormats/MP3ChannelMode"), &cmode, CHANNEL_STEREO);
1726  gPrefs->Read(wxT("/FileFormats/MP3ForceMono"), &forceMono, 0);
1727 
1728  // Set the bitrate/quality and mode
1729  if (rmode == MODE_SET) {
1730  int q = FindValue(setRates, WXSIZEOF(setRates), brate, PRESET_STANDARD);
1731  int r = FindValue(varModes, WXSIZEOF(varModes), vmode, ROUTINE_FAST);
1732  exporter.SetMode(MODE_SET);
1733  exporter.SetQuality(q, r);
1734  }
1735  else if (rmode == MODE_VBR) {
1736  int q = FindValue(varRates, WXSIZEOF(varRates), brate, QUALITY_2);
1737  int r = FindValue(varModes, WXSIZEOF(varModes), vmode, ROUTINE_FAST);
1738  exporter.SetMode(MODE_VBR);
1739  exporter.SetQuality(q, r);
1740  }
1741  else if (rmode == MODE_ABR) {
1742  bitrate = FindValue(fixRates, WXSIZEOF(fixRates), brate, 128);
1743  exporter.SetMode(MODE_ABR);
1744  exporter.SetBitrate(bitrate);
1745 
1746  if (bitrate > 160) {
1747  lowrate = 32000;
1748  }
1749  else if (bitrate < 32 || bitrate == 144) {
1750  highrate = 24000;
1751  }
1752  }
1753  else {
1754  bitrate = FindValue(fixRates, WXSIZEOF(fixRates), brate, 128);
1755  exporter.SetMode(MODE_CBR);
1756  exporter.SetBitrate(bitrate);
1757 
1758  if (bitrate > 160) {
1759  lowrate = 32000;
1760  }
1761  else if (bitrate < 32 || bitrate == 144) {
1762  highrate = 24000;
1763  }
1764  }
1765 
1766  // Verify sample rate
1767  if (FindName(sampRates, WXSIZEOF(sampRates), rate).IsEmpty() ||
1768  (rate < lowrate) || (rate > highrate)) {
1769  rate = AskResample(bitrate, rate, lowrate, highrate);
1770  if (rate == 0) {
1772  }
1773  }
1774 
1775  // Set the channel mode
1776  if (forceMono) {
1777  exporter.SetChannel(CHANNEL_MONO);
1778  }
1779  else if (cmode == CHANNEL_JOINT) {
1780  exporter.SetChannel(CHANNEL_JOINT);
1781  }
1782  else {
1783  exporter.SetChannel(CHANNEL_STEREO);
1784  }
1785 
1786  auto inSamples = exporter.InitializeStream(channels, rate);
1787  if (((int)inSamples) < 0) {
1788  AudacityMessageBox(_("Unable to initialize MP3 stream"));
1790  }
1791 
1792  // Put ID3 tags at beginning of file
1793  if (metadata == NULL)
1794  metadata = project->GetTags();
1795 
1796  // Open file for writing
1797  wxFFile outFile(fName, wxT("w+b"));
1798  if (!outFile.IsOpened()) {
1799  AudacityMessageBox(_("Unable to open target file for writing"));
1801  }
1802 
1803  ArrayOf<char> id3buffer;
1804  bool endOfFile;
1805  id3_length_t id3len = AddTags(project, id3buffer, &endOfFile, metadata);
1806  if (id3len && !endOfFile) {
1807  if (id3len > outFile.Write(id3buffer.get(), id3len)) {
1808  // TODO: more precise message
1809  AudacityMessageBox(_("Unable to export"));
1811  }
1812  }
1813 
1814  wxFileOffset pos = outFile.Tell();
1815  auto updateResult = ProgressResult::Success;
1816  int bytes = 0;
1817 
1818  size_t bufferSize = std::max(0, exporter.GetOutBufferSize());
1819  if (bufferSize <= 0) {
1820  // TODO: more precise message
1821  AudacityMessageBox(_("Unable to export"));
1823  }
1824 
1825  ArrayOf<unsigned char> buffer{ bufferSize };
1826  wxASSERT(buffer);
1827 
1828  const WaveTrackConstArray waveTracks =
1829  tracks->GetWaveTrackConstArray(selectionOnly, false);
1830  {
1831  auto mixer = CreateMixer(waveTracks,
1832  tracks->GetTimeTrack(),
1833  t0, t1,
1834  channels, inSamples, true,
1835  rate, int16Sample, true, mixerSpec);
1836 
1837  wxString title;
1838  if (rmode == MODE_SET) {
1839  title.Printf(selectionOnly ?
1840  _("Exporting selected audio with %s preset") :
1841  _("Exporting the audio with %s preset"),
1842  FindName(setRates, WXSIZEOF(setRates), brate));
1843  }
1844  else if (rmode == MODE_VBR) {
1845  title.Printf(selectionOnly ?
1846  _("Exporting selected audio with VBR quality %s") :
1847  _("Exporting the audio with VBR quality %s"),
1848  FindName(varRates, WXSIZEOF(varRates), brate));
1849  }
1850  else {
1851  title.Printf(selectionOnly ?
1852  _("Exporting selected audio at %d Kbps") :
1853  _("Exporting the audio at %d Kbps"),
1854  brate);
1855  }
1856 
1857  InitProgress( pDialog, wxFileName(fName).GetName(), title );
1858  auto &progress = *pDialog;
1859 
1860  while (updateResult == ProgressResult::Success) {
1861  auto blockLen = mixer->Process(inSamples);
1862 
1863  if (blockLen == 0) {
1864  break;
1865  }
1866 
1867  short *mixed = (short *)mixer->GetBuffer();
1868 
1869  if ((int)blockLen < inSamples) {
1870  if (channels > 1) {
1871  bytes = exporter.EncodeRemainder(mixed, blockLen, buffer.get());
1872  }
1873  else {
1874  bytes = exporter.EncodeRemainderMono(mixed, blockLen, buffer.get());
1875  }
1876  }
1877  else {
1878  if (channels > 1) {
1879  bytes = exporter.EncodeBuffer(mixed, buffer.get());
1880  }
1881  else {
1882  bytes = exporter.EncodeBufferMono(mixed, buffer.get());
1883  }
1884  }
1885 
1886  if (bytes < 0) {
1887  wxString msg;
1888  msg.Printf(_("Error %ld returned from MP3 encoder"), bytes);
1889  AudacityMessageBox(msg);
1890  updateResult = ProgressResult::Cancelled;
1891  break;
1892  }
1893 
1894  if (bytes > (int)outFile.Write(buffer.get(), bytes)) {
1895  // TODO: more precise message
1896  AudacityMessageBox(_("Unable to export"));
1897  updateResult = ProgressResult::Cancelled;
1898  break;
1899  }
1900 
1901  updateResult = progress.Update(mixer->MixGetCurrentTime() - t0, t1 - t0);
1902  }
1903  }
1904 
1905  if ( updateResult == ProgressResult::Success ||
1906  updateResult == ProgressResult::Stopped ) {
1907  bytes = exporter.FinishStream(buffer.get());
1908 
1909  if (bytes < 0) {
1910  // TODO: more precise message
1911  AudacityMessageBox(_("Unable to export"));
1913  }
1914 
1915  if (bytes > 0) {
1916  if (bytes > (int)outFile.Write(buffer.get(), bytes)) {
1917  // TODO: more precise message
1918  AudacityMessageBox(_("Unable to export"));
1920  }
1921  }
1922 
1923  // Write ID3 tag if it was supposed to be at the end of the file
1924  if (id3len > 0 && endOfFile) {
1925  if (bytes > (int)outFile.Write(id3buffer.get(), id3len)) {
1926  // TODO: more precise message
1927  AudacityMessageBox(_("Unable to export"));
1929  }
1930  }
1931 
1932  // Always write the info (Xing/Lame) tag. Until we stop supporting Lame
1933  // versions before 3.98, we must do this after the MP3 file has been
1934  // closed.
1935  //
1936  // Also, if beWriteInfoTag() is used, mGF will no longer be valid after
1937  // this call, so do not use it.
1938  if (!exporter.PutInfoTag(outFile, pos) ||
1939  !outFile.Flush() ||
1940  !outFile.Close()) {
1941  // TODO: more precise message
1942  AudacityMessageBox(_("Unable to export"));
1944  }
1945  }
1946 
1947  return updateResult;
1948 }
int EncodeBuffer(short int inbuffer[], unsigned char outbuffer[])
Definition: ExportMP3.cpp:1323
AudacityPrefs * gPrefs
Definition: Prefs.cpp:73
A list of TrackListNode items.
Definition: Track.h:618
void SetBitrate(int rate)
Definition: ExportMP3.cpp:1050
#define QUALITY_2
Definition: ExportMP3.cpp:119
bool InitLibrary(wxString libpath)
Definition: ExportMP3.cpp:1066
bool LoadLibrary(wxWindow *parent, AskUser askuser)
Definition: ExportMP3.cpp:981
#define CHANNEL_JOINT
Definition: ExportMP3.cpp:113
int EncodeRemainder(short int inbuffer[], int nSamples, unsigned char outbuffer[])
Definition: ExportMP3.cpp:1333
#define MODE_VBR
Definition: ExportMP3.cpp:109
int AudacityMessageBox(const wxString &message, const wxString &caption=AudacityMessageBoxCaptionStr(), long style=wxOK|wxCENTRE, wxWindow *parent=NULL, int x=wxDefaultCoord, int y=wxDefaultCoord)
Definition: ErrorDialog.h:92
int InitializeStream(unsigned channels, int sampleRate)
Definition: ExportMP3.cpp:1209
static CHOICES varRates[]
Definition: ExportMP3.cpp:171
bool ValidLibraryLoaded()
Definition: ExportMP3.cpp:1038
std::unique_ptr< Mixer > CreateMixer(const WaveTrackConstArray &inputTracks, const TimeTrack *timeTrack, double startTime, double stopTime, unsigned numOutChannels, size_t outBufferSize, bool outInterleaved, double outRate, sampleFormat outFormat, bool highQuality=true, MixerSpec *mixerSpec=NULL)
Definition: Export.cpp:235
bool PutInfoTag(wxFFile &f, wxFileOffset off)
Definition: ExportMP3.cpp:1391
void SetMode(int mode)
Definition: ExportMP3.cpp:1045
TimeTrack * GetTimeTrack()
Definition: Track.cpp:1244
static CHOICES sampRates[]
Definition: ExportMP3.cpp:214
#define PRESET_STANDARD
Definition: ExportMP3.cpp:133
WaveTrackConstArray GetWaveTrackConstArray(bool selectionOnly, bool includeMuted=true) const
Definition: Track.cpp:1349
int FindValue(CHOICES *choices, int cnt, int needle, int def)
Definition: ExportMP3.cpp:1956
std::vector< std::shared_ptr< const WaveTrack > > WaveTrackConstArray
Definition: AudioIO.h:66
int EncodeBufferMono(short int inbuffer[], unsigned char outbuffer[])
Definition: ExportMP3.cpp:1344
#define lrint(dbl)
Definition: float_cast.h:136
static CHOICES varModes[]
Definition: ExportMP3.cpp:200
#define MODE_ABR
Definition: ExportMP3.cpp:110
#define ROUTINE_FAST
Definition: ExportMP3.cpp:128
int EncodeRemainderMono(short int inbuffer[], int nSamples, unsigned char outbuffer[])
Definition: ExportMP3.cpp:1354
#define MODE_SET
Definition: ExportMP3.cpp:108
_("Move Track &Down")+wxT("\t")+(GetActiveProject() -> GetCommandManager() ->GetKeyFromName(wxT("TrackMoveDown")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveTopID, _("Move Track to &Top")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveTop")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveBottomID, _("Move Track to &Bottom")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveBottom")).Raw()), OnMoveTrack)#define SET_TRACK_NAME_PLUGIN_SYMBOLclass SetTrackNameCommand:public AudacityCommand
#define CHANNEL_STEREO
Definition: ExportMP3.cpp:114
#define MODE_CBR
Definition: ExportMP3.cpp:111
int GetOutBufferSize()
Definition: ExportMP3.cpp:1315
static CHOICES setRates[]
Definition: ExportMP3.cpp:206
static CHOICES fixRates[]
Definition: ExportMP3.cpp:148
const Tags * GetTags()
Definition: Project.cpp:1453
void SetQuality(int q, int r)
Definition: ExportMP3.cpp:1055
int AskResample(int bitrate, int rate, int lowrate, int highrate)
Definition: ExportMP3.cpp:1978
void SetChannel(int mode)
Definition: ExportMP3.cpp:1061
double GetRate() const
Definition: Project.h:199
#define CHANNEL_MONO
Definition: ExportMP3.cpp:115
id3_length_t AddTags(AudacityProject *project, ArrayOf< char > &buffer, bool *endOfFile, const Tags *tags)
Definition: ExportMP3.cpp:2055
TrackList * GetTracks()
Definition: Project.h:192
wxString FindName(CHOICES *choices, int cnt, int needle)
Definition: ExportMP3.cpp:1967
Class used to export MP3 files.
Definition: ExportMP3.cpp:797
static void InitProgress(std::unique_ptr< ProgressDialog > &pDialog, const wxString &title, const wxString &message)
Definition: Export.cpp:253
int FinishStream(unsigned char outbuffer[])
Definition: ExportMP3.cpp:1365
wxString ExportMP3::FindName ( CHOICES choices,
int  cnt,
int  needle 
)
private

Definition at line 1967 of file ExportMP3.cpp.

References label, and CHOICES::name.

Referenced by Export().

1968 {
1969  for (int i = 0; i < cnt; i++) {
1970  if (choices[i].label == needle) {
1971  return choices[i].name.BeforeFirst(wxT(','));
1972  }
1973  }
1974 
1975  return wxT("");
1976 }
wxString label
Definition: Tags.cpp:727
wxString name
Definition: ExportMP3.cpp:144
int ExportMP3::FindValue ( CHOICES choices,
int  cnt,
int  needle,
int  def 
)
private

Definition at line 1956 of file ExportMP3.cpp.

References label.

Referenced by Export().

1957 {
1958  for (int i = 0; i < cnt; i++) {
1959  if (choices[i].label == needle) {
1960  return needle;
1961  }
1962  }
1963 
1964  return def;
1965 }
wxString label
Definition: Tags.cpp:727
wxWindow * ExportMP3::OptionsCreate ( wxWindow *  parent,
int  format 
)
overridevirtual

Implements ExportPlugin.

Definition at line 1950 of file ExportMP3.cpp.

References safenew.

1951 {
1952  wxASSERT(parent); // to justify safenew
1953  return safenew ExportMP3Options(parent, format);
1954 }
#define safenew
Definition: Audacity.h:230
int format
Definition: ExportPCM.cpp:56
int ExportMP3::SetNumExportChannels ( )
overrideprivatevirtual

Exporter plug-ins may override this to specify the number of channels in exported file. -1 for unspecified.

Reimplemented from ExportPlugin.

Definition at line 1659 of file ExportMP3.cpp.

References gPrefs.

1660 {
1661  bool mono;
1662  gPrefs->Read(wxT("/FileFormats/MP3ForceMono"), &mono, 0);
1663 
1664  return (mono)? 1 : -1;
1665 }
AudacityPrefs * gPrefs
Definition: Prefs.cpp:73

The documentation for this class was generated from the following file: