Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exposing the output device stream directly. #30

Closed
mitchmindtree opened this issue Mar 2, 2015 · 5 comments
Closed

Exposing the output device stream directly. #30

mitchmindtree opened this issue Mar 2, 2015 · 5 comments

Comments

@mitchmindtree
Copy link
Member

At the moment the way CPAL interfaces with the audio stream is via .append_data. .append_data takes channels, sample rate and maximum buffer size as arguments while allowing the user to use any sample format they wish. This is a useful, high-level approach, allowing the user to not worry about the underlying stream format if they don't want to and also allowing a dynamic stream format.

This can however require a conversion to take place between the stream format given and the output device's current stream format every time a buffer is requested (if any part of either stream format differs, that is). It is not immediately obvious that this conversion takes place or is even necessary from a user's perspective.

CPAL does not currently offer direct access to the pure device stream. Perhaps before exposing the sort of dynamic interface that is currently implemented, it could be a good idea to first provide the pure audio device stream itself. As CPAL aims to be a cross-platform audio library, it could be beneficial to first provide the direct stream for users who wish to gain as low-level access as possible before providing the dynamic abstraction on top.

I think there are a couple ways we could do this - the following is the most satisfying I could think of:

We could change append_data to provide direct access to the device's stream.

let mut buffer = voice.append_data();
buffer.fill(|samples: &mut[u16], num_channels: usize, sample_rate: u32| {
    // fill samples
});

The dynamic stream format style that is currently in use could then be implemented on top of this:

let mut buffer = voice.append_data().custom(channels, sample_rate, max_elements);
// fill buffer

@tomaka what are your thoughts? I'd be happy to implement this.

@tomaka
Copy link
Collaborator

tomaka commented Mar 2, 2015

For the moment the user can retreive the format that is expected by the backend with the methods on the Voice.

If you call append_data and match this format, it is optimized to directly fill what the backend returns: https://github.com/tomaka/cpal/blob/master/src/lib.rs#L189-229
(the code is if needs_conversion { return TemporaryBufferWithConversionInfos } else { return BackendBuffer })

Is that a bad system?

@mitchmindtree
Copy link
Member Author

No I think that code is great!

My only issue with this is that it's not immediately obvious to the reader of the client code that using a custom format will be more expensive than the device's format.

If we add an explicit custom method then perhaps it could be more clear that there is extra computation going on than there would be if they were to just use the device's format. The device format would simply be default (encouraging the user to use the more performant option, instead of the users having to call Voice's methods to get the default settings to then pass to append_data.

So

let mut buffer = voice.append_data(channels, sample_rate, max_elements);

could become

let mut buffer = voice.append_data().custom(channels, sample_rate, max_elements);

?

@tomaka
Copy link
Collaborator

tomaka commented Mar 2, 2015

What about voice.append_raw_data() and voice.append_custom_data() instead?

@mitchmindtree
Copy link
Member Author

Yeah that sounds good 👍

@tomaka
Copy link
Collaborator

tomaka commented Sep 22, 2015

No longer relevant with the new design.

@tomaka tomaka closed this as completed Sep 22, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants