如何在Delphi 11 FMX的Android应用中禁用录制音频效果
Delphi 11 FMX Android 音频录制:禁用系统音频效果解决电平异常问题
核心问题分析
系统默认的自动增益(AGC)、降噪(NS)等音频效果会在部分设备上干扰录制电平,导致音量异常、低频衰减等问题。需针对当前AudioRecord实例的音频会话,绑定并禁用这些系统级效果。
分步解决方案
1. 正确获取AudioRecord的会话ID(Session ID)
所有音频效果必须绑定到当前AudioRecord实例的会话ID,不能使用AUDIO_SESSION_ID_GENERATE。初始化FAudioRecord后立即获取:
var LSessionID: Integer; begin // 初始化FAudioRecord后获取会话ID LSessionID := (FAudioRecord as JAudioRecord).getAudioSessionId; end;
2. 禁用自动增益控制(AGC)
使用TJAutomaticGainControl类,先检查设备兼容性,再绑定会话并禁用:
var LAGC: JAutomaticGainControl; begin // API 16及以上支持AGC if TJBuild_VERSION.JavaClass.SDK_INT >= 16 then begin if TJAutomaticGainControl.JavaClass.isAvailable then begin LAGC := TJAutomaticGainControl.JavaClass.create(LSessionID); if Assigned(LAGC) then LAGC.setEnabled(False); // 禁用自动增益 end; end; end;
3. 禁用降噪(Noise Suppression)
类似AGC,使用TJNoiseSuppressor类处理降噪效果:
var LNS: JNoiseSuppressor; begin // API 17及以上支持降噪 if TJBuild_VERSION.JavaClass.SDK_INT >= 17 then begin if TJNoiseSuppressor.JavaClass.isAvailable then begin LNS := TJNoiseSuppressor.JavaClass.create(LSessionID); if Assigned(LNS) then LNS.setEnabled(False); // 禁用降噪 end; end; end;
4. 处理均衡器初始化异常
TJEqualizer多针对播放场景,录制端很多设备不支持。若必须使用,需做兼容性检查和异常捕获:
var LEQ: JEqualizer; begin try if TJEqualizer.JavaClass.isAvailable then begin LEQ := TJEqualizer.JavaClass.create(0, LSessionID); // 0为优先级参数 if Assigned(LEQ) then LEQ.setEnabled(False); // 禁用均衡器效果 end; except // 捕获初始化异常,跳过均衡器处理 end; end;
5. 权限确认与动态申请
确保AndroidManifest.xml中添加必要权限:
<uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
注意:RECORD_AUDIO需要动态申请,启动录制前需执行权限检查:
uses Androidapi.Helpers, Androidapi.JNI.Os; function CheckRecordPermission: Boolean; var LPermission: JString; begin LPermission := StringToJString('android.permission.RECORD_AUDIO'); Result := TAndroidHelper.Activity.checkSelfPermission(LPermission) = TJPackageManager.JavaClass.PERMISSION_GRANTED; if not Result then TAndroidHelper.Activity.requestPermissions(TJavaObjectArray<JString>.Create(1, LPermission), 100); end;
完整修正后的录制初始化代码
var FChannelConfig: Integer; FAudioFormat: Integer; FTailleBufferBytes: Integer; AUDIO_SOURCE: Integer; FAudioManager: JAudioManager; AudioMngrProp: JString; FAudioRecord: JAudioRecord; LSessionID: Integer; LAGC: JAutomaticGainControl; LNS: JNoiseSuppressor; begin FChannelConfig := TJAudioFormat.JavaClass.CHANNEL_IN_STEREO; FAudioFormat := TJAudioFormat.JavaClass.ENCODING_PCM_16BIT; FTailleBufferBytes := TJAudioRecord.JavaClass.getMinBufferSize(FSampleRate, FChannelConfig, FAudioFormat); // VOICE_RECOGNITION AUDIO_SOURCE := TJMediaRecorder_AudioSource.JavaClass.VOICE_RECOGNITION; // UNPROCESSED 音频源(API 24+),优先使用可绕过部分系统处理 if (TJBuild_VERSION.JavaClass.SDK_INT >= 24) then begin FAudioManager := TJAudioManager.Wrap((TAndroidHelper.Activity.getSystemService(TJContext.JavaClass.AUDIO_SERVICE) as ILocalObject).GetObjectID); AudioMngrProp := FAudioManager.getProperty(TJAudioManager.JavaClass.PROPERTY_SUPPORT_AUDIO_SOURCE_UNPROCESSED); if (Boolean.Parse(JStringToString(AudioMngrProp))) then AUDIO_SOURCE := TJMediaRecorder_AudioSource.JavaClass.UNPROCESSED; end; // 检查录音权限 if not CheckRecordPermission then begin // 权限未授予,执行提示或退出逻辑 Exit; end; // 初始化AudioRecord FAudioRecord := TJAudioRecord.JavaClass.init(AUDIO_SOURCE, FSampleRate, FChannelConfig, FAudioFormat, FTailleBufferBytes); // 获取会话ID LSessionID := (FAudioRecord as JAudioRecord).getAudioSessionId; // 禁用自动增益 if TJBuild_VERSION.JavaClass.SDK_INT >= 16 then begin if TJAutomaticGainControl.JavaClass.isAvailable then begin LAGC := TJAutomaticGainControl.JavaClass.create(LSessionID); if Assigned(LAGC) then LAGC.setEnabled(False); end; end; // 禁用降噪 if TJBuild_VERSION.JavaClass.SDK_INT >= 17 then begin if TJNoiseSuppressor.JavaClass.isAvailable then begin LNS := TJNoiseSuppressor.JavaClass.create(LSessionID); if Assigned(LNS) then LNS.setEnabled(False); end; end; // 可选:禁用均衡器(按需启用) // try // if TJEqualizer.JavaClass.isAvailable then // begin // LEQ := TJEqualizer.JavaClass.create(0, LSessionID); // if Assigned(LEQ) then // LEQ.setEnabled(False); // end; // except // end; // 开始录制 (FAudioRecord As JAudioRecord).StartRecording; end;
关键注意事项
- 所有音频效果配置必须在
FAudioRecord初始化后、StartRecording前完成,确保效果绑定到正确会话。 - 部分设备可能不支持特定效果,必须做可用性检查和异常捕获,避免崩溃。
- 优先使用
UNPROCESSED音频源(API 24+),可直接绕过大部分系统音频处理,是解决电平异常的最优方案。
内容的提问来源于stack exchange,提问作者lefjucabro
相关产品推荐
相关产品推荐

