1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00
JUCE/modules/juce_audio_devices/sources/juce_AudioSourcePlayer.cpp

183 lines
6 KiB
C++

/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-11 by Raw Material Software Ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified under the terms of the GNU General
Public License (Version 2), as published by the Free Software Foundation.
A copy of the license is included in the JUCE distribution, or can be found
online at www.gnu.org/licenses.
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.rawmaterialsoftware.com/juce for more information.
==============================================================================
*/
AudioSourcePlayer::AudioSourcePlayer()
: source (nullptr),
sampleRate (0),
bufferSize (0),
tempBuffer (2, 8),
lastGain (1.0f),
gain (1.0f)
{
}
AudioSourcePlayer::~AudioSourcePlayer()
{
setSource (nullptr);
}
void AudioSourcePlayer::setSource (AudioSource* newSource)
{
if (source != newSource)
{
AudioSource* const oldSource = source;
if (newSource != nullptr && bufferSize > 0 && sampleRate > 0)
newSource->prepareToPlay (bufferSize, sampleRate);
{
const ScopedLock sl (readLock);
source = newSource;
}
if (oldSource != nullptr)
oldSource->releaseResources();
}
}
void AudioSourcePlayer::setGain (const float newGain) noexcept
{
gain = newGain;
}
void AudioSourcePlayer::audioDeviceIOCallback (const float** inputChannelData,
int totalNumInputChannels,
float** outputChannelData,
int totalNumOutputChannels,
int numSamples)
{
// these should have been prepared by audioDeviceAboutToStart()...
jassert (sampleRate > 0 && bufferSize > 0);
const ScopedLock sl (readLock);
if (source != nullptr)
{
AudioSourceChannelInfo info;
int i, numActiveChans = 0, numInputs = 0, numOutputs = 0;
// messy stuff needed to compact the channels down into an array
// of non-zero pointers..
for (i = 0; i < totalNumInputChannels; ++i)
{
if (inputChannelData[i] != nullptr)
{
inputChans [numInputs++] = inputChannelData[i];
if (numInputs >= numElementsInArray (inputChans))
break;
}
}
for (i = 0; i < totalNumOutputChannels; ++i)
{
if (outputChannelData[i] != nullptr)
{
outputChans [numOutputs++] = outputChannelData[i];
if (numOutputs >= numElementsInArray (outputChans))
break;
}
}
if (numInputs > numOutputs)
{
// if there aren't enough output channels for the number of
// inputs, we need to create some temporary extra ones (can't
// use the input data in case it gets written to)
tempBuffer.setSize (numInputs - numOutputs, numSamples,
false, false, true);
for (i = 0; i < numOutputs; ++i)
{
channels[numActiveChans] = outputChans[i];
memcpy (channels[numActiveChans], inputChans[i], sizeof (float) * (size_t) numSamples);
++numActiveChans;
}
for (i = numOutputs; i < numInputs; ++i)
{
channels[numActiveChans] = tempBuffer.getSampleData (i - numOutputs, 0);
memcpy (channels[numActiveChans], inputChans[i], sizeof (float) * (size_t) numSamples);
++numActiveChans;
}
}
else
{
for (i = 0; i < numInputs; ++i)
{
channels[numActiveChans] = outputChans[i];
memcpy (channels[numActiveChans], inputChans[i], sizeof (float) * (size_t) numSamples);
++numActiveChans;
}
for (i = numInputs; i < numOutputs; ++i)
{
channels[numActiveChans] = outputChans[i];
zeromem (channels[numActiveChans], sizeof (float) * (size_t) numSamples);
++numActiveChans;
}
}
AudioSampleBuffer buffer (channels, numActiveChans, numSamples);
info.buffer = &buffer;
info.startSample = 0;
info.numSamples = numSamples;
source->getNextAudioBlock (info);
for (i = info.buffer->getNumChannels(); --i >= 0;)
info.buffer->applyGainRamp (i, info.startSample, info.numSamples, lastGain, gain);
lastGain = gain;
}
else
{
for (int i = 0; i < totalNumOutputChannels; ++i)
if (outputChannelData[i] != nullptr)
zeromem (outputChannelData[i], sizeof (float) * (size_t) numSamples);
}
}
void AudioSourcePlayer::audioDeviceAboutToStart (AudioIODevice* device)
{
sampleRate = device->getCurrentSampleRate();
bufferSize = device->getCurrentBufferSizeSamples();
zeromem (channels, sizeof (channels));
if (source != nullptr)
source->prepareToPlay (bufferSize, sampleRate);
}
void AudioSourcePlayer::audioDeviceStopped()
{
if (source != nullptr)
source->releaseResources();
sampleRate = 0.0;
bufferSize = 0;
tempBuffer.setSize (2, 8);
}