mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-10-29 05:40:23 -04:00
Add SPDIF/HDMI ALSA devices and device descriptions to device search table
This commit is contained in:
parent
33c22b0102
commit
4d4956ea2f
5 changed files with 189 additions and 78 deletions
|
|
@ -474,33 +474,81 @@ int pa_alsa_set_sw_params(snd_pcm_t *pcm, snd_pcm_uframes_t avail_min) {
|
|||
|
||||
struct device_info {
|
||||
pa_channel_map map;
|
||||
const char *alsa_name;
|
||||
const char *description;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
static const struct device_info device_table[] = {
|
||||
{{ 2, { PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT } }, "front" },
|
||||
{{ 1, { PA_CHANNEL_POSITION_MONO }},
|
||||
"hw",
|
||||
"Analog Mono",
|
||||
"analog-mono" },
|
||||
|
||||
{{ 2, { PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT }},
|
||||
"front",
|
||||
"Analog Stereo",
|
||||
"analog-stereo" },
|
||||
|
||||
{{ 2, { PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT }},
|
||||
"iec958",
|
||||
"IEC958 Digital Stereo",
|
||||
"iec958-stereo" },
|
||||
|
||||
{{ 2, { PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT }},
|
||||
"hdmi",
|
||||
"HDMI Digital Stereo",
|
||||
"hdmi-stereo"},
|
||||
|
||||
{{ 4, { PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
|
||||
PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT }}, "surround40" },
|
||||
PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT }},
|
||||
"surround40",
|
||||
"Analog Surround 4.0",
|
||||
"analog-surround-40" },
|
||||
|
||||
{{ 4, { PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
|
||||
PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT }},
|
||||
"a52",
|
||||
"IEC958/AC3 Digital Surround 4.0",
|
||||
"iec958-ac3-surround-40" },
|
||||
|
||||
{{ 5, { PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
|
||||
PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT,
|
||||
PA_CHANNEL_POSITION_LFE }}, "surround41" },
|
||||
PA_CHANNEL_POSITION_LFE }},
|
||||
"surround41",
|
||||
"Analog Surround 4.1",
|
||||
"analog-surround-41"},
|
||||
|
||||
{{ 5, { PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
|
||||
PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT,
|
||||
PA_CHANNEL_POSITION_CENTER }}, "surround50" },
|
||||
PA_CHANNEL_POSITION_CENTER }},
|
||||
"surround50",
|
||||
"Analog Surround 5.0",
|
||||
"analog-surround-50" },
|
||||
|
||||
{{ 6, { PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
|
||||
PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT,
|
||||
PA_CHANNEL_POSITION_CENTER, PA_CHANNEL_POSITION_LFE }}, "surround51" },
|
||||
PA_CHANNEL_POSITION_CENTER, PA_CHANNEL_POSITION_LFE }},
|
||||
"surround51",
|
||||
"Analog Surround 5.1",
|
||||
"analog-surround-51" },
|
||||
|
||||
{{ 6, { PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_CENTER,
|
||||
PA_CHANNEL_POSITION_FRONT_RIGHT, PA_CHANNEL_POSITION_REAR_LEFT,
|
||||
PA_CHANNEL_POSITION_REAR_RIGHT, PA_CHANNEL_POSITION_LFE}},
|
||||
"a52",
|
||||
"IEC958/AC3 Digital Surround 5.1",
|
||||
"iec958-ac3-surround-51" },
|
||||
|
||||
{{ 8, { PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
|
||||
PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT,
|
||||
PA_CHANNEL_POSITION_CENTER, PA_CHANNEL_POSITION_LFE,
|
||||
PA_CHANNEL_POSITION_SIDE_LEFT, PA_CHANNEL_POSITION_SIDE_RIGHT }} , "surround71" },
|
||||
PA_CHANNEL_POSITION_SIDE_LEFT, PA_CHANNEL_POSITION_SIDE_RIGHT }},
|
||||
"surround71",
|
||||
"Analog Surround 7.1",
|
||||
"analog-surround-71" },
|
||||
|
||||
{{ 0, { 0 }}, NULL }
|
||||
{{ 0, { 0 }}, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
static pa_bool_t channel_map_superset(const pa_channel_map *a, const pa_channel_map *b) {
|
||||
|
|
@ -532,7 +580,9 @@ snd_pcm_t *pa_alsa_open_by_device_id(
|
|||
snd_pcm_uframes_t *period_size,
|
||||
snd_pcm_uframes_t tsched_size,
|
||||
pa_bool_t *use_mmap,
|
||||
pa_bool_t *use_tsched) {
|
||||
pa_bool_t *use_tsched,
|
||||
const char**config_description,
|
||||
const char **config_name) {
|
||||
|
||||
int i;
|
||||
int direction = 1;
|
||||
|
|
@ -554,32 +604,15 @@ snd_pcm_t *pa_alsa_open_by_device_id(
|
|||
* way, we iterate backwards, and check all devices that do not
|
||||
* provide a superset of the requested channel map.*/
|
||||
|
||||
for (i = 0;; i += direction) {
|
||||
i = 0;
|
||||
for (;;) {
|
||||
pa_sample_spec try_ss;
|
||||
pa_bool_t reformat;
|
||||
|
||||
if (i < 0) {
|
||||
pa_assert(direction == -1);
|
||||
if ((direction > 0) == channel_map_superset(&device_table[i].map, map)) {
|
||||
pa_log_debug("Checking for %s (%s)", device_table[i].name, device_table[i].alsa_name);
|
||||
|
||||
/* OK, so we iterated backwards, and now are at the
|
||||
* beginning of our list. */
|
||||
|
||||
break;
|
||||
|
||||
} else if (!device_table[i].name) {
|
||||
pa_assert(direction == 1);
|
||||
|
||||
/* OK, so we are at the end of our list. at iterated
|
||||
* forwards. */
|
||||
|
||||
i--;
|
||||
direction = -1;
|
||||
}
|
||||
|
||||
if ((direction > 0) == !channel_map_superset(&device_table[i].map, map))
|
||||
continue;
|
||||
|
||||
d = pa_sprintf_malloc("%s:%s", device_table[i].name, dev_id);
|
||||
d = pa_sprintf_malloc("%s:%s", device_table[i].alsa_name, dev_id);
|
||||
|
||||
reformat = FALSE;
|
||||
for (;;) {
|
||||
|
|
@ -634,12 +667,61 @@ snd_pcm_t *pa_alsa_open_by_device_id(
|
|||
*map = device_table[i].map;
|
||||
pa_assert(map->channels == ss->channels);
|
||||
*dev = d;
|
||||
if (config_description)
|
||||
*config_description = device_table[i].description;
|
||||
if (config_name)
|
||||
*config_name = device_table[i].name;
|
||||
|
||||
return pcm_handle;
|
||||
}
|
||||
|
||||
pa_xfree(d);
|
||||
}
|
||||
|
||||
if (direction > 0) {
|
||||
if (!device_table[i+1].alsa_name) {
|
||||
/* OK, so we are at the end of our list. Let's turn
|
||||
* back. */
|
||||
direction = -1;
|
||||
} else {
|
||||
/* We are not at the end of the list, so let's simply
|
||||
* try the next entry */
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if (direction < 0) {
|
||||
|
||||
if (device_table[i+1].alsa_name &&
|
||||
device_table[i].map.channels == device_table[i+1].map.channels) {
|
||||
|
||||
/* OK, the next entry has the same number of channels,
|
||||
* let's try it */
|
||||
i++;
|
||||
|
||||
} else {
|
||||
/* Hmm, so the next entry does not have the same
|
||||
* number of channels, so let's go backwards until we
|
||||
* find the next entry with a differnt number of
|
||||
* channels */
|
||||
|
||||
for (i--; i >= 0; i--)
|
||||
if (device_table[i].map.channels != device_table[i+1].map.channels)
|
||||
break;
|
||||
|
||||
/* Hmm, there is no entry with a different number of
|
||||
* entries, then we're done */
|
||||
if (i < 0)
|
||||
break;
|
||||
|
||||
/* OK, now lets find go back as long as we have the same number of channels */
|
||||
for (; i > 0; i--)
|
||||
if (device_table[i].map.channels != device_table[i-1].map.channels)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* OK, we didn't find any good device, so let's try the raw plughw: stuff */
|
||||
|
||||
d = pa_sprintf_malloc("hw:%s", dev_id);
|
||||
|
|
@ -647,6 +729,11 @@ snd_pcm_t *pa_alsa_open_by_device_id(
|
|||
pcm_handle = pa_alsa_open_by_device_string(d, dev, ss, map, mode, nfrags, period_size, tsched_size, use_mmap, use_tsched);
|
||||
pa_xfree(d);
|
||||
|
||||
if (pcm_handle) {
|
||||
*config_description = NULL;
|
||||
*config_name = NULL;
|
||||
}
|
||||
|
||||
return pcm_handle;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -64,7 +64,9 @@ snd_pcm_t *pa_alsa_open_by_device_id(
|
|||
snd_pcm_uframes_t *period_size,
|
||||
snd_pcm_uframes_t tsched_size,
|
||||
pa_bool_t *use_mmap,
|
||||
pa_bool_t *use_tsched);
|
||||
pa_bool_t *use_tsched,
|
||||
const char **config_name,
|
||||
const char **config_description);
|
||||
|
||||
snd_pcm_t *pa_alsa_open_by_device_string(
|
||||
const char *device,
|
||||
|
|
|
|||
|
|
@ -1253,6 +1253,7 @@ int pa__init(pa_module*m) {
|
|||
pa_bool_t use_mmap = TRUE, b, use_tsched = TRUE, d;
|
||||
pa_usec_t usec;
|
||||
pa_sink_new_data data;
|
||||
const char *profile_description = NULL, *profile_name = NULL;
|
||||
|
||||
snd_pcm_info_alloca(&pcm_info);
|
||||
|
||||
|
|
@ -1338,7 +1339,7 @@ int pa__init(pa_module*m) {
|
|||
&ss, &map,
|
||||
SND_PCM_STREAM_PLAYBACK,
|
||||
&nfrags, &period_frames, tsched_frames,
|
||||
&b, &d)))
|
||||
&b, &d, &profile_description, &profile_name)))
|
||||
|
||||
goto fail;
|
||||
|
||||
|
|
@ -1358,6 +1359,9 @@ int pa__init(pa_module*m) {
|
|||
pa_assert(u->device_name);
|
||||
pa_log_info("Successfully opened device %s.", u->device_name);
|
||||
|
||||
if (profile_description)
|
||||
pa_log_info("Selected configuration '%s' (%s).", profile_description, profile_name);
|
||||
|
||||
if (use_mmap && !b) {
|
||||
pa_log_info("Device doesn't support mmap(), falling back to UNIX read/write mode.");
|
||||
u->use_mmap = use_mmap = FALSE;
|
||||
|
|
@ -1441,6 +1445,11 @@ int pa__init(pa_module*m) {
|
|||
pa_proplist_setf(data.proplist, PA_PROP_DEVICE_BUFFERING_FRAGMENT_SIZE, "%lu", (unsigned long) (period_frames * frame_size));
|
||||
pa_proplist_sets(data.proplist, PA_PROP_DEVICE_ACCESS_MODE, u->use_tsched ? "mmap+timer" : (u->use_mmap ? "mmap" : "serial"));
|
||||
|
||||
if (profile_name)
|
||||
pa_proplist_sets(data.proplist, PA_PROP_DEVICE_PROFILE_NAME, profile_name);
|
||||
if (profile_description)
|
||||
pa_proplist_sets(data.proplist, PA_PROP_DEVICE_PROFILE_DESCRIPTION, profile_description);
|
||||
|
||||
u->sink = pa_sink_new(m->core, &data, PA_SINK_HARDWARE|PA_SINK_LATENCY);
|
||||
pa_sink_new_data_done(&data);
|
||||
pa_xfree(name_buf);
|
||||
|
|
|
|||
|
|
@ -1087,6 +1087,7 @@ int pa__init(pa_module*m) {
|
|||
pa_bool_t namereg_fail;
|
||||
pa_bool_t use_mmap = TRUE, b, use_tsched = TRUE, d;
|
||||
pa_source_new_data data;
|
||||
const char *profile_description = NULL, *profile_name = NULL;
|
||||
|
||||
snd_pcm_info_alloca(&pcm_info);
|
||||
|
||||
|
|
@ -1167,7 +1168,7 @@ int pa__init(pa_module*m) {
|
|||
&ss, &map,
|
||||
SND_PCM_STREAM_CAPTURE,
|
||||
&nfrags, &period_frames, tsched_frames,
|
||||
&b, &d)))
|
||||
&b, &d, &profile_description, &profile_name)))
|
||||
goto fail;
|
||||
|
||||
} else {
|
||||
|
|
@ -1185,6 +1186,9 @@ int pa__init(pa_module*m) {
|
|||
pa_assert(u->device_name);
|
||||
pa_log_info("Successfully opened device %s.", u->device_name);
|
||||
|
||||
if (profile_description)
|
||||
pa_log_info("Selected configuration '%s' (%s).", profile_description, profile_name);
|
||||
|
||||
if (use_mmap && !b) {
|
||||
pa_log_info("Device doesn't support mmap(), falling back to UNIX read/write mode.");
|
||||
u->use_mmap = use_mmap = FALSE;
|
||||
|
|
@ -1268,6 +1272,11 @@ int pa__init(pa_module*m) {
|
|||
pa_proplist_setf(data.proplist, PA_PROP_DEVICE_BUFFERING_FRAGMENT_SIZE, "%lu", (unsigned long) (period_frames * frame_size));
|
||||
pa_proplist_sets(data.proplist, PA_PROP_DEVICE_ACCESS_MODE, u->use_tsched ? "mmap+timer" : (u->use_mmap ? "mmap" : "serial"));
|
||||
|
||||
if (profile_name)
|
||||
pa_proplist_sets(data.proplist, PA_PROP_DEVICE_PROFILE_NAME, profile_name);
|
||||
if (profile_description)
|
||||
pa_proplist_sets(data.proplist, PA_PROP_DEVICE_PROFILE_DESCRIPTION, profile_description);
|
||||
|
||||
u->source = pa_source_new(m->core, &data, PA_SOURCE_HARDWARE|PA_SOURCE_LATENCY);
|
||||
pa_source_new_data_done(&data);
|
||||
pa_xfree(name_buf);
|
||||
|
|
|
|||
|
|
@ -75,8 +75,10 @@ PA_C_DECL_BEGIN
|
|||
* device.connector isa, pci, usb, firewire, bluetooth
|
||||
* device.access_mode mmap, mmap_rewrite, serial
|
||||
* device.master_device
|
||||
* device.bufferin.buffer_size
|
||||
* device.bufferin.fragment_size
|
||||
* device.buffering.buffer_size
|
||||
* device.buffering.fragment_size
|
||||
* device.profile.name analog-stereo, analog-surround-40, iec958-stereo, ...
|
||||
* device.profile.description "Analog Stereo", ...
|
||||
*/
|
||||
#define PA_PROP_MEDIA_NAME "media.name"
|
||||
#define PA_PROP_MEDIA_TITLE "media.title"
|
||||
|
|
@ -124,6 +126,8 @@ PA_C_DECL_BEGIN
|
|||
#define PA_PROP_DEVICE_MASTER_DEVICE "device.master_device"
|
||||
#define PA_PROP_DEVICE_BUFFERING_BUFFER_SIZE "device.buffering.buffer_size"
|
||||
#define PA_PROP_DEVICE_BUFFERING_FRAGMENT_SIZE "device.buffering.fragment_size"
|
||||
#define PA_PROP_DEVICE_PROFILE_NAME "device.profile.name"
|
||||
#define PA_PROP_DEVICE_PROFILE_DESCRIPTION "device.profile.description"
|
||||
|
||||
/** A property list object. Basically a dictionary with UTF-8 strings
|
||||
* as keys and arbitrary data as values. \since 0.9.11 */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue