⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 importraw.cpp

📁 Audacity是一款用於錄音和編輯聲音的、免費的開放源碼軟體。它可以執行於Mac OS X、Microsoft Windows、GNU/Linux和其它作業系統
💻 CPP
字号:
/**********************************************************************  Audacity: A Digital Audio Editor  ImportRaw.cpp  Dominic Mazzoni**********************************************************************/#include "ImportRaw.h"#include "Import.h"#include "RawAudioGuess.h"#include "../DirManager.h"#include "../FileFormats.h"#include "../Internat.h"#include "../Prefs.h"#include "../WaveTrack.h"#include <math.h>#include <wx/defs.h>#include <wx/button.h>#include <wx/choice.h>#include <wx/intl.h>#include <wx/msgdlg.h>#include <wx/panel.h>#include <wx/progdlg.h>#include <wx/sizer.h>#include <wx/stattext.h>#include <wx/textctrl.h>#include <wx/timer.h>#include "sndfile.h"class ImportRawDialog:public wxDialog {  public:   ImportRawDialog(wxWindow * parent,                   int encoding, int channels,                   int offset, double rate);   ~ImportRawDialog();   void OnOK(wxCommandEvent & event);   void OnCancel(wxCommandEvent & event);   void OnPlay(wxCommandEvent & event);   void OnChoice(wxCommandEvent & event);   // in and out   int mEncoding;   int mChannels;   int mOffset;   double mRate;   double mPercent; private:   wxButton   *mOK;   wxChoice   *mEncodingChoice;   wxChoice   *mEndianChoice;   wxChoice   *mChannelChoice;   wxTextCtrl *mOffsetText;   wxTextCtrl *mPercentText;   wxTextCtrl *mRateText;   int         mNumEncodings;   int        *mEncodingSubtype;   wxString   *mEncodingString;   DECLARE_EVENT_TABLE()};int ImportRaw(wxWindow *parent, wxString fileName,              TrackFactory *trackFactory, Track ***outTracks,              progress_callback_t progressCallback, void *userData){   int encoding = 0; // Guess Format   int numChannels = 0;   sampleFormat format;   sf_count_t offset = 0;   int int_offset = 0;   longSampleCount totalFrames;   double rate = 44100.0;   double percent = 100.0;   SNDFILE *sndFile;   SF_INFO sndInfo;   int result;   encoding = RawAudioGuess(fileName,                            &int_offset, &numChannels);   offset = (sf_count_t)int_offset;   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;   }   ImportRawDialog dlog(parent, encoding, numChannels, (int)offset, rate);   dlog.ShowModal();   if (!dlog.GetReturnCode())      return false;   encoding = dlog.mEncoding;   numChannels = dlog.mChannels;   rate = dlog.mRate;   offset = (sf_count_t)dlog.mOffset;   percent = dlog.mPercent;   memset(&sndInfo, 0, sizeof(SF_INFO));   sndInfo.samplerate = (int)rate;   sndInfo.channels = (int)numChannels;   sndInfo.format = encoding | SF_FORMAT_RAW;   #ifdef _UNICODE      /* sf_open doesn't handle fn_Str() in Unicode build. May or may not actually work. */      sndFile = sf_open(FILENAME(fileName).mb_str(), SFM_READ, &sndInfo);   #else // ANSI      sndFile = sf_open(FILENAME(fileName).fn_str(), SFM_READ, &sndInfo);   #endif // Unicode/ANSI   if (!sndFile) {      // TODO: Handle error      char str[1000];      sf_error_str((SNDFILE *)NULL, str, 1000);      printf("%s\n", str);      return 0;   }   result = sf_command(sndFile, SFC_SET_RAW_START_OFFSET, &offset, sizeof(offset));   if (result != 0) {      char str[1000];      sf_error_str(sndFile, str, 1000);      printf("%s\n", str);   }   sf_seek(sndFile, 0, SEEK_SET);      totalFrames = (longSampleCount)(sndInfo.frames * percent / 100.0);   //   // Sample format:   //   // In general, go with the user's preferences.  However, if   // the file is higher-quality, go with a format which preserves   // the quality of the original file.   //      format = (sampleFormat)      gPrefs->Read(wxT("/SamplingRate/DefaultProjectSampleFormat"), floatSample);   if (format != floatSample &&       sf_subtype_more_than_16_bits(encoding))      format = floatSample;   WaveTrack **channels = new WaveTrack *[numChannels];   int c;   for (c = 0; c < numChannels; c++) {      channels[c] = trackFactory->NewWaveTrack(format);      channels[c]->SetRate(rate);      if (numChannels > 1)         switch (c) {         case 0:            channels[c]->SetChannel(Track::LeftChannel);            break;         case 1:            channels[c]->SetChannel(Track::RightChannel);            break;         default:            channels[c]->SetChannel(Track::MonoChannel);         }   }   if (numChannels == 2)      channels[0]->SetLinked(true);   sampleCount maxBlockSize = channels[0]->GetMaxBlockSize();   bool cancelled = false;   samplePtr srcbuffer = NewSamples(maxBlockSize * numChannels, format);   samplePtr buffer = NewSamples(maxBlockSize, format);      longSampleCount framescompleted = 0;      long block;   do {      block = maxBlockSize;      if (block + framescompleted > totalFrames)         block = totalFrames - framescompleted;            if (format == int16Sample)         block = sf_readf_short(sndFile, (short *)srcbuffer, block);      else         block = sf_readf_float(sndFile, (float *)srcbuffer, block);      if (block) {         for(c=0; c<numChannels; c++) {            if (format==int16Sample) {               for(int j=0; j<block; j++)                  ((short *)buffer)[j] =                     ((short *)srcbuffer)[numChannels*j+c];            }            else {               for(int j=0; j<block; j++)                  ((float *)buffer)[j] =                     ((float *)srcbuffer)[numChannels*j+c];            }                        channels[c]->Append(buffer, format, block);         }         framescompleted += block;      }      if( progressCallback )         cancelled = progressCallback(userData, framescompleted*1.0 / totalFrames);      if (cancelled)         break;         } while (block > 0 && framescompleted < totalFrames);   sf_close(sndFile);   if (cancelled) {      for (c = 0; c < numChannels; c++)         delete channels[c];      delete[] channels;      return 0;   }   else {      for (c = 0; c < numChannels; c++)         channels[c]->Flush();      *outTracks = (Track **)channels;      return numChannels;   }}//// ImportRawDialog//enum {   ChoiceID = 9000,   PlayID};BEGIN_EVENT_TABLE(ImportRawDialog, wxDialog)   EVT_BUTTON(wxID_OK, ImportRawDialog::OnOK)   EVT_BUTTON(wxID_CANCEL, ImportRawDialog::OnCancel)   EVT_BUTTON(PlayID, ImportRawDialog::OnPlay)   EVT_CHOICE(ChoiceID, ImportRawDialog::OnChoice)END_EVENT_TABLE()ImportRawDialog::ImportRawDialog(wxWindow * parent,                                 int encoding, int channels,                                 int offset, double rate)   :wxDialog(parent, -1, _("Import Raw Data"),             wxDefaultPosition, wxDefaultSize,             wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER),    mEncoding(encoding), mChannels(channels),    mOffset(offset), mRate(rate){   wxBoxSizer *mainSizer, *hSizer, *vSizer;   wxFlexGridSizer *gridSizer;   wxButton *button;   int selection, i;   mainSizer = new wxBoxSizer(wxVERTICAL);      hSizer = new wxBoxSizer(wxHORIZONTAL);   //   // Left-Side Controls (for manually selecting format)   //   vSizer = new wxBoxSizer(wxVERTICAL);   // Encoding Choice   mNumEncodings = 0;   mEncodingSubtype = new int[sf_num_encodings()];   mEncodingString = new wxString[sf_num_encodings()];   selection = 0;   for(i=0; i<sf_num_encodings(); i++) {      SF_INFO info;      memset(&info, 0, sizeof(SF_INFO));      int subtype = (int)sf_encoding_index_to_subtype(i);      info.format = SF_FORMAT_RAW + SF_ENDIAN_LITTLE + subtype;      info.channels = 1;      info.samplerate = 44100;      if (sf_format_check(&info)) {         mEncodingSubtype[mNumEncodings] = subtype;         mEncodingString[mNumEncodings] = sf_encoding_index_name(i);;         if ((mEncoding & SF_FORMAT_SUBMASK) == subtype)            selection = mNumEncodings;         mNumEncodings++;      }   }   mEncodingChoice =       new wxChoice(this, ChoiceID,                   wxDefaultPosition, wxDefaultSize,                   mNumEncodings, mEncodingString);   mEncodingChoice->SetSelection(selection);   vSizer->Add(mEncodingChoice, 0, wxALIGN_LEFT | wxALL, 5);   // Endian choice   wxString endianStrings[4] =      {/* i18n-hint: Refers to byte-order.  Don't translate "endianness" if you don't          know the correct technical word. */         _("No endianness"),         /* i18n-hint: Refers to byte-order.  Don't translate this if you don't          know the correct technical word. */       _("Little-endian"),         /* i18n-hint: Refers to byte-order.  Don't translate this if you don't            know the correct technical word. */       _("Big-endian"),         /* i18n-hint: Refers to byte-order.  Don't translate "endianness" if you don't            know the correct technical word. */       _("Default endianness")};   mEndianChoice =      new wxChoice(this, ChoiceID,                   wxDefaultPosition, wxDefaultSize,                   4, endianStrings);   switch(mEncoding & (SF_FORMAT_ENDMASK)) {   case SF_ENDIAN_FILE:      mEndianChoice->SetSelection(0);      break;   case SF_ENDIAN_LITTLE:      mEndianChoice->SetSelection(1);      break;   case SF_ENDIAN_BIG:      mEndianChoice->SetSelection(2);      break;   case SF_ENDIAN_CPU:      mEndianChoice->SetSelection(3);      break;   }   vSizer->Add(mEndianChoice, 0, wxALIGN_LEFT | wxALL, 5);   // Channels choice   wxString channelStrings[16];   channelStrings[0].Printf(_("1 Channel (Mono)"));   channelStrings[1].Printf(_("2 Channels (Stereo)"));   for(i=2; i<16; i++) {      channelStrings[i].Printf(_("%d Channels"), i+1);   }   mChannelChoice =      new wxChoice(this, ChoiceID,                   wxDefaultPosition, wxDefaultSize,                   16, channelStrings);   mChannelChoice->SetSelection(mChannels-1);   vSizer->Add(mChannelChoice, 0, wxALIGN_LEFT | wxALL, 5);   // Offset text   gridSizer = new wxFlexGridSizer(3, 0, 0);      gridSizer->Add(new wxStaticText(this, 0, _("Start offset:")),                  0, wxALIGN_LEFT | wxALL, 5);   mOffsetText = new wxTextCtrl(this, 0, wxString::Format(wxT("%d"), mOffset));   gridSizer->Add(mOffsetText, 0, wxALIGN_LEFT | wxALL, 5);   gridSizer->Add(new wxStaticText(this, 0, _("bytes")),                  0, wxALIGN_LEFT | wxALL, 5);   // Percent text   gridSizer->Add(new wxStaticText(this, 0, _("Amount to import:")),                  0, wxALIGN_LEFT | wxALL, 5);   mPercentText = new wxTextCtrl(this, 0, wxT("100"));   gridSizer->Add(mPercentText, 0, wxALIGN_LEFT | wxALL, 5);   gridSizer->Add(new wxStaticText(this, 0, wxT("%")),                  0, wxALIGN_LEFT | wxALL, 5);   // Rate text   gridSizer->Add(new wxStaticText(this, 0, _("Sample rate:")),                  0, wxALIGN_LEFT | wxALL, 5);   mRateText = new wxTextCtrl(this, 0, wxString::Format(wxT("%d"), (int)mRate));   gridSizer->Add(mRateText, 0, wxALIGN_LEFT | wxALL, 5);   /* i18n-hint: This is the abbreviation for "Hertz", or      cycles per second. */   gridSizer->Add(new wxStaticText(this, 0, _("Hz")),                  0, wxALIGN_LEFT | wxALL, 5);   vSizer->Add(gridSizer, 0, wxALIGN_LEFT | wxALL, 0);   hSizer->Add(vSizer, 0, wxALIGN_TOP | wxALL, 5);   //   // Preview Pane goes here   //   wxPanel *p = new wxPanel(this, 0, wxDefaultPosition, wxSize(100, 100));   hSizer->Add(p, 0, wxALIGN_TOP | wxALL, 5);   mainSizer->Add(hSizer, 0, wxALIGN_CENTER | wxALL, 5);   //   // Button row   //   hSizer = new wxBoxSizer(wxHORIZONTAL);   /*   button = new wxButton(this, PlayID, _("Play"));   hSizer->Add(button, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);   */   button = new wxButton(this, wxID_CANCEL, _("Cancel"));   hSizer->Add(button, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);   mOK = new wxButton(this, wxID_OK, _("Import"));   hSizer->Add(mOK, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);   mainSizer->Add(hSizer, 0, wxALIGN_CENTER | wxALL, 5);   SetAutoLayout(true);   SetSizer(mainSizer);   mainSizer->Fit(this);   mainSizer->SetSizeHints(this);   Centre(wxBOTH);}ImportRawDialog::~ImportRawDialog(){   delete[] mEncodingSubtype;   delete[] mEncodingString;}void ImportRawDialog::OnOK(wxCommandEvent & WXUNUSED(event)){   long l;      mEncoding = mEncodingSubtype[mEncodingChoice->GetSelection()];   mEncoding += (mEndianChoice->GetSelection() * 0x10000000);   mChannels = mChannelChoice->GetSelection() + 1;   mOffsetText->GetValue().ToLong(&l);   mOffset = l;   mPercentText->GetValue().ToDouble(&mPercent);   mRateText->GetValue().ToDouble(&mRate);   if (mChannels < 1 || mChannels > 16)      mChannels = 1;   if (mOffset < 0)      mOffset = 0;   if (mPercent < 0.0)      mPercent = 0.0;   if (mPercent > 100.0)      mPercent = 100.0;   if (mRate < 100.0)      mRate = 100.0;   if (mRate > 100000.0)      mRate = 100000.0;   EndModal(true);}void ImportRawDialog::OnCancel(wxCommandEvent & WXUNUSED(event)){   EndModal(false);}void ImportRawDialog::OnPlay(wxCommandEvent & WXUNUSED(event)){}void ImportRawDialog::OnChoice(wxCommandEvent & WXUNUSED(event)){   SF_INFO info;   memset(&info, 0, sizeof(SF_INFO));   mEncoding = mEncodingSubtype[mEncodingChoice->GetSelection()];   mEncoding += (mEndianChoice->GetSelection() * 0x10000000);   info.format = mEncoding | SF_FORMAT_RAW;   info.channels = mChannelChoice->GetSelection() + 1;   info.samplerate = 44100;   if (sf_format_check(&info)) {      mOK->Enable(true);      return;   }   // Try it with 1-channel   info.channels = 1;   if (sf_format_check(&info)) {      mChannelChoice->SetSelection(0);      mOK->Enable(true);      return;   }   // Otherwise, this is an unsupported format   mOK->Enable(false);}// Indentation settings for Vim and Emacs and unique identifier for Arch, a// version control system. Please do not modify past this point.//// Local Variables:// c-basic-offset: 3// indent-tabs-mode: nil// End://// vim: et sts=3 sw=3// arch-tag: 3e6ead61-1ef2-4518-a622-523f1efebb9a

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -