PS:本文是原创,写此文的目的,是为记录自己的andriod 开发之路~~
正文:
既然要做语音对讲,那么就涉及到android 语音的提取,播放,发送.
记录:android里面记录语音两个类:一个是AudioRecord,一个是Mediarecord,现在分别列出两个的优缺点
AudioRecord:优点是:可以实时处理语音数据 缺点是:提取的数据是原始pcm数据(数据量大),要压缩和编码,得自己移植库。
MediaRecord:优点是:记录的音频数据已经编码 缺点是:不能实时处理数据
ps:Tom猫就是AudioRecord来写的
播放:由于我们是AudioRecord,进行提取的是pcm数据,为了简化程序,我打算使用andriod自带的AudioTrack来播放记录的数据。
发送:简单起见,使用udp,下一版本使用rtp
类的构造:
AudioRecord类的构造函数:
Public AudioRecord (int audioSource,int sampleRateInHz,int channelConfig, int audioFormat,int bufferSiizeInBytes)
AudioSource:音频源:指的是从从哪里采集音频。 参数设置为MIC(麦克风采集音频)
sampleRateInHz采样率:音频的采样频率,每秒钟能够采样的次数,采样率越高,音质越高。给出的实例是44100,22050,11025,要采集低质量的音频可以使用4000,8000低采样率
channelConfig:声道设置 MONO单声道,STEREO立体声
audioFormat:编码方式和采样大小,采集来的数据使用pcm编码。 ENCODING_PCM_16BIT,ENCODING_PCM_8BIT,在低质量的语音传输的时候8bit足够了。
bufferSizelnBytes:采集数据需要的缓冲区大小,如果不知道大小 可以使用getMinBufferSize()查看。
AudioTrack类的构造函数:
Public AudioTrack(int streamType,int sampleRateInhz, int channelConfig,int audioFormat,int bufferSizeInBytes,int mode)
streamType:STREAM_VOICE_CALL,STREAM_SYSTEM,STREAM_RING,STREAM_MUSIC,STREAM_ALARM
sampleRateInhz:44100,22050,11025
channelConfig:CHANNEL_OUT_MONO ,CHANNEL_OUT_STEREO
audioFormat: ENCODING_PCM_16BIT,ENCODING_PCM_8BIT
bufferSizeInbytes:可以通过getMinbufferSize(int,int,int)
Mode:MODE_STATIC ,MODE_STREAM
使用列子:
构造audioRecord:
private static final int frequency=11025;
private static final int channel=AudioFormat.CHANNEL_CONFIGURATION_MONO;
private static final int audioEncoding=AudioFormat.ENCODING_PCM_16BIT;
private int buffersize;
private AudioRecord record;
//初始化
buffersize=AudioRecord.getMinBufferSize(frequency, channel,
audioEncoding);
record=new AudioRecord(MediaRecorder.AudioSource.MIC,frequency,channel,
audioEncoding,buffersize);
//开启录音
record.startRecording();
//销毁/释放录音
record.stop();
record.release();
构造AudioTrack;
private AudioTrack audio;
private int buffersize;
//初始化
buffersize=AudioTrack.getMinBufferSize(11025,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT);
audio=new AudioTrack(AudioManager.STREAM_MUSIC,11025
,AudioFormat.CHANNEL_CONFIGURATION_MONO
,AudioFormat.ENCODING_PCM_16BIT
,buffersize,AudioTrack.MODE_STREAM);
//启动AudioTrack
audio.play();
//关闭AudioTrack
audio.stop();
audio.release();
UDP的接收和发送:
接受:
1.创建DatagramSocket对象,并指定监听端口
DatagramSocket sock=new DatagramSocket(端口);
2.创建一个byte数组用于接受
byte data[]=new byte[1024];
3.创建一个空的DatagramPackage对象
DatagramPackage pack=new DatagramPackage(data,data.length());
4.使用receiver 方法接收数据 阻塞方法
sock.receive(pack)
发送:
1创建DatagramSocket对象,并指定监听端口
DatagramSocket sock=new DatagramSocket(端口);
2创建一个InetAddress,相当于地址
InetAddress add=InetAddress.getByname(“IP地址”);
3 欲发送的数据:
byte data[]=XXXXXXXXXX;
4创建一个DatagramPacket 对象,制定网络地址,和端口号
DatagramPacket pack=new DatagramPacket(data,data.length,add,端口号);
5调用DatagramSock对象发送
socket.send(pack);
到此需要的类代码全部搞清,已经初步实现语音功能。但是问题很严重,一是杂音,二是回音造成的啸叫。需要解决的问题还多,初步打算移植speex库解决。但是对回音的处理一直是voip电话的难题,市面上应该有成熟的模块,打算做可以考虑购买。
PS. 代码就不上传了,需要的q我.