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:
commit
089e696cab
@ -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);
|
||||||
|
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
108
src/MemoryX.h
108
src/MemoryX.h
@ -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
|
||||||
*/
|
*/
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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++)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user