Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.
Sign upAdd Audio support #265
Conversation
Xaeroxe
requested a review
from amethyst/engine-devs
Jul 23, 2017
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Xaeroxe
Jul 23, 2017
Member
Linux developers: the libasound2-dev package will be required to compile amethyst once this package is merged, rodio interfaces with alsa which makes this necessary.
|
Linux developers: the libasound2-dev package will be required to compile amethyst once this package is merged, rodio interfaces with alsa which makes this necessary. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
vitvakatu
Jul 23, 2017
Contributor
Linux developers: the libasound2-dev package will be required to compile amethyst once this package is merged, rodio interfaces with alsa which makes this necessary.
Add information about it in readme, please
Add information about it in readme, please |
| ticketed_lock = "0.1" | ||
| wavefront_obj = "5.0" | ||
| thread_profiler = { version = "0.1", optional = true } | ||
| +[dev_dependencies] |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Xaeroxe
Jul 24, 2017
Member
I guess it is. Woops. For some reason it still worked when I added this but I'll fix it.
Xaeroxe
Jul 24, 2017
Member
I guess it is. Woops. For some reason it still worked when I added this but I'll fix it.
| +use rodio::*; | ||
| + | ||
| +/// A speaker(s) through which audio can be played. | ||
| +pub struct Endpoint { |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Xaeroxe
Jul 24, 2017
Member
Mostly just making it so users of the API don't also have to depend on rodio.
Xaeroxe
Jul 24, 2017
Member
Mostly just making it so users of the API don't also have to depend on rodio.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
torkleyy
Jul 24, 2017
Member
Could we give it another name? I think something like Output or OutputDevice is probably clearer to people who didn't deal with cpal stuff before.
torkleyy
Jul 24, 2017
Member
Could we give it another name? I think something like Output or OutputDevice is probably clearer to people who didn't deal with cpal stuff before.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
| +/// Provides structures used to load audio files. | ||
| +pub mod source; | ||
| + | ||
| +/// Provides functions used to play audio. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This was referenced Jul 24, 2017
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
ebkalderon
Jul 27, 2017
Member
@Xaeroxe Will this pull request eventually include an AudioSystem and components for audio listeners and emitters?
|
@Xaeroxe Will this pull request eventually include an |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Xaeroxe
Jul 27, 2017
Member
@ebkalderon Yes it will, I'm not going to be able to work on this for a few days as my life is a little busy recently but I'll get back to this PR as soon as I can
|
@ebkalderon Yes it will, I'm not going to be able to work on this for a few days as my life is a little busy recently but I'll get back to this PR as soon as I can |
| +} | ||
| + | ||
| +/// Loads audio from wav files. | ||
| +pub struct WavFormat; |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
torkleyy
Jul 27, 2017
Member
Could we have a module assets which reexports * from amethyst_assets and add the amethyst-specific functionality in there similar to how we do it with amethyst::ecs?
So like
// src/assets/mod.rs
use amethyst_assets::*;
pub mod formats;and then keep the formats in the formats module.
torkleyy
Jul 27, 2017
Member
Could we have a module assets which reexports * from amethyst_assets and add the amethyst-specific functionality in there similar to how we do it with amethyst::ecs?
So like
// src/assets/mod.rs
use amethyst_assets::*;
pub mod formats;and then keep the formats in the formats module.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
torkleyy
Jul 27, 2017
Member
But I'm also not sure whether or not formats should belong to amethyst_assets.
torkleyy
Jul 27, 2017
Member
But I'm also not sure whether or not formats should belong to amethyst_assets.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Xaeroxe
Aug 2, 2017
Member
@torkleyy I'd prefer to keep the formats in Amethyst. I also like your first proposal, @ebkalderon Does this sound good to you? Bunching up all asset formats into assets::formats would help with asset type discoverability.
Xaeroxe
Aug 2, 2017
Member
@torkleyy I'd prefer to keep the formats in Amethyst. I also like your first proposal, @ebkalderon Does this sound good to you? Bunching up all asset formats into assets::formats would help with asset type discoverability.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
alteous
Aug 3, 2017
It may be worth dropping the Format suffix if all the format types are put into one module.
alteous
Aug 3, 2017
It may be worth dropping the Format suffix if all the format types are put into one module.
torkleyy
added
the
project: audio
label
Aug 6, 2017
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
I think this PR is worth a line in the |
torkleyy
added
status: working
type: feature
labels
Aug 7, 2017
| @@ -10,12 +10,14 @@ The format is based on [Keep a Changelog][kc], and this project adheres to | ||
| ## [Unreleased] | ||
| ### Changed | ||
| * Asset management rewrite (pull request [#244]). | ||
| +* Add audio support ([#265]) |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
| @@ -0,0 +1,10 @@ | ||
| +# --- |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
| + | ||
| +pub use amethyst_assets::*; | ||
| + | ||
| +pub mod formats; |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
| + | ||
| +/// A context for loading audio files | ||
| +pub struct AudioContext { | ||
| + inner: SimpleContext<Source, Vec<u8>, NoError, fn(Vec<u8>) -> Result<Source, NoError>>, |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
torkleyy
Aug 15, 2017
Member
Not sure about that dynamic dispatch here..I think we should replace that. Pretty sure a change in amethyst_assets is required.
torkleyy
Aug 15, 2017
Member
Not sure about that dynamic dispatch here..I think we should replace that. Pretty sure a change in amethyst_assets is required.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Xaeroxe
Aug 15, 2017
Member
@torkleyy Just to clarify: Dynamic dispatch usually refers to a vtable lookup occurring, this doesn't involve a vtable lookup though, it just uses a hard coded function pointer so this isn't really that expensive.
Xaeroxe
Aug 15, 2017
Member
@torkleyy Just to clarify: Dynamic dispatch usually refers to a vtable lookup occurring, this doesn't involve a vtable lookup though, it just uses a hard coded function pointer so this isn't really that expensive.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
torkleyy
Aug 15, 2017
Member
Oh yeah sorry, I'm pretty inaccurate about that. The problem with a runtime function pointer is that inlining isn't possible. And it is a bit ugly in a type signature IMO.
torkleyy
Aug 15, 2017
Member
Oh yeah sorry, I'm pretty inaccurate about that. The problem with a runtime function pointer is that inlining isn't possible. And it is a bit ugly in a type signature IMO.
| +mod audio_context; | ||
| +mod source; | ||
| + | ||
| +pub use self::audio_context::AudioContext; |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
torkleyy
Aug 15, 2017
Member
I guess we don't need such a deep hierarchy. I would move source and context into this file, actually.
torkleyy
Aug 15, 2017
Member
I guess we don't need such a deep hierarchy. I would move source and context into this file, actually.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Xaeroxe
Aug 15, 2017
Member
I like to keep my mod files as clean as possible, make them only describe the hierarchy and exports. Makes the code a little easier to read in my opinion. What do you think of that?
Xaeroxe
Aug 15, 2017
Member
I like to keep my mod files as clean as possible, make them only describe the hierarchy and exports. Makes the code a little easier to read in my opinion. What do you think of that?
| + | ||
| +/// Get a list of outputs available to the system. | ||
| +pub fn outputs() -> Vec<Output> { | ||
| + get_endpoints_list().map(|re| Output {endpoint: re}).collect::<Vec<Output>>() |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Xaeroxe
Aug 15, 2017
Member
I guess it isn't. (I'm really looking forward to impl Trait so that I can have efficient interfaces that aren't a pain to write)
Xaeroxe
Aug 15, 2017
Member
I guess it isn't. (I'm really looking forward to impl Trait so that I can have efficient interfaces that aren't a pain to write)
| + /// See documentation for DecoderError here: | ||
| + /// https://docs.rs/rodio/0.5.1/rodio/decoder/enum.DecoderError.html | ||
| + Err(_) => { | ||
| + Err(()) |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
torkleyy
Aug 15, 2017
Member
Not () Box<Error> or similar cases. A unit type DecoderError is much more descriptive here.
torkleyy
Aug 15, 2017
Member
Not () Box<Error> or similar cases. A unit type DecoderError is much more descriptive here.
| +/// An audio listener, add this component to the local player character. | ||
| +pub struct AudioListener { | ||
| + /// Position of the left_ear in the world. | ||
| + pub left_ear: [f32; 3], |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
| +} | ||
| + | ||
| +impl Component for AudioListener { | ||
| + type Storage = VecStorage<Self>; |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
torkleyy
Aug 16, 2017
Member
As far as I see it, there is only one AudioListener, so VecStorage is not very efficient here.
torkleyy
Aug 16, 2017
Member
As far as I see it, there is only one AudioListener, so VecStorage is not very efficient here.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Xaeroxe
Aug 16, 2017
Member
Alright, I'll check out the other storage types and see if I can find a better one.
Xaeroxe
Aug 16, 2017
Member
Alright, I'll check out the other storage types and see if I can find a better one.
| + } | ||
| + | ||
| + /// Adds an audio source to the queue of sounds to be played from this emitter. | ||
| + pub fn append(&self, source: &Source) { |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
torkleyy
Aug 16, 2017
Member
Shouldn't a source also allow playing multiple sounds at once? If that's already the case, I would ask you to improve naming or docs.
torkleyy
Aug 16, 2017
Member
Shouldn't a source also allow playing multiple sounds at once? If that's already the case, I would ask you to improve naming or docs.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Xaeroxe
Aug 16, 2017
Member
Current architecture doesn't permit multiple sounds at once, but it probably should. I'll think about ways to accomplish this.
Xaeroxe
Aug 16, 2017
Member
Current architecture doesn't permit multiple sounds at once, but it probably should. I'll think about ways to accomplish this.
| + let z = transform.0[3][2]; | ||
| + let emitter_position = [x, y, z]; | ||
| + // Remove all sinks whose sounds have ended. | ||
| + for i in 0..audio_emitter.sinks.len() { |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Xaeroxe
Aug 17, 2017
Member
This is broken and will cause panics. I was trying to emulate the retain functionality here since that doesn't exist on SmallVec. I've opened a PR to add retain to SmallVec here
Xaeroxe
Aug 17, 2017
Member
This is broken and will cause panics. I was trying to emulate the retain functionality here since that doesn't exist on SmallVec. I've opened a PR to add retain to SmallVec here
| @@ -1,27 +1,35 @@ | ||
| //! Provides structures and functions used to get audio outputs. | ||
| +// We have to use types from this to provide an output iterator type. | ||
| +extern crate cpal; |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
| +//! Provides structures and functions used to get audio outputs. | ||
| + | ||
| +// We have to use types from this to provide an output iterator type. | ||
| +extern crate cpal; |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
torkleyy
Aug 17, 2017
Member
Somehow my comment was marked as outdated... Could you please move this declaration to src/lib.rs?
torkleyy
Aug 17, 2017
Member
Somehow my comment was marked as outdated... Could you please move this declaration to src/lib.rs?
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Xaeroxe
Aug 17, 2017
Member
I was reluctant to add a dependency on this crate at all, but it was necessary to write the OutputIterator type, as soon as impl Trait is stabilized I'd like to remove this dependency, so I chose to limit the scope of it. Do you feel my decision making process here was sound?
Xaeroxe
Aug 17, 2017
Member
I was reluctant to add a dependency on this crate at all, but it was necessary to write the OutputIterator type, as soon as impl Trait is stabilized I'd like to remove this dependency, so I chose to limit the scope of it. Do you feel my decision making process here was sound?
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
| +} | ||
| + | ||
| +/// An iterator over outputs | ||
| +pub type OutputIterator = Map<EndpointsIterator, fn(Endpoint) -> Output>; |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
torkleyy
Aug 17, 2017
Member
Could you just create a struct which owns EndpointIterator and map it in the next method? Would probably be more efficient.
torkleyy
Aug 17, 2017
Member
Could you just create a struct which owns EndpointIterator and map it in the next method? Would probably be more efficient.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
| +/// Play a sound once. | ||
| +/// | ||
| +/// This will return an Error if the loaded audio file in source could not be decoded. | ||
| +pub fn once(source: &Source, endpoint: &Output) -> Result<(), DecoderError> { |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
torkleyy
Aug 19, 2017
Member
Calling this function from ECS is a bit ugly, since you got two unwraps above and the default ouptut has to be retrieved every time. Not sure, but I don't think a game should really crash / exit even if such a thing failed. Especially during development, it's enough to see an error in the console IMO.
torkleyy
Aug 19, 2017
Member
Calling this function from ECS is a bit ugly, since you got two unwraps above and the default ouptut has to be retrieved every time. Not sure, but I don't think a game should really crash / exit even if such a thing failed. Especially during development, it's enough to see an error in the console IMO.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Xaeroxe
Aug 19, 2017
Member
I fixed how the pong example was handling this, can you take a look at it and tell me what you think?
Xaeroxe
Aug 19, 2017
Member
I fixed how the pong example was handling this, can you take a look at it and tell me what you think?
| + | ||
| +impl Output { | ||
| + /// Gets the name of the output | ||
| + pub fn get_name(&self) -> String { |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
torkleyy
Aug 19, 2017
Member
Sorry about me nitpicking, but getters shouldn't have a get_ unless necessary.
torkleyy
Aug 19, 2017
Member
Sorry about me nitpicking, but getters shouldn't have a get_ unless necessary.
| } | ||
| // Check if the ball is above the bottom boundary, if it is not deflect it | ||
| if ball.position[1] - ball.size / 2. < bottom_bound { | ||
| ball.position[1] = bottom_bound + ball.size / 2.; | ||
| ball.velocity[1] = -ball.velocity[1]; | ||
| + play::once(&self.bounce_sfx, &output::default_output().unwrap()).unwrap(); |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
torkleyy
Aug 19, 2017
Member
Do we really need this 6 times? Probably we can improve that once we got proper collision detection added.
torkleyy
Aug 19, 2017
Member
Do we really need this 6 times? Probably we can improve that once we got proper collision detection added.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Xaeroxe
Aug 19, 2017
Member
Yeah I was just working in the existing framework of the pong example :P I'm happy to refactor this to use a physics system as soon as we have it.
Xaeroxe
Aug 19, 2017
Member
Yeah I was just working in the existing framework of the pong example :P I'm happy to refactor this to use a physics system as soon as we have it.
| +} | ||
| + | ||
| +impl Component for AudioEmitter { | ||
| + type Storage = VecStorage<Self>; |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
| +use ecs::{Component, HashMapStorage}; | ||
| + | ||
| +/// An audio listener, add this component to the local player character. | ||
| +pub struct AudioListener { |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
| + ReadStorage<'a, AudioListener>, | ||
| + WriteStorage<'a, AudioEmitter>); | ||
| + | ||
| + fn run(&mut self, (transform, listener, mut audio_emitter): Self::SystemData) { |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
torkleyy
Aug 19, 2017
Member
Looks amazing, especially because it uses Transform now! Have to look at this code later.
torkleyy
Aug 19, 2017
Member
Looks amazing, especially because it uses Transform now! Have to look at this code later.
| + | ||
| +/// An error occurred while decoding the source. | ||
| +#[derive(Debug)] | ||
| +pub struct DecoderError; |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
torkleyy
Aug 19, 2017
Member
I think it is better than before, but the function should probably part of the library and I'm not sure if we should get the default output every frame. Do you know how expensive that is?
|
I think it is better than before, but the function should probably part of the library and I'm not sure if we should get the default output every frame. Do you know how expensive that is? |
Xaeroxe
self-assigned this
Aug 25, 2017
Xaeroxe
changed the base branch from
develop
to
renderer
Aug 25, 2017
Xaeroxe
changed the base branch from
renderer
to
develop
Aug 25, 2017
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Xaeroxe
Aug 26, 2017
Member
Documentation generated on this branch: https://xaeroxe.github.io/amethyst/doc/amethyst/index.html
|
Documentation generated on this branch: https://xaeroxe.github.io/amethyst/doc/amethyst/index.html |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
torkleyy
Aug 27, 2017
Member
It's really hard to review this given you merged all the commits of renderer into this branch.
|
It's really hard to review this given you merged all the commits of |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Xaeroxe
Aug 27, 2017
Member
I know :/ I wasn't expecting anyone to review this until renderer was merged. Which by the way while I have your attention, is there any reason for us to not merge renderer yet? Everything seems to be up to speed on that branch after @omni-viral 's PR is merged.
|
I know :/ I wasn't expecting anyone to review this until renderer was merged. Which by the way while I have your attention, is there any reason for us to not merge renderer yet? Everything seems to be up to speed on that branch after @omni-viral 's PR is merged. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
Well, let's do this :) |
| pub use self::rendering::RenderSystem; | ||
| pub use self::transform::TransformSystem; | ||
| // use config::Config; | ||
| use error::Result; | ||
| use ecs::{System, World}; | ||
| -mod rendering; |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
torkleyy
Aug 27, 2017
Member
Actually, the standard seems to be to put use before mod, although I did it the other way around before I read about it.
torkleyy
Aug 27, 2017
Member
Actually, the standard seems to be to put use before mod, although I did it the other way around before I read about it.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
torkleyy
Aug 27, 2017
Member
Oh and could you please try to not create any merge commits in PRs? It is pretty confusing when you're looking at the commit log.
|
Oh and could you please try to not create any merge commits in PRs? It is pretty confusing when you're looking at the commit log. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Xaeroxe
Aug 27, 2017
Member
The two commit histories are so intertwined at this point it's basically impossible to rebase, hence the merge commits.
|
The two commit histories are so intertwined at this point it's basically impossible to rebase, hence the merge commits. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
torkleyy
Aug 27, 2017
Member
Guess we could also just sqash this into three commits: low level, ecs stuff and example.
|
Guess we could also just sqash this into three commits: low level, ecs stuff and example. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Xaeroxe
Aug 27, 2017
Member
I am trying and failing. These two could probably be made to work together without merges but it would involve a lot of manual labor during which I'd probably make a few mistakes and break something.
|
I am trying and failing. These two could probably be made to work together without merges but it would involve a lot of manual labor during which I'd probably make a few mistakes and break something. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
I can do it if you want. Shouldn't be hard thanks to |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
By all means go ahead |
Xaeroxe
added some commits
Aug 27, 2017
Xaeroxe
changed the title from
[WIP] Add Audio support
to
Add Audio support
Aug 27, 2017
Xaeroxe
removed
the
status: working
label
Aug 27, 2017
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Xaeroxe
Aug 27, 2017
Member
Ready to merge as far as I'm concerned. Thanks @torkleyy for your help straightening out the commit history.
|
Ready to merge as far as I'm concerned. Thanks @torkleyy for your help straightening out the commit history. |
Xaeroxe commentedJul 23, 2017
•
edited
Edited 1 time
-
Xaeroxe
edited Aug 27, 2017 (most recent)
Things done in this PR: