1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-07-03 22:19:07 +02:00

More utilities in MemoryX.h

This commit is contained in:
Paul Licameli 2017-03-09 09:51:45 -05:00
commit 089e696cab
12 changed files with 129 additions and 31 deletions

View File

@ -349,7 +349,7 @@ void BlockFile::FixSummary(void *data)
if (min != summary64K[0] || max != summary64K[1] || bad > 0) { if (min != summary64K[0] || max != summary64K[1] || bad > 0) {
unsigned int *buffer = (unsigned int *)data; unsigned int *buffer = (unsigned int *)data;
int len = mSummaryInfo.totalSummaryBytes / 4; auto len = mSummaryInfo.totalSummaryBytes / 4;
for(i=0; i<len; i++) for(i=0; i<len; i++)
buffer[i] = wxUINT32_SWAP_ALWAYS(buffer[i]); buffer[i] = wxUINT32_SWAP_ALWAYS(buffer[i]);
@ -735,7 +735,7 @@ bool AliasBlockFile::ReadSummary(void *data)
if (!summaryFile.IsOpened()){ if (!summaryFile.IsOpened()){
// NEW model; we need to return valid data // NEW model; we need to return valid data
memset(data, 0, (size_t)mSummaryInfo.totalSummaryBytes); memset(data, 0, mSummaryInfo.totalSummaryBytes);
// we silence the logging for this operation in this object // we silence the logging for this operation in this object
// after first occurrence of error; it's already reported and // after first occurrence of error; it's already reported and
@ -748,7 +748,7 @@ bool AliasBlockFile::ReadSummary(void *data)
else mSilentLog = FALSE; // worked properly, any future error is NEW else mSilentLog = FALSE; // worked properly, any future error is NEW
} }
int read = summaryFile.Read(data, (size_t)mSummaryInfo.totalSummaryBytes); auto read = summaryFile.Read(data, mSummaryInfo.totalSummaryBytes);
FixSummary(data); FixSummary(data);

View File

@ -38,7 +38,7 @@ class SummaryInfo {
int offset64K; int offset64K;
size_t frames256; size_t frames256;
int offset256; int offset256;
int totalSummaryBytes; size_t totalSummaryBytes;
}; };

View File

@ -36,6 +36,7 @@ namespace std {
using std::tr1::weak_ptr; using std::tr1::weak_ptr;
using std::tr1::static_pointer_cast; using std::tr1::static_pointer_cast;
using std::tr1::remove_reference; using std::tr1::remove_reference;
using std::tr1::is_unsigned;
template<typename X> struct default_delete template<typename X> struct default_delete
{ {
@ -160,7 +161,7 @@ namespace std {
// Skip the self-assignment test -- self-assignment should go to the non-template overload // Skip the self-assignment test -- self-assignment should go to the non-template overload
get_deleter()(p); get_deleter()(p);
p = that.release(); p = that.release();
((D&)*this) = move(that.get_deleter()); get_deleter() = move(that.get_deleter());
return *this; return *this;
} }
@ -439,11 +440,15 @@ class ArrayOf : public std::unique_ptr<X[]>
{ {
public: public:
ArrayOf() {} ArrayOf() {}
explicit ArrayOf(size_t count, bool initialize = false)
template<typename Integral>
explicit ArrayOf(Integral count, bool initialize = false)
{ {
static_assert(std::is_unsigned<Integral>::value, "Unsigned arguments only");
reinit(count, initialize); reinit(count, initialize);
} }
ArrayOf(const ArrayOf&) = delete;
ArrayOf(const ArrayOf&) PROHIBITED;
ArrayOf(ArrayOf&& that) ArrayOf(ArrayOf&& that)
: std::unique_ptr < X[] > : std::unique_ptr < X[] >
(std::move((std::unique_ptr < X[] >&)(that))) (std::move((std::unique_ptr < X[] >&)(that)))
@ -460,11 +465,16 @@ public:
return *this; return *this;
} }
void reinit(size_t count, bool initialize = false) template< typename Integral >
void reinit(Integral count,
bool initialize = false)
{ {
static_assert(std::is_unsigned<Integral>::value, "Unsigned arguments only");
if (initialize) if (initialize)
// Initialize elements (usually, to zero for a numerical type)
std::unique_ptr<X[]>::reset(safenew X[count]{}); std::unique_ptr<X[]>::reset(safenew X[count]{});
else else
// Avoid the slight initialization overhead
std::unique_ptr<X[]>::reset(safenew X[count]); std::unique_ptr<X[]>::reset(safenew X[count]);
} }
}; };
@ -480,25 +490,46 @@ class ArraysOf : public ArrayOf<ArrayOf<X>>
{ {
public: public:
ArraysOf() {} ArraysOf() {}
explicit ArraysOf(size_t N)
template<typename Integral>
explicit ArraysOf(Integral N)
: ArrayOf<ArrayOf<X>>( N ) : ArrayOf<ArrayOf<X>>( N )
{} {}
ArraysOf(size_t N, size_t M, bool initialize = false)
: ArrayOf<ArrayOf<X>>( N ) template<typename Integral1, typename Integral2 >
ArraysOf(Integral1 N, Integral2 M, bool initialize = false)
: ArrayOf<ArrayOf<X>>( N )
{ {
static_assert(std::is_unsigned<Integral1>::value, "Unsigned arguments only");
static_assert(std::is_unsigned<Integral2>::value, "Unsigned arguments only");
for (size_t ii = 0; ii < N; ++ii) for (size_t ii = 0; ii < N; ++ii)
(*this)[ii] = ArrayOf<X>{ M, initialize }; (*this)[ii] = ArrayOf<X>{ M, initialize };
} }
ArraysOf(const ArraysOf&) = delete;
ArraysOf(const ArraysOf&) PROHIBITED;
ArraysOf& operator= (ArraysOf&& that) ArraysOf& operator= (ArraysOf&& that)
{ {
ArrayOf<ArrayOf<X>>::operator=(std::move(that)); ArrayOf<ArrayOf<X>>::operator=(std::move(that));
return *this; return *this;
} }
using ArrayOf<ArrayOf<X>>::reinit; template< typename Integral >
void reinit(size_t countN, size_t countM, bool initialize = false) void reinit(Integral count)
{ {
ArrayOf<ArrayOf<X>>::reinit( count );
}
template< typename Integral >
void reinit(Integral count, bool initialize)
{
ArrayOf<ArrayOf<X>>::reinit( count, initialize );
}
template<typename Integral1, typename Integral2 >
void reinit(Integral1 countN, Integral2 countM, bool initialize = false)
{
static_assert(std::is_unsigned<Integral1>::value, "Unsigned arguments only");
static_assert(std::is_unsigned<Integral2>::value, "Unsigned arguments only");
reinit(countN, false); reinit(countN, false);
for (size_t ii = 0; ii < countN; ++ii) for (size_t ii = 0; ii < countN; ++ii)
(*this)[ii].reinit(countM, initialize); (*this)[ii].reinit(countM, initialize);
@ -719,6 +750,23 @@ make_movable_with_deleter(const Deleter &d, Args&&... args)
return movable_ptr_with_deleter<T, Deleter>(safenew T(std::forward<Args>(args)...), d); return movable_ptr_with_deleter<T, Deleter>(safenew T(std::forward<Args>(args)...), d);
} }
/*
* A deleter for pointers obtained with malloc
*/
struct freer { void operator() (void *p) const { free(p); } };
/*
* A useful alias for holding the result of malloc
*/
template< typename T >
using MallocPtr = std::unique_ptr< T, freer >;
/*
* A useful alias for holding the result of strup and similar
*/
template <typename Character = char>
using MallocString = std::unique_ptr< Character[], freer >;
/* /*
* A deleter class to supply the second template parameter of unique_ptr for * A deleter class to supply the second template parameter of unique_ptr for
* classes like wxWindow that should be sent a message called Destroy rather * classes like wxWindow that should be sent a message called Destroy rather
@ -758,6 +806,46 @@ Final_action<F> finally (F f)
return Final_action<F>(f); return Final_action<F>(f);
} }
/*
* Set a variable temporarily in a scope
*/
template< typename T >
struct RestoreValue {
T oldValue;
void operator () ( T *p ) const { if (p) *p = oldValue; }
};
template< typename T >
class ValueRestorer : public std::unique_ptr< T, RestoreValue<T> >
{
using std::unique_ptr< T, RestoreValue<T> >::reset; // make private
// But release() remains public and can be useful to commit a changed value
public:
explicit ValueRestorer( T &var )
: std::unique_ptr< T, RestoreValue<T> >( &var, { var } )
{}
explicit ValueRestorer( T &var, const T& newValue )
: std::unique_ptr< T, RestoreValue<T> >( &var, { var } )
{ var = newValue; }
ValueRestorer(ValueRestorer &&that)
: std::unique_ptr < T, RestoreValue<T> > ( std::move(that) ) {};
ValueRestorer & operator= (ValueRestorer &&that)
{
if (this != &that)
std::unique_ptr < T, RestoreValue<T> >::operator=(std::move(that));
return *this;
}
};
// inline functions provide convenient parameter type deduction
template< typename T >
ValueRestorer< T > valueRestorer( T& var )
{ return ValueRestorer< T >{ var }; }
template< typename T >
ValueRestorer< T > valueRestorer( T& var, const T& newValue )
{ return ValueRestorer< T >{ var, newValue }; }
/* /*
* A convenience for use with range-for * A convenience for use with range-for
*/ */

View File

@ -12,6 +12,7 @@
#define __AUDACITY_SAMPLE_FORMAT__ #define __AUDACITY_SAMPLE_FORMAT__
#include "Audacity.h" #include "Audacity.h"
#include "MemoryX.h"
#include <wx/defs.h> #include <wx/defs.h>
#include "audacity/Types.h" #include "audacity/Types.h"
@ -151,4 +152,10 @@ void ReverseSamples(samplePtr buffer, sampleFormat format,
void InitDitherers(); void InitDitherers();
// These are so commonly done for processing samples in floating point form in memory,
// let's have abbeviations.
using Floats = ArrayOf<float>;
using FloatBuffers = ArraysOf<float>;
using Doubles = ArrayOf<double>;
#endif #endif

View File

@ -159,7 +159,7 @@ LegacyBlockFile::~LegacyBlockFile()
bool LegacyBlockFile::ReadSummary(void *data) bool LegacyBlockFile::ReadSummary(void *data)
{ {
wxFFile summaryFile(mFileName.GetFullPath(), wxT("rb")); wxFFile summaryFile(mFileName.GetFullPath(), wxT("rb"));
int read; size_t read;
{ {
Maybe<wxLogNull> silence{}; Maybe<wxLogNull> silence{};
if (mSilentLog) if (mSilentLog)
@ -167,14 +167,14 @@ bool LegacyBlockFile::ReadSummary(void *data)
if (!summaryFile.IsOpened()){ if (!summaryFile.IsOpened()){
memset(data, 0, (size_t)mSummaryInfo.totalSummaryBytes); memset(data, 0, mSummaryInfo.totalSummaryBytes);
mSilentLog = TRUE; mSilentLog = TRUE;
return true; return true;
} }
read = summaryFile.Read(data, (size_t)mSummaryInfo.totalSummaryBytes); read = summaryFile.Read(data, mSummaryInfo.totalSummaryBytes);
} }
mSilentLog=FALSE; mSilentLog=FALSE;

View File

@ -472,7 +472,7 @@ bool ODDecodeBlockFile::ReadSummary(void *data)
if(IsSummaryAvailable()) if(IsSummaryAvailable())
return SimpleBlockFile::ReadSummary(data); return SimpleBlockFile::ReadSummary(data);
memset(data, 0, (size_t)mSummaryInfo.totalSummaryBytes); memset(data, 0, mSummaryInfo.totalSummaryBytes);
return true; return true;
} }

View File

@ -518,7 +518,7 @@ bool ODPCMAliasBlockFile::ReadSummary(void *data)
if( !summaryFile.IsOpened() ){ if( !summaryFile.IsOpened() ){
// NEW model; we need to return valid data // NEW model; we need to return valid data
memset(data,0,(size_t)mSummaryInfo.totalSummaryBytes); memset(data, 0, mSummaryInfo.totalSummaryBytes);
// we silence the logging for this operation in this object // we silence the logging for this operation in this object
// after first occurrence of error; it's already reported and // after first occurrence of error; it's already reported and
@ -529,9 +529,11 @@ bool ODPCMAliasBlockFile::ReadSummary(void *data)
mFileNameMutex.Unlock(); mFileNameMutex.Unlock();
return true; return true;
}else mSilentLog=FALSE; // worked properly, any future error is NEW }
else
mSilentLog=FALSE; // worked properly, any future error is NEW
int read = summaryFile.Read(data, (size_t)mSummaryInfo.totalSummaryBytes); auto read = summaryFile.Read(data, mSummaryInfo.totalSummaryBytes);
FixSummary(data); FixSummary(data);

View File

@ -26,7 +26,7 @@ SilentBlockFile::~SilentBlockFile()
bool SilentBlockFile::ReadSummary(void *data) bool SilentBlockFile::ReadSummary(void *data)
{ {
memset(data, 0, (size_t)mSummaryInfo.totalSummaryBytes); memset(data, 0, mSummaryInfo.totalSummaryBytes);
return true; return true;
} }

View File

@ -131,7 +131,7 @@ SimpleBlockFile::SimpleBlockFile(wxFileNameWrapper &&baseFileName,
format, cleanup); format, cleanup);
mCache.summaryData = new char[mSummaryInfo.totalSummaryBytes]; mCache.summaryData = new char[mSummaryInfo.totalSummaryBytes];
memcpy(mCache.summaryData, summaryData, memcpy(mCache.summaryData, summaryData,
(size_t)mSummaryInfo.totalSummaryBytes); mSummaryInfo.totalSummaryBytes);
} }
} }
@ -346,9 +346,10 @@ bool SimpleBlockFile::ReadSummary(void *data)
if (mCache.active) if (mCache.active)
{ {
//wxLogDebug("SimpleBlockFile::ReadSummary(): Summary is already in cache."); //wxLogDebug("SimpleBlockFile::ReadSummary(): Summary is already in cache.");
memcpy(data, mCache.summaryData, (size_t)mSummaryInfo.totalSummaryBytes); memcpy(data, mCache.summaryData, mSummaryInfo.totalSummaryBytes);
return true; return true;
} else }
else
{ {
//wxLogDebug("SimpleBlockFile::ReadSummary(): Reading summary from disk."); //wxLogDebug("SimpleBlockFile::ReadSummary(): Reading summary from disk.");
@ -361,7 +362,7 @@ bool SimpleBlockFile::ReadSummary(void *data)
// FIXME: TRAP_ERR no report to user of absent summary files? // FIXME: TRAP_ERR no report to user of absent summary files?
// filled with zero instead. // filled with zero instead.
if (!file.IsOpened()){ if (!file.IsOpened()){
memset(data, 0, (size_t)mSummaryInfo.totalSummaryBytes); memset(data, 0, mSummaryInfo.totalSummaryBytes);
mSilentLog = TRUE; mSilentLog = TRUE;
return true; return true;
} }
@ -373,7 +374,7 @@ bool SimpleBlockFile::ReadSummary(void *data)
if( !file.Seek(sizeof(auHeader)) ) if( !file.Seek(sizeof(auHeader)) )
return false; return false;
int read = (int)file.Read(data, (size_t)mSummaryInfo.totalSummaryBytes); auto read = file.Read(data, mSummaryInfo.totalSummaryBytes);
FixSummary(data); FixSummary(data);

View File

@ -1555,7 +1555,7 @@ bool Effect::ProcessTrack(int count,
decltype(mBufferSize) outputBufferCnt = 0; decltype(mBufferSize) outputBufferCnt = 0;
bool cleared = false; bool cleared = false;
auto chans = std::min(mNumAudioOut, mNumChannels); auto chans = std::min<unsigned>(mNumAudioOut, mNumChannels);
std::unique_ptr<WaveTrack> genLeft, genRight; std::unique_ptr<WaveTrack> genLeft, genRight;
decltype(len) genLength = 0; decltype(len) genLength = 0;

View File

@ -501,8 +501,8 @@ private:
// For client driver // For client driver
EffectClientInterface *mClient; EffectClientInterface *mClient;
unsigned mNumAudioIn; size_t mNumAudioIn;
unsigned mNumAudioOut; size_t mNumAudioOut;
float **mInBuffer; float **mInBuffer;
float **mOutBuffer; float **mOutBuffer;

View File

@ -392,7 +392,7 @@ bool FFmpegImportFileHandle::InitCodecs()
{ {
// Allocate the array of pointers to hold stream contexts pointers // Allocate the array of pointers to hold stream contexts pointers
// Some of the allocated space may be unused (corresponds to video, subtitle, or undecodeable audio streams) // Some of the allocated space may be unused (corresponds to video, subtitle, or undecodeable audio streams)
mScs = std::make_shared<Scs>(mFormatContext->nb_streams); mScs = std::make_shared<Scs>(size_t{mFormatContext->nb_streams});
// Fill the stream contexts // Fill the stream contexts
for (unsigned int i = 0; i < mFormatContext->nb_streams; i++) for (unsigned int i = 0; i < mFormatContext->nb_streams; i++)
{ {