23#include <wavpack/wavpack.h>
25#include <wx/checkbox.h>
30#include "../ProjectSettings.h"
41#define ID_HYBRID_MODE 9000
42#define ID_CREATE_WVC 9001
74 PopulateOrExchange(
S);
76 TransferDataToWindow();
85 XO(
"Low Quality (Fast)") ,
86 XO(
"Normal Quality") ,
87 XO(
"High Quality (Slow)") ,
88 XO(
"Very High Quality (Slowest)") ,
160 S.StartVerticalLay();
162 S.StartHorizontalLay(wxEXPAND);
164 S.SetSizerProportion(1);
165 S.StartMultiColumn(2, wxCENTER);
184 XXO(
"Create Correction(.wvc) File"),
188 mBitRate =
S.Disable(!hybridMode).TieNumberAsChoice(
197 S.EndHorizontalLay();
249 std::unique_ptr<BasicUI::ProgressDialog>& pDialog,
256 const Tags *metadata = NULL,
257 int subformat = 0)
override;
259 static int WriteBlock(
void *
id,
void *data, int32_t length);
274 std::unique_ptr<BasicUI::ProgressDialog> &pDialog,
275 unsigned numChannels,
281 const Tags *metadata,
282 int WXUNUSED(subformat))
284 WavpackConfig config = {};
286 outWvFile.
file = std::make_unique< wxFile >();
288 if (!outWvFile.
file->Create(fName.GetFullPath(),
true) || !outWvFile.
file.get()->IsOpened()) {
290 return ProgressResult::Failed;
303 if (bitDepth == 24) {
305 }
else if (bitDepth == 32) {
309 config.num_channels = numChannels;
310 config.sample_rate = rate;
311 config.bits_per_sample = bitDepth;
312 config.bytes_per_sample = bitDepth/8;
315 if (config.num_channels <= 2)
316 config.channel_mask = 0x5 - config.num_channels;
317 else if (config.num_channels <= 18)
318 config.channel_mask = (1U << config.num_channels) - 1;
320 config.channel_mask = 0x3FFFF;
323 config.flags |= CONFIG_FAST_FLAG;
324 }
else if (quality == 2) {
325 config.flags |= CONFIG_HIGH_FLAG;
326 }
else if (quality == 3) {
327 config.flags |= CONFIG_HIGH_FLAG | CONFIG_VERY_HIGH_FLAG;
331 config.flags |= CONFIG_HYBRID_FLAG;
332 config.bitrate = bitRate / 10.0;
334 if (createCorrectionFile) {
335 config.flags |= CONFIG_CREATE_WVC;
337 outWvcFile.
file = std::make_unique< wxFile >();
338 if (!outWvcFile.
file->Create(fName.GetFullPath().Append(
"c"),
true)) {
340 return ProgressResult::Failed;
348 if (!hybridMode || !createCorrectionFile)
349 wxRemoveFile(fName.GetFullPath().Append(
"c"));
351 WavpackContext *wpc = WavpackOpenFileOutput(
WriteBlock, &outWvFile, createCorrectionFile ? &outWvcFile :
nullptr);
352 auto closeWavPackContext =
finally([wpc]() { WavpackCloseFile(wpc); });
354 if (!WavpackSetConfiguration64(wpc, &config, -1,
nullptr) || !WavpackPackInit(wpc)) {
356 return ProgressResult::Failed;
373 ?
XO(
"Exporting selected audio as WavPack")
374 :
XO(
"Exporting the audio as WavPack") );
375 auto &progress = *pDialog;
378 auto samplesThisRun = mixer->Process();
380 if (samplesThisRun == 0)
384 const int16_t *mixed =
reinterpret_cast<const int16_t*
>(mixer->GetBuffer());
385 for (
decltype(samplesThisRun) j = 0; j < samplesThisRun; j++) {
386 for (
size_t i = 0; i < numChannels; i++) {
387 wavpackBuffer[j*numChannels + i] = (
static_cast<int32_t
>(*mixed++) * 65536) >> 16;
391 const int *mixed =
reinterpret_cast<const int*
>(mixer->GetBuffer());
392 for (
decltype(samplesThisRun) j = 0; j < samplesThisRun; j++) {
393 for (
size_t i = 0; i < numChannels; i++) {
394 wavpackBuffer[j*numChannels + i] = *mixed++;
399 if (!WavpackPackSamples(wpc, wavpackBuffer.get(), samplesThisRun)) {
401 return ProgressResult::Failed;
406 progress.Poll(mixer->MixGetCurrentTime() - t0, t1 - t0);
410 if (!WavpackFlushSamples(wpc)) {
412 return ProgressResult::Failed;
414 if (metadata == NULL)
418 for (
const auto &pair : metadata->
GetRange()) {
420 const auto &v = pair.second;
422 WavpackAppendTagItem(wpc,
423 n.mb_str(wxConvUTF8),
424 v.mb_str(wxConvUTF8),
425 static_cast<int>( strlen(v.mb_str(wxConvUTF8)) ));
428 if (!WavpackWriteTag(wpc)) {
430 return ProgressResult::Failed;
434 if ( !outWvFile.
file.get()->Close()
435 || ( outWvcFile.
file && outWvcFile.
file.get() && !outWvcFile.
file.get()->Close())) {
436 return ProgressResult::Failed;
441 if (!outWvFile.
file->Open(fName.GetFullPath(), wxFile::read_write)) {
443 return ProgressResult::Failed;
447 size_t bytesRead = outWvFile.
file->Read(firstBlockBuffer.get(), outWvFile.
firstBlockSize);
450 WavpackUpdateNumSamples(wpc, firstBlockBuffer.get());
451 outWvFile.
file->Seek(0);
452 size_t bytesWritten = outWvFile.
file->Write(firstBlockBuffer.get(), outWvFile.
firstBlockSize);
454 if ( !outWvFile.
file.get()->Close() ) {
455 return ProgressResult::Failed;
465 if (
id ==
nullptr || data ==
nullptr || length == 0)
476 if (outId->
file->Write(data, length) != length) {
495 []{
return std::make_unique< ExportWavPack >(); }
498#ifdef HAS_CLOUD_UPLOAD
527 [](
const AudacityProject&) {
return std::make_unique<WavPackCloudHelper>(); });
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
void ShowExportErrorDialog(wxString ErrorCode, TranslatableString message, const TranslatableString &caption, bool allowReporting)
const std::vector< int > ExportQualityValues
static Exporter::RegisteredExportPlugin sRegisteredPlugin
const TranslatableStrings ExportQualityNames
XXO("&Cut/Copy/Paste Toolbar")
wxString FileExtension
File extension, not including any leading dot.
an object holding per-project preferred sample rate
declares abstract base class Track, TrackList, and iterators over TrackList
std::vector< TranslatableString > TranslatableStrings
This simplifies arrays of arrays, each array separately allocated with NEW[] But it might be better t...
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
This specialization of Setting for bool adds a Toggle method to negate the saved value.
bool Toggle()
Write the negation of the previous value, and then return the current value.
void AddExtension(const FileExtension &extension, int index)
int AddFormat()
Add a NEW entry to the list of formats this plug-in can export.
static void InitProgress(std::unique_ptr< BasicUI::ProgressDialog > &pDialog, const TranslatableString &title, const TranslatableString &message)
void SetFormat(const wxString &format, int index)
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, MixerSpec *mixerSpec)
void SetDescription(const TranslatableString &description, int index)
void SetCanMetaData(bool canmetadata, int index)
void SetMaxChannels(unsigned maxchannels, unsigned index)
void OptionsCreate(ShuttleGui &S, int format) override
ProgressResult Export(AudacityProject *project, std::unique_ptr< BasicUI::ProgressDialog > &pDialog, unsigned channels, const wxFileNameWrapper &fName, bool selectedOnly, double t0, double t1, MixerSpec *mixerSpec=NULL, const Tags *metadata=NULL, int subformat=0) override
called to export audio into a file.
static int WriteBlock(void *id, void *data, int32_t length)
ExportWavPackOptions(wxWindow *parent, int format)
wxCheckBox * mCreateCorrectionFile
void OnHybridMode(wxCommandEvent &evt)
void OnCreateCorrection(wxCommandEvent &evt)
virtual ~ExportWavPackOptions()
bool TransferDataToWindow() override
void PopulateOrExchange(ShuttleGui &S)
bool TransferDataFromWindow() override
virtual bool Flush(bool bCurrentOnly=false) wxOVERRIDE
Specialization of Setting for int.
A matrix of booleans, one row per input channel, column per output.
static ProjectRate & Get(AudacityProject &project)
bool Write(const T &value)
Write value to config and return true if successful.
bool Read(T *pVar) const
overload of Read returning a boolean that is true if the value was previously defined */
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
static TrackList & Get(AudacityProject &project)
Holds a msgid for the translation catalog; may also bind format arguments.
Helper interface, that allows to setup the desired export format on the ExportPlugin.
virtual wxString GetExporterID() const =0
Identifier of the ExportPlugin to be used.
virtual FileExtension GetFileExtension() const =0
File extension that is expected with this plugin.
virtual void OnBeforeExport()=0
Setup the preferred format for the export.
const TranslatableStrings ExportBitDepthNames
const std::vector< int > ExportBitDepthValues
IntSetting BitrateSetting
const std::vector< int > BitRateValues
BoolSetting HybridModeSetting
IntSetting QualitySetting
TranslatableString n_bps(int n)
IntSetting BitDepthSetting
BoolSetting CreateCorrectionFileSetting
const TranslatableStrings BitRateNames
bool RegisterCloudExporter(MimeType mimeType, CloudExporterPluginFactory factory)
Registers a factory for a specific mime type.
std::unique_ptr< wxFile > file