mozilla / cubeb-coreaudio-rs

The audio backend of Firefox on Mac OS X.
ISC License
25 stars 10 forks source link

Implement a API to get `groupd_id` with special case handling #69

Closed ChunMinChang closed 4 years ago

ChunMinChang commented 4 years ago

This address #73. In general, we use model-uid as group_id of cuben-device-info. However, the group_id for built-in mic and built-in speaker might be different (or TRRS mic and TRRS headphone), so we use a hardcode group_id for those devices.

On the other hand, I find my AirPods will return an error when querying kAudioDevicePropertyModelUID within input or output scope (kAudioDevicePropertyScopeInput or kAudioDevicePropertyScopeOutput), but it's ok within global (kAudioObjectPropertyScopeGlobal) scope. So it might be good if we fallback to use global scope for querying model-uid when querying in input or output scope fails.

padenot commented 4 years ago

I'd rather have a good group id here. We can special case airpods, we are already special-casing them elsewhere. We should also special case built-in speakers and mic, and built-in trrs plug, but this can be done in another patch.

ChunMinChang commented 4 years ago

I'd rather have a good group id here. We can special case airpods, we are already special-casing them elsewhere. We should also special case built-in speakers and mic, and built-in trrs plug, but this can be done in another patch.

Now, group_id of AirPod in input side and output side returns the same string. And the group_id of built-in speakers, mic, and built-in trrs plug are all the same (I guess they are actually on the same soundcard).

After using the global model, the AirPods return the same group_id for both input and output scope, instead of returning a nullptr since failing to query get_device_model_uid in input or output scope.

For built-in speakers, mic, and built-in trrs plug, before or after these changes, they return the same group_id.

I'll add a test later to guarantee we always return the same group_id for <builtin mic, builtin speaker>, or <built-in trrs mic, built-in trrs speaker> and <AirPods mic, AirPods speaker>.

padenot commented 4 years ago

I'd rather have a good group id here. We can special case airpods, we are already special-casing them elsewhere. We should also special case built-in speakers and mic, and built-in trrs plug, but this can be done in another patch.

Now, group_id of AirPod in input side and output side returns the same string. And the group_id of built-in speakers, mic, and built-in trrs plug are all the same (I guess they are actually on the same soundcard).

This is not what I see on my computer (dump below).

After using the global model, the AirPods return the same group_id for both input and output scope, instead of returning a nullptr since failing to query get_device_model_uid in input or output scope.

For built-in speakers, mic, and built-in trrs plug, before or after these changes, they return the same group_id.

With or without this patch, this is what I have when running test_devices in the regular cubeb repo, with this backed:

dev: "BuiltInSpeakerDevice"
    Name:    "MacBook Pro Speakers"
    Group:   "Speaker"
    Vendor:  "Apple Inc."
    Type:    output
    State:   enabled
    Ch:      2
    Format:  S16LE S16BE F32LE F32BE (0x3030) (default: F32LE)
    Rate:    44100 - 96000 (default: 48000)
    Latency: lo 309 frames, hi 4390 frames
dev: "BuiltInHeadphoneOutputDevice" (PREFERRED)
    Name:    "External Headphones"
    Group:   "Codec Output"
    Vendor:  "Apple Inc."
    Type:    output
    State:   enabled
    Ch:      2
    Format:  S16LE S16BE F32LE F32BE (0x3030) (default: F32LE)
    Rate:    44100 - 96000 (default: 48000)
    Latency: lo 80 frames, hi 4161 frames
dev: "BuiltInMicrophoneDevice" (PREFERRED)
    Name:    "MacBook Pro Microphone"
    Group:   "Digital Mic"
    Vendor:  "Apple Inc."
    Type:    input
    State:   enabled
    Ch:      1
    Format:  S16LE S16BE F32LE F32BE (0x3030) (default: F32LE)
    Rate:    44100 - 96000 (default: 48000)
    Latency: lo 1971 frames, hi 6052 frames

I'll add a test later to guarantee we always return the same group_id for <builtin mic, builtin speaker>, or <built-in trrs mic, built-in trrs speaker> and <AirPods mic, AirPods speaker>.

Sounds good, but we need to fix the above first. I'm running Catalina (10.15.4 (19E266)) on a MacBook Pro (15-inch, 2018), I don't know if this matters.

ChunMinChang commented 4 years ago

With or without this patch, this is what I have when running test_devices in the regular cubeb repo, with this backed:

dev: "BuiltInSpeakerDevice"
  Name:    "MacBook Pro Speakers"
  Group:   "Speaker"
  Vendor:  "Apple Inc."
  Type:    output
  State:   enabled
  Ch:      2
  Format:  S16LE S16BE F32LE F32BE (0x3030) (default: F32LE)
  Rate:    44100 - 96000 (default: 48000)
  Latency: lo 309 frames, hi 4390 frames
dev: "BuiltInHeadphoneOutputDevice" (PREFERRED)
  Name:    "External Headphones"
  Group:   "Codec Output"
  Vendor:  "Apple Inc."
  Type:    output
  State:   enabled
  Ch:      2
  Format:  S16LE S16BE F32LE F32BE (0x3030) (default: F32LE)
  Rate:    44100 - 96000 (default: 48000)
  Latency: lo 80 frames, hi 4161 frames
dev: "BuiltInMicrophoneDevice" (PREFERRED)
  Name:    "MacBook Pro Microphone"
  Group:   "Digital Mic"
  Vendor:  "Apple Inc."
  Type:    input
  State:   enabled
  Ch:      1
  Format:  S16LE S16BE F32LE F32BE (0x3030) (default: F32LE)
  Rate:    44100 - 96000 (default: 48000)
  Latency: lo 1971 frames, hi 6052 frames

I'm running Catalina (10.15.4 (19E266)) on a MacBook Pro (15-inch, 2018), I don't know if this matters.

Probably. I am on MacBook Pro (15-inch, 2017). The built-in speaker is

dev: "AppleHDAEngineOutput:1F,3,0,1,1:0"
    Name:    "Internal Speakers"
    Group:   "AppleHDA:57"
    Vendor:  "Apple Inc."
    Type:    output
    State:   enabled
    Ch:      2
    Format:  S16LE S16BE F32LE F32BE (0x3030) (default: F32LE)
    Rate:    44100 - 96000 (default: 44100)
    Latency: lo 342 frames, hi 4424 frames

and the microphone is:

dev: "AppleHDAEngineInput:1F,3,0,1,0:1" (PREFERRED)
    Name:    "Internal Microphone"
    Group:   "AppleHDA:57"
    Vendor:  "Apple Inc."
    Type:    input
    State:   enabled
    Ch:      2
    Format:  S16LE S16BE F32LE F32BE (0x3030) (default: F32LE)
    Rate:    44100 - 96000 (default: 44100)
    Latency: lo 23 frames, hi 4105 frames

Their group_id are both "AppleHDA:57".

Another surprising fact is: When plugging TRRS, my mbp replace the "Internal Speakers" and "Internal Microphone" by "Headphones" and "External Microphone",

dev: "AppleHDAEngineOutput:1F,3,0,1,1:0" (PREFERRED)
    Name:    "Headphones"
    Group:   "AppleHDA:57"
    Vendor:  "Apple Inc."
    Type:    output
    State:   enabled
    Ch:      2
    Format:  S16LE S16BE F32LE F32BE (0x3030) (default: F32LE)
    Rate:    44100 - 48000 (default: 44100)
    Latency: lo 21 frames, hi 4103 frames
dev: "AppleHDAEngineInput:1F,3,0,1,0:1" (PREFERRED)
    Name:    "External Microphone"
    Group:   "AppleHDA:57"
    Vendor:  "Apple Inc."
    Type:    input
    State:   enabled
    Ch:      2
    Format:  S16LE S16BE F32LE F32BE (0x3030) (default: F32LE)
    Rate:    44100 - 48000 (default: 44100)
    Latency: lo 21 frames, hi 4103 frames

but your "BuiltInSpeakerDevice" doesn't be replaced even you plug a TRRS

dev: "BuiltInSpeakerDevice" Name: "MacBook Pro Speakers" Group: "Speaker" Vendor: "Apple Inc." Type: output State: enabled Ch: 2 Format: S16LE S16BE F32LE F32BE (0x3030) (default: F32LE) Rate: 44100 - 96000 (default: 48000) Latency: lo 309 frames, hi 4390 frames

Is that true?

It seems we really need to generate a custom group_id for the builtin devices.

padenot commented 4 years ago

but your "BuiltInSpeakerDevice" doesn't be replaced even you plug a TRRS

dev: "BuiltInSpeakerDevice" Name: "MacBook Pro Speakers" Group: "Speaker" Vendor: "Apple Inc." Type: output State: enabled Ch: 2 Format: S16LE S16BE F32LE F32BE (0x3030) (default: F32LE) Rate: 44100 - 96000 (default: 48000) Latency: lo 309 frames, hi 4390 frames

Is that true?

It seems we really need to generate a custom group_id for the builtin devices.

Yes, it switches the default automatically when I plug something in the TRRS socket, but I can manually select the other, and for example have the speakers playing something and the headphones playing something else.

I'll agree we'll have to unfortunately handle everything, and have hard-coded strings, for when we find the case that can be reproduced on my machine.