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 79 static uint32_t getMaxCaptureSize() { return VISUALIZER_CAPTURE_SIZE_MAX; } 80 // minimum capture size in samples 81 static uint32_t getMinCaptureSize() { return VISUALIZER_CAPTURE_SIZE_MIN; } 82 // maximum capture rate in millihertz 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 100 // set the capture size capture size must be a power of two in the range 101 // [VISUALIZER_CAPTURE_SIZE_MAX. VISUALIZER_CAPTURE_SIZE_MIN] 102 // must be called when the visualizer is not enabled 103 status_t setCaptureSize(uint32_t size); 104 uint32_t getCaptureSize() { return mCaptureSize; } 105 106 // returns the capture rate indicated when installing the callback 107 uint32_t getCaptureRate() { return mCaptureRate; } 108 109 // returns the sampling rate of the audio being captured 110 uint32_t getSamplingRate() { return mSampleRate; } 111 112 // set the way volume affects the captured data 113 // mode must one of VISUALIZER_SCALING_MODE_NORMALIZED, 114 // VISUALIZER_SCALING_MODE_AS_PLAYED 115 status_t setScalingMode(uint32_t mode); 116 uint32_t getScalingMode() { return mScalingMode; } 117 118 // set which measurements are done on the audio buffers processed by the effect. 119 // valid measurements (mask): MEASUREMENT_MODE_PEAK_RMS 120 status_t setMeasurementMode(uint32_t mode); 121 uint32_t getMeasurementMode() { return mMeasurementMode; } 122 123 // return a set of int32_t measurements 124 status_t getIntMeasurements(uint32_t type, uint32_t number, int32_t *measurements); 125 126 // return a capture in PCM 8 bit unsigned format. The size of the capture is equal to 127 // getCaptureSize() 128 status_t getWaveForm(uint8_t *waveform); 129 130 // return a capture in FFT 8 bit signed format. The size of the capture is equal to 131 // getCaptureSize() but the length of the FFT is half of the size (both parts of the spectrum 132 // are returned 133 status_t getFft(uint8_t *fft); 134 135 protected: 136 // from IEffectClient 137 virtual void controlStatusChanged(bool controlGranted); 138 139 private: 140 141 static const uint32_t CAPTURE_RATE_MAX = 20000; 142 static const uint32_t CAPTURE_RATE_DEF = 10000; 143 static const uint32_t CAPTURE_SIZE_DEF = VISUALIZER_CAPTURE_SIZE_MAX; 144 145 /* internal class to handle the callback */ 146 class CaptureThread : public Thread 147 { 148 public: 149 CaptureThread(Visualizer& receiver, uint32_t captureRate, bool bCanCallJava = false); 150 151 private: 152 friend class Visualizer; 153 virtual bool threadLoop(); 154 Visualizer& mReceiver; 155 Mutex mLock; 156 uint32_t mSleepTimeUs; 157 }; 158 159 status_t doFft(uint8_t *fft, uint8_t *waveform); 160 void periodicCapture(); 161 uint32_t initCaptureSize(); 162 163 Mutex mCaptureLock; 164 uint32_t mCaptureRate; 165 uint32_t mCaptureSize; 166 uint32_t mSampleRate; 167 uint32_t mScalingMode; 168 uint32_t mMeasurementMode; 169 capture_cbk_t mCaptureCallBack; 170 void *mCaptureCbkUser; 171 sp<CaptureThread> mCaptureThread; 172 uint32_t mCaptureFlags; 173 }; 174 175 176 }; // namespace android 177 178 #endif // ANDROID_MEDIA_VISUALIZER_H 179