mirror of
https://github.com/cookiengineer/audacity
synced 2025-07-19 14:17:41 +02:00
Complete the exception handling project, enable the throws
This commit is contained in:
commit
d417acd5c6
@ -616,8 +616,7 @@ size_t BlockFile::CommonReadData(
|
|||||||
|
|
||||||
if ( framesRead < len ) {
|
if ( framesRead < len ) {
|
||||||
if (mayThrow)
|
if (mayThrow)
|
||||||
//throw FileException{ FileException::Cause::Read, fileName }
|
throw FileException{ FileException::Cause::Read, fileName };
|
||||||
;
|
|
||||||
ClearSamples(data, format, framesRead, len - framesRead);
|
ClearSamples(data, format, framesRead, len - framesRead);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,6 +90,7 @@
|
|||||||
#include "AudacityApp.h"
|
#include "AudacityApp.h"
|
||||||
#include "AudacityException.h"
|
#include "AudacityException.h"
|
||||||
#include "BlockFile.h"
|
#include "BlockFile.h"
|
||||||
|
#include "FileException.h"
|
||||||
#include "blockfile/LegacyBlockFile.h"
|
#include "blockfile/LegacyBlockFile.h"
|
||||||
#include "blockfile/LegacyAliasBlockFile.h"
|
#include "blockfile/LegacyAliasBlockFile.h"
|
||||||
#include "blockfile/SimpleBlockFile.h"
|
#include "blockfile/SimpleBlockFile.h"
|
||||||
@ -97,6 +98,7 @@
|
|||||||
#include "blockfile/PCMAliasBlockFile.h"
|
#include "blockfile/PCMAliasBlockFile.h"
|
||||||
#include "blockfile/ODPCMAliasBlockFile.h"
|
#include "blockfile/ODPCMAliasBlockFile.h"
|
||||||
#include "blockfile/ODDecodeBlockFile.h"
|
#include "blockfile/ODDecodeBlockFile.h"
|
||||||
|
#include "InconsistencyException.h"
|
||||||
#include "Internat.h"
|
#include "Internat.h"
|
||||||
#include "Project.h"
|
#include "Project.h"
|
||||||
#include "Prefs.h"
|
#include "Prefs.h"
|
||||||
@ -1110,8 +1112,12 @@ bool DirManager::ContainsBlockFile(const wxString &filepath) const
|
|||||||
// Adds one to the reference count of the block file,
|
// Adds one to the reference count of the block file,
|
||||||
// UNLESS it is "locked", then it makes a NEW copy of
|
// UNLESS it is "locked", then it makes a NEW copy of
|
||||||
// the BlockFile.
|
// the BlockFile.
|
||||||
|
// This function returns non-NULL, or else throws
|
||||||
BlockFilePtr DirManager::CopyBlockFile(const BlockFilePtr &b)
|
BlockFilePtr DirManager::CopyBlockFile(const BlockFilePtr &b)
|
||||||
{
|
{
|
||||||
|
if (!b)
|
||||||
|
THROW_INCONSISTENCY_EXCEPTION;
|
||||||
|
|
||||||
auto result = b->GetFileName();
|
auto result = b->GetFileName();
|
||||||
const auto &fn = result.name;
|
const auto &fn = result.name;
|
||||||
|
|
||||||
@ -1122,7 +1128,7 @@ BlockFilePtr DirManager::CopyBlockFile(const BlockFilePtr &b)
|
|||||||
//
|
//
|
||||||
// LLL: Except for silent block files which have uninitialized filename.
|
// LLL: Except for silent block files which have uninitialized filename.
|
||||||
if (fn.IsOk())
|
if (fn.IsOk())
|
||||||
mBlockFileHash[fn.GetName()]=b;
|
mBlockFileHash[fn.GetName()] = b;
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1148,7 +1154,9 @@ BlockFilePtr DirManager::CopyBlockFile(const BlockFilePtr &b)
|
|||||||
{
|
{
|
||||||
if( !wxCopyFile(fn.GetFullPath(),
|
if( !wxCopyFile(fn.GetFullPath(),
|
||||||
newFile.GetFullPath()) )
|
newFile.GetFullPath()) )
|
||||||
return {};
|
// Disk space exhaustion, maybe
|
||||||
|
throw FileException{
|
||||||
|
FileException::Cause::Write, newFile };
|
||||||
}
|
}
|
||||||
|
|
||||||
// Done with fn
|
// Done with fn
|
||||||
@ -1156,13 +1164,13 @@ BlockFilePtr DirManager::CopyBlockFile(const BlockFilePtr &b)
|
|||||||
|
|
||||||
b2 = b->Copy(std::move(newFile));
|
b2 = b->Copy(std::move(newFile));
|
||||||
|
|
||||||
if (b2 == NULL)
|
mBlockFileHash[newName] = b2;
|
||||||
return {};
|
|
||||||
|
|
||||||
mBlockFileHash[newName]=b2;
|
|
||||||
aliasList.Add(newPath);
|
aliasList.Add(newPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!b2)
|
||||||
|
THROW_INCONSISTENCY_EXCEPTION;
|
||||||
|
|
||||||
return b2;
|
return b2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,6 +95,8 @@ class PROFILE_DLL_API DirManager final : public XMLTagHandler {
|
|||||||
// Adds one to the reference count of the block file,
|
// Adds one to the reference count of the block file,
|
||||||
// UNLESS it is "locked", then it makes a NEW copy of
|
// UNLESS it is "locked", then it makes a NEW copy of
|
||||||
// the BlockFile.
|
// the BlockFile.
|
||||||
|
// May throw an exception in case of disk space exhaustion, otherwise
|
||||||
|
// returns non-null.
|
||||||
BlockFilePtr CopyBlockFile(const BlockFilePtr &b);
|
BlockFilePtr CopyBlockFile(const BlockFilePtr &b);
|
||||||
|
|
||||||
BlockFile *LoadBlockFile(const wxChar **attrs, sampleFormat format);
|
BlockFile *LoadBlockFile(const wxChar **attrs, sampleFormat format);
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include "Audacity.h"
|
#include "Audacity.h"
|
||||||
#include "NoteTrack.h"
|
#include "NoteTrack.h"
|
||||||
|
#include "Experimental.h"
|
||||||
|
|
||||||
#include <wx/dc.h>
|
#include <wx/dc.h>
|
||||||
#include <wx/brush.h>
|
#include <wx/brush.h>
|
||||||
@ -33,7 +34,7 @@
|
|||||||
#include "Prefs.h"
|
#include "Prefs.h"
|
||||||
#include "effects/TimeWarper.h"
|
#include "effects/TimeWarper.h"
|
||||||
|
|
||||||
#include "Experimental.h"
|
#include "InconsistencyException.h"
|
||||||
|
|
||||||
#ifdef SONIFY
|
#ifdef SONIFY
|
||||||
#include "portmidi.h"
|
#include "portmidi.h"
|
||||||
@ -435,8 +436,8 @@ int NoteTrack::GetVisibleChannels()
|
|||||||
Track::Holder NoteTrack::Cut(double t0, double t1)
|
Track::Holder NoteTrack::Cut(double t0, double t1)
|
||||||
{
|
{
|
||||||
if (t1 <= t0)
|
if (t1 <= t0)
|
||||||
//THROW_INCONSISTENCY_EXCEPTION
|
THROW_INCONSISTENCY_EXCEPTION;
|
||||||
;
|
|
||||||
double len = t1-t0;
|
double len = t1-t0;
|
||||||
|
|
||||||
auto newTrack = std::make_unique<NoteTrack>(mDirManager);
|
auto newTrack = std::make_unique<NoteTrack>(mDirManager);
|
||||||
@ -458,8 +459,8 @@ Track::Holder NoteTrack::Cut(double t0, double t1)
|
|||||||
Track::Holder NoteTrack::Copy(double t0, double t1, bool) const
|
Track::Holder NoteTrack::Copy(double t0, double t1, bool) const
|
||||||
{
|
{
|
||||||
if (t1 <= t0)
|
if (t1 <= t0)
|
||||||
//THROW_INCONSISTENCY_EXCEPTION
|
THROW_INCONSISTENCY_EXCEPTION;
|
||||||
;
|
|
||||||
double len = t1-t0;
|
double len = t1-t0;
|
||||||
|
|
||||||
auto newTrack = std::make_unique<NoteTrack>(mDirManager);
|
auto newTrack = std::make_unique<NoteTrack>(mDirManager);
|
||||||
@ -494,10 +495,9 @@ bool NoteTrack::Trim(double t0, double t1)
|
|||||||
|
|
||||||
void NoteTrack::Clear(double t0, double t1)
|
void NoteTrack::Clear(double t0, double t1)
|
||||||
{
|
{
|
||||||
// If t1 = t0, should Clear return true?
|
|
||||||
if (t1 <= t0)
|
if (t1 <= t0)
|
||||||
// THROW_INCONSISTENCY_EXCEPTION; ?
|
THROW_INCONSISTENCY_EXCEPTION;
|
||||||
return;
|
|
||||||
double len = t1-t0;
|
double len = t1-t0;
|
||||||
|
|
||||||
if (mSeq)
|
if (mSeq)
|
||||||
|
@ -441,8 +441,7 @@ void Sequence::Paste(sampleCount s, const Sequence *src)
|
|||||||
// PRL: Why bother with Internat when the above is just wxT?
|
// PRL: Why bother with Internat when the above is just wxT?
|
||||||
Internat::ToString(s.as_double(), 0).c_str(),
|
Internat::ToString(s.as_double(), 0).c_str(),
|
||||||
Internat::ToString(mNumSamples.as_double(), 0).c_str());
|
Internat::ToString(mNumSamples.as_double(), 0).c_str());
|
||||||
//THROW_INCONSISTENCY_EXCEPTION
|
THROW_INCONSISTENCY_EXCEPTION;
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Quick check to make sure that it doesn't overflow
|
// Quick check to make sure that it doesn't overflow
|
||||||
@ -453,8 +452,7 @@ void Sequence::Paste(sampleCount s, const Sequence *src)
|
|||||||
// PRL: Why bother with Internat when the above is just wxT?
|
// PRL: Why bother with Internat when the above is just wxT?
|
||||||
Internat::ToString(mNumSamples.as_double(), 0).c_str(),
|
Internat::ToString(mNumSamples.as_double(), 0).c_str(),
|
||||||
Internat::ToString(src->mNumSamples.as_double(), 0).c_str());
|
Internat::ToString(src->mNumSamples.as_double(), 0).c_str());
|
||||||
//THROW_INCONSISTENCY_EXCEPTION
|
THROW_INCONSISTENCY_EXCEPTION;
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (src->mSampleFormat != mSampleFormat)
|
if (src->mSampleFormat != mSampleFormat)
|
||||||
@ -462,8 +460,7 @@ void Sequence::Paste(sampleCount s, const Sequence *src)
|
|||||||
wxLogError(
|
wxLogError(
|
||||||
wxT("Sequence::Paste: Sample format to be pasted, %s, does not match destination format, %s."),
|
wxT("Sequence::Paste: Sample format to be pasted, %s, does not match destination format, %s."),
|
||||||
GetSampleFormatStr(src->mSampleFormat), GetSampleFormatStr(src->mSampleFormat));
|
GetSampleFormatStr(src->mSampleFormat), GetSampleFormatStr(src->mSampleFormat));
|
||||||
//THROW_INCONSISTENCY_EXCEPTION
|
THROW_INCONSISTENCY_EXCEPTION;
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const BlockArray &srcBlock = src->mBlock;
|
const BlockArray &srcBlock = src->mBlock;
|
||||||
@ -607,11 +604,7 @@ void Sequence::Paste(sampleCount s, const Sequence *src)
|
|||||||
for (i = 2; i < srcNumBlocks - 2; i++) {
|
for (i = 2; i < srcNumBlocks - 2; i++) {
|
||||||
const SeqBlock &block = srcBlock[i];
|
const SeqBlock &block = srcBlock[i];
|
||||||
auto file = mDirManager->CopyBlockFile(block.f);
|
auto file = mDirManager->CopyBlockFile(block.f);
|
||||||
if (!file) {
|
// We can assume file is not null
|
||||||
wxASSERT(false); // TODO: Handle this better, alert the user of failure.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
newBlock.push_back(SeqBlock(file, block.start + s));
|
newBlock.push_back(SeqBlock(file, block.start + s));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -645,8 +638,7 @@ void Sequence::InsertSilence(sampleCount s0, sampleCount len)
|
|||||||
{
|
{
|
||||||
// Quick check to make sure that it doesn't overflow
|
// Quick check to make sure that it doesn't overflow
|
||||||
if (Overflows((mNumSamples.as_double()) + (len.as_double())))
|
if (Overflows((mNumSamples.as_double()) + (len.as_double())))
|
||||||
//THROW_INCONSISTENCY_EXCEPTION
|
THROW_INCONSISTENCY_EXCEPTION;
|
||||||
;
|
|
||||||
|
|
||||||
if (len <= 0)
|
if (len <= 0)
|
||||||
return;
|
return;
|
||||||
@ -696,8 +688,7 @@ void Sequence::AppendAlias(const wxString &fullPath,
|
|||||||
{
|
{
|
||||||
// Quick check to make sure that it doesn't overflow
|
// Quick check to make sure that it doesn't overflow
|
||||||
if (Overflows((mNumSamples.as_double()) + ((double)len)))
|
if (Overflows((mNumSamples.as_double()) + ((double)len)))
|
||||||
//THROW_INCONSISTENCY_EXCEPTION
|
THROW_INCONSISTENCY_EXCEPTION;
|
||||||
;
|
|
||||||
|
|
||||||
SeqBlock newBlock(
|
SeqBlock newBlock(
|
||||||
useOD?
|
useOD?
|
||||||
@ -715,8 +706,7 @@ void Sequence::AppendCoded(const wxString &fName, sampleCount start,
|
|||||||
{
|
{
|
||||||
// Quick check to make sure that it doesn't overflow
|
// Quick check to make sure that it doesn't overflow
|
||||||
if (Overflows((mNumSamples.as_double()) + ((double)len)))
|
if (Overflows((mNumSamples.as_double()) + ((double)len)))
|
||||||
//THROW_INCONSISTENCY_EXCEPTION
|
THROW_INCONSISTENCY_EXCEPTION;
|
||||||
;
|
|
||||||
|
|
||||||
SeqBlock newBlock(
|
SeqBlock newBlock(
|
||||||
mDirManager->NewODDecodeBlockFile(fName, start, len, channel, decodeType),
|
mDirManager->NewODDecodeBlockFile(fName, start, len, channel, decodeType),
|
||||||
@ -732,19 +722,13 @@ void Sequence::AppendBlock
|
|||||||
{
|
{
|
||||||
// Quick check to make sure that it doesn't overflow
|
// Quick check to make sure that it doesn't overflow
|
||||||
if (Overflows((mNumSamples.as_double()) + ((double)b.f->GetLength())))
|
if (Overflows((mNumSamples.as_double()) + ((double)b.f->GetLength())))
|
||||||
// THROW_INCONSISTENCY_EXCEPTION
|
THROW_INCONSISTENCY_EXCEPTION;
|
||||||
return
|
|
||||||
;
|
|
||||||
|
|
||||||
SeqBlock newBlock(
|
SeqBlock newBlock(
|
||||||
mDirManager.CopyBlockFile(b.f), // Bump ref count if not locked, else copy
|
mDirManager.CopyBlockFile(b.f), // Bump ref count if not locked, else copy
|
||||||
mNumSamples
|
mNumSamples
|
||||||
);
|
);
|
||||||
if (!newBlock.f) {
|
// We can assume newBlock.f is not null
|
||||||
/// \todo Error Could not paste! (Out of disk space?)
|
|
||||||
wxASSERT(false); // TODO: Handle this better, alert the user of failure.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mBlock.push_back(newBlock);
|
mBlock.push_back(newBlock);
|
||||||
mNumSamples += newBlock.f->GetLength();
|
mNumSamples += newBlock.f->GetLength();
|
||||||
@ -1137,8 +1121,7 @@ bool Sequence::Get(samplePtr buffer, sampleFormat format,
|
|||||||
if (start < 0 || start > mNumSamples ||
|
if (start < 0 || start > mNumSamples ||
|
||||||
start + len > mNumSamples) {
|
start + len > mNumSamples) {
|
||||||
if (mayThrow)
|
if (mayThrow)
|
||||||
//THROW_INCONSISTENCY_EXCEPTION
|
THROW_INCONSISTENCY_EXCEPTION;
|
||||||
;
|
|
||||||
ClearSamples( buffer, floatSample, 0, len );
|
ClearSamples( buffer, floatSample, 0, len );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1176,8 +1159,7 @@ void Sequence::SetSamples(samplePtr buffer, sampleFormat format,
|
|||||||
{
|
{
|
||||||
if (start < 0 || start >= mNumSamples ||
|
if (start < 0 || start >= mNumSamples ||
|
||||||
start + len > mNumSamples)
|
start + len > mNumSamples)
|
||||||
//THROW_INCONSISTENCY_EXCEPTION
|
THROW_INCONSISTENCY_EXCEPTION;
|
||||||
;
|
|
||||||
|
|
||||||
SampleBuffer scratch(mMaxSamples, mSampleFormat);
|
SampleBuffer scratch(mMaxSamples, mSampleFormat);
|
||||||
|
|
||||||
@ -1213,9 +1195,7 @@ void Sequence::SetSamples(samplePtr buffer, sampleFormat format,
|
|||||||
|
|
||||||
if (!(fileLength <= mMaxSamples &&
|
if (!(fileLength <= mMaxSamples &&
|
||||||
bstart + blen <= fileLength))
|
bstart + blen <= fileLength))
|
||||||
//THROW_INCONSISTENCY_EXCEPTION
|
THROW_INCONSISTENCY_EXCEPTION;
|
||||||
wxASSERT(false)
|
|
||||||
;
|
|
||||||
|
|
||||||
if ( bstart > 0 || blen < fileLength ) {
|
if ( bstart > 0 || blen < fileLength ) {
|
||||||
Read(scratch.ptr(), mSampleFormat, block, 0, fileLength, true);
|
Read(scratch.ptr(), mSampleFormat, block, 0, fileLength, true);
|
||||||
@ -1527,8 +1507,7 @@ void Sequence::Append(samplePtr buffer, sampleFormat format,
|
|||||||
|
|
||||||
// Quick check to make sure that it doesn't overflow
|
// Quick check to make sure that it doesn't overflow
|
||||||
if (Overflows(mNumSamples.as_double() + ((double)len)))
|
if (Overflows(mNumSamples.as_double() + ((double)len)))
|
||||||
//THROW_INCONSISTENCY_EXCEPTION
|
THROW_INCONSISTENCY_EXCEPTION;
|
||||||
;
|
|
||||||
|
|
||||||
BlockArray newBlock;
|
BlockArray newBlock;
|
||||||
sampleCount newNumSamples = mNumSamples;
|
sampleCount newNumSamples = mNumSamples;
|
||||||
@ -1644,8 +1623,7 @@ void Sequence::Delete(sampleCount start, sampleCount len)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (len < 0 || start < 0 || start >= mNumSamples)
|
if (len < 0 || start < 0 || start >= mNumSamples)
|
||||||
//THROW_INCONSISTENCY_EXCEPTION
|
THROW_INCONSISTENCY_EXCEPTION;
|
||||||
;
|
|
||||||
|
|
||||||
//TODO: add a ref-deref mechanism to SeqBlock/BlockArray so we don't have to make this a critical section.
|
//TODO: add a ref-deref mechanism to SeqBlock/BlockArray so we don't have to make this a critical section.
|
||||||
//On-demand threads iterate over the mBlocks and the GUI thread deletes them, so for now put a mutex here over
|
//On-demand threads iterate over the mBlocks and the GUI thread deletes them, so for now put a mutex here over
|
||||||
@ -1858,8 +1836,7 @@ void Sequence::ConsistencyCheck
|
|||||||
wxT("Undo the failed operation(s), then export or save your work and quit."));
|
wxT("Undo the failed operation(s), then export or save your work and quit."));
|
||||||
|
|
||||||
if (mayThrow)
|
if (mayThrow)
|
||||||
//throw ex
|
throw ex;
|
||||||
;
|
|
||||||
else
|
else
|
||||||
wxASSERT(false);
|
wxASSERT(false);
|
||||||
}
|
}
|
||||||
|
@ -103,6 +103,7 @@ class PROFILE_DLL_API Sequence final : public XMLTagHandler{
|
|||||||
bool GetWaveDisplay(float *min, float *max, float *rms, int* bl,
|
bool GetWaveDisplay(float *min, float *max, float *rms, int* bl,
|
||||||
size_t len, const sampleCount *where) const;
|
size_t len, const sampleCount *where) const;
|
||||||
|
|
||||||
|
// Return non-null, or else throw!
|
||||||
std::unique_ptr<Sequence> Copy(sampleCount s0, sampleCount s1) const;
|
std::unique_ptr<Sequence> Copy(sampleCount s0, sampleCount s1) const;
|
||||||
void Paste(sampleCount s0, const Sequence *src);
|
void Paste(sampleCount s0, const Sequence *src);
|
||||||
|
|
||||||
|
@ -1298,8 +1298,7 @@ std::pair<float, float> WaveClip::GetMinMax(
|
|||||||
{
|
{
|
||||||
if (t0 > t1) {
|
if (t0 > t1) {
|
||||||
if (mayThrow)
|
if (mayThrow)
|
||||||
//THROW_INCONSISTENCY_EXCEPTION
|
THROW_INCONSISTENCY_EXCEPTION;
|
||||||
;
|
|
||||||
return {
|
return {
|
||||||
0.f, // harmless, but unused since Sequence::GetMinMax does not use these values
|
0.f, // harmless, but unused since Sequence::GetMinMax does not use these values
|
||||||
0.f // harmless, but unused since Sequence::GetMinMax does not use these values
|
0.f // harmless, but unused since Sequence::GetMinMax does not use these values
|
||||||
@ -1321,8 +1320,7 @@ float WaveClip::GetRMS(double t0, double t1, bool mayThrow) const
|
|||||||
{
|
{
|
||||||
if (t0 > t1) {
|
if (t0 > t1) {
|
||||||
if (mayThrow)
|
if (mayThrow)
|
||||||
//THROW_INCONSISTENCY_EXCEPTION
|
THROW_INCONSISTENCY_EXCEPTION;
|
||||||
;
|
|
||||||
return 0.f;
|
return 0.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1783,10 +1781,8 @@ void WaveClip::ExpandCutLine(double cutLinePosition)
|
|||||||
[=](const WaveClipHolder &p) { return p.get() == cutline; });
|
[=](const WaveClipHolder &p) { return p.get() == cutline; });
|
||||||
if (it != end)
|
if (it != end)
|
||||||
mCutLines.erase(it); // deletes cutline!
|
mCutLines.erase(it); // deletes cutline!
|
||||||
else {
|
else
|
||||||
// THROW_INCONSISTENCY_EXCEPTION;
|
THROW_INCONSISTENCY_EXCEPTION;
|
||||||
wxASSERT(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1906,13 +1902,14 @@ void WaveClip::Resample(int rate, ProgressDialog *progress)
|
|||||||
);
|
);
|
||||||
error = (updateResult != ProgressResult::Success);
|
error = (updateResult != ProgressResult::Success);
|
||||||
if (error)
|
if (error)
|
||||||
break;
|
throw UserException{};
|
||||||
//throw UserException{};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
;
|
throw SimpleMessageBoxException{
|
||||||
|
_("Resampling failed.")
|
||||||
|
};
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Use NOFAIL-GUARANTEE in these steps
|
// Use NOFAIL-GUARANTEE in these steps
|
||||||
|
@ -555,8 +555,7 @@ bool WaveTrack::IsEmpty(double t0, double t1) const
|
|||||||
Track::Holder WaveTrack::Cut(double t0, double t1)
|
Track::Holder WaveTrack::Cut(double t0, double t1)
|
||||||
{
|
{
|
||||||
if (t1 < t0)
|
if (t1 < t0)
|
||||||
// THROW_INCONSISTENCY_EXCEPTION
|
THROW_INCONSISTENCY_EXCEPTION;
|
||||||
;
|
|
||||||
|
|
||||||
auto tmp = Copy(t0, t1);
|
auto tmp = Copy(t0, t1);
|
||||||
|
|
||||||
@ -569,8 +568,7 @@ Track::Holder WaveTrack::SplitCut(double t0, double t1)
|
|||||||
// STRONG-GUARANTEE
|
// STRONG-GUARANTEE
|
||||||
{
|
{
|
||||||
if (t1 < t0)
|
if (t1 < t0)
|
||||||
//THROW_INCONSISTENCY_EXCEPTION
|
THROW_INCONSISTENCY_EXCEPTION;
|
||||||
;
|
|
||||||
|
|
||||||
// SplitCut is the same as 'Copy', then 'SplitDelete'
|
// SplitCut is the same as 'Copy', then 'SplitDelete'
|
||||||
auto tmp = Copy(t0, t1);
|
auto tmp = Copy(t0, t1);
|
||||||
@ -584,15 +582,12 @@ Track::Holder WaveTrack::SplitCut(double t0, double t1)
|
|||||||
Track::Holder WaveTrack::CutAndAddCutLine(double t0, double t1)
|
Track::Holder WaveTrack::CutAndAddCutLine(double t0, double t1)
|
||||||
{
|
{
|
||||||
if (t1 < t0)
|
if (t1 < t0)
|
||||||
//THROW_INCONSISTENCY_EXCEPTION
|
THROW_INCONSISTENCY_EXCEPTION;
|
||||||
;
|
|
||||||
|
|
||||||
// Cut is the same as 'Copy', then 'Delete'
|
// Cut is the same as 'Copy', then 'Delete'
|
||||||
auto tmp = Copy(t0, t1);
|
auto tmp = Copy(t0, t1);
|
||||||
|
|
||||||
if (!ClearAndAddCutLine(t0, t1))
|
ClearAndAddCutLine(t0, t1);
|
||||||
//THROW_INCONSISTENCY_EXCEPTION
|
|
||||||
;
|
|
||||||
|
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
@ -648,8 +643,7 @@ void WaveTrack::Trim (double t0, double t1)
|
|||||||
Track::Holder WaveTrack::Copy(double t0, double t1, bool forClipboard) const
|
Track::Holder WaveTrack::Copy(double t0, double t1, bool forClipboard) const
|
||||||
{
|
{
|
||||||
if (t1 <= t0)
|
if (t1 <= t0)
|
||||||
//THROW_INCONSISTENCY_EXCEPTION
|
THROW_INCONSISTENCY_EXCEPTION;
|
||||||
;
|
|
||||||
|
|
||||||
WaveTrack *newTrack;
|
WaveTrack *newTrack;
|
||||||
Track::Holder result
|
Track::Holder result
|
||||||
@ -1038,8 +1032,7 @@ void WaveTrack::HandleClear(double t0, double t1,
|
|||||||
// STRONG-GUARANTEE
|
// STRONG-GUARANTEE
|
||||||
{
|
{
|
||||||
if (t1 < t0)
|
if (t1 < t0)
|
||||||
// THROW_INCONSISTENCY_EXCEPTION; // ?
|
THROW_INCONSISTENCY_EXCEPTION;
|
||||||
return;
|
|
||||||
|
|
||||||
bool editClipCanMove = true;
|
bool editClipCanMove = true;
|
||||||
gPrefs->Read(wxT("/GUI/EditClipCanMove"), &editClipCanMove);
|
gPrefs->Read(wxT("/GUI/EditClipCanMove"), &editClipCanMove);
|
||||||
@ -1221,12 +1214,10 @@ void WaveTrack::SyncLockAdjust(double oldT1, double newT1)
|
|||||||
// follow EditClipCanMove rules (Paste() does it right)
|
// follow EditClipCanMove rules (Paste() does it right)
|
||||||
AudacityProject *p = GetActiveProject();
|
AudacityProject *p = GetActiveProject();
|
||||||
if (!p)
|
if (!p)
|
||||||
// THROW_INCONSISTENCY_EXCEPTION
|
THROW_INCONSISTENCY_EXCEPTION;
|
||||||
;
|
|
||||||
TrackFactory *f = p->GetTrackFactory();
|
TrackFactory *f = p->GetTrackFactory();
|
||||||
if (!f)
|
if (!f)
|
||||||
// THROW_INCONSISTENCY_EXCEPTION
|
THROW_INCONSISTENCY_EXCEPTION;
|
||||||
;
|
|
||||||
auto tmp = f->NewWaveTrack(GetSampleFormat(), GetRate());
|
auto tmp = f->NewWaveTrack(GetSampleFormat(), GetRate());
|
||||||
|
|
||||||
tmp->InsertSilence(0.0, newT1 - oldT1);
|
tmp->InsertSilence(0.0, newT1 - oldT1);
|
||||||
@ -1395,8 +1386,7 @@ void WaveTrack::Paste(double t0, const Track *src)
|
|||||||
void WaveTrack::Silence(double t0, double t1)
|
void WaveTrack::Silence(double t0, double t1)
|
||||||
{
|
{
|
||||||
if (t1 < t0)
|
if (t1 < t0)
|
||||||
// THROW_INCONSISTENCY_EXCEPTION; // ?
|
THROW_INCONSISTENCY_EXCEPTION;
|
||||||
return;
|
|
||||||
|
|
||||||
auto start = (sampleCount)floor(t0 * mRate + 0.5);
|
auto start = (sampleCount)floor(t0 * mRate + 0.5);
|
||||||
auto len = (sampleCount)floor(t1 * mRate + 0.5) - start;
|
auto len = (sampleCount)floor(t1 * mRate + 0.5) - start;
|
||||||
@ -1432,8 +1422,7 @@ void WaveTrack::InsertSilence(double t, double len)
|
|||||||
// STRONG-GUARANTEE
|
// STRONG-GUARANTEE
|
||||||
{
|
{
|
||||||
if (len <= 0)
|
if (len <= 0)
|
||||||
// THROW_INCONSISTENCY_EXCEPTION; // ?
|
THROW_INCONSISTENCY_EXCEPTION;
|
||||||
return;
|
|
||||||
|
|
||||||
if (mClips.empty())
|
if (mClips.empty())
|
||||||
{
|
{
|
||||||
@ -1953,8 +1942,7 @@ std::pair<float, float> WaveTrack::GetMinMax(
|
|||||||
|
|
||||||
if (t0 > t1) {
|
if (t0 > t1) {
|
||||||
if (mayThrow)
|
if (mayThrow)
|
||||||
//THROW_INCONSISTENCY_EXCEPTION
|
THROW_INCONSISTENCY_EXCEPTION;
|
||||||
;
|
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1986,8 +1974,7 @@ float WaveTrack::GetRMS(double t0, double t1, bool mayThrow) const
|
|||||||
{
|
{
|
||||||
if (t0 > t1) {
|
if (t0 > t1) {
|
||||||
if (mayThrow)
|
if (mayThrow)
|
||||||
//THROW_INCONSISTENCY_EXCEPTION
|
THROW_INCONSISTENCY_EXCEPTION;
|
||||||
;
|
|
||||||
return 0.f;
|
return 0.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@ The summary is eventually computed and written to a file in a background thread.
|
|||||||
#include <wx/thread.h>
|
#include <wx/thread.h>
|
||||||
#include <sndfile.h>
|
#include <sndfile.h>
|
||||||
|
|
||||||
|
#include "../FileException.h"
|
||||||
#include "../FileFormats.h"
|
#include "../FileFormats.h"
|
||||||
#include "../Internat.h"
|
#include "../Internat.h"
|
||||||
#include "NotYetAvailableException.h"
|
#include "NotYetAvailableException.h"
|
||||||
@ -38,8 +39,9 @@ char bheaderTag[bheaderTagLen + 1] = "AudacityBlockFile112";
|
|||||||
|
|
||||||
/// Create a disk file and write summary and sample data to it
|
/// Create a disk file and write summary and sample data to it
|
||||||
ODDecodeBlockFile::ODDecodeBlockFile(wxFileNameWrapper &&baseFileName, wxFileNameWrapper &&audioFileName, sampleCount aliasStart,
|
ODDecodeBlockFile::ODDecodeBlockFile(wxFileNameWrapper &&baseFileName, wxFileNameWrapper &&audioFileName, sampleCount aliasStart,
|
||||||
size_t aliasLen, int aliasChannel,unsigned int decodeType):
|
size_t aliasLen, int aliasChannel,unsigned int decodeType)
|
||||||
SimpleBlockFile{ std::move(baseFileName),
|
try
|
||||||
|
: SimpleBlockFile{ std::move(baseFileName),
|
||||||
NULL, aliasLen, floatSample, true, true },
|
NULL, aliasLen, floatSample, true, true },
|
||||||
//floatSample has no effect. last two bools - bypass writing of blockfile and cache
|
//floatSample has no effect. last two bools - bypass writing of blockfile and cache
|
||||||
|
|
||||||
@ -51,6 +53,14 @@ ODDecodeBlockFile::ODDecodeBlockFile(wxFileNameWrapper &&baseFileName, wxFileNam
|
|||||||
mAudioFileName = std::move(audioFileName);
|
mAudioFileName = std::move(audioFileName);
|
||||||
mFormat = int16Sample;
|
mFormat = int16Sample;
|
||||||
}
|
}
|
||||||
|
catch ( const FileException & e )
|
||||||
|
{
|
||||||
|
// The constructor SimpleBlockFile sometimes throws this,
|
||||||
|
// but it never will for the arguments that were passed to it here.
|
||||||
|
// So add a catch for completeness, but just assert that this won't happen.
|
||||||
|
wxASSERT(false);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
/// Create the memory structure to refer to the given block file
|
/// Create the memory structure to refer to the given block file
|
||||||
ODDecodeBlockFile::ODDecodeBlockFile(wxFileNameWrapper &&existingFile, wxFileNameWrapper &&audioFileName, sampleCount aliasStart,
|
ODDecodeBlockFile::ODDecodeBlockFile(wxFileNameWrapper &&existingFile, wxFileNameWrapper &&audioFileName, sampleCount aliasStart,
|
||||||
@ -102,8 +112,7 @@ auto ODDecodeBlockFile::GetMinMaxRMS(
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (mayThrow)
|
if (mayThrow)
|
||||||
// throw NotYetAvailableException{ mAudioFileName }
|
throw NotYetAvailableException{ mAudioFileName };
|
||||||
;
|
|
||||||
|
|
||||||
//fake values. These values are used usually for normalization and amplifying, so we want
|
//fake values. These values are used usually for normalization and amplifying, so we want
|
||||||
//the max to be maximal and the min to be minimal
|
//the max to be maximal and the min to be minimal
|
||||||
@ -123,8 +132,7 @@ auto ODDecodeBlockFile::GetMinMaxRMS(bool mayThrow) const -> MinMaxRMS
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (mayThrow)
|
if (mayThrow)
|
||||||
// throw NotYetAvailableException{ mAudioFileName }
|
throw NotYetAvailableException{ mAudioFileName };
|
||||||
;
|
|
||||||
|
|
||||||
//fake values. These values are used usually for normalization and amplifying, so we want
|
//fake values. These values are used usually for normalization and amplifying, so we want
|
||||||
//the max to be maximal and the min to be minimal
|
//the max to be maximal and the min to be minimal
|
||||||
@ -446,8 +454,7 @@ size_t ODDecodeBlockFile::ReadData(samplePtr data, sampleFormat format,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (mayThrow)
|
if (mayThrow)
|
||||||
//throw NotYetAvailableException{ mFileName }
|
throw NotYetAvailableException{ mAudioFileName };
|
||||||
;
|
|
||||||
|
|
||||||
//we should do an ODRequest to start processing the data here, and wait till it finishes. and just do a SimpleBlockFile
|
//we should do an ODRequest to start processing the data here, and wait till it finishes. and just do a SimpleBlockFile
|
||||||
//ReadData.
|
//ReadData.
|
||||||
|
@ -133,8 +133,7 @@ auto ODPCMAliasBlockFile::GetMinMaxRMS(
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (mayThrow)
|
if (mayThrow)
|
||||||
//throw NotYetAvailableException{ GetAliasedFileName() }
|
throw NotYetAvailableException{ GetAliasedFileName() };
|
||||||
;
|
|
||||||
|
|
||||||
//fake values. These values are used usually for normalization and amplifying, so we want
|
//fake values. These values are used usually for normalization and amplifying, so we want
|
||||||
//the max to be maximal and the min to be minimal
|
//the max to be maximal and the min to be minimal
|
||||||
@ -156,8 +155,7 @@ auto ODPCMAliasBlockFile::GetMinMaxRMS(bool mayThrow) const -> MinMaxRMS
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (mayThrow)
|
if (mayThrow)
|
||||||
//throw NotYetAvailableException{ GetAliasedFileName() }
|
throw NotYetAvailableException{ GetAliasedFileName() };
|
||||||
;
|
|
||||||
|
|
||||||
//fake values. These values are used usually for normalization and amplifying, so we want
|
//fake values. These values are used usually for normalization and amplifying, so we want
|
||||||
//the max to be maximal and the min to be minimal
|
//the max to be maximal and the min to be minimal
|
||||||
@ -415,9 +413,8 @@ void ODPCMAliasBlockFile::WriteSummary()
|
|||||||
//and wxLog calls are not thread safe.
|
//and wxLog calls are not thread safe.
|
||||||
printf("Unable to write summary data to file: %s", fileNameChar.get());
|
printf("Unable to write summary data to file: %s", fileNameChar.get());
|
||||||
|
|
||||||
// throw FileException{
|
throw FileException{
|
||||||
// FileException::Cause::Read, wxFileName{ fileNameChar.get() } };
|
FileException::Cause::Read, wxFileName{ fileNameChar.get() } };
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayOf<char> cleanup;
|
ArrayOf<char> cleanup;
|
||||||
|
@ -57,15 +57,18 @@ to get its definition, rather than rolling our own.
|
|||||||
|
|
||||||
*//*******************************************************************/
|
*//*******************************************************************/
|
||||||
|
|
||||||
|
#include "../Audacity.h"
|
||||||
|
#include "SimpleBlockFile.h"
|
||||||
|
|
||||||
#include <wx/wx.h>
|
#include <wx/wx.h>
|
||||||
#include <wx/filefn.h>
|
#include <wx/filefn.h>
|
||||||
#include <wx/ffile.h>
|
#include <wx/ffile.h>
|
||||||
#include <wx/utils.h>
|
#include <wx/utils.h>
|
||||||
#include <wx/log.h>
|
#include <wx/log.h>
|
||||||
|
|
||||||
|
#include "../FileException.h"
|
||||||
#include "../Prefs.h"
|
#include "../Prefs.h"
|
||||||
|
|
||||||
#include "SimpleBlockFile.h"
|
|
||||||
#include "../FileFormats.h"
|
#include "../FileFormats.h"
|
||||||
|
|
||||||
#include "sndfile.h"
|
#include "sndfile.h"
|
||||||
@ -114,8 +117,9 @@ SimpleBlockFile::SimpleBlockFile(wxFileNameWrapper &&baseFileName,
|
|||||||
if (!(allowDeferredWrite && useCache) && !bypassCache)
|
if (!(allowDeferredWrite && useCache) && !bypassCache)
|
||||||
{
|
{
|
||||||
bool bSuccess = WriteSimpleBlockFile(sampleData, sampleLen, format, NULL);
|
bool bSuccess = WriteSimpleBlockFile(sampleData, sampleLen, format, NULL);
|
||||||
wxASSERT(bSuccess); // TODO: Handle failure here by alert to user and undo partial op.
|
if (!bSuccess)
|
||||||
wxUnusedVar(bSuccess);
|
throw FileException{
|
||||||
|
FileException::Cause::Write, GetFileName().name };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (useCache) {
|
if (useCache) {
|
||||||
@ -404,8 +408,7 @@ size_t SimpleBlockFile::ReadData(samplePtr data, sampleFormat format,
|
|||||||
if ( framesRead < len ) {
|
if ( framesRead < len ) {
|
||||||
if (mayThrow)
|
if (mayThrow)
|
||||||
// Not the best exception class?
|
// Not the best exception class?
|
||||||
//throw FileException{ FileException::Cause::Read, mFileName }
|
throw FileException{ FileException::Cause::Read, mFileName };
|
||||||
;
|
|
||||||
ClearSamples(data, format, framesRead, len - framesRead);
|
ClearSamples(data, format, framesRead, len - framesRead);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,10 +27,12 @@ and sample size to help you importing data of an unknown format.
|
|||||||
#include "Import.h"
|
#include "Import.h"
|
||||||
|
|
||||||
#include "../DirManager.h"
|
#include "../DirManager.h"
|
||||||
|
#include "../FileException.h"
|
||||||
#include "../FileFormats.h"
|
#include "../FileFormats.h"
|
||||||
#include "../Internat.h"
|
#include "../Internat.h"
|
||||||
#include "../Prefs.h"
|
#include "../Prefs.h"
|
||||||
#include "../ShuttleGui.h"
|
#include "../ShuttleGui.h"
|
||||||
|
#include "../UserException.h"
|
||||||
#include "../WaveTrack.h"
|
#include "../WaveTrack.h"
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
@ -92,6 +94,9 @@ class ImportRawDialog final : public wxDialogWrapper {
|
|||||||
DECLARE_EVENT_TABLE()
|
DECLARE_EVENT_TABLE()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 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.
|
||||||
void ImportRaw(wxWindow *parent, const wxString &fileName,
|
void ImportRaw(wxWindow *parent, const wxString &fileName,
|
||||||
TrackFactory *trackFactory, TrackHolders &outTracks)
|
TrackFactory *trackFactory, TrackHolders &outTracks)
|
||||||
{
|
{
|
||||||
@ -158,12 +163,11 @@ void ImportRaw(wxWindow *parent, const wxString &fileName,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!sndFile){
|
if (!sndFile){
|
||||||
// TODO: Handle error
|
|
||||||
char str[1000];
|
char str[1000];
|
||||||
sf_error_str((SNDFILE *)NULL, str, 1000);
|
sf_error_str((SNDFILE *)NULL, str, 1000);
|
||||||
printf("%s\n", str);
|
printf("%s\n", str);
|
||||||
|
|
||||||
return;
|
throw FileException{ FileException::Cause::Open, fileName };
|
||||||
}
|
}
|
||||||
|
|
||||||
result = sf_command(sndFile.get(), SFC_SET_RAW_START_OFFSET, &offset, sizeof(offset));
|
result = sf_command(sndFile.get(), SFC_SET_RAW_START_OFFSET, &offset, sizeof(offset));
|
||||||
@ -171,6 +175,8 @@ void ImportRaw(wxWindow *parent, const wxString &fileName,
|
|||||||
char str[1000];
|
char str[1000];
|
||||||
sf_error_str(sndFile.get(), str, 1000);
|
sf_error_str(sndFile.get(), str, 1000);
|
||||||
printf("%s\n", str);
|
printf("%s\n", str);
|
||||||
|
|
||||||
|
throw FileException{ FileException::Cause::Read, fileName };
|
||||||
}
|
}
|
||||||
|
|
||||||
SFCall<sf_count_t>(sf_seek, sndFile.get(), 0, SEEK_SET);
|
SFCall<sf_count_t>(sf_seek, sndFile.get(), 0, SEEK_SET);
|
||||||
@ -254,9 +260,7 @@ void ImportRaw(wxWindow *parent, const wxString &fileName,
|
|||||||
else {
|
else {
|
||||||
// This is not supposed to happen, sndfile.h says result is always
|
// This is not supposed to happen, sndfile.h says result is always
|
||||||
// a count, not an invalid value for error
|
// a count, not an invalid value for error
|
||||||
wxASSERT(false);
|
throw FileException{ FileException::Cause::Read, fileName };
|
||||||
updateResult = ProgressResult::Failed;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (block) {
|
if (block) {
|
||||||
@ -288,10 +292,8 @@ void ImportRaw(wxWindow *parent, const wxString &fileName,
|
|||||||
} while (block > 0 && framescompleted < totalFrames);
|
} while (block > 0 && framescompleted < totalFrames);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (updateResult == ProgressResult::Failed || updateResult == ProgressResult::Cancelled) {
|
if (updateResult == ProgressResult::Failed || updateResult == ProgressResult::Cancelled)
|
||||||
// It's a shame we can't return proper error code
|
throw UserException{};
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto &channel : channels)
|
for (const auto &channel : channels)
|
||||||
channel->Flush();
|
channel->Flush();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user