mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-22 01:34:21 +00:00
Added method AudioFormatWriter::writeFromFloatArrays()
This commit is contained in:
parent
42ade06d78
commit
fe3a2e4495
2 changed files with 68 additions and 46 deletions
|
|
@ -42,6 +42,23 @@ AudioFormatWriter::~AudioFormatWriter()
|
|||
delete output;
|
||||
}
|
||||
|
||||
static void convertFloatsToInts (int* dest, const float* src, int numSamples) noexcept
|
||||
{
|
||||
while (--numSamples >= 0)
|
||||
{
|
||||
const double samp = *src++;
|
||||
|
||||
if (samp <= -1.0)
|
||||
*dest = std::numeric_limits<int>::min();
|
||||
else if (samp >= 1.0)
|
||||
*dest = std::numeric_limits<int>::max();
|
||||
else
|
||||
*dest = roundToInt (std::numeric_limits<int>::max() * samp);
|
||||
|
||||
++dest;
|
||||
}
|
||||
}
|
||||
|
||||
bool AudioFormatWriter::writeFromAudioReader (AudioFormatReader& reader,
|
||||
int64 startSample,
|
||||
int64 numSamplesToRead)
|
||||
|
|
@ -70,31 +87,12 @@ bool AudioFormatWriter::writeFromAudioReader (AudioFormatReader& reader,
|
|||
|
||||
while (*bufferChan != nullptr)
|
||||
{
|
||||
int* b = *bufferChan++;
|
||||
void* const b = *bufferChan++;
|
||||
|
||||
if (isFloatingPoint())
|
||||
{
|
||||
// int -> float
|
||||
const double factor = 1.0 / std::numeric_limits<int>::max();
|
||||
|
||||
for (int i = 0; i < numToDo; ++i)
|
||||
reinterpret_cast<float*> (b)[i] = (float) (factor * b[i]);
|
||||
}
|
||||
FloatVectorOperations::convertFixedToFloat ((float*) b, (int*) b, 1.0f / 0x7fffffff, numToDo);
|
||||
else
|
||||
{
|
||||
// float -> int
|
||||
for (int i = 0; i < numToDo; ++i)
|
||||
{
|
||||
const double samp = *(const float*) b;
|
||||
|
||||
if (samp <= -1.0)
|
||||
*b++ = std::numeric_limits<int>::min();
|
||||
else if (samp >= 1.0)
|
||||
*b++ = std::numeric_limits<int>::max();
|
||||
else
|
||||
*b++ = roundToInt (std::numeric_limits<int>::max() * samp);
|
||||
}
|
||||
}
|
||||
convertFloatsToInts ((int*) b, (float*) b, numToDo);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -130,39 +128,60 @@ bool AudioFormatWriter::writeFromAudioSource (AudioSource& source, int numSample
|
|||
return true;
|
||||
}
|
||||
|
||||
bool AudioFormatWriter::writeFromAudioSampleBuffer (const AudioSampleBuffer& source, int startSample, int numSamples)
|
||||
bool AudioFormatWriter::writeFromFloatArrays (const float** channels, int numSourceChannels, int numSamples)
|
||||
{
|
||||
jassert (startSample >= 0 && startSample + numSamples <= source.getNumSamples() && source.getNumChannels() > 0);
|
||||
|
||||
if (numSamples <= 0)
|
||||
return true;
|
||||
|
||||
HeapBlock<int> tempBuffer;
|
||||
HeapBlock<int*> chans (numChannels + 1);
|
||||
chans [numChannels] = 0;
|
||||
|
||||
if (isFloatingPoint())
|
||||
{
|
||||
for (int i = (int) numChannels; --i >= 0;)
|
||||
chans[i] = reinterpret_cast<int*> (source.getSampleData (i, startSample));
|
||||
}
|
||||
else
|
||||
{
|
||||
tempBuffer.malloc (((size_t) numSamples) * (size_t) numChannels);
|
||||
return write ((const int**) channels, numSamples);
|
||||
|
||||
for (unsigned int i = 0; i < numChannels; ++i)
|
||||
{
|
||||
typedef AudioData::Pointer <AudioData::Int32, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::NonConst> DestSampleType;
|
||||
typedef AudioData::Pointer <AudioData::Float32, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::Const> SourceSampleType;
|
||||
int* chans [256];
|
||||
int scratch [4096];
|
||||
|
||||
chans[i] = tempBuffer + (int) i * numSamples;
|
||||
DestSampleType destData (chans[i]);
|
||||
SourceSampleType sourceData (source.getSampleData ((int) i, startSample));
|
||||
destData.convertSamples (sourceData, numSamples);
|
||||
}
|
||||
jassert (numSourceChannels < numElementsInArray (chans));
|
||||
const int maxSamples = (int) (numElementsInArray (scratch) / numSourceChannels);
|
||||
|
||||
for (int i = 0; i < numSourceChannels; ++i)
|
||||
chans[i] = scratch + (i * maxSamples);
|
||||
|
||||
chans[numSourceChannels] = nullptr;
|
||||
int startSample = 0;
|
||||
|
||||
while (numSamples > 0)
|
||||
{
|
||||
const int numToDo = jmin (numSamples, maxSamples);
|
||||
|
||||
for (int i = 0; i < numSourceChannels; ++i)
|
||||
convertFloatsToInts (chans[i], channels[i] + startSample, numToDo);
|
||||
|
||||
if (! write ((const int**) chans, numToDo))
|
||||
return false;
|
||||
|
||||
startSample += numToDo;
|
||||
numSamples -= numToDo;
|
||||
}
|
||||
|
||||
return write ((const int**) chans.getData(), numSamples);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AudioFormatWriter::writeFromAudioSampleBuffer (const AudioSampleBuffer& source, int startSample, int numSamples)
|
||||
{
|
||||
const int numSourceChannels = source.getNumChannels();
|
||||
jassert (startSample >= 0 && startSample + numSamples <= source.getNumSamples() && numSourceChannels > 0);
|
||||
|
||||
if (startSample == 0)
|
||||
return writeFromFloatArrays ((const float**) source.getArrayOfChannels(), numSourceChannels, numSamples);
|
||||
|
||||
const float* chans [256];
|
||||
jassert (numChannels < numElementsInArray (chans));
|
||||
|
||||
for (int i = 0; i < numSourceChannels; ++i)
|
||||
chans[i] = source.getSampleData (i, startSample);
|
||||
|
||||
chans[numSourceChannels] = nullptr;
|
||||
|
||||
return writeFromFloatArrays (chans, numSourceChannels, numSamples);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
|
|
|||
|
|
@ -130,6 +130,9 @@ public:
|
|||
bool writeFromAudioSampleBuffer (const AudioSampleBuffer& source,
|
||||
int startSample, int numSamples);
|
||||
|
||||
/** Writes some samples from a set of float data channels. */
|
||||
bool writeFromFloatArrays (const float** channels, int numChannels, int numSamples);
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the sample rate being used. */
|
||||
double getSampleRate() const noexcept { return sampleRate; }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue