summaryrefslogtreecommitdiffstats
path: root/media/libmedia/mediaplayer.cpp
diff options
context:
space:
mode:
authorMarco Nelissen <marcone@google.com>2009-09-20 10:42:13 -0700
committerMarco Nelissen <marcone@google.com>2009-10-06 08:51:16 -0700
commitc39d2e3c012fb96999991e30659a474f9f30f789 (patch)
treef3312cf6fee6b373f0e6486de4013e986eba552d /media/libmedia/mediaplayer.cpp
parent52cde7279bad58285704498eea57bdaf9e595b49 (diff)
downloadframeworks_base-c39d2e3c012fb96999991e30659a474f9f30f789.zip
frameworks_base-c39d2e3c012fb96999991e30659a474f9f30f789.tar.gz
frameworks_base-c39d2e3c012fb96999991e30659a474f9f30f789.tar.bz2
Music visualizer support hack.
This currently assumes 44k stereo (won't crash on other formats, but won't give the correct results either), and links statically with libspeex to get FFT data, increasing the size of libmedia by about 45kb.
Diffstat (limited to 'media/libmedia/mediaplayer.cpp')
-rw-r--r--media/libmedia/mediaplayer.cpp57
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