Browse Source

AudioThumbnail: Add new member to set an AudioBuffer as source

v7.0.9
attila 2 years ago
parent
commit
fa37d47ebb
3 changed files with 85 additions and 0 deletions
  1. +3
    -0
      modules/juce_audio_basics/buffers/juce_AudioDataConverters.h
  2. +70
    -0
      modules/juce_audio_utils/gui/juce_AudioThumbnail.cpp
  3. +12
    -0
      modules/juce_audio_utils/gui/juce_AudioThumbnail.h

+ 3
- 0
modules/juce_audio_basics/buffers/juce_AudioDataConverters.h View File

@@ -436,6 +436,9 @@ public:
/** Adds a number of samples to the pointer's position. */
Pointer& operator+= (int samplesToJump) noexcept { this->advanceDataBy (data, samplesToJump); return *this; }
/** Returns a new pointer with the specified offset from this pointer's position. */
Pointer operator+ (int samplesToJump) const { return Pointer { *this } += samplesToJump; }
/** Writes a stream of samples into this pointer from another pointer.
This will copy the specified number of samples, converting between formats appropriately.
*/


+ 70
- 0
modules/juce_audio_utils/gui/juce_AudioThumbnail.cpp View File

@@ -83,6 +83,66 @@ private:
int8 values[2];
};
//==============================================================================
template <typename T>
class AudioBufferReader : public AudioFormatReader
{
public:
AudioBufferReader (const AudioBuffer<T>* bufferIn, double rate)
: AudioFormatReader (nullptr, "AudioBuffer"), buffer (bufferIn)
{
sampleRate = rate;
bitsPerSample = 32;
lengthInSamples = buffer->getNumSamples();
numChannels = (unsigned int) buffer->getNumChannels();
usesFloatingPointData = std::is_floating_point_v<T>;
}
bool readSamples (int* const* destChannels,
int numDestChannels,
int startOffsetInDestBuffer,
int64 startSampleInFile,
int numSamples) override
{
clearSamplesBeyondAvailableLength (destChannels, numDestChannels, startOffsetInDestBuffer,
startSampleInFile, numSamples, lengthInSamples);
const auto numAvailableSamples = (int) ((int64) buffer->getNumSamples() - startSampleInFile);
const auto numSamplesToCopy = std::clamp (numAvailableSamples, 0, numSamples);
if (numSamplesToCopy == 0)
return true;
for (int i = 0; i < numDestChannels; ++i)
{
if (void* targetChannel = destChannels[i])
{
const auto dest = DestType (targetChannel) + startOffsetInDestBuffer;
if (i < buffer->getNumChannels())
dest.convertSamples (SourceType (buffer->getReadPointer (i) + startSampleInFile), numSamplesToCopy);
else
dest.clearSamples (numSamples);
}
}
return true;
}
private:
using SourceNumericalType =
std::conditional_t<std::is_same_v<T, int>, AudioData::Int32,
std::conditional_t<std::is_same_v<T, float>, AudioData::Float32, void>>;
using DestinationNumericalType = std::conditional_t<std::is_floating_point_v<T>, AudioData::Float32, AudioData::Int32>;
using DestType = AudioData::Pointer<DestinationNumericalType, AudioData::LittleEndian, AudioData::NonInterleaved, AudioData::NonConst>;
using SourceType = AudioData::Pointer<SourceNumericalType, AudioData::LittleEndian, AudioData::NonInterleaved, AudioData::Const>;
const AudioBuffer<T>* buffer;
};
//==============================================================================
class AudioThumbnail::LevelDataSource : public TimeSliceClient
{
@@ -687,6 +747,16 @@ void AudioThumbnail::setReader (AudioFormatReader* newReader, int64 hash)
setDataSource (new LevelDataSource (*this, newReader, hash));
}
void AudioThumbnail::setSource (const AudioBuffer<float>* newSource, double rate, int64 hash)
{
setReader (new AudioBufferReader<float> (newSource, rate), hash);
}
void AudioThumbnail::setSource (const AudioBuffer<int>* newSource, double rate, int64 hash)
{
setReader (new AudioBufferReader<int> (newSource, rate), hash);
}
int64 AudioThumbnail::getHashCode() const
{
return source == nullptr ? 0 : source->hashCode;


+ 12
- 0
modules/juce_audio_utils/gui/juce_AudioThumbnail.h View File

@@ -99,6 +99,18 @@ public:
*/
void setReader (AudioFormatReader* newReader, int64 hashCode) override;
/** Sets an AudioBuffer as the source for the thumbnail.
The buffer contents aren't copied and you must ensure that the lifetime of the buffer is
valid for as long as the AudioThumbnail uses it as its source. Calling this function will
start reading the audio in a background thread (unless the hash code can be looked-up
successfully in the thumbnail cache).
*/
void setSource (const AudioBuffer<float>* newSource, double sampleRate, int64 hashCode);
/** Same as the other setSource() overload except for int data. */
void setSource (const AudioBuffer<int>* newSource, double sampleRate, int64 hashCode);
/** Resets the thumbnail, ready for adding data with the specified format.
If you're going to generate a thumbnail yourself, call this before using addBlock()
to add the data.


Loading…
Cancel
Save