Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing the Android media stream for audio visualization

Tags:

Basically, I want to make an audio visualizer. I know it's possible, because my phone came with a few live wallpapers that do it. The problem is, I can't seem to figure out how to do this with the Android API.

My app would pick up the currently playing media stream and then depending upon the volume that is playing at that time, it would display more or less bars on the screen.

How can I do this? It looks like I could do something like this using the microphone, but I want to be able to do it for music, podcasts, etc.

like image 210
HenryAdamsJr Avatar asked Aug 26 '10 03:08

HenryAdamsJr


3 Answers

It looks like in 2.3 things have changed here, there is permissions now

<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>

And there is a AudioCapture helper class in the aosp to help the live wallpapers do it properly. https://android.googlesource.com/platform/packages/wallpapers/MusicVisualization/+/gingerbread-release/src/com/android/musicvis/AudioCapture.java

Edit:

One of the imports in the AOSP doesn't match the public api.
import android.media.audiofx.Visualizer;

it is
import android.media.Visualizer;

if it gives a headache make sure to switch. This is all 2.3 api, it apparently returns a low-resolution audio stream for viz, but not good enough for recording.

like image 50
HaMMeReD Avatar answered Oct 03 '22 05:10

HaMMeReD


The MusicVisualization wallpaper source is available at the AOSP. It basically seems to involve calling MediaPlayer.snoop(), an undocumented method added in Eclair.

like image 29
adietrich Avatar answered Oct 03 '22 05:10

adietrich


Basically what roskit said except with a minor return value modification from

return 0;

to

return Integer.parseInt( (m.invoke(c, outData, kind)).toString() );

In other words:

public static int snoop(short [] outData, int kind){    
              try {
                  Class c = MediaPlayer.class;
                  Method m = c.getMethod("snoop", outData.getClass(), Integer.TYPE);
                  m.setAccessible(true);
                  return Integer.parseInt( (m.invoke(c, outData, kind)).toString() ); 
              } catch (Exception e) {
               // TODO Auto-generated catch block
               e.printStackTrace();
               return 1;
           }
    }
like image 23
aschyiel Avatar answered Oct 03 '22 03:10

aschyiel