2016-09-28 2 views
9

Ich schreibe eine neue Android Audio HAL, damit meine App Audio an andere Apps füttern kann, damit meine Handfernmikrofoneingabe die Google App erreichen kann. Im Wesentlichen ein virtuelles Audiokabel.Was benötigt wird, damit Android ein neues Audio verwendet HAL

Es ist ein work in progress. Ich werde wahrscheinlich AUDIO_DEVICE_IN_BACK_MIC außer Kraft setzen, aber dies ist offen für Vorschläge.

Ich habe Zweifel, wie Sie sicherstellen, dass Android diese HAL für die Eingabe verwendet.

Muss ich audio.primary.default.so ersetzen oder sollte ich es als audio.vcable.default.so belassen?

Genauer gesagt: Wenn ich Primär nicht ersetze, wie wird Android wissen, meine HAL anstelle von primären zu verwenden?


Update:

ich wirklich jede Hilfe in dieser Arbeit nutzen könnten. Alle Zeiger sind hilfreich.

Ich habe ein Audio-HAL-Modul geschrieben. Ich habe folgende (fett Artikel) audio_policy.conf:

global:

global_configuration { 
    attached_output_devices AUDIO_DEVICE_OUT_SPEAKER|**AUDIO_DEVICE_OUT_LINE** 
    default_output_device AUDIO_DEVICE_OUT_SPEAKER 
    attached_input_devices AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_BACK_MIC|AUDIO_DEVICE_IN_REMOTE_SUBMIX|**AUDIO_DEVICE_IN_LINE** 
} 

und unter audio_hw_modules

vloop { 
    inputs { 
     vloop { 
     sampling_rates 16000 
     channel_masks AUDIO_CHANNEL_IN_MONO 
     formats AUDIO_FORMAT_PCM_16_BIT 
     devices AUDIO_DEVICE_IN_LINE 
     } 
    } 
    outputs { 
     vloop { 
     sampling_rates 16000 
     channel_masks AUDIO_CHANNEL_OUT_STEREO 
     formats AUDIO_FORMAT_PCM_16_BIT 
     devices AUDIO_DEVICE_OUT_LINE 
     flags AUDIO_OUTPUT_FLAG_DIRECT 
     } 
    } 
    } 

ich auch folgende (fett) hinzugefügt AudioFlinger.cpp

static const char * const audio_interfaces[] = { 
    AUDIO_HARDWARE_MODULE_ID_PRIMARY, 
    AUDIO_HARDWARE_MODULE_ID_A2DP, 
    AUDIO_HARDWARE_MODULE_ID_USB, 
    **AUDIO_HARDWARE_MODULE_ID_VLOOP** 
}; 

Ich kann sehen, dass während des Bootens meine HAL geladen wird, und ich bekomme diese Protokolle:

10-06 06:14:40.365 194-194/? I/AudioFlinger: Using default 3000 mSec as standby time. 
10-06 06:14:46.664 194-194/? I/AudioPolicyService: AudioPolicyService CSTOR in new mode 
10-06 06:14:46.673 194-194/? I/APM::ConfigParsingUtils: loadAudioPolicyConfig() loaded /system/etc/audio_policy.conf 
10-06 06:14:46.681 194-194/? D/audio_hw_primary: adev_open: enter 
10-06 06:14:46.797 194-194/? I/AudioFlinger: loadHwModule() Loaded primary audio interface from QCOM Audio HAL (audio) handle 1 
10-06 06:14:46.797 194-194/? I/AudioFlinger: openOutput(), module 1 Device 2, SamplingRate 48000, Format 0x000001, Channels 3, flags 2 
10-06 06:14:46.797 194-194/? I/AudioFlinger: AudioStreamOut::open(), mHalFormatIsLinearPcm = 1 
10-06 06:14:46.798 194-194/? I/AudioFlinger: HAL output buffer size 240 frames, normal sink buffer size 960 frames 
10-06 06:14:46.813 194-194/? I/AudioFlinger: Using module 1 has the primary audio interface 
10-06 06:14:46.816 194-607/? I/AudioFlinger: AudioFlinger's thread 0xb4140000 ready to run 
10-06 06:14:46.816 194-607/? D/audio_hw_primary: out_set_parameters: enter: usecase(1: low-latency-playback) kvpairs: routing=2 
10-06 06:14:46.818 194-194/? I/AudioFlinger: openOutput(), module 1 Device 2, SamplingRate 48000, Format 0x000001, Channels 3, flags 8 
10-06 06:14:46.818 194-194/? I/AudioFlinger: AudioStreamOut::open(), mHalFormatIsLinearPcm = 1 
10-06 06:14:46.818 194-194/? I/AudioFlinger: HAL output buffer size 960 frames, normal sink buffer size 960 frames 
10-06 06:14:46.818 194-608/? I/AudioFlinger: AudioFlinger's thread 0xb3dc0000 ready to run 
10-06 06:14:46.818 194-607/? E/AudioFlinger: no wake lock to update! 
10-06 06:14:46.818 194-608/? D/audio_hw_primary: out_set_parameters: enter: usecase(0: deep-buffer-playback) kvpairs: routing=2 
10-06 06:14:46.818 194-608/? E/AudioFlinger: no wake lock to update! 
10-06 06:14:46.820 194-609/? I/AudioFlinger: AudioFlinger's thread 0xb3c40000 ready to run 
10-06 06:14:46.823 194-194/? I/AudioFlinger: loadHwModule() Loaded a2dp audio interface from A2DP Audio HW HAL (audio) handle 7 
10-06 06:14:46.828 194-194/? I/AudioFlinger: loadHwModule() Loaded usb audio interface from USB audio HW HAL (audio) handle 8 
10-06 06:14:46.832 194-194/? I/r_submix: adev_open(name=audio_hw_if) 
10-06 06:14:46.832 194-194/? I/AudioFlinger: loadHwModule() Loaded r_submix audio interface from Wifi Display audio HAL (audio) handle 9 
10-06 06:14:46.832 194-194/? D/r_submix: submix_audio_device_create_pipe_l(addr=0, idx=9) 
10-06 06:14:46.833 194-610/? I/AudioFlinger: AudioFlinger's thread 0xb3bc0000 ready to run 
10-06 06:14:46.833 194-194/? D/r_submix: submix_audio_device_release_pipe_l(idx=9) addr=0 
10-06 06:14:46.833 194-194/? D/r_submix: submix_audio_device_destroy_pipe_l(): pipe destroyed 
10-06 06:14:46.835 194-194/? D/audio_vloop: adev_open: audio_hw_if 
10-06 06:14:46.835 194-194/? D/audio_vloop: adev_open(): 1678 
10-06 06:14:46.835 194-194/? D/audio_vloop: adev_open(): 1685 
10-06 06:14:46.835 194-194/? D/audio_vloop: adev_open(): 1688 
10-06 06:14:46.835 194-194/? D/audio_vloop: adev_open(): 1722 
10-06 06:14:46.835 194-194/? D/audio_vloop: adev_init_check(): 1252 
10-06 06:14:46.835 194-194/? D/audio_vloop: adev_set_master_volume: 1.000000 
10-06 06:14:46.835 194-194/? D/audio_vloop: adev_set_master_mute: 0 
10-06 06:14:46.835 194-194/? I/AudioFlinger: loadHwModule() Loaded vloop audio interface from UI_audio_HW_HAL (audio) handle 11 
10-06 06:14:46.835 194-194/? D/audio_vloop: adev_open_input_stream(): 1490 
10-06 06:14:46.835 194-194/? D/audio_vloop: in_get_sample_rate(): 979 
10-06 06:14:46.835 194-194/? D/audio_vloop: in_get_channels(): 1017 
10-06 06:14:46.835 194-194/? D/audio_vloop: in_get_channels: 0x00000001 
10-06 06:14:46.835 194-194/? D/audio_vloop: in_get_format(): 1029 
10-06 06:14:46.836 194-194/? D/audio_vloop: in_get_format: 0x00000001 
10-06 06:14:46.836 194-194/? D/audio_vloop: in_get_format(): 1029 
10-06 06:14:46.836 194-194/? D/audio_vloop: in_get_format: 0x00000001 
10-06 06:14:46.836 194-194/? D/audio_vloop: in_get_channels(): 1017 
10-06 06:14:46.836 194-194/? D/audio_vloop: in_get_channels: 0x00000001 
10-06 06:14:46.836 194-194/? D/audio_vloop: in_get_buffer_size(): 1005 
10-06 06:14:46.836 194-194/? D/audio_vloop: in_get_buffer_size: 1600 
10-06 06:14:46.836 194-194/? D/audio_vloop: in_get_buffer_size(): 1005 
10-06 06:14:46.836 194-194/? D/audio_vloop: in_get_buffer_size: 1600 
10-06 06:14:46.836 194-194/? D/audio_vloop: in_get_format(): 1029 
10-06 06:14:46.836 194-194/? D/audio_vloop: in_get_format: 0x00000001 
10-06 06:14:46.836 194-194/? D/audio_vloop: in_get_sample_rate(): 979 
10-06 06:14:46.836 194-194/? D/audio_vloop: in_get_channels(): 1017 
10-06 06:14:46.836 194-194/? D/audio_vloop: in_get_channels: 0x00000001 
10-06 06:14:46.838 194-613/? I/AudioFlinger: AudioFlinger's thread 0xb3bc0000 ready to run 
10-06 06:14:46.838 194-194/? D/audio_vloop: adev_close_input_stream(): 1570 
10-06 06:14:46.839 194-194/? W/APM::AudioPolicyManager: Input device 00020000 unreachable 
10-06 06:14:46.839 194-611/? D/audio_vloop: looper_thread(): 216: Entered 
10-06 06:14:46.839 194-611/? D/audio_vloop: looper_thread(): 366: Exiting 
10-06 06:15:07.137 616-616/? I/InputManager: Initializing input manager, mUseDevInputEventForAudioJack=false 
10-06 06:15:10.155 616-616/? I/SystemServer: Audio Service 
10-06 06:15:10.222 194-607/? E/AudioFlinger: no wake lock to update! 
10-06 06:15:10.222 194-608/? E/AudioFlinger: no wake lock to update! 
10-06 06:15:10.224 194-614/? D/audio_hw_primary: adev_set_mic_mute: state 0 
10-06 06:15:10.224 194-614/? D/audio_vloop: adev_set_mic_mute: 0 
10-06 06:15:14.061 194-614/? D/audio_hw_primary: adev_set_parameters: enter: A2dpSuspended=false 
10-06 06:15:14.061 194-614/? D/audio_vloop: adev_set_parameters(): [A2dpSuspended=false] 
10-06 06:15:14.084 194-194/? I/AudioFlinger: systemReady 
10-06 06:15:16.308 194-194/? D/audio_hw_primary: adev_set_mic_mute: state 0 
10-06 06:15:16.308 194-194/? D/audio_vloop: adev_set_mic_mute: 0 
10-06 06:15:17.072 194-194/? D/audio_hw_primary: adev_set_parameters: enter: A2dpSuspended=false 
10-06 06:15:17.072 194-194/? D/audio_vloop: adev_set_parameters(): [A2dpSuspended=false] 
10-06 06:15:25.023 733-733/? W/AudioTrack: AUDIO_OUTPUT_FLAG_FAST denied by client; transfer 4, track 44100 Hz, output 48000 Hz 
10-06 06:15:25.032 194-607/? D/audio_hw_primary: out_set_parameters: enter: usecase(1: low-latency-playback) kvpairs: routing=2 
10-06 06:15:25.043 194-607/? D/audio_hw_primary: select_devices: out_snd_device(2: speaker) in_snd_device(0: none) 
10-06 06:15:25.043 194-607/? D/audio_hw_primary: enable_snd_device: snd_device(2: speaker) 
10-06 06:15:25.050 194-607/? D/audio_hw_primary: enable_audio_route: apply and update mixer path: low-latency-playback 
10-06 06:15:26.431 1150-1298/? I/MicrophoneInputStream: mic_starting [email protected] 
10-06 06:15:26.443 194-1585/? I/AudioFlinger: AudioFlinger's thread 0xb3bc0000 ready to run 
10-06 06:15:26.447 1150-1298/? I/MicrophoneInputStream: mic_started [email protected] 
10-06 06:15:26.457 194-1585/? D/audio_hw_primary: select_devices: out_snd_device(0: none) in_snd_device(38: voice-rec-mic) 
10-06 06:15:26.457 194-1585/? D/audio_hw_primary: enable_snd_device: snd_device(38: voice-rec-mic) 
10-06 06:15:26.460 194-1585/? D/audio_hw_primary: enable_audio_route: apply and update mixer path: audio-record 
10-06 06:15:26.942 1150-1271/? I/AudioController: internalShutdown 
10-06 06:15:26.943 1150-1271/? I/MicrophoneInputStream: mic_close [email protected] 
10-06 06:15:26.943 1150-1298/? E/AudioRecord-JNI: Error -4 during AudioRecord native read 
10-06 06:15:26.986 194-1585/? D/audio_hw_primary: disable_audio_route: reset and update mixer path: audio-record 
10-06 06:15:26.987 194-1585/? D/audio_hw_primary: disable_snd_device: snd_device(38: voice-rec-mic) 
10-06 06:15:27.066 194-607/? D/audio_hw_primary: out_set_parameters: enter: usecase(1: low-latency-playback) kvpairs: routing=2 
10-06 06:15:27.100 194-607/? D/AudioFlinger: mixer(0xb4140000) throttle end: throttle time(7) 
10-06 06:15:30.257 194-607/? D/audio_hw_primary: disable_audio_route: reset and update mixer path: low-latency-playback 
10-06 06:15:30.257 194-607/? D/audio_hw_primary: disable_snd_device: snd_device(2: speaker) 
10-06 06:15:30.262 194-607/? D/audio_hw_primary: out_set_parameters: enter: usecase(1: low-latency-playback) kvpairs: routing=2 
10-06 06:15:30.272 194-607/? D/audio_hw_primary: select_devices: out_snd_device(2: speaker) in_snd_device(0: none) 
10-06 06:15:30.273 194-607/? D/audio_hw_primary: enable_snd_device: snd_device(2: speaker) 
10-06 06:15:30.280 194-607/? D/audio_hw_primary: enable_audio_route: apply and update mixer path: low-latency-playback 
10-06 06:15:30.347 194-607/? D/AudioFlinger: mixer(0xb4140000) throttle end: throttle time(10) 
10-06 06:15:31.517 194-607/? D/audio_hw_primary: out_set_parameters: enter: usecase(1: low-latency-playback) kvpairs: routing=2 
10-06 06:15:31.751 1150-1298/? I/MicrophoneInputStream: mic_starting [email protected] 
10-06 06:15:31.762 194-1826/? I/AudioFlinger: AudioFlinger's thread 0xb3bc0000 ready to run 
10-06 06:15:31.771 1150-1298/? I/MicrophoneInputStream: mic_started [email protected] 
10-06 06:15:31.780 194-1826/? D/audio_hw_primary: select_devices: out_snd_device(0: none) in_snd_device(38: voice-rec-mic) 
10-06 06:15:31.780 194-1826/? D/audio_hw_primary: enable_snd_device: snd_device(38: voice-rec-mic) 
10-06 06:15:31.783 194-1826/? D/audio_hw_primary: enable_audio_route: apply and update mixer path: audio-record 
10-06 06:15:34.695 194-607/? D/audio_hw_primary: disable_audio_route: reset and update mixer path: low-latency-playback 
10-06 06:15:34.695 194-607/? D/audio_hw_primary: disable_snd_device: snd_device(2: speaker) 
10-06 06:15:34.850 1150-1271/? I/AudioController: internalShutdown 
10-06 06:15:34.851 1150-1271/? I/MicrophoneInputStream: mic_close [email protected] 
10-06 06:15:34.851 1150-1298/? E/AudioRecord-JNI: Error -4 during AudioRecord native read 
10-06 06:15:34.885 194-1826/? D/audio_hw_primary: disable_audio_route: reset and update mixer path: audio-record 
10-06 06:15:34.885 194-1826/? D/audio_hw_primary: disable_snd_device: snd_device(38: voice-rec-mic) 

Meine ist audio_vloop. Ich kann sehen, dass Android mein Gerät öffnet, öffnet dann den Eingabestream und schließt dann den Eingabestream. Es versucht nie, den Ausgabestream zu öffnen. audio_vloop implementiert sowohl Eingabe- als auch Ausgabeströme. Danach wird nichts in audio_vloop von Android aufgerufen.

Ich machte eine kleine App, die Audio spielt (aus einer PCM-Datei für den Moment). Ich möchte diese Ausgabe an meine HAL umleiten. Um dies zu erreichen, muss ein AudioTrack.setPreferredDevice() auf meiner Audiospur ausgeführt werden. Ich habe festgestellt, dass Audio Manager eine Liste aller Audiogeräte haben sollte.

so nenne ich:

AudioDeviceInfo aDevInfo[] = am.getDevices(AudioManager.GET_DEVICES_OUTPUTS); 

Es findet nur ein Gerät, mehr Informationen zu diesem Gerät:

10-06 06:37:01.962 3295-3663/? D/AudioPlayer: Have [1] devices 
10-06 06:37:01.964 3295-3663/? D/AudioPlayer: devInfo[0]: [Landroid.media.AudioDeviceInfo;@90bd9da 
10-06 06:37:01.965 3295-3663/? D/AudioPlayer: getProductName()AOSP on Flo 
10-06 06:37:01.965 3295-3663/? D/AudioPlayer: getType()2 
10-06 06:37:01.966 3295-3663/? D/AudioPlayer: isSink()true 
10-06 06:37:01.966 3295-3663/? D/AudioPlayer: isSource()false 

Diese scheinbar von Audioport, die ich noch nicht umgesetzt haben. Also nicht von meiner HAL.

Ich habe offensichtlich einen oder mehrere Schritte verpasst, bevor Android meine App erlaubt, mit meinem Gerät zu sprechen.

Ich muss in der Lage sein, Audio von meiner App in meine HAL zu senden. Später muss ich auch Audio von meinem HAL (über AudioRecord usw.) empfangen können.

Was habe ich bei der Integration meiner HAL in Android verpasst? Muss ich Audio-Ports implementieren? Wird noch etwas benötigt?


Update 2

Ich fand ein Tippfehler in AOSP gibt es in AudioPolicyManager.cpp[email protected]

Statt Output, druckt es Input

ich dieses Protokoll hatte AudioPolicyManager: Input device 00020000 unreachable das ich außer Acht gelassen vorausgesetzt, es ist Sprechen über BT/A2DP Eingabegerät.

Ich habe das Protokoll für mein Gerät repariert, und es stellt sich heraus, Line-Out-Gerät, das wir verwenden möchten. Ich debugge jetzt diese Richtung.

+1

Sie müssten Ihr eigenes [Audiomodul] (https://android.googlesource.com/platform/hardware/libhardware/+/master/modules/usbaudio) implementieren und es zu den 'PRODUCT_PACKAGES' hinzufügen Ihr Gerät Makefile. Sie müssten es wahrscheinlich auch in [den 'AudioFlinger'] (https://android.googlesource.com/platform/frameworks/av/+/master/services/audioflinger/AudioFlinger.cpp#279) hinzufügen. Es könnte andere Änderungen geben, die notwendig sind. Es ist eine Weile her, seit ich mit solchen Sachen gearbeitet habe. – Michael

+0

Siehe auch [diese alte Antwort von mir] (http://stackoverflow.com/questions/21024851/redirecting-audio-creating-alternate-sound-paths-in-android/21217919#21217919) wo ich gehe durch, wie man könnte Implementieren Sie eine neue 'AudioSource', die die aktuelle Audioausgabe auf einigen Qualcomm-Plattformen erfasst. – Michael

+0

findet findSuitableHwDev_l() letztlich welche Audio-Hal zu verwenden? Wenn ja, könnte ich das ändern, um immer mein Modul für die Audioeingabe auszuwählen. Danke für den Zeiger. – GPS

Antwort

4

Gefundene Antworten.

Denn aus stream:

  1. Ausgänge, die AUDIO_CHANNEL_OUT_STEREO nicht nicht geöffnet unterstützen, werden von Android
  2. Ausgänge, die Flagge erwähnen AUDIO_OUTPUT_FLAG_DIRECT nicht durch Android automatisch geöffnet. Dies zeigt sich in folgenden Code in AudioPolicyManager.cpp

    if ((outProfile->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) { 
         continue; 
        } 
    

    von here

Es kann ein Weg sein, um sie in programmatisch zu öffnen, aber ich habe nicht Antwort darauf gefunden.

Diese beiden, einmal behoben, waren ausreichend für Android, um meinen outstream zu verwenden.

Für in stream:

In-Stream war bereits ein Teil der Ergebnisse der AudioManager.getDevices()

So war es möglich, aus Vloop im Strom nach AudioTrack.setPreferredDevice() zu lesen.

Um sicherzustellen, dass andere Anwendungen Mic-Eingang von Vloop lesen, musste ich es zu implementieren AUDIO_DEVICE_IN_BUILTIN_MIC zu implementieren. Damit dies funktioniert, habe ich auch AUDIO_DEVICE_IN_BUILTIN_MIC von der primären HAL in audio_policy.conf entfernt.

Zusätzlich habe ich in Stream-Stereo gemacht, nur um die Kompatibilität mit out-Stream-Puffer-Format zu erhalten.

Nach diesen Änderungen sehe ich, dass es dauernde Lese- und Schreibaufrufe zu vloop gibt.

UPDATE:

Später fand ich, dass oben erwähnte Verhalten auf Audio Policy Manager Implementierung abhängig ist. Die meisten von ihnen verhalten sich auf die gleiche Weise (z.B.(INBUILT_MIC für VOICE_RECOGNITION-Eingang öffnen), aber einige nicht (Nexus Player) Für diese Ausreißer implementieren Sie entweder, was ihre APMs öffnen, oder ändern APMs, um zu öffnen, was Ihre HAL implementiert.

Verwandte Themen