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