Ändern der Sprachwiedergabe während eines Anrufs im benutzerdefinierten Android-ROM

78

Ich möchte das Android-Betriebssystem (offizielles Bild von AOSP) ändern, um einem normalen Wiedergabeton für Telefonanrufe eine Vorverarbeitung hinzuzufügen.

Ich habe diese Filterung für die App-Audiowiedergabe bereits erreicht (durch Ändern von HAL und Audioflinger ).

Ich kann nur ein bestimmtes Gerät (Nexus 5X) als Ziel festlegen. Außerdem muss ich nur die Wiedergabe filtern - die Aufnahme (Uplink) ist mir egal.

UPDATE # 1:

Um es klar zu machen: Ich bin damit einverstanden, Qualcomm-spezifische Treiber oder den Teil zu ändern, der auf dem Nexus 5X ausgeführt wird und mir bei der Änderung der Anrufwiedergabe helfen kann.

UPDATE 2:

Ich versuche, eine Java-Layer-App zu erstellen, die die Telefonwiedergabe in Echtzeit an den Musikstrom weiterleitet.

Es ist mir bereits gelungen, es als System-App zu installieren und Berechtigungen zum Initialisieren AudioRecordmit zu erhalten AudioSource.VOICE_DOWNLINK. Die Aufzeichnung liefert jedoch leere Proben; Der Sprachanruf wird nicht aufgezeichnet.

Dies ist der Code in meinem Arbeitsthread:

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

Ich verwende ein Nexus 5X, mein eigenes AOSP-ROM, Android 7.1.1. Ich muss den Ort finden, an dem die Anrufaufzeichnung funktioniert - wahrscheinlich irgendwo hardware/qcom/audio/halim Plattformcode.

Ich habe mir auch die Funktion voice_check_and_set_incall_rec_usecaseunter angesehen hardware/qcom/audio/hal/voice.c. Ich konnte sie jedoch nicht verstehen (wie man sie so funktioniert, wie ich es möchte).

UPDATE 3:

Ich habe eine spezifischere Frage zur Verwendung geöffnet AudioSource.VOICE_DOWNLINK, die möglicherweise die richtige Aufmerksamkeit auf sich zieht und mir schließlich auch bei der Lösung des Problems dieser Frage helfen wird.

SirKnigget
quelle
Ich wollte das machen. Damit der Anruf nach Schlüsselwörtern überwacht wird, wird der Anruf mit Ton versehen. Wie ich schon "Golf" sage und dann wird ein Golfklatschgeräusch in den Anruf eingespeist.
danny117
Ich bezweifle, dass das Ändern von Standard-E / A möglich ist, ohne mit ndk-jni zu spielen
Pararth
1
Ich spreche über das Erstellen eines benutzerdefinierten ROM, nicht einer normalen App.
SirKnigget
IIRC, ein Telefonanruf wird als vertrauliche Information betrachtet und offene Software hat keinen Zugriff darauf. Sie müssten die als "Radio" bekannte Closed-Source-Firmware hacken. Wahrscheinlich nicht machbar.
Zdenek
Das ist nicht wahr. Es gibt eine Anrufaufzeichnungs-API und unzählige Apps, die ihren Weg gefunden haben, sie mithilfe verschiedener Hacks auf vielen Geräten zu verwenden.
SirKnigget

Antworten:

1

Es gibt mehrere mögliche Probleme, die mir in den Sinn kommen. Der leere Puffer zeigt möglicherweise an, dass Sie die falsche Quelle ausgewählt haben. Auch da laut https://developer.android.com/reference/android/media/AudioRecord.html#AudioRecord(int,%20int,%20int,%20int,%20int) Sie möglicherweise nicht immer eine Ausnahme erhalten, selbst wenn etwas passiert Wenn Sie mit der Konfiguration falsch sind, möchten Sie möglicherweise bestätigen, ob Ihr Objekt ordnungsgemäß initialisiert wurde. Wenn alles andere fehlschlägt, können Sie auch ein "mRecord.setPreferredDevice (AudioDeviceInfo.TYPE_BUILTIN_EARPIECE)" ausführen. um den eingebauten Ohrhörer des Telefons direkt an den Eingang Ihres Rekorders zu leiten. Ja, es ist ein bisschen schmutzig und hackig, aber vielleicht passt es zum Zweck.

Die andere Sache, die mich verwirrte, war, dass Sie anstelle der Builder-Klasse versucht haben, das Objekt direkt über seinen Konstruktor zu konfigurieren. Gibt es einen bestimmten Grund, warum Sie AudioRecord.Builder nicht verwenden möchten (es gibt sogar ein schönes Beispiel unter https://developer.android.com/reference/android/media/AudioRecord.Builder.html )?

CoolKoon
quelle
Alle Punkte, die Sie angesprochen haben, wurden überprüft. Dies hängt nicht zusammen. Die Builder-Klasse ist zwar aktueller, aber intern befindet sie sich genau an derselben Stelle (siehe Android-Quellcode).
SirKnigget
Das Anschließen an die Funktion der Quelle des eingebauten Ohrhörers funktionierte also auch nicht als Problemumgehung?
CoolKoon
Nein, es hängt nicht mit dem zugrunde liegenden Problem zusammen.
SirKnigget