mirror of
https://github.com/cookiengineer/audacity
synced 2025-08-09 08:31:13 +02:00
One function for the common parts of BlockFile::ReadData overrides
This commit is contained in:
parent
a86cc1cb3b
commit
a4a9df5c03
@ -55,6 +55,9 @@ out.
|
||||
|
||||
#include "Internat.h"
|
||||
#include "MemoryX.h"
|
||||
#include "sndfile.h"
|
||||
#include "FileFormats.h"
|
||||
#include "AudacityApp.h"
|
||||
|
||||
// msmeyer: Define this to add debug output via printf()
|
||||
//#define DEBUG_BLOCKFILE
|
||||
@ -498,6 +501,135 @@ bool BlockFile::Read64K(float *buffer,
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t BlockFile::CommonReadData(
|
||||
const wxFileName &fileName, bool &mSilentLog,
|
||||
const AliasBlockFile *pAliasFile, sampleCount origin, unsigned channel,
|
||||
samplePtr data, sampleFormat format, size_t start, size_t len,
|
||||
const sampleFormat *pLegacyFormat, size_t legacyLen)
|
||||
{
|
||||
// Third party library has its own type alias, check it before
|
||||
// adding origin + size_t
|
||||
static_assert(sizeof(sampleCount::type) <= sizeof(sf_count_t),
|
||||
"Type sf_count_t is too narrow to hold a sampleCount");
|
||||
|
||||
SF_INFO info;
|
||||
memset(&info, 0, sizeof(info));
|
||||
|
||||
if ( pLegacyFormat ) {
|
||||
switch( *pLegacyFormat ) {
|
||||
case int16Sample:
|
||||
info.format =
|
||||
SF_FORMAT_RAW | SF_FORMAT_PCM_16 | SF_ENDIAN_CPU;
|
||||
break;
|
||||
default:
|
||||
case floatSample:
|
||||
info.format =
|
||||
SF_FORMAT_RAW | SF_FORMAT_FLOAT | SF_ENDIAN_CPU;
|
||||
break;
|
||||
case int24Sample:
|
||||
info.format = SF_FORMAT_RAW | SF_FORMAT_PCM_32 | SF_ENDIAN_CPU;
|
||||
break;
|
||||
}
|
||||
info.samplerate = 44100; // Doesn't matter
|
||||
info.channels = 1;
|
||||
info.frames = legacyLen + origin.as_long_long();
|
||||
}
|
||||
|
||||
|
||||
wxFile f; // will be closed when it goes out of scope
|
||||
SFFile sf;
|
||||
|
||||
{
|
||||
Maybe<wxLogNull> silence{};
|
||||
if (mSilentLog)
|
||||
silence.create();
|
||||
|
||||
const auto fullPath = fileName.GetFullPath();
|
||||
if (wxFile::Exists(fullPath) && f.Open(fullPath)) {
|
||||
// Even though there is an sf_open() that takes a filename, use the one that
|
||||
// takes a file descriptor since wxWidgets can open a file with a Unicode name and
|
||||
// libsndfile can't (under Windows).
|
||||
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) {
|
||||
|
||||
memset(data, 0, SAMPLE_SIZE(format)*len);
|
||||
|
||||
mSilentLog = TRUE;
|
||||
|
||||
if (pAliasFile) {
|
||||
// Set a marker to display an error message for the silence
|
||||
if (!wxGetApp().ShouldShowMissingAliasedFileWarning())
|
||||
wxGetApp().MarkAliasedFilesMissingWarning(pAliasFile);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
}
|
||||
mSilentLog=FALSE;
|
||||
|
||||
SFCall<sf_count_t>(
|
||||
sf_seek, sf.get(), ( origin + start ).as_long_long(), SEEK_SET);
|
||||
|
||||
auto channels = info.channels;
|
||||
wxASSERT(channels >= 1);
|
||||
wxASSERT(channel < channels);
|
||||
|
||||
size_t framesRead = 0;
|
||||
|
||||
if (channels == 1 &&
|
||||
format == int16Sample &&
|
||||
sf_subtype_is_integer(info.format)) {
|
||||
// If both the src and dest formats are integer formats,
|
||||
// read integers directly from the file, comversions not needed
|
||||
framesRead = SFCall<sf_count_t>(
|
||||
sf_readf_short, sf.get(), (short *)data, len);
|
||||
}
|
||||
else if (channels == 1 &&
|
||||
format == int24Sample &&
|
||||
sf_subtype_is_integer(info.format)) {
|
||||
framesRead = SFCall<sf_count_t>(sf_readf_int, sf.get(), (int *)data, len);
|
||||
|
||||
// libsndfile gave us the 3 byte sample in the 3 most
|
||||
// significant bytes -- we want it in the 3 least
|
||||
// significant bytes.
|
||||
int *intPtr = (int *)data;
|
||||
for( int i = 0; i < framesRead; i++ )
|
||||
intPtr[i] = intPtr[i] >> 8;
|
||||
}
|
||||
else if (format == int16Sample &&
|
||||
!sf_subtype_more_than_16_bits(info.format)) {
|
||||
// Special case: if the file is in 16-bit (or less) format,
|
||||
// and the calling method wants 16-bit data, go ahead and
|
||||
// read 16-bit data directly. This is a pretty common
|
||||
// case, as most audio files are 16-bit.
|
||||
SampleBuffer buffer(len * channels, int16Sample);
|
||||
framesRead = SFCall<sf_count_t>(
|
||||
sf_readf_short, sf.get(), (short *)buffer.ptr(), len);
|
||||
for (int i = 0; i < framesRead; i++)
|
||||
((short *)data)[i] =
|
||||
((short *)buffer.ptr())[(channels * i) + channel];
|
||||
}
|
||||
else {
|
||||
// Otherwise, let libsndfile handle the conversion and
|
||||
// scaling, and pass us normalized data as floats. We can
|
||||
// then convert to whatever format we want.
|
||||
SampleBuffer buffer(len * channels, floatSample);
|
||||
framesRead = SFCall<sf_count_t>(
|
||||
sf_readf_float, sf.get(), (float *)buffer.ptr(), len);
|
||||
auto bufferPtr = (samplePtr)((float *)buffer.ptr() + channel);
|
||||
CopySamples(bufferPtr, floatSample,
|
||||
(samplePtr)data, format,
|
||||
framesRead,
|
||||
true /* high quality by default */,
|
||||
channels /* source stride */);
|
||||
}
|
||||
|
||||
return framesRead;
|
||||
}
|
||||
|
||||
/// Constructs an AliasBlockFile based on the given information about
|
||||
/// the aliased file.
|
||||
///
|
||||
|
@ -44,6 +44,7 @@ class SummaryInfo {
|
||||
|
||||
|
||||
class BlockFile;
|
||||
class AliasBlockFile;
|
||||
using BlockFilePtr = std::shared_ptr<BlockFile>;
|
||||
|
||||
template< typename Result, typename... Args >
|
||||
@ -185,6 +186,12 @@ class PROFILE_DLL_API BlockFile /* not final, abstract */ {
|
||||
/// on a different platform
|
||||
virtual void FixSummary(void *data);
|
||||
|
||||
static size_t CommonReadData(
|
||||
const wxFileName &fileName, bool &mSilentLog,
|
||||
const AliasBlockFile *pAliasFile, sampleCount origin, unsigned channel,
|
||||
samplePtr data, sampleFormat format, size_t start, size_t len,
|
||||
const sampleFormat *pLegacyFormat = nullptr, size_t legacyLen = 0);
|
||||
|
||||
private:
|
||||
int mLockCount;
|
||||
|
||||
@ -247,7 +254,7 @@ class AliasBlockFile /* not final */ : public BlockFile
|
||||
|
||||
wxFileNameWrapper mAliasedFileName;
|
||||
sampleCount mAliasStart;
|
||||
int mAliasChannel;
|
||||
const int mAliasChannel;
|
||||
mutable bool mSilentAliasLog;
|
||||
};
|
||||
|
||||
|
@ -191,90 +191,11 @@ bool LegacyBlockFile::ReadSummary(void *data)
|
||||
size_t LegacyBlockFile::ReadData(samplePtr data, sampleFormat format,
|
||||
size_t start, size_t len) const
|
||||
{
|
||||
SF_INFO info;
|
||||
|
||||
memset(&info, 0, sizeof(info));
|
||||
|
||||
switch(mFormat) {
|
||||
case int16Sample:
|
||||
info.format =
|
||||
SF_FORMAT_RAW | SF_FORMAT_PCM_16 | SF_ENDIAN_CPU;
|
||||
break;
|
||||
default:
|
||||
case floatSample:
|
||||
info.format =
|
||||
SF_FORMAT_RAW | SF_FORMAT_FLOAT | SF_ENDIAN_CPU;
|
||||
break;
|
||||
case int24Sample:
|
||||
info.format = SF_FORMAT_RAW | SF_FORMAT_PCM_32 | SF_ENDIAN_CPU;
|
||||
break;
|
||||
}
|
||||
info.samplerate = 44100; // Doesn't matter
|
||||
info.channels = 1;
|
||||
info.frames = mLen + (mSummaryInfo.totalSummaryBytes /
|
||||
SAMPLE_SIZE(mFormat));
|
||||
|
||||
wxFile f; // will be closed when it goes out of scope
|
||||
SFFile sf;
|
||||
|
||||
if (f.Open(mFileName.GetFullPath())) {
|
||||
// Even though there is an sf_open() that takes a filename, use the one that
|
||||
// takes a file descriptor since wxWidgets can open a file with a Unicode name and
|
||||
// libsndfile can't (under Windows).
|
||||
sf.reset(SFCall<SNDFILE*>(sf_open_fd, f.fd(), SFM_READ, &info, FALSE));
|
||||
}
|
||||
// FIXME: TRAP_ERR failure of wxFile open incompletely handled in LegacyBlockfile::ReadData.
|
||||
|
||||
{
|
||||
Maybe<wxLogNull> silence{};
|
||||
if (mSilentLog)
|
||||
silence.create();
|
||||
|
||||
if (!sf){
|
||||
|
||||
memset(data, 0, SAMPLE_SIZE(format)*len);
|
||||
|
||||
mSilentLog = TRUE;
|
||||
|
||||
return len;
|
||||
}
|
||||
}
|
||||
mSilentLog=FALSE;
|
||||
|
||||
sf_count_t seekstart = start +
|
||||
(mSummaryInfo.totalSummaryBytes / SAMPLE_SIZE(mFormat));
|
||||
SFCall<sf_count_t>(sf_seek, sf.get(), seekstart , SEEK_SET);
|
||||
|
||||
SampleBuffer buffer(len, floatSample);
|
||||
size_t framesRead = 0;
|
||||
|
||||
// If both the src and dest formats are integer formats,
|
||||
// read integers from the file (otherwise we would be
|
||||
// converting to float and back, which is unneccesary)
|
||||
if (format == int16Sample &&
|
||||
sf_subtype_is_integer(info.format)) {
|
||||
framesRead = SFCall<sf_count_t>(sf_readf_short, sf.get(), (short *)data, len);
|
||||
}
|
||||
else if (format == int24Sample &&
|
||||
sf_subtype_is_integer(info.format)) {
|
||||
framesRead = SFCall<sf_count_t>(sf_readf_int, sf.get(), (int *)data, len);
|
||||
|
||||
// libsndfile gave us the 3 byte sample in the 3 most
|
||||
// significant bytes -- we want it in the 3 least
|
||||
// significant bytes.
|
||||
int *intPtr = (int *)data;
|
||||
for( int i = 0; i < framesRead; i++ )
|
||||
intPtr[i] = intPtr[i] >> 8;
|
||||
} else {
|
||||
// Otherwise, let libsndfile handle the conversion and
|
||||
// scaling, and pass us normalized data as floats. We can
|
||||
// then convert to whatever format we want.
|
||||
framesRead = SFCall<sf_count_t>(sf_readf_float, sf.get(), (float *)buffer.ptr(), len);
|
||||
CopySamples(buffer.ptr(), floatSample,
|
||||
(samplePtr)data, format, framesRead);
|
||||
}
|
||||
|
||||
return framesRead;
|
||||
sf_count_t origin = (mSummaryInfo.totalSummaryBytes / SAMPLE_SIZE(mFormat));
|
||||
return CommonReadData(
|
||||
mFileName, mSilentLog, nullptr, origin, 0, data, format, start, len,
|
||||
&mFormat, mLen
|
||||
);
|
||||
}
|
||||
|
||||
void LegacyBlockFile::SaveXML(XMLWriter &xmlFile)
|
||||
|
@ -185,7 +185,7 @@ class ODDecodeBlockFile final : public SimpleBlockFile
|
||||
sampleFormat mFormat;
|
||||
|
||||
sampleCount mAliasStart;//where in the encoded audio file this block corresponds to.
|
||||
int mAliasChannel;//The channel number in the encoded file..
|
||||
const int mAliasChannel;//The channel number in the encoded file..
|
||||
|
||||
};
|
||||
|
||||
|
@ -490,81 +490,18 @@ size_t ODPCMAliasBlockFile::ReadData(samplePtr data, sampleFormat format,
|
||||
|
||||
LockRead();
|
||||
|
||||
SF_INFO info;
|
||||
|
||||
if(!mAliasedFileName.IsOk()){ // intentionally silenced
|
||||
memset(data,0,SAMPLE_SIZE(format)*len);
|
||||
UnlockRead();
|
||||
return len;
|
||||
}
|
||||
|
||||
memset(&info, 0, sizeof(info));
|
||||
|
||||
wxString aliasPath = mAliasedFileName.GetFullPath();
|
||||
|
||||
wxFile f; // will be closed when it goes out of scope
|
||||
SFFile sf;
|
||||
|
||||
if (f.Exists(aliasPath) && f.Open(aliasPath)) {
|
||||
// Even though there is an sf_open() that takes a filename, use the one that
|
||||
// takes a file descriptor since wxWidgets can open a file with a Unicode name and
|
||||
// libsndfile can't (under Windows).
|
||||
sf.reset(SFCall<SNDFILE*>(sf_open_fd, f.fd(), SFM_READ, &info, FALSE));
|
||||
}
|
||||
// FIXME: TRAP_ERR failure of wxFile open incompletely handled in ODPCMAliasBlockFile::ReadData.
|
||||
|
||||
|
||||
if (!sf) {
|
||||
|
||||
memset(data,0,SAMPLE_SIZE(format)*len);
|
||||
|
||||
mSilentAliasLog = TRUE;
|
||||
// Set a marker to display an error message
|
||||
if (!wxGetApp().ShouldShowMissingAliasedFileWarning())
|
||||
wxGetApp().MarkAliasedFilesMissingWarning(this);
|
||||
|
||||
UnlockRead();
|
||||
return len;
|
||||
}
|
||||
|
||||
mSilentAliasLog=FALSE;
|
||||
|
||||
// Third party library has its own type alias, check it
|
||||
static_assert(sizeof(sampleCount::type) <= sizeof(sf_count_t),
|
||||
"Type sf_count_t is too narrow to hold a sampleCount");
|
||||
SFCall<sf_count_t>(sf_seek, sf.get(),
|
||||
( mAliasStart + start ).as_long_long(), SEEK_SET);
|
||||
|
||||
wxASSERT(info.channels >= 0);
|
||||
SampleBuffer buffer(len * info.channels, floatSample);
|
||||
|
||||
size_t framesRead = 0;
|
||||
|
||||
if (format == int16Sample &&
|
||||
!sf_subtype_more_than_16_bits(info.format)) {
|
||||
// Special case: if the file is in 16-bit (or less) format,
|
||||
// and the calling method wants 16-bit data, go ahead and
|
||||
// read 16-bit data directly. This is a pretty common
|
||||
// case, as most audio files are 16-bit.
|
||||
framesRead = SFCall<sf_count_t>(sf_readf_short, sf.get(), (short *)buffer.ptr(), len);
|
||||
|
||||
for (int i = 0; i < framesRead; i++)
|
||||
((short *)data)[i] =
|
||||
((short *)buffer.ptr())[(info.channels * i) + mAliasChannel];
|
||||
}
|
||||
else {
|
||||
// Otherwise, let libsndfile handle the conversion and
|
||||
// scaling, and pass us normalized data as floats. We can
|
||||
// then convert to whatever format we want.
|
||||
framesRead = SFCall<sf_count_t>(sf_readf_float, sf.get(), (float *)buffer.ptr(), len);
|
||||
float *bufferPtr = &((float *)buffer.ptr())[mAliasChannel];
|
||||
CopySamples((samplePtr)bufferPtr, floatSample,
|
||||
(samplePtr)data, format,
|
||||
framesRead, true, info.channels);
|
||||
}
|
||||
auto result = CommonReadData(
|
||||
mAliasedFileName, mSilentAliasLog, this, mAliasStart, mAliasChannel,
|
||||
data, format, start, len);
|
||||
|
||||
UnlockRead();
|
||||
return framesRead;
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Read the summary of this alias block from disk. Since the audio data
|
||||
|
@ -77,79 +77,14 @@ PCMAliasBlockFile::~PCMAliasBlockFile()
|
||||
size_t PCMAliasBlockFile::ReadData(samplePtr data, sampleFormat format,
|
||||
size_t start, size_t len) const
|
||||
{
|
||||
SF_INFO info;
|
||||
|
||||
if(!mAliasedFileName.IsOk()){ // intentionally silenced
|
||||
memset(data,0,SAMPLE_SIZE(format)*len);
|
||||
memset(data, 0, SAMPLE_SIZE(format) * len);
|
||||
return len;
|
||||
}
|
||||
|
||||
wxFile f; // will be closed when it goes out of scope
|
||||
SFFile sf;
|
||||
{
|
||||
Maybe<wxLogNull> silence{};
|
||||
if (mSilentAliasLog)
|
||||
silence.create();
|
||||
|
||||
memset(&info, 0, sizeof(info));
|
||||
|
||||
if (f.Exists(mAliasedFileName.GetFullPath())) { // Don't use Open if file does not exits
|
||||
if (f.Open(mAliasedFileName.GetFullPath())) {
|
||||
// Even though there is an sf_open() that takes a filename, use the one that
|
||||
// takes a file descriptor since wxWidgets can open a file with a Unicode name and
|
||||
// libsndfile can't (under Windows).
|
||||
sf.reset(SFCall<SNDFILE*>(sf_open_fd, f.fd(), SFM_READ, &info, FALSE));
|
||||
}
|
||||
// FIXME: TRAP_ERR failure of wxFile open incompletely handled in PCMAliasBlockFile::ReadData.
|
||||
|
||||
}
|
||||
|
||||
if (!sf) {
|
||||
memset(data, 0, SAMPLE_SIZE(format)*len);
|
||||
silence.reset();
|
||||
mSilentAliasLog = TRUE;
|
||||
|
||||
// Set a marker to display an error message for the silence
|
||||
if (!wxGetApp().ShouldShowMissingAliasedFileWarning())
|
||||
wxGetApp().MarkAliasedFilesMissingWarning(this);
|
||||
return len;
|
||||
}
|
||||
}
|
||||
mSilentAliasLog=FALSE;
|
||||
|
||||
// Third party library has its own type alias, check it
|
||||
static_assert(sizeof(sampleCount::type) <= sizeof(sf_count_t),
|
||||
"Type sf_count_t is too narrow to hold a sampleCount");
|
||||
SFCall<sf_count_t>(sf_seek, sf.get(),
|
||||
( mAliasStart + start ).as_long_long(), SEEK_SET);
|
||||
wxASSERT(info.channels >= 0);
|
||||
SampleBuffer buffer(len * info.channels, floatSample);
|
||||
|
||||
size_t framesRead = 0;
|
||||
|
||||
if (format == int16Sample &&
|
||||
!sf_subtype_more_than_16_bits(info.format)) {
|
||||
// Special case: if the file is in 16-bit (or less) format,
|
||||
// and the calling method wants 16-bit data, go ahead and
|
||||
// read 16-bit data directly. This is a pretty common
|
||||
// case, as most audio files are 16-bit.
|
||||
framesRead = SFCall<sf_count_t>(sf_readf_short, sf.get(), (short *)buffer.ptr(), len);
|
||||
for (int i = 0; i < framesRead; i++)
|
||||
((short *)data)[i] =
|
||||
((short *)buffer.ptr())[(info.channels * i) + mAliasChannel];
|
||||
}
|
||||
else {
|
||||
// Otherwise, let libsndfile handle the conversion and
|
||||
// scaling, and pass us normalized data as floats. We can
|
||||
// then convert to whatever format we want.
|
||||
framesRead = SFCall<sf_count_t>(sf_readf_float, sf.get(), (float *)buffer.ptr(), len);
|
||||
float *bufferPtr = &((float *)buffer.ptr())[mAliasChannel];
|
||||
CopySamples((samplePtr)bufferPtr, floatSample,
|
||||
(samplePtr)data, format,
|
||||
framesRead, true, info.channels);
|
||||
}
|
||||
|
||||
return framesRead;
|
||||
return CommonReadData(
|
||||
mAliasedFileName, mSilentAliasLog, this, mAliasStart, mAliasChannel,
|
||||
data, format, start, len);
|
||||
}
|
||||
|
||||
/// Construct a NEW PCMAliasBlockFile based on this one, but writing
|
||||
|
@ -402,76 +402,9 @@ size_t SimpleBlockFile::ReadData(samplePtr data, sampleFormat format,
|
||||
mCache.format, data, format, len);
|
||||
return len;
|
||||
}
|
||||
else {
|
||||
//wxLogDebug("SimpleBlockFile::ReadData(): Reading data from disk.");
|
||||
|
||||
SF_INFO info;
|
||||
wxFile f; // will be closed when it goes out of scope
|
||||
SFFile sf;
|
||||
{
|
||||
Maybe<wxLogNull> silence{};
|
||||
if (mSilentLog)
|
||||
silence.create();
|
||||
|
||||
memset(&info, 0, sizeof(info));
|
||||
|
||||
if (f.Open(mFileName.GetFullPath())) {
|
||||
// Even though there is an sf_open() that takes a filename, use the one that
|
||||
// takes a file descriptor since wxWidgets can open a file with a Unicode name and
|
||||
// libsndfile can't (under Windows).
|
||||
sf.reset(SFCall<SNDFILE*>(sf_open_fd, f.fd(), SFM_READ, &info, FALSE));
|
||||
}
|
||||
// FIXME: TRAP_ERR failure of wxFile open incompletely handled in SimpleBlockFile::ReadData.
|
||||
// FIXME: Too much cut and paste code between the different block file types.
|
||||
|
||||
|
||||
if (!sf) {
|
||||
|
||||
memset(data, 0, SAMPLE_SIZE(format)*len);
|
||||
|
||||
mSilentLog = TRUE;
|
||||
|
||||
return len;
|
||||
}
|
||||
}
|
||||
mSilentLog=FALSE;
|
||||
|
||||
SFCall<sf_count_t>(sf_seek, sf.get(), start, SEEK_SET);
|
||||
SampleBuffer buffer(len, floatSample);
|
||||
|
||||
size_t framesRead = 0;
|
||||
|
||||
// If both the src and dest formats are integer formats,
|
||||
// read integers from the file (otherwise we would be
|
||||
// converting to float and back, which is unneccesary)
|
||||
if (format == int16Sample &&
|
||||
sf_subtype_is_integer(info.format)) {
|
||||
framesRead = SFCall<sf_count_t>(sf_readf_short, sf.get(), (short *)data, len);
|
||||
}
|
||||
else
|
||||
if (format == int24Sample &&
|
||||
sf_subtype_is_integer(info.format))
|
||||
{
|
||||
framesRead = SFCall<sf_count_t>(sf_readf_int, sf.get(), (int *)data, len);
|
||||
|
||||
// libsndfile gave us the 3 byte sample in the 3 most
|
||||
// significant bytes -- we want it in the 3 least
|
||||
// significant bytes.
|
||||
int *intPtr = (int *)data;
|
||||
for( int i = 0; i < framesRead; i++ )
|
||||
intPtr[i] = intPtr[i] >> 8;
|
||||
}
|
||||
else {
|
||||
// Otherwise, let libsndfile handle the conversion and
|
||||
// scaling, and pass us normalized data as floats. We can
|
||||
// then convert to whatever format we want.
|
||||
framesRead = SFCall<sf_count_t>(sf_readf_float, sf.get(), (float *)buffer.ptr(), len);
|
||||
CopySamples(buffer.ptr(), floatSample,
|
||||
(samplePtr)data, format, framesRead);
|
||||
}
|
||||
|
||||
return framesRead;
|
||||
}
|
||||
else
|
||||
return CommonReadData(
|
||||
mFileName, mSilentLog, nullptr, 0, 0, data, format, start, len);
|
||||
}
|
||||
|
||||
void SimpleBlockFile::SaveXML(XMLWriter &xmlFile)
|
||||
|
Loading…
x
Reference in New Issue
Block a user