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 
 54 class AVFAudioSpectrumUnit : public CAudioSpectrum {
 55 public:
 56     AVFAudioSpectrumUnit();
 57     virtual ~AVFAudioSpectrumUnit();
 58 
 59     // We'll use ProcessBufferLists as it sends all channels at once instead
 60     // of individual channels
 61     bool ProcessBufferLists(const AudioBufferList& inBuffer,
 62                             UInt32 inFramesToProcess);
 63 
 64     // Parameter accessors
 65     virtual bool IsEnabled();
 66     virtual void SetEnabled(bool isEnabled);
 67 
 68     virtual void SetBands(int bands, CBandsHolder* holder);
 69     virtual size_t GetBands();
 70 
 71     virtual double GetInterval();
 72     virtual void SetInterval(double interval);
 73 
 74     virtual int GetThreshold();
 75     virtual void SetThreshold(int threshold);
 76 
 77     virtual void UpdateBands(int size, const float* magnitudes, const float* phases);
 78 
 79     void SetSampleRate(UInt32 rate);
 80     void SetChannels(UInt32 count);
 81     void SetMaxFrames(UInt32 maxFrames);
 82     void SetSpectrumCallbackProc(AVFSpectrumUnitCallbackProc proc, void *context);
 83 
 84 private:
 85     AVFSpectrumUnitCallbackProc mSpectrumCallbackProc;
 86     void *mSpectrumCallbackContext;
 87     bool mEnabled;
 88 
 89     pthread_mutex_t mBandLock;      // prevent bands from disappearing while we're processing
 90     int mBandCount;
 91     CBandsHolder *mBands;
 92     double mUpdateInterval;
 93     Float32 mThreshold;
 94 
 95     AudioBufferList mMixBuffer;
 96     int mMixBufferFrameCapacity;    // number of frames that can currently be stored in mix buffer
 97 
 98     // Audio parameters
 99     UInt32 mSampleRate;
100     UInt32 mChannels;
101     UInt32 mMaxFrames;
102     UInt32 mSamplesPerInterval;
103 
104     bool mRebuildCrunch;
105 
106     // GStreamer
107     GstElement *mSpectrumElement;
108     GstSpectrum *mSpectrum;
109 
110     void lockBands() {
111         pthread_mutex_lock(&mBandLock);
112     }
113 
114     void unlockBands() {
115         pthread_mutex_unlock(&mBandLock);
116     }
117 
118     void SetupSpectralProcessor();
119     void ReleaseSpectralProcessor();
120 };
121 
122 typedef std::shared_ptr<AVFAudioSpectrumUnit> AVFAudioSpectrumUnitPtr;
123 
124 #endif /* defined(__JFXMedia__AVFAudioSpectrumUnit__) */