QScriptValue ProgressDialog::constructor(QScriptContext *context, QScriptEngine *engine) { ProgressDialog *progressDialog = new ProgressDialog; progressDialog->setupConstructorParameters(context, engine, context->argument(0)); QScriptValueIterator it(context->argument(0)); while(it.hasNext()) { it.next(); if(it.name() == "value") progressDialog->mProgressDialog->setValue(it.value().toInt32()); else if(it.name() == "labelText") progressDialog->mProgressDialog->setLabelText(it.value().toString()); else if(it.name() == "minimum") progressDialog->mProgressDialog->setMinimum(it.value().toInt32()); else if(it.name() == "maximum") progressDialog->mProgressDialog->setMaximum(it.value().toInt32()); else if(it.name() == "range") { progressDialog->mProgressDialog->setMinimum(it.value().property("minimum").toInt32()); progressDialog->mProgressDialog->setMaximum(it.value().property("maximum").toInt32()); } else if(it.name() == "onCanceled") progressDialog->mOnCanceled = it.value(); } return CodeClass::constructor(progressDialog, context, engine); }
void VersionSelectDialog::loadList() { ProgressDialog *taskDlg = new ProgressDialog(this); Task *loadTask = m_vlist->getLoadTask(); loadTask->setParent(taskDlg); taskDlg->exec(loadTask); }
void CMainFrame::OnFileDefrag() { CzpEditorDoc* document = (CzpEditorDoc*)GetActiveDocument(); ZpExplorer& explorer = document->GetZpExplorer(); if (!explorer.isOpen()) { return; } //zp::u64 fragSize = explorer.getPack()->countFragmentSize(); //if (fragSize == 0) //{ // ::MessageBox(NULL, _T("No fragment found in package."), _T("Note"), MB_OK | MB_ICONINFORMATION); // return; //} //StringStream tip; //tip << _T("You can save ") << fragSize << _T(" bytes, continue?"); if (::MessageBox(NULL, _T("It will take minutes for large package, continue?"), _T("Note"), MB_YESNO | MB_ICONQUESTION) != IDYES) { return; } ProgressDialog progressDlg; progressDlg.m_explorer = &(document->GetZpExplorer()); progressDlg.m_running = true; progressDlg.m_params = NULL; progressDlg.m_operation = ProgressDialog::OP_DEFRAG; progressDlg.m_totalFileSize = explorer.countNodeFileSize(explorer.rootNode()); progressDlg.DoModal(); }
void MainWindow::on_pushButton_clicked() { ProgressDialog* progressDialog = new ProgressDialog(nullptr, new DriveTransfer(nullptr, ".", "./Test")); progressDialog->show(); //Console* console = new Console(this); //console->show(); }
BOOL CALLBACK ProgressDialog::dlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_INITDIALOG: { ::SetWindowLongPtr(hWnd, GWL_USERDATA, lParam); ProgressDialog* dlg = reinterpret_cast<ProgressDialog*>(lParam); return dlg->runDlgProc(hWnd, message, wParam, lParam); } case WM_COMMAND: { if (IDCANCEL == wParam) { int mbResult = MessageBox(hWnd, _T("Are you sure you wish to abort the current installation/removal?"), _T("Cancel installation / removal?"), MB_YESNO | MB_ICONQUESTION); if (IDYES == mbResult) { ProgressDialog* dlg = reinterpret_cast<ProgressDialog*>(::GetWindowLongPtr(hWnd, GWL_USERDATA)); dlg->_cancelToken.triggerCancel(); } } return FALSE; } default: { ProgressDialog* dlg = reinterpret_cast<ProgressDialog*>(::GetWindowLongPtr(hWnd, GWL_USERDATA)); return dlg->runDlgProc(hWnd, message, wParam, lParam); } } }
void CzpEditorView::startOperation(ProgressDialog::Operation op, zp::u64 totalFileSize, const std::vector<std::pair<zp::String, zp::String>>* params) { ProgressDialog progressDlg; progressDlg.m_explorer = &(GetDocument()->GetZpExplorer()); progressDlg.m_running = true; progressDlg.m_params = params; progressDlg.m_operation = op; progressDlg.m_totalFileSize = totalFileSize; progressDlg.DoModal(); }
void LocalView::slot_local_new_download_requested(const TaskPackage &local_pkg, const TaskPackage &remote_pkg) { ProgressDialog *pdlg = new ProgressDialog(0); // src is remote file , dest if localfile pdlg->set_transfer_info(remote_pkg, local_pkg); QObject::connect(pdlg, SIGNAL(transfer_finished(int, QString)), this, SLOT(slot_transfer_finished(int, QString))); this->main_mdi_area->addSubWindow(pdlg); pdlg->show(); this->own_progress_dialog = pdlg; }
// ---------------------------------------------------------------------------- // dialogProc // ---------------------------------------------------------------------------- // the message procedure for the cgp dialog procedure, a dummy procedure INT_PTR CALLBACK ProgressDialog::progDialogProc(HWND hWndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { //this->hWnd = hWnd; if (msg == WM_INITDIALOG) { ProgressDialog* progD = reinterpret_cast<ProgressDialog*>(lParam); SetWindowLong(hWndDlg, GWL_USERDATA, reinterpret_cast<long>(progD)); } // get the WWindow structure and pass the data to that ProgressDialog* progD = (ProgressDialog *) GetWindowLong(hWndDlg, GWL_USERDATA); if (progD) return progD->realProgDialogProc(hWndDlg, msg, wParam, lParam); } // --- dialogProc -----------------------------------------------------------
BOOL CALLBACK ProgressDialog::dlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_INITDIALOG: { ::SetWindowLongPtr(hWnd, GWLP_USERDATA, lParam); ProgressDialog* dlg = reinterpret_cast<ProgressDialog*>(lParam); return dlg->runDlgProc(hWnd, message, wParam, lParam); } default: { ProgressDialog* dlg = reinterpret_cast<ProgressDialog*>(static_cast<LONG_PTR>(::GetWindowLongPtr(hWnd, GWLP_USERDATA))); return dlg->runDlgProc(hWnd, message, wParam, lParam); } } }
void LocalView::slot_transfer_finished(int status, QString errorString) { qDebug() <<__FUNCTION__<<": "<<__LINE__<<":"<< __FILE__<<status; // SFTPView *remote_view = this; ProgressDialog *pdlg = (ProgressDialog*)sender(); this->main_mdi_area->removeSubWindow(pdlg->parentWidget()); delete pdlg; this->own_progress_dialog = NULL; if (status == 0 // || status == 3 ) { //TODO 通知UI更新目录结构,在某些情况下会导致左侧树目录变空。 //int transfer_type = pdlg->get_transfer_type(); //if ( transfer_type == TransferThread::TRANSFER_GET ) { // this->local_view->update_layout(); // local 不需要吧,这个能自动更新的??? this->update_layout(); } //else if ( transfer_type == TransferThread::TRANSFER_PUT ) { // remote_view->update_layout(); } //else { // xxxxx: 没有预期到的错误 //assert ( 1== 2 ); } } else if (status == 52 // Transportor::ERROR_CANCEL ) { // user cancel, show nothing } else if (status != 0 // && status != 3 ) { QString errmsg = QString(errorString + " Code: %1").arg(status); if (errmsg.length() < 50) errmsg = errmsg.leftJustified(50); QMessageBox::critical(this, QString(tr("Error: ")), errmsg); } else { Q_ASSERT(1 == 2); } // remote_view->slot_leave_remote_dir_retrive_loop(); }
void HttpWindow::startRequest(const QUrl &requestedUrl) { url = requestedUrl; httpRequestAborted = false; reply = qnam.get(QNetworkRequest(url)); connect(reply, &QNetworkReply::finished, this, &HttpWindow::httpFinished); connect(reply, &QIODevice::readyRead, this, &HttpWindow::httpReadyRead); ProgressDialog *progressDialog = new ProgressDialog(url, this); progressDialog->setAttribute(Qt::WA_DeleteOnClose); connect(progressDialog, &QProgressDialog::canceled, this, &HttpWindow::cancelDownload); connect(reply, &QNetworkReply::downloadProgress, progressDialog, &ProgressDialog::networkReplyProgress); connect(reply, &QNetworkReply::finished, progressDialog, &ProgressDialog::hide); progressDialog->show(); statusLabel->setText(tr("Downloading %1...").arg(url.toString())); songBeingDownloaded = true;// }
void ImageTags::applyUserAction(QList<QTreeWidgetItem *> tagsList) { int processEventsCounter = 0; ProgressDialog *dialog = new ProgressDialog(this); dialog->show(); QStringList currentSelectedImages = thumbView->getSelectedThumbsList(); for (int i = 0; i < currentSelectedImages.size(); ++i) { QString imageName = currentSelectedImages[i]; for (int i = tagsList.size() - 1; i > -1; --i) { Qt::CheckState tagState = tagsList.at(i)->checkState(0); setTagIcon(tagsList.at(i), (tagState == Qt::Checked? TagIconEnabled : TagIconDisabled)); QString tagName = tagsList.at(i)->text(0); if (tagState == Qt::Checked) { dialog->opLabel->setText(tr("Tagging ") + imageName); mdCache->addTagToImage(imageName, tagName); } else { dialog->opLabel->setText(tr("Untagging ") + imageName); mdCache->removeTagFromImage(imageName, tagName); } } if (!writeTagsToImage(imageName, mdCache->getImageTags(imageName))) { mdCache->removeImage(imageName); } ++processEventsCounter; if (processEventsCounter > 9) { processEventsCounter = 0; QApplication::processEvents(); } if (dialog->abortOp) { break; } } dialog->close(); delete(dialog); }
void ResourceManagementUtil::editResource( const std::string& path, const QIcon& resourceIcon ) { ProgressDialog progressDlg; progressDlg.initialize( "Loading a resource", 1 ); ResourcesManager& resMgr = ResourcesManager::getInstance(); Resource* resource = resMgr.create( path ); progressDlg.advance(); if ( resource ) { TamyEditor& tamyEd = TamyEditor::getInstance(); if ( tamyEd.activateResourceEditor( resource ) == false ) { ResourceEditor* resourceEd = tamyEd.createResourceEditor( resource, resourceIcon ); tamyEd.addResourceEditor( resourceEd ); } } }
bool ZpCallback(const zp::Char* path, zp::u32 fileSize, void* param) { ProgressDialog* dlg = (ProgressDialog*)param; if (dlg == NULL) { return true; } if (dlg->m_running) { if (dlg->m_totalFileSize != 0) { dlg->setProgress(path, (float)dlg->m_doneFileSize / dlg->m_totalFileSize); } else { dlg->setProgress(path, 1.0f); } } dlg->m_doneFileSize += fileSize; return dlg->m_running; }
void FreqWindow::Recalc() { wxLogMessage(wxT("Starting FreqWindow::Recalc()")); if (mProcessed) delete[] mProcessed; mProcessed = NULL; if (!mData) { mFreqPlot->Refresh(true); return; } int alg = mAlgChoice->GetSelection(); int windowFunc = mFuncChoice->GetSelection(); long windowSize = 0; (mSizeChoice->GetStringSelection()).ToLong(&windowSize); int f = NumWindowFuncs(); if (!(windowSize >= 32 && windowSize <= 65536 && alg >= 0 && alg <= 4 && windowFunc >= 0 && windowFunc < f)) { mFreqPlot->Refresh(true); return; } mWindowSize = windowSize; if (mDataLen < mWindowSize) { mFreqPlot->Refresh(true); return; } mProcessed = new float[mWindowSize]; int i; for (i = 0; i < mWindowSize; i++) mProcessed[i] = float(0.0); int half = mWindowSize / 2; float *in = new float[mWindowSize]; float *in2 = new float[mWindowSize]; float *out = new float[mWindowSize]; float *out2 = new float[mWindowSize]; float *win = new float[mWindowSize]; // initialize the window for(int i=0; i<mWindowSize; i++) win[i] = 1.0; WindowFunc(windowFunc, mWindowSize, win); // Scale window such that an amplitude of 1.0 in the time domain // shows an amplitude of 0dB in the frequency domain double wss = 0; for(int i=0; i<mWindowSize; i++) wss += win[i]; if(wss > 0) wss = 4.0 / (wss*wss); else wss = 1.0; //Progress dialog over FFT operation wxLogMessage(wxT("Starting progress dialogue in FreqWindow::Recalc()")); ProgressDialog *mProgress = new ProgressDialog(_("FreqWindow"),_("Drawing Spectrum")); int start = 0; int windows = 0; while (start + mWindowSize <= mDataLen) { for (i = 0; i < mWindowSize; i++) in[i] = win[i] * mData[start + i]; switch (alg) { case 0: // Spectrum PowerSpectrum(mWindowSize, in, out); for (i = 0; i < half; i++) mProcessed[i] += out[i]; break; case 1: case 2: case 3: // Autocorrelation, Cuberoot AC or Enhanced AC // Take FFT #ifdef EXPERIMENTAL_USE_REALFFTF RealFFT(mWindowSize, in, out, out2); #else FFT(mWindowSize, false, in, NULL, out, out2); #endif // Compute power for (i = 0; i < mWindowSize; i++) in[i] = (out[i] * out[i]) + (out2[i] * out2[i]); if (alg == 1) { for (i = 0; i < mWindowSize; i++) in[i] = sqrt(in[i]); } if (alg == 2 || alg == 3) { // Tolonen and Karjalainen recommend taking the cube root // of the power, instead of the square root for (i = 0; i < mWindowSize; i++) in[i] = pow(in[i], 1.0f / 3.0f); } // Take FFT #ifdef EXPERIMENTAL_USE_REALFFTF RealFFT(mWindowSize, in, out, out2); #else FFT(mWindowSize, false, in, NULL, out, out2); #endif // Take real part of result for (i = 0; i < half; i++) mProcessed[i] += out[i]; break; case 4: // Cepstrum #ifdef EXPERIMENTAL_USE_REALFFTF RealFFT(mWindowSize, in, out, out2); #else FFT(mWindowSize, false, in, NULL, out, out2); #endif // Compute log power // Set a sane lower limit assuming maximum time amplitude of 1.0 float power; float minpower = 1e-20*mWindowSize*mWindowSize; for (i = 0; i < mWindowSize; i++) { power = (out[i] * out[i]) + (out2[i] * out2[i]); if(power < minpower) in[i] = log(minpower); else in[i] = log(power); } // Take IFFT #ifdef EXPERIMENTAL_USE_REALFFTF InverseRealFFT(mWindowSize, in, NULL, out); #else FFT(mWindowSize, true, in, NULL, out, out2); #endif // Take real part of result for (i = 0; i < half; i++) mProcessed[i] += out[i]; break; } //switch start += half; windows++; // only update the progress dialogue infrequently to reduce it's overhead // If we do it every time, it spends as much time updating X11 as doing // the calculations. 10 seems a reasonable compromise on Linux that // doesn't make it unresponsive, but avoids the slowdown. if ((windows % 10) == 0) mProgress->Update(1 - static_cast<float>(mDataLen - start) / mDataLen); } wxLogMessage(wxT("Finished updating progress dialogue in FreqWindow::Recalc()")); switch (alg) { double scale; case 0: // Spectrum // Convert to decibels mYMin = 1000000.; mYMax = -1000000.; scale = wss / (double)windows; for (i = 0; i < half; i++) { mProcessed[i] = 10 * log10(mProcessed[i] * scale); if(mProcessed[i] > mYMax) mYMax = mProcessed[i]; else if(mProcessed[i] < mYMin) mYMin = mProcessed[i]; } if(mYMin < -dBRange) mYMin = -dBRange; if(mYMax <= -dBRange) mYMax = -dBRange + 10.; // it's all out of range, but show a scale. else mYMax += .5; mProcessedSize = half; mYStep = 10; break; case 1: // Standard Autocorrelation case 2: // Cuberoot Autocorrelation for (i = 0; i < half; i++) mProcessed[i] = mProcessed[i] / windows; // Find min/max mYMin = mProcessed[0]; mYMax = mProcessed[0]; for (i = 1; i < half; i++) if (mProcessed[i] > mYMax) mYMax = mProcessed[i]; else if (mProcessed[i] < mYMin) mYMin = mProcessed[i]; mYStep = 1; mProcessedSize = half; break; case 3: // Enhanced Autocorrelation for (i = 0; i < half; i++) mProcessed[i] = mProcessed[i] / windows; // Peak Pruning as described by Tolonen and Karjalainen, 2000 // Clip at zero, copy to temp array for (i = 0; i < half; i++) { if (mProcessed[i] < 0.0) mProcessed[i] = float(0.0); out[i] = mProcessed[i]; } // Subtract a time-doubled signal (linearly interp.) from the original // (clipped) signal for (i = 0; i < half; i++) if ((i % 2) == 0) mProcessed[i] -= out[i / 2]; else mProcessed[i] -= ((out[i / 2] + out[i / 2 + 1]) / 2); // Clip at zero again for (i = 0; i < half; i++) if (mProcessed[i] < 0.0) mProcessed[i] = float(0.0); // Find new min/max mYMin = mProcessed[0]; mYMax = mProcessed[0]; for (i = 1; i < half; i++) if (mProcessed[i] > mYMax) mYMax = mProcessed[i]; else if (mProcessed[i] < mYMin) mYMin = mProcessed[i]; mYStep = 1; mProcessedSize = half; break; case 4: // Cepstrum for (i = 0; i < half; i++) mProcessed[i] = mProcessed[i] / windows; // Find min/max, ignoring first and last few values int ignore = 4; mYMin = mProcessed[ignore]; mYMax = mProcessed[ignore]; for (i = ignore + 1; i < half - ignore; i++) if (mProcessed[i] > mYMax) mYMax = mProcessed[i]; else if (mProcessed[i] < mYMin) mYMin = mProcessed[i]; mYStep = 1; mProcessedSize = half; break; } delete[]in; delete[]in2; delete[]out; delete[]out2; delete[]win; wxLogMessage(wxT("About to draw plot in FreqWindow::Recalc()")); DrawPlot(); mFreqPlot->Refresh(true); delete mProgress; }
int ExportOGG::Export(AudacityProject *project, int numChannels, wxString fName, bool selectionOnly, double t0, double t1, MixerSpec *mixerSpec, Tags *metadata, int WXUNUSED(subformat)) { double rate = project->GetRate(); TrackList *tracks = project->GetTracks(); double quality = (gPrefs->Read(wxT("/FileFormats/OggExportQuality"), 50)/(float)100.0); wxLogNull logNo; // temporarily disable wxWidgets error messages int updateResult = eProgressSuccess; int eos = 0; FileIO outFile(fName, FileIO::Output); if (!outFile.IsOpened()) { wxMessageBox(_("Unable to open target file for writing")); return false; } // All the Ogg and Vorbis encoding data ogg_stream_state stream; ogg_page page; ogg_packet packet; vorbis_info info; vorbis_comment comment; vorbis_dsp_state dsp; vorbis_block block; // Encoding setup vorbis_info_init(&info); vorbis_encode_init_vbr(&info, numChannels, int(rate + 0.5), quality); // Retrieve tags if (!FillComment(project, &comment, metadata)) { return false; } // Set up analysis state and auxiliary encoding storage vorbis_analysis_init(&dsp, &info); vorbis_block_init(&dsp, &block); // Set up packet->stream encoder. According to encoder example, // a random serial number makes it more likely that you can make // chained streams with concatenation. srand(time(NULL)); ogg_stream_init(&stream, rand()); // First we need to write the required headers: // 1. The Ogg bitstream header, which contains codec setup params // 2. The Vorbis comment header // 3. The bitstream codebook. // // After we create those our responsibility is complete, libvorbis will // take care of any other ogg bistream constraints (again, according // to the example encoder source) ogg_packet bitstream_header; ogg_packet comment_header; ogg_packet codebook_header; vorbis_analysis_headerout(&dsp, &comment, &bitstream_header, &comment_header, &codebook_header); // Place these headers into the stream ogg_stream_packetin(&stream, &bitstream_header); ogg_stream_packetin(&stream, &comment_header); ogg_stream_packetin(&stream, &codebook_header); // Flushing these headers now guarentees that audio data will // start on a NEW page, which apparently makes streaming easier while (ogg_stream_flush(&stream, &page)) { outFile.Write(page.header, page.header_len); outFile.Write(page.body, page.body_len); } int numWaveTracks; WaveTrack **waveTracks; tracks->GetWaveTracks(selectionOnly, &numWaveTracks, &waveTracks); Mixer *mixer = CreateMixer(numWaveTracks, waveTracks, tracks->GetTimeTrack(), t0, t1, numChannels, SAMPLES_PER_RUN, false, rate, floatSample, true, mixerSpec); delete [] waveTracks; ProgressDialog *progress = new ProgressDialog(wxFileName(fName).GetName(), selectionOnly ? _("Exporting the selected audio as Ogg Vorbis") : _("Exporting the entire project as Ogg Vorbis")); while (updateResult == eProgressSuccess && !eos) { float **vorbis_buffer = vorbis_analysis_buffer(&dsp, SAMPLES_PER_RUN); sampleCount samplesThisRun = mixer->Process(SAMPLES_PER_RUN); if (samplesThisRun == 0) { // Tell the library that we wrote 0 bytes - signalling the end. vorbis_analysis_wrote(&dsp, 0); } else { for (int i = 0; i < numChannels; i++) { float *temp = (float *)mixer->GetBuffer(i); memcpy(vorbis_buffer[i], temp, sizeof(float)*SAMPLES_PER_RUN); } // tell the encoder how many samples we have vorbis_analysis_wrote(&dsp, samplesThisRun); } // I don't understand what this call does, so here is the comment // from the example, verbatim: // // vorbis does some data preanalysis, then divvies up blocks // for more involved (potentially parallel) processing. Get // a single block for encoding now while (vorbis_analysis_blockout(&dsp, &block) == 1) { // analysis, assume we want to use bitrate management vorbis_analysis(&block, NULL); vorbis_bitrate_addblock(&block); while (vorbis_bitrate_flushpacket(&dsp, &packet)) { // add the packet to the bitstream ogg_stream_packetin(&stream, &packet); // From vorbis-tools-1.0/oggenc/encode.c: // If we've gone over a page boundary, we can do actual output, // so do so (for however many pages are available). while (!eos) { int result = ogg_stream_pageout(&stream, &page); if (!result) { break; } outFile.Write(page.header, page.header_len); outFile.Write(page.body, page.body_len); if (ogg_page_eos(&page)) { eos = 1; } } } } updateResult = progress->Update(mixer->MixGetCurrentTime()-t0, t1-t0); } delete progress;; delete mixer; ogg_stream_clear(&stream); vorbis_block_clear(&block); vorbis_dsp_clear(&dsp); vorbis_info_clear(&info); vorbis_comment_clear(&comment); outFile.Close(); return updateResult; }
int ExportFFmpeg::Export(AudacityProject *project, int channels, wxString fName, bool selectionOnly, double t0, double t1, MixerSpec *mixerSpec, Tags *metadata, int subformat) { if (!CheckFFmpegPresence()) return false; mChannels = channels; // subformat index may not correspond directly to fmts[] index, convert it mSubFormat = AdjustFormatIndex(subformat); if (channels > ExportFFmpegOptions::fmts[mSubFormat].maxchannels) { wxMessageBox( wxString::Format( _("Attempted to export %d channels, but maximum number of channels for selected output format is %d"), channels, ExportFFmpegOptions::fmts[mSubFormat].maxchannels), _("Error")); return false; } mName = fName; TrackList *tracks = project->GetTracks(); bool ret = true; if (mSubFormat >= FMT_LAST) return false; wxString shortname(ExportFFmpegOptions::fmts[mSubFormat].shortname); if (mSubFormat == FMT_OTHER) shortname = gPrefs->Read(wxT("/FileFormats/FFmpegFormat"),wxT("matroska")); ret = Init(shortname.mb_str(),project, metadata, subformat); if (!ret) return false; int pcmBufferSize = 1024; int numWaveTracks; WaveTrack **waveTracks; tracks->GetWaveTracks(selectionOnly, &numWaveTracks, &waveTracks); Mixer *mixer = CreateMixer(numWaveTracks, waveTracks, tracks->GetTimeTrack(), t0, t1, channels, pcmBufferSize, true, mSampleRate, int16Sample, true, mixerSpec); delete [] waveTracks; ProgressDialog *progress = new ProgressDialog(wxFileName(fName).GetName(), selectionOnly ? wxString::Format(_("Exporting selected audio as %s"), ExportFFmpegOptions::fmts[mSubFormat].description) : wxString::Format(_("Exporting entire file as %s"), ExportFFmpegOptions::fmts[mSubFormat].description)); int updateResult = eProgressSuccess; while(updateResult == eProgressSuccess) { sampleCount pcmNumSamples = mixer->Process(pcmBufferSize); if (pcmNumSamples == 0) break; short *pcmBuffer = (short *)mixer->GetBuffer(); EncodeAudioFrame(pcmBuffer,(pcmNumSamples)*sizeof(int16_t)*mChannels); updateResult = progress->Update(mixer->MixGetCurrentTime()-t0, t1-t0); } delete progress; delete mixer; Finalize(); return updateResult; }
/* static */ void VSTEffect::Scan() { wxArrayString audacityPathList = wxGetApp().audacityPathList; wxArrayString pathList; wxArrayString files; // Check for the VST_PATH environment variable wxString vstpath = wxGetenv(wxT("VST_PATH")); if (!vstpath.IsEmpty()) { wxGetApp().AddUniquePathToPathList(vstpath, pathList); } // Add Audacity specific paths for (size_t i = 0; i < audacityPathList.GetCount(); i++) { wxString prefix = audacityPathList[i] + wxFILE_SEP_PATH; wxGetApp().AddUniquePathToPathList(prefix + VSTPLUGINTYPE, pathList); wxGetApp().AddUniquePathToPathList(prefix + wxT("plugins"), pathList); wxGetApp().AddUniquePathToPathList(prefix + wxT("plug-ins"), pathList); } #if defined(__WXMAC__) #define VSTPATH wxT("/Library/Audio/Plug-Ins/VST") // Look in /Library/Audio/Plug-Ins/VST and $HOME/Library/Audio/Plug-Ins/VST wxGetApp().AddUniquePathToPathList(VSTPATH, pathList); wxGetApp().AddUniquePathToPathList(wxString(wxGetenv(wxT("HOME"))) + VSTPATH, pathList); // Recursively search all paths for Info.plist files. This will identify all // bundles. wxGetApp().FindFilesInPathList(wxT("Info.plist"), pathList, files, wxDIR_DEFAULT); // Remove the 'Contents/Info.plist' portion of the names for (size_t i = 0, cnt = files.GetCount(); i < cnt; i++) { files[i] = wxPathOnly(wxPathOnly(files[i])); } #elif defined(__WXMSW__) TCHAR dpath[MAX_PATH]; TCHAR tpath[MAX_PATH]; DWORD len = WXSIZEOF(tpath); // Setup the default VST path. dpath[0] = '\0'; ExpandEnvironmentStrings(wxT("%ProgramFiles%\\Steinberg\\VSTPlugins"), dpath, WXSIZEOF(dpath)); // Check registry for the real path if (SHRegGetUSValue(wxT("Software\\VST"), wxT("VSTPluginsPath"), NULL, tpath, &len, FALSE, dpath, (DWORD) _tcslen(dpath)) == ERROR_SUCCESS) { tpath[len] = 0; ExpandEnvironmentStrings(tpath, dpath, WXSIZEOF(dpath)); wxGetApp().AddUniquePathToPathList(LAT1CTOWX(dpath), pathList); } // Recursively scan for all DLLs wxGetApp().FindFilesInPathList(wxT("*.dll"), pathList, files, wxDIR_DEFAULT); #else // Recursively scan for all shared objects wxGetApp().FindFilesInPathList(wxT("*.so"), pathList, files); #endif // This is a hack to allow for long paths in the progress dialog. The // progress dialog should really truncate the message if it's too wide // for the dialog. size_t cnt = files.GetCount(); wxString longest; // JKC: Let's not show the progress dialog if there are no // files to test. if( cnt <= 0 ) return; for (size_t i = 0; i < cnt; i++) { if (files[i].Length() > longest.Length()) { longest = files[i]; } } ProgressDialog *progress = new ProgressDialog(_("Scanning VST Plugins"), longest, pdlgHideStopButton); // progress->SetSize(wxSize(500, -1)); progress->CenterOnScreen(); const wxChar * argv[4]; argv[0] = PlatformCompatibility::GetExecutablePath().c_str(); argv[1] = VSTCMDKEY; argv[2] = NULL; argv[3] = NULL; for (size_t i = 0; i < cnt; i++) { wxString file = files[i]; int status = progress->Update(wxLongLong(i), wxLongLong(cnt), wxString::Format(_("Checking %s"), file.c_str())); if (status != eProgressSuccess) { break; } argv[2] = file.c_str(); // ToDo: do we need a try--catch around this in case a bad plug-in // fails? (JKC Nov09) wxExecute((wxChar **) argv, wxEXEC_SYNC | wxEXEC_NODISABLE, NULL); } delete progress; }
int ExportFLAC::Export(AudacityProject *project, int numChannels, wxString fName, bool selectionOnly, double t0, double t1, MixerSpec *mixerSpec, Tags *metadata, int WXUNUSED(subformat)) { double rate = project->GetRate(); TrackList *tracks = project->GetTracks(); wxLogNull logNo; // temporarily disable wxWidgets error messages int updateResult = eProgressSuccess; int levelPref; gPrefs->Read(wxT("/FileFormats/FLACLevel"), &levelPref, 5); wxString bitDepthPref = gPrefs->Read(wxT("/FileFormats/FLACBitDepth"), wxT("16")); FLAC::Encoder::File encoder; #ifdef LEGACY_FLAC encoder.set_filename(OSOUTPUT(fName)); #endif encoder.set_channels(numChannels); encoder.set_sample_rate(lrint(rate)); // See note in GetMetadata() about a bug in libflac++ 1.1.2 if (!GetMetadata(project, metadata)) { return false; } if (mMetadata) { encoder.set_metadata(&mMetadata, 1); } sampleFormat format; if (bitDepthPref == wxT("24")) { format = int24Sample; encoder.set_bits_per_sample(24); } else { //convert float to 16 bits format = int16Sample; encoder.set_bits_per_sample(16); } // Duplicate the flac command line compression levels if (levelPref < 0 || levelPref > 8) { levelPref = 5; } encoder.set_do_exhaustive_model_search(flacLevels[levelPref].do_exhaustive_model_search); encoder.set_do_escape_coding(flacLevels[levelPref].do_escape_coding); if (numChannels != 2) { encoder.set_do_mid_side_stereo(false); encoder.set_loose_mid_side_stereo(false); } else { encoder.set_do_mid_side_stereo(flacLevels[levelPref].do_mid_side_stereo); encoder.set_loose_mid_side_stereo(flacLevels[levelPref].loose_mid_side_stereo); } encoder.set_qlp_coeff_precision(flacLevels[levelPref].qlp_coeff_precision); encoder.set_min_residual_partition_order(flacLevels[levelPref].min_residual_partition_order); encoder.set_max_residual_partition_order(flacLevels[levelPref].max_residual_partition_order); encoder.set_rice_parameter_search_dist(flacLevels[levelPref].rice_parameter_search_dist); encoder.set_max_lpc_order(flacLevels[levelPref].max_lpc_order); #ifdef LEGACY_FLAC encoder.init(); #else wxFFile f; // will be closed when it goes out of scope if (!f.Open(fName, wxT("w+b"))) { wxMessageBox(wxString::Format(_("FLAC export couldn't open %s"), fName.c_str())); return false; } // Even though there is an init() method that takes a filename, use the one that // takes a file handle because wxWidgets can open a file with a Unicode name and // libflac can't (under Windows). int status = encoder.init(f.fp()); if (status != FLAC__STREAM_ENCODER_INIT_STATUS_OK) { wxMessageBox(wxString::Format(_("FLAC encoder failed to initialize\nStatus: %d"), status)); return false; } #endif if (mMetadata) { ::FLAC__metadata_object_delete(mMetadata); } int numWaveTracks; WaveTrack **waveTracks; tracks->GetWaveTracks(selectionOnly, &numWaveTracks, &waveTracks); Mixer *mixer = CreateMixer(numWaveTracks, waveTracks, tracks->GetTimeTrack(), t0, t1, numChannels, SAMPLES_PER_RUN, false, rate, format, true, mixerSpec); delete [] waveTracks; int i, j; FLAC__int32 **tmpsmplbuf = new FLAC__int32*[numChannels]; for (i = 0; i < numChannels; i++) { tmpsmplbuf[i] = (FLAC__int32 *) calloc(SAMPLES_PER_RUN, sizeof(FLAC__int32)); } ProgressDialog *progress = new ProgressDialog(wxFileName(fName).GetName(), selectionOnly ? _("Exporting the selected audio as FLAC") : _("Exporting the entire project as FLAC")); while (updateResult == eProgressSuccess) { sampleCount samplesThisRun = mixer->Process(SAMPLES_PER_RUN); if (samplesThisRun == 0) { //stop encoding break; } else { for (i = 0; i < numChannels; i++) { samplePtr mixed = mixer->GetBuffer(i); if (format == int24Sample) { for (j = 0; j < samplesThisRun; j++) { tmpsmplbuf[i][j] = ((int *) mixed)[j]; } } else { for (j = 0; j < samplesThisRun; j++) { tmpsmplbuf[i][j] = ((short *) mixed)[j]; } } } encoder.process(tmpsmplbuf, samplesThisRun); } updateResult = progress->Update(mixer->MixGetCurrentTime()-t0, t1-t0); } f.Detach(); // libflac closes the file encoder.finish(); delete progress; for (i = 0; i < numChannels; i++) { free(tmpsmplbuf[i]); } delete mixer; delete[] tmpsmplbuf; return updateResult; }
bool ExportFFmpeg::EncodeAudioFrame(int16_t *pFrame, int frameSize) { AVPacket pkt; int nBytesToWrite = 0; uint8_t * pRawSamples = NULL; int nAudioFrameSizeOut = mEncAudioCodecCtx->frame_size * mEncAudioCodecCtx->channels * sizeof(int16_t); if (mEncAudioCodecCtx->frame_size == 1) nAudioFrameSizeOut = mEncAudioEncodedBufSiz; int ret; nBytesToWrite = frameSize; pRawSamples = (uint8_t*)pFrame; #if FFMPEG_STABLE FFmpegLibsInst->av_fifo_realloc(&mEncAudioFifo, FFmpegLibsInst->av_fifo_size(&mEncAudioFifo) + frameSize); #else FFmpegLibsInst->av_fifo_realloc2(mEncAudioFifo, FFmpegLibsInst->av_fifo_size(mEncAudioFifo) + frameSize); #endif // Put the raw audio samples into the FIFO. #if FFMPEG_STABLE ret = FFmpegLibsInst->av_fifo_generic_write(&mEncAudioFifo, pRawSamples, nBytesToWrite,NULL); #else ret = FFmpegLibsInst->av_fifo_generic_write(mEncAudioFifo, pRawSamples, nBytesToWrite,NULL); #endif wxASSERT(ret == nBytesToWrite); // Read raw audio samples out of the FIFO in nAudioFrameSizeOut byte-sized groups to encode. #if FFMPEG_STABLE while ((ret = FFmpegLibsInst->av_fifo_size(&mEncAudioFifo)) >= nAudioFrameSizeOut) { ret = FFmpegLibsInst->av_fifo_read(&mEncAudioFifo, mEncAudioFifoOutBuf, nAudioFrameSizeOut); #else while ((ret = FFmpegLibsInst->av_fifo_size(mEncAudioFifo)) >= nAudioFrameSizeOut) { ret = FFmpegLibsInst->av_fifo_generic_read(mEncAudioFifo, mEncAudioFifoOutBuf, nAudioFrameSizeOut, NULL); #endif FFmpegLibsInst->av_init_packet(&pkt); pkt.size = FFmpegLibsInst->avcodec_encode_audio(mEncAudioCodecCtx, mEncAudioEncodedBuf, mEncAudioEncodedBufSiz, // out (int16_t*)mEncAudioFifoOutBuf); // in if (mEncAudioCodecCtx->frame_size == 1) { wxASSERT(pkt.size == mEncAudioEncodedBufSiz); } if (pkt.size < 0) { wxLogMessage(wxT("FFmpeg : ERROR - Can't encode audio frame.")); return false; } // Rescale from the codec time_base to the AVStream time_base. if (mEncAudioCodecCtx->coded_frame && mEncAudioCodecCtx->coded_frame->pts != int64_t(AV_NOPTS_VALUE)) pkt.pts = FFmpegLibsInst->av_rescale_q(mEncAudioCodecCtx->coded_frame->pts, mEncAudioCodecCtx->time_base, mEncAudioStream->time_base); //wxLogMessage(wxT("FFmpeg : (%d) Writing audio frame with PTS: %lld."), mEncAudioCodecCtx->frame_number, pkt.pts); pkt.stream_index = mEncAudioStream->index; pkt.data = mEncAudioEncodedBuf; pkt.flags |= PKT_FLAG_KEY; // Write the encoded audio frame to the output file. if ((ret = FFmpegLibsInst->av_interleaved_write_frame(mEncFormatCtx, &pkt)) != 0) { wxLogMessage(wxT("FFmpeg : ERROR - Failed to write audio frame to file.")); return false; } } return true; } int ExportFFmpeg::Export(AudacityProject *project, int channels, wxString fName, bool selectionOnly, double t0, double t1, MixerSpec *mixerSpec, Tags *metadata, int subformat) { if (!CheckFFmpegPresence()) return false; mChannels = channels; // subformat index may not correspond directly to fmts[] index, convert it mSubFormat = AdjustFormatIndex(subformat); if (channels > ExportFFmpegOptions::fmts[mSubFormat].maxchannels) { wxLogMessage(wxT("Attempted to export %d channels, but max. channels = %d"),channels,ExportFFmpegOptions::fmts[mSubFormat].maxchannels); wxMessageBox(wxString::Format(_("Attempted to export %d channels, but max. channels for selected output format is %d"),channels,ExportFFmpegOptions::fmts[mSubFormat].maxchannels),_("Error")); return false; } mName = fName; TrackList *tracks = project->GetTracks(); bool ret = true; if (mSubFormat >= FMT_LAST) return false; wxString shortname(ExportFFmpegOptions::fmts[mSubFormat].shortname); if (mSubFormat == FMT_OTHER) shortname = gPrefs->Read(wxT("/FileFormats/FFmpegFormat"),wxT("matroska")); ret = Init(shortname.mb_str(),project, metadata); if (!ret) return false; int pcmBufferSize = 1024; int numWaveTracks; WaveTrack **waveTracks; tracks->GetWaveTracks(selectionOnly, &numWaveTracks, &waveTracks); Mixer *mixer = new Mixer(numWaveTracks, waveTracks, tracks->GetTimeTrack(), t0, t1, channels, pcmBufferSize, true, mSampleRate, int16Sample, true, mixerSpec); delete [] waveTracks; ProgressDialog *progress = new ProgressDialog(wxFileName(fName).GetName(), selectionOnly ? wxString::Format(_("Exporting selected audio as %s"), ExportFFmpegOptions::fmts[mSubFormat].description) : wxString::Format(_("Exporting entire file as %s"), ExportFFmpegOptions::fmts[mSubFormat].description)); int updateResult = eProgressSuccess; while(updateResult == eProgressSuccess) { sampleCount pcmNumSamples = mixer->Process(pcmBufferSize); if (pcmNumSamples == 0) break; short *pcmBuffer = (short *)mixer->GetBuffer(); EncodeAudioFrame(pcmBuffer,(pcmNumSamples)*sizeof(int16_t)*mChannels); updateResult = progress->Update(mixer->MixGetCurrentTime()-t0, t1-t0); } delete progress; delete mixer; Finalize(); return updateResult; } void AddStringTagUTF8(char field[], int size, wxString value) { memset(field,0,size); memcpy(field,value.ToUTF8(),(int)strlen(value.ToUTF8()) > size -1 ? size -1 : strlen(value.ToUTF8())); }
// Given a project and a list of aliased files that should no // longer be external dependencies (selected by the user), replace // all of those alias block files with disk block files. void RemoveDependencies(AudacityProject *project, AliasedFileArray *aliasedFiles) { DirManager *dirManager = project->GetDirManager(); ProgressDialog *progress = new ProgressDialog(_("Removing Dependencies"), _("Copying audio data into project...")); int updateResult = eProgressSuccess; // Hash aliasedFiles based on their full paths and // count total number of bytes to process. AliasedFileHash aliasedFileHash; wxLongLong totalBytesToProcess = 0; unsigned int i; for (i = 0; i < aliasedFiles->GetCount(); i++) { totalBytesToProcess += aliasedFiles->Item(i).mByteCount; wxString fileNameStr = aliasedFiles->Item(i).mFileName.GetFullPath(); aliasedFileHash[fileNameStr] = &aliasedFiles->Item(i); } BlockArray blocks; GetAllSeqBlocks(project, &blocks); const sampleFormat format = project->GetDefaultFormat(); ReplacedBlockFileHash blockFileHash; wxLongLong completedBytes = 0; for (i = 0; i < blocks.GetCount(); i++) { BlockFile *f = blocks[i]->f; if (f->IsAlias() && (blockFileHash.count(f) == 0)) { // f is an alias block we have not yet processed. AliasBlockFile *aliasBlockFile = (AliasBlockFile *)f; wxFileName fileName = aliasBlockFile->GetAliasedFileName(); wxString fileNameStr = fileName.GetFullPath(); if (aliasedFileHash.count(fileNameStr) == 0) // This aliased file was not selected to be replaced. Skip it. continue; // Convert it from an aliased file to an actual file in the project. unsigned int len = aliasBlockFile->GetLength(); samplePtr buffer = NewSamples(len, format); f->ReadData(buffer, format, 0, len); BlockFile *newBlockFile = dirManager->NewSimpleBlockFile(buffer, len, format); DeleteSamples(buffer); // Update our hash so we know what block files we've done blockFileHash[f] = newBlockFile; // Update the progress bar completedBytes += SAMPLE_SIZE(format) * len; updateResult = progress->Update(completedBytes, totalBytesToProcess); if (updateResult != eProgressSuccess) break; } } // Above, we created a SimpleBlockFile contained in our project // to go with each AliasBlockFile that we wanted to migrate. // However, that didn't actually change any references to these // blockfiles in the Sequences, so we do that next... ReplaceBlockFiles(project, blockFileHash); // Subtract one from reference count of new block files; they're // now all referenced the proper number of times by the Sequences ReplacedBlockFileHash::iterator it; for( it = blockFileHash.begin(); it != blockFileHash.end(); ++it ) { BlockFile *f = it->second; dirManager->Deref(f); } delete progress; }
//TODO-MB: wouldn't it make more sense to delete the time track after 'mix and render'? bool MixAndRender(TrackList *tracks, TrackFactory *trackFactory, double rate, sampleFormat format, double startTime, double endTime, WaveTrack **newLeft, WaveTrack **newRight) { // This function was formerly known as "Quick Mix". WaveTrack **waveArray; Track *t; int numWaves = 0; /* number of wave tracks in the selection */ int numMono = 0; /* number of mono, centre-panned wave tracks in selection*/ bool mono = false; /* flag if output can be mono without loosing anything*/ bool oneinput = false; /* flag set to true if there is only one input track (mono or stereo) */ int w; TrackListIterator iter(tracks); SelectedTrackListOfKindIterator usefulIter(Track::Wave, tracks); // this only iterates tracks which are relevant to this function, i.e. // selected WaveTracks. The tracklist is (confusingly) the list of all // tracks in the project t = iter.First(); while (t) { if (t->GetSelected() && t->GetKind() == Track::Wave) { numWaves++; float pan = ((WaveTrack*)t)->GetPan(); if (t->GetChannel() == Track::MonoChannel && pan == 0) numMono++; } t = iter.Next(); } if (numMono == numWaves) mono = true; /* the next loop will do two things at once: * 1. build an array of all the wave tracks were are trying to process * 2. determine when the set of WaveTracks starts and ends, in case we * need to work out for ourselves when to start and stop rendering. */ double mixStartTime = 0.0; /* start time of first track to start */ bool gotstart = false; // flag indicates we have found a start time double mixEndTime = 0.0; /* end time of last track to end */ double tstart, tend; // start and end times for one track. waveArray = new WaveTrack *[numWaves]; w = 0; t = iter.First(); while (t) { if (t->GetSelected() && t->GetKind() == Track::Wave) { waveArray[w++] = (WaveTrack *) t; tstart = t->GetStartTime(); tend = t->GetEndTime(); if (tend > mixEndTime) mixEndTime = tend; // try and get the start time. If the track is empty we will get 0, // which is ambiguous because it could just mean the track starts at // the beginning of the project, as well as empty track. The give-away // is that an empty track also ends at zero. if (tstart != tend) { // we don't get empty tracks here if (!gotstart) { // no previous start, use this one unconditionally mixStartTime = tstart; gotstart = true; } else if (tstart < mixStartTime) mixStartTime = tstart; // have a start, only make it smaller } // end if start and end are different } // end if track is a selected WaveTrack. /** @TODO: could we not use a SelectedTrackListOfKindIterator here? */ t = iter.Next(); } /* create the destination track (new track) */ if ((numWaves == 1) || ((numWaves == 2) && (usefulIter.First()->GetLink() != NULL))) oneinput = true; // only one input track (either 1 mono or one linked stereo pair) WaveTrack *mixLeft = trackFactory->NewWaveTrack(format, rate); if (oneinput) mixLeft->SetName(usefulIter.First()->GetName()); /* set name of output track to be the same as the sole input track */ else mixLeft->SetName(_("Mix")); mixLeft->SetOffset(mixStartTime); WaveTrack *mixRight = 0; if (mono) { mixLeft->SetChannel(Track::MonoChannel); } else { mixRight = trackFactory->NewWaveTrack(format, rate); if (oneinput) { if (usefulIter.First()->GetLink() != NULL) // we have linked track mixLeft->SetName(usefulIter.First()->GetLink()->GetName()); /* set name to match input track's right channel!*/ else mixLeft->SetName(usefulIter.First()->GetName()); /* set name to that of sole input channel */ } else mixRight->SetName(_("Mix")); mixLeft->SetChannel(Track::LeftChannel); mixRight->SetChannel(Track::RightChannel); mixRight->SetOffset(mixStartTime); mixLeft->SetLinked(true); } int maxBlockLen = mixLeft->GetIdealBlockSize(); // If the caller didn't specify a time range, use the whole range in which // any input track had clips in it. if (startTime == endTime) { startTime = mixStartTime; endTime = mixEndTime; } Mixer *mixer = new Mixer(numWaves, waveArray, Mixer::WarpOptions(tracks->GetTimeTrack()), startTime, endTime, mono ? 1 : 2, maxBlockLen, false, rate, format); ::wxSafeYield(); ProgressDialog *progress = new ProgressDialog(_("Mix and Render"), _("Mixing and rendering tracks")); int updateResult = eProgressSuccess; while(updateResult == eProgressSuccess) { sampleCount blockLen = mixer->Process(maxBlockLen); if (blockLen == 0) break; if (mono) { samplePtr buffer = mixer->GetBuffer(); mixLeft->Append(buffer, format, blockLen); } else { samplePtr buffer; buffer = mixer->GetBuffer(0); mixLeft->Append(buffer, format, blockLen); buffer = mixer->GetBuffer(1); mixRight->Append(buffer, format, blockLen); } updateResult = progress->Update(mixer->MixGetCurrentTime() - startTime, endTime - startTime); } delete progress; mixLeft->Flush(); if (!mono) mixRight->Flush(); if (updateResult == eProgressCancelled || updateResult == eProgressFailed) { delete mixLeft; if (!mono) delete mixRight; } else { *newLeft = mixLeft; if (!mono) *newRight = mixRight; #if 0 int elapsedMS = wxGetElapsedTime(); double elapsedTime = elapsedMS * 0.001; double maxTracks = totalTime / (elapsedTime / numWaves); // Note: these shouldn't be translated - they're for debugging // and profiling only. printf(" Tracks: %d\n", numWaves); printf(" Mix length: %f sec\n", totalTime); printf("Elapsed time: %f sec\n", elapsedTime); printf("Max number of tracks to mix in real time: %f\n", maxTracks); #endif } delete[] waveArray; delete mixer; return (updateResult == eProgressSuccess || updateResult == eProgressStopped); }