Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/223.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android录制通话参数_Android_Format_Call_Record - Fatal编程技术网

Android录制通话参数

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

我正在开发一个DTMF解码器。我需要的是录制语音通话,然后提取频率范围。一切正常,但在一些android版本中,我在设置音频源时遇到以下错误

“音频属性的捕获预设3无效”

为了获得正确的参数,我开发了一种算法:

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;
    }