diff options
Diffstat (limited to 'media/libmedia/mediaplayer.cpp')
-rw-r--r-- | media/libmedia/mediaplayer.cpp | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp index aeb43c5..040366b 100644 --- a/media/libmedia/mediaplayer.cpp +++ b/media/libmedia/mediaplayer.cpp @@ -690,4 +690,61 @@ MediaPlayer::DeathNotifier::~DeathNotifier() } +extern "C" { +#define FLOATING_POINT 1 +#include "fftwrap.h" +} + +static void *ffttable = NULL; + +// peeks at the audio data and fills 'data' with the requested kind +// (currently kind=0 returns mono 16 bit PCM data, and kind=1 returns +// 256 point FFT data). Return value is number of samples returned, +// which may be 0. +/*static*/ int MediaPlayer::snoop(short* data, int len, int kind) { + + sp<IMemory> p; + const sp<IMediaPlayerService>& service = getMediaPlayerService(); + if (service != 0) { + // Take a peek at the waveform. The returned data consists of 16 bit mono PCM data. + p = service->snoop(); + + if (p == NULL) { + return 0; + } + + if (kind == 0) { // return waveform data + int plen = p->size(); + len *= 2; // number of shorts -> number of bytes + short *src = (short*) p->pointer(); + if (plen > len) { + plen = len; + } + memcpy(data, src, plen); + return plen / sizeof(short); // return number of samples + } else if (kind == 1) { + // TODO: use a more efficient FFT + // Right now this uses the speex library, which is compiled to do a float FFT + if (!ffttable) ffttable = spx_fft_init(512); + short *usrc = (short*) p->pointer(); + float fsrc[512]; + for (int i=0;i<512;i++) + fsrc[i] = usrc[i]; + float fdst[512]; + spx_fft_float(ffttable, fsrc, fdst); + if (len > 512) { + len = 512; + } + len /= 2; // only half the output data is valid + for (int i=0; i < len; i++) + data[i] = fdst[i]; + return len; + } + + } else { + LOGE("Unable to locate media service"); + } + return 0; +} + }; // namespace android |