Audacity 3.2.0
Public Member Functions | Static Private Member Functions | Private Attributes | List of all members
MP3ExportProcessor Class Referencefinal
Inheritance diagram for MP3ExportProcessor:
[legend]
Collaboration diagram for MP3ExportProcessor:
[legend]

Public Member Functions

bool Initialize (AudacityProject &project, const Parameters &parameters, const wxFileNameWrapper &filename, double t0, double t1, bool selectedOnly, double sampleRate, unsigned channels, MixerOptions::Downmix *mixerSpec, const Tags *tags) override
 Called before start processing. More...
 
ExportResult Process (ExportProcessorDelegate &delegate) override
 
- Public Member Functions inherited from ExportProcessor
 ExportProcessor (const ExportProcessor &)=delete
 
ExportProcessoroperator= (const ExportProcessor &)=delete
 
 ExportProcessor ()=default
 
virtual ~ExportProcessor ()
 
virtual bool Initialize (AudacityProject &project, const Parameters &parameters, const wxFileNameWrapper &filename, double t0, double t1, bool selectedOnly, double rate, unsigned channels, MixerOptions::Downmix *mixerSpec=nullptr, const Tags *tags=nullptr)=0
 Called before start processing. More...
 
virtual ExportResult Process (ExportProcessorDelegate &delegate)=0
 

Static Private Member Functions

static int AskResample (int bitrate, int rate, int lowrate, int highrate)
 
static unsigned long AddTags (ArrayOf< char > &buffer, bool *endOfFile, const Tags *tags)
 

Private Attributes

struct {
   TranslatableString   status
 
   unsigned   channels
 
   double   t0
 
   double   t1
 
   MP3Exporter   exporter
 
   wxFFile   outFile
 
   ArrayOf< char >   id3buffer
 
   unsigned long   id3len
 
   wxFileOffset   infoTagPos
 
   size_t   bufferSize
 
   int   inSamples
 
   std::unique_ptr< Mixer >   mixer
 
context
 

Additional Inherited Members

- Public Types inherited from ExportProcessor
using Parameters = std::vector< std::tuple< ExportOptionID, ExportValue > >
 

Detailed Description

Definition at line 1589 of file ExportMP3.cpp.

Member Function Documentation

◆ AddTags()

unsigned long MP3ExportProcessor::AddTags ( ArrayOf< char > &  buffer,
bool *  endOfFile,
const Tags tags 
)
staticprivate

Definition at line 2120 of file ExportMP3.cpp.

2121{
2122#ifdef USE_LIBID3TAG
2123 id3_tag_holder tp { id3_tag_new() };
2124
2125 for (const auto &pair : tags->GetRange()) {
2126 const auto &n = pair.first;
2127 const auto &v = pair.second;
2128 const char *name = "TXXX";
2129
2130 if (n.CmpNoCase(TAG_TITLE) == 0) {
2131 name = ID3_FRAME_TITLE;
2132 }
2133 else if (n.CmpNoCase(TAG_ARTIST) == 0) {
2134 name = ID3_FRAME_ARTIST;
2135 }
2136 else if (n.CmpNoCase(TAG_ALBUM) == 0) {
2137 name = ID3_FRAME_ALBUM;
2138 }
2139 else if (n.CmpNoCase(TAG_YEAR) == 0) {
2140 // LLL: Some apps do not like the newer frame ID (ID3_FRAME_YEAR),
2141 // so we add old one as well.
2142 AddFrame(tp.get(), n, v, "TYER");
2143 name = ID3_FRAME_YEAR;
2144 }
2145 else if (n.CmpNoCase(TAG_GENRE) == 0) {
2146 name = ID3_FRAME_GENRE;
2147 }
2148 else if (n.CmpNoCase(TAG_COMMENTS) == 0) {
2149 name = ID3_FRAME_COMMENT;
2150 }
2151 else if (n.CmpNoCase(TAG_TRACK) == 0) {
2152 name = ID3_FRAME_TRACK;
2153 }
2154
2155 AddFrame(tp.get(), n, v, name);
2156 }
2157
2158 tp->options &= (~ID3_TAG_OPTION_COMPRESSION); // No compression
2159
2160 // If this version of libid3tag supports it, use v2.3 ID3
2161 // tags instead of the newer, but less well supported, v2.4
2162 // that libid3tag uses by default.
2163 #ifdef ID3_TAG_HAS_TAG_OPTION_ID3V2_3
2164 tp->options |= ID3_TAG_OPTION_ID3V2_3;
2165 #endif
2166
2167 *endOfFile = false;
2168
2169 unsigned long len;
2170
2171 len = id3_tag_render(tp.get(), 0);
2172 buffer.reinit(len);
2173 len = id3_tag_render(tp.get(), (id3_byte_t *)buffer.get());
2174
2175 return len;
2176#else //ifdef USE_LIBID3TAG
2177 return 0;
2178#endif
2179}
#define TAG_TRACK
Definition: Tags.h:61
#define TAG_COMMENTS
Definition: Tags.h:64
#define TAG_GENRE
Definition: Tags.h:63
#define TAG_ALBUM
Definition: Tags.h:60
#define TAG_YEAR
Definition: Tags.h:62
#define TAG_TITLE
Definition: Tags.h:58
#define TAG_ARTIST
Definition: Tags.h:59
wxString name
Definition: TagsEditor.cpp:166
void reinit(Integral count, bool initialize=false)
Definition: MemoryX.h:59
Iterators GetRange() const
Definition: Tags.cpp:426

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

Referenced by Initialize().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ AskResample()

int MP3ExportProcessor::AskResample ( int  bitrate,
int  rate,
int  lowrate,
int  highrate 
)
staticprivate

Definition at line 2045 of file ExportMP3.cpp.

2046{
2047 wxDialogWrapper d(nullptr, wxID_ANY, XO("Invalid sample rate"));
2048 d.SetName();
2049 wxChoice *choice;
2051
2052 int selected = -1;
2053
2054 S.StartVerticalLay();
2055 {
2056 S.SetBorder(10);
2057 S.StartStatic(XO("Resample"));
2058 {
2059 S.StartHorizontalLay(wxALIGN_CENTER, false);
2060 {
2061 S.AddTitle(
2062 ((bitrate == 0)
2063 ? XO(
2064"The project sample rate (%d) is not supported by the MP3\nfile format. ")
2065 .Format( rate )
2066 : XO(
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.")
2070 );
2071 }
2072 S.EndHorizontalLay();
2073
2074 S.StartHorizontalLay(wxALIGN_CENTER, false);
2075 {
2076 choice = S.AddChoice(XXO("Sample Rates"),
2077 [&]{
2078 TranslatableStrings choices;
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 ) );
2083 if (label <= rate)
2084 selected = ii;
2085 }
2086 }
2087 return choices;
2088 }(),
2089 std::max( 0, selected )
2090 );
2091 }
2092 S.EndHorizontalLay();
2093 }
2094 S.EndStatic();
2095
2096 S.AddStandardButtons();
2097 }
2098 S.EndVerticalLay();
2099
2100 d.Layout();
2101 d.Fit();
2102 d.SetMinSize(d.GetSize());
2103 d.Center();
2104
2105 if (d.ShowModal() == wxID_CANCEL) {
2106 return 0;
2107 }
2108
2109 return wxAtoi(choice->GetStringSelection());
2110}
static const std::vector< int > sampRates
Definition: ExportMP3.cpp:197
XO("Cut/Copy/Paste")
XXO("&Cut/Copy/Paste Toolbar")
@ eIsCreating
Definition: ShuttleGui.h:37
#define S(N)
Definition: ToChars.cpp:64
std::vector< TranslatableString > TranslatableStrings
Abstract base class used in importing a file.
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:640

References eIsCreating, S, sampRates, wxDialogWrapper::SetName(), XO(), and XXO().

Referenced by Initialize().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Initialize()

bool MP3ExportProcessor::Initialize ( AudacityProject project,
const Parameters parameters,
const wxFileNameWrapper filename,
double  t0,
double  t1,
bool  selectedOnly,
double  rate,
unsigned  channels,
MixerOptions::Downmix mixerSpec,
const Tags tags 
)
overridevirtual

Called before start processing.

Parameters
projectProcessor may access project data, take care to exclude any data race
parametersA format-dependent set of parameters used in exporting
selectedOnlySet to true if all tracks should be mixed, to false if only the selected tracks should be mixed and exported.
tagsA Tags object that will over-ride the one in *project and be used to tag the file that is exported. @retern Implementations may simply return false without any error reporting. This is to temporarily preserve old behavior, which is to be removed in the nearest future.

Implements ExportProcessor.

Definition at line 1773 of file ExportMP3.cpp.

1780{
1781 context.t0 = t0;
1782 context.t1 = t1;
1783 context.channels = channels;
1784
1785 int rate = lrint(sampleRate);
1786 auto& exporter = context.exporter;
1787
1788#ifdef DISABLE_DYNAMIC_LOADING_LAME
1789 if (!exporter.InitLibrary(wxT(""))) {
1790 gPrefs->Write(wxT("/MP3/MP3LibPath"), wxString(wxT("")));
1791 gPrefs->Flush();
1792 throw ExportException(_("Could not initialize MP3 encoding library!"));
1793 }
1794#else
1795 if (!exporter.LoadLibrary(nullptr, MP3Exporter::Maybe)) {
1796 gPrefs->Write(wxT("/MP3/MP3LibPath"), wxString(wxT("")));
1797 gPrefs->Flush();
1798 throw ExportException(_("Could not open MP3 encoding library!"));
1799 }
1800
1802 gPrefs->Write(wxT("/MP3/MP3LibPath"), wxString(wxT("")));
1803 gPrefs->Flush();
1804 throw ExportException(_("Not a valid or supported MP3 encoding library!"));
1805 }
1806#endif // DISABLE_DYNAMIC_LOADING_LAME
1807
1808 // Retrieve preferences
1809 int highrate = 48000;
1810 int lowrate = 8000;
1811 int bitrate = 0;
1812 int quality;
1813
1815 parameters,
1817 std::string("CBR"));
1818 // Set the bitrate/quality and mode
1819 if (rmode == "SET") {
1820 quality = ExportPluginHelpers::GetParameterValue<int>(
1821 parameters,
1825 exporter.SetQuality(quality);
1826 }
1827 else if (rmode == "VBR") {
1828 quality = ExportPluginHelpers::GetParameterValue<int>(
1829 parameters,
1831 QUALITY_2);
1833 exporter.SetQuality(quality);
1834 }
1835 else if (rmode == "ABR") {
1837 parameters,
1839 128);
1841 exporter.SetBitrate(bitrate);
1842 if (bitrate > 160) {
1843 lowrate = 32000;
1844 }
1845 else if (bitrate < 32 || bitrate == 144) {
1846 highrate = 24000;
1847 }
1848 }
1849 else {
1852 exporter.SetBitrate(bitrate);
1853
1854 if (bitrate > 160) {
1855 lowrate = 32000;
1856 }
1857 else if (bitrate < 32 || bitrate == 144) {
1858 highrate = 24000;
1859 }
1860 }
1861
1862 // Verify sample rate
1863 if (!make_iterator_range( sampRates ).contains( rate ) ||
1864 (rate < lowrate) || (rate > highrate)) {
1865 // Force valid sample rate in macros.
1866 if (project.mBatchMode) {
1867 if (!make_iterator_range( sampRates ).contains( rate )) {
1868 auto const bestRateIt = std::lower_bound(sampRates.begin(),
1869 sampRates.end(), rate);
1870 rate = (bestRateIt == sampRates.end()) ? highrate : *bestRateIt;
1871 }
1872 if (rate < lowrate) {
1873 rate = lowrate;
1874 }
1875 else if (rate > highrate) {
1876 rate = highrate;
1877 }
1878 }
1879 // else validate or prompt
1880 else {
1881 if (!make_iterator_range( sampRates ).contains( rate ) ||
1882 (rate < lowrate) || (rate > highrate)) {
1883 //This call should go away once export project rate option
1884 //is available as an export dialog option
1885 rate = AskResample(bitrate, rate, lowrate, highrate);
1886 }
1887 if (rate == 0) {
1888 return false;
1889 }
1890 }
1891 }
1892
1893 context.inSamples = exporter.InitializeStream(channels, rate);
1894 if (context.inSamples < 0) {
1895 throw ExportException(_("Unable to initialize MP3 stream"));
1896 }
1897
1898 // Put ID3 tags at beginning of file
1899 if (metadata == nullptr)
1900 metadata = &Tags::Get( project );
1901
1902 // Open file for writing
1903 if (!context.outFile.Open(fName.GetFullPath(), wxT("w+b"))) {
1904 throw ExportException(_("Unable to open target file for writing"));
1905 }
1906
1907 bool endOfFile;
1908 context.id3len = AddTags(context.id3buffer, &endOfFile, metadata);
1909 if (context.id3len && !endOfFile) {
1910 if (context.id3len > context.outFile.Write(context.id3buffer.get(), context.id3len)) {
1911 // TODO: more precise message
1912 throw ExportErrorException("MP3:1882");
1913 }
1914 context.id3len = 0;
1915 context.id3buffer.reset();
1916 }
1917
1918 context.infoTagPos = context.outFile.Tell();
1919
1920 context.bufferSize = std::max(0, exporter.GetOutBufferSize());
1921 if (context.bufferSize == 0) {
1922 // TODO: more precise message
1923 throw ExportErrorException("MP3:1849");
1924 }
1925
1926 if (rmode == "SET") {
1927 context.status = (selectionOnly ?
1928 XO("Exporting selected audio with %s preset") :
1929 XO("Exporting the audio with %s preset"))
1930 .Format( setRateNamesShort[quality] );
1931 }
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"))
1936 .Format( varRateNames[quality] );
1937 }
1938 else {
1939 context.status = (selectionOnly ?
1940 XO("Exporting selected audio at %d Kbps") :
1941 XO("Exporting the audio at %d Kbps"))
1942 .Format( bitrate );
1943 }
1944
1946 project, selectionOnly, t0, t1, channels, context.inSamples, true, rate,
1947 floatSample, mixerSpec);
1948
1949 return true;
1950}
wxT("CloseDown"))
static const TranslatableStrings varRateNames
Definition: ExportMP3.cpp:165
@ MP3OptionIDQualityABR
Definition: ExportMP3.cpp:213
@ MP3OptionIDQualityVBR
Definition: ExportMP3.cpp:212
@ MP3OptionIDQualityCBR
Definition: ExportMP3.cpp:214
@ MP3OptionIDQualitySET
Definition: ExportMP3.cpp:211
@ MP3OptionIDMode
Definition: ExportMP3.cpp:210
static const TranslatableStrings setRateNamesShort
Definition: ExportMP3.cpp:190
@ QUALITY_2
Definition: ExportMP3.cpp:109
@ PRESET_STANDARD
Definition: ExportMP3.cpp:116
@ MODE_SET
Definition: ExportMP3.h:19
@ MODE_ABR
Definition: ExportMP3.h:21
@ MODE_VBR
Definition: ExportMP3.h:20
@ MODE_CBR
Definition: ExportMP3.h:22
#define _(s)
Definition: Internat.h:73
IteratorRange< Iterator > make_iterator_range(const Iterator &i1, const Iterator &i2)
Definition: IteratorX.h:210
audacity::BasicSettings * gPrefs
Definition: Prefs.cpp:68
const auto project
static T GetParameterValue(const ExportProcessor::Parameters &parameters, int id, T defaultValue=T())
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)
MP3Exporter exporter
Definition: ExportMP3.cpp:1597
static int AskResample(int bitrate, int rate, int lowrate, int highrate)
Definition: ExportMP3.cpp:2045
static unsigned long AddTags(ArrayOf< char > &buffer, bool *endOfFile, const Tags *tags)
Definition: ExportMP3.cpp:2120
struct MP3ExportProcessor::@175 context
int GetOutBufferSize()
Definition: ExportMP3.cpp:1266
void SetBitrate(int rate)
Definition: ExportMP3.cpp:959
bool ValidLibraryLoaded()
Definition: ExportMP3.cpp:947
bool LoadLibrary(wxWindow *parent, AskUser askuser)
Definition: ExportMP3.cpp:884
bool InitLibrary(wxString libpath)
Definition: ExportMP3.cpp:969
void SetMode(int mode)
Definition: ExportMP3.cpp:954
int InitializeStream(unsigned channels, int sampleRate)
Definition: ExportMP3.cpp:1168
void SetQuality(int q)
Definition: ExportMP3.cpp:964
static Tags & Get(AudacityProject &project)
Definition: Tags.cpp:214
virtual bool Flush() noexcept=0
virtual bool Write(const wxString &key, bool value)=0
#define lrint(dbl)
Definition: float_cast.h:169

References _, AddTags(), AskResample(), channels, context, ExportPluginHelpers::CreateMixer(), exporter, floatSample, audacity::BasicSettings::Flush(), Tags::Get(), MP3Exporter::GetOutBufferSize(), ExportPluginHelpers::GetParameterValue(), gPrefs, MP3Exporter::InitializeStream(), MP3Exporter::InitLibrary(), MP3Exporter::LoadLibrary(), lrint, make_iterator_range(), MP3Exporter::Maybe, MODE_ABR, MODE_CBR, MODE_SET, MODE_VBR, MP3OptionIDMode, MP3OptionIDQualityABR, MP3OptionIDQualityCBR, MP3OptionIDQualitySET, MP3OptionIDQualityVBR, PRESET_STANDARD, project, QUALITY_2, anonymous_namespace{ClipSegmentTest.cpp}::sampleRate, sampRates, MP3Exporter::SetBitrate(), MP3Exporter::SetMode(), MP3Exporter::SetQuality(), setRateNamesShort, t0, t1, MP3Exporter::ValidLibraryLoaded(), varRateNames, audacity::BasicSettings::Write(), wxT(), and XO().

Here is the call graph for this function:

◆ Process()

ExportResult MP3ExportProcessor::Process ( ExportProcessorDelegate delegate)
overridevirtual

Implements ExportProcessor.

Definition at line 1952 of file ExportMP3.cpp.

1953{
1954 delegate.SetStatusString(context.status);
1955
1956 auto& exporter = context.exporter;
1957 int bytes = 0;
1958
1959 ArrayOf<unsigned char> buffer{ context.bufferSize };
1960 wxASSERT(buffer);
1961
1962 auto exportResult = ExportResult::Success;
1963
1964 {
1965 while (exportResult == ExportResult::Success) {
1966 auto blockLen = context.mixer->Process();
1967 if (blockLen == 0)
1968 break;
1969
1970 float *mixed = (float *)context.mixer->GetBuffer();
1971
1972 if ((int)blockLen < context.inSamples) {
1973 if (context.channels > 1) {
1974 bytes = exporter.EncodeRemainder(mixed, blockLen, buffer.get());
1975 }
1976 else {
1977 bytes = exporter.EncodeRemainderMono(mixed, blockLen, buffer.get());
1978 }
1979 }
1980 else {
1981 if (context.channels > 1) {
1982 bytes = exporter.EncodeBuffer(mixed, buffer.get());
1983 }
1984 else {
1985 bytes = exporter.EncodeBufferMono(mixed, buffer.get());
1986 }
1987 }
1988
1989 if (bytes < 0) {
1990 throw ExportException(XO("Error %ld returned from MP3 encoder")
1991 .Format( bytes )
1992 .Translation());
1993 }
1994
1995 if (bytes > (int)context.outFile.Write(buffer.get(), bytes)) {
1996 // TODO: more precise message
1997 throw ExportDiskFullError(context.outFile.GetName());
1998 }
1999
2000 if(exportResult == ExportResult::Success)
2002 delegate, *context.mixer, context.t0, context.t1);
2003 }
2004 }
2005
2006 if (exportResult == ExportResult::Success) {
2007 bytes = exporter.FinishStream(buffer.get());
2008
2009 if (bytes < 0) {
2010 // TODO: more precise message
2011 throw ExportErrorException("MP3:1981");
2012 }
2013
2014 if (bytes > 0) {
2015 if (bytes > (int)context.outFile.Write(buffer.get(), bytes)) {
2016 // TODO: more precise message
2017 throw ExportErrorException("MP3:1988");
2018 }
2019 }
2020
2021 // Write ID3 tag if it was supposed to be at the end of the file
2022 if (context.id3len > 0) {
2023 if (bytes > (int)context.outFile.Write(context.id3buffer.get(), context.id3len)) {
2024 // TODO: more precise message
2025 throw ExportErrorException("MP3:1997");
2026 }
2027 }
2028
2029 // Always write the info (Xing/Lame) tag. Until we stop supporting Lame
2030 // versions before 3.98, we must do this after the MP3 file has been
2031 // closed.
2032 //
2033 // Also, if beWriteInfoTag() is used, mGF will no longer be valid after
2034 // this call, so do not use it.
2035 if (!exporter.PutInfoTag(context.outFile, context.infoTagPos) ||
2036 !context.outFile.Flush() ||
2037 !context.outFile.Close()) {
2038 // TODO: more precise message
2039 throw ExportErrorException("MP3:2012");
2040 }
2041 }
2042 return exportResult;
2043}
This simplifies arrays of arrays, each array separately allocated with NEW[] But it might be better t...
Definition: MemoryX.h:29
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...
virtual void SetStatusString(const TranslatableString &str)=0
int EncodeBufferMono(float inbuffer[], unsigned char outbuffer[])
Definition: ExportMP3.cpp:1295
int EncodeRemainderMono(float inbuffer[], int nSamples, unsigned char outbuffer[])
Definition: ExportMP3.cpp:1305
bool PutInfoTag(wxFFile &f, wxFileOffset off)
Definition: ExportMP3.cpp:1342
int EncodeBuffer(float inbuffer[], unsigned char outbuffer[])
Definition: ExportMP3.cpp:1274
int FinishStream(unsigned char outbuffer[])
Definition: ExportMP3.cpp:1316
int EncodeRemainder(float inbuffer[], int nSamples, unsigned char outbuffer[])
Definition: ExportMP3.cpp:1284

References context, MP3Exporter::EncodeBuffer(), MP3Exporter::EncodeBufferMono(), MP3Exporter::EncodeRemainder(), MP3Exporter::EncodeRemainderMono(), exporter, MP3Exporter::FinishStream(), MP3Exporter::PutInfoTag(), ExportProcessorDelegate::SetStatusString(), Success, ExportPluginHelpers::UpdateProgress(), and XO().

Here is the call graph for this function:

Member Data Documentation

◆ bufferSize

size_t MP3ExportProcessor::bufferSize

Definition at line 1602 of file ExportMP3.cpp.

◆ channels

unsigned MP3ExportProcessor::channels

Definition at line 1594 of file ExportMP3.cpp.

Referenced by Initialize().

◆ 

struct { ... } MP3ExportProcessor::context

Referenced by Initialize(), and Process().

◆ exporter

MP3Exporter MP3ExportProcessor::exporter

Definition at line 1597 of file ExportMP3.cpp.

Referenced by Initialize(), and Process().

◆ id3buffer

ArrayOf<char> MP3ExportProcessor::id3buffer

Definition at line 1599 of file ExportMP3.cpp.

◆ id3len

unsigned long MP3ExportProcessor::id3len

Definition at line 1600 of file ExportMP3.cpp.

◆ infoTagPos

wxFileOffset MP3ExportProcessor::infoTagPos

Definition at line 1601 of file ExportMP3.cpp.

◆ inSamples

int MP3ExportProcessor::inSamples

Definition at line 1603 of file ExportMP3.cpp.

◆ mixer

std::unique_ptr<Mixer> MP3ExportProcessor::mixer

Definition at line 1604 of file ExportMP3.cpp.

◆ outFile

wxFFile MP3ExportProcessor::outFile

Definition at line 1598 of file ExportMP3.cpp.

◆ status

TranslatableString MP3ExportProcessor::status

Definition at line 1593 of file ExportMP3.cpp.

◆ t0

double MP3ExportProcessor::t0

Definition at line 1595 of file ExportMP3.cpp.

Referenced by Initialize().

◆ t1

double MP3ExportProcessor::t1

Definition at line 1596 of file ExportMP3.cpp.

Referenced by Initialize().


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