1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ANDROID_MEDIA_VISUALIZER_H 18 #define ANDROID_MEDIA_VISUALIZER_H 19 20 #include <media/AudioEffect.h> 21 #include <audio_effects/effect_visualizer.h> 22 #include <utils/Thread.h> 23 24 /** 25 * The Visualizer class enables application to retrieve part of the currently playing audio for 26 * visualization purpose. It is not an audio recording interface and only returns partial and low 27 * quality audio content. However, to protect privacy of certain audio data (e.g voice mail) the use 28 * of the visualizer requires the permission android.permission.RECORD_AUDIO. 29 * The audio session ID passed to the constructor indicates which audio content should be 30 * visualized: 31 * - If the session is 0, the audio output mix is visualized 32 * - If the session is not 0, the audio from a particular MediaPlayer or AudioTrack 33 * using this audio session is visualized 34 * Two types of representation of audio content can be captured: 35 * - Waveform data: consecutive 8-bit (unsigned) mono samples by using the getWaveForm() method 36 * - Frequency data: 8-bit magnitude FFT by using the getFft() method 37 * 38 * The length of the capture can be retrieved or specified by calling respectively 39 * getCaptureSize() and setCaptureSize() methods. Note that the size of the FFT 40 * is half of the specified capture size but both sides of the spectrum are returned yielding in a 41 * number of bytes equal to the capture size. The capture size must be a power of 2 in the range 42 * returned by getMinCaptureSize() and getMaxCaptureSize(). 43 * In addition to the polling capture mode, a callback mode is also available by installing a 44 * callback function by use of the setCaptureCallBack() method. The rate at which the callback 45 * is called as well as the type of data returned is specified. 46 * Before capturing data, the Visualizer must be enabled by calling the setEnabled() method. 47 * When data capture is not needed any more, the Visualizer should be disabled. 48 */ 49 50 51 namespace android { 52 53 // ---------------------------------------------------------------------------- 54 55 class Visualizer: public AudioEffect { 56 public: 57 58 enum callback_flags { 59 CAPTURE_WAVEFORM = 0x00000001, // capture callback returns a PCM wave form 60 CAPTURE_FFT = 0x00000002, // apture callback returns a frequency representation 61 CAPTURE_CALL_JAVA = 0x00000004 // the callback thread can call java 62 }; 63 64 65 /* Constructor. 66 * See AudioEffect constructor for details on parameters. 67 */ 68 Visualizer(const String16& opPackageName, 69 int32_t priority = 0, 70 effect_callback_t cbf = NULL, 71 void* user = NULL, 72 audio_session_t sessionId = AUDIO_SESSION_OUTPUT_MIX); 73 74 ~Visualizer(); 75 76 virtual status_t setEnabled(bool enabled); 77 78 // maximum capture size in samples getMaxCaptureSize()79 static uint32_t getMaxCaptureSize() { return VISUALIZER_CAPTURE_SIZE_MAX; } 80 // minimum capture size in samples getMinCaptureSize()81 static uint32_t getMinCaptureSize() { return VISUALIZER_CAPTURE_SIZE_MIN; } 82 // maximum capture rate in millihertz getMaxCaptureRate()83 static uint32_t getMaxCaptureRate() { return CAPTURE_RATE_MAX; } 84 85 // callback used to return periodic PCM or FFT captures to the application. Either one or both 86 // types of data are returned (PCM and FFT) according to flags indicated when installing the 87 // callback. When a type of data is not present, the corresponding size (waveformSize or 88 // fftSize) is 0. 89 typedef void (*capture_cbk_t)(void* user, 90 uint32_t waveformSize, 91 uint8_t *waveform, 92 uint32_t fftSize, 93 uint8_t *fft, 94 uint32_t samplingrate); 95 96 // install a callback to receive periodic captures. The capture rate is specified in milliHertz 97 // and the capture format is according to flags (see callback_flags). 98 status_t setCaptureCallBack(capture_cbk_t cbk, void* user, uint32_t flags, uint32_t rate, 99 bool force = false); 100 101 // set the capture size capture size must be a power of two in the range 102 // [VISUALIZER_CAPTURE_SIZE_MAX. VISUALIZER_CAPTURE_SIZE_MIN] 103 // must be called when the visualizer is not enabled 104 status_t setCaptureSize(uint32_t size); getCaptureSize()105 uint32_t getCaptureSize() { return mCaptureSize; } 106 107 // returns the capture rate indicated when installing the callback getCaptureRate()108 uint32_t getCaptureRate() { return mCaptureRate; } 109 110 // returns the sampling rate of the audio being captured getSamplingRate()111 uint32_t getSamplingRate() { return mSampleRate; } 112 113 // set the way volume affects the captured data 114 // mode must one of VISUALIZER_SCALING_MODE_NORMALIZED, 115 // VISUALIZER_SCALING_MODE_AS_PLAYED 116 status_t setScalingMode(uint32_t mode); getScalingMode()117 uint32_t getScalingMode() { return mScalingMode; } 118 119 // set which measurements are done on the audio buffers processed by the effect. 120 // valid measurements (mask): MEASUREMENT_MODE_PEAK_RMS 121 status_t setMeasurementMode(uint32_t mode); getMeasurementMode()122 uint32_t getMeasurementMode() { return mMeasurementMode; } 123 124 // return a set of int32_t measurements 125 status_t getIntMeasurements(uint32_t type, uint32_t number, int32_t *measurements); 126 127 // return a capture in PCM 8 bit unsigned format. The size of the capture is equal to 128 // getCaptureSize() 129 status_t getWaveForm(uint8_t *waveform); 130 131 // return a capture in FFT 8 bit signed format. The size of the capture is equal to 132 // getCaptureSize() but the length of the FFT is half of the size (both parts of the spectrum 133 // are returned 134 status_t getFft(uint8_t *fft); 135 136 protected: 137 // from IEffectClient 138 virtual void controlStatusChanged(bool controlGranted); 139 140 private: 141 142 static const uint32_t CAPTURE_RATE_MAX = 20000; 143 static const uint32_t CAPTURE_RATE_DEF = 10000; 144 static const uint32_t CAPTURE_SIZE_DEF = VISUALIZER_CAPTURE_SIZE_MAX; 145 146 /* internal class to handle the callback */ 147 class CaptureThread : public Thread 148 { 149 public: 150 CaptureThread(Visualizer& receiver, uint32_t captureRate, bool bCanCallJava = false); 151 152 private: 153 friend class Visualizer; 154 virtual bool threadLoop(); 155 Visualizer& mReceiver; 156 Mutex mLock; 157 uint32_t mSleepTimeUs; 158 }; 159 160 status_t doFft(uint8_t *fft, uint8_t *waveform); 161 void periodicCapture(); 162 uint32_t initCaptureSize(); 163 164 Mutex mCaptureLock; 165 uint32_t mCaptureRate; 166 uint32_t mCaptureSize; 167 uint32_t mSampleRate; 168 uint32_t mScalingMode; 169 uint32_t mMeasurementMode; 170 capture_cbk_t mCaptureCallBack; 171 void *mCaptureCbkUser; 172 sp<CaptureThread> mCaptureThread; 173 uint32_t mCaptureFlags; 174 }; 175 176 177 }; // namespace android 178 179 #endif // ANDROID_MEDIA_VISUALIZER_H 180