The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

143 lines
4.7KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-11 by Raw Material Software Ltd.
  5. ------------------------------------------------------------------------------
  6. JUCE can be redistributed and/or modified under the terms of the GNU General
  7. Public License (Version 2), as published by the Free Software Foundation.
  8. A copy of the license is included in the JUCE distribution, or can be found
  9. online at www.gnu.org/licenses.
  10. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  11. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  12. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  13. ------------------------------------------------------------------------------
  14. To release a closed-source product which uses JUCE, commercial licenses are
  15. available: visit www.rawmaterialsoftware.com/juce for more information.
  16. ==============================================================================
  17. */
  18. #ifndef __AUDIOLIVESCROLLINGDISPLAY_H_4C3BD3A7__
  19. #define __AUDIOLIVESCROLLINGDISPLAY_H_4C3BD3A7__
  20. #include "../JuceDemoHeader.h"
  21. //==============================================================================
  22. /* This component scrolls a continuous waveform showing the audio that's
  23. coming into whatever audio inputs this object is connected to.
  24. */
  25. class LiveScrollingAudioDisplay : public Component,
  26. public AudioIODeviceCallback,
  27. private Timer
  28. {
  29. public:
  30. LiveScrollingAudioDisplay()
  31. : nextSample (0), subSample (0), accumulator (0)
  32. {
  33. setOpaque (true);
  34. clear();
  35. startTimerHz (75); // use a timer to keep repainting this component
  36. }
  37. //==============================================================================
  38. void audioDeviceAboutToStart (AudioIODevice*) override
  39. {
  40. clear();
  41. }
  42. void audioDeviceStopped() override
  43. {
  44. clear();
  45. }
  46. void audioDeviceIOCallback (const float** inputChannelData, int numInputChannels,
  47. float** outputChannelData, int numOutputChannels,
  48. int numSamples) override
  49. {
  50. for (int i = 0; i < numSamples; ++i)
  51. {
  52. float inputSample = 0;
  53. for (int chan = 0; chan < numInputChannels; ++chan)
  54. if (inputChannelData[chan] != nullptr)
  55. inputSample += std::abs (inputChannelData[chan][i]); // find the sum of all the channels
  56. pushSample (10.0f * inputSample); // boost the level to make it more easily visible.
  57. }
  58. // We need to clear the output buffers before returning, in case they're full of junk..
  59. for (int j = 0; j < numOutputChannels; ++j)
  60. if (outputChannelData[j] != nullptr)
  61. zeromem (outputChannelData[j], sizeof (float) * (size_t) numSamples);
  62. }
  63. private:
  64. float samples[1024];
  65. int nextSample, subSample;
  66. float accumulator;
  67. void clear()
  68. {
  69. zeromem (samples, sizeof (samples));
  70. accumulator = 0;
  71. subSample = 0;
  72. }
  73. void paint (Graphics& g) override
  74. {
  75. g.fillAll (Colours::black);
  76. const float midY = getHeight() * 0.5f;
  77. int samplesAgo = (nextSample + numElementsInArray (samples) - 1);
  78. RectangleList<float> waveform;
  79. waveform.ensureStorageAllocated ((int) numElementsInArray (samples));
  80. for (int x = jmin (getWidth(), (int) numElementsInArray (samples)); --x >= 0;)
  81. {
  82. const float sampleSize = midY * samples [samplesAgo-- % numElementsInArray (samples)];
  83. waveform.addWithoutMerging (Rectangle<float> ((float) x, midY - sampleSize, 1.0f, sampleSize * 2.0f));
  84. }
  85. g.setColour (Colours::lightgreen);
  86. g.fillRectList (waveform);
  87. }
  88. void timerCallback() override
  89. {
  90. repaint();
  91. }
  92. void pushSample (const float newSample)
  93. {
  94. accumulator += newSample;
  95. if (subSample == 0)
  96. {
  97. const int inputSamplesPerPixel = 200;
  98. samples[nextSample] = accumulator / inputSamplesPerPixel;
  99. nextSample = (nextSample + 1) % numElementsInArray (samples);
  100. subSample = inputSamplesPerPixel;
  101. accumulator = 0;
  102. }
  103. else
  104. {
  105. --subSample;
  106. }
  107. }
  108. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LiveScrollingAudioDisplay);
  109. };
  110. #endif // __AUDIOLIVESCROLLINGDISPLAY_H_4C3BD3A7__