2

I9505 在 APQ8064T 上运行,与上一代 MSM8960 相比,HAL 层在芯片组上设置通话录音音频路径的方式发生了变化。现在,除了在内核中设置正确的混音器控件外,还需要通过 libcs​​d-client.so(Qualcomm 专有,关闭源代码)库向基带调制解调器发送某种“魔术”命令。

Google 通过 dlsym libcs​​d-client.so 为 Nexus 4(运行 APQ8064)在 HAL 层执行此操作(请参阅csd_start_record函数)。但是,在应用程序级别使用带有 MediaRecorder.AudioSource.VOICE_DOWNLINK 的 AudioRecord API 将不起作用,因为AudioPolicyManagerBase.cpp已被硬编码为仅在通话中录音时接收带有通道掩码“AUDIO_CHANNEL_IN_MONO”或“AUDIO_CHANNEL_IN_STEREO”的 IOProfile用例,使用的通道掩码必须是 AUDIO_CHANNEL_IN_VOICE_UPLINK 或 AUDIO_CHANNEL_IN_VOICE_DNLINK。谷歌和三星似乎都无意纠正这个问题。奇怪的是,用于记录呼叫的公共 android API 永远不能保证正常工作。

因此,为了克服这个问题,我决定编写一个 NDK 可执行文件来对 csd_start_recording/csd_stop_recording 进行 dlsym,就像 Google 为 Nexus 4 所做的一样,并使用 amix/arec 实用程序在有根设备上进行本地录制。但现在问题来了。

在我的可执行文件中,我调用了 csd_client_init 和 csd_start_record,这两个调用都没有返回错误,但是 logcat 显示来自 libcs​​d-client.so 的一些 QMI(Qualcomm MSM 接口)错误,并且记录的波形文件只有静音。有没有人尝试过类似的事情?我现在完全不知道如何在无需将修改后的 ROM 闪存到设备的情况下进行通话录音。

更新

我再次重复测试,但似乎 QMI 错误消失了。我猜我上次遇到的 QMI 错误是由于我在测试期间搞砸了机器的状态。但是,录制仍然不起作用。结果仍然只是沉默。下面是我通过“csd” grep 的 logcat 输出:

D/        (  217): csd_client_disable_device: rx 7, tx 4, client_state=1
E/        (  217): csd_client_disable_device: Disable received in invalid state:1
D/        (  217): csd_client_enable_device: APQ rx 7, tx 34, ec 43, tty 0x10012 state 1
D/        (  217): csd_client_enable_device: Remote rx -1, tx -1
E/        (  217): csd_client_enable_device: Enable received in invalid state 1
D/        (  217): csd_client_start_voice: State 1
D/        (  217): csd_client_async_cb: msg_id 0x33 result 0 error 0
D/        (  217): csd_client_async_cb: msg_id 0x34 result 0 error 0
D/        (  217): csd_client_async_cb: msg_id 0x55 result 0 error 0
D/        (  217): csd_client_async_cb: msg_id 0x5c result 0 error 0
D/        (  217): csd_client_async_cb: msg_id 0x4c result 0 error 0
D/        (  217): csd_client_async_cb: msg_id 0x4c result 0 error 0
D/        (  217): csd_client_async_cb: msg_id 0x57 result 0 error 0
D/        (  217): csd_client_async_cb: msg_id 0x36 result 0 error 0
D/        (  217): csd_client_async_cb: msg_id 0x3e result 0 error 0
D/        (  217): csd_client_async_cb: msg_id 0x36 result 0 error 0
D/        (  217): csd_client_volume: volume 0, state 2, rc 0
D/        (  217): csd_client_async_cb: msg_id 0x37 result 0 error 0
D/        (  217): csd_client_set_rx_mute: mute 0, state 2, rc 0
D/        (  217): csd_client_async_cb: msg_id 0x3e result 0 error 0
D/        (  217): csd_client_mic_mute: mute 0, state 2, rc 0
D/        (  217): csd_client_async_cb: msg_id 0x36 result 0 error 0
D/        (  217): csd_client_volume: volume 4, state 2, rc 0
D/        ( 6801): csd_client_init
E/        ( 6801): csd_client_service_init: Invalid rx device 0, setting to handset
E/        ( 6801): csd_client_service_init: Invalid tx device 0, setting to handset
D/        (  217): csd_client_stop_voice: State 2
D/        (  217): csd_client_async_cb: msg_id 0x58 result 1 error 3
E/        (  217): csd_client_stop_voice: Error -1 stopping voice manager
E/ALSADevice(  217): s_close: csd_client error -1

PID 217 是设备上的原始 csd_client,PID 6801 是我的可执行文件。

我的可执行文件进行客户端初始化并在建立调用后一起调用 libcs​​d-client.so 上的“csd_start_recording”。从日志中可以看出,“真正的”csd-client 显然正在与调制解调器进行双向通信,即在设备启动时注册一些回调并从那时起调节音频设置。例如,“csd_client_start_voice”在呼叫通过时由 HAL 调用。我怀疑我伪造的 csd-client 错过了所有这些中间状态,因此未能达到目的。

无论如何,现阶段信息真的很有限,我感觉就像在黑暗中拍摄。希望有人可以在这里提供帮助。

4

1 回答 1

0

我有解决办法。基本上,您必须调用 medisaserver,因为除非您是该语音会话的所有者,否则 libcs​​d 中的任何内容都不会起作用。avs234.net/temp/csd_calls.c

于 2013-12-29T06:02:47.013 回答