diff options
| author | Heitor Carvalho <[email protected]> | 2018-10-24 18:10:17 -0300 |
|---|---|---|
| committer | Tom Black <[email protected]> | 2018-10-24 14:10:16 -0700 |
| commit | 830d99fde4555263967dfee94b4095ee300c12e1 (patch) | |
| tree | 8360ba4b8bc60a45fd50c484f4de39dee13246cd | |
| parent | 1b646f82c67e7c38df08113bcc3323c7aaf4639f (diff) | |
| download | ruby2d-830d99fde4555263967dfee94b4095ee300c12e1.tar.gz ruby2d-830d99fde4555263967dfee94b4095ee300c12e1.zip | |
Implements volume control to Music (#123)
| -rw-r--r-- | ext/ruby2d/ruby2d.c | 20 | ||||
| -rw-r--r-- | lib/ruby2d/music.rb | 16 | ||||
| -rw-r--r-- | test/audio.rb | 25 | ||||
| -rw-r--r-- | test/music_spec.rb | 27 |
4 files changed, 81 insertions, 7 deletions
diff --git a/ext/ruby2d/ruby2d.c b/ext/ruby2d/ruby2d.c index 885bf5c..03caf3d 100644 --- a/ext/ruby2d/ruby2d.c +++ b/ext/ruby2d/ruby2d.c @@ -65,6 +65,7 @@ #define r_define_module(name) mrb_define_module(mrb, name) #define r_define_class(module, name) mrb_define_class_under(mrb, module, name, mrb->object_class) #define r_define_method(class, name, function, args) mrb_define_method(mrb, class, name, function, args) + #define r_define_class_method(class, name, function, args) mrb_define_class_method(mrb, class, name, function, args) #define r_args_none (MRB_ARGS_NONE()) #define r_args_req(n) MRB_ARGS_REQ(n) // Helpers @@ -87,6 +88,7 @@ #define r_define_module(name) rb_define_module(name) #define r_define_class(module, name) rb_define_class_under(module, name, rb_cObject) #define r_define_method(class, name, function, args) rb_define_method(class, name, function, args) + #define r_define_class_method(class, name, function, args) rb_define_singleton_method(class, name, function, args) #define r_args_none 0 #define r_args_req(n) n // Helpers @@ -670,6 +672,21 @@ static R_VAL ruby2d_music_ext_stop(R_VAL self) { /* + * Ruby2D::Music#ext_volume + */ +#if MRUBY +static R_VAL ruby2d_music_ext_volume(mrb_state* mrb, R_VAL self) { + mrb_value vol; + mrb_get_args(mrb, "o", &vol); +#else +static R_VAL ruby2d_music_ext_volume(R_VAL self, R_VAL vol) { +#endif + int mix_vol = NUM2INT(vol) == -1 ? -1 : MIX_MAX_VOLUME * NUM2INT(vol) / 100.0; + return INT2NUM(ceil(Mix_VolumeMusic(mix_vol) * 100.0 / MIX_MAX_VOLUME)); +} + + +/* * Ruby2D::Music#ext_fadeout */ #if MRUBY @@ -1133,6 +1150,9 @@ void Init_ruby2d() { // Ruby2D::Music#ext_stop r_define_method(ruby2d_music_class, "ext_stop", ruby2d_music_ext_stop, r_args_none); + // Ruby2D::Music#self.ext_volume + r_define_class_method(ruby2d_music_class, "ext_volume", ruby2d_music_ext_volume, r_args_req(1)); + // Ruby2D::Music#ext_fadeout r_define_method(ruby2d_music_class, "ext_fadeout", ruby2d_music_ext_fadeout, r_args_req(1)); diff --git a/lib/ruby2d/music.rb b/lib/ruby2d/music.rb index 41b8901..5974a8a 100644 --- a/lib/ruby2d/music.rb +++ b/lib/ruby2d/music.rb @@ -39,6 +39,22 @@ module Ruby2D ext_stop end + # Returns the previous volume setting, in percentage + def self.volume + self.ext_volume(-1) + end + + # Set music volume, 0 to 100% + def self.volume=(v) + # If a negative value, volume will be 0 + if v < 0 then v = 0 end + self.ext_volume(v) + end + + # Alias instance methods to class methods + def volume; Music.volume end + def volume=(v); Music.volume=(v) end + # Fade out music over provided milliseconds def fadeout(ms) ext_fadeout(ms) diff --git a/test/audio.rb b/test/audio.rb index 7d39569..8a0e8f6 100644 --- a/test/audio.rb +++ b/test/audio.rb @@ -11,28 +11,39 @@ set width: 300, height: 200, title: "Ruby 2D — Audio" snd = Sound.new("#{media}/sound.wav") mus = Music.new("#{media}/music.wav") +volume_bar = Rectangle.new(color: 'green', width: 300, height: 50) + +on :mouse_down do |event| + Music.volume = event.x / Window.width.to_f * 100 + volume_bar.width = Music.volume / 100.0 * Window.width + puts "Music volume: #{Music.volume}%" +end + on :key_down do |event| case event.key when 'p' - puts "Playing sound..." + puts "Playing sound" snd.play when 'm' - puts "Playing music..." + puts "Playing music" mus.play + mus.volume = 100 + volume_bar.width = Window.width + puts "Music volume: #{mus.volume}" when 'l' - puts "Loop music true..." + puts "Looping music" mus.loop = true when 'a' - puts "Pause music..." + puts "Music paused" mus.pause when 'r' - puts "Resume music..." + puts "Music resumed" mus.resume when 's' - puts "Stop music..." + puts "Music stopped" mus.stop when 'f' - puts "fade out music..." + puts "Music fading out" mus.fadeout 2000 when 'escape' close diff --git a/test/music_spec.rb b/test/music_spec.rb index c3a1173..09b6f1c 100644 --- a/test/music_spec.rb +++ b/test/music_spec.rb @@ -6,6 +6,33 @@ RSpec.describe Ruby2D::Music do it "raises exception if audio file doesn't exist" do expect { Music.new("bad_music.mp3") }.to raise_error(Ruby2D::Error) end + + it "creates new music" do + Music.new("test/media/music.mp3") + end + end + + describe "#volume" do + it "sets the volume on music instances" do + mus = Music.new("test/media/music.mp3") + expect(mus.volume).to eq(100) + mus.volume = 68 + expect(mus.volume).to eq(68) + end + + it "sets the volume using class methods" do + Music.volume = 27 + expect(Music.volume).to eq(27) + end + + it "sets volume to 0 or 100 if outside of range" do + Music.volume = 234 + expect(Music.volume).to eq(100) + Music.volume = -312 + expect(Music.volume).to eq(0) + Music.volume = -1 + expect(Music.volume).to eq(0) + end end end |
