summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorHeitor Carvalho <[email protected]>2018-10-24 18:10:17 -0300
committerTom Black <[email protected]>2018-10-24 14:10:16 -0700
commit830d99fde4555263967dfee94b4095ee300c12e1 (patch)
tree8360ba4b8bc60a45fd50c484f4de39dee13246cd
parent1b646f82c67e7c38df08113bcc3323c7aaf4639f (diff)
downloadruby2d-830d99fde4555263967dfee94b4095ee300c12e1.tar.gz
ruby2d-830d99fde4555263967dfee94b4095ee300c12e1.zip
Implements volume control to Music (#123)
-rw-r--r--ext/ruby2d/ruby2d.c20
-rw-r--r--lib/ruby2d/music.rb16
-rw-r--r--test/audio.rb25
-rw-r--r--test/music_spec.rb27
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