| 
							- /*
 -   ==============================================================================
 - 
 -    This file is part of the JUCE 6 technical preview.
 -    Copyright (c) 2017 - ROLI Ltd.
 - 
 -    You may use this code under the terms of the GPL v3
 -    (see www.gnu.org/licenses).
 - 
 -    For this technical preview, this file is not subject to commercial licensing.
 - 
 -    JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
 -    EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
 -    DISCLAIMED.
 - 
 -   ==============================================================================
 - */
 - 
 - namespace juce
 - {
 - 
 - struct AudioVisualiserComponent::ChannelInfo
 - {
 -     ChannelInfo (AudioVisualiserComponent& o, int bufferSize) : owner (o)
 -     {
 -         setBufferSize (bufferSize);
 -         clear();
 -     }
 - 
 -     void clear() noexcept
 -     {
 -         levels.fill ({});
 -         value = {};
 -         subSample = 0;
 -     }
 - 
 -     void pushSamples (const float* inputSamples, int num) noexcept
 -     {
 -         for (int i = 0; i < num; ++i)
 -             pushSample (inputSamples[i]);
 -     }
 - 
 -     void pushSample (float newSample) noexcept
 -     {
 -         if (--subSample <= 0)
 -         {
 -             if (++nextSample == levels.size())
 -                 nextSample = 0;
 - 
 -             levels.getReference (nextSample) = value;
 -             subSample = owner.getSamplesPerBlock();
 -             value = Range<float> (newSample, newSample);
 -         }
 -         else
 -         {
 -             value = value.getUnionWith (newSample);
 -         }
 -     }
 - 
 -     void setBufferSize (int newSize)
 -     {
 -         levels.removeRange (newSize, levels.size());
 -         levels.insertMultiple (-1, {}, newSize - levels.size());
 - 
 -         if (nextSample >= newSize)
 -             nextSample = 0;
 -     }
 - 
 -     AudioVisualiserComponent& owner;
 -     Array<Range<float>> levels;
 -     Range<float> value;
 -     std::atomic<int> nextSample { 0 }, subSample { 0 };
 - 
 -     JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ChannelInfo)
 - };
 - 
 - //==============================================================================
 - AudioVisualiserComponent::AudioVisualiserComponent (int initialNumChannels)
 -   : numSamples (1024),
 -     inputSamplesPerBlock (256),
 -     backgroundColour (Colours::black),
 -     waveformColour (Colours::white)
 - {
 -     setOpaque (true);
 -     setNumChannels (initialNumChannels);
 -     setRepaintRate (60);
 - }
 - 
 - AudioVisualiserComponent::~AudioVisualiserComponent()
 - {
 - }
 - 
 - void AudioVisualiserComponent::setNumChannels (int numChannels)
 - {
 -     channels.clear();
 - 
 -     for (int i = 0; i < numChannels; ++i)
 -         channels.add (new ChannelInfo (*this, numSamples));
 - }
 - 
 - void AudioVisualiserComponent::setBufferSize (int newNumSamples)
 - {
 -     numSamples = newNumSamples;
 - 
 -     for (auto* c : channels)
 -         c->setBufferSize (newNumSamples);
 - }
 - 
 - void AudioVisualiserComponent::clear()
 - {
 -     for (auto* c : channels)
 -         c->clear();
 - }
 - 
 - void AudioVisualiserComponent::pushBuffer (const float** d, int numChannels, int num)
 - {
 -     numChannels = jmin (numChannels, channels.size());
 - 
 -     for (int i = 0; i < numChannels; ++i)
 -         channels.getUnchecked(i)->pushSamples (d[i], num);
 - }
 - 
 - void AudioVisualiserComponent::pushBuffer (const AudioBuffer<float>& buffer)
 - {
 -     pushBuffer (buffer.getArrayOfReadPointers(),
 -                 buffer.getNumChannels(),
 -                 buffer.getNumSamples());
 - }
 - 
 - void AudioVisualiserComponent::pushBuffer (const AudioSourceChannelInfo& buffer)
 - {
 -     auto numChannels = jmin (buffer.buffer->getNumChannels(), channels.size());
 - 
 -     for (int i = 0; i < numChannels; ++i)
 -         channels.getUnchecked(i)->pushSamples (buffer.buffer->getReadPointer (i, buffer.startSample),
 -                                                buffer.numSamples);
 - }
 - 
 - void AudioVisualiserComponent::pushSample (const float* d, int numChannels)
 - {
 -     numChannels = jmin (numChannels, channels.size());
 - 
 -     for (int i = 0; i < numChannels; ++i)
 -         channels.getUnchecked(i)->pushSample (d[i]);
 - }
 - 
 - void AudioVisualiserComponent::setSamplesPerBlock (int newSamplesPerPixel) noexcept
 - {
 -     inputSamplesPerBlock = newSamplesPerPixel;
 - }
 - 
 - void AudioVisualiserComponent::setRepaintRate (int frequencyInHz)
 - {
 -     startTimerHz (frequencyInHz);
 - }
 - 
 - void AudioVisualiserComponent::timerCallback()
 - {
 -     repaint();
 - }
 - 
 - void AudioVisualiserComponent::setColours (Colour bk, Colour fg) noexcept
 - {
 -     backgroundColour = bk;
 -     waveformColour = fg;
 -     repaint();
 - }
 - 
 - void AudioVisualiserComponent::paint (Graphics& g)
 - {
 -     g.fillAll (backgroundColour);
 - 
 -     auto r = getLocalBounds().toFloat();
 -     auto channelHeight = r.getHeight() / channels.size();
 - 
 -     g.setColour (waveformColour);
 - 
 -     for (auto* c : channels)
 -         paintChannel (g, r.removeFromTop (channelHeight),
 -                       c->levels.begin(), c->levels.size(), c->nextSample);
 - }
 - 
 - void AudioVisualiserComponent::getChannelAsPath (Path& path, const Range<float>* levels,
 -                                                  int numLevels, int nextSample)
 - {
 -     path.preallocateSpace (4 * numLevels + 8);
 - 
 -     for (int i = 0; i < numLevels; ++i)
 -     {
 -         auto level = -(levels[(nextSample + i) % numLevels].getEnd());
 - 
 -         if (i == 0)
 -             path.startNewSubPath (0.0f, level);
 -         else
 -             path.lineTo ((float) i, level);
 -     }
 - 
 -     for (int i = numLevels; --i >= 0;)
 -         path.lineTo ((float) i, -(levels[(nextSample + i) % numLevels].getStart()));
 - 
 -     path.closeSubPath();
 - }
 - 
 - void AudioVisualiserComponent::paintChannel (Graphics& g, Rectangle<float> area,
 -                                              const Range<float>* levels, int numLevels, int nextSample)
 - {
 -     Path p;
 -     getChannelAsPath (p, levels, numLevels, nextSample);
 - 
 -     g.fillPath (p, AffineTransform::fromTargetPoints (0.0f, -1.0f,               area.getX(), area.getY(),
 -                                                       0.0f, 1.0f,                area.getX(), area.getBottom(),
 -                                                       (float) numLevels, -1.0f,  area.getRight(), area.getY()));
 - }
 - 
 - } // namespace juce
 
 
  |