mirror of
https://github.com/cookiengineer/audacity
synced 2025-08-07 15:49:42 +02:00
BlockFile::ReadData overrides: on failure, pad with 0s or throw...
... as the mayThrow argument directs.
This commit is contained in:
parent
70d9e4bdc7
commit
98d1468a01
@ -376,7 +376,8 @@ auto BlockFile::GetMinMaxRMS(size_t start, size_t len, bool mayThrow)
|
|||||||
{
|
{
|
||||||
// TODO: actually use summaries
|
// TODO: actually use summaries
|
||||||
SampleBuffer blockData(len, floatSample);
|
SampleBuffer blockData(len, floatSample);
|
||||||
this->ReadData(blockData.ptr(), floatSample, start, len);
|
|
||||||
|
this->ReadData(blockData.ptr(), floatSample, start, len, mayThrow);
|
||||||
|
|
||||||
float min = FLT_MAX;
|
float min = FLT_MAX;
|
||||||
float max = -FLT_MAX;
|
float max = -FLT_MAX;
|
||||||
@ -485,6 +486,7 @@ bool BlockFile::Read64K(float *buffer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t BlockFile::CommonReadData(
|
size_t BlockFile::CommonReadData(
|
||||||
|
bool mayThrow,
|
||||||
const wxFileName &fileName, bool &mSilentLog,
|
const wxFileName &fileName, bool &mSilentLog,
|
||||||
const AliasBlockFile *pAliasFile, sampleCount origin, unsigned channel,
|
const AliasBlockFile *pAliasFile, sampleCount origin, unsigned channel,
|
||||||
samplePtr data, sampleFormat format, size_t start, size_t len,
|
samplePtr data, sampleFormat format, size_t start, size_t len,
|
||||||
@ -534,34 +536,33 @@ size_t BlockFile::CommonReadData(
|
|||||||
// libsndfile can't (under Windows).
|
// libsndfile can't (under Windows).
|
||||||
sf.reset(SFCall<SNDFILE*>(sf_open_fd, f.fd(), SFM_READ, &info, FALSE));
|
sf.reset(SFCall<SNDFILE*>(sf_open_fd, f.fd(), SFM_READ, &info, FALSE));
|
||||||
}
|
}
|
||||||
// FIXME: TRAP_ERR failure of wxFile open incompletely handled in BlockFile::CommonReadData.
|
|
||||||
|
|
||||||
if (!sf) {
|
if (!sf) {
|
||||||
|
|
||||||
memset(data, 0, SAMPLE_SIZE(format)*len);
|
memset(data, 0, SAMPLE_SIZE(format)*len);
|
||||||
|
|
||||||
mSilentLog = TRUE;
|
|
||||||
|
|
||||||
if (pAliasFile) {
|
if (pAliasFile) {
|
||||||
// Set a marker to display an error message for the silence
|
// Set a marker to display an error message for the silence
|
||||||
if (!wxGetApp().ShouldShowMissingAliasedFileWarning())
|
if (!wxGetApp().ShouldShowMissingAliasedFileWarning())
|
||||||
wxGetApp().MarkAliasedFilesMissingWarning(pAliasFile);
|
wxGetApp().MarkAliasedFilesMissingWarning(pAliasFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mSilentLog=FALSE;
|
mSilentLog = !sf;
|
||||||
|
|
||||||
SFCall<sf_count_t>(
|
size_t framesRead = 0;
|
||||||
|
if (sf) {
|
||||||
|
auto seek_result = SFCall<sf_count_t>(
|
||||||
sf_seek, sf.get(), ( origin + start ).as_long_long(), SEEK_SET);
|
sf_seek, sf.get(), ( origin + start ).as_long_long(), SEEK_SET);
|
||||||
|
|
||||||
|
if (seek_result < 0)
|
||||||
|
// error
|
||||||
|
;
|
||||||
|
else {
|
||||||
auto channels = info.channels;
|
auto channels = info.channels;
|
||||||
wxASSERT(channels >= 1);
|
wxASSERT(channels >= 1);
|
||||||
wxASSERT(channel < channels);
|
wxASSERT(channel < channels);
|
||||||
|
|
||||||
size_t framesRead = 0;
|
|
||||||
|
|
||||||
if (channels == 1 &&
|
if (channels == 1 &&
|
||||||
format == int16Sample &&
|
format == int16Sample &&
|
||||||
sf_subtype_is_integer(info.format)) {
|
sf_subtype_is_integer(info.format)) {
|
||||||
@ -573,7 +574,8 @@ size_t BlockFile::CommonReadData(
|
|||||||
else if (channels == 1 &&
|
else if (channels == 1 &&
|
||||||
format == int24Sample &&
|
format == int24Sample &&
|
||||||
sf_subtype_is_integer(info.format)) {
|
sf_subtype_is_integer(info.format)) {
|
||||||
framesRead = SFCall<sf_count_t>(sf_readf_int, sf.get(), (int *)data, len);
|
framesRead = SFCall<sf_count_t>(
|
||||||
|
sf_readf_int, sf.get(), (int *)data, len);
|
||||||
|
|
||||||
// libsndfile gave us the 3 byte sample in the 3 most
|
// libsndfile gave us the 3 byte sample in the 3 most
|
||||||
// significant bytes -- we want it in the 3 least
|
// significant bytes -- we want it in the 3 least
|
||||||
@ -609,6 +611,15 @@ size_t BlockFile::CommonReadData(
|
|||||||
true /* high quality by default */,
|
true /* high quality by default */,
|
||||||
channels /* source stride */);
|
channels /* source stride */);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( framesRead < len ) {
|
||||||
|
if (mayThrow)
|
||||||
|
//throw FileException{ FileException::Cause::Read, fileName }
|
||||||
|
;
|
||||||
|
ClearSamples(data, format, framesRead, len - framesRead);
|
||||||
|
}
|
||||||
|
|
||||||
return framesRead;
|
return framesRead;
|
||||||
}
|
}
|
||||||
|
@ -67,8 +67,12 @@ class PROFILE_DLL_API BlockFile /* not final, abstract */ {
|
|||||||
// Reading
|
// Reading
|
||||||
|
|
||||||
/// Retrieves audio data from this BlockFile
|
/// Retrieves audio data from this BlockFile
|
||||||
|
/// Returns the number of samples really read, not more than len
|
||||||
|
/// If fewer can be read than len, throws an exception if mayThrow is true,
|
||||||
|
/// otherwise fills the remainder of data with zeroes.
|
||||||
virtual size_t ReadData(samplePtr data, sampleFormat format,
|
virtual size_t ReadData(samplePtr data, sampleFormat format,
|
||||||
size_t start, size_t len) const = 0;
|
size_t start, size_t len, bool mayThrow = true)
|
||||||
|
const = 0;
|
||||||
|
|
||||||
// Other Properties
|
// Other Properties
|
||||||
|
|
||||||
@ -223,6 +227,7 @@ class PROFILE_DLL_API BlockFile /* not final, abstract */ {
|
|||||||
virtual void FixSummary(void *data);
|
virtual void FixSummary(void *data);
|
||||||
|
|
||||||
static size_t CommonReadData(
|
static size_t CommonReadData(
|
||||||
|
bool mayThrow,
|
||||||
const wxFileName &fileName, bool &mSilentLog,
|
const wxFileName &fileName, bool &mSilentLog,
|
||||||
const AliasBlockFile *pAliasFile, sampleCount origin, unsigned channel,
|
const AliasBlockFile *pAliasFile, sampleCount origin, unsigned channel,
|
||||||
samplePtr data, sampleFormat format, size_t start, size_t len,
|
samplePtr data, sampleFormat format, size_t start, size_t len,
|
||||||
|
@ -194,10 +194,10 @@ bool LegacyBlockFile::ReadSummary(ArrayOf<char> &data)
|
|||||||
/// @param start The offset in this block file
|
/// @param start The offset in this block file
|
||||||
/// @param len The number of samples to read
|
/// @param len The number of samples to read
|
||||||
size_t LegacyBlockFile::ReadData(samplePtr data, sampleFormat format,
|
size_t LegacyBlockFile::ReadData(samplePtr data, sampleFormat format,
|
||||||
size_t start, size_t len) const
|
size_t start, size_t len, bool mayThrow) const
|
||||||
{
|
{
|
||||||
sf_count_t origin = (mSummaryInfo.totalSummaryBytes / SAMPLE_SIZE(mFormat));
|
sf_count_t origin = (mSummaryInfo.totalSummaryBytes / SAMPLE_SIZE(mFormat));
|
||||||
return CommonReadData(
|
return CommonReadData( mayThrow,
|
||||||
mFileName, mSilentLog, nullptr, origin, 0, data, format, start, len,
|
mFileName, mSilentLog, nullptr, origin, 0, data, format, start, len,
|
||||||
&mFormat, mLen
|
&mFormat, mLen
|
||||||
);
|
);
|
||||||
|
@ -51,7 +51,7 @@ class LegacyBlockFile final : public BlockFile {
|
|||||||
bool ReadSummary(ArrayOf<char> &data) override;
|
bool ReadSummary(ArrayOf<char> &data) override;
|
||||||
/// Read the data section of the disk file
|
/// Read the data section of the disk file
|
||||||
size_t ReadData(samplePtr data, sampleFormat format,
|
size_t ReadData(samplePtr data, sampleFormat format,
|
||||||
size_t start, size_t len) const override;
|
size_t start, size_t len, bool mayThrow) const override;
|
||||||
|
|
||||||
/// Create a NEW block file identical to this one
|
/// Create a NEW block file identical to this one
|
||||||
BlockFilePtr Copy(wxFileNameWrapper &&newFileName) override;
|
BlockFilePtr Copy(wxFileNameWrapper &&newFileName) override;
|
||||||
|
@ -438,20 +438,22 @@ void *ODDecodeBlockFile::CalcSummary(samplePtr buffer, size_t len,
|
|||||||
/// @param start The offset within the block to begin reading
|
/// @param start The offset within the block to begin reading
|
||||||
/// @param len The number of samples to read
|
/// @param len The number of samples to read
|
||||||
size_t ODDecodeBlockFile::ReadData(samplePtr data, sampleFormat format,
|
size_t ODDecodeBlockFile::ReadData(samplePtr data, sampleFormat format,
|
||||||
size_t start, size_t len) const
|
size_t start, size_t len, bool mayThrow) const
|
||||||
{
|
{
|
||||||
size_t ret;
|
|
||||||
auto locker = LockForRead();
|
auto locker = LockForRead();
|
||||||
if(IsSummaryAvailable())
|
if(IsSummaryAvailable())
|
||||||
ret = SimpleBlockFile::ReadData(data,format,start,len);
|
return SimpleBlockFile::ReadData(data, format, start, len, mayThrow);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (mayThrow)
|
||||||
|
//throw NotYetAvailableException{ mFileName }
|
||||||
|
;
|
||||||
|
|
||||||
//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.
|
||||||
ClearSamples(data, format, 0, len);
|
ClearSamples(data, format, 0, len);
|
||||||
ret = len;
|
return 0;
|
||||||
}
|
}
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read the summary of this alias block from disk. Since the audio data
|
/// Read the summary of this alias block from disk. Since the audio data
|
||||||
|
@ -109,7 +109,7 @@ class ODDecodeBlockFile final : public SimpleBlockFile
|
|||||||
|
|
||||||
/// Reads the specified data from the aliased file using libsndfile
|
/// Reads the specified data from the aliased file using libsndfile
|
||||||
size_t ReadData(samplePtr data, sampleFormat format,
|
size_t ReadData(samplePtr data, sampleFormat format,
|
||||||
size_t start, size_t len) const override;
|
size_t start, size_t len, bool mayThrow) const override;
|
||||||
|
|
||||||
/// Read the summary into a buffer
|
/// Read the summary into a buffer
|
||||||
bool ReadSummary(ArrayOf<char> &data) override;
|
bool ReadSummary(ArrayOf<char> &data) override;
|
||||||
|
@ -414,7 +414,7 @@ void ODPCMAliasBlockFile::WriteSummary()
|
|||||||
// To build the summary data, call ReadData (implemented by the
|
// To build the summary data, call ReadData (implemented by the
|
||||||
// derived classes) to get the sample data
|
// derived classes) to get the sample data
|
||||||
SampleBuffer sampleData(mLen, floatSample);
|
SampleBuffer sampleData(mLen, floatSample);
|
||||||
this->ReadData(sampleData.ptr(), floatSample, 0, mLen);
|
this->ReadData(sampleData.ptr(), floatSample, 0, mLen, true);
|
||||||
|
|
||||||
ArrayOf<char> cleanup;
|
ArrayOf<char> cleanup;
|
||||||
void *summaryData = CalcSummary(sampleData.ptr(), mLen,
|
void *summaryData = CalcSummary(sampleData.ptr(), mLen,
|
||||||
@ -495,7 +495,7 @@ void *ODPCMAliasBlockFile::CalcSummary(samplePtr buffer, size_t len,
|
|||||||
/// @param start The offset within the block to begin reading
|
/// @param start The offset within the block to begin reading
|
||||||
/// @param len The number of samples to read
|
/// @param len The number of samples to read
|
||||||
size_t ODPCMAliasBlockFile::ReadData(samplePtr data, sampleFormat format,
|
size_t ODPCMAliasBlockFile::ReadData(samplePtr data, sampleFormat format,
|
||||||
size_t start, size_t len) const
|
size_t start, size_t len, bool mayThrow) const
|
||||||
{
|
{
|
||||||
|
|
||||||
auto locker = LockForRead();
|
auto locker = LockForRead();
|
||||||
@ -505,7 +505,7 @@ size_t ODPCMAliasBlockFile::ReadData(samplePtr data, sampleFormat format,
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
return CommonReadData(
|
return CommonReadData( mayThrow,
|
||||||
mAliasedFileName, mSilentAliasLog, this, mAliasStart, mAliasChannel,
|
mAliasedFileName, mSilentAliasLog, this, mAliasStart, mAliasChannel,
|
||||||
data, format, start, len);
|
data, format, start, len);
|
||||||
}
|
}
|
||||||
|
@ -118,7 +118,7 @@ class ODPCMAliasBlockFile final : public PCMAliasBlockFile
|
|||||||
|
|
||||||
/// Reads the specified data from the aliased file using libsndfile
|
/// Reads the specified data from the aliased file using libsndfile
|
||||||
size_t ReadData(samplePtr data, sampleFormat format,
|
size_t ReadData(samplePtr data, sampleFormat format,
|
||||||
size_t start, size_t len) const override;
|
size_t start, size_t len, bool mayThrow) const override;
|
||||||
|
|
||||||
/// Read the summary into a buffer
|
/// Read the summary into a buffer
|
||||||
bool ReadSummary(ArrayOf<char> &data) override;
|
bool ReadSummary(ArrayOf<char> &data) override;
|
||||||
|
@ -75,14 +75,14 @@ PCMAliasBlockFile::~PCMAliasBlockFile()
|
|||||||
/// @param start The offset within the block to begin reading
|
/// @param start The offset within the block to begin reading
|
||||||
/// @param len The number of samples to read
|
/// @param len The number of samples to read
|
||||||
size_t PCMAliasBlockFile::ReadData(samplePtr data, sampleFormat format,
|
size_t PCMAliasBlockFile::ReadData(samplePtr data, sampleFormat format,
|
||||||
size_t start, size_t len) const
|
size_t start, size_t len, bool mayThrow) const
|
||||||
{
|
{
|
||||||
if(!mAliasedFileName.IsOk()){ // intentionally silenced
|
if(!mAliasedFileName.IsOk()){ // intentionally silenced
|
||||||
memset(data, 0, SAMPLE_SIZE(format) * len);
|
memset(data, 0, SAMPLE_SIZE(format) * len);
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
return CommonReadData(
|
return CommonReadData( mayThrow,
|
||||||
mAliasedFileName, mSilentAliasLog, this, mAliasStart, mAliasChannel,
|
mAliasedFileName, mSilentAliasLog, this, mAliasStart, mAliasChannel,
|
||||||
data, format, start, len);
|
data, format, start, len);
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ class PCMAliasBlockFile /* not final */ : public AliasBlockFile
|
|||||||
|
|
||||||
/// Reads the specified data from the aliased file using libsndfile
|
/// Reads the specified data from the aliased file using libsndfile
|
||||||
size_t ReadData(samplePtr data, sampleFormat format,
|
size_t ReadData(samplePtr data, sampleFormat format,
|
||||||
size_t start, size_t len) const override;
|
size_t start, size_t len, bool mayThrow) const override;
|
||||||
|
|
||||||
void SaveXML(XMLWriter &xmlFile) override;
|
void SaveXML(XMLWriter &xmlFile) override;
|
||||||
BlockFilePtr Copy(wxFileNameWrapper &&fileName) override;
|
BlockFilePtr Copy(wxFileNameWrapper &&fileName) override;
|
||||||
|
@ -32,7 +32,7 @@ bool SilentBlockFile::ReadSummary(ArrayOf<char> &data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t SilentBlockFile::ReadData(samplePtr data, sampleFormat format,
|
size_t SilentBlockFile::ReadData(samplePtr data, sampleFormat format,
|
||||||
size_t WXUNUSED(start), size_t len) const
|
size_t WXUNUSED(start), size_t len, bool) const
|
||||||
{
|
{
|
||||||
ClearSamples(data, format, 0, len);
|
ClearSamples(data, format, 0, len);
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ class SilentBlockFile final : public BlockFile {
|
|||||||
bool ReadSummary(ArrayOf<char> &data) override;
|
bool ReadSummary(ArrayOf<char> &data) override;
|
||||||
/// Read the data section of the disk file
|
/// Read the data section of the disk file
|
||||||
size_t ReadData(samplePtr data, sampleFormat format,
|
size_t ReadData(samplePtr data, sampleFormat format,
|
||||||
size_t start, size_t len) const override;
|
size_t start, size_t len, bool mayThrow) const override;
|
||||||
|
|
||||||
/// Create a NEW block file identical to this one
|
/// Create a NEW block file identical to this one
|
||||||
BlockFilePtr Copy(wxFileNameWrapper &&newFileName) override;
|
BlockFilePtr Copy(wxFileNameWrapper &&newFileName) override;
|
||||||
|
@ -315,7 +315,9 @@ void SimpleBlockFile::FillCache()
|
|||||||
|
|
||||||
// Read samples into cache
|
// Read samples into cache
|
||||||
mCache.sampleData.reinit(mLen * SAMPLE_SIZE(mCache.format));
|
mCache.sampleData.reinit(mLen * SAMPLE_SIZE(mCache.format));
|
||||||
if (ReadData(mCache.sampleData.get(), mCache.format, 0, mLen) != mLen)
|
if (ReadData(mCache.sampleData.get(), mCache.format, 0, mLen,
|
||||||
|
// no exceptions!
|
||||||
|
false) != mLen)
|
||||||
{
|
{
|
||||||
// Could not read all samples
|
// Could not read all samples
|
||||||
mCache.sampleData.reset();
|
mCache.sampleData.reset();
|
||||||
@ -387,21 +389,30 @@ bool SimpleBlockFile::ReadSummary(ArrayOf<char> &data)
|
|||||||
/// @param start The offset in this block file
|
/// @param start The offset in this block file
|
||||||
/// @param len The number of samples to read
|
/// @param len The number of samples to read
|
||||||
size_t SimpleBlockFile::ReadData(samplePtr data, sampleFormat format,
|
size_t SimpleBlockFile::ReadData(samplePtr data, sampleFormat format,
|
||||||
size_t start, size_t len) const
|
size_t start, size_t len, bool mayThrow) const
|
||||||
{
|
{
|
||||||
if (mCache.active)
|
if (mCache.active)
|
||||||
{
|
{
|
||||||
//wxLogDebug("SimpleBlockFile::ReadData(): Data are already in cache.");
|
//wxLogDebug("SimpleBlockFile::ReadData(): Data are already in cache.");
|
||||||
|
|
||||||
len = std::min(len, std::max(start, mLen) - start);
|
auto framesRead = std::min(len, std::max(start, mLen) - start);
|
||||||
CopySamples(
|
CopySamples(
|
||||||
(samplePtr)(mCache.sampleData.get() +
|
(samplePtr)(mCache.sampleData.get() +
|
||||||
start * SAMPLE_SIZE(mCache.format)),
|
start * SAMPLE_SIZE(mCache.format)),
|
||||||
mCache.format, data, format, len);
|
mCache.format, data, format, framesRead);
|
||||||
return len;
|
|
||||||
|
if ( framesRead < len ) {
|
||||||
|
if (mayThrow)
|
||||||
|
// Not the best exception class?
|
||||||
|
//throw FileException{ FileException::Cause::Read, mFileName }
|
||||||
|
;
|
||||||
|
ClearSamples(data, format, framesRead, len - framesRead);
|
||||||
|
}
|
||||||
|
|
||||||
|
return framesRead;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return CommonReadData(
|
return CommonReadData( mayThrow,
|
||||||
mFileName, mSilentLog, nullptr, 0, 0, data, format, start, len);
|
mFileName, mSilentLog, nullptr, 0, 0, data, format, start, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ class PROFILE_DLL_API SimpleBlockFile /* not final */ : public BlockFile {
|
|||||||
bool ReadSummary(ArrayOf<char> &data) override;
|
bool ReadSummary(ArrayOf<char> &data) override;
|
||||||
/// Read the data section of the disk file
|
/// Read the data section of the disk file
|
||||||
size_t ReadData(samplePtr data, sampleFormat format,
|
size_t ReadData(samplePtr data, sampleFormat format,
|
||||||
size_t start, size_t len) const override;
|
size_t start, size_t len, bool mayThrow) const override;
|
||||||
|
|
||||||
/// Create a NEW block file identical to this one
|
/// Create a NEW block file identical to this one
|
||||||
BlockFilePtr Copy(wxFileNameWrapper &&newFileName) override;
|
BlockFilePtr Copy(wxFileNameWrapper &&newFileName) override;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user