mirror of
https://github.com/cookiengineer/audacity
synced 2025-10-13 14:13:32 +02:00
AUP3: Removes OD code related to project file handling
This removes all of the OnDemand code embedded throughout the main codebase. Individual files related specifically to OD have been left in place, but removed from the build.
This commit is contained in:
@@ -29,8 +29,6 @@ Licensed under the GNU General Public License v2 or later
|
||||
|
||||
#include "../FFmpeg.h" // which brings in avcodec.h, avformat.h
|
||||
#include "../WaveClip.h"
|
||||
#include "../blockfile/ODDecodeBlockFile.h"
|
||||
#include "../ondemand/ODManager.h"
|
||||
#ifndef WX_PRECOMP
|
||||
// Include your minimal set of headers here, or wx.h
|
||||
#include <wx/window.h>
|
||||
@@ -158,11 +156,6 @@ static const auto exts = {
|
||||
#include "../WaveTrack.h"
|
||||
#include "ImportPlugin.h"
|
||||
|
||||
|
||||
#ifdef EXPERIMENTAL_OD_FFMPEG
|
||||
#include "../ondemand/ODDecodeFFmpegTask.h"
|
||||
#endif
|
||||
|
||||
class FFmpegImportFileHandle;
|
||||
|
||||
/// A representative of FFmpeg loader in
|
||||
@@ -276,10 +269,6 @@ private:
|
||||
//!< First dimension - streams,
|
||||
//!< second - channels of a stream.
|
||||
//!< Length is mNumStreams
|
||||
#ifdef EXPERIMENTAL_OD_FFMPEG
|
||||
bool mUsingOD;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -561,75 +550,6 @@ ProgressResult FFmpegImportFileHandle::Import(TrackFactory *trackFactory,
|
||||
// The result of Import() to be returned. It will be something other than zero if user canceled or some error appears.
|
||||
auto res = ProgressResult::Success;
|
||||
|
||||
#ifdef EXPERIMENTAL_OD_FFMPEG
|
||||
mUsingOD = false;
|
||||
gPrefs->Read(wxT("/Library/FFmpegOnDemand"), &mUsingOD);
|
||||
//at this point we know the file is good and that we have to load the number of channels in mScs[s]->m_stream->codec->channels;
|
||||
//so for OD loading we create the tracks and releasee the modal lock after starting the ODTask.
|
||||
if (mUsingOD) {
|
||||
std::vector<std::unique_ptr<ODDecodeFFmpegTask>> tasks;
|
||||
//append blockfiles to each stream and add an individual ODDecodeTask for each one.
|
||||
s = -1;
|
||||
for (const auto &stream : mChannels) {
|
||||
++s;
|
||||
auto odTask =
|
||||
std::make_unique<ODDecodeFFmpegTask>(mScs, ODDecodeFFmpegTask::FromList(mChannels), mContext, s);
|
||||
odTask->CreateFileDecoder(mFilename);
|
||||
|
||||
//each stream has different duration. We need to know it if seeking is to be allowed.
|
||||
sampleCount sampleDuration = 0;
|
||||
auto sc = scs[s].get();
|
||||
if (sc->m_stream->duration > 0)
|
||||
sampleDuration = ((sampleCount)sc->m_stream->duration * sc->m_stream->time_base.num) * sc->m_stream->codec->sample_rate / sc->m_stream->time_base.den;
|
||||
else
|
||||
sampleDuration = ((sampleCount)mFormatContext->duration *sc->m_stream->codec->sample_rate) / AV_TIME_BASE;
|
||||
|
||||
// wxPrintf(" OD duration samples %qi, sr %d, secs %d\n",sampleDuration, (int)sc->m_stream->codec->sample_rate, (int)sampleDuration/sc->m_stream->codec->sample_rate);
|
||||
|
||||
//for each wavetrack within the stream add coded blockfiles
|
||||
for (int c = 0; c < sc->m_stream->codec->channels; c++) {
|
||||
auto t = stream[c];
|
||||
odTask->AddWaveTrack(t);
|
||||
|
||||
auto maxBlockSize = t->GetMaxBlockSize();
|
||||
//use the maximum blockfile size to divide the sections (about 11secs per blockfile at 44.1khz)
|
||||
|
||||
for (decltype(sampleDuration) i = 0; i < sampleDuration; i += maxBlockSize) {
|
||||
const auto blockLen =
|
||||
limitSampleBufferSize( maxBlockSize, sampleDuration - i );
|
||||
|
||||
t->RightmostOrNewClip()->AppendBlockFile(
|
||||
[&]( wxFileNameWrapper filePath, size_t len ) {
|
||||
return make_blockfile<ODDecodeBlockFile>(
|
||||
std::move(filePath), wxFileNameWrapper{ mFilename },
|
||||
i, len, c, ODTask::eODFFMPEG);
|
||||
},
|
||||
blockLen
|
||||
);
|
||||
|
||||
// This only works well for single streams since we assume
|
||||
// each stream is of the same duration and channels
|
||||
res = mProgress->Update(
|
||||
(i+sampleDuration * c +
|
||||
sampleDuration*sc->m_stream->codec->channels * s
|
||||
).as_long_long(),
|
||||
(sampleDuration *
|
||||
sc->m_stream->codec->channels * mNumStreams
|
||||
).as_long_long()
|
||||
);
|
||||
if (res != ProgressResult::Success)
|
||||
break;
|
||||
}
|
||||
}
|
||||
tasks.push_back(std::move(odTask));
|
||||
}
|
||||
//Now we add the tasks and let them run, or DELETE them if the user cancelled
|
||||
if (res == ProgressResult::Success)
|
||||
for (int i = 0; i < (int)tasks.size(); i++)
|
||||
ODManager::Instance()->AddNewTask(std::move(tasks[i]));
|
||||
} else {
|
||||
#endif
|
||||
|
||||
// Read next frame.
|
||||
for (streamContext *sc; (sc = ReadNextFrame()) != NULL && (res == ProgressResult::Success);)
|
||||
{
|
||||
@@ -667,9 +587,6 @@ ProgressResult FFmpegImportFileHandle::Import(TrackFactory *trackFactory,
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef EXPERIMENTAL_OD_FFMPEG
|
||||
} // else -- !mUsingOD == true
|
||||
#endif //EXPERIMENTAL_OD_FFMPEG
|
||||
|
||||
// Something bad happened - destroy everything!
|
||||
if (res == ProgressResult::Cancelled || res == ProgressResult::Failed)
|
||||
|
@@ -43,7 +43,6 @@
|
||||
|
||||
#include "../Tags.h"
|
||||
#include "../WaveClip.h"
|
||||
#include "../blockfile/ODDecodeBlockFile.h"
|
||||
#include "../prefs/QualityPrefs.h"
|
||||
#include "../widgets/ProgressDialog.h"
|
||||
|
||||
@@ -76,8 +75,6 @@ static Importer::RegisteredUnusableImportPlugin registered{
|
||||
#include "../Prefs.h"
|
||||
#include "../WaveTrack.h"
|
||||
#include "ImportPlugin.h"
|
||||
#include "../ondemand/ODDecodeFlacTask.h"
|
||||
#include "../ondemand/ODManager.h"
|
||||
|
||||
#ifdef USE_LIBID3TAG
|
||||
extern "C" {
|
||||
@@ -178,7 +175,6 @@ private:
|
||||
bool mStreamInfoDone;
|
||||
ProgressResult mUpdateResult;
|
||||
NewChannelGroup mChannels;
|
||||
std::unique_ptr<ODDecodeFlacTask> mDecoderTask;
|
||||
};
|
||||
|
||||
|
||||
@@ -349,28 +345,6 @@ FLACImportFileHandle::FLACImportFileHandle(const FilePath & name)
|
||||
|
||||
bool FLACImportFileHandle::Init()
|
||||
{
|
||||
#ifdef EXPERIMENTAL_OD_FLAC
|
||||
mDecoderTask = std::make_unique<ODDecodeFlacTask>();
|
||||
|
||||
ODFlacDecoder* odDecoder = (ODFlacDecoder*)mDecoderTask->CreateFileDecoder(mFilename);
|
||||
if(!odDecoder || !odDecoder->ReadHeader())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
//copy the meta data over to the class
|
||||
|
||||
mSampleRate=odDecoder->mSampleRate;
|
||||
mNumChannels=odDecoder->mNumChannels;
|
||||
mBitsPerSample=odDecoder->mBitsPerSample;
|
||||
|
||||
mNumSamples=odDecoder->mNumSamples;
|
||||
mBitsPerSample=odDecoder->mBitsPerSample;
|
||||
mFormat=odDecoder->mFormat;
|
||||
mStreamInfoDone=true;
|
||||
|
||||
|
||||
return true;
|
||||
#endif
|
||||
#ifdef LEGACY_FLAC
|
||||
bool success = mFile->set_filename(OSINPUT(mFilename));
|
||||
if (!success) {
|
||||
@@ -452,70 +426,15 @@ ProgressResult FLACImportFileHandle::Import(TrackFactory *trackFactory,
|
||||
*iter = trackFactory->NewWaveTrack(mFormat, mSampleRate);
|
||||
}
|
||||
|
||||
//Start OD
|
||||
bool useOD = false;
|
||||
#ifdef EXPERIMENTAL_OD_FLAC
|
||||
useOD=true;
|
||||
#endif
|
||||
|
||||
// TODO: Vigilant Sentry: Variable res unused after assignment (error code DA1)
|
||||
// Should check the result.
|
||||
#ifdef LEGACY_FLAC
|
||||
bool res = (mFile->process_until_end_of_file() != 0);
|
||||
#else
|
||||
bool res = true;
|
||||
if(!useOD)
|
||||
res = (mFile->process_until_end_of_stream() != 0);
|
||||
bool res = (mFile->process_until_end_of_stream() != 0);
|
||||
#endif
|
||||
wxUnusedVar(res);
|
||||
|
||||
//add the task to the ODManager
|
||||
if(useOD)
|
||||
{
|
||||
auto fileTotalFrames =
|
||||
(sampleCount)mNumSamples; // convert from FLAC__uint64
|
||||
auto maxBlockSize = mChannels.begin()->get()->GetMaxBlockSize();
|
||||
for (decltype(fileTotalFrames) i = 0; i < fileTotalFrames; i += maxBlockSize) {
|
||||
const auto blockLen =
|
||||
limitSampleBufferSize( maxBlockSize, fileTotalFrames - i );
|
||||
|
||||
auto iter = mChannels.begin();
|
||||
for (size_t c = 0; c < mNumChannels; ++c, ++iter)
|
||||
iter->get()->RightmostOrNewClip()->AppendBlockFile(
|
||||
[&]( wxFileNameWrapper filePath, size_t len ) {
|
||||
return make_blockfile<ODDecodeBlockFile>(
|
||||
std::move(filePath), wxFileNameWrapper{ mFilename },
|
||||
i, len, c, ODTask::eODFLAC);
|
||||
},
|
||||
blockLen
|
||||
);
|
||||
|
||||
mUpdateResult = mProgress->Update(
|
||||
i.as_long_long(),
|
||||
fileTotalFrames.as_long_long()
|
||||
);
|
||||
if (mUpdateResult != ProgressResult::Success)
|
||||
break;
|
||||
}
|
||||
|
||||
bool moreThanStereo = mNumChannels>2;
|
||||
for (const auto &channel : mChannels)
|
||||
{
|
||||
mDecoderTask->AddWaveTrack(channel);
|
||||
if(moreThanStereo)
|
||||
{
|
||||
//if we have 3 more channels, they get imported on separate tracks, so we add individual tasks for each.
|
||||
ODManager::Instance()->AddNewTask(std::move(mDecoderTask));
|
||||
mDecoderTask = std::make_unique<ODDecodeFlacTask>(); //TODO: see if we need to use clone to keep the metadata.
|
||||
}
|
||||
}
|
||||
//if we have mono or a linked track (stereo), we add ONE task for the one linked wave track
|
||||
if(!moreThanStereo)
|
||||
ODManager::Instance()->AddNewTask(std::move(mDecoderTask));
|
||||
}
|
||||
//END OD
|
||||
|
||||
|
||||
if (mUpdateResult == ProgressResult::Failed || mUpdateResult == ProgressResult::Cancelled) {
|
||||
return mUpdateResult;
|
||||
}
|
||||
@@ -546,11 +465,7 @@ ProgressResult FLACImportFileHandle::Import(TrackFactory *trackFactory,
|
||||
|
||||
FLACImportFileHandle::~FLACImportFileHandle()
|
||||
{
|
||||
//don't finish *mFile if we are using OD,
|
||||
//because it was not initialized in Init().
|
||||
#ifndef EXPERIMENTAL_OD_FLAC
|
||||
mFile->finish();
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* USE_LIBFLAC */
|
||||
|
@@ -39,16 +39,9 @@
|
||||
#include "../WaveClip.h"
|
||||
#include "../ShuttleGui.h"
|
||||
|
||||
#include "../ondemand/ODManager.h"
|
||||
#include "../ondemand/ODComputeSummaryTask.h"
|
||||
#include "../blockfile/ODPCMAliasBlockFile.h"
|
||||
#include "../prefs/QualityPrefs.h"
|
||||
#include "../widgets/ProgressDialog.h"
|
||||
|
||||
//If OD is enabled, he minimum number of samples a file has to use it.
|
||||
//Otherwise, we use the older PCMAliasBlockFile method since it should be fast enough.
|
||||
#define kMinimumODFileSampleSize 44100*30
|
||||
|
||||
#ifndef SNDFILE_1
|
||||
#error Requires libsndfile 1.0 or higher
|
||||
#endif
|
||||
@@ -288,115 +281,6 @@ auto PCMImportFileHandle::GetFileUncompressedBytes() -> ByteCount
|
||||
return mInfo.frames * mInfo.channels * SAMPLE_SIZE(mFormat);
|
||||
}
|
||||
|
||||
#ifdef EXPERIMENTAL_OD_DATA
|
||||
// returns "copy" or "edit" (aliased) as the user selects.
|
||||
// if the cancel button is hit then "cancel" is returned.
|
||||
static wxString AskCopyOrEdit()
|
||||
{
|
||||
|
||||
auto oldCopyPref = FileFormatsCopyOrEditSetting.Read();
|
||||
|
||||
bool firstTimeAsk = gPrefs->Read(wxT("/Warnings/CopyOrEditUncompressedDataFirstAsk"), true)?true:false;
|
||||
bool oldAskPref = gPrefs->Read(wxT("/Warnings/CopyOrEditUncompressedDataAsk"), true)?true:false;
|
||||
|
||||
// The first time the user is asked we force it to 'copy'.
|
||||
// This effectively does a one-time change to the preferences.
|
||||
if (firstTimeAsk) {
|
||||
if (oldCopyPref != wxT("copy")) {
|
||||
FileFormatsCopyOrEditSetting.Write( wxT("copy") );
|
||||
oldCopyPref = wxT("copy");
|
||||
}
|
||||
gPrefs->Write(wxT("/Warnings/CopyOrEditUncompressedDataFirstAsk"), (long) false);
|
||||
gPrefs->Flush();
|
||||
}
|
||||
|
||||
// check the current preferences for whether or not we should ask the user about this.
|
||||
if (oldAskPref) {
|
||||
wxString newCopyPref = wxT("copy");
|
||||
wxDialogWrapper dialog( nullptr, -1, XO("Warning") );
|
||||
dialog.SetName();
|
||||
|
||||
auto clause1 = XO(
|
||||
"When importing uncompressed audio files you can either copy them into the project,"
|
||||
" or read them directly from their current location (without copying).\n\n"
|
||||
);
|
||||
|
||||
auto clause2 = (oldCopyPref == wxT("copy"))
|
||||
? XO("Your current preference is set to copy in.\n\n")
|
||||
: XO("Your current preference is set to read directly.\n\n")
|
||||
;
|
||||
|
||||
auto clause3 = XO(
|
||||
"Reading the files directly allows you to play or edit them almost immediately. "
|
||||
"This is less safe than copying in, because you must retain the files with their "
|
||||
"original names in their original locations.\n"
|
||||
"Help > Diagnostics > Check Dependencies will show the original names and locations of any files "
|
||||
"that you are reading directly.\n\n"
|
||||
"How do you want to import the current file(s)?"
|
||||
);
|
||||
|
||||
ShuttleGui S{ &dialog, eIsCreating };
|
||||
S.SetBorder(10);
|
||||
S
|
||||
.Position( wxALL | wxEXPAND )
|
||||
.AddUnits( clause1 + clause2 + clause3, 500);
|
||||
|
||||
wxRadioButton *aliasRadio;
|
||||
wxRadioButton *copyRadio;
|
||||
wxCheckBox *dontAskNextTimeBox;
|
||||
|
||||
S.StartStatic(XO("Choose an import method"));
|
||||
{
|
||||
S.SetBorder(0);
|
||||
|
||||
copyRadio = S.AddRadioButton(
|
||||
XXO("Make a © of the files before editing (safer)") );
|
||||
|
||||
aliasRadio = S.AddRadioButtonToGroup(
|
||||
XXO("Read the files &directly from the original (faster)") );
|
||||
|
||||
dontAskNextTimeBox = S.AddCheckBox(
|
||||
XXO("Don't &warn again and always use my choice above"),
|
||||
false);
|
||||
}
|
||||
S.EndStatic();
|
||||
|
||||
dontAskNextTimeBox->SetName(wxStripMenuCodes(dontAskNextTimeBox->GetLabel()));
|
||||
|
||||
|
||||
wxRadioButton *prefsRadio = oldCopyPref == wxT("copy") ? copyRadio : aliasRadio;
|
||||
prefsRadio->SetValue(true);
|
||||
|
||||
S.SetBorder( 10 );
|
||||
S.AddStandardButtons( eOkButton | eCancelButton );
|
||||
|
||||
dialog.SetSize(dialog.GetBestSize());
|
||||
dialog.Layout();
|
||||
dialog.Center();
|
||||
|
||||
if (dialog.ShowModal() == wxID_OK) {
|
||||
if (aliasRadio->GetValue()) {
|
||||
newCopyPref = wxT("edit");
|
||||
}
|
||||
if (dontAskNextTimeBox->IsChecked()) {
|
||||
gPrefs->Write(wxT("/Warnings/CopyOrEditUncompressedDataAsk"), (long) false);
|
||||
gPrefs->Flush();
|
||||
}
|
||||
} else {
|
||||
return wxT("cancel");
|
||||
}
|
||||
|
||||
// if the preference changed, save it.
|
||||
if (newCopyPref != oldCopyPref) {
|
||||
FileFormatsCopyOrEditSetting.Write( newCopyPref );
|
||||
gPrefs->Flush();
|
||||
}
|
||||
oldCopyPref = newCopyPref;
|
||||
}
|
||||
return oldCopyPref;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_LIBID3TAG
|
||||
struct id3_tag_deleter {
|
||||
void operator () (id3_tag *p) const { if (p) id3_tag_delete(p); }
|
||||
@@ -414,20 +298,6 @@ ProgressResult PCMImportFileHandle::Import(TrackFactory *trackFactory,
|
||||
|
||||
wxASSERT(mFile.get());
|
||||
|
||||
#ifdef EXPERIMENTAL_OD_DATA
|
||||
// Get the preference / warn the user about aliased files.
|
||||
wxString copyEdit = AskCopyOrEdit();
|
||||
|
||||
if (copyEdit == wxT("cancel"))
|
||||
return ProgressResult::Cancelled;
|
||||
|
||||
// Fall back to "copy" if it doesn't match anything else, since it is safer
|
||||
bool doEdit = false;
|
||||
if (copyEdit.IsSameAs(wxT("edit"), false))
|
||||
doEdit = true;
|
||||
#endif
|
||||
|
||||
|
||||
CreateProgress();
|
||||
|
||||
NewChannelGroup channels(mInfo.channels);
|
||||
@@ -444,82 +314,6 @@ ProgressResult PCMImportFileHandle::Import(TrackFactory *trackFactory,
|
||||
auto maxBlockSize = channels.begin()->get()->GetMaxBlockSize();
|
||||
auto updateResult = ProgressResult::Cancelled;
|
||||
|
||||
#ifdef EXPERIMENTAL_OD_DATA
|
||||
// If the format is not seekable, we must use 'copy' mode,
|
||||
// because 'edit' mode depends on the ability to seek to an
|
||||
// arbitrary location in the file.
|
||||
if (!mInfo.seekable)
|
||||
doEdit = false;
|
||||
|
||||
if (doEdit) {
|
||||
// If this mode has been selected, we form the tracks as
|
||||
// aliases to the files we're editing, i.e. ("foo.wav", 12000-18000)
|
||||
// instead of actually making fresh copies of the samples.
|
||||
|
||||
// lets use OD only if the file is longer than 30 seconds. Otherwise, why wake up extra threads.
|
||||
//todo: make this a user pref.
|
||||
bool useOD =fileTotalFrames>kMinimumODFileSampleSize;
|
||||
int updateCounter = 0;
|
||||
|
||||
for (decltype(fileTotalFrames) i = 0; i < fileTotalFrames; i += maxBlockSize) {
|
||||
|
||||
const auto blockLen =
|
||||
limitSampleBufferSize( maxBlockSize, fileTotalFrames - i );
|
||||
|
||||
auto iter = channels.begin();
|
||||
for (int c = 0; c < mInfo.channels; ++iter, ++c)
|
||||
iter->get()->RightmostOrNewClip()->AppendBlockFile(
|
||||
[&]( wxFileNameWrapper filePath, size_t len ) {
|
||||
return useOD
|
||||
? make_blockfile<ODPCMAliasBlockFile>(
|
||||
std::move(filePath), wxFileNameWrapper{ mFilename },
|
||||
i, len, c)
|
||||
: make_blockfile<PCMAliasBlockFile>(
|
||||
std::move(filePath), wxFileNameWrapper{ mFilename },
|
||||
i, len, c);
|
||||
},
|
||||
blockLen
|
||||
);
|
||||
|
||||
if (++updateCounter == 50) {
|
||||
updateResult = mProgress->Update(
|
||||
i.as_long_long(),
|
||||
fileTotalFrames.as_long_long()
|
||||
);
|
||||
updateCounter = 0;
|
||||
if (updateResult != ProgressResult::Success)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// One last update for completion
|
||||
updateResult = mProgress->Update(
|
||||
fileTotalFrames.as_long_long(),
|
||||
fileTotalFrames.as_long_long()
|
||||
);
|
||||
|
||||
if(useOD)
|
||||
{
|
||||
auto computeTask = std::make_unique<ODComputeSummaryTask>();
|
||||
bool moreThanStereo = mInfo.channels>2;
|
||||
for (const auto &channel : channels)
|
||||
{
|
||||
computeTask->AddWaveTrack(channel);
|
||||
if(moreThanStereo)
|
||||
{
|
||||
//if we have 3 more channels, they get imported on separate tracks, so we add individual tasks for each.
|
||||
ODManager::Instance()->AddNewTask(std::move(computeTask));
|
||||
computeTask = std::make_unique<ODComputeSummaryTask>();
|
||||
}
|
||||
}
|
||||
//if we have a linked track, we add ONE task.
|
||||
if(!moreThanStereo)
|
||||
ODManager::Instance()->AddNewTask(std::move(computeTask));
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
{
|
||||
// Otherwise, we're in the "copy" mode, where we read in the actual
|
||||
// samples from the file and store our own local copy of the
|
||||
|
Reference in New Issue
Block a user