From f83f65cadc7608a2eae850c68874dd739c3d4248 Mon Sep 17 00:00:00 2001 From: dofuuz Date: Wed, 23 Jun 2021 23:53:17 +0900 Subject: [PATCH] Disable auto format detection of Import Raw Data - Use recent import setting instead of auto detection - Add Detect button --- src/import/ImportRaw.cpp | 151 ++++++++++++++++++++++++--------------- 1 file changed, 94 insertions(+), 57 deletions(-) diff --git a/src/import/ImportRaw.cpp b/src/import/ImportRaw.cpp index 688fe7fa6..4568019af 100644 --- a/src/import/ImportRaw.cpp +++ b/src/import/ImportRaw.cpp @@ -61,22 +61,22 @@ and sample size to help you importing data of an unknown format. class ImportRawDialog final : public wxDialogWrapper { public: - ImportRawDialog(wxWindow * parent, - int encoding, unsigned channels, - int offset, double rate); + ImportRawDialog(wxWindow * parent, const wxString & fileName); ~ImportRawDialog(); void OnOK(wxCommandEvent & event); void OnCancel(wxCommandEvent & event); void OnPlay(wxCommandEvent & event); + void OnDetect(wxCommandEvent & event); void OnChoice(wxCommandEvent & event); // in and out - int mEncoding; - unsigned mChannels; - int mOffset; - double mRate; - double mPercent; + // Make static to preserve value for next raw import + static int mEncoding; + static unsigned mChannels; + static int mOffset; + static double mRate; + static double mPercent; private: @@ -91,9 +91,19 @@ class ImportRawDialog final : public wxDialogWrapper { int mNumEncodings; ArrayOf mEncodingSubtype; + wxString mFileName; + DECLARE_EVENT_TABLE() }; +// Initial value for Import Raw dialog +int ImportRawDialog::mEncoding = SF_FORMAT_RAW | SF_ENDIAN_CPU | SF_FORMAT_PCM_16; +unsigned ImportRawDialog::mChannels = 1; +int ImportRawDialog::mOffset = 0; +double ImportRawDialog::mRate = 0; // -> project rate +double ImportRawDialog::mPercent = 100.; + + // This function leaves outTracks empty as an indication of error, // but may also throw FileException to make use of the application's // user visible error reporting. @@ -101,52 +111,27 @@ void ImportRaw(const AudacityProject &project, wxWindow *parent, const wxString WaveTrackFactory *trackFactory, TrackHolders &outTracks) { outTracks.clear(); - int encoding = 0; // Guess Format - sf_count_t offset = 0; - double rate = 44100.0; - double percent = 100.0; + TrackHolders results; auto updateResult = ProgressResult::Success; { - SF_INFO sndInfo; - unsigned numChannels = 0; + // On first run, set default sample rate from project rate + if (ImportRawDialog::mRate < 100.) + ImportRawDialog::mRate = ProjectSettings::Get(project).GetRate(); - try { - // Yes, FormatClassifier currently handles filenames in UTF8 format only, that's - // a TODO ... - FormatClassifier theClassifier(fileName.utf8_str()); - encoding = theClassifier.GetResultFormatLibSndfile(); - numChannels = theClassifier.GetResultChannels(); - offset = 0; - } catch (...) { - // Something went wrong in FormatClassifier, use defaults instead. - encoding = 0; - } - - if (encoding <= 0) { - // Unable to guess. Use mono, 16-bit samples with CPU endianness - // as the default. - encoding = SF_FORMAT_RAW | SF_ENDIAN_CPU | SF_FORMAT_PCM_16; - numChannels = 1; - offset = 0; - } - - rate = ProjectSettings::Get( project ).GetRate(); - - numChannels = std::max(1u, numChannels); - ImportRawDialog dlog(parent, encoding, numChannels, (int)offset, rate); + ImportRawDialog dlog(parent, fileName); dlog.ShowModal(); if (!dlog.GetReturnCode()) return; - encoding = dlog.mEncoding; - numChannels = dlog.mChannels; - rate = dlog.mRate; - offset = (sf_count_t)dlog.mOffset; - percent = dlog.mPercent; + int encoding = dlog.mEncoding; + unsigned numChannels = dlog.mChannels; + double rate = dlog.mRate; + sf_count_t offset = (sf_count_t)dlog.mOffset; + double percent = dlog.mPercent; - memset(&sndInfo, 0, sizeof(SF_INFO)); + SF_INFO sndInfo = { 0 }; sndInfo.samplerate = (int)rate; sndInfo.channels = (int)numChannels; sndInfo.format = encoding | SF_FORMAT_RAW; @@ -289,28 +274,25 @@ void ImportRaw(const AudacityProject &project, wxWindow *parent, const wxString enum { ChoiceID = 9000, - PlayID + PlayID, + DetectID, }; BEGIN_EVENT_TABLE(ImportRawDialog, wxDialogWrapper) EVT_BUTTON(wxID_OK, ImportRawDialog::OnOK) EVT_BUTTON(wxID_CANCEL, ImportRawDialog::OnCancel) EVT_BUTTON(PlayID, ImportRawDialog::OnPlay) + EVT_BUTTON(DetectID, ImportRawDialog::OnDetect) EVT_CHOICE(ChoiceID, ImportRawDialog::OnChoice) END_EVENT_TABLE() -ImportRawDialog::ImportRawDialog(wxWindow * parent, - int encoding, unsigned channels, - int offset, double rate) +ImportRawDialog::ImportRawDialog(wxWindow * parent, const wxString & fileName) : wxDialogWrapper(parent, wxID_ANY, XO("Import Raw Data"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER), - mEncoding(encoding), - mChannels(channels), - mOffset(offset), - mRate(rate) + mFileName(fileName) { - wxASSERT(channels >= 1); + wxASSERT(mChannels >= 1); SetName(); @@ -437,11 +419,20 @@ ImportRawDialog::ImportRawDialog(wxWindow * parent, } S.EndMultiColumn(); - // - // Preview Pane goes here - // + S.SetBorder(5); + S.StartTwoColumn(); + { + /* i18n-hint: Guess format of raw file */ + S.Id(DetectID).AddButton(XXO("Detect")); + + // + // Preview Pane goes here + // + + S.AddStandardButtons(); + } + S.EndTwoColumn(); - S.AddStandardButtons(); // Find the OK button, and change its text to 'Import'. // We MUST set mOK because it is used later. mOK = (wxButton *)wxWindow::FindWindowById(wxID_OK, this); @@ -497,6 +488,52 @@ void ImportRawDialog::OnPlay(wxCommandEvent & WXUNUSED(event)) { } +void ImportRawDialog::OnDetect(wxCommandEvent & event) +{ + try { + // Yes, FormatClassifier currently handles filenames in UTF8 format only, that's a TODO ... + FormatClassifier theClassifier(mFileName.utf8_str()); + mEncoding = theClassifier.GetResultFormatLibSndfile(); + mChannels = theClassifier.GetResultChannels(); + } catch (...) { + // Something went wrong in FormatClassifier, abort. + return; + } + + int selection = 0; + for (int i = 0; i < mNumEncodings; i++) { + int subtype = mEncodingSubtype[i]; + if ((mEncoding & SF_FORMAT_SUBMASK) == subtype) { + selection = i; + break; + } + } + + int endian = 0; + switch (mEncoding & SF_FORMAT_ENDMASK) + { + default: + case SF_ENDIAN_FILE: + endian = 0; + break; + case SF_ENDIAN_LITTLE: + endian = 1; + break; + case SF_ENDIAN_BIG: + endian = 2; + break; + case SF_ENDIAN_CPU: + endian = 3; + break; + } + + mEncodingChoice->SetSelection(selection); + mEndianChoice->SetSelection(endian); + mChannelChoice->SetSelection(mChannels - 1); + + OnChoice(event); +} + void ImportRawDialog::OnChoice(wxCommandEvent & WXUNUSED(event)) { SF_INFO info;