本程序为用Visualizer和AudioRecord实现的音乐律动Demo,共享给大家。同时具有基本音乐播放器的雏形,可以搜索本机所有音乐,并可以切换歌曲。歌曲使用SimpleAdapter绑定在ListView上。可以随意切换歌曲。
主Activity
public class YymdActivity extends Activity {
/**
* 主Activity相关控件
*/
private TextView showTitle = null, showArtist = null;
private Button previousSong = null, playOrPause = null, nextSong = null;
private ListView musicListView = null;
private List<Music> musicInfos = null;
/* 音乐频谱 */
private MediaPlayer mMediaPlayer = null;
private Visualizer mVisualizer = null;
private static final int RATE = 1024;// 注意
/* 音乐分贝 */
private static final int SAMPLE_RATE_IN_HZ = 8000;
private static final int BUFFER_SIZE = AudioRecord.getMinBufferSize(
SAMPLE_RATE_IN_HZ, AudioFormat.CHANNEL_IN_DEFAULT,
AudioFormat.ENCODING_PCM_16BIT);
private AudioRecord mAudioRecord = null;
private boolean isRunning = true;
private Object mLock;
private static final int WAITING = 50; // 等待时间
private Handler handler = null;
/* 和音乐播放相关 */
private int current_position = 0;
private boolean isFirstTime = true;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.music);
/* 处理通信 */
handler = new Handler() {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
double volume = (Double) msg.obj;// 分贝值
byte[] fft = new byte[1024];
mVisualizer.getFft(fft);
int color = getColor(fft);// 得到颜色值
/* 把颜色值传出去就成了 */
System.out.println("volume:" + volume);
System.out.println("color:" + color);
}
};
findViewsById();
musicInfos = findMusic(this);
initListView(musicInfos);
musicListView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
current_position = arg2;
playMusic(arg2);
}
});
/* 音乐频谱部分 */
mMediaPlayer = new MediaPlayer();
mVisualizer = new Visualizer(mMediaPlayer.getAudioSessionId());
mVisualizer
.setCaptureSize(mVisualizer.getCaptureSizeRange()[mVisualizer
.getCaptureSizeRange().length - 1]);// 注意
mMediaPlayer.setOnCompletionListener(new OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
// TODO Auto-generated method stub
mVisualizer.setEnabled(false);
isRunning = false;
}
});
/* 处理分贝 */
mLock = new Object();
mAudioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,
SAMPLE_RATE_IN_HZ, AudioFormat.CHANNEL_IN_DEFAULT,
AudioFormat.ENCODING_PCM_16BIT, BUFFER_SIZE);
if (mAudioRecord == null) {
Toast.makeText(this, "AudioRecord初始化失败", Toast.LENGTH_SHORT).show();
}
}
/**
* 录音分析分贝的Runnable类
*
* @author Leo
*
*/
private class RecordRunnable implements Runnable {
public void run() {
mAudioRecord.startRecording();
short[] buffer = new short[BUFFER_SIZE];
while (isRunning) {
int r = mAudioRecord.read(buffer, 0, BUFFER_SIZE);
long v = 0;
for (int i = 0; i < buffer.length; i++) {
v += buffer[i] * buffer[i];
}
double mean = v / (double) r;
double volume = 10 * Math.log10(mean);
System.out.println("声音大小:" + volume + "分贝");
Message msg = new Message();
msg.obj = volume;
handler.sendMessage(msg);
synchronized (mLock) {
try {
mLock.wait(WAITING);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
mVisualizer.setEnabled(false);
mAudioRecord.stop();
}
}
/**
* 根据频率比重最大得到颜色
*
* @param fft
* @return
*/
private int getColor(byte[] fft) {
byte[] model = fft2Model(fft);
int w = 0;
byte max = model[0];
for (int i = 1; i < model.length; i++) {
if (model[i] > max) {
max = model[i];
w = i;
}
}
return setColorByW(w);
}
/**
* 设置颜色
*
* @param w
* @return
*/
private int setColorByW(int w) {
int color = Color.rgb(0, 0, 0);
switch (w % 7) {
case 0:
color = Color.RED;
break;
case 1:
color = Color.BLUE;
break;
case 2:
color = Color.GREEN;
break;
case 3:
color = Color.YELLOW;
break;
case 4:
color = Color.CYAN;
break;
case 5:
color = Color.MAGENTA;
break;
case 6:
color = Color.GREEN;
break;
default:
color = Color.WHITE;
break;
}
return color;
}
/**
* fft转成振幅
*
* @param fft
* @return
*/
private byte[] fft2Model(byte[] fft) {
byte[] model = new byte[fft.length / 2 + 1];
model[0] = (byte) Math.abs(fft[0]);
for (int i = 2, j = 1; i < fft.length - 1; i += 2, j++) {
model[j] = (byte) Math.hypot(fft[i], fft[i + 1]);
}
return model;
}
/**
* 把音乐绑定到ListView
*
* @param list
*/
private void initListView(List<Music> list) {
/*
* 生成适配器并绑定到ListView上绑定监听器
*/
List<Map<String, Object>> musicList = new ArrayList<Map<String, Object>>();
for (Music m : list) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("music_title", m.getTitle());
map.put("music_artist", m.getArtist());
musicList.add(map);
}
SimpleAdapter adapter = new SimpleAdapter(this, musicList,
R.layout.music_item, new String[] { "music_title",
"music_artist" }, new int[] { R.id.music_title,
R.id.music_artist });
musicListView.setAdapter(adapter);
}
/**
* 根据id得到控件
*/
private void findViewsById() {
musicListView = (ListView) findViewById(R.id.music_listView);// 得到控件
showTitle = (TextView) findViewById(R.id.show_title);
showArtist = (TextView) findViewById(R.id.show_artist);
previousSong = (Button) findViewById(R.id.previous_song);
nextSong = (Button) findViewById(R.id.next_song);
playOrPause = (Button) findViewById(R.id.play_pause);
previousSong.setOnClickListener(listener);
nextSong.setOnClickListener(listener);
playOrPause.setOnClickListener(listener);
}
private View.OnClickListener listener = new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
int id = v.getId();
switch (id) {
case R.id.previous_song:
previousMusic();
break;
case R.id.play_pause:
playOrPauseMusic();
break;
case R.id.next_song:
nextMusic();
break;
default:
Toast.makeText(YymdActivity.this, "您太厉害了,我真的不知道您按了哪个按钮",
Toast.LENGTH_SHORT).show();
break;
}
}
};
private void playOrPauseMusic() {
if (mMediaPlayer == null) {
return;
}
if (mMediaPlayer.isPlaying()) {
isRunning = false;
mMediaPlayer.pause();
playOrPause.setText("播放");
} else {
if (isFirstTime) {
playMusic(current_position);
return;
}
mMediaPlayer.start();
mVisualizer.setEnabled(true);
isRunning = true;
new Thread(new RecordRunnable()).start();
playOrPause.setText("暂停");
}
}
private void playMusic(int position) {
if (mMediaPlayer == null) {
return;
}
isRunning = false;
Music music = musicInfos.get(position);
showTitle.setText(music.getTitle());
showArtist.setText(music.getArtist());
try {
mMediaPlayer.reset();
mMediaPlayer.setDataSource(music.getData());
mMediaPlayer.prepare();
mMediaPlayer.start();
isFirstTime = false;
mVisualizer.setEnabled(true);
isRunning = true;
new Thread(new RecordRunnable()).start();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 上一曲
*/
private void previousMusic() {
int position = current_position - 1;
if (position < 0) {
position = musicInfos.size() - 1;
}
current_position = position;
playMusic(position);
}
/**
* 下一曲
*/
private void nextMusic() {
int position = current_position + 1;
if (position >= musicInfos.size()) {
position = 0;
}
current_position = position;
playMusic(position);
}
/**
* 查找本地音乐放到List<Music>里面
*
* @param context
* @return
*/
private List<Music> findMusic(Context context) {
Cursor cursor = context.getContentResolver().query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null,
MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
List<Music> musicInfos = new ArrayList<Music>();
while (cursor.moveToNext()) {
int indexTitle = cursor
.getColumnIndex(MediaStore.Audio.AudioColumns.TITLE);
int indexArtist = cursor
.getColumnIndex(MediaStore.Audio.AudioColumns.ARTIST);
int indexData = cursor
.getColumnIndex(MediaStore.Audio.AudioColumns.DATA);
String title = cursor.getString(indexTitle);
String artist = cursor.getString(indexArtist);
String data = cursor.getString(indexData);
Music music = new Music();
music.setTitle(title);
music.setArtist(artist);
music.setData(data);
musicInfos.add(music);
}
return musicInfos;
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
isRunning = false;
if (mAudioRecord != null) {
mAudioRecord.stop();
mAudioRecord.release();
}
if (mVisualizer != null) {
if (mVisualizer.getEnabled()) {
mVisualizer.setEnabled(false);
}
mVisualizer.release();
}
if (mMediaPlayer != null) {
if (mMediaPlayer.isPlaying()) {
mMediaPlayer.stop();
}
mMediaPlayer.release();
}
super.onDestroy();
}
}
Music类:
package com.leo.yymd;
public class Music {
private String title;
private String artist;
private String data;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getArtist() {
return artist;
}
public void setArtist(String artist) {
this.artist = artist;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
}