音乐律动Demo
来源:互联网 发布:python遗传算法工具包 编辑:程序博客网 时间:2024/04/27 13:22
本程序为用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;
}
}
- 音乐律动Demo
- 音乐在线播放Demo
- android音乐播放demo
- android_56_Service_音乐播放demo
- 本地音乐查询播放Demo
- 音乐播放demo知识点总结
- Android音乐播放器demo
- 音乐类Demo资源大全
- 点击按钮播放音乐的demo
- Android demo 01,音乐显示列表
- IOS-音乐播放器(附Demo)
- iOS 音乐播放Tool (配Demo下载)
- 【demo】react+webpack音乐播放器
- iOS 音乐播放器demo讲解
- 能实现播放本地音乐的Demo
- android 多媒体之播放网络音乐demo
- demo-musicGet(爬取音乐数据笔记)
- 婉约、律动的浅夏
- NLP资源(转载)
- C# sqlserver 之 数据库DAO的类集合!
- 【Oracle】Solaris10下安装Oracle,报错:Xlib:connection to ":0.0" refused by server Xlib:No protocol specified
- [Android 性能优化系列]布局篇之动态加载布局
- 中介者模式
- 音乐律动Demo
- Vivado开发工具熟悉之工具使用杂记
- 关于 IOS 百度地图API viewForOverlay viewForAnnotation 等Override 无法执行问题
- Differences between Thumb and ARM instruction sets
- 编码规范总结 源自bootstrap
- MySQL COUNT(*) INNER JOIN 内连接查询
- golang中image/draw包用法
- jQuery.extend和jQuery.fn.extend的区别
- Openwrt 编译添加模块 Package