1 /*
  2  * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.  Oracle designates this
  8  * particular file as subject to the "Classpath" exception as provided
  9  * by Oracle in the LICENSE file that accompanied this code.
 10  *
 11  * This code is distributed in the hope that it will be useful, but WITHOUT
 12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 14  * version 2 for more details (a copy is included in the LICENSE file that
 15  * accompanied this code).
 16  *
 17  * You should have received a copy of the GNU General Public License version
 18  * 2 along with this work; if not, write to the Free Software Foundation,
 19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  *
 21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  * or visit www.oracle.com if you need additional information or have any
 23  * questions.
 24  */
 25 
 26 #ifndef __JFXMedia__AVFAudioSpectrumUnit__
 27 #define __JFXMedia__AVFAudioSpectrumUnit__
 28 
 29 #include <AudioUnit/AudioUnit.h>
 30 
 31 #include <pthread.h>
 32 #include <memory>
 33 
 34 #include "PipelineManagement/AudioSpectrum.h"
 35 
 36 #include <gst/gst.h>
 37 #include <gstspectrum.h>
 38 
 39 // Defaults, these match the current defaults in JavaFX which get set anyways
 40 // but we can optimize things a bit here...
 41 #define kDefaultAudioSpectrumUpdateInterval 0.1 // every 1/10 second
 42 #define kDefaultAudioSpectrumThreshold -60.0    // -60 dB
 43 
 44 /*
 45  * Callback proc invoked by the audio spectrum unit. This call is made periodically
 46  * depending on the requested update interval. The band data is updated out-of-line.
 47  *
 48  * callbackContext: user specified context pointer
 49  * timeStamp: the beginning time in seconds of the sample period (from beginning of stream)
 50  * duration: the length of time in seconds of the sample period
 51  */
 52 typedef void (*AVFSpectrumUnitCallbackProc)(void *callbackContext, double duration,
 53                                             double timestamp);
 54 
 55 class AVFAudioSpectrumUnit : public CAudioSpectrum {
 56 public:
 57     AVFAudioSpectrumUnit();
 58     virtual ~AVFAudioSpectrumUnit();
 59 
 60     // We'll use ProcessBufferLists as it sends all channels at once instead
 61     // of individual channels
 62     bool ProcessBufferLists(const AudioBufferList& inBuffer,
 63                             UInt32 inFramesToProcess);
 64 
 65     // Parameter accessors
 66     virtual bool IsEnabled();
 67     virtual void SetEnabled(bool isEnabled);
 68 
 69     virtual void SetBands(int bands, CBandsHolder* holder);
 70     virtual size_t GetBands();
 71 
 72     virtual double GetInterval();
 73     virtual void SetInterval(double interval);
 74 
 75     virtual int GetThreshold();
 76     virtual void SetThreshold(int threshold);
 77 
 78     virtual void UpdateBands(int size, const float* magnitudes, const float* phases);
 79 
 80     void SetSampleRate(UInt32 rate);
 81     void SetChannels(UInt32 count);
 82     void SetMaxFrames(UInt32 maxFrames);
 83     void SetSpectrumCallbackProc(AVFSpectrumUnitCallbackProc proc, void *context);
 84     void SetFirstBufferDelivered(bool isFirstBufferDelivered);
 85 
 86 private:
 87     AVFSpectrumUnitCallbackProc mSpectrumCallbackProc;
 88     void *mSpectrumCallbackContext;
 89     bool mEnabled;
 90 
 91     pthread_mutex_t mBandLock;      // prevent bands from disappearing while we're processing
 92     int mBandCount;
 93     CBandsHolder *mBands;
 94     double mUpdateInterval;
 95     Float32 mThreshold;
 96 
 97     AudioBufferList mMixBuffer;
 98     int mMixBufferFrameCapacity;    // number of frames that can currently be stored in mix buffer
 99 
100     // Audio parameters
101     UInt32 mSampleRate;
102     UInt32 mChannels;
103     UInt32 mMaxFrames;
104     UInt32 mSamplesPerInterval;
105 
106     bool mRebuildCrunch;
107     bool mFirstBufferDelivered;
108 
109     // GStreamer
110     GstElement *mSpectrumElement;
111     GstSpectrum *mSpectrum;
112 
113     void lockBands() {
114         pthread_mutex_lock(&mBandLock);
115     }
116 
117     void unlockBands() {
118         pthread_mutex_unlock(&mBandLock);
119     }
120 
121     void SetupSpectralProcessor();
122     void ReleaseSpectralProcessor();
123 };
124 
125 typedef std::shared_ptr<AVFAudioSpectrumUnit> AVFAudioSpectrumUnitPtr;
126 
127 #endif /* defined(__JFXMedia__AVFAudioSpectrumUnit__) */