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 <string.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(int32_t priority = 0, 69 effect_callback_t cbf = NULL, 70 void* user = NULL, 71 int sessionId = 0); 72 73 ~Visualizer(); 74 75 virtual status_t setEnabled(bool enabled); 76 77 // maximum capture size in samples getMaxCaptureSize()78 static uint32_t getMaxCaptureSize() { return VISUALIZER_CAPTURE_SIZE_MAX; } 79 // minimum capture size in samples getMinCaptureSize()80 static uint32_t getMinCaptureSize() { return VISUALIZER_CAPTURE_SIZE_MIN; } 81 // maximum capture rate in millihertz getMaxCaptureRate()82 static uint32_t getMaxCaptureRate() { return CAPTURE_RATE_MAX; } 83 84 // callback used to return periodic PCM or FFT captures to the application. Either one or both 85 // types of data are returned (PCM and FFT) according to flags indicated when installing the 86 // callback. When a type of data is not present, the corresponding size (waveformSize or 87 // fftSize) is 0. 88 typedef void (*capture_cbk_t)(void* user, 89 uint32_t waveformSize, 90 uint8_t *waveform, 91 uint32_t fftSize, 92 uint8_t *fft, 93 uint32_t samplingrate); 94 95 // install a callback to receive periodic captures. The capture rate is specified in milliHertz 96 // and the capture format is according to flags (see callback_flags). 97 status_t setCaptureCallBack(capture_cbk_t cbk, void* user, uint32_t flags, uint32_t rate); 98 99 // set the capture size capture size must be a power of two in the range 100 // [VISUALIZER_CAPTURE_SIZE_MAX. VISUALIZER_CAPTURE_SIZE_MIN] 101 // must be called when the visualizer is not enabled 102 status_t setCaptureSize(uint32_t size); getCaptureSize()103 uint32_t getCaptureSize() { return mCaptureSize; } 104 105 // returns the capture rate indicated when installing the callback getCaptureRate()106 uint32_t getCaptureRate() { return mCaptureRate; } 107 108 // returns the sampling rate of the audio being captured getSamplingRate()109 uint32_t getSamplingRate() { return mSampleRate; } 110 111 // set the way volume affects the captured data 112 // mode must one of VISUALIZER_SCALING_MODE_NORMALIZED, 113 // VISUALIZER_SCALING_MODE_AS_PLAYED 114 status_t setScalingMode(uint32_t mode); getScalingMode()115 uint32_t getScalingMode() { return mScalingMode; } 116 117 // return a capture in PCM 8 bit unsigned format. The size of the capture is equal to 118 // getCaptureSize() 119 status_t getWaveForm(uint8_t *waveform); 120 121 // return a capture in FFT 8 bit signed format. The size of the capture is equal to 122 // getCaptureSize() but the length of the FFT is half of the size (both parts of the spectrum 123 // are returned 124 status_t getFft(uint8_t *fft); 125 126 protected: 127 // from IEffectClient 128 virtual void controlStatusChanged(bool controlGranted); 129 130 private: 131 132 static const uint32_t CAPTURE_RATE_MAX = 20000; 133 static const uint32_t CAPTURE_RATE_DEF = 10000; 134 static const uint32_t CAPTURE_SIZE_DEF = VISUALIZER_CAPTURE_SIZE_MAX; 135 136 /* internal class to handle the callback */ 137 class CaptureThread : public Thread 138 { 139 public: 140 CaptureThread(Visualizer& receiver, uint32_t captureRate, bool bCanCallJava = false); 141 142 private: 143 friend class Visualizer; 144 virtual bool threadLoop(); 145 virtual status_t readyToRun(); 146 virtual void onFirstRef(); 147 Visualizer& mReceiver; 148 Mutex mLock; 149 uint32_t mSleepTimeUs; 150 }; 151 152 status_t doFft(uint8_t *fft, uint8_t *waveform); 153 void periodicCapture(); 154 uint32_t initCaptureSize(); 155 156 Mutex mCaptureLock; 157 uint32_t mCaptureRate; 158 uint32_t mCaptureSize; 159 uint32_t mSampleRate; 160 uint32_t mScalingMode; 161 capture_cbk_t mCaptureCallBack; 162 void *mCaptureCbkUser; 163 sp<CaptureThread> mCaptureThread; 164 uint32_t mCaptureFlags; 165 }; 166 167 168 }; // namespace android 169 170 #endif // ANDROID_MEDIA_VISUALIZER_H 171