OpenShot Library | libopenshot-audio  0.2.0
juce_AudioSourcePlayer.cpp
1 /*
2  ==============================================================================
3 
4  This file is part of the JUCE library.
5  Copyright (c) 2017 - ROLI Ltd.
6 
7  JUCE is an open source library subject to commercial or open-source
8  licensing.
9 
10  The code included in this file is provided under the terms of the ISC license
11  http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12  To use, copy, modify, and/or distribute this software for any purpose with or
13  without fee is hereby granted provided that the above copyright notice and
14  this permission notice appear in all copies.
15 
16  JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17  EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18  DISCLAIMED.
19 
20  ==============================================================================
21 */
22 
23 namespace juce
24 {
25 
27 {
28 }
29 
31 {
32  setSource (nullptr);
33 }
34 
36 {
37  if (source != newSource)
38  {
39  auto* oldSource = source;
40 
41  if (newSource != nullptr && bufferSize > 0 && sampleRate > 0)
42  newSource->prepareToPlay (bufferSize, sampleRate);
43 
44  {
45  const ScopedLock sl (readLock);
46  source = newSource;
47  }
48 
49  if (oldSource != nullptr)
50  oldSource->releaseResources();
51  }
52 }
53 
54 void AudioSourcePlayer::setGain (const float newGain) noexcept
55 {
56  gain = newGain;
57 }
58 
59 void AudioSourcePlayer::audioDeviceIOCallback (const float** inputChannelData,
60  int totalNumInputChannels,
61  float** outputChannelData,
62  int totalNumOutputChannels,
63  int numSamples)
64 {
65  // these should have been prepared by audioDeviceAboutToStart()...
66  jassert (sampleRate > 0 && bufferSize > 0);
67 
68  const ScopedLock sl (readLock);
69 
70  if (source != nullptr)
71  {
72  int numActiveChans = 0, numInputs = 0, numOutputs = 0;
73 
74  // messy stuff needed to compact the channels down into an array
75  // of non-zero pointers..
76  for (int i = 0; i < totalNumInputChannels; ++i)
77  {
78  if (inputChannelData[i] != nullptr)
79  {
80  inputChans [numInputs++] = inputChannelData[i];
81  if (numInputs >= numElementsInArray (inputChans))
82  break;
83  }
84  }
85 
86  for (int i = 0; i < totalNumOutputChannels; ++i)
87  {
88  if (outputChannelData[i] != nullptr)
89  {
90  outputChans [numOutputs++] = outputChannelData[i];
91  if (numOutputs >= numElementsInArray (outputChans))
92  break;
93  }
94  }
95 
96  if (numInputs > numOutputs)
97  {
98  // if there aren't enough output channels for the number of
99  // inputs, we need to create some temporary extra ones (can't
100  // use the input data in case it gets written to)
101  tempBuffer.setSize (numInputs - numOutputs, numSamples,
102  false, false, true);
103 
104  for (int i = 0; i < numOutputs; ++i)
105  {
106  channels[numActiveChans] = outputChans[i];
107  memcpy (channels[numActiveChans], inputChans[i], sizeof (float) * (size_t) numSamples);
108  ++numActiveChans;
109  }
110 
111  for (int i = numOutputs; i < numInputs; ++i)
112  {
113  channels[numActiveChans] = tempBuffer.getWritePointer (i - numOutputs);
114  memcpy (channels[numActiveChans], inputChans[i], sizeof (float) * (size_t) numSamples);
115  ++numActiveChans;
116  }
117  }
118  else
119  {
120  for (int i = 0; i < numInputs; ++i)
121  {
122  channels[numActiveChans] = outputChans[i];
123  memcpy (channels[numActiveChans], inputChans[i], sizeof (float) * (size_t) numSamples);
124  ++numActiveChans;
125  }
126 
127  for (int i = numInputs; i < numOutputs; ++i)
128  {
129  channels[numActiveChans] = outputChans[i];
130  zeromem (channels[numActiveChans], sizeof (float) * (size_t) numSamples);
131  ++numActiveChans;
132  }
133  }
134 
135  AudioBuffer<float> buffer (channels, numActiveChans, numSamples);
136 
137  AudioSourceChannelInfo info (&buffer, 0, numSamples);
138  source->getNextAudioBlock (info);
139 
140  for (int i = info.buffer->getNumChannels(); --i >= 0;)
141  buffer.applyGainRamp (i, info.startSample, info.numSamples, lastGain, gain);
142 
143  lastGain = gain;
144  }
145  else
146  {
147  for (int i = 0; i < totalNumOutputChannels; ++i)
148  if (outputChannelData[i] != nullptr)
149  zeromem (outputChannelData[i], sizeof (float) * (size_t) numSamples);
150  }
151 }
152 
154 {
156  device->getCurrentBufferSizeSamples());
157 }
158 
159 void AudioSourcePlayer::prepareToPlay (double newSampleRate, int newBufferSize)
160 {
161  sampleRate = newSampleRate;
162  bufferSize = newBufferSize;
163  zeromem (channels, sizeof (channels));
164 
165  if (source != nullptr)
166  source->prepareToPlay (bufferSize, sampleRate);
167 }
168 
170 {
171  if (source != nullptr)
172  source->releaseResources();
173 
174  sampleRate = 0.0;
175  bufferSize = 0;
176 
177  tempBuffer.setSize (2, 8);
178 }
179 
180 } // namespace juce
juce::AudioIODevice::getCurrentSampleRate
virtual double getCurrentSampleRate()=0
Returns the sample rate that the device is currently using.
juce::AudioSourcePlayer::audioDeviceIOCallback
void audioDeviceIOCallback(const float **inputChannelData, int totalNumInputChannels, float **outputChannelData, int totalNumOutputChannels, int numSamples) override
Implementation of the AudioIODeviceCallback method.
Definition: juce_AudioSourcePlayer.cpp:59
juce::AudioSourcePlayer::setSource
void setSource(AudioSource *newSource)
Changes the current audio source to play from.
Definition: juce_AudioSourcePlayer.cpp:35
juce::AudioSource
Base class for objects that can produce a continuous stream of audio.
Definition: juce_AudioSource.h:113
juce::AudioBuffer< float >
juce::AudioSourcePlayer::AudioSourcePlayer
AudioSourcePlayer()
Creates an empty AudioSourcePlayer.
Definition: juce_AudioSourcePlayer.cpp:26
juce::AudioBuffer::setSize
void setSize(int newNumChannels, int newNumSamples, bool keepExistingContent=false, bool clearExtraSpace=false, bool avoidReallocating=false)
Changes the buffer's size or number of channels.
Definition: juce_AudioSampleBuffer.h:335
juce::AudioSourcePlayer::setGain
void setGain(float newGain) noexcept
Sets a gain to apply to the audio data.
Definition: juce_AudioSourcePlayer.cpp:54
juce::AudioSourcePlayer::audioDeviceAboutToStart
void audioDeviceAboutToStart(AudioIODevice *device) override
Implementation of the AudioIODeviceCallback method.
Definition: juce_AudioSourcePlayer.cpp:153
juce::AudioBuffer::getWritePointer
Type * getWritePointer(int channelNumber) noexcept
Returns a writeable pointer to one of the buffer's channels.
Definition: juce_AudioSampleBuffer.h:277
juce::AudioSource::getNextAudioBlock
virtual void getNextAudioBlock(const AudioSourceChannelInfo &bufferToFill)=0
Called repeatedly to fetch subsequent blocks of audio data.
juce::AudioSource::prepareToPlay
virtual void prepareToPlay(int samplesPerBlockExpected, double sampleRate)=0
Tells the source to prepare for playing.
juce::AudioSourceChannelInfo::startSample
int startSample
The first sample in the buffer from which the callback is expected to write data.
Definition: juce_AudioSource.h:81
juce::AudioSourceChannelInfo::numSamples
int numSamples
The number of samples in the buffer which the callback is expected to fill with data.
Definition: juce_AudioSource.h:85
juce::AudioIODevice::getCurrentBufferSizeSamples
virtual int getCurrentBufferSizeSamples()=0
Returns the buffer size that the device is currently using.
juce::AudioIODevice
Base class for an audio device with synchronised input and output channels.
Definition: juce_AudioIODevice.h:140
juce::AudioBuffer::getNumChannels
int getNumChannels() const noexcept
Returns the number of channels of audio data that this buffer contains.
Definition: juce_AudioSampleBuffer.h:237
juce::AudioBuffer::applyGainRamp
void applyGainRamp(int channel, int startSample, int numSamples, Type startGain, Type endGain) noexcept
Applies a range of gains to a region of a channel.
Definition: juce_AudioSampleBuffer.h:648
juce::AudioSourceChannelInfo::buffer
AudioBuffer< float > * buffer
The destination buffer to fill with audio data.
Definition: juce_AudioSource.h:77
juce::AudioSourceChannelInfo
Used by AudioSource::getNextAudioBlock().
Definition: juce_AudioSource.h:36
juce::AudioSourcePlayer::prepareToPlay
void prepareToPlay(double sampleRate, int blockSize)
An alternative method for initialising the source without an AudioIODevice.
Definition: juce_AudioSourcePlayer.cpp:159
juce::GenericScopedLock
Automatically locks and unlocks a mutex object.
Definition: juce_ScopedLock.h:58
juce::AudioSource::releaseResources
virtual void releaseResources()=0
Allows the source to release anything it no longer needs after playback has stopped.
juce::AudioSourcePlayer::audioDeviceStopped
void audioDeviceStopped() override
Implementation of the AudioIODeviceCallback method.
Definition: juce_AudioSourcePlayer.cpp:169
juce::AudioSourcePlayer::~AudioSourcePlayer
~AudioSourcePlayer() override
Destructor.
Definition: juce_AudioSourcePlayer.cpp:30