Skip to content

SupportedConfig searcher #1304

Description

@Marco-Farruggio

I've seen an issue on this, and also I've noticed its in the design goals for 0.19 (Edit: What I'm referencing here is the try_with_buffer_size), I just had a few ideas id like to note down:

(Edit: The reason of creating this issue was because when I started out with cpal a few months ago I found the whole SupportedStreamConfigRange -> SupportedStreamConfig -> StreamConfig a bit confusing, but if you're happy with the current architecture, by all means close this, i just thought it was a good way to incorporate the buffer size issue too)

I was thinking of a preference-based sorting system, ordered by importance, e.g. you could request 2 channels, and 48khz, but give 2channels a higher priority, so it would find a config with 2 channels and 44.1khz rather than 1 channel 48khz,

this could be done with some sort of ordering heuristic value, like a u8, but I think that sort of escapes cpal's low level, low abstraction feeling, so maybe make it a standalone function which took many configs, but what came to mind first was a single unified SupportedConfigSearcher, (or a name to a similar meaning). or even just a .search method on SupportedOutputConfigs, here's an example of which:

let search: SupprtedConfigSearch = SupportedConfigSearch::new()
    .channels(2)
    .sample_format(SampleFormat::F32)
    .sample_rate(SAMPLE_RATE_48K)
    .buffer_size(BufferSize::Fixed(1024))

let config = device.supported_output_configs().unwrap().search(search)

(search could either return an Option<the config>, or an Option<list of configs>, depending on whether or not search would take into account the searching criteria, and THEN maximise for the best one, so as only onc was found, or return all of them, in some way or other)

Searching could either be strict (more like filtering) or more preference-based. I think preference based makes more sense, obviously both could be included or some complex design could be made, I think a decent idea is something like this:

let search: SupprtedConfigSearch = SupportedConfigSearch::new()
    .channels(2)
    .sample_format(SampleFormat::F32)
    .sample_format(SampleFormat::U8)
    .sample_rate(SAMPLE_RATE_48K)

(Prefering U8 here is silly, I just used it for sake of example)

here it would prefer F32 over U8 (some internal constructer would get incremented at every new .[some search] called to it.

(Just one final note because I realise this is getting very long, maybe there could be SupportedConfigSearch::strict(), and ::prefer, rather than splitting it into 2 different searchers, I just think keeping everything together is a lot nice)

Oh and also I'd be more than happy to open a rough pr for this too :)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions