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::@174 context

References context.

Member Function Documentation

◆ AddTags()

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

Definition at line 483 of file ExportMP2.cpp.

485{
486#ifdef USE_LIBID3TAG
487 id3_tag_holder tp { id3_tag_new() };
488
489 for (const auto &pair : tags->GetRange()) {
490 const auto &n = pair.first;
491 const auto &v = pair.second;
492 const char *name = "TXXX";
493
494 if (n.CmpNoCase(TAG_TITLE) == 0) {
495 name = ID3_FRAME_TITLE;
496 }
497 else if (n.CmpNoCase(TAG_ARTIST) == 0) {
498 name = ID3_FRAME_ARTIST;
499 }
500 else if (n.CmpNoCase(TAG_ALBUM) == 0) {
501 name = ID3_FRAME_ALBUM;
502 }
503 else if (n.CmpNoCase(TAG_YEAR) == 0) {
504 // LLL: Some apps do not like the newer frame ID (ID3_FRAME_YEAR),
505 // so we add old one as well.
506 AddFrame(tp.get(), n, v, "TYER");
507 name = ID3_FRAME_YEAR;
508 }
509 else if (n.CmpNoCase(TAG_GENRE) == 0) {
510 name = ID3_FRAME_GENRE;
511 }
512 else if (n.CmpNoCase(TAG_COMMENTS) == 0) {
513 name = ID3_FRAME_COMMENT;
514 }
515 else if (n.CmpNoCase(TAG_TRACK) == 0) {
516 name = ID3_FRAME_TRACK;
517 }
518
519 AddFrame(tp.get(), n, v, name);
520 }
521
522 tp->options &= (~ID3_TAG_OPTION_COMPRESSION); // No compression
523
524 // If this version of libid3tag supports it, use v2.3 ID3
525 // tags instead of the newer, but less well supported, v2.4
526 // that libid3tag uses by default.
527 #ifdef ID3_TAG_HAS_TAG_OPTION_ID3V2_3
528 tp->options |= ID3_TAG_OPTION_ID3V2_3;
529 #endif
530
531 *endOfFile = false;
532
533 id3_length_t len;
534
535 len = id3_tag_render(tp.get(), 0);
536 buffer.reinit(len);
537 len = id3_tag_render(tp.get(), (id3_byte_t *)buffer.get());
538
539
540 return len;
541#else //ifdef USE_LIBID3TAG
542 return 0;
543#endif
544}
const TranslatableString name
Definition: Distortion.cpp:76
#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
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 const auto &tracks = TrackList::Get( project );
358
359 wxLogNull logNo; /* temporarily disable wxWidgets error messages */
360
361 twolame_options *&encodeOptions = context.encodeOptions;
362 encodeOptions = twolame_init();
363
364 twolame_set_version(encodeOptions, version);
365 twolame_set_in_samplerate(encodeOptions, static_cast<int>(sampleRate));
366 twolame_set_out_samplerate(encodeOptions, static_cast<int>(sampleRate));
367 twolame_set_bitrate(encodeOptions, bitrate);
368 twolame_set_num_channels(encodeOptions, stereo ? 2 : 1);
369
370 if (twolame_init_params(encodeOptions) != 0)
371 {
372 throw ExportException(_("Cannot export MP2 with this sample rate and bit rate"));
373 }
374
375 // Put ID3 tags at beginning of file
376 if (metadata == NULL)
377 metadata = &Tags::Get( project );
378
379 context.outFile = std::make_unique<FileIO>(fName, FileIO::Output);
380 if (!context.outFile->IsOpened()) {
381 throw ExportException(_("Unable to open target file for writing"));
382 }
383
384 bool endOfFile;
385 context.id3len = AddTags(context.id3buffer, &endOfFile, metadata);
386 if (context.id3len && !endOfFile) {
387 if ( context.outFile->Write(context.id3buffer.get(), context.id3len).GetLastError() ) {
388 // TODO: more precise message
389 throw ExportErrorException("MP2:292");
390 }
391 context.id3len = 0;
392 context.id3buffer.reset();
393 }
394
395 context.status = selectionOnly
396 ? XO("Exporting selected audio at %ld kbps")
397 .Format( bitrate )
398 : XO("Exporting the audio at %ld kbps")
399 .Format( bitrate );
400
401 context.mixer = ExportPluginHelpers::CreateMixer(tracks, selectionOnly,
402 t0, t1,
403 stereo ? 2 : 1, pcmBufferSize, true,
404 sampleRate, int16Sample, mixerSpec);
405
406 return true;
407}
XO("Cut/Copy/Paste")
#define _(s)
Definition: Internat.h:73
const auto tracks
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 TrackList &tracks, 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:483
wxFileNameWrapper fName
Definition: ExportMP2.cpp:254
static constexpr size_t pcmBufferSize
Definition: ExportMP2.cpp:246
static Tags & Get(AudacityProject &project)
Definition: Tags.cpp:214
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:314

References _, AddTags(), context, ExportPluginHelpers::CreateMixer(), encodeOptions, fName, Tags::Get(), TrackList::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, tracks, and XO().

Here is the call graph for this function:

◆ Process()

ExportResult MP2ExportProcessor::Process ( ExportProcessorDelegate delegate)
overridevirtual

Implements ExportProcessor.

Definition at line 409 of file ExportMP2.cpp.

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