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

Public Member Functions

 ~MP2ExportProcessor () override
 
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 AddTags (ArrayOf< char > &buffer, bool *endOfFile, const Tags *tags)
 

Private Attributes

struct {
   TranslatableString   status
 
   double   t0
 
   double   t1
 
   wxFileNameWrapper   fName
 
   std::unique_ptr< Mixer >   mixer
 
   ArrayOf< char >   id3buffer
 
   int   id3len
 
   twolame_options *   encodeOptions {}
 
   std::unique_ptr< FileIO >   outFile
 
context
 

Static Private Attributes

static constexpr size_t pcmBufferSize = 9216 / 2
 
static constexpr size_t mp2BufferSize = 16384u
 

Additional Inherited Members

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

Detailed Description

Definition at line 243 of file ExportMP2.cpp.

Constructor & Destructor Documentation

◆ ~MP2ExportProcessor()

MP2ExportProcessor::~MP2ExportProcessor ( )
override

Definition at line 326 of file ExportMP2.cpp.

327{
328 if(context.encodeOptions)
329 twolame_close(&context.encodeOptions);
330}
struct MP2ExportProcessor::@173 context

References context.

Member Function Documentation

◆ AddTags()

int MP2ExportProcessor::AddTags ( ArrayOf< char > &  buffer,
bool *  endOfFile,
const Tags tags 
)
staticprivate

Definition at line 481 of file ExportMP2.cpp.

483{
484#ifdef USE_LIBID3TAG
485 id3_tag_holder tp { id3_tag_new() };
486
487 for (const auto &pair : tags->GetRange()) {
488 const auto &n = pair.first;
489 const auto &v = pair.second;
490 const char *name = "TXXX";
491
492 if (n.CmpNoCase(TAG_TITLE) == 0) {
493 name = ID3_FRAME_TITLE;
494 }
495 else if (n.CmpNoCase(TAG_ARTIST) == 0) {
496 name = ID3_FRAME_ARTIST;
497 }
498 else if (n.CmpNoCase(TAG_ALBUM) == 0) {
499 name = ID3_FRAME_ALBUM;
500 }
501 else if (n.CmpNoCase(TAG_YEAR) == 0) {
502 // LLL: Some apps do not like the newer frame ID (ID3_FRAME_YEAR),
503 // so we add old one as well.
504 AddFrame(tp.get(), n, v, "TYER");
505 name = ID3_FRAME_YEAR;
506 }
507 else if (n.CmpNoCase(TAG_GENRE) == 0) {
508 name = ID3_FRAME_GENRE;
509 }
510 else if (n.CmpNoCase(TAG_COMMENTS) == 0) {
511 name = ID3_FRAME_COMMENT;
512 }
513 else if (n.CmpNoCase(TAG_TRACK) == 0) {
514 name = ID3_FRAME_TRACK;
515 }
516
517 AddFrame(tp.get(), n, v, name);
518 }
519
520 tp->options &= (~ID3_TAG_OPTION_COMPRESSION); // No compression
521
522 // If this version of libid3tag supports it, use v2.3 ID3
523 // tags instead of the newer, but less well supported, v2.4
524 // that libid3tag uses by default.
525 #ifdef ID3_TAG_HAS_TAG_OPTION_ID3V2_3
526 tp->options |= ID3_TAG_OPTION_ID3V2_3;
527 #endif
528
529 *endOfFile = false;
530
531 id3_length_t len;
532
533 len = id3_tag_render(tp.get(), 0);
534 buffer.reinit(len);
535 len = id3_tag_render(tp.get(), (id3_byte_t *)buffer.get());
536
537
538 return len;
539#else //ifdef USE_LIBID3TAG
540 return 0;
541#endif
542}
#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:

◆ Initialize()

bool MP2ExportProcessor::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 333 of file ExportMP2.cpp.

340{
341 context.t0 = t0;
342 context.t1 = t1;
343 context.fName = fName;
344
345 bool stereo = (channels == 2);
346 const auto version = static_cast<TWOLAME_MPEG_version>(
349
350 const auto bitrate = version == TWOLAME_MPEG1
352 parameters,
354 : ExportPluginHelpers::GetParameterValue(
355 parameters,
357
358 wxLogNull logNo; /* temporarily disable wxWidgets error messages */
359
360 twolame_options *&encodeOptions = context.encodeOptions;
361 encodeOptions = twolame_init();
362
363 twolame_set_version(encodeOptions, version);
364 twolame_set_in_samplerate(encodeOptions, static_cast<int>(sampleRate));
365 twolame_set_out_samplerate(encodeOptions, static_cast<int>(sampleRate));
366 twolame_set_bitrate(encodeOptions, bitrate);
367 twolame_set_num_channels(encodeOptions, stereo ? 2 : 1);
368
369 if (twolame_init_params(encodeOptions) != 0)
370 {
371 throw ExportException(_("Cannot export MP2 with this sample rate and bit rate"));
372 }
373
374 // Put ID3 tags at beginning of file
375 if (metadata == NULL)
376 metadata = &Tags::Get( project );
377
378 context.outFile = std::make_unique<FileIO>(fName, FileIO::Output);
379 if (!context.outFile->IsOpened()) {
380 throw ExportException(_("Unable to open target file for writing"));
381 }
382
383 bool endOfFile;
384 context.id3len = AddTags(context.id3buffer, &endOfFile, metadata);
385 if (context.id3len && !endOfFile) {
386 if ( context.outFile->Write(context.id3buffer.get(), context.id3len).GetLastError() ) {
387 // TODO: more precise message
388 throw ExportErrorException("MP2:292");
389 }
390 context.id3len = 0;
391 context.id3buffer.reset();
392 }
393
394 context.status = selectionOnly
395 ? XO("Exporting selected audio at %ld kbps")
396 .Format( bitrate )
397 : XO("Exporting the audio at %ld kbps")
398 .Format( bitrate );
399
401 project, selectionOnly, t0, t1, stereo ? 2 : 1, pcmBufferSize, true,
402 sampleRate, int16Sample, mixerSpec);
403
404 return true;
405}
XO("Cut/Copy/Paste")
#define _(s)
Definition: Internat.h:73
const auto project
Utility class that provides helper functions for ExportPlugin.
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)
@ Output
Definition: FileIO.h:27
twolame_options * encodeOptions
Definition: ExportMP2.cpp:258
static int AddTags(ArrayOf< char > &buffer, bool *endOfFile, const Tags *tags)
Definition: ExportMP2.cpp:481
wxFileNameWrapper fName
Definition: ExportMP2.cpp:254
static constexpr size_t pcmBufferSize
Definition: ExportMP2.cpp:246
static Tags & Get(AudacityProject &project)
Definition: Tags.cpp:214

References _, AddTags(), context, ExportPluginHelpers::CreateMixer(), encodeOptions, fName, Tags::Get(), ExportPluginHelpers::GetParameterValue(), int16Sample, anonymous_namespace{ExportMP2.cpp}::MP2OptionIDBitRateMPEG1, anonymous_namespace{ExportMP2.cpp}::MP2OptionIDBitRateMPEG2, anonymous_namespace{ExportMP2.cpp}::MP2OptionIDVersion, FileIO::Output, pcmBufferSize, project, anonymous_namespace{ClipSegmentTest.cpp}::sampleRate, t0, t1, and XO().

Here is the call graph for this function:

◆ Process()

ExportResult MP2ExportProcessor::Process ( ExportProcessorDelegate delegate)
overridevirtual

Implements ExportProcessor.

Definition at line 407 of file ExportMP2.cpp.

408{
409 delegate.SetStatusString(context.status);
410 // We allocate a buffer which is twice as big as the
411 // input buffer, which should always be enough.
412 // We have to multiply by 4 because one sample is 2 bytes wide!
414
415 auto exportResult = ExportResult::Success;
416
417 {
418 while (exportResult == ExportResult::Success) {
419 auto pcmNumSamples = context.mixer->Process();
420 if (pcmNumSamples == 0)
421 break;
422
423 short *pcmBuffer = (short *)context.mixer->GetBuffer();
424
425 int mp2BufferNumBytes = twolame_encode_buffer_interleaved(
426 context.encodeOptions,
427 pcmBuffer,
428 pcmNumSamples,
429 mp2Buffer.get(),
431
432 if (mp2BufferNumBytes < 0) {
433 // TODO: more precise message
434 throw ExportErrorException("MP2:339");
435 }
436
437 if ( context.outFile->Write(mp2Buffer.get(), mp2BufferNumBytes).GetLastError() ) {
438 // TODO: more precise message
439 throw ExportDiskFullError(context.fName);
440 }
442 delegate, *context.mixer, context.t0, context.t1);
443 }
444 }
445
446 int mp2BufferNumBytes = twolame_encode_flush(
447 context.encodeOptions,
448 mp2Buffer.get(),
450
451 if (mp2BufferNumBytes > 0)
452 if ( context.outFile->Write(mp2Buffer.get(), mp2BufferNumBytes).GetLastError() ) {
453 // TODO: more precise message
454 throw ExportErrorException("MP2:362");
455 }
456
457 /* Write ID3 tag if it was supposed to be at the end of the file */
458
459 if (context.id3len)
460 if ( context.outFile->Write(context.id3buffer.get(), context.id3len).GetLastError() ) {
461 // TODO: more precise message
462 throw ExportErrorException("MP2:371");
463 }
464
465 if ( !context.outFile->Close() ) {
466 // TODO: more precise message
467 throw ExportErrorException("MP2:377");
468 }
469 return exportResult;
470}
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
static constexpr size_t mp2BufferSize
Definition: ExportMP2.cpp:247

References context, mp2BufferSize, ExportProcessorDelegate::SetStatusString(), Success, and ExportPluginHelpers::UpdateProgress().

Here is the call graph for this function:

Member Data Documentation

◆ 

struct { ... } MP2ExportProcessor::context

◆ encodeOptions

twolame_options* MP2ExportProcessor::encodeOptions {}

Definition at line 258 of file ExportMP2.cpp.

Referenced by Initialize().

◆ fName

wxFileNameWrapper MP2ExportProcessor::fName

Definition at line 254 of file ExportMP2.cpp.

Referenced by Initialize().

◆ id3buffer

ArrayOf<char> MP2ExportProcessor::id3buffer

Definition at line 256 of file ExportMP2.cpp.

◆ id3len

int MP2ExportProcessor::id3len

Definition at line 257 of file ExportMP2.cpp.

◆ mixer

std::unique_ptr<Mixer> MP2ExportProcessor::mixer

Definition at line 255 of file ExportMP2.cpp.

◆ mp2BufferSize

constexpr size_t MP2ExportProcessor::mp2BufferSize = 16384u
staticconstexprprivate

Definition at line 247 of file ExportMP2.cpp.

Referenced by Process().

◆ outFile

std::unique_ptr<FileIO> MP2ExportProcessor::outFile

Definition at line 259 of file ExportMP2.cpp.

◆ pcmBufferSize

constexpr size_t MP2ExportProcessor::pcmBufferSize = 9216 / 2
staticconstexprprivate

Definition at line 246 of file ExportMP2.cpp.

Referenced by Initialize().

◆ status

TranslatableString MP2ExportProcessor::status

Definition at line 251 of file ExportMP2.cpp.

◆ t0

double MP2ExportProcessor::t0

Definition at line 252 of file ExportMP2.cpp.

Referenced by Initialize().

◆ t1

double MP2ExportProcessor::t1

Definition at line 253 of file ExportMP2.cpp.

Referenced by Initialize().


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