安卓手机和单片机音频通信

2019-04-13 10:58发布

        这里是这几天做的实验,在安卓上的软件程序主要参考《疯狂的安卓讲义》,电路中的一些东西参考的是HiJack项目中的电路。在这里,我真的突然感慨学好模电真的很重要。在没有参考HIJACK之前,我对这些音频信号手足无措。在这个小项目学习完后,我决定再重新学习模电,感觉这一次重温应该能让我这模电知识再上一个台阶。 下面我从几个方面记录一下自己的学习过程,给自己留个记录以后翻阅,也可以给大家一个参考; 1).耳机线的接口; 2).话筒和耳机的声音原理; 3).安卓中的程序编写
1.耳机接口问题         一般MP3中的耳机就真的是耳机,其中没有话筒,分为三段左声道、右声道、地。而我们的手机中原装的耳机是带有话筒的,这种耳机分为四段分别为左声道、右声道、地、MIC。就是这手机带的四段带话筒的耳机还不同,像国内的一些手机厂商和国外的厂商,这种耳机的地和MIC可能是对换了的。有条件的可以折几个测测就知道。
2.其实话筒接收的是振动信号,以些振动信号产生变化的电流,通过耳机接口传到手机里面的处理电路,最后被采样。所以,这里用以下电路,参考HIJACK中的,单片机用PWM来输出。 用的是1KHZ占空比为50%的PWM波,最后在安卓中保存话筒采集到的数据,用的是16bit单通道格式保存为PCM,显示的波形图如下:振动幅值都是最大的-32768,32767.
在手机播放500HZ的音频时,我在耳机中测到的输入波形如下图:C1即为在左声道测得的波形,Z1、Z2为放大后的。 从手机通过耳机到单片机的电路如下:
3.安卓中的程序主要是涉及两个模块,一个是音频的录放,另一个就是文件的存储; 程序如下:APK编写的时候是支持android2.3.1以上的,大家可以在资源里下载http://download.csdn.net/detail/raoqin/5884203
界面文件main.xml [java] view plaincopy
  1. "1.0" encoding="utf-8"?>  
  2. "fill_parent" android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent">  
  3.   
  4.     "wrap_content" android:text="开始边录边放"   
  5.             android:layout_width="fill_parent" android:id="@+id/btnRecord">  
  6.     "@+id/btnStop" android:layout_width="fill_parent"   
  7.             android:text="停止" android:layout_height="wrap_content">  
  8.     "fill_parent" android:layout_height="wrap_content"   
  9.             android:id="@+id/btnExit" android:text="退出">  
  10.     "@+id/TextView01" android:layout_height="wrap_content"   
  11.             android:layout_width="fill_parent" android:text="程序音量调节">  
  12.     "fill_parent" android:id="@+id/skbVolume"   
  13.             android:layout_height="wrap_content">  
  14.     "match_parent" android:layout_height="wrap_content"   
  15.             android:id="@+id/tableRow1">  
  16.         "@+id/read" android:layout_height="wrap_content"   
  17.             android:layout_width="wrap_content" android:text="读">  
  18.         "@+id/write" android:layout_height="wrap_content"   
  19.             android:layout_width="wrap_content" android:text="写">  
  20.       
  21.     "EditText" android:id="@+id/edit1"   
  22.               android:layout_width="match_parent" android:layout_height="wrap_content">  
  23.     "match_parent" android:hint="EditText"   
  24.               android:id="@+id/edit2" android:layout_height="wrap_content">  
  25.   
  26.    

主程序如下: [java] view plaincopy
  1. package packname.test;  
  2.   
  3.   
  4. import java.io.BufferedReader;  
  5. import java.io.File;  
  6. import java.io.FileInputStream;  
  7. import java.io.FileOutputStream;  
  8. import java.io.IOException;  
  9. import java.io.InputStreamReader;  
  10. import java.io.PrintStream;  
  11. import java.io.RandomAccessFile;  
  12.   
  13. import android.app.Activity;  
  14. import android.media.AudioFormat;  
  15. import android.media.AudioManager;  
  16. import android.media.AudioRecord;  
  17. import android.media.AudioTrack;  
  18. import android.media.MediaRecorder;  
  19. import android.os.Bundle;  
  20. import android.os.Environment;  
  21. import android.view.View;  
  22. import android.widget.Button;  
  23. import android.widget.EditText;  
  24. import android.widget.SeekBar;  
  25. import android.widget.Toast;  
  26.   
  27. public class acti extends Activity   
  28. {  
  29.     /** Called when the activity is first created. */  
  30.     //----  
  31.     final String FILE_NAME = "/myraoqin.bin";  
  32.     File sdCardDir = null;  
  33.     File targetFile = null;  
  34.     RandomAccessFile raf = null;  
  35.     //----  
  36.     Button btnRecord, btnStop, btnExit;  
  37.     SeekBar skbVolume;//调节音量  
  38.     boolean isRecording = false;//是否录放的标记  
  39.     static final int frequency = 44100;  
  40.     static final int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO;  
  41.     static final int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;//AudioFormat.ENCODING_PCM_16BIT;  
  42.     int recBufSize,playBufSize;  
  43.     AudioRecord audioRecord;  
  44.     AudioTrack audioTrack;  
  45.   
  46.     @Override  
  47.     public void onCreate(Bundle savedInstanceState)   
  48.     {  
  49.         super.onCreate(savedInstanceState);  
  50.         setContentView(R.layout.main);  
  51.         setTitle("Lhyraoqin");  
  52.         //----------------------------SD卡文件   
  53.         //获取SD卡的目录  
  54.         try  
  55.         {  
  56.         sdCardDir = Environment.getExternalStorageDirectory();  
  57.         targetFile = new File(sdCardDir.getCanonicalPath() + FILE_NAME );  
  58.         //以指定文件创建 randomaccessfile对象  
  59.         raf = new RandomAccessFile( targetFile, "rw" );  
  60.         }