1
0
Эх сурвалжийг харах

aaudio: Respect SDL_HINT_AUDIO_DEVICE_STREAM_ROLE hint.

Fixes #15299.
Ryan C. Gordon 1 өдөр өмнө
parent
commit
4d17b99d0a

+ 5 - 0
include/SDL3/SDL_hints.h

@@ -402,6 +402,11 @@ extern "C" {
  * - "Movie" - Music or sound with dialog
  * - "Movie" - Music or sound with dialog
  * - "Media" - Music or sound without dialog
  * - "Media" - Music or sound without dialog
  *
  *
+ * Android's AAudio target supports this hint as of SDL 3.4.4. Android does
+ * not support the exact same options as WASAPI, but for portability, will
+ * attempt to map these same strings to the `aaudio_usage_t` constants. For
+ * example, "Movie" and "Media" will both map to `AAUDIO_USAGE_MEDIA`, etc.
+ *
  * If your application applies its own echo cancellation, gain control, and
  * If your application applies its own echo cancellation, gain control, and
  * noise reduction it should also set SDL_HINT_AUDIO_DEVICE_RAW_STREAM.
  * noise reduction it should also set SDL_HINT_AUDIO_DEVICE_RAW_STREAM.
  *
  *

+ 24 - 0
src/audio/aaudio/SDL_aaudio.c

@@ -285,6 +285,28 @@ static void AAUDIO_CloseDevice(SDL_AudioDevice *device)
     }
     }
 }
 }
 
 
+static void SetOptionalStreamUsage(AAudioStreamBuilder *builder)
+{
+    if (ctx.AAudioStreamBuilder_setUsage) {    // optional API: requires Android 28
+        const char *hint = SDL_GetHint(SDL_HINT_AUDIO_DEVICE_STREAM_ROLE);
+        if (hint) {
+            aaudio_usage_t usage = AAUDIO_USAGE_MEDIA;  // covers most things, and is the system default.
+            if ((SDL_strcasecmp(hint, "Communications") == 0) || (SDL_strcasecmp(hint, "GameChat") == 0)) {
+                usage = AAUDIO_USAGE_VOICE_COMMUNICATION;
+            } else if (SDL_strcasecmp(hint, "Game") == 0) {
+                usage = AAUDIO_USAGE_GAME;
+            }
+            ctx.AAudioStreamBuilder_setUsage(builder, usage);
+
+            // !!! FIXME: I _think_ this is okay with the current set of usages we support, but the docs
+            // !!! FIXME:  say you need to dip down into Java to call android.app.Activity.setVolumeControlStream(usage)
+            // !!! FIXME:  so the physical volume buttons control this stream, but that might be more for special cases
+            // !!! FIXME:  like notification sounds, etc, and it's possible you _don't_ want to override this for those
+            // !!! FIXME:  special cases, too! We'll revisit if there are bug reports.
+        }
+    }
+}
+
 static bool BuildAAudioStream(SDL_AudioDevice *device)
 static bool BuildAAudioStream(SDL_AudioDevice *device)
 {
 {
     struct SDL_PrivateAudioData *hidden = device->hidden;
     struct SDL_PrivateAudioData *hidden = device->hidden;
@@ -343,6 +365,8 @@ static bool BuildAAudioStream(SDL_AudioDevice *device)
         SDL_Log("Low latency audio disabled");
         SDL_Log("Low latency audio disabled");
     }
     }
 
 
+    SetOptionalStreamUsage(builder);
+
     if (recording && ctx.AAudioStreamBuilder_setInputPreset) {    // optional API: requires Android 28
     if (recording && ctx.AAudioStreamBuilder_setInputPreset) {    // optional API: requires Android 28
         // try to use a microphone that is for recording external audio. Otherwise Android might choose the mic used for talking
         // try to use a microphone that is for recording external audio. Otherwise Android might choose the mic used for talking
         // on the telephone when held to the user's ear, which is often not useful at any distance from the device.
         // on the telephone when held to the user's ear, which is often not useful at any distance from the device.

+ 1 - 1
src/audio/aaudio/SDL_aaudiofuncs.h

@@ -37,7 +37,7 @@ SDL_PROC_UNUSED(void, AAudioStreamBuilder_setSharingMode, (AAudioStreamBuilder *
 SDL_PROC(void, AAudioStreamBuilder_setDirection, (AAudioStreamBuilder * builder, aaudio_direction_t direction))
 SDL_PROC(void, AAudioStreamBuilder_setDirection, (AAudioStreamBuilder * builder, aaudio_direction_t direction))
 SDL_PROC(void, AAudioStreamBuilder_setBufferCapacityInFrames, (AAudioStreamBuilder * builder, int32_t numFrames))
 SDL_PROC(void, AAudioStreamBuilder_setBufferCapacityInFrames, (AAudioStreamBuilder * builder, int32_t numFrames))
 SDL_PROC(void, AAudioStreamBuilder_setPerformanceMode, (AAudioStreamBuilder * builder, aaudio_performance_mode_t mode))
 SDL_PROC(void, AAudioStreamBuilder_setPerformanceMode, (AAudioStreamBuilder * builder, aaudio_performance_mode_t mode))
-SDL_PROC_UNUSED(void, AAudioStreamBuilder_setUsage, (AAudioStreamBuilder * builder, aaudio_usage_t usage))                                         // API 28
+SDL_PROC_OPTIONAL(void, AAudioStreamBuilder_setUsage, (AAudioStreamBuilder * builder, aaudio_usage_t usage))                                         // API 28
 SDL_PROC_UNUSED(void, AAudioStreamBuilder_setContentType, (AAudioStreamBuilder * builder, aaudio_content_type_t contentType))                      // API 28
 SDL_PROC_UNUSED(void, AAudioStreamBuilder_setContentType, (AAudioStreamBuilder * builder, aaudio_content_type_t contentType))                      // API 28
 SDL_PROC_OPTIONAL(void, AAudioStreamBuilder_setInputPreset, (AAudioStreamBuilder * builder, aaudio_input_preset_t inputPreset))                      // API 28
 SDL_PROC_OPTIONAL(void, AAudioStreamBuilder_setInputPreset, (AAudioStreamBuilder * builder, aaudio_input_preset_t inputPreset))                      // API 28
 SDL_PROC_UNUSED(void, AAudioStreamBuilder_setAllowedCapturePolicy, (AAudioStreamBuilder * builder, aaudio_allowed_capture_policy_t capturePolicy)) // API 29
 SDL_PROC_UNUSED(void, AAudioStreamBuilder_setAllowedCapturePolicy, (AAudioStreamBuilder * builder, aaudio_allowed_capture_policy_t capturePolicy)) // API 29