zoukankan      html  css  js  c++  java
  • Android进阶——声波振幅显示

    最近博主想做一个app,中间有一个是录音的功能。于是博主想把UI做的好看一些,想仿照微信或者QQ语音输入时,能够随着声音的大小显示声波振幅。于是查找了一些资料,现在把这个功能的Demo分享给大家,以后也会把更多的项目学习到的知识分享给大家。

    其实这个功能主要是依靠MediaRecorder的getMaxAmplitude()方法来获得声音的振幅,然后依据计算公式分贝的计算公式K=20lg(Vo/Vi) Vo当前的振幅值,Vi基准值为600来获得分贝数然后在根据分贝来显示ImageView上的不同图片。这样就实现了声波振幅显示了。

    下面列出主要的函数,后面会给出录音显示声波振幅的Demo下载链接:

    	public RecordDialog(Context context){
    		this.context=context;
    		dialog_view=LayoutInflater.from(context).inflate(R.layout.dialog_sound, null);
    		
    		//初始化振幅图片
    		progressImg[0]=context.getResources().getDrawable(R.drawable.mic_1);
    		progressImg[1]=context.getResources().getDrawable(R.drawable.mic_2);
    		progressImg[2]=context.getResources().getDrawable(R.drawable.mic_3);
    		progressImg[3]=context.getResources().getDrawable(R.drawable.mic_4);
    		progressImg[4]=context.getResources().getDrawable(R.drawable.mic_5);
    		progressImg[5]=context.getResources().getDrawable(R.drawable.mic_6);
    		progressImg[6]=context.getResources().getDrawable(R.drawable.mic_7);
    		
    		dialog=new AlertDialog.Builder(context).setView(dialog_view).show();
    //		dialog.cancel();
    		
    		progress=(ImageView) dialog_view.findViewById(R.id.sound_progress);
    		btn_cancel=(ImageView) dialog_view.findViewById(R.id.cancel);
    		btn_submit=(TextView) dialog_view.findViewById(R.id.submit);
    		mic_icon=(ImageView) dialog.findViewById(R.id.mic);
    		dialog_title=(TextView) dialog.findViewById(R.id.title);
    		txt_msg=(TextView) dialog.findViewById(R.id.msg);
    		
    		btn_cancel.setOnClickListener(onCancel);
    		btn_submit.setOnClickListener(onSubmit);
    		}
    

      

    然后我们实现一个自定义的接口SoundAmplitudeListen用来处理获取分贝值之后显示不同的波动图片:

    private SoundAmplitudeListen onSoundAmplitudeListen=new SoundAmplitudeListen() {
    		
    		@SuppressWarnings("deprecation")
    		@Override
    		public void amplitude(int amplitude, int db, int value) {
    			// TODO Auto-generated method stub
    			if(value>=6){
    				value=6;
    			}
    			progress.setBackgroundDrawable(progressImg[value]);
    		}
    	};
    

      


    最后就是录音时处理分贝的RecodeManager类了:

     
    
    package com.example.voiceviewdemo;
    
    import java.io.File;
    import java.io.IOException;
    import java.util.Calendar;
    import java.util.Locale;
    
    import android.R.integer;
    import android.media.MediaRecorder;
    import android.os.Environment;
    import android.os.Handler;
    import android.text.format.DateFormat;
    
    public class RecodeManager {
    
    	private File file;//录音文件
    	private MediaRecorder mediaRecorder;//android 媒体录音类
    	private SoundAmplitudeListen soundAmplitudeListen;//声波振幅监听器
    	private final Handler mHandler=new Handler();
    	private Runnable mUpdateMicStatusTimer=new Runnable() {
    		/**
    		 * 分贝的计算公式K=20lg(Vo/Vi) Vo当前的振幅值,Vi基准值为600
    		 */
    		private int BASE=500;
    		private int RATIO=5;
    		private int postDelayed=200;
    		@Override
    		public void run() {
    			int ratio=mediaRecorder.getMaxAmplitude()/BASE;
    			int db=(int)(20*Math.log10(Math.abs(ratio)));
    			int value=db/RATIO;
    			if(value<0) value=0;
    			if(soundAmplitudeListen!=null){
    				soundAmplitudeListen.amplitude(ratio, db, value);
    				mHandler.postDelayed(mUpdateMicStatusTimer,postDelayed);
    			}
    		}
    	};
    	
    	public void startRecordCreateFile() throws IOException{
    		if(!Environment.getExternalStorageState().equals(
    				Environment.MEDIA_MOUNTED)){
    			return ;
    		}
    		file=new File(Environment.getExternalStorageDirectory()+File.separator+"1"+File.separator+
    				new DateFormat().format("yyyyMMdd_HHmmss", Calendar.getInstance(Locale.CHINA))+".amr");
    		mediaRecorder=new MediaRecorder();//创建录音对象
    		mediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);//从麦克风源进行录音
    		mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);//设置输出格式
    		mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);//设置编码格式
    		mediaRecorder.setOutputFile(file.getAbsolutePath());
    		
    		//创建文件
    		if(!file.getParentFile().exists()){
    			file.getParentFile().mkdirs();
    		}
    		file.createNewFile();
    		mediaRecorder.prepare();
    		mediaRecorder.start();
    		mHandler.post(mUpdateMicStatusTimer);
    	}
    	
    	public File stopRecord(){
    		if(mediaRecorder!=null){
    			mediaRecorder.stop();
    			mediaRecorder.release();
    			mediaRecorder=null;
    			mHandler.removeCallbacks(mUpdateMicStatusTimer);
    		}
    		return file;
    	}
    	public void setSoundAmplitudeListen(SoundAmplitudeListen soundAmplitudeListen){
    		this.soundAmplitudeListen=soundAmplitudeListen;
    	}
    	public interface SoundAmplitudeListen{
    		public void amplitude(int amplitude,int db,int value);
    	}
    }
    

      

    
    

    效果如下:

    Demo 资源: http://download.csdn.net/detail/u014132820/9369346

    下面给出博主自己开发的一些小App,分享给大家:

  • 相关阅读:
    Sql Server Report 导出到EXCEL 指定行高
    SQLSqlserver中如何将一列数据,不重复的拼接成一个字符串
    SQL Server Management Studio无法记住密码
    nuget.org无法解析的办法
    js获取select标签选中的值及文本
    Word 如何实现表格快速一分为二
    sql server rdl report 如何用动态sql
    浏览器窗口刷新
    SWFUpload 在ie9上出现的bug
    历数PC发展史上的祖先们
  • 原文地址:https://www.cnblogs.com/BasilLee/p/5061797.html
Copyright © 2011-2022 走看看