本文来讲述在Android中使用AudioRecord和AudioTrack来进行音频录制播放,并使用speex进行音频压缩编码,再采用TCP传输思路和方法。
1 开篇
2
相关知识
3
多线程音频读取思路
android-recorder项目中的两个线程处理方法非常好。一个线程启动录制,然后循环调用Read方法,并将数据压倒另外一个线程的数据处理队列中,在另外一个线程的run里面,循环从队列里面取出一条,并写入到文件里面。代码示例如下:
线程1
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
public void run() {
PcmWriter pcmWriter = new PcmWriter(); pcmWriter.init(); Thread writerThread = new Thread (pcmWriter); pcmWriter.setRecording(true); writerThread.start(); synchronized (mutex) { while (!this.isRecording) { try { mutex.wait(); } catch (InterruptedException e) { throw new IllegalStateException("Wait() interrupted!", e); } } } android.os.Process .setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO); int bufferRead = 0; int bufferSize = AudioRecord.getMinBufferSize(frequency, AudioFormat.CHANNEL_IN_MONO, audioEncoding); short[] tempBuffer = new short[bufferSize]; AudioRecord recordInstance = new AudioRecord( MediaRecorder.AudioSource.MIC, frequency, AudioFormat.CHANNEL_IN_MONO, audioEncoding, bufferSize); recordInstance.startRecording(); while (this.isRecording) { bufferRead = recordInstance.read(tempBuffer, 0, bufferSize); if (bufferRead == AudioRecord.ERROR_INVALID_OPERATION) { throw new IllegalStateException( "read() returned AudioRecord.ERROR_INVALID_OPERATION"); } else if (bufferRead == AudioRecord.ERROR_BAD_VALUE) { throw new IllegalStateException( "read() returned AudioRecord.ERROR_BAD_VALUE"); } else if (bufferRead == AudioRecord.ERROR_INVALID_OPERATION) { throw new IllegalStateException( "read() returned AudioRecord.ERROR_INVALID_OPERATION"); } pcmWriter.putData(tempBuffer, bufferRead); log.debug("put data done!"); } recordInstance.stop(); pcmWriter.setRecording(false); } |
线程2
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
public void run() {
log.error("pcmwriter thread runing"); while (this.isRecording()) { if(list.size() > 0){ rawData = list.remove(0); try { for (int i = 0; i < rawData.size; ++i) { dataOutputStreamInstance.writeShort(rawData.pcm[i]); } } catch (IOException e) { e.printStackTrace(); } } else { try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } } } stop()
【上篇】关于用css数字与汉字的垂直对其问题
【下篇】几个不错的开源的.net界面控件 转自http://zchuang2004.spaces.live.com/blog/cns!8C4AEEE059DED8B1!157.entry |