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

Update mixer example to run sound effect in addition to music #666

Merged
merged 5 commits into from
May 28, 2017
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 34 additions & 11 deletions examples/mixer_demo.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
/// Demonstrates the simultaneous mixing of music and sound effects.

extern crate sdl2;

use std::env;
use std::path::Path;
use sdl2::mixer::{INIT_MP3, INIT_FLAC, INIT_MOD, INIT_FLUIDSYNTH, INIT_MODPLUG, INIT_OGG,
AUDIO_S16LSB};
use sdl2::mixer::{DEFAULT_CHANNELS, INIT_MP3, INIT_FLAC, INIT_MOD, INIT_FLUIDSYNTH, INIT_MODPLUG,
INIT_OGG, AUDIO_S16LSB};

fn main() {

let args: Vec<_> = env::args().collect();

if args.len() < 2 {
println!("Usage: ./demo audio.[mp3|wav|ogg]")
if args.len() == 2 {
demo(Path::new(&args[1]), Path::new(""));
} else if args.len() == 3 {
Copy link
Member

@Cobrand Cobrand May 28, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a pretty un-rusty way to do this, in Rust we have nice things like options instead of empty strings, so let's use these instead! Make demo have this signature: demo(music_path: &Path, sound_path: Option<&Path>), and just pass args.get(2) to actually have an Option<&Path>. That effectively means merging the branches args.len() == 2 and args.len() == 3 as one here.

In demo, if the option is None, don't output anything. If it's Some(path) but the path is wrong, output an error, and if it's a correct sound file, just output the same thing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trying to use .get(2) directly as the input seems to not work since we need to re-wrap into a new Option<T>.

25 |         demo(Path::new(&args[1]), args.get(2));
   |                                   ^^^^^^^^^^^ expected struct `std::path::Path`, found struct `std::string::String`
   |
   = note: expected type `std::option::Option<&std::path::Path>`
              found type `std::option::Option<&std::string::String>`

Let me know if there is a more idiomatic way to do this than what I did, which was to de-structure and re-structure.

demo(Path::new(&args[1]), Path::new(&args[2]));
} else {
demo(Path::new(&args[1]));
println!("Usage: ./demo music.[mp3|wav|ogg] [sound-effect.[mp3|wav|ogg]]")
}
}

fn demo(filename: &Path) {
fn demo(music_file: &Path, sound_file: &Path) {

println!("linked version: {}", sdl2::mixer::get_linked_version());

Expand All @@ -30,10 +34,13 @@ fn demo(filename: &Path) {

let frequency = 44100;
let format = AUDIO_S16LSB; // signed 16 bit samples, in little-endian byte order
let channels = 2; // Stereo
let channels = DEFAULT_CHANNELS; // Stereo
let chunk_size = 1024;
sdl2::mixer::open_audio(frequency, format, channels, chunk_size).unwrap();
sdl2::mixer::allocate_channels(0);

// Number of mixing channels available for sound effect `Chunk`s to play
// simultaneously.
sdl2::mixer::allocate_channels(4);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this mean that you can play 4 sound effects + the usual music with that? Is that why iy wouldn't work with sdl2::mixer::allocate_channel(0)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, exactly. If you allocate_channel(0) you cannot play sound effects.

See: https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer_26.html

Set the number of channels being mixed. This can be called multiple times, even with sounds playing. If numchans is less than the current number of channels, then the higher channels will be stopped, freed, and therefore not mixed any longer. It's probably not a good idea to change the size 1000 times a second though.
If any channels are deallocated, any callback set by Mix_ChannelFinished will be called when each channel is halted to be freed. Note: passing in zero WILL free all mixing channels, however music will still play.

The rust-sdl2 docs for that function should probably be updated.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, it should probably be updated, but I intended to rewrite it completely, and add tons of meaningful comments with it as well (#646). But in the meantime a small comment about what this does would be much needed indeed.


{
let n = sdl2::mixer::get_chunk_decoders_number();
Expand All @@ -53,8 +60,7 @@ fn demo(filename: &Path) {

println!("query spec => {:?}", sdl2::mixer::query_spec());


let music = sdl2::mixer::Music::from_file(filename).unwrap();
let music = sdl2::mixer::Music::from_file(music_file).unwrap();

fn hook_finished() {
println!("play ends! from rust cb");
Expand All @@ -67,6 +73,24 @@ fn demo(filename: &Path) {
println!("music volume => {:?}", sdl2::mixer::Music::get_volume());
println!("play => {:?}", music.play(1));

let sound_chunk_res = sdl2::mixer::Chunk::from_file(sound_file);

match sound_chunk_res {
Ok(sound_chunk) => {
println!("chunk volume => {:?}", sound_chunk.get_volume());
println!("playing sound twice");
let play_res = sdl2::mixer::Channel::all().play(&sound_chunk, 1);

timer.delay(5000);

match play_res {
Ok(_) => { println!("played sound")},
Err(e) => { println!("{:?}", e) },
}
}
Err(e) => { println!("Cannot load sound file: {:?}", e) },
}

timer.delay(10000);

println!("fading out ... {:?}", sdl2::mixer::Music::fade_out(4000));
Expand All @@ -80,6 +104,5 @@ fn demo(filename: &Path) {
sdl2::mixer::Music::halt();
timer.delay(1000);


println!("quitting sdl");
}