AudioRecord记录在Android的大号断续声

编程入门 行业动态 更新时间:2024-10-11 17:23:27
本文介绍了AudioRecord记录在Android的大号断续声的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我录音与AudioRecord在PCM16LE格式,8000Hz的,1路。它记录确定在Android的版本2.3.3-4.4.4,但奇怪的记录声音断断续续在Android的L(上承上启下5,承上启下7和仿真器)。

下面是录制的声音(上半场 - 记录,下半场 - 回放)的示例: www.dropbox/s/3wcgufua5pphwtt/android_l_sound_record_error.m4a?dl=0

我试着用不同的采样率(4000,16000),并为8位,但声音一直是断断续续的播放录制的声音。有什么问题可以用这种声音?

我用这个AudioRecordTask录制音频getAudioRecord()用于初始化输入(操作过程中没有返回错误;接收的音频数据块大小同样为internalBufferSize值):

公众最终诠释SAMPLING_RATE = 8000; 私人AudioRecord getAudioRecord(){     INT internalBufferSize = AudioRecord.getMinBufferSize(SAMPLING_RATE,             AudioFormat.CHANNEL_IN_MONO,             AudioFormat.ENCODING_PCM_16BIT); //返回640     internalBufferSize = 8000; //还试图返回的值(640)和值2560,30000 - 无变化     最终诠释来源;     如果(Build.VERSION.SDK_INT&所述; 11){         来源= MediaRecorder.AudioSource.MIC;     } 其他 {         来源= MediaRecorder.AudioSource.VOICE_COMMUNICATION;     }     AudioRecord纪录=新AudioRecord(SOURCE,             采样率,             AudioFormat.CHANNEL_IN_MONO,             AudioFormat.ENCODING_PCM_16BIT,             internalBufferSize);     INT状态= record.getState();     如果(状态!= AudioRecord.STATE_INITIALIZED){         尝试 {             record.release();         }赶上(例外五){         }         返回null;     }     如果(record.getState()== android.media.AudioRecord.STATE_INITIALIZED){         record.startRecording();     } 其他 {         record.release();         返回null;     }     返回记录; } 私有类AudioRecordTask扩展的AsyncTask<虚空,虚空,虚空> {     最终诠释PARTIAL_BUFFER_SIZE = SAMPLING_RATE;     最终诠释NECESSARY_BUFFER_SIZE = 15 * PARTIAL_BUFFER_SIZE * Short.SIZE / 8;     最终诠释FULL_BUFFER_SIZE = NECESSARY_BUFFER_SIZE * 2; // XXX:* 2时,系统会返回比需要更多的数据的情况下     短[] mBuffer;     INT mTotalSize;     INT mTotalSizeInBytes;     布尔mResult;     私有对象MLOCK =新的对象();     @覆盖     在preExecute保护无效()     {         mIsRecording = TRUE;         mBuffer =新的短[FULL_BUFFER_SIZE]         mTotalSize = 0;         mTotalSizeInBytes = 0;         mResult = FALSE;     }     @覆盖     保护无效doInBackground(虚空......为arg0){         同步(MLOCK){             android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);             AudioRecord纪录= getAudioRecord();             如果(记录== NULL){                 mResult = FALSE;                 返回null;             }             的for(int i = 0; I< 15 * 100;我++){// XXX:* 100来记录足够的数据(系统可以返回较小的比需要的)                 INT DATALEN = record.read(mBuffer,mTotalSize,PARTIAL_BUFFER_SIZE);                 如果(DATALEN大于0){                     mTotalSize + = DATALEN;                     mTotalSizeInBytes = mTotalSize * 2;                 } 其他 {                     Log.w(,错误+ DATALEN +在AudioRecord.read);                 }                 如果(isCancelled()|| mTotalSizeInBytes> NECESSARY_BUFFER_SIZE){                     打破;                 }             }             如果(record.getRecordingState()== AudioRecord.RECORDSTATE_RECORDING){                 record.stop();             }             record.release();             mResult = TRUE;             返回null;         }     }     @覆盖     保护无效onPostExecute(空R){         同步(MLOCK){             mIsRecording = FALSE;             鳍();         }     }     @覆盖     保护无效onCancelled(){         // XXX:老机器人(如2.3.3)onCancelled被调用时doInBackground仍在运行         同步(MLOCK){             mIsRecording = FALSE;             如果(mAbort){                 返回;             }             鳍();         }     }     私人无效鳍(){         如果(mResult&安培;&安培; mTotalSizeInBytes大于0){             sendRecordedAudioToServer(mBuffer,mTotalSize,mTotalSizeInBytes);         } 其他 {             showError(空);         }     } }

解决方案

这是在Android的大号开发preVIEW一个错误:的 HTTPS://$c$c.google/p/android-developer-$p$pview/issues/detail? ID = 1492

AudioRecord.read为以字节为单位,而不是短裤值短期[]缓存参数返回值。

作为一种解决方法使用AudioRecord.read用byte []的缓冲区。

I'm recording sound with AudioRecord in PCM16LE format, 8000Hz, 1channel. It records ok in Android versions 2.3.3-4.4.4, but records strange intermittent sound in Android L (on nexus 5, nexus 7 and emulator).

Here is the sample of recorded sound (the first half - recording, the second half - playback): www.dropbox/s/3wcgufua5pphwtt/android_l_sound_record_error.m4a?dl=0

I tried to play recorded sound using different sample rate (4000, 16000) and as 8bit but sound keeps to be intermittent. What the problem could be with this sound?

I'm using this AudioRecordTask to record audio with getAudioRecord() for initializing input (no errors returned during operation; receiving audio chunks sized equally to internalBufferSize value):

public final int SAMPLING_RATE = 8000; private AudioRecord getAudioRecord() { int internalBufferSize = AudioRecord.getMinBufferSize(SAMPLING_RATE, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT); //returns 640 internalBufferSize = 8000; //also tried returned value (640) and values 2560, 30000 - no changes final int SOURCE; if (Build.VERSION.SDK_INT < 11) { SOURCE = MediaRecorder.AudioSource.MIC; } else { SOURCE = MediaRecorder.AudioSource.VOICE_COMMUNICATION; } AudioRecord record = new AudioRecord(SOURCE, SAMPLING_RATE, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, internalBufferSize); int state = record.getState(); if (state != AudioRecord.STATE_INITIALIZED) { try { record.release(); } catch (Exception e) { } return null; } if (record.getState() == android.media.AudioRecord.STATE_INITIALIZED) { record.startRecording(); } else { record.release(); return null; } return record; } private class AudioRecordTask extends AsyncTask<Void, Void, Void> { final int PARTIAL_BUFFER_SIZE = SAMPLING_RATE; final int NECESSARY_BUFFER_SIZE = 15 * PARTIAL_BUFFER_SIZE * Short.SIZE / 8; final int FULL_BUFFER_SIZE = NECESSARY_BUFFER_SIZE * 2; //XXX: * 2 for the case when system returns more data than needed short[] mBuffer; int mTotalSize; int mTotalSizeInBytes; boolean mResult; private Object mLock = new Object(); @Override protected void onPreExecute() { mIsRecording = true; mBuffer = new short[FULL_BUFFER_SIZE]; mTotalSize = 0; mTotalSizeInBytes = 0; mResult = false; } @Override protected Void doInBackground(Void... arg0) { synchronized (mLock) { android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO); AudioRecord record = getAudioRecord(); if (record == null) { mResult = false; return null; } for (int i = 0; i < 15 * 100; i++) { //XXX: * 100 to record enough data (system can return lesser than needed) int datalen = record.read(mBuffer, mTotalSize, PARTIAL_BUFFER_SIZE); if (datalen > 0) { mTotalSize += datalen; mTotalSizeInBytes = mTotalSize*2; } else { Log.w("", "error " + datalen + " in AudioRecord.read"); } if (isCancelled() || mTotalSizeInBytes > NECESSARY_BUFFER_SIZE) { break; } } if (record.getRecordingState() == AudioRecord.RECORDSTATE_RECORDING) { record.stop(); } record.release(); mResult = true; return null; } } @Override protected void onPostExecute(Void r) { synchronized (mLock) { mIsRecording = false; fin(); } } @Override protected void onCancelled() { //XXX: on old Androids (e.g. 2.3.3) onCancelled being called while doInBackground is still running synchronized (mLock) { mIsRecording = false; if (mAbort) { return; } fin(); } } private void fin() { if (mResult && mTotalSizeInBytes > 0) { sendRecordedAudioToServer(mBuffer, mTotalSize, mTotalSizeInBytes); } else { showError(null); } } }

解决方案

It's a bug in Android L Developer Preview: code.google/p/android-developer-preview/issues/detail?id=1492

AudioRecord.read for short[] buffer argument returns value in bytes instead of value in shorts.

As a workaround use AudioRecord.read with byte[] buffer.

更多推荐

AudioRecord记录在Android的大号断续声

本文发布于:2023-11-29 14:03:21,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1646598.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:断续   大号   AudioRecord   Android

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!