diff options
author | Eric Laurent <elaurent@google.com> | 2010-07-02 08:12:41 -0700 |
---|---|---|
committer | Eric Laurent <elaurent@google.com> | 2010-07-07 11:00:28 -0700 |
commit | df9b81ced437b11f8a3fcf4ba3ea6af703d121e2 (patch) | |
tree | c80b989df744ea74f62c800a8848813174792cc2 /include | |
parent | 31e0ffe8444b70500cac319da084c4c45e62aca2 (diff) | |
download | frameworks_base-df9b81ced437b11f8a3fcf4ba3ea6af703d121e2.zip frameworks_base-df9b81ced437b11f8a3fcf4ba3ea6af703d121e2.tar.gz frameworks_base-df9b81ced437b11f8a3fcf4ba3ea6af703d121e2.tar.bz2 |
Added Visualizer effect.
The visualizer enables application to retrieve part of the currently playing audio for visualization purpose.
It is not an audio recording interface and only returns partial and low quality audio content as a waveform or
a frequency representation (FFT).
Removed temporary hack made in MediaPlayer for animated wall papers based on audio visualization (snoop() method.
This commit also includes a change in AudioEffect class:
- the enable()/disable() methods have been replaced bya more standard setEnabled() method.
- some fixes in javadoc
Change-Id: Id092a1340e9e38dae68646ade7be054e3a36980e
Diffstat (limited to 'include')
-rw-r--r-- | include/media/AudioEffect.h | 70 | ||||
-rw-r--r-- | include/media/EffectVisualizerApi.h | 55 | ||||
-rw-r--r-- | include/media/IMediaPlayerService.h | 4 | ||||
-rw-r--r-- | include/media/Visualizer.h | 160 | ||||
-rw-r--r-- | include/media/mediaplayer.h | 1 |
5 files changed, 252 insertions, 38 deletions
diff --git a/include/media/AudioEffect.h b/include/media/AudioEffect.h index 66670f3..e9ff8a3 100644 --- a/include/media/AudioEffect.h +++ b/include/media/AudioEffect.h @@ -307,29 +307,18 @@ public: int32_t priority() const { return mPriority; } - /* Enables the effect engine. + /* Enables or disables the effect engine. * * Parameters: - * None. + * enabled: requested enable state. * * Returned status (from utils/Errors.h) can be: * - NO_ERROR: successful operation - * - INVALID_OPERATION: the application does not have control of the effect engine + * - INVALID_OPERATION: the application does not have control of the effect engine or the + * effect is already in the requested state. */ - status_t enable(); - - /* Disables the effect engine. - * - * Parameters: - * None. - * - * Returned status (from utils/Errors.h) can be: - * - NO_ERROR: successful operation - * - INVALID_OPERATION: the application does not have control of the effect engine - */ - status_t disable(); - - bool isEnabled() const; + virtual status_t setEnabled(bool enabled); + bool getEnabled() const; /* Sets a parameter value. * @@ -342,7 +331,7 @@ public: * - BAD_VALUE: invalid parameter identifier or value. * - DEAD_OBJECT: the effect engine has been deleted. */ - status_t setParameter(effect_param_t *param); + virtual status_t setParameter(effect_param_t *param); /* Prepare a new parameter value that will be set by next call to * setParameterCommit(). This method can be used to set multiple parameters @@ -359,7 +348,7 @@ public: * - NO_MEMORY: no more space available in shared memory used for deferred parameter * setting. */ - status_t setParameterDeferred(effect_param_t *param); + virtual status_t setParameterDeferred(effect_param_t *param); /* Commit all parameter values previously prepared by setParameterDeferred(). * @@ -373,7 +362,7 @@ public: * as to which of the parameters caused this error. * - DEAD_OBJECT: the effect engine has been deleted. */ - status_t setParameterCommit(); + virtual status_t setParameterCommit(); /* Gets a parameter value. * @@ -387,13 +376,17 @@ public: * - BAD_VALUE: invalid parameter identifier. * - DEAD_OBJECT: the effect engine has been deleted. */ - status_t getParameter(effect_param_t *param); + virtual status_t getParameter(effect_param_t *param); /* Sends a command and receives a response to/from effect engine. * See EffectApi.h for details on effect command() function, valid command codes * and formats. */ - status_t command(int32_t cmdCode, int32_t cmdSize, void *cmdData, int32_t *replySize, void *replyData); + virtual status_t command(int32_t cmdCode, + int32_t cmdSize, + void *cmdData, + int32_t *replySize, + void *replyData); /* @@ -409,6 +402,17 @@ public: */ static status_t guidToString(const effect_uuid_t *guid, char *str, size_t maxLen); +protected: + volatile int32_t mEnabled; // enable state + int32_t mSessionId; // audio session ID + int32_t mPriority; // priority for effect control + status_t mStatus; // effect status + effect_callback_t mCbf; // callback function for status, control and + // parameter changes notifications + void* mUserData; // client context for callback function + effect_descriptor_t mDescriptor; // effect descriptor + int32_t mId; // system wide unique effect engine instance ID + private: // Implements the IEffectClient interface @@ -419,9 +423,17 @@ private: EffectClient(AudioEffect *effect) : mEffect(effect){} // IEffectClient - virtual void controlStatusChanged(bool controlGranted) {mEffect->controlStatusChanged(controlGranted);} - virtual void enableStatusChanged(bool enabled) {mEffect->enableStatusChanged(enabled);} - virtual void commandExecuted(int cmdCode, int cmdSize, void *pCmdData, int replySize, void *pReplyData) { + virtual void controlStatusChanged(bool controlGranted) { + mEffect->controlStatusChanged(controlGranted); + } + virtual void enableStatusChanged(bool enabled) { + mEffect->enableStatusChanged(enabled); + } + virtual void commandExecuted(int cmdCode, + int cmdSize, + void *pCmdData, + int replySize, + void *pReplyData) { mEffect->commandExecuted(cmdCode, cmdSize, pCmdData, replySize, pReplyData); } @@ -446,14 +458,6 @@ private: sp<EffectClient> mIEffectClient; // IEffectClient implementation sp<IMemory> mCblkMemory; // shared memory for deferred parameter setting effect_param_cblk_t* mCblk; // control block for deferred parameter setting - int32_t mPriority; // priority for effect control - status_t mStatus; // effect status - volatile int32_t mEnabled; // enable state - effect_callback_t mCbf; // callback function for status, control, parameter changes notifications - void* mUserData; // client context for callback function - effect_descriptor_t mDescriptor; // effect descriptor - int32_t mId; // system wide unique effect engine instance identifier - int32_t mSessionId; // audio session ID }; diff --git a/include/media/EffectVisualizerApi.h b/include/media/EffectVisualizerApi.h new file mode 100644 index 0000000..1155db8 --- /dev/null +++ b/include/media/EffectVisualizerApi.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_EFFECTVISUALIZERAPI_H_ +#define ANDROID_EFFECTVISUALIZERAPI_H_ + +#include <media/EffectApi.h> + +#if __cplusplus +extern "C" { +#endif + +//TODO replace by openSL ES include when available +static const effect_uuid_t SL_IID_VISUALIZATION_ = + { 0xe46b26a0, 0xdddd, 0x11db, 0x8afd, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } }; +const effect_uuid_t * const SL_IID_VISUALIZATION = &SL_IID_VISUALIZATION_; + +#define VISUALIZER_CAPTURE_SIZE_MAX 1024 // maximum capture size in samples +#define VISUALIZER_CAPTURE_SIZE_MIN 128 // minimum capture size in samples + +/* enumerated parameters for Visualizer effect */ +typedef enum +{ + VISU_PARAM_CAPTURE_SIZE, // Sets the number PCM samples in the capture. +} t_visualizer_params; + +/* commands */ +typedef enum +{ + VISU_CMD_CAPTURE = EFFECT_CMD_FIRST_PROPRIETARY, // Gets the latest PCM capture. +}t_visualizer_cmds; + +// VISU_CMD_CAPTURE retrieves the latest PCM snapshot captured by the visualizer engine. +// It returns the number of samples specified by VISU_PARAM_CAPTURE_SIZE +// in 8 bit unsigned format (0 = 0x80) + +#if __cplusplus +} // extern "C" +#endif + + +#endif /*ANDROID_EFFECTVISUALIZERAPI_H_*/ diff --git a/include/media/IMediaPlayerService.h b/include/media/IMediaPlayerService.h index e892875..9416ca1 100644 --- a/include/media/IMediaPlayerService.h +++ b/include/media/IMediaPlayerService.h @@ -48,10 +48,6 @@ public: virtual sp<IMemory> decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat) = 0; virtual sp<IMemory> decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat) = 0; virtual sp<IOMX> getOMX() = 0; - - // Take a peek at currently playing audio, for visualization purposes. - // This returns a buffer of 16 bit mono PCM data, or NULL if no visualization buffer is currently available. - virtual sp<IMemory> snoop() = 0; }; // ---------------------------------------------------------------------------- diff --git a/include/media/Visualizer.h b/include/media/Visualizer.h new file mode 100644 index 0000000..5d51de8 --- /dev/null +++ b/include/media/Visualizer.h @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_MEDIA_VISUALIZER_H +#define ANDROID_MEDIA_VISUALIZER_H + +#include <media/AudioEffect.h> +#include <media/EffectVisualizerApi.h> +#include <string.h> + +/** + * The Visualizer class enables application to retrieve part of the currently playing audio for + * visualization purpose. It is not an audio recording interface and only returns partial and low + * quality audio content. However, to protect privacy of certain audio data (e.g voice mail) the use + * of the visualizer requires the permission android.permission.RECORD_AUDIO. + * The audio session ID passed to the constructor indicates which audio content should be + * visualized: + * - If the session is 0, the audio output mix is visualized + * - If the session is not 0, the audio from a particular MediaPlayer or AudioTrack + * using this audio session is visualized + * Two types of representation of audio content can be captured: + * - Waveform data: consecutive 8-bit (unsigned) mono samples by using the getWaveForm() method + * - Frequency data: 8-bit magnitude FFT by using the getFft() method + * + * The length of the capture can be retrieved or specified by calling respectively + * getCaptureSize() and setCaptureSize() methods. Note that the size of the FFT + * is half of the specified capture size but both sides of the spectrum are returned yielding in a + * number of bytes equal to the capture size. The capture size must be a power of 2 in the range + * returned by getMinCaptureSize() and getMaxCaptureSize(). + * In addition to the polling capture mode, a callback mode is also available by installing a + * callback function by use of the setCaptureCallBack() method. The rate at which the callback + * is called as well as the type of data returned is specified. + * Before capturing data, the Visualizer must be enabled by calling the setEnabled() method. + * When data capture is not needed any more, the Visualizer should be disabled. + */ + + +namespace android { + +// ---------------------------------------------------------------------------- + +class Visualizer: public AudioEffect { +public: + + enum callback_flags { + CAPTURE_WAVEFORM = 0x00000001, // capture callback returns a PCM wave form + CAPTURE_FFT = 0x00000002, // apture callback returns a frequency representation + CAPTURE_CALL_JAVA = 0x00000004 // the callback thread can call java + }; + + + /* Constructor. + * See AudioEffect constructor for details on parameters. + */ + Visualizer(int32_t priority = 0, + effect_callback_t cbf = 0, + void* user = 0, + int sessionId = 0); + + ~Visualizer(); + + virtual status_t setEnabled(bool enabled); + + // maximum capture size in samples + static uint32_t getMaxCaptureSize() { return VISUALIZER_CAPTURE_SIZE_MAX; } + // minimum capture size in samples + static uint32_t getMinCaptureSize() { return VISUALIZER_CAPTURE_SIZE_MIN; } + // maximum capture rate in millihertz + static uint32_t getMaxCaptureRate() { return CAPTURE_RATE_MAX; } + + // callback used to return periodic PCM or FFT captures to the application. Either one or both + // types of data are returned (PCM and FFT) according to flags indicated when installing the + // callback. When a type of data is not present, the corresponding size (waveformSize or + // fftSize) is 0. + typedef void (*capture_cbk_t)(void* user, + uint32_t waveformSize, + uint8_t *waveform, + uint32_t fftSize, + uint8_t *fft, + uint32_t samplingrate); + + // install a callback to receive periodic captures. The capture rate is specified in milliHertz + // and the capture format is according to flags (see callback_flags). + status_t setCaptureCallBack(capture_cbk_t cbk, void* user, uint32_t flags, uint32_t rate); + + // set the capture size capture size must be a power of two in the range + // [VISUALIZER_CAPTURE_SIZE_MAX. VISUALIZER_CAPTURE_SIZE_MIN] + // must be called when the visualizer is not enabled + status_t setCaptureSize(uint32_t size); + uint32_t getCaptureSize() { return mCaptureSize; } + + // returns the capture rate indicated when installing the callback + uint32_t getCaptureRate() { return mCaptureRate; } + + // returns the sampling rate of the audio being captured + uint32_t getSamplingRate() { return mSampleRate; } + + // return a capture in PCM 8 bit unsigned format. The size of the capture is equal to + // getCaptureSize() + status_t getWaveForm(uint8_t *waveform); + + // return a capture in FFT 8 bit signed format. The size of the capture is equal to + // getCaptureSize() but the length of the FFT is half of the size (both parts of the spectrum + // are returned + status_t getFft(uint8_t *fft); + +private: + + static const uint32_t CAPTURE_RATE_MAX = 20000; + static const uint32_t CAPTURE_RATE_DEF = 10000; + static const uint32_t CAPTURE_SIZE_DEF = VISUALIZER_CAPTURE_SIZE_MAX; + + /* internal class to handle the callback */ + class CaptureThread : public Thread + { + public: + CaptureThread(Visualizer& receiver, uint32_t captureRate, bool bCanCallJava = false); + + private: + friend class Visualizer; + virtual bool threadLoop(); + virtual status_t readyToRun(); + virtual void onFirstRef(); + Visualizer& mReceiver; + Mutex mLock; + uint32_t mSleepTimeUs; + }; + + status_t doFft(uint8_t *fft, uint8_t *waveform); + void periodicCapture(); + uint32_t initCaptureSize(); + + Mutex mLock; + uint32_t mCaptureRate; + uint32_t mCaptureSize; + uint32_t mSampleRate; + capture_cbk_t mCaptureCallBack; + void *mCaptureCbkUser; + sp<CaptureThread> mCaptureThread; + uint32_t mCaptureFlags; + void *mFftTable; +}; + + +}; // namespace android + +#endif // ANDROID_MEDIA_VISUALIZER_H diff --git a/include/media/mediaplayer.h b/include/media/mediaplayer.h index 62a4e50..4963f73 100644 --- a/include/media/mediaplayer.h +++ b/include/media/mediaplayer.h @@ -166,7 +166,6 @@ public: void notify(int msg, int ext1, int ext2); static sp<IMemory> decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat); static sp<IMemory> decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat); - static int snoop(short *data, int len, int kind); status_t invoke(const Parcel& request, Parcel *reply); status_t setMetadataFilter(const Parcel& filter); status_t getMetadata(bool update_only, bool apply_filter, Parcel *metadata); |