当前位置:操作系统 > 安卓/Android >>

通过J2ME的录音功能实现简易示波器

早就有人通过PC声卡的输入(麦克风孔)来做模拟示波器,但是用手机来实现的比较少。用J2ME的MMAPI实现模拟示波器,具体效果稍逊于智能机,因为智能机可以实时读取麦克风输入流,而J2ME还需要有短暂的缓冲构成了阻塞,不过,实现出来玩一下还是足够了。

先贴出效果图:

 

左图是程序在WTK

\

运行的结果,右图是Audition读取音频输入口的波形,信号源是一个经过信号放大的压力传感器。

程序使用NetBeans + LWUIT类库,接下来贴出全部代码:

view plaincopy to clipboardprint?
import com.sun.lwuit.Command;  
import com.sun.lwuit.Display;  
import com.sun.lwuit.Form;  
import com.sun.lwuit.events.ActionEvent;  
import com.sun.lwuit.events.ActionListener;  
import com.sun.lwuit.layouts.BorderLayout;  
import java.io.ByteArrayOutputStream;  
import javax.microedition.media.Manager;  
import javax.microedition.media.Player;  
import javax.microedition.media.control.RecordControl;  
 
/** 
 * @author 张国威 
 */ 
public class Frm_MainMenu extends javax.microedition.midlet.MIDlet implements ActionListener {  
    public Form form ;  
    private  Command cmdExit = new Command("退出", 1);  
    private ThreadReceive threadReceive =new ThreadReceive();//接收数据线程  
    private Cmp_Wave cmp_HeartWave=null;  
    private Player capturePlayer = null;  
    private RecordControl recordControl = null;  
    private ByteArrayOutputStream bos = new ByteArrayOutputStream();  
    public void startApp() {  
        Display.init(this);  
          
        form = new Form();//达到全屏的效果  
        cmp_HeartWave=new Cmp_Wave(form.getHeight(),form.getWidth());  
        form.getStyle().setBgImage(null);//本窗体不需要背景  
        form.addCommand(cmdExit);  
        form.setCommandListener(this);  
        form.setLayout(new BorderLayout());  
        //设置画板控件  
        form.addComponent(BorderLayout.CENTER,cmp_HeartWave);//添加控件  
        form.show();  
        try {  
          capturePlayer = Manager.createPlayer("capture://audio?rate=8000&bits=8&channels=1");//PCM,8位,8kH  
          if (capturePlayer != null) {  
            capturePlayer.realize();  
            recordControl = (RecordControl) capturePlayer  
                .getControl("javax.microedition.media.control.RecordControl");  
            if (recordControl == null)  
              throw new Exception("No RecordControl available");  
            recordControl.setRecordStream(bos);  
          } else {  
            throw new Exception("Capture Audio Player is not available");  
          }  
        } catch (Exception e) {}  
        threadReceive.start();//开始启动线程  
  }  
/* 
 * byte转为int的函数,因为JAVA的byte范围从-127~127 
 */ 
public static int unsignedByteToInt(byte b) {  
    return (int) b & 0xFF;  
    }  
class ThreadReceive extends Thread {  
      private boolean isRuning=true;//默认线程内部while循环可以执行  
      public void StopThread()  
      {  
          isRuning=false;  
      }  
      public void run(){  
          //*************************************************************  
          //绘制波形数据  
          //*************************************************************  
          try {  
              capturePlayer.start();  
              while(isRuning)  
              {  
                  recordControl = (RecordControl) capturePlayer.getControl("javax.microedition.media.control.RecordControl");  
                  recordControl.setRecordStream(bos);  
                  recordControl.startRecord();  
                  Thread.sleep(25);//停顿25ms录音  
                  recordControl.stopRecord();  
                  recordControl.commit();  
                  //由于采集频率太高,手机不能完全显示,所以需要通过均值滤波来降低分辨率  
                  int Zoom_out=200;//缩小200倍  
                  int[] bits=new int[bos.toByteArray().length/Zoom_out];  
                  for(int i=0,total=0,index=0;i<bos.toByteArray().length;i++)  

补充:移动开发 , Android ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,