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 <system/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 // Declared 'final' because we call this in ~Visualizer(). 77 status_t setEnabled(bool enabled) final; 78 79 // maximum capture size in samples getMaxCaptureSize()80 static uint32_t getMaxCaptureSize() { return VISUALIZER_CAPTURE_SIZE_MAX; } 81 // minimum capture size in samples getMinCaptureSize()82 static uint32_t getMinCaptureSize() { return VISUALIZER_CAPTURE_SIZE_MIN; } 83 // maximum capture rate in millihertz getMaxCaptureRate()84 static uint32_t getMaxCaptureRate() { return CAPTURE_RATE_MAX; } 85 86 // callback used to return periodic PCM or FFT captures to the application. Either one or both 87 // types of data are returned (PCM and FFT) according to flags indicated when installing the 88 // callback. When a type of data is not present, the corresponding size (waveformSize or 89 // fftSize) is 0. 90 typedef void (*capture_cbk_t)(void* user, 91 uint32_t waveformSize, 92 uint8_t *waveform, 93 uint32_t fftSize, 94 uint8_t *fft, 95 uint32_t samplingrate); 96 97 // install a callback to receive periodic captures. The capture rate is specified in milliHertz 98 // and the capture format is according to flags (see callback_flags). 99 status_t setCaptureCallBack(capture_cbk_t cbk, void* user, uint32_t flags, uint32_t rate); 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 void release(); 136 137 protected: 138 // from IEffectClient 139 virtual void controlStatusChanged(bool controlGranted); 140 141 private: 142 143 static const uint32_t CAPTURE_RATE_MAX = 20000; 144 static const uint32_t CAPTURE_RATE_DEF = 10000; 145 static const uint32_t CAPTURE_SIZE_DEF = VISUALIZER_CAPTURE_SIZE_MAX; 146 147 /* internal class to handle the callback */ 148 class CaptureThread : public Thread 149 { 150 public: 151 CaptureThread(Visualizer* visualizer, uint32_t captureRate, bool bCanCallJava = false); 152 153 private: 154 friend class Visualizer; 155 virtual bool threadLoop(); 156 wp<Visualizer> mReceiver; 157 Mutex mLock; 158 uint32_t mSleepTimeUs; 159 }; 160 161 status_t doFft(uint8_t *fft, uint8_t *waveform); 162 void periodicCapture(); 163 uint32_t initCaptureSize(); 164 165 Mutex mCaptureLock; 166 uint32_t mCaptureRate; 167 uint32_t mCaptureSize; 168 uint32_t mSampleRate; 169 uint32_t mScalingMode; 170 uint32_t mMeasurementMode; 171 capture_cbk_t mCaptureCallBack; 172 void *mCaptureCbkUser; 173 sp<CaptureThread> mCaptureThread; 174 uint32_t mCaptureFlags; 175 }; 176 177 178 }; // namespace android 179 180 #endif // ANDROID_MEDIA_VISUALIZER_H 181