Android录制通话参数
我正在开发一个DTMF解码器。我需要的是录制语音通话,然后提取频率范围。一切正常,但在一些android版本中,我在设置音频源时遇到以下错误 “音频属性的捕获预设3无效” 为了获得正确的参数,我开发了一种算法:Android录制通话参数,android,format,call,record,Android,Format,Call,Record,我正在开发一个DTMF解码器。我需要的是录制语音通话,然后提取频率范围。一切正常,但在一些android版本中,我在设置音频源时遇到以下错误 “音频属性的捕获预设3无效” 为了获得正确的参数,我开发了一种算法: private static final int[] FREQUENCY = {8000, 11025, 16000, 22050, 44100}; // 44100 is guaranteed to work in all devices private static final i
private static final int[] FREQUENCY = {8000, 11025, 16000, 22050, 44100}; // 44100 is guaranteed to work in all devices
private static final int[] CHANNEL_CONFIGURATION = {AudioFormat.CHANNEL_IN_MONO,
AudioFormat.CHANNEL_IN_STEREO};
private static final int[] AUDIO_ENCODING = {AudioFormat.ENCODING_DEFAULT,
AudioFormat.ENCODING_PCM_8BIT,
AudioFormat.ENCODING_PCM_16BIT};
for (int i = 0; i < FREQUENCY.length && !found; i ++) {
for (int j = 0; j < CHANNEL_CONFIGURATION.length && !found; j ++) {
for (int k = 0; k < AUDIO_ENCODING.length && !found; k ++) {
try {
bufferSize = AudioRecord.getMinBufferSize(FREQUENCY[i], CHANNEL_CONFIGURATION[j], AUDIO_ENCODING[k]);
if (bufferSize != AudioRecord.ERROR_BAD_VALUE && bufferSize != AudioRecord.ERROR) {
audioRecord = new AudioRecord(MediaRecorder.AudioSource.VOICE_DOWNLINK, FREQUENCY[i], CHANNEL_CONFIGURATION[j], AUDIO_ENCODING[k], bufferSize);
found = true;
}
} catch (Exception e) {
Log.e(TAG, e.toString());
}
}
}
}
private static final int[]频率={8000、11025、16000、22050、44100};//44100保证在所有设备中工作
私有静态最终int[]通道配置={AudioFormat.CHANNEL\u IN_MONO,
AudioFormat.CHANNEL_IN_STEREO};
私有静态final int[]音频编码={AudioFormat.ENCODING_默认值,
AudioFormat.ENCODING_PCM8bit,
AudioFormat.ENCODING_PCM_16BIT};
对于(int i=0;i
未找到api 19或22的正确参数,无法设置录音。在任何情况下都会引发异常。
我对这件事很感兴趣。我没有考虑使用MediaRecoder类,因为我不能直接从recoder读取缓冲区,这对dtmf解码过程至关重要。我也见过一些dtmf开源解码器,但它们都有这个问题
Android官方BUG
第一
它的构造器公共录音(int audioSource,int sampleRateInHz,int channelConfig,int audioFormat,int bufferSizeInBytes)
可能不推荐使用(我认为),一个非法的argumentexception被直接抛出,另一个构造器方法如下(特别是公共API的候选构造器):
第二
你可以试试
/**语音呼叫上行+下行音频源*/
公共静态最终int语音通话=4;
第三
参考资源
一些android版本禁用了此功能。如果你有android的源代码,你可以让它工作。我目前正在使用cyanogenmod,因此我定制了AudioAttributes.java类,以便在发生异常时不引发异常 我们只需在AudioAttributes.java中更改setCapturePreset()方法,即在switch/case结构中添加所需的所有音频源 这是原件:
/**
* @hide
* Sets the capture preset.
* Use this audio attributes configuration method when building an {@link AudioRecord}
* instance with {@link AudioRecord#AudioRecord(AudioAttributes, AudioFormat, int)}.
* @param preset one of {@link MediaRecorder.AudioSource#DEFAULT},
* {@link MediaRecorder.AudioSource#MIC}, {@link MediaRecorder.AudioSource#CAMCORDER},
* {@link MediaRecorder.AudioSource#VOICE_RECOGNITION} or
* {@link MediaRecorder.AudioSource#VOICE_COMMUNICATION}.
* @return the same Builder instance.
*/
@SystemApi
public Builder setCapturePreset(int preset) {
switch (preset) {
case MediaRecorder.AudioSource.DEFAULT:
case MediaRecorder.AudioSource.MIC:
case MediaRecorder.AudioSource.CAMCORDER:
case MediaRecorder.AudioSource.VOICE_RECOGNITION:
case MediaRecorder.AudioSource.VOICE_COMMUNICATION:
mSource = preset;
break;
default:
Log.e(TAG, "Invalid capture preset " + preset + " for AudioAttributes");
}
return this;
}
我用这个来代替:
/**
* @hide
* Sets the capture preset.
* Use this audio attributes configuration method when building an {@link AudioRecord}
* instance with {@link AudioRecord#AudioRecord(AudioAttributes, AudioFormat, int)}.
* @param preset one of {@link MediaRecorder.AudioSource#DEFAULT},
* {@link MediaRecorder.AudioSource#MIC}, {@link MediaRecorder.AudioSource#CAMCORDER},
* {@link MediaRecorder.AudioSource#VOICE_RECOGNITION} or
* {@link MediaRecorder.AudioSource#VOICE_COMMUNICATION}.
* @return the same Builder instance.
*/
@SystemApi
public Builder setCapturePreset(int preset) {
switch (preset) {
case MediaRecorder.AudioSource.DEFAULT:
case MediaRecorder.AudioSource.MIC:
case MediaRecorder.AudioSource.CAMCORDER:
case MediaRecorder.AudioSource.VOICE_RECOGNITION:
case MediaRecorder.AudioSource.VOICE_COMMUNICATION:
case MediaRecorder.AudioSource.VOICE_DOWNLINK:
case MediaRecorder.AudioSource.VOICE_UPLINK:
case MediaRecorder.AudioSource.VOICE_CALL:
mSource = preset;
break;
default:
Log.e(TAG, "Invalid capture preset " + preset + " for AudioAttributes");
}
return this;
}
嗨,谢谢你的回复。当我这样做时,我得到一个反射调用目标异常:Constructor cons=AudioRecord.class.getConstructor(AudioAttributes.class,AudioFormat.class,int.class,int.class);audioRecord=(audioRecord)cons.newInstance(attrs.build(),format.build(),bufferSize,AudioManager.AUDIO_SESSION_ID_GENERATE);--有什么想法吗?我用api 22编译
/**
* @hide
* Sets the capture preset.
* Use this audio attributes configuration method when building an {@link AudioRecord}
* instance with {@link AudioRecord#AudioRecord(AudioAttributes, AudioFormat, int)}.
* @param preset one of {@link MediaRecorder.AudioSource#DEFAULT},
* {@link MediaRecorder.AudioSource#MIC}, {@link MediaRecorder.AudioSource#CAMCORDER},
* {@link MediaRecorder.AudioSource#VOICE_RECOGNITION} or
* {@link MediaRecorder.AudioSource#VOICE_COMMUNICATION}.
* @return the same Builder instance.
*/
@SystemApi
public Builder setCapturePreset(int preset) {
switch (preset) {
case MediaRecorder.AudioSource.DEFAULT:
case MediaRecorder.AudioSource.MIC:
case MediaRecorder.AudioSource.CAMCORDER:
case MediaRecorder.AudioSource.VOICE_RECOGNITION:
case MediaRecorder.AudioSource.VOICE_COMMUNICATION:
mSource = preset;
break;
default:
Log.e(TAG, "Invalid capture preset " + preset + " for AudioAttributes");
}
return this;
}
/**
* @hide
* Sets the capture preset.
* Use this audio attributes configuration method when building an {@link AudioRecord}
* instance with {@link AudioRecord#AudioRecord(AudioAttributes, AudioFormat, int)}.
* @param preset one of {@link MediaRecorder.AudioSource#DEFAULT},
* {@link MediaRecorder.AudioSource#MIC}, {@link MediaRecorder.AudioSource#CAMCORDER},
* {@link MediaRecorder.AudioSource#VOICE_RECOGNITION} or
* {@link MediaRecorder.AudioSource#VOICE_COMMUNICATION}.
* @return the same Builder instance.
*/
@SystemApi
public Builder setCapturePreset(int preset) {
switch (preset) {
case MediaRecorder.AudioSource.DEFAULT:
case MediaRecorder.AudioSource.MIC:
case MediaRecorder.AudioSource.CAMCORDER:
case MediaRecorder.AudioSource.VOICE_RECOGNITION:
case MediaRecorder.AudioSource.VOICE_COMMUNICATION:
case MediaRecorder.AudioSource.VOICE_DOWNLINK:
case MediaRecorder.AudioSource.VOICE_UPLINK:
case MediaRecorder.AudioSource.VOICE_CALL:
mSource = preset;
break;
default:
Log.e(TAG, "Invalid capture preset " + preset + " for AudioAttributes");
}
return this;
}