50#define LIBTWOLAME_STATIC
60 struct id3_frame *id3_frame_new(
char const *);
61 id3_length_t id3_latin1_length(id3_latin1_t
const *);
62 void id3_latin1_decode(id3_latin1_t
const *, id3_ucs4_t *);
122 {
XO(
"MPEG2"),
XO(
"MPEG1") },
129 { 32, 48, 56, 64, 80, 96,112,128,160, 192, 224, 256, 320, 384 },
136 { 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160 },
146 std::unordered_map<ExportOptionID, ExportValue>
mValues;
153 mValues[option.id] = option.defaultValue;
158 return static_cast<int>(
mOptions.size());
162 if(index >= 0 && index <
mOptions.size())
171 const auto it =
mValues.find(
id);
182 if(it ==
mValues.end() || it->second.index() != value.index())
206 if(*std::get_if<int>(&it->second) == TWOLAME_MPEG1)
207 return { 32000, 44100, 48000 };
208 return {16000, 22050, 24000 };
213 config.
Write(
wxT(
"/FileFormats/MP2Version"), *std::get_if<int>(&it->second));
215 config.
Write(
wxT(
"/FileFormats/MP2BitrateMPEG1"), *std::get_if<int>(&it->second));
217 config.
Write(
wxT(
"/FileFormats/MP2BitrateMPEG2"), *std::get_if<int>(&it->second));
269 double t0,
double t1,
bool selectedOnly,
272 const Tags* tags)
override;
279 static void AddFrame(
struct id3_tag *tp,
const wxString & n,
const wxString & v,
const char *
name);
295 std::unique_ptr<ExportOptionsEditor>
311 wxT(
"MP2"),
XO(
"MP2 Files"), {
wxT(
"mp2") }, 2,
true
315std::unique_ptr<ExportOptionsEditor>
318 return std::make_unique<MP2ExportOptionsEditor>(listener);
323 return std::make_unique<MP2ExportProcessor>();
329 twolame_close(&
context.encodeOptions);
336 double t0,
double t1,
bool selectionOnly,
339 const Tags* metadata)
345 bool stereo = (channels == 2);
346 const auto version =
static_cast<TWOLAME_MPEG_version
>(
350 const auto bitrate = version == TWOLAME_MPEG1
371 throw ExportException(
_(
"Cannot export MP2 with this sample rate and bit rate"));
375 if (metadata == NULL)
379 if (!
context.outFile->IsOpened()) {
385 if (
context.id3len && !endOfFile) {
395 ?
XO(
"Exporting selected audio at %ld kbps")
397 :
XO(
"Exporting the audio at %ld kbps")
419 auto pcmNumSamples =
context.mixer->Process();
420 if (pcmNumSamples == 0)
423 short *pcmBuffer = (
short *)
context.mixer->GetBuffer();
425 int mp2BufferNumBytes = twolame_encode_buffer_interleaved(
432 if (mp2BufferNumBytes < 0) {
437 if (
context.outFile->Write(mp2Buffer.get(), mp2BufferNumBytes).GetLastError() ) {
446 int mp2BufferNumBytes = twolame_encode_flush(
451 if (mp2BufferNumBytes > 0)
452 if (
context.outFile->Write(mp2Buffer.get(), mp2BufferNumBytes).GetLastError() ) {
465 if ( !
context.outFile->Close() ) {
474struct id3_tag_deleter {
475 void operator () (id3_tag *p)
const {
if (p) id3_tag_delete(p); }
477using id3_tag_holder = std::unique_ptr<id3_tag, id3_tag_deleter>;
482 bool *endOfFile,
const Tags *tags)
485 id3_tag_holder tp { id3_tag_new() };
487 for (
const auto &pair : tags->
GetRange()) {
488 const auto &n = pair.first;
489 const auto &v = pair.second;
490 const char *
name =
"TXXX";
493 name = ID3_FRAME_TITLE;
496 name = ID3_FRAME_ARTIST;
499 name = ID3_FRAME_ALBUM;
501 else if (n.CmpNoCase(
TAG_YEAR) == 0) {
504 AddFrame(tp.get(), n, v,
"TYER");
505 name = ID3_FRAME_YEAR;
508 name = ID3_FRAME_GENRE;
511 name = ID3_FRAME_COMMENT;
514 name = ID3_FRAME_TRACK;
517 AddFrame(tp.get(), n, v,
name);
520 tp->options &= (~ID3_TAG_OPTION_COMPRESSION);
525 #ifdef ID3_TAG_HAS_TAG_OPTION_ID3V2_3
526 tp->options |= ID3_TAG_OPTION_ID3V2_3;
533 len = id3_tag_render(tp.get(), 0);
535 len = id3_tag_render(tp.get(), (id3_byte_t *)buffer.get());
545void MP2ExportProcessor::AddFrame(
struct id3_tag *tp,
const wxString & n,
const wxString & v,
const char *
name)
547 struct id3_frame *frame = id3_frame_new(
name);
549 if (!n.IsAscii() || !v.IsAscii()) {
550 id3_field_settextencoding(id3_frame_field(frame, 0), ID3_FIELD_TEXTENCODING_UTF_16);
553 id3_field_settextencoding(id3_frame_field(frame, 0), ID3_FIELD_TEXTENCODING_ISO_8859_1);
557 id3_utf8_ucs4duplicate((id3_utf8_t *) (
const char *) v.mb_str(wxConvUTF8)) };
559 if (strcmp(
name, ID3_FRAME_COMMENT) == 0) {
565 id3_field *f = id3_frame_field(frame, 1);
566 memset(f->immediate.value, 0,
sizeof(f->immediate.value));
567 id3_field_setfullstring(id3_frame_field(frame, 3), ucs4.get());
569 else if (strcmp(
name,
"TXXX") == 0) {
570 id3_field_setstring(id3_frame_field(frame, 2), ucs4.get());
572 ucs4.reset(id3_utf8_ucs4duplicate((id3_utf8_t *) (
const char *) n.mb_str(wxConvUTF8)));
574 id3_field_setstring(id3_frame_field(frame, 1), ucs4.get());
577 auto addr = ucs4.get();
578 id3_field_setstrings(id3_frame_field(frame, 1), 1, &addr);
581 id3_tag_attachframe(tp, frame);
586 []{
return std::make_unique< ExportMP2 >(); }
static ExportPluginRegistry::RegisteredPlugin sRegisteredPlugin
TranslatableString n_kbps(int n)
std::variant< bool, int, double, std::string > ExportValue
A type of option values (parameters) used by exporting plugins.
std::unique_ptr< Character[], freer > MallocString
declares abstract base class Track, TrackList, and iterators over TrackList
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...
int GetFormatCount() const override
std::unique_ptr< ExportProcessor > CreateProcessor(int) const override
std::unique_ptr< ExportOptionsEditor > CreateOptionsEditor(int, ExportOptionsEditor::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< ExportOption > mOptions
bool GetOption(int index, ExportOption &option) const override
void Load(const audacity::BasicSettings &config) override
std::unordered_map< ExportOptionID, ExportValue > mValues
bool GetValue(ExportOptionID id, ExportValue &value) const override
int GetOptionsCount() const override
MP2ExportOptionsEditor(Listener *listener)
SampleRateList GetSampleRateList() const override
void Store(audacity::BasicSettings &config) const override
bool SetValue(ExportOptionID id, const ExportValue &value) override
ArrayOf< char > id3buffer
static constexpr size_t mp2BufferSize
struct MP2ExportProcessor::@173 context
ExportResult Process(ExportProcessorDelegate &delegate) override
std::unique_ptr< FileIO > outFile
twolame_options * encodeOptions
static int AddTags(ArrayOf< char > &buffer, bool *endOfFile, const Tags *tags)
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.
TranslatableString status
std::unique_ptr< Mixer > mixer
~MP2ExportProcessor() override
static constexpr size_t pcmBufferSize
A matrix of booleans, one row per input channel, column per output.
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 Write(const wxString &key, bool value)=0
virtual bool Read(const wxString &key, bool *value) const =0
constexpr auto sampleRate
const std::initializer_list< ExportOption > MP2Options
const TranslatableStrings BitRateMPEG2Names
@ MP2OptionIDBitRateMPEG2
@ MP2OptionIDBitRateMPEG1
const TranslatableStrings BitRateMPEG1Names
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.