Изменение воспроизведения голоса во время разговора в пользовательском ПЗУ Android
Я хотел бы изменить ОС Android (официальное изображение из AOSP), чтобы добавить предварительную обработку к обычному звуку воспроизведения телефонного звонка.
Я уже достиг этой фильтрации для воспроизведения аудио в приложении (изменив HAL и audioflinger).
Я в порядке с таргетингом только на конкретное устройство (Nexus 5X). Кроме того, мне нужно только отфильтровать воспроизведение - меня не волнует запись (uplink).
ОБНОВЛЕНИЕ № 1:
Чтобы было ясно - я согласен с модификацией драйверов для Qualcomm или любой другой части, которая работает на Nexus 5X и может помочь мне изменить воспроизведение при вызове.
ОБНОВЛЕНИЕ № 2:
Я пытаюсь создать приложение слоя Java, которое направляет воспроизведение телефона в музыкальный поток в режиме реального времени.
Мне уже удалось установить его как системное приложение, получить разрешения на инициализацию AudioRecord
с AudioSource.VOICE_DOWNLINK
, Тем не менее, запись дает пустые образцы; он не записывает голосовой вызов.
Это код внутри моего рабочего потока:
// Start recording
int recBufferSize = AudioRecord.getMinBufferSize(44100, AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_16BIT);
mRecord = new AudioRecord(MediaRecorder.AudioSource.VOICE_DOWNLINK, 44100, AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_16BIT, recBufferSize);
// Start playback
int playBufferSize = AudioTrack.getMinBufferSize(44100, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT);
mTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT, playBufferSize, AudioTrack.MODE_STREAM);
mRecord.startRecording();;
mTrack.play();
int bufSize = 1024;
short[] buffer = new short[bufSize];
int res;
while (!interrupted())
{
// Pull recording buffers and play back
res = mRecord.read(buffer, 0, bufSize, AudioRecord.READ_NON_BLOCKING);
mTrack.write(buffer, 0, res, AudioTrack.WRITE_BLOCKING);
}
// Stop recording
mRecord.stop();
mRecord.release();
mRecord = null;
// Stop playback
mTrack.stop();
mTrack.release();;
mTrack = null;
Я работаю на Nexus 5X, моем собственном AOSP, Android 7.1.1. Мне нужно найти место, которое позволит записывать звонки, возможно, где-то в hardware/qcom/audio/hal
в коде платформы.
Также я смотрю на функцию voice_check_and_set_incall_rec_usecase
в hardware/qcom/audio/hal/voice.c
Однако я не смог понять это (как заставить это работать так, как я хочу).
ОБНОВЛЕНИЕ № 3:
Я открыл более конкретный вопрос об использовании AudioSource.VOICE_DOWNLINK
, что может привлечь правильное внимание и в конечном итоге поможет мне решить проблему этого вопроса.
1 ответ
Есть несколько возможных проблем, которые приходят мне в голову. Пустой буфер может указывать на то, что вы выбрали неверный источник. Кроме того, поскольку в соответствии с https://developer.android.com/reference/android/media/AudioRecord.html вы не всегда можете получить исключение, даже если что-то неправильно с конфигурацией, вы можете проверить, правильно ли инициализирован ваш объект. Если ничего не помогает, вы также можете сделать "mRecord.setPreferredDevice(AudioDeviceInfo.TYPE_BUILTIN_EARPIECE);" направить встроенный динамик телефона прямо на вход вашего рекордера. Да, это немного грязно и непристойно, но, возможно, подходит для этой цели.
Другая вещь, которая меня озадачивала, это то, что вместо использования класса builder вы пытались настроить объект напрямую через его конструктор. Есть ли конкретная причина, по которой вы не хотите использовать AudioRecord.Builder (есть даже хороший пример взамен https://developer.android.com/reference/android/media/AudioRecord.Builder.html)?