1
0
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:
Leland Lucius
2020-06-21 18:21:43 -05:00
parent 2fbfd3e0a5
commit cbf1bb558e
46 changed files with 58 additions and 1183 deletions

View File

@@ -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)

View File

@@ -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 */

View File

@@ -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 &copy 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