mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-02-03 03:30:06 +00:00
Moved the data format structure of AudioThumbnail to be a public class.
This commit is contained in:
parent
90b74fcdee
commit
322cd4dba2
5 changed files with 162 additions and 163 deletions
|
|
@ -21535,45 +21535,13 @@ END_JUCE_NAMESPACE
|
|||
/*** Start of inlined file: juce_AudioThumbnail.cpp ***/
|
||||
BEGIN_JUCE_NAMESPACE
|
||||
|
||||
const int timeBeforeDeletingReader = 2000;
|
||||
|
||||
struct AudioThumbnailDataFormat
|
||||
{
|
||||
char thumbnailMagic[4];
|
||||
int samplesPerThumbSample;
|
||||
int64 totalSamples; // source samples
|
||||
int64 numFinishedSamples; // source samples
|
||||
int numThumbnailSamples;
|
||||
int numChannels;
|
||||
int sampleRate;
|
||||
char future[16];
|
||||
char data[1];
|
||||
|
||||
void swapEndiannessIfNeeded() throw()
|
||||
{
|
||||
#if JUCE_BIG_ENDIAN
|
||||
flip (samplesPerThumbSample);
|
||||
flip (totalSamples);
|
||||
flip (numFinishedSamples);
|
||||
flip (numThumbnailSamples);
|
||||
flip (numChannels);
|
||||
flip (sampleRate);
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
#if JUCE_BIG_ENDIAN
|
||||
static void flip (int& n) { n = (int) ByteOrder::swap ((uint32) n); }
|
||||
static void flip (int64& n) { n = (int64) ByteOrder::swap ((uint64) n); }
|
||||
#endif
|
||||
};
|
||||
|
||||
AudioThumbnail::AudioThumbnail (const int orginalSamplesPerThumbnailSample_,
|
||||
AudioFormatManager& formatManagerToUse_,
|
||||
AudioThumbnailCache& cacheToUse)
|
||||
: formatManagerToUse (formatManagerToUse_),
|
||||
cache (cacheToUse),
|
||||
orginalSamplesPerThumbnailSample (orginalSamplesPerThumbnailSample_)
|
||||
orginalSamplesPerThumbnailSample (orginalSamplesPerThumbnailSample_),
|
||||
timeBeforeDeletingReader (2000)
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
|
@ -21586,6 +21554,12 @@ AudioThumbnail::~AudioThumbnail()
|
|||
reader = 0;
|
||||
}
|
||||
|
||||
AudioThumbnail::DataFormat* AudioThumbnail::getData() const throw()
|
||||
{
|
||||
jassert (data.getData() != 0);
|
||||
return static_cast <DataFormat*> (data.getData());
|
||||
}
|
||||
|
||||
void AudioThumbnail::setSource (InputSource* const newSource)
|
||||
{
|
||||
cache.removeThumbnail (this);
|
||||
|
|
@ -21670,9 +21644,9 @@ void AudioThumbnail::timerCallback()
|
|||
|
||||
void AudioThumbnail::clear()
|
||||
{
|
||||
data.setSize (sizeof (AudioThumbnailDataFormat) + 3);
|
||||
data.setSize (sizeof (DataFormat) + 3);
|
||||
|
||||
AudioThumbnailDataFormat* const d = (AudioThumbnailDataFormat*) data.getData();
|
||||
DataFormat* const d = getData();
|
||||
|
||||
d->thumbnailMagic[0] = 'j';
|
||||
d->thumbnailMagic[1] = 'a';
|
||||
|
|
@ -21697,8 +21671,8 @@ void AudioThumbnail::loadFrom (InputStream& input)
|
|||
data.setSize (0);
|
||||
input.readIntoMemoryBlock (data);
|
||||
|
||||
AudioThumbnailDataFormat* const d = (AudioThumbnailDataFormat*) data.getData();
|
||||
d->swapEndiannessIfNeeded();
|
||||
DataFormat* const d = getData();
|
||||
d->flipEndiannessIfBigEndian();
|
||||
|
||||
if (! (d->thumbnailMagic[0] == 'j'
|
||||
&& d->thumbnailMagic[1] == 'a'
|
||||
|
|
@ -21714,15 +21688,17 @@ void AudioThumbnail::loadFrom (InputStream& input)
|
|||
|
||||
void AudioThumbnail::saveTo (OutputStream& output) const
|
||||
{
|
||||
AudioThumbnailDataFormat* const d = (AudioThumbnailDataFormat*) data.getData();
|
||||
d->swapEndiannessIfNeeded();
|
||||
output.write (data.getData(), (int) data.getSize());
|
||||
d->swapEndiannessIfNeeded();
|
||||
const ScopedLock sl (readerLock);
|
||||
|
||||
DataFormat* const d = getData();
|
||||
d->flipEndiannessIfBigEndian();
|
||||
output.write (d, (int) data.getSize());
|
||||
d->flipEndiannessIfBigEndian();
|
||||
}
|
||||
|
||||
bool AudioThumbnail::initialiseFromAudioFile (AudioFormatReader& fileReader)
|
||||
{
|
||||
AudioThumbnailDataFormat* d = (AudioThumbnailDataFormat*) data.getData();
|
||||
DataFormat* d = getData();
|
||||
|
||||
d->totalSamples = fileReader.lengthInSamples;
|
||||
d->numChannels = jmin ((uint32) 2, fileReader.numChannels);
|
||||
|
|
@ -21730,17 +21706,17 @@ bool AudioThumbnail::initialiseFromAudioFile (AudioFormatReader& fileReader)
|
|||
d->sampleRate = roundToInt (fileReader.sampleRate);
|
||||
d->numThumbnailSamples = (int) (d->totalSamples / d->samplesPerThumbSample) + 1;
|
||||
|
||||
data.setSize (sizeof (AudioThumbnailDataFormat) + 3 + d->numThumbnailSamples * d->numChannels * 2);
|
||||
data.setSize (sizeof (DataFormat) + 3 + d->numThumbnailSamples * d->numChannels * 2);
|
||||
|
||||
d = (AudioThumbnailDataFormat*) data.getData();
|
||||
zeromem (&(d->data[0]), d->numThumbnailSamples * d->numChannels * 2);
|
||||
d = getData();
|
||||
zeromem (d->data, d->numThumbnailSamples * d->numChannels * 2);
|
||||
|
||||
return d->totalSamples > 0;
|
||||
}
|
||||
|
||||
bool AudioThumbnail::readNextBlockFromAudioFile (AudioFormatReader& fileReader)
|
||||
{
|
||||
AudioThumbnailDataFormat* const d = (AudioThumbnailDataFormat*) data.getData();
|
||||
DataFormat* const d = getData();
|
||||
|
||||
if (d->numFinishedSamples < d->totalSamples)
|
||||
{
|
||||
|
|
@ -21754,24 +21730,20 @@ bool AudioThumbnail::readNextBlockFromAudioFile (AudioFormatReader& fileReader)
|
|||
}
|
||||
|
||||
cacheNeedsRefilling = true;
|
||||
return (d->numFinishedSamples < d->totalSamples);
|
||||
return d->numFinishedSamples < d->totalSamples;
|
||||
}
|
||||
|
||||
int AudioThumbnail::getNumChannels() const throw()
|
||||
{
|
||||
const AudioThumbnailDataFormat* const d = (const AudioThumbnailDataFormat*) data.getData();
|
||||
jassert (d != 0);
|
||||
|
||||
return d->numChannels;
|
||||
return getData()->numChannels;
|
||||
}
|
||||
|
||||
double AudioThumbnail::getTotalLength() const throw()
|
||||
{
|
||||
const AudioThumbnailDataFormat* const d = (const AudioThumbnailDataFormat*) data.getData();
|
||||
jassert (d != 0);
|
||||
const DataFormat* const d = getData();
|
||||
|
||||
if (d->sampleRate > 0)
|
||||
return d->totalSamples / (double)d->sampleRate;
|
||||
return d->totalSamples / (double) d->sampleRate;
|
||||
else
|
||||
return 0.0;
|
||||
}
|
||||
|
|
@ -21780,14 +21752,13 @@ void AudioThumbnail::generateSection (AudioFormatReader& fileReader,
|
|||
int64 startSample,
|
||||
int numSamples)
|
||||
{
|
||||
AudioThumbnailDataFormat* const d = (AudioThumbnailDataFormat*) data.getData();
|
||||
jassert (d != 0);
|
||||
DataFormat* const d = getData();
|
||||
|
||||
int firstDataPos = (int) (startSample / d->samplesPerThumbSample);
|
||||
int lastDataPos = (int) ((startSample + numSamples) / d->samplesPerThumbSample);
|
||||
const int firstDataPos = (int) (startSample / d->samplesPerThumbSample);
|
||||
const int lastDataPos = (int) ((startSample + numSamples) / d->samplesPerThumbSample);
|
||||
|
||||
char* l = getChannelData (0);
|
||||
char* r = getChannelData (1);
|
||||
char* const l = getChannelData (0);
|
||||
char* const r = getChannelData (1);
|
||||
|
||||
for (int i = firstDataPos; i < lastDataPos; ++i)
|
||||
{
|
||||
|
|
@ -21822,8 +21793,7 @@ void AudioThumbnail::generateSection (AudioFormatReader& fileReader,
|
|||
|
||||
char* AudioThumbnail::getChannelData (int channel) const
|
||||
{
|
||||
AudioThumbnailDataFormat* const d = (AudioThumbnailDataFormat*) data.getData();
|
||||
jassert (d != 0);
|
||||
DataFormat* const d = getData();
|
||||
|
||||
if (channel >= 0 && channel < d->numChannels)
|
||||
return d->data + (channel * 2 * d->numThumbnailSamples);
|
||||
|
|
@ -21833,9 +21803,7 @@ char* AudioThumbnail::getChannelData (int channel) const
|
|||
|
||||
bool AudioThumbnail::isFullyLoaded() const throw()
|
||||
{
|
||||
const AudioThumbnailDataFormat* const d = (const AudioThumbnailDataFormat*) data.getData();
|
||||
jassert (d != 0);
|
||||
|
||||
const DataFormat* const d = getData();
|
||||
return d->numFinishedSamples >= d->totalSamples;
|
||||
}
|
||||
|
||||
|
|
@ -21843,8 +21811,7 @@ void AudioThumbnail::refillCache (const int numSamples,
|
|||
double startTime,
|
||||
const double timePerPixel)
|
||||
{
|
||||
const AudioThumbnailDataFormat* const d = (const AudioThumbnailDataFormat*) data.getData();
|
||||
jassert (d != 0);
|
||||
const DataFormat* const d = getData();
|
||||
|
||||
if (numSamples <= 0
|
||||
|| timePerPixel <= 0.0
|
||||
|
|
@ -22017,17 +21984,33 @@ void AudioThumbnail::drawChannel (Graphics& g,
|
|||
cacheData += numChannelsCached << 1;
|
||||
|
||||
if (mn <= mx) // if the wrong way round, signifies that the sample's not yet known
|
||||
g.drawLine ((float) x, jmax (midY - mx * vscale - 0.3f, topY),
|
||||
(float) x, jmin (midY - mn * vscale + 0.3f, bottomY));
|
||||
g.drawVerticalLine (x, jmax (midY - mx * vscale - 0.3f, topY),
|
||||
jmin (midY - mn * vscale + 0.3f, bottomY));
|
||||
|
||||
++x;
|
||||
|
||||
if (x >= clip.getRight())
|
||||
if (++x >= clip.getRight())
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AudioThumbnail::DataFormat::flipEndiannessIfBigEndian() throw()
|
||||
{
|
||||
#if JUCE_BIG_ENDIAN
|
||||
struct Flipper
|
||||
{
|
||||
static void flip (int32& n) { n = (int32) ByteOrder::swap ((uint32) n); }
|
||||
static void flip (int64& n) { n = (int64) ByteOrder::swap ((uint64) n); }
|
||||
};
|
||||
|
||||
Flipper::flip (samplesPerThumbSample);
|
||||
Flipper::flip (totalSamples);
|
||||
Flipper::flip (numFinishedSamples);
|
||||
Flipper::flip (numThumbnailSamples);
|
||||
Flipper::flip (numChannels);
|
||||
Flipper::flip (sampleRate);
|
||||
#endif
|
||||
}
|
||||
|
||||
END_JUCE_NAMESPACE
|
||||
/*** End of inlined file: juce_AudioThumbnail.cpp ***/
|
||||
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@
|
|||
*/
|
||||
#define JUCE_MAJOR_VERSION 1
|
||||
#define JUCE_MINOR_VERSION 52
|
||||
#define JUCE_BUILDNUMBER 56
|
||||
#define JUCE_BUILDNUMBER 57
|
||||
|
||||
/** Current Juce version number.
|
||||
|
||||
|
|
@ -31087,10 +31087,27 @@ public:
|
|||
int channelNum,
|
||||
float verticalZoomFactor);
|
||||
|
||||
/** Returns true if the low res preview is fully generated.
|
||||
*/
|
||||
/** Returns true if the low res preview is fully generated. */
|
||||
bool isFullyLoaded() const throw();
|
||||
|
||||
/** The binary data format that is stored in the thumbnail file. */
|
||||
struct DataFormat
|
||||
{
|
||||
char thumbnailMagic[4]; /**< Should be 'jatm'. */
|
||||
int32 samplesPerThumbSample; /**< Number of source samples per thumbnail sample. */
|
||||
int64 totalSamples; /**< Total number of source samples. */
|
||||
int64 numFinishedSamples; /**< Number of valid source samples that have been read into the thumbnail. */
|
||||
int32 numThumbnailSamples; /**< Number of samples in the thumbnail data. */
|
||||
int32 numChannels; /**< Number of audio channels. */
|
||||
int32 sampleRate; /**< Source sample rate. */
|
||||
char future[16]; /**< Reserved for future use. */
|
||||
char data[1]; /**< The raw thumbnail samples, two signed bytes per
|
||||
sample (min and max values). Channels are interleaved. */
|
||||
|
||||
/** Flips the endianness of the values in this data structure if the CPU is big-endian. */
|
||||
void flipEndiannessIfBigEndian() throw();
|
||||
};
|
||||
|
||||
/** @internal */
|
||||
bool useTimeSlice();
|
||||
/** @internal */
|
||||
|
|
@ -31102,24 +31119,23 @@ private:
|
|||
AudioFormatManager& formatManagerToUse;
|
||||
AudioThumbnailCache& cache;
|
||||
ScopedPointer <InputSource> source;
|
||||
|
||||
CriticalSection readerLock;
|
||||
ScopedPointer <AudioFormatReader> reader;
|
||||
|
||||
MemoryBlock data, cachedLevels;
|
||||
int orginalSamplesPerThumbnailSample;
|
||||
|
||||
int numChannelsCached, numSamplesCached;
|
||||
double cachedStart, cachedTimePerPixel;
|
||||
bool cacheNeedsRefilling;
|
||||
const int timeBeforeDeletingReader;
|
||||
|
||||
friend class AudioThumbnailCache;
|
||||
|
||||
void clear();
|
||||
AudioFormatReader* createReader() const;
|
||||
void generateSection (AudioFormatReader& reader, int64 startSample, int numSamples);
|
||||
char* getChannelData (int channel) const;
|
||||
void refillCache (int numSamples, double startTime, double timePerPixel);
|
||||
|
||||
friend class AudioThumbnailCache;
|
||||
DataFormat* getData() const throw();
|
||||
|
||||
// true if it needs more callbacks from the readNextBlockFromAudioFile() method
|
||||
bool initialiseFromAudioFile (AudioFormatReader& reader);
|
||||
|
|
|
|||
|
|
@ -30,40 +30,6 @@ BEGIN_JUCE_NAMESPACE
|
|||
#include "juce_AudioThumbnail.h"
|
||||
#include "juce_AudioThumbnailCache.h"
|
||||
|
||||
const int timeBeforeDeletingReader = 2000;
|
||||
|
||||
|
||||
//==============================================================================
|
||||
struct AudioThumbnailDataFormat
|
||||
{
|
||||
char thumbnailMagic[4];
|
||||
int samplesPerThumbSample;
|
||||
int64 totalSamples; // source samples
|
||||
int64 numFinishedSamples; // source samples
|
||||
int numThumbnailSamples;
|
||||
int numChannels;
|
||||
int sampleRate;
|
||||
char future[16];
|
||||
char data[1];
|
||||
|
||||
void swapEndiannessIfNeeded() throw()
|
||||
{
|
||||
#if JUCE_BIG_ENDIAN
|
||||
flip (samplesPerThumbSample);
|
||||
flip (totalSamples);
|
||||
flip (numFinishedSamples);
|
||||
flip (numThumbnailSamples);
|
||||
flip (numChannels);
|
||||
flip (sampleRate);
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
#if JUCE_BIG_ENDIAN
|
||||
static void flip (int& n) { n = (int) ByteOrder::swap ((uint32) n); }
|
||||
static void flip (int64& n) { n = (int64) ByteOrder::swap ((uint64) n); }
|
||||
#endif
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
AudioThumbnail::AudioThumbnail (const int orginalSamplesPerThumbnailSample_,
|
||||
|
|
@ -71,7 +37,8 @@ AudioThumbnail::AudioThumbnail (const int orginalSamplesPerThumbnailSample_,
|
|||
AudioThumbnailCache& cacheToUse)
|
||||
: formatManagerToUse (formatManagerToUse_),
|
||||
cache (cacheToUse),
|
||||
orginalSamplesPerThumbnailSample (orginalSamplesPerThumbnailSample_)
|
||||
orginalSamplesPerThumbnailSample (orginalSamplesPerThumbnailSample_),
|
||||
timeBeforeDeletingReader (2000)
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
|
@ -84,6 +51,12 @@ AudioThumbnail::~AudioThumbnail()
|
|||
reader = 0;
|
||||
}
|
||||
|
||||
AudioThumbnail::DataFormat* AudioThumbnail::getData() const throw()
|
||||
{
|
||||
jassert (data.getData() != 0);
|
||||
return static_cast <DataFormat*> (data.getData());
|
||||
}
|
||||
|
||||
void AudioThumbnail::setSource (InputSource* const newSource)
|
||||
{
|
||||
cache.removeThumbnail (this);
|
||||
|
|
@ -168,9 +141,9 @@ void AudioThumbnail::timerCallback()
|
|||
|
||||
void AudioThumbnail::clear()
|
||||
{
|
||||
data.setSize (sizeof (AudioThumbnailDataFormat) + 3);
|
||||
data.setSize (sizeof (DataFormat) + 3);
|
||||
|
||||
AudioThumbnailDataFormat* const d = (AudioThumbnailDataFormat*) data.getData();
|
||||
DataFormat* const d = getData();
|
||||
|
||||
d->thumbnailMagic[0] = 'j';
|
||||
d->thumbnailMagic[1] = 'a';
|
||||
|
|
@ -195,8 +168,8 @@ void AudioThumbnail::loadFrom (InputStream& input)
|
|||
data.setSize (0);
|
||||
input.readIntoMemoryBlock (data);
|
||||
|
||||
AudioThumbnailDataFormat* const d = (AudioThumbnailDataFormat*) data.getData();
|
||||
d->swapEndiannessIfNeeded();
|
||||
DataFormat* const d = getData();
|
||||
d->flipEndiannessIfBigEndian();
|
||||
|
||||
if (! (d->thumbnailMagic[0] == 'j'
|
||||
&& d->thumbnailMagic[1] == 'a'
|
||||
|
|
@ -212,15 +185,17 @@ void AudioThumbnail::loadFrom (InputStream& input)
|
|||
|
||||
void AudioThumbnail::saveTo (OutputStream& output) const
|
||||
{
|
||||
AudioThumbnailDataFormat* const d = (AudioThumbnailDataFormat*) data.getData();
|
||||
d->swapEndiannessIfNeeded();
|
||||
output.write (data.getData(), (int) data.getSize());
|
||||
d->swapEndiannessIfNeeded();
|
||||
const ScopedLock sl (readerLock);
|
||||
|
||||
DataFormat* const d = getData();
|
||||
d->flipEndiannessIfBigEndian();
|
||||
output.write (d, (int) data.getSize());
|
||||
d->flipEndiannessIfBigEndian();
|
||||
}
|
||||
|
||||
bool AudioThumbnail::initialiseFromAudioFile (AudioFormatReader& fileReader)
|
||||
{
|
||||
AudioThumbnailDataFormat* d = (AudioThumbnailDataFormat*) data.getData();
|
||||
DataFormat* d = getData();
|
||||
|
||||
d->totalSamples = fileReader.lengthInSamples;
|
||||
d->numChannels = jmin ((uint32) 2, fileReader.numChannels);
|
||||
|
|
@ -228,17 +203,17 @@ bool AudioThumbnail::initialiseFromAudioFile (AudioFormatReader& fileReader)
|
|||
d->sampleRate = roundToInt (fileReader.sampleRate);
|
||||
d->numThumbnailSamples = (int) (d->totalSamples / d->samplesPerThumbSample) + 1;
|
||||
|
||||
data.setSize (sizeof (AudioThumbnailDataFormat) + 3 + d->numThumbnailSamples * d->numChannels * 2);
|
||||
data.setSize (sizeof (DataFormat) + 3 + d->numThumbnailSamples * d->numChannels * 2);
|
||||
|
||||
d = (AudioThumbnailDataFormat*) data.getData();
|
||||
zeromem (&(d->data[0]), d->numThumbnailSamples * d->numChannels * 2);
|
||||
d = getData();
|
||||
zeromem (d->data, d->numThumbnailSamples * d->numChannels * 2);
|
||||
|
||||
return d->totalSamples > 0;
|
||||
}
|
||||
|
||||
bool AudioThumbnail::readNextBlockFromAudioFile (AudioFormatReader& fileReader)
|
||||
{
|
||||
AudioThumbnailDataFormat* const d = (AudioThumbnailDataFormat*) data.getData();
|
||||
DataFormat* const d = getData();
|
||||
|
||||
if (d->numFinishedSamples < d->totalSamples)
|
||||
{
|
||||
|
|
@ -252,24 +227,20 @@ bool AudioThumbnail::readNextBlockFromAudioFile (AudioFormatReader& fileReader)
|
|||
}
|
||||
|
||||
cacheNeedsRefilling = true;
|
||||
return (d->numFinishedSamples < d->totalSamples);
|
||||
return d->numFinishedSamples < d->totalSamples;
|
||||
}
|
||||
|
||||
int AudioThumbnail::getNumChannels() const throw()
|
||||
{
|
||||
const AudioThumbnailDataFormat* const d = (const AudioThumbnailDataFormat*) data.getData();
|
||||
jassert (d != 0);
|
||||
|
||||
return d->numChannels;
|
||||
return getData()->numChannels;
|
||||
}
|
||||
|
||||
double AudioThumbnail::getTotalLength() const throw()
|
||||
{
|
||||
const AudioThumbnailDataFormat* const d = (const AudioThumbnailDataFormat*) data.getData();
|
||||
jassert (d != 0);
|
||||
const DataFormat* const d = getData();
|
||||
|
||||
if (d->sampleRate > 0)
|
||||
return d->totalSamples / (double)d->sampleRate;
|
||||
return d->totalSamples / (double) d->sampleRate;
|
||||
else
|
||||
return 0.0;
|
||||
}
|
||||
|
|
@ -278,14 +249,13 @@ void AudioThumbnail::generateSection (AudioFormatReader& fileReader,
|
|||
int64 startSample,
|
||||
int numSamples)
|
||||
{
|
||||
AudioThumbnailDataFormat* const d = (AudioThumbnailDataFormat*) data.getData();
|
||||
jassert (d != 0);
|
||||
DataFormat* const d = getData();
|
||||
|
||||
int firstDataPos = (int) (startSample / d->samplesPerThumbSample);
|
||||
int lastDataPos = (int) ((startSample + numSamples) / d->samplesPerThumbSample);
|
||||
const int firstDataPos = (int) (startSample / d->samplesPerThumbSample);
|
||||
const int lastDataPos = (int) ((startSample + numSamples) / d->samplesPerThumbSample);
|
||||
|
||||
char* l = getChannelData (0);
|
||||
char* r = getChannelData (1);
|
||||
char* const l = getChannelData (0);
|
||||
char* const r = getChannelData (1);
|
||||
|
||||
for (int i = firstDataPos; i < lastDataPos; ++i)
|
||||
{
|
||||
|
|
@ -320,8 +290,7 @@ void AudioThumbnail::generateSection (AudioFormatReader& fileReader,
|
|||
|
||||
char* AudioThumbnail::getChannelData (int channel) const
|
||||
{
|
||||
AudioThumbnailDataFormat* const d = (AudioThumbnailDataFormat*) data.getData();
|
||||
jassert (d != 0);
|
||||
DataFormat* const d = getData();
|
||||
|
||||
if (channel >= 0 && channel < d->numChannels)
|
||||
return d->data + (channel * 2 * d->numThumbnailSamples);
|
||||
|
|
@ -331,9 +300,7 @@ char* AudioThumbnail::getChannelData (int channel) const
|
|||
|
||||
bool AudioThumbnail::isFullyLoaded() const throw()
|
||||
{
|
||||
const AudioThumbnailDataFormat* const d = (const AudioThumbnailDataFormat*) data.getData();
|
||||
jassert (d != 0);
|
||||
|
||||
const DataFormat* const d = getData();
|
||||
return d->numFinishedSamples >= d->totalSamples;
|
||||
}
|
||||
|
||||
|
|
@ -341,8 +308,7 @@ void AudioThumbnail::refillCache (const int numSamples,
|
|||
double startTime,
|
||||
const double timePerPixel)
|
||||
{
|
||||
const AudioThumbnailDataFormat* const d = (const AudioThumbnailDataFormat*) data.getData();
|
||||
jassert (d != 0);
|
||||
const DataFormat* const d = getData();
|
||||
|
||||
if (numSamples <= 0
|
||||
|| timePerPixel <= 0.0
|
||||
|
|
@ -515,16 +481,33 @@ void AudioThumbnail::drawChannel (Graphics& g,
|
|||
cacheData += numChannelsCached << 1;
|
||||
|
||||
if (mn <= mx) // if the wrong way round, signifies that the sample's not yet known
|
||||
g.drawLine ((float) x, jmax (midY - mx * vscale - 0.3f, topY),
|
||||
(float) x, jmin (midY - mn * vscale + 0.3f, bottomY));
|
||||
g.drawVerticalLine (x, jmax (midY - mx * vscale - 0.3f, topY),
|
||||
jmin (midY - mn * vscale + 0.3f, bottomY));
|
||||
|
||||
++x;
|
||||
|
||||
if (x >= clip.getRight())
|
||||
if (++x >= clip.getRight())
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void AudioThumbnail::DataFormat::flipEndiannessIfBigEndian() throw()
|
||||
{
|
||||
#if JUCE_BIG_ENDIAN
|
||||
struct Flipper
|
||||
{
|
||||
static void flip (int32& n) { n = (int32) ByteOrder::swap ((uint32) n); }
|
||||
static void flip (int64& n) { n = (int64) ByteOrder::swap ((uint64) n); }
|
||||
};
|
||||
|
||||
Flipper::flip (samplesPerThumbSample);
|
||||
Flipper::flip (totalSamples);
|
||||
Flipper::flip (numFinishedSamples);
|
||||
Flipper::flip (numThumbnailSamples);
|
||||
Flipper::flip (numChannels);
|
||||
Flipper::flip (sampleRate);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
END_JUCE_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -136,10 +136,28 @@ public:
|
|||
int channelNum,
|
||||
float verticalZoomFactor);
|
||||
|
||||
/** Returns true if the low res preview is fully generated.
|
||||
*/
|
||||
/** Returns true if the low res preview is fully generated. */
|
||||
bool isFullyLoaded() const throw();
|
||||
|
||||
//==============================================================================
|
||||
/** The binary data format that is stored in the thumbnail file. */
|
||||
struct DataFormat
|
||||
{
|
||||
char thumbnailMagic[4]; /**< Should be 'jatm'. */
|
||||
int32 samplesPerThumbSample; /**< Number of source samples per thumbnail sample. */
|
||||
int64 totalSamples; /**< Total number of source samples. */
|
||||
int64 numFinishedSamples; /**< Number of valid source samples that have been read into the thumbnail. */
|
||||
int32 numThumbnailSamples; /**< Number of samples in the thumbnail data. */
|
||||
int32 numChannels; /**< Number of audio channels. */
|
||||
int32 sampleRate; /**< Source sample rate. */
|
||||
char future[16]; /**< Reserved for future use. */
|
||||
char data[1]; /**< The raw thumbnail samples, two signed bytes per
|
||||
sample (min and max values). Channels are interleaved. */
|
||||
|
||||
/** Flips the endianness of the values in this data structure if the CPU is big-endian. */
|
||||
void flipEndiannessIfBigEndian() throw();
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** @internal */
|
||||
bool useTimeSlice();
|
||||
|
|
@ -153,24 +171,23 @@ private:
|
|||
AudioFormatManager& formatManagerToUse;
|
||||
AudioThumbnailCache& cache;
|
||||
ScopedPointer <InputSource> source;
|
||||
|
||||
CriticalSection readerLock;
|
||||
ScopedPointer <AudioFormatReader> reader;
|
||||
|
||||
MemoryBlock data, cachedLevels;
|
||||
int orginalSamplesPerThumbnailSample;
|
||||
|
||||
int numChannelsCached, numSamplesCached;
|
||||
double cachedStart, cachedTimePerPixel;
|
||||
bool cacheNeedsRefilling;
|
||||
const int timeBeforeDeletingReader;
|
||||
|
||||
friend class AudioThumbnailCache;
|
||||
|
||||
void clear();
|
||||
AudioFormatReader* createReader() const;
|
||||
void generateSection (AudioFormatReader& reader, int64 startSample, int numSamples);
|
||||
char* getChannelData (int channel) const;
|
||||
void refillCache (int numSamples, double startTime, double timePerPixel);
|
||||
|
||||
friend class AudioThumbnailCache;
|
||||
DataFormat* getData() const throw();
|
||||
|
||||
// true if it needs more callbacks from the readNextBlockFromAudioFile() method
|
||||
bool initialiseFromAudioFile (AudioFormatReader& reader);
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
*/
|
||||
#define JUCE_MAJOR_VERSION 1
|
||||
#define JUCE_MINOR_VERSION 52
|
||||
#define JUCE_BUILDNUMBER 56
|
||||
#define JUCE_BUILDNUMBER 57
|
||||
|
||||
/** Current Juce version number.
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue