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

Public Member Functions

 ~WavPackExportProcessor ()
 
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 WriteBlock (void *id, void *data, int32_t length)
 

Private Attributes

struct {
   TranslatableString   status
 
   double   t0
 
   double   t1
 
   unsigned   numChannels
 
   wxFileNameWrapper   fName
 
   sampleFormat   format
 
   WriteId   outWvFile
 
   WriteId   outWvcFile
 
   WavpackContext *   wpc {}
 
   std::unique_ptr< Mixer >   mixer
 
   std::unique_ptr< Tags >   metadata
 
context
 

Static Private Attributes

static constexpr size_t SAMPLES_PER_RUN = 8192u
 

Additional Inherited Members

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

Detailed Description

Definition at line 244 of file ExportWavPack.cpp.

Constructor & Destructor Documentation

◆ ~WavPackExportProcessor()

WavPackExportProcessor::~WavPackExportProcessor ( )

Definition at line 373 of file ExportWavPack.cpp.

374{
375 if(context.wpc)
376 WavpackCloseFile(context.wpc);
377}
struct WavPackExportProcessor::@187 context

References context.

Member Function Documentation

◆ Initialize()

bool WavPackExportProcessor::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 379 of file ExportWavPack.cpp.

386{
387 context.t0 = t0;
388 context.t1 = t1;
389 context.numChannels = numChannels;
390 context.fName = fName;
391
392 WavpackConfig config = {};
393 auto& outWvFile = context.outWvFile;
394 auto& outWvcFile = context.outWvcFile;
395 outWvFile.file = std::make_unique< wxFile >();
396
397 if (!outWvFile.file->Create(fName.GetFullPath(), true) || !outWvFile.file->IsOpened()) {
398 throw ExportException(_("Unable to open target file for writing"));
399 }
400
401 const auto &tracks = TrackList::Get( project );
402
403 const auto quality = ExportPluginHelpers::GetParameterValue<int>(
404 parameters,
406 1);
407 const auto hybridMode = ExportPluginHelpers::GetParameterValue<bool>(
408 parameters,
410 false);
411 const auto createCorrectionFile = ExportPluginHelpers::GetParameterValue<bool>(
412 parameters,
414 false);
415 const auto bitRate = ExportPluginHelpers::GetParameterValue<int>(
416 parameters,
418 40);
419 const auto bitDepth = ExportPluginHelpers::GetParameterValue<int>(
420 parameters,
422 16);
423
424
425 context.format = int16Sample;
426 if (bitDepth == 24) {
427 context.format = int24Sample;
428 } else if (bitDepth == 32) {
429 context.format = floatSample;
430 }
431
432 config.num_channels = numChannels;
433 config.sample_rate = sampleRate;
434 config.bits_per_sample = bitDepth;
435 config.bytes_per_sample = bitDepth/8;
436 config.float_norm_exp = context.format == floatSample ? 127 : 0;
437
438 if (config.num_channels <= 2)
439 config.channel_mask = 0x5 - config.num_channels;
440 else if (config.num_channels <= 18)
441 config.channel_mask = (1U << config.num_channels) - 1;
442 else
443 config.channel_mask = 0x3FFFF;
444
445 if (quality == 0) {
446 config.flags |= CONFIG_FAST_FLAG;
447 } else if (quality == 2) {
448 config.flags |= CONFIG_HIGH_FLAG;
449 } else if (quality == 3) {
450 config.flags |= CONFIG_HIGH_FLAG | CONFIG_VERY_HIGH_FLAG;
451 }
452
453 if (hybridMode) {
454 config.flags |= CONFIG_HYBRID_FLAG;
455 config.bitrate = bitRate / 10.0;
456
457 if (createCorrectionFile) {
458 config.flags |= CONFIG_CREATE_WVC;
459
460 outWvcFile.file = std::make_unique< wxFile >();
461 if (!outWvcFile.file->Create(fName.GetFullPath().Append("c"), true)) {
462 throw ExportException(_("Unable to create target file for writing"));
463 }
464 }
465 }
466
467 // If we're not creating a correction file now, any one that currently exists with this name
468 // will become obsolete now, so delete it if it happens to exist (although it usually won't)
469
470 if (!hybridMode || !createCorrectionFile)
471 wxRemoveFile(fName.GetFullPath().Append("c"));
472
473 context.wpc = WavpackOpenFileOutput(WriteBlock, &outWvFile, createCorrectionFile ? &outWvcFile : nullptr);
474 if (!WavpackSetConfiguration64(context.wpc, &config, -1, nullptr) || !WavpackPackInit(context.wpc)) {
475 throw ExportErrorException( WavpackGetErrorMessage(context.wpc) );
476 }
477
478 context.status = selectionOnly
479 ? XO("Exporting selected audio as WavPack")
480 : XO("Exporting the audio as WavPack");
481
482 context.metadata = std::make_unique<Tags>(
483 metadata == nullptr
484 ? Tags::Get( project )
485 : *metadata
486 );
487
488 context.mixer = ExportPluginHelpers::CreateMixer(tracks, selectionOnly,
489 t0, t1,
491 sampleRate, context.format, mixerSpec);
492
493 return true;
494}
XO("Cut/Copy/Paste")
#define _(s)
Definition: Internat.h:73
const auto tracks
const auto project
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)
static Tags & Get(AudacityProject &project)
Definition: Tags.cpp:214
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:314
static constexpr size_t SAMPLES_PER_RUN
static int WriteBlock(void *id, void *data, int32_t length)
wxFileNameWrapper fName
std::unique_ptr< Tags > metadata
std::unique_ptr< wxFile > file

References _, context, ExportPluginHelpers::CreateMixer(), WriteId::file, floatSample, fName, Tags::Get(), TrackList::Get(), int16Sample, int24Sample, metadata, numChannels, anonymous_namespace{ExportWavPack.cpp}::OptionIDBitDepth, anonymous_namespace{ExportWavPack.cpp}::OptionIDBitRate, anonymous_namespace{ExportWavPack.cpp}::OptionIDCreateCorrection, anonymous_namespace{ExportWavPack.cpp}::OptionIDHybridMode, anonymous_namespace{ExportWavPack.cpp}::OptionIDQuality, outWvcFile, outWvFile, project, anonymous_namespace{ClipSegmentTest.cpp}::sampleRate, SAMPLES_PER_RUN, t0, t1, tracks, WriteBlock(), and XO().

Here is the call graph for this function:

◆ Process()

ExportResult WavPackExportProcessor::Process ( ExportProcessorDelegate delegate)
overridevirtual

Implements ExportProcessor.

Definition at line 496 of file ExportWavPack.cpp.

497{
498 delegate.SetStatusString(context.status);
499
500 const size_t bufferSize = SAMPLES_PER_RUN * context.numChannels;
501
502 ArrayOf<int32_t> wavpackBuffer{ bufferSize };
503
504 auto exportResult = ExportResult::Success;
505 {
506
507 while (exportResult == ExportResult::Success) {
508 auto samplesThisRun = context.mixer->Process();
509
510 if (samplesThisRun == 0)
511 break;
512
513 if (context.format == int16Sample) {
514 const int16_t *mixed = reinterpret_cast<const int16_t*>(context.mixer->GetBuffer());
515 for (decltype(samplesThisRun) j = 0; j < samplesThisRun; j++) {
516 for (size_t i = 0; i < context.numChannels; i++) {
517 wavpackBuffer[j*context.numChannels + i] = (static_cast<int32_t>(*mixed++) * 65536) >> 16;
518 }
519 }
520 } else {
521 const int *mixed = reinterpret_cast<const int*>(context.mixer->GetBuffer());
522 for (decltype(samplesThisRun) j = 0; j < samplesThisRun; j++) {
523 for (size_t i = 0; i < context.numChannels; i++) {
524 wavpackBuffer[j*context.numChannels + i] = *mixed++;
525 }
526 }
527 }
528
529 if (!WavpackPackSamples(context.wpc, wavpackBuffer.get(), samplesThisRun)) {
530 throw ExportErrorException(WavpackGetErrorMessage(context.wpc));
531 }
533 delegate, *context.mixer, context.t0, context.t1);
534 }
535 }
536
537 if (!WavpackFlushSamples(context.wpc)) {
538 throw ExportErrorException( WavpackGetErrorMessage(context.wpc) );
539 } else {
540
541
542 wxString n;
543 for (const auto &pair : context.metadata->GetRange()) {
544 n = pair.first;
545 const auto &v = pair.second;
546
547 WavpackAppendTagItem(context.wpc,
548 n.mb_str(wxConvUTF8),
549 v.mb_str(wxConvUTF8),
550 static_cast<int>( strlen(v.mb_str(wxConvUTF8)) ));
551 }
552
553 if (!WavpackWriteTag(context.wpc)) {
554 throw ExportErrorException( WavpackGetErrorMessage(context.wpc) );
555 }
556 }
557
558 if ( !context.outWvFile.file.get()->Close()
559 || ( context.outWvcFile.file && context.outWvcFile.file.get() && !context.outWvcFile.file.get()->Close())) {
560 return ExportResult::Error;
561 }
562
563 // wxFile::Create opens the file with only write access
564 // So, need to open the file again with both read and write access
565 if (!context.outWvFile.file->Open(context.fName.GetFullPath(), wxFile::read_write)) {
566 throw ExportErrorException("Unable to update the actual length of the file");
567 }
568
569 ArrayOf<int32_t> firstBlockBuffer { context.outWvFile.firstBlockSize };
570 context.outWvFile.file->Read(firstBlockBuffer.get(), context.outWvFile.firstBlockSize);
571
572 // Update the first block written with the actual number of samples written
573 WavpackUpdateNumSamples(context.wpc, firstBlockBuffer.get());
574 context.outWvFile.file->Seek(0);
575 context.outWvFile.file->Write(firstBlockBuffer.get(), context.outWvFile.firstBlockSize);
576
577 if ( !context.outWvFile.file.get()->Close() ) {
578 return ExportResult::Error;
579 }
580 return exportResult;
581}
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

References context, Error, int16Sample, SAMPLES_PER_RUN, ExportProcessorDelegate::SetStatusString(), Success, and ExportPluginHelpers::UpdateProgress().

Here is the call graph for this function:

◆ WriteBlock()

int WavPackExportProcessor::WriteBlock ( void *  id,
void *  data,
int32_t  length 
)
staticprivate

Definition at line 586 of file ExportWavPack.cpp.

587{
588 if (id == nullptr || data == nullptr || length == 0)
589 return true; // This is considered to be success in wavpack.c reference code
590
591 WriteId *outId = static_cast<WriteId*>(id);
592
593 if (!outId->file)
594 // This does not match the wavpack.c but in our case if file is nullptr -
595 // the stream error has occured
596 return false;
597
598 // if (!outId->file->Write(data, length).IsOk()) {
599 if (outId->file->Write(data, length) != length) {
600 outId->file.reset();
601 return false;
602 }
603
604 outId->bytesWritten += length;
605
606 if (outId->firstBlockSize == 0)
607 outId->firstBlockSize = length;
608
609 return true;
610}
int id
uint32_t bytesWritten
uint32_t firstBlockSize

References WriteId::bytesWritten, WriteId::file, WriteId::firstBlockSize, and id.

Referenced by Initialize().

Here is the caller graph for this function:

Member Data Documentation

◆ 

struct { ... } WavPackExportProcessor::context

◆ fName

wxFileNameWrapper WavPackExportProcessor::fName

Definition at line 255 of file ExportWavPack.cpp.

Referenced by Initialize().

◆ format

sampleFormat WavPackExportProcessor::format

Definition at line 256 of file ExportWavPack.cpp.

◆ metadata

std::unique_ptr<Tags> WavPackExportProcessor::metadata

Definition at line 260 of file ExportWavPack.cpp.

Referenced by Initialize().

◆ mixer

std::unique_ptr<Mixer> WavPackExportProcessor::mixer

Definition at line 259 of file ExportWavPack.cpp.

◆ numChannels

unsigned WavPackExportProcessor::numChannels

Definition at line 254 of file ExportWavPack.cpp.

Referenced by Initialize().

◆ outWvcFile

WriteId WavPackExportProcessor::outWvcFile

Definition at line 257 of file ExportWavPack.cpp.

Referenced by Initialize().

◆ outWvFile

WriteId WavPackExportProcessor::outWvFile

Definition at line 257 of file ExportWavPack.cpp.

Referenced by Initialize().

◆ SAMPLES_PER_RUN

constexpr size_t WavPackExportProcessor::SAMPLES_PER_RUN = 8192u
staticconstexprprivate

Definition at line 247 of file ExportWavPack.cpp.

Referenced by Initialize(), and Process().

◆ status

TranslatableString WavPackExportProcessor::status

Definition at line 251 of file ExportWavPack.cpp.

◆ t0

double WavPackExportProcessor::t0

Definition at line 252 of file ExportWavPack.cpp.

Referenced by Initialize().

◆ t1

double WavPackExportProcessor::t1

Definition at line 253 of file ExportWavPack.cpp.

Referenced by Initialize().

◆ wpc

WavpackContext* WavPackExportProcessor::wpc {}

Definition at line 258 of file ExportWavPack.cpp.


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