ruby-sdl2 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/README.md +5 -6
- data/Rakefile +13 -0
- data/clipboard.c +24 -0
- data/event.c +216 -5
- data/filesystem.c +27 -0
- data/gamecontroller.c +244 -30
- data/gamecontroller.c.m4 +408 -0
- data/gl.c.m4 +159 -9
- data/hint.c +51 -8
- data/key.c.m4 +6 -0
- data/lib/sdl2/version.rb +2 -2
- data/messagebox.c +40 -38
- data/mixer.c +138 -21
- data/mixer.c.m4 +1196 -0
- data/mouse.c +5 -5
- data/sample/message_box.rb +5 -5
- data/sample/primitives.rb +1 -1
- data/sample/test_video.rb +3 -3
- data/sample/testgl.rb +1 -1
- data/sample/testsprite.rb +5 -5
- data/ttf.c +193 -14
- data/ttf.c.m4 +375 -0
- data/video.c.m4 +465 -122
- metadata +6 -3
data/mixer.c
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
/* -*- mode: C -*- */
|
1
2
|
#ifdef HAVE_SDL_MIXER_H
|
2
3
|
#include "rubysdl2_internal.h"
|
3
4
|
#include <SDL_mixer.h>
|
@@ -232,6 +233,9 @@ static VALUE Channels_s_allocate(VALUE self, VALUE num_channels)
|
|
232
233
|
|
233
234
|
/*
|
234
235
|
* @overload reserve(num)
|
236
|
+
* Reserve channel from 0 to num-1 and reserved channels are not used by
|
237
|
+
* {Channels.play} and {Channels.fade_in} with **channels**==-1.
|
238
|
+
*
|
235
239
|
* @param num [Integer]
|
236
240
|
* @return [Integer]
|
237
241
|
*/
|
@@ -520,29 +524,73 @@ static VALUE Channels_s_playing_chunk(VALUE self, VALUE channel)
|
|
520
524
|
return rb_ary_entry(playing_chunks, NUM2INT(channel));
|
521
525
|
}
|
522
526
|
|
527
|
+
/*
|
528
|
+
* Document-class: SDL2::Mixer::Channels::Group
|
529
|
+
*
|
530
|
+
* This class represents a channel group. A channel group is
|
531
|
+
* a set of channels and you can stop playing and fade out playing
|
532
|
+
* channels of an group at the same time.
|
533
|
+
*
|
534
|
+
* Each channel group is identified by an integer called tag.
|
535
|
+
*/
|
536
|
+
|
537
|
+
/*
|
538
|
+
* Initialize the channel with given **tag**.
|
539
|
+
*
|
540
|
+
* Groups with a common tag are identified.
|
541
|
+
*/
|
523
542
|
static VALUE Group_initialize(VALUE self, VALUE tag)
|
524
543
|
{
|
525
544
|
rb_iv_set(self, "@tag", tag);
|
526
545
|
return Qnil;
|
527
546
|
}
|
528
547
|
|
548
|
+
/*
|
549
|
+
* Get the default channel group.
|
550
|
+
*
|
551
|
+
* The default channel group refers all channels in the mixer system.
|
552
|
+
*
|
553
|
+
* @return [SDL2::Mixer::Channels::Group]
|
554
|
+
*/
|
529
555
|
static VALUE Group_s_default(VALUE self)
|
530
556
|
{
|
531
557
|
VALUE tag = INT2FIX(-1);
|
532
558
|
return rb_class_new_instance(1, &tag, self);
|
533
559
|
}
|
534
560
|
|
561
|
+
/*
|
562
|
+
* Get the tag of the group.
|
563
|
+
*
|
564
|
+
* @return [Integer]
|
565
|
+
*/
|
535
566
|
inline static int Group_tag(VALUE group)
|
536
567
|
{
|
537
568
|
return NUM2INT(rb_iv_get(group, "@tag"));
|
538
569
|
}
|
539
570
|
|
571
|
+
/*
|
572
|
+
* @overload ==(other)
|
573
|
+
* Return true if **self** and **other** are same.
|
574
|
+
*
|
575
|
+
* **self** and **other** are considered to be same
|
576
|
+
* if they have the same tag.
|
577
|
+
*
|
578
|
+
* @param other [SDL2::Mixer::Channel::Group] a compared object
|
579
|
+
* @return [Boolean]
|
580
|
+
*/
|
540
581
|
static VALUE Group_eq(VALUE self, VALUE other)
|
541
582
|
{
|
542
583
|
return INT2BOOL(rb_obj_is_instance_of(other, cGroup) &&
|
543
584
|
Group_tag(self) == Group_tag(other));
|
544
585
|
}
|
545
586
|
|
587
|
+
/*
|
588
|
+
* @overload add(which)
|
589
|
+
* Add a channel to the group.
|
590
|
+
*
|
591
|
+
* @param which [Integer] a channel id
|
592
|
+
* @return [nil]
|
593
|
+
*/
|
546
594
|
static VALUE Group_add(VALUE self, VALUE which)
|
547
595
|
{
|
548
596
|
if (!Mix_GroupChannel(NUM2INT(which), Group_tag(self))) {
|
@@ -552,37 +600,85 @@ static VALUE Group_add(VALUE self, VALUE which)
|
|
552
600
|
return Qnil;
|
553
601
|
}
|
554
602
|
|
603
|
+
/*
|
604
|
+
* Get the number of channels belong to the group.
|
605
|
+
*
|
606
|
+
* @return [Integer]
|
607
|
+
*/
|
555
608
|
static VALUE Group_count(VALUE self)
|
556
609
|
{
|
557
610
|
return INT2NUM(Mix_GroupCount(Group_tag(self)));
|
558
611
|
}
|
559
612
|
|
613
|
+
/*
|
614
|
+
* Return the first available channel in the group.
|
615
|
+
*
|
616
|
+
* Return -1 if no channel is available.
|
617
|
+
*
|
618
|
+
* @return [Integer]
|
619
|
+
*/
|
560
620
|
static VALUE Group_available(VALUE self)
|
561
621
|
{
|
562
622
|
return INT2NUM(Mix_GroupAvailable(Group_tag(self)));
|
563
623
|
}
|
564
624
|
|
625
|
+
/*
|
626
|
+
* Return the oldest cahnnel in the group.
|
627
|
+
*
|
628
|
+
* Return -1 if no channel is available.
|
629
|
+
*
|
630
|
+
* @return [Integer]
|
631
|
+
*/
|
565
632
|
static VALUE Group_oldest(VALUE self)
|
566
633
|
{
|
567
634
|
return INT2NUM(Mix_GroupOldest(Group_tag(self)));
|
568
635
|
}
|
569
636
|
|
637
|
+
/*
|
638
|
+
* Return the newer cahnnel in the group.
|
639
|
+
*
|
640
|
+
* Return -1 if no channel is available.
|
641
|
+
*
|
642
|
+
* @return [Integer]
|
643
|
+
*/
|
570
644
|
static VALUE Group_newer(VALUE self)
|
571
645
|
{
|
572
646
|
return INT2NUM(Mix_GroupNewer(Group_tag(self)));
|
573
647
|
}
|
574
648
|
|
649
|
+
/*
|
650
|
+
* @overload fade_out(ms)
|
651
|
+
* Halt playing of all channels in the group with fade-out effect.
|
652
|
+
*
|
653
|
+
* @param ms [Integer] milliseconds of fade-out effect
|
654
|
+
* @return [Integer] the number of channels affected by this method
|
655
|
+
* @see Channels.fade_out
|
656
|
+
* @see .halt
|
657
|
+
*/
|
575
658
|
static VALUE Group_fade_out(VALUE self, VALUE ms)
|
576
659
|
{
|
577
660
|
return INT2NUM(Mix_FadeOutGroup(Group_tag(self), NUM2INT(ms)));
|
578
661
|
}
|
579
662
|
|
663
|
+
/*
|
664
|
+
* Halt playing of all channels in the group.
|
665
|
+
*
|
666
|
+
* @return [nil]
|
667
|
+
* @see Channels.halt
|
668
|
+
* @see .fade_out
|
669
|
+
*/
|
580
670
|
static VALUE Group_halt(VALUE self)
|
581
671
|
{
|
582
672
|
Mix_HaltGroup(Group_tag(self));
|
583
673
|
return Qnil;
|
584
674
|
}
|
585
675
|
|
676
|
+
/*
|
677
|
+
* Document-module: SDL2::Mixer::MusicChannel
|
678
|
+
*
|
679
|
+
* This module provides the functions to play {SDL2::Mixer::Music}.
|
680
|
+
*/
|
681
|
+
|
586
682
|
/*
|
587
683
|
* @overload play(music, loops)
|
588
684
|
* Play **music** **loops** times.
|
@@ -596,7 +692,7 @@ static VALUE Group_halt(VALUE self)
|
|
596
692
|
*
|
597
693
|
* @return [nil]
|
598
694
|
*
|
599
|
-
* @see
|
695
|
+
* @see .fade_in
|
600
696
|
*
|
601
697
|
*/
|
602
698
|
static VALUE MusicChannel_s_play(VALUE self, VALUE music, VALUE loops)
|
@@ -622,7 +718,7 @@ static VALUE MusicChannel_s_play(VALUE self, VALUE music, VALUE loops)
|
|
622
718
|
*
|
623
719
|
* @return [nil]
|
624
720
|
*
|
625
|
-
* @see
|
721
|
+
* @see .play
|
626
722
|
*/
|
627
723
|
static VALUE MusicChannel_s_fade_in(int argc, VALUE* argv, VALUE self)
|
628
724
|
{
|
@@ -970,31 +1066,50 @@ void rubysdl2_init_mixer(void)
|
|
970
1066
|
rb_define_module_function(mMixer, "close", Mixer_s_close, 0);
|
971
1067
|
rb_define_module_function(mMixer, "query", Mixer_s_query, 0);
|
972
1068
|
|
973
|
-
|
974
|
-
|
975
|
-
|
976
|
-
|
977
|
-
|
978
|
-
|
979
|
-
|
980
|
-
|
981
|
-
|
982
|
-
|
983
|
-
rb_define_const(mMixer, "
|
984
|
-
|
985
|
-
|
986
|
-
|
987
|
-
|
988
|
-
|
989
|
-
|
990
|
-
|
991
|
-
|
1069
|
+
/* */
|
1070
|
+
/* Initialize Ogg flac loader */
|
1071
|
+
rb_define_const(mMixer, "INIT_FLAC", UINT2NUM(MIX_INIT_FLAC));
|
1072
|
+
/* Initialize MOD loader */
|
1073
|
+
rb_define_const(mMixer, "INIT_MOD", UINT2NUM(MIX_INIT_MOD));
|
1074
|
+
/* Initialize libmodplug */
|
1075
|
+
rb_define_const(mMixer, "INIT_MODPLUG", UINT2NUM(MIX_INIT_MODPLUG));
|
1076
|
+
/* Initialize MP3 loader */
|
1077
|
+
rb_define_const(mMixer, "INIT_MP3", UINT2NUM(MIX_INIT_MP3));
|
1078
|
+
/* Initialize Ogg vorbis loader */
|
1079
|
+
rb_define_const(mMixer, "INIT_OGG", UINT2NUM(MIX_INIT_OGG));
|
1080
|
+
/* Initialize fluidsynth */
|
1081
|
+
rb_define_const(mMixer, "INIT_FLUIDSYNTH", UINT2NUM(MIX_INIT_FLUIDSYNTH));
|
1082
|
+
|
1083
|
+
/* */
|
1084
|
+
/* Unsiged 8-bit sample format. Used by {Mixer.open} */
|
1085
|
+
rb_define_const(mMixer, "FORMAT_U8", UINT2NUM(AUDIO_U8));
|
1086
|
+
/* Siged 8-bit sample format. Used by {Mixer.open} */
|
1087
|
+
rb_define_const(mMixer, "FORMAT_S8", UINT2NUM(AUDIO_S8));
|
1088
|
+
/* Unsiged 16-bit little-endian sample format. Used by {Mixer.open} */
|
1089
|
+
rb_define_const(mMixer, "FORMAT_U16LSB", UINT2NUM(AUDIO_U16LSB));
|
1090
|
+
/* Siged 16-bit little-endian sample format. Used by {Mixer.open} */
|
1091
|
+
rb_define_const(mMixer, "FORMAT_S16LSB", UINT2NUM(AUDIO_S16LSB));
|
1092
|
+
/* Unsiged 16-bit big-endian sample format. Used by {Mixer.open} */
|
1093
|
+
rb_define_const(mMixer, "FORMAT_U16MSB", UINT2NUM(AUDIO_U16MSB));
|
1094
|
+
/* Unsiged 16-bit big-endian sample format. Used by {Mixer.open} */
|
1095
|
+
rb_define_const(mMixer, "FORMAT_S16MSB", UINT2NUM(AUDIO_S16MSB));
|
1096
|
+
/* Unsiged 16-bit sample format. Endian is same as system byte order. Used by {Mixer.open} */
|
1097
|
+
rb_define_const(mMixer, "FORMAT_U16SYS", UINT2NUM(AUDIO_U16SYS));
|
1098
|
+
/* Siged 16-bit sample format. Endian is same as system byte order. Used by {Mixer.open} */
|
1099
|
+
rb_define_const(mMixer, "FORMAT_S16SYS", UINT2NUM(AUDIO_S16SYS));
|
1100
|
+
/* Default frequency. 22050 (Hz) */
|
992
1101
|
rb_define_const(mMixer, "DEFAULT_FREQUENCY", UINT2NUM(MIX_DEFAULT_FREQUENCY));
|
1102
|
+
/* Default sample format. Same as {Mixer::FORMAT_S16SYS}. */
|
993
1103
|
rb_define_const(mMixer, "DEFAULT_FORMAT", UINT2NUM(MIX_DEFAULT_FORMAT));
|
1104
|
+
/* Default number of channels. 2. */
|
994
1105
|
rb_define_const(mMixer, "DEFAULT_CHANNELS", INT2FIX(MIX_DEFAULT_CHANNELS));
|
1106
|
+
/* Max volume value. 128. */
|
995
1107
|
rb_define_const(mMixer, "MAX_VOLUME", INT2FIX(MIX_MAX_VOLUME));
|
1108
|
+
/* This constants represents that the channel is not fading in and fading out. */
|
996
1109
|
rb_define_const(mMixer, "NO_FADING", INT2FIX(MIX_NO_FADING));
|
1110
|
+
/* This constants represents that the channel is fading out. */
|
997
1111
|
rb_define_const(mMixer, "FADING_OUT", INT2FIX(MIX_FADING_OUT));
|
1112
|
+
/* This constants represents that the channel is fading in. */
|
998
1113
|
rb_define_const(mMixer, "FADING_IN", INT2FIX(MIX_FADING_IN));
|
999
1114
|
|
1000
1115
|
|
@@ -1007,6 +1122,7 @@ void rubysdl2_init_mixer(void)
|
|
1007
1122
|
rb_define_method(cChunk, "volume", Chunk_volume, 0);
|
1008
1123
|
rb_define_method(cChunk, "volume=", Chunk_set_volume, 1);
|
1009
1124
|
rb_define_method(cChunk, "inspect", Chunk_inspect, 0);
|
1125
|
+
/* @return [String] The file name of the file from which the sound is loaded. */
|
1010
1126
|
rb_define_attr(cChunk, "filename", 1, 0);
|
1011
1127
|
|
1012
1128
|
|
@@ -1040,6 +1156,7 @@ void rubysdl2_init_mixer(void)
|
|
1040
1156
|
cGroup = rb_define_class_under(mChannels, "Group", rb_cObject);
|
1041
1157
|
rb_define_method(cGroup, "initialize", Group_initialize, 1);
|
1042
1158
|
rb_define_singleton_method(cGroup, "default", Group_s_default, 0);
|
1159
|
+
/* @return [Integer] tag id */
|
1043
1160
|
rb_define_attr(cGroup, "tag", 1, 0);
|
1044
1161
|
rb_define_method(cGroup, "==", Group_eq, 1);
|
1045
1162
|
rb_define_method(cGroup, "add", Group_add, 1);
|
data/mixer.c.m4
ADDED
@@ -0,0 +1,1196 @@
|
|
1
|
+
/* -*- mode: C -*- */
|
2
|
+
#ifdef HAVE_SDL_MIXER_H
|
3
|
+
#include "rubysdl2_internal.h"
|
4
|
+
#include <SDL_mixer.h>
|
5
|
+
|
6
|
+
static VALUE mMixer;
|
7
|
+
static VALUE cChunk;
|
8
|
+
static VALUE cMusic;
|
9
|
+
static VALUE mChannels;
|
10
|
+
static VALUE cGroup;
|
11
|
+
static VALUE mMusicChannel;
|
12
|
+
|
13
|
+
static VALUE playing_chunks = Qnil;
|
14
|
+
static VALUE playing_music = Qnil;
|
15
|
+
|
16
|
+
#define MIX_ERROR() do { HANDLE_ERROR(SDL_SetError(Mix_GetError())); } while(0)
|
17
|
+
#define HANDLE_MIX_ERROR(code) \
|
18
|
+
do { if ((code) < 0) { MIX_ERROR(); } } while (0)
|
19
|
+
|
20
|
+
typedef struct Chunk {
|
21
|
+
Mix_Chunk* chunk;
|
22
|
+
} Chunk;
|
23
|
+
|
24
|
+
typedef struct Music {
|
25
|
+
Mix_Music* music;
|
26
|
+
} Music;
|
27
|
+
|
28
|
+
static void Chunk_free(Chunk* c)
|
29
|
+
{
|
30
|
+
if (rubysdl2_is_active() && c->chunk)
|
31
|
+
Mix_FreeChunk(c->chunk);
|
32
|
+
free(c);
|
33
|
+
}
|
34
|
+
|
35
|
+
static VALUE Chunk_new(Mix_Chunk* chunk)
|
36
|
+
{
|
37
|
+
Chunk* c = ALLOC(Chunk);
|
38
|
+
c->chunk = chunk;
|
39
|
+
return Data_Wrap_Struct(cChunk, 0, Chunk_free, c);
|
40
|
+
}
|
41
|
+
|
42
|
+
DEFINE_WRAPPER(Mix_Chunk, Chunk, chunk, cChunk, "SDL2::Mixer::Chunk");
|
43
|
+
|
44
|
+
static void Music_free(Music* m)
|
45
|
+
{
|
46
|
+
if (rubysdl2_is_active() && m->music)
|
47
|
+
Mix_FreeMusic(m->music);
|
48
|
+
free(m);
|
49
|
+
}
|
50
|
+
|
51
|
+
static VALUE Music_new(Mix_Music* music)
|
52
|
+
{
|
53
|
+
Music* c = ALLOC(Music);
|
54
|
+
c->music = music;
|
55
|
+
return Data_Wrap_Struct(cMusic, 0, Music_free, c);
|
56
|
+
}
|
57
|
+
|
58
|
+
DEFINE_WRAPPER(Mix_Music, Music, music, cMusic, "SDL2::Mixer::Music");
|
59
|
+
|
60
|
+
/*
|
61
|
+
* Document-module: SDL2::Mixer
|
62
|
+
*
|
63
|
+
* Sound mixing module.
|
64
|
+
*
|
65
|
+
* With this module, you can play many kinds of sound files such as:
|
66
|
+
*
|
67
|
+
* * WAVE/RIFF (.wav)
|
68
|
+
* * AIFF (.aiff)
|
69
|
+
* * VOC (.voc)
|
70
|
+
* * MOD (.mod .xm .s3m .669 .it .med etc.)
|
71
|
+
* * MIDI (.mid)
|
72
|
+
* * OggVorbis (.ogg)
|
73
|
+
* * MP3 (.mp3)
|
74
|
+
* * FLAC (.flac)
|
75
|
+
*
|
76
|
+
* Before playing sounds,
|
77
|
+
* you need to initialize this module by {.init} and
|
78
|
+
* open a sound device by {.open}.
|
79
|
+
*
|
80
|
+
* This module mixes multiple sound sources in parallel.
|
81
|
+
* To play a sound source, you assign the source to a "channel"
|
82
|
+
* and this module mixes all sound sources assigned to the channels.
|
83
|
+
*
|
84
|
+
* In this module, there are two types of sound sources:
|
85
|
+
* {SDL2::Mixer::Chunk} and {SDL2::Mixer::Music}.
|
86
|
+
* And there are two corresponding types of channels:
|
87
|
+
* {SDL2::Mixer::Channels} and {SDL2::Mixer::MusicChannel}.
|
88
|
+
*
|
89
|
+
* {SDL2::Mixer::Channels} module plays {SDL2::Mixer::Chunk} objects,
|
90
|
+
* through multiple (default eight) channels. This module is suitable
|
91
|
+
* for the sound effects.
|
92
|
+
* The number of channels is variable with {SDL2::Mixer::Channels.allocate}.
|
93
|
+
*
|
94
|
+
* {SDL2::Mixer::MusicChannel} module plays {SDL2::Mixer::Music} objects.
|
95
|
+
* This module has only one playing channel, and you cannot play
|
96
|
+
* multiple music in parallel. However an {SDL2::Mixer::Music} object
|
97
|
+
* is more efficient for memory, and this module supports more file formats
|
98
|
+
* than {SDL2::Mixer::Channels}.
|
99
|
+
* This module is suitable for playing "BGMs" of your application.
|
100
|
+
*
|
101
|
+
*/
|
102
|
+
|
103
|
+
/*
|
104
|
+
* @overload init(flags)
|
105
|
+
* Initialize the mixer library.
|
106
|
+
*
|
107
|
+
* This module function load dynamically-linked libraries for sound file
|
108
|
+
* formats such as ogg and flac.
|
109
|
+
*
|
110
|
+
* You can give the initialized libraries (file formats) with OR'd bits of the
|
111
|
+
* following constants:
|
112
|
+
*
|
113
|
+
* * SDL2::Mixer::INIT_FLAC
|
114
|
+
* * SDL2::Mixer::INIT_MOD
|
115
|
+
* * SDL2::Mixer::INIT_MODPLUG
|
116
|
+
* * SDL2::Mixer::INIT_MP3
|
117
|
+
* * SDL2::Mixer::INIT_OGG
|
118
|
+
* * SDL2::Mixer::INIT_FLUIDSYNTH
|
119
|
+
*
|
120
|
+
* @param flags [Integer] intialized sublibraries
|
121
|
+
* @return [nil]
|
122
|
+
*
|
123
|
+
*/
|
124
|
+
static VALUE Mixer_s_init(VALUE self, VALUE f)
|
125
|
+
{
|
126
|
+
int flags = NUM2INT(f);
|
127
|
+
if (Mix_Init(flags) & flags != flags)
|
128
|
+
rb_raise(eSDL2Error, "Couldn't initialize SDL_mixer");
|
129
|
+
|
130
|
+
return Qnil;
|
131
|
+
}
|
132
|
+
|
133
|
+
static void check_channel(VALUE ch, int allow_minus_1)
|
134
|
+
{
|
135
|
+
int channel = NUM2INT(ch);
|
136
|
+
if (channel >= Mix_AllocateChannels(-1))
|
137
|
+
rb_raise(rb_eArgError, "too large number of channel (%d)", channel);
|
138
|
+
if (channel == -1 && !allow_minus_1 || channel < -1)
|
139
|
+
rb_raise(rb_eArgError, "negative number of channel is not allowed");
|
140
|
+
}
|
141
|
+
|
142
|
+
/*
|
143
|
+
* @overload open(freq=22050, format=SDL2::Mixer::DEFAULT_FORMAT, channels=2, chunksize=1024)
|
144
|
+
* Open a sound device.
|
145
|
+
*
|
146
|
+
* Before calling loading/playing methods in the mixer module,
|
147
|
+
* this method must be called.
|
148
|
+
* Before calling this method,
|
149
|
+
* {SDL2.init} must be called with SDL2::INIT_AUDIO.
|
150
|
+
*
|
151
|
+
* @param freq [Integer] output sampling frequency in Hz.
|
152
|
+
* Normally 22050 or 44100 is used.
|
153
|
+
* 44100 is CD audio rate. SDL2::Mixer::DEFAULT_FREQUENCY(22050) is best for
|
154
|
+
* many kinds of game because 44100 requires too much CPU power on older computers.
|
155
|
+
* @param format [Integer] output sample format
|
156
|
+
* @param channels 1 is for mono, and 2 is for stereo.
|
157
|
+
* @param chunksize bytes used per output sample
|
158
|
+
*
|
159
|
+
* @return [nil]
|
160
|
+
*
|
161
|
+
* @raise [SDL2::Error] raised when a device cannot be opened
|
162
|
+
*
|
163
|
+
* @see .init
|
164
|
+
* @see .close
|
165
|
+
* @see .query
|
166
|
+
*/
|
167
|
+
static VALUE Mixer_s_open(int argc, VALUE* argv, VALUE self)
|
168
|
+
{
|
169
|
+
VALUE freq, format, channels, chunksize;
|
170
|
+
rb_scan_args(argc, argv, "04", &freq, &format, &channels, &chunksize);
|
171
|
+
HANDLE_MIX_ERROR(Mix_OpenAudio((freq == Qnil) ? MIX_DEFAULT_FREQUENCY : NUM2INT(freq),
|
172
|
+
(format == Qnil) ? MIX_DEFAULT_FORMAT : NUM2UINT(format),
|
173
|
+
(channels == Qnil) ? 2 : NUM2INT(channels),
|
174
|
+
(chunksize == Qnil) ? 1024 : NUM2INT(chunksize)));
|
175
|
+
playing_chunks = rb_ary_new();
|
176
|
+
return Qnil;
|
177
|
+
}
|
178
|
+
|
179
|
+
/*
|
180
|
+
* Close the audio device.
|
181
|
+
*
|
182
|
+
* @return [nil]
|
183
|
+
*/
|
184
|
+
static VALUE Mixer_s_close(VALUE self)
|
185
|
+
{
|
186
|
+
Mix_CloseAudio();
|
187
|
+
return Qnil;
|
188
|
+
}
|
189
|
+
|
190
|
+
|
191
|
+
/*
|
192
|
+
* Query a sound device spec.
|
193
|
+
*
|
194
|
+
* This method returns the most suitable setting for {.open} the device.
|
195
|
+
*
|
196
|
+
* @return [[Integer, Integer, Integer, Integer]]
|
197
|
+
* the suitable frequency in Hz, the suitable format,
|
198
|
+
* the suitable number of channels (1 for mono, 2 for stereo),
|
199
|
+
* and the number of call of {.open}.
|
200
|
+
*
|
201
|
+
*/
|
202
|
+
static VALUE Mixer_s_query(VALUE self)
|
203
|
+
{
|
204
|
+
int frequency = 0, channels = 0, num_opened;
|
205
|
+
Uint16 format = 0;
|
206
|
+
|
207
|
+
num_opened = Mix_QuerySpec(&frequency, &format, &channels);
|
208
|
+
return rb_ary_new3(4, INT2NUM(frequency), UINT2NUM(format),
|
209
|
+
INT2NUM(channels), INT2NUM(num_opened));
|
210
|
+
}
|
211
|
+
|
212
|
+
/*
|
213
|
+
* Document-module: SDL2::Mixer::Channels
|
214
|
+
*
|
215
|
+
* This module plays {SDL2::Mixer::Chunk} objects in parallel.
|
216
|
+
*
|
217
|
+
* Each virtual sound output device is called channel, and
|
218
|
+
* the number of channels determines the f
|
219
|
+
*/
|
220
|
+
|
221
|
+
/*
|
222
|
+
* @overload allocate(num_channels)
|
223
|
+
* Set the number of channels being mixed.
|
224
|
+
*
|
225
|
+
* @param num_channels [Integer] Number of channels prepared for mixing.
|
226
|
+
*
|
227
|
+
* @return [Integer] the number of prepared channels.
|
228
|
+
*/
|
229
|
+
static VALUE Channels_s_allocate(VALUE self, VALUE num_channels)
|
230
|
+
{
|
231
|
+
return INT2NUM(Mix_AllocateChannels(NUM2INT(num_channels)));
|
232
|
+
}
|
233
|
+
|
234
|
+
/*
|
235
|
+
* @overload reserve(num)
|
236
|
+
* Reserve channel from 0 to num-1 and reserved channels are not used by
|
237
|
+
* {Channels.play} and {Channels.fade_in} with **channels**==-1.
|
238
|
+
*
|
239
|
+
* @param num [Integer]
|
240
|
+
* @return [Integer]
|
241
|
+
*/
|
242
|
+
static VALUE Channels_s_reserve(VALUE self, VALUE num)
|
243
|
+
{
|
244
|
+
return INT2NUM(Mix_ReserveChannels(NUM2INT(num)));
|
245
|
+
}
|
246
|
+
|
247
|
+
/*
|
248
|
+
* @overload volume(channel)
|
249
|
+
* Get the volume of specified channel.
|
250
|
+
*
|
251
|
+
* @param channel [Integer] the channel to get volume for.
|
252
|
+
* If the specified channel is -1, this method returns
|
253
|
+
* the average volume of all channels.
|
254
|
+
* @return [Integer] the volume, 0-128
|
255
|
+
*
|
256
|
+
* @see .set_volume
|
257
|
+
*/
|
258
|
+
static VALUE Channels_s_volume(VALUE self, VALUE channel)
|
259
|
+
{
|
260
|
+
return INT2NUM(Mix_Volume(NUM2INT(channel), -1));
|
261
|
+
}
|
262
|
+
|
263
|
+
/*
|
264
|
+
* @overload set_volume(channel, volume)
|
265
|
+
* Set the volume of specified channel.
|
266
|
+
*
|
267
|
+
* The volume should be from 0 to {SDL2::Mixer::MAX_VOLUME}(128).
|
268
|
+
* If the specified channel is -1, set volume for all channels.
|
269
|
+
*
|
270
|
+
* @param channel [Integer] the channel to set volume for.
|
271
|
+
* @param volume [Integer] the volume to use
|
272
|
+
* @return [void]
|
273
|
+
*
|
274
|
+
* @see .volume
|
275
|
+
*/
|
276
|
+
static VALUE Channels_s_set_volume(VALUE self, VALUE channel, VALUE volume)
|
277
|
+
{
|
278
|
+
return INT2NUM(Mix_Volume(NUM2INT(channel), NUM2INT(volume)));
|
279
|
+
}
|
280
|
+
|
281
|
+
static void protect_playing_chunk_from_gc(int channel, VALUE chunk)
|
282
|
+
{
|
283
|
+
rb_ary_store(playing_chunks, channel, chunk);
|
284
|
+
}
|
285
|
+
|
286
|
+
/*
|
287
|
+
* @overload play(channel, chunk, loops, ticks = -1)
|
288
|
+
* Play a {SDL2::Mixer::Chunk} on **channel**.
|
289
|
+
*
|
290
|
+
* @param channel [Integer] the channel to play, or -1 for the first free unreserved
|
291
|
+
* channel
|
292
|
+
* @param chunk [SDL2::Mixer::Chunk] the chunk to play
|
293
|
+
* @param loops [Integer] the number of loops, or -1 for infite loops.
|
294
|
+
* passing 1 plays the sample twice (1 loop).
|
295
|
+
* @param ticks [Integer] milliseconds limit to play, at most.
|
296
|
+
* If the chunk is long enough and **loops** is large enough,
|
297
|
+
* the play will stop after **ticks** milliseconds.
|
298
|
+
* Otherwise, the play will stop when the loop ends.
|
299
|
+
* -1 means infinity.
|
300
|
+
* @return [Integer] the channel that plays the chunk.
|
301
|
+
*
|
302
|
+
* @raise [SDL2::Error] raised on a playing error. For example,
|
303
|
+
* **channel** is out of the allocated channels, or
|
304
|
+
* there is no free channels when **channel** is -1.
|
305
|
+
*
|
306
|
+
* @see .fade_in
|
307
|
+
*/
|
308
|
+
static VALUE Channels_s_play(int argc, VALUE* argv, VALUE self)
|
309
|
+
{
|
310
|
+
VALUE channel, chunk, loops, ticks;
|
311
|
+
int ch;
|
312
|
+
rb_scan_args(argc, argv, "31", &channel, &chunk, &loops, &ticks);
|
313
|
+
if (ticks == Qnil)
|
314
|
+
ticks = INT2FIX(-1);
|
315
|
+
check_channel(channel, 1);
|
316
|
+
ch = Mix_PlayChannelTimed(NUM2INT(channel), Get_Mix_Chunk(chunk),
|
317
|
+
NUM2INT(loops), NUM2INT(ticks));
|
318
|
+
HANDLE_MIX_ERROR(ch);
|
319
|
+
protect_playing_chunk_from_gc(ch, chunk);
|
320
|
+
return INT2FIX(ch);
|
321
|
+
}
|
322
|
+
|
323
|
+
/*
|
324
|
+
* @overload fade_in(channel, chunk, loops, ms, ticks = -1)
|
325
|
+
* Play a {SDL2::Mixer::Chunk} on **channel** with fading in.
|
326
|
+
*
|
327
|
+
* @param channel [Integer] the channel to play, or -1 for the first free unreserved
|
328
|
+
* channel
|
329
|
+
* @param chunk [SDL2::Mixer::Chunk] the chunk to play
|
330
|
+
* @param loops [Integer] the number of loops, or -1 for infite loops.
|
331
|
+
* passing 1 plays the sample twice (1 loop).
|
332
|
+
* @param ms [Integer] milliseconds of time of fade-in effect.
|
333
|
+
* @param ticks [Integer] milliseconds limit to play, at most.
|
334
|
+
* If the chunk is long enough and **loops** is large enough,
|
335
|
+
* the play will stop after **ticks** milliseconds.
|
336
|
+
* Otherwise, the play will stop when the loop ends.
|
337
|
+
* -1 means infinity.
|
338
|
+
* @return [Integer] the channel that plays the chunk.
|
339
|
+
*
|
340
|
+
* @raise [SDL2::Error] raised on a playing error. For example,
|
341
|
+
* **channel** is out of the allocated channels, or
|
342
|
+
* there is no free channels when **channel** is -1.
|
343
|
+
*
|
344
|
+
* @see .play
|
345
|
+
* @see .fade_out
|
346
|
+
*/
|
347
|
+
static VALUE Channels_s_fade_in(int argc, VALUE* argv, VALUE self)
|
348
|
+
{
|
349
|
+
VALUE channel, chunk, loops, ms, ticks;
|
350
|
+
int ch;
|
351
|
+
rb_scan_args(argc, argv, "41", &channel, &chunk, &loops, &ms, &ticks);
|
352
|
+
if (ticks == Qnil)
|
353
|
+
ticks = INT2FIX(-1);
|
354
|
+
check_channel(channel, 1);
|
355
|
+
ch = Mix_FadeInChannelTimed(NUM2INT(channel), Get_Mix_Chunk(chunk),
|
356
|
+
NUM2INT(loops), NUM2INT(ms), NUM2INT(ticks));
|
357
|
+
HANDLE_MIX_ERROR(ch);
|
358
|
+
protect_playing_chunk_from_gc(ch, chunk);
|
359
|
+
return INT2FIX(ch);
|
360
|
+
}
|
361
|
+
|
362
|
+
/*
|
363
|
+
* @overload pause(channel)
|
364
|
+
* Pause a specified channel.
|
365
|
+
*
|
366
|
+
* @param channel [Integer] the channel to pause, or -1 for all channels.
|
367
|
+
* @return [nil]
|
368
|
+
*
|
369
|
+
* @see .resume
|
370
|
+
* @see .pause?
|
371
|
+
*/
|
372
|
+
static VALUE Channels_s_pause(VALUE self, VALUE channel)
|
373
|
+
{
|
374
|
+
check_channel(channel, 1);
|
375
|
+
Mix_Pause(NUM2INT(channel));
|
376
|
+
return Qnil;
|
377
|
+
}
|
378
|
+
|
379
|
+
/*
|
380
|
+
* @overload resume(channel)
|
381
|
+
* Resume a specified channel that already pauses.
|
382
|
+
*
|
383
|
+
* @note This method has no effect to unpaused channels.
|
384
|
+
* @param channel [Integer] the channel to be resumed, or -1 for all channels.
|
385
|
+
* @return [nil]
|
386
|
+
*
|
387
|
+
* @see .pause
|
388
|
+
* @see .pause?
|
389
|
+
*/
|
390
|
+
static VALUE Channels_s_resume(VALUE self, VALUE channel)
|
391
|
+
{
|
392
|
+
check_channel(channel, 1);
|
393
|
+
Mix_Resume(NUM2INT(channel));
|
394
|
+
return Qnil;
|
395
|
+
}
|
396
|
+
|
397
|
+
/*
|
398
|
+
* @overload halt(channel)
|
399
|
+
* Halt playing of a specified channel.
|
400
|
+
*
|
401
|
+
* @param channel [Integer] the channel to be halted, or -1 for all channels.
|
402
|
+
* @return [nil]
|
403
|
+
*
|
404
|
+
* @see .expire
|
405
|
+
* @see .fade_out
|
406
|
+
* @see .play?
|
407
|
+
*/
|
408
|
+
static VALUE Channels_s_halt(VALUE self, VALUE channel)
|
409
|
+
{
|
410
|
+
check_channel(channel, 1);
|
411
|
+
Mix_HaltChannel(NUM2INT(channel));
|
412
|
+
return Qnil;
|
413
|
+
}
|
414
|
+
|
415
|
+
/*
|
416
|
+
* @overload expire(channel, ticks)
|
417
|
+
* Halt playing of a specified channel after **ticks** milliseconds.
|
418
|
+
*
|
419
|
+
* @param channel [Integer] the channel to be halted, or -1 for all channels.
|
420
|
+
* @param ticks [Integer] milliseconds untils the channel halts playback.
|
421
|
+
* @return [nil]
|
422
|
+
*
|
423
|
+
* @see .halt
|
424
|
+
* @see .fade_out
|
425
|
+
* @see .play?
|
426
|
+
*/
|
427
|
+
static VALUE Channels_s_expire(VALUE self, VALUE channel, VALUE ticks)
|
428
|
+
{
|
429
|
+
check_channel(channel, 1);
|
430
|
+
Mix_ExpireChannel(NUM2INT(channel), NUM2INT(ticks));
|
431
|
+
return Qnil;
|
432
|
+
}
|
433
|
+
|
434
|
+
/*
|
435
|
+
* @overload fade_out(channel, ms)
|
436
|
+
* Halt playing of a specified channel with fade-out effect.
|
437
|
+
*
|
438
|
+
* @param channel [Integer] the channel to be halted, or -1 for all channels.
|
439
|
+
* @param ms [Integer] milliseconds of fade-out effect
|
440
|
+
* @return [nil]
|
441
|
+
*
|
442
|
+
* @see .halt
|
443
|
+
* @see .expire
|
444
|
+
* @see .play?
|
445
|
+
* @see .fade_in
|
446
|
+
*/
|
447
|
+
static VALUE Channels_s_fade_out(VALUE self, VALUE channel, VALUE ms)
|
448
|
+
{
|
449
|
+
check_channel(channel, 1);
|
450
|
+
Mix_FadeOutChannel(NUM2INT(channel), NUM2INT(ms));
|
451
|
+
return Qnil;
|
452
|
+
}
|
453
|
+
|
454
|
+
/*
|
455
|
+
* @overload play?(channel)
|
456
|
+
* Return true if a specified channel is playing.
|
457
|
+
*
|
458
|
+
* @param channel [Integer] channel to test
|
459
|
+
* @see .pause?
|
460
|
+
* @see .fading
|
461
|
+
*/
|
462
|
+
static VALUE Channels_s_play_p(VALUE self, VALUE channel)
|
463
|
+
{
|
464
|
+
check_channel(channel, 0);
|
465
|
+
return INT2BOOL(Mix_Playing(NUM2INT(channel)));
|
466
|
+
}
|
467
|
+
|
468
|
+
/*
|
469
|
+
* @overload pause?(channel)
|
470
|
+
* Return true if a specified channel is paused.
|
471
|
+
*
|
472
|
+
* @note This method returns true if a paused channel is halted by {.halt}, or any
|
473
|
+
* other halting methods.
|
474
|
+
*
|
475
|
+
* @param channel [Integer] channel to test
|
476
|
+
*
|
477
|
+
* @see .play?
|
478
|
+
* @see .fading
|
479
|
+
*/
|
480
|
+
static VALUE Channels_s_pause_p(VALUE self, VALUE channel)
|
481
|
+
{
|
482
|
+
check_channel(channel, 0);
|
483
|
+
return INT2BOOL(Mix_Paused(NUM2INT(channel)));
|
484
|
+
}
|
485
|
+
|
486
|
+
/*
|
487
|
+
* @overload fading(channel)
|
488
|
+
* Return the fading state of a specified channel.
|
489
|
+
*
|
490
|
+
* The return value is one of the following:
|
491
|
+
*
|
492
|
+
* * {SDL2::Mixer::NO_FADING} - **channel** is not fading in, and fading out
|
493
|
+
* * {SDL2::Mixer::FADING_IN} - **channel** is fading in
|
494
|
+
* * {SDL2::Mixer::FADING_OUT} - **channel** is fading out
|
495
|
+
*
|
496
|
+
* @param channel [Integer] channel to test
|
497
|
+
*
|
498
|
+
* @return [Integer]
|
499
|
+
*
|
500
|
+
* @see .play?
|
501
|
+
* @see .pause?
|
502
|
+
* @see .fade_in
|
503
|
+
* @see .fade_out
|
504
|
+
*/
|
505
|
+
static VALUE Channels_s_fading(VALUE self, VALUE which)
|
506
|
+
{
|
507
|
+
check_channel(which, 0);
|
508
|
+
return INT2FIX(Mix_FadingChannel(NUM2INT(which)));
|
509
|
+
}
|
510
|
+
|
511
|
+
/*
|
512
|
+
* @overload playing_chunk(channel)
|
513
|
+
* Get the {SDL2::Mixer::Chunk} object most recently playing on **channel**.
|
514
|
+
*
|
515
|
+
* If **channel** is out of allocated channels, or
|
516
|
+
* no chunk is played yet on **channel**, this method returns nil.
|
517
|
+
*
|
518
|
+
* @param channel [Integer] the channel to get the chunk object
|
519
|
+
* @return [SDL2::Mixer::Chunk,nil]
|
520
|
+
*/
|
521
|
+
static VALUE Channels_s_playing_chunk(VALUE self, VALUE channel)
|
522
|
+
{
|
523
|
+
check_channel(channel, 0);
|
524
|
+
return rb_ary_entry(playing_chunks, NUM2INT(channel));
|
525
|
+
}
|
526
|
+
|
527
|
+
/*
|
528
|
+
* Document-class: SDL2::Mixer::Channels::Group
|
529
|
+
*
|
530
|
+
* This class represents a channel group. A channel group is
|
531
|
+
* a set of channels and you can stop playing and fade out playing
|
532
|
+
* channels of an group at the same time.
|
533
|
+
*
|
534
|
+
* Each channel group is identified by an integer called tag.
|
535
|
+
*/
|
536
|
+
|
537
|
+
/*
|
538
|
+
* Initialize the channel with given **tag**.
|
539
|
+
*
|
540
|
+
* Groups with a common tag are identified.
|
541
|
+
*/
|
542
|
+
static VALUE Group_initialize(VALUE self, VALUE tag)
|
543
|
+
{
|
544
|
+
rb_iv_set(self, "@tag", tag);
|
545
|
+
return Qnil;
|
546
|
+
}
|
547
|
+
|
548
|
+
/*
|
549
|
+
* Get the default channel group.
|
550
|
+
*
|
551
|
+
* The default channel group refers all channels in the mixer system.
|
552
|
+
*
|
553
|
+
* @return [SDL2::Mixer::Channels::Group]
|
554
|
+
*/
|
555
|
+
static VALUE Group_s_default(VALUE self)
|
556
|
+
{
|
557
|
+
VALUE tag = INT2FIX(-1);
|
558
|
+
return rb_class_new_instance(1, &tag, self);
|
559
|
+
}
|
560
|
+
|
561
|
+
/*
|
562
|
+
* Get the tag of the group.
|
563
|
+
*
|
564
|
+
* @return [Integer]
|
565
|
+
*/
|
566
|
+
inline static int Group_tag(VALUE group)
|
567
|
+
{
|
568
|
+
return NUM2INT(rb_iv_get(group, "@tag"));
|
569
|
+
}
|
570
|
+
|
571
|
+
/*
|
572
|
+
* @overload ==(other)
|
573
|
+
* Return true if **self** and **other** are same.
|
574
|
+
*
|
575
|
+
* **self** and **other** are considered to be same
|
576
|
+
* if they have the same tag.
|
577
|
+
*
|
578
|
+
* @param other [SDL2::Mixer::Channel::Group] a compared object
|
579
|
+
* @return [Boolean]
|
580
|
+
*/
|
581
|
+
static VALUE Group_eq(VALUE self, VALUE other)
|
582
|
+
{
|
583
|
+
return INT2BOOL(rb_obj_is_instance_of(other, cGroup) &&
|
584
|
+
Group_tag(self) == Group_tag(other));
|
585
|
+
}
|
586
|
+
|
587
|
+
/*
|
588
|
+
* @overload add(which)
|
589
|
+
* Add a channel to the group.
|
590
|
+
*
|
591
|
+
* @param which [Integer] a channel id
|
592
|
+
* @return [nil]
|
593
|
+
*/
|
594
|
+
static VALUE Group_add(VALUE self, VALUE which)
|
595
|
+
{
|
596
|
+
if (!Mix_GroupChannel(NUM2INT(which), Group_tag(self))) {
|
597
|
+
SDL_SetError("Cannot add channel %d", NUM2INT(which));
|
598
|
+
SDL_ERROR();
|
599
|
+
}
|
600
|
+
return Qnil;
|
601
|
+
}
|
602
|
+
|
603
|
+
/*
|
604
|
+
* Get the number of channels belong to the group.
|
605
|
+
*
|
606
|
+
* @return [Integer]
|
607
|
+
*/
|
608
|
+
static VALUE Group_count(VALUE self)
|
609
|
+
{
|
610
|
+
return INT2NUM(Mix_GroupCount(Group_tag(self)));
|
611
|
+
}
|
612
|
+
|
613
|
+
/*
|
614
|
+
* Return the first available channel in the group.
|
615
|
+
*
|
616
|
+
* Return -1 if no channel is available.
|
617
|
+
*
|
618
|
+
* @return [Integer]
|
619
|
+
*/
|
620
|
+
static VALUE Group_available(VALUE self)
|
621
|
+
{
|
622
|
+
return INT2NUM(Mix_GroupAvailable(Group_tag(self)));
|
623
|
+
}
|
624
|
+
|
625
|
+
/*
|
626
|
+
* Return the oldest cahnnel in the group.
|
627
|
+
*
|
628
|
+
* Return -1 if no channel is available.
|
629
|
+
*
|
630
|
+
* @return [Integer]
|
631
|
+
*/
|
632
|
+
static VALUE Group_oldest(VALUE self)
|
633
|
+
{
|
634
|
+
return INT2NUM(Mix_GroupOldest(Group_tag(self)));
|
635
|
+
}
|
636
|
+
|
637
|
+
/*
|
638
|
+
* Return the newer cahnnel in the group.
|
639
|
+
*
|
640
|
+
* Return -1 if no channel is available.
|
641
|
+
*
|
642
|
+
* @return [Integer]
|
643
|
+
*/
|
644
|
+
static VALUE Group_newer(VALUE self)
|
645
|
+
{
|
646
|
+
return INT2NUM(Mix_GroupNewer(Group_tag(self)));
|
647
|
+
}
|
648
|
+
|
649
|
+
/*
|
650
|
+
* @overload fade_out(ms)
|
651
|
+
* Halt playing of all channels in the group with fade-out effect.
|
652
|
+
*
|
653
|
+
* @param ms [Integer] milliseconds of fade-out effect
|
654
|
+
* @return [Integer] the number of channels affected by this method
|
655
|
+
* @see Channels.fade_out
|
656
|
+
* @see .halt
|
657
|
+
*/
|
658
|
+
static VALUE Group_fade_out(VALUE self, VALUE ms)
|
659
|
+
{
|
660
|
+
return INT2NUM(Mix_FadeOutGroup(Group_tag(self), NUM2INT(ms)));
|
661
|
+
}
|
662
|
+
|
663
|
+
/*
|
664
|
+
* Halt playing of all channels in the group.
|
665
|
+
*
|
666
|
+
* @return [nil]
|
667
|
+
* @see Channels.halt
|
668
|
+
* @see .fade_out
|
669
|
+
*/
|
670
|
+
static VALUE Group_halt(VALUE self)
|
671
|
+
{
|
672
|
+
Mix_HaltGroup(Group_tag(self));
|
673
|
+
return Qnil;
|
674
|
+
}
|
675
|
+
|
676
|
+
/*
|
677
|
+
* Document-module: SDL2::Mixer::MusicChannel
|
678
|
+
*
|
679
|
+
* This module provides the functions to play {SDL2::Mixer::Music}.
|
680
|
+
*/
|
681
|
+
|
682
|
+
/*
|
683
|
+
* @overload play(music, loops)
|
684
|
+
* Play **music** **loops** times.
|
685
|
+
*
|
686
|
+
* @note the meaning of **loop** is different from {SDL2::Mixer::Channels.play}.
|
687
|
+
*
|
688
|
+
* @param music [SDL2::Mixer::Music] music to play
|
689
|
+
* @param loops [Integer] number of times to play the music.
|
690
|
+
* 0 plays the music zero times.
|
691
|
+
* -1 plays the music forever.
|
692
|
+
*
|
693
|
+
* @return [nil]
|
694
|
+
*
|
695
|
+
* @see .fade_in
|
696
|
+
*
|
697
|
+
*/
|
698
|
+
static VALUE MusicChannel_s_play(VALUE self, VALUE music, VALUE loops)
|
699
|
+
{
|
700
|
+
HANDLE_MIX_ERROR(Mix_PlayMusic(Get_Mix_Music(music), NUM2INT(loops)));
|
701
|
+
playing_music = music;
|
702
|
+
return Qnil;
|
703
|
+
}
|
704
|
+
|
705
|
+
/*
|
706
|
+
* @overload fade_in(music, loops, ms, pos=0)
|
707
|
+
* Play **music** **loops** times with fade-in effect.
|
708
|
+
*
|
709
|
+
* @note the meaning of **loop** is different from {SDL2::Mixer::Channels.play}.
|
710
|
+
*
|
711
|
+
* @param music [SDL2::Mixer::Music] music to play
|
712
|
+
* @param loops [Integer] number of times to play the music.
|
713
|
+
* 0 plays the music zero times.
|
714
|
+
* -1 plays the music forever.
|
715
|
+
* @param ms [Integer] milliseconds for the fade-in effect
|
716
|
+
* @param pos [Float] the position to play from.
|
717
|
+
* The meaning of "position" is different for the type of music sources.
|
718
|
+
*
|
719
|
+
* @return [nil]
|
720
|
+
*
|
721
|
+
* @see .play
|
722
|
+
*/
|
723
|
+
static VALUE MusicChannel_s_fade_in(int argc, VALUE* argv, VALUE self)
|
724
|
+
{
|
725
|
+
VALUE music, loops, fade_in_ms, pos;
|
726
|
+
rb_scan_args(argc, argv, "31", &music, &loops, &fade_in_ms, &pos);
|
727
|
+
HANDLE_MIX_ERROR(Mix_FadeInMusicPos(Get_Mix_Music(music), NUM2INT(loops),
|
728
|
+
NUM2INT(fade_in_ms),
|
729
|
+
pos == Qnil ? 0 : NUM2DBL(pos)));
|
730
|
+
playing_music = music;
|
731
|
+
return Qnil;
|
732
|
+
}
|
733
|
+
|
734
|
+
/*
|
735
|
+
* Get the volume of the music channel.
|
736
|
+
*
|
737
|
+
* @return [Integer]
|
738
|
+
*
|
739
|
+
* @see .volume=
|
740
|
+
*/
|
741
|
+
static VALUE MusicChannel_s_volume(VALUE self)
|
742
|
+
{
|
743
|
+
return INT2FIX(Mix_VolumeMusic(-1));
|
744
|
+
}
|
745
|
+
|
746
|
+
/*
|
747
|
+
* @overload volume=(vol)
|
748
|
+
* Set the volume of the music channel.
|
749
|
+
*
|
750
|
+
* @param vol [Integer] the volume for mixing,
|
751
|
+
* from 0 to {SDL2::Mixer::MAX_VOLUME}(128).
|
752
|
+
* @return [vol]
|
753
|
+
*
|
754
|
+
* @see .volume
|
755
|
+
*/
|
756
|
+
static VALUE MusicChannel_s_set_volume(VALUE self, VALUE volume)
|
757
|
+
{
|
758
|
+
Mix_VolumeMusic(NUM2INT(volume));
|
759
|
+
return volume;
|
760
|
+
}
|
761
|
+
|
762
|
+
/*
|
763
|
+
* Pause the playback of the music channel.
|
764
|
+
*
|
765
|
+
* @return [nil]
|
766
|
+
*
|
767
|
+
* @see .resume
|
768
|
+
* @see .pause?
|
769
|
+
*/
|
770
|
+
static VALUE MusicChannel_s_pause(VALUE self)
|
771
|
+
{
|
772
|
+
Mix_PauseMusic(); return Qnil;
|
773
|
+
}
|
774
|
+
|
775
|
+
/*
|
776
|
+
* Resume the playback of the music channel.
|
777
|
+
*
|
778
|
+
* @return [nil]
|
779
|
+
*
|
780
|
+
* @see .pause
|
781
|
+
* @see .pause?
|
782
|
+
*/
|
783
|
+
static VALUE MusicChannel_s_resume(VALUE self)
|
784
|
+
{
|
785
|
+
Mix_ResumeMusic(); return Qnil;
|
786
|
+
}
|
787
|
+
|
788
|
+
/*
|
789
|
+
* Rewind the music to the start.
|
790
|
+
*
|
791
|
+
* @return [nil]
|
792
|
+
*/
|
793
|
+
static VALUE MusicChannel_s_rewind(VALUE self)
|
794
|
+
{
|
795
|
+
Mix_RewindMusic(); return Qnil;
|
796
|
+
}
|
797
|
+
|
798
|
+
/*
|
799
|
+
* @overload set_position(position)
|
800
|
+
* Set the position of the currently playing music.
|
801
|
+
*
|
802
|
+
* @param position [Float] the position to play from.
|
803
|
+
* @return [nil]
|
804
|
+
*/
|
805
|
+
static VALUE MusicChannel_s_set_position(VALUE self, VALUE position)
|
806
|
+
{
|
807
|
+
HANDLE_MIX_ERROR(Mix_SetMusicPosition(NUM2DBL(position)));
|
808
|
+
return Qnil;
|
809
|
+
}
|
810
|
+
|
811
|
+
/*
|
812
|
+
* Halt the music playback.
|
813
|
+
*
|
814
|
+
* @return [nil]
|
815
|
+
*/
|
816
|
+
static VALUE MusicChannel_s_halt(VALUE self)
|
817
|
+
{
|
818
|
+
Mix_HaltMusic(); return Qnil;
|
819
|
+
}
|
820
|
+
|
821
|
+
/*
|
822
|
+
* @overload fade_out(ms)
|
823
|
+
* Halt the music playback with fade-out effect.
|
824
|
+
*
|
825
|
+
* @return [nil]
|
826
|
+
*/
|
827
|
+
static VALUE MusicChannel_s_fade_out(VALUE self, VALUE fade_out_ms)
|
828
|
+
{
|
829
|
+
Mix_FadeOutMusic(NUM2INT(fade_out_ms)); return Qnil;
|
830
|
+
}
|
831
|
+
|
832
|
+
/*
|
833
|
+
* Return true if a music is playing.
|
834
|
+
*/
|
835
|
+
static VALUE MusicChannel_s_play_p(VALUE self)
|
836
|
+
{
|
837
|
+
return INT2BOOL(Mix_PlayingMusic());
|
838
|
+
}
|
839
|
+
|
840
|
+
/*
|
841
|
+
* Return true if a music playback is paused.
|
842
|
+
*/
|
843
|
+
static VALUE MusicChannel_s_pause_p(VALUE self)
|
844
|
+
{
|
845
|
+
return INT2BOOL(Mix_PausedMusic());
|
846
|
+
}
|
847
|
+
|
848
|
+
/*
|
849
|
+
* Get the fading state of the music playback.
|
850
|
+
*
|
851
|
+
* The return value is one of the following:
|
852
|
+
*
|
853
|
+
* * {SDL2::Mixer::NO_FADING} - not fading in, and fading out
|
854
|
+
* * {SDL2::Mixer::FADING_IN} - fading in
|
855
|
+
* * {SDL2::Mixer::FADING_OUT} - fading out
|
856
|
+
*
|
857
|
+
* @return [Integer]
|
858
|
+
*
|
859
|
+
* @see .fade_in
|
860
|
+
* @see .fade_out
|
861
|
+
*
|
862
|
+
*/
|
863
|
+
static VALUE MusicChannel_s_fading(VALUE self)
|
864
|
+
{
|
865
|
+
return INT2NUM(Mix_FadingMusic());
|
866
|
+
}
|
867
|
+
|
868
|
+
/*
|
869
|
+
* Get the {SDL2::Mixer::Music} object that most recently played.
|
870
|
+
*
|
871
|
+
* Return nil if no music object is played yet.
|
872
|
+
*
|
873
|
+
* @return [SDL2::Mixer::Music,nil]
|
874
|
+
*/
|
875
|
+
static VALUE MusicChannel_s_playing_music(VALUE self)
|
876
|
+
{
|
877
|
+
return playing_music;
|
878
|
+
}
|
879
|
+
|
880
|
+
/*
|
881
|
+
* Document-class: SDL2::Mixer::Chunk
|
882
|
+
*
|
883
|
+
* This class represents a sound sample, a kind of sound sources.
|
884
|
+
*
|
885
|
+
* Chunk objects is playable on {SDL2::Mixer::Channels}.
|
886
|
+
*
|
887
|
+
* @!method destroy?
|
888
|
+
* Return true if the memory is deallocated by {#destroy}.
|
889
|
+
*/
|
890
|
+
|
891
|
+
/*
|
892
|
+
* @overload load(path)
|
893
|
+
* Load a sample from file.
|
894
|
+
*
|
895
|
+
* This can load WAVE, AIFF, RIFF, OGG, and VOC files.
|
896
|
+
*
|
897
|
+
* @note {SDL2::Mixer.open} must be called before calling this method.
|
898
|
+
*
|
899
|
+
* @param path [String] the fine name
|
900
|
+
* @return [SDL2::Mixer::Chunk]
|
901
|
+
*
|
902
|
+
* @raise [SDL2::Error] raised when failing to load
|
903
|
+
*/
|
904
|
+
static VALUE Chunk_s_load(VALUE self, VALUE fname)
|
905
|
+
{
|
906
|
+
Mix_Chunk* chunk = Mix_LoadWAV(StringValueCStr(fname));
|
907
|
+
VALUE c;
|
908
|
+
if (!chunk)
|
909
|
+
MIX_ERROR();
|
910
|
+
c = Chunk_new(chunk);
|
911
|
+
rb_iv_set(c, "@filename", fname);
|
912
|
+
return c;
|
913
|
+
}
|
914
|
+
|
915
|
+
/*
|
916
|
+
* Get the names of the sample decoders.
|
917
|
+
*
|
918
|
+
* @return [Array<String>] the names of decoders, such as: "WAVE", "OGG", etc.
|
919
|
+
*/
|
920
|
+
static VALUE Chunk_s_decoders(VALUE self)
|
921
|
+
{
|
922
|
+
int i;
|
923
|
+
int num_decoders = Mix_GetNumChunkDecoders();
|
924
|
+
VALUE ary = rb_ary_new();
|
925
|
+
for (i=0; i < num_decoders; ++i)
|
926
|
+
rb_ary_push(ary, rb_usascii_str_new_cstr(Mix_GetChunkDecoder(i)));
|
927
|
+
return ary;
|
928
|
+
}
|
929
|
+
|
930
|
+
/*
|
931
|
+
* Deallocate the sample memory.
|
932
|
+
*
|
933
|
+
* Normally, the memory is deallocated by ruby's GC, but
|
934
|
+
* you can surely deallocate the memory with this method at any time.
|
935
|
+
*
|
936
|
+
* @return [nil]
|
937
|
+
*/
|
938
|
+
static VALUE Chunk_destroy(VALUE self)
|
939
|
+
{
|
940
|
+
Chunk* c = Get_Chunk(self);
|
941
|
+
if (c->chunk) Mix_FreeChunk(c->chunk);
|
942
|
+
c->chunk = NULL;
|
943
|
+
return Qnil;
|
944
|
+
}
|
945
|
+
|
946
|
+
/*
|
947
|
+
* Get the volume of the sample.
|
948
|
+
*
|
949
|
+
* @return [Integer] the volume from 0 to {SDL2::Mixer::MAX_VOLUME}.
|
950
|
+
*
|
951
|
+
* @see #volume=
|
952
|
+
*/
|
953
|
+
static VALUE Chunk_volume(VALUE self)
|
954
|
+
{
|
955
|
+
return INT2NUM(Mix_VolumeChunk(Get_Mix_Chunk(self), -1));
|
956
|
+
}
|
957
|
+
|
958
|
+
/*
|
959
|
+
* @overload volume=(vol)
|
960
|
+
* Set the volume of the sample.
|
961
|
+
*
|
962
|
+
* @param vol [Integer] the new volume
|
963
|
+
* @return [vol]
|
964
|
+
*
|
965
|
+
* @see #volume
|
966
|
+
*/
|
967
|
+
static VALUE Chunk_set_volume(VALUE self, VALUE vol)
|
968
|
+
{
|
969
|
+
return INT2NUM(Mix_VolumeChunk(Get_Mix_Chunk(self), NUM2INT(vol)));
|
970
|
+
}
|
971
|
+
|
972
|
+
/* @return [String] inspection string */
|
973
|
+
static VALUE Chunk_inspect(VALUE self)
|
974
|
+
{
|
975
|
+
VALUE filename = rb_iv_get(self, "@filename");
|
976
|
+
if (RTEST(Chunk_destroy_p(self)))
|
977
|
+
return rb_sprintf("<%s: destroyed>", rb_obj_classname(self));
|
978
|
+
|
979
|
+
return rb_sprintf("<%s: filename=\"%s\" volume=%d>",
|
980
|
+
rb_obj_classname(self),
|
981
|
+
StringValueCStr(filename),
|
982
|
+
Mix_VolumeChunk(Get_Mix_Chunk(self), -1));
|
983
|
+
}
|
984
|
+
|
985
|
+
/*
|
986
|
+
* Document-class: SDL2::Mixer::Music
|
987
|
+
*
|
988
|
+
* This class represents music, a kind of sound sources.
|
989
|
+
*
|
990
|
+
* Music is playable on {SDL2::Mixer::MusicChannel}, not on {SDL2::Mixer::Channels}.
|
991
|
+
*
|
992
|
+
* @!method destroy?
|
993
|
+
* Return true if the memory is deallocated by {#destroy}.
|
994
|
+
*/
|
995
|
+
|
996
|
+
/*
|
997
|
+
* Get the names of music decoders.
|
998
|
+
*
|
999
|
+
* @return [Array<String>] the names of decorders (supported sound formats),
|
1000
|
+
* such as: "OGG", "WAVE", "MP3"
|
1001
|
+
*/
|
1002
|
+
static VALUE Music_s_decoders(VALUE self)
|
1003
|
+
{
|
1004
|
+
int num_decoders = Mix_GetNumMusicDecoders();
|
1005
|
+
int i;
|
1006
|
+
VALUE decoders = rb_ary_new2(num_decoders);
|
1007
|
+
for (i=0; i<num_decoders; ++i)
|
1008
|
+
rb_ary_push(decoders, utf8str_new_cstr(Mix_GetMusicDecoder(i)));
|
1009
|
+
return decoders;
|
1010
|
+
}
|
1011
|
+
|
1012
|
+
/*
|
1013
|
+
* @overload load(path)
|
1014
|
+
* Load a music from file.
|
1015
|
+
*
|
1016
|
+
* @param path [String] the file path
|
1017
|
+
* @return [SDL2::Mixer::Music]
|
1018
|
+
*
|
1019
|
+
* @raise [SDL2::Error] raised when failing to load.
|
1020
|
+
*/
|
1021
|
+
static VALUE Music_s_load(VALUE self, VALUE fname)
|
1022
|
+
{
|
1023
|
+
Mix_Music* music = Mix_LoadMUS(StringValueCStr(fname));
|
1024
|
+
VALUE mus;
|
1025
|
+
if (!music) MIX_ERROR();
|
1026
|
+
mus = Music_new(music);
|
1027
|
+
rb_iv_set(mus, "@filename", fname);
|
1028
|
+
return mus;
|
1029
|
+
}
|
1030
|
+
|
1031
|
+
/*
|
1032
|
+
* Deallocate the music memory.
|
1033
|
+
*
|
1034
|
+
* Normally, the memory is deallocated by ruby's GC, but
|
1035
|
+
* you can surely deallocate the memory with this method at any time.
|
1036
|
+
*
|
1037
|
+
* @return [nil]
|
1038
|
+
*/
|
1039
|
+
static VALUE Music_destroy(VALUE self)
|
1040
|
+
{
|
1041
|
+
Music* c = Get_Music(self);
|
1042
|
+
if (c) Mix_FreeMusic(c->music);
|
1043
|
+
c->music = NULL;
|
1044
|
+
return Qnil;
|
1045
|
+
}
|
1046
|
+
|
1047
|
+
/* @return [String] inspection string */
|
1048
|
+
static VALUE Music_inspect(VALUE self)
|
1049
|
+
{
|
1050
|
+
VALUE filename = rb_iv_get(self, "@filename");
|
1051
|
+
if (RTEST(Music_destroy_p(self)))
|
1052
|
+
return rb_sprintf("<%s: destroyed>", rb_obj_classname(self));
|
1053
|
+
|
1054
|
+
return rb_sprintf("<%s: filename=\"%s\" type=%d>",
|
1055
|
+
rb_obj_classname(self), StringValueCStr(filename),
|
1056
|
+
Mix_GetMusicType(Get_Mix_Music(self)));
|
1057
|
+
}
|
1058
|
+
|
1059
|
+
|
1060
|
+
void rubysdl2_init_mixer(void)
|
1061
|
+
{
|
1062
|
+
mMixer = rb_define_module_under(mSDL2, "Mixer");
|
1063
|
+
|
1064
|
+
rb_define_module_function(mMixer, "init", Mixer_s_init, 1);
|
1065
|
+
rb_define_module_function(mMixer, "open", Mixer_s_open, -1);
|
1066
|
+
rb_define_module_function(mMixer, "close", Mixer_s_close, 0);
|
1067
|
+
rb_define_module_function(mMixer, "query", Mixer_s_query, 0);
|
1068
|
+
|
1069
|
+
/* define(`DEFINE_MIX_INIT',`rb_define_const(mMixer, "INIT_$1", UINT2NUM(MIX_INIT_$1))') */
|
1070
|
+
/* Initialize Ogg flac loader */
|
1071
|
+
DEFINE_MIX_INIT(FLAC);
|
1072
|
+
/* Initialize MOD loader */
|
1073
|
+
DEFINE_MIX_INIT(MOD);
|
1074
|
+
/* Initialize libmodplug */
|
1075
|
+
DEFINE_MIX_INIT(MODPLUG);
|
1076
|
+
/* Initialize MP3 loader */
|
1077
|
+
DEFINE_MIX_INIT(MP3);
|
1078
|
+
/* Initialize Ogg vorbis loader */
|
1079
|
+
DEFINE_MIX_INIT(OGG);
|
1080
|
+
/* Initialize fluidsynth */
|
1081
|
+
DEFINE_MIX_INIT(FLUIDSYNTH);
|
1082
|
+
|
1083
|
+
/* define(`DEFINE_MIX_FORMAT',`rb_define_const(mMixer, "FORMAT_$1", UINT2NUM(AUDIO_$1))') */
|
1084
|
+
/* Unsiged 8-bit sample format. Used by {Mixer.open} */
|
1085
|
+
DEFINE_MIX_FORMAT(U8);
|
1086
|
+
/* Siged 8-bit sample format. Used by {Mixer.open} */
|
1087
|
+
DEFINE_MIX_FORMAT(S8);
|
1088
|
+
/* Unsiged 16-bit little-endian sample format. Used by {Mixer.open} */
|
1089
|
+
DEFINE_MIX_FORMAT(U16LSB);
|
1090
|
+
/* Siged 16-bit little-endian sample format. Used by {Mixer.open} */
|
1091
|
+
DEFINE_MIX_FORMAT(S16LSB);
|
1092
|
+
/* Unsiged 16-bit big-endian sample format. Used by {Mixer.open} */
|
1093
|
+
DEFINE_MIX_FORMAT(U16MSB);
|
1094
|
+
/* Unsiged 16-bit big-endian sample format. Used by {Mixer.open} */
|
1095
|
+
DEFINE_MIX_FORMAT(S16MSB);
|
1096
|
+
/* Unsiged 16-bit sample format. Endian is same as system byte order. Used by {Mixer.open} */
|
1097
|
+
DEFINE_MIX_FORMAT(U16SYS);
|
1098
|
+
/* Siged 16-bit sample format. Endian is same as system byte order. Used by {Mixer.open} */
|
1099
|
+
DEFINE_MIX_FORMAT(S16SYS);
|
1100
|
+
/* Default frequency. 22050 (Hz) */
|
1101
|
+
rb_define_const(mMixer, "DEFAULT_FREQUENCY", UINT2NUM(MIX_DEFAULT_FREQUENCY));
|
1102
|
+
/* Default sample format. Same as {Mixer::FORMAT_S16SYS}. */
|
1103
|
+
rb_define_const(mMixer, "DEFAULT_FORMAT", UINT2NUM(MIX_DEFAULT_FORMAT));
|
1104
|
+
/* Default number of channels. 2. */
|
1105
|
+
rb_define_const(mMixer, "DEFAULT_CHANNELS", INT2FIX(MIX_DEFAULT_CHANNELS));
|
1106
|
+
/* Max volume value. 128. */
|
1107
|
+
rb_define_const(mMixer, "MAX_VOLUME", INT2FIX(MIX_MAX_VOLUME));
|
1108
|
+
/* This constants represents that the channel is not fading in and fading out. */
|
1109
|
+
rb_define_const(mMixer, "NO_FADING", INT2FIX(MIX_NO_FADING));
|
1110
|
+
/* This constants represents that the channel is fading out. */
|
1111
|
+
rb_define_const(mMixer, "FADING_OUT", INT2FIX(MIX_FADING_OUT));
|
1112
|
+
/* This constants represents that the channel is fading in. */
|
1113
|
+
rb_define_const(mMixer, "FADING_IN", INT2FIX(MIX_FADING_IN));
|
1114
|
+
|
1115
|
+
|
1116
|
+
cChunk = rb_define_class_under(mMixer, "Chunk", rb_cObject);
|
1117
|
+
rb_undef_alloc_func(cChunk);
|
1118
|
+
rb_define_singleton_method(cChunk, "load", Chunk_s_load, 1);
|
1119
|
+
rb_define_singleton_method(cChunk, "decoders", Chunk_s_decoders, 0);
|
1120
|
+
rb_define_method(cChunk, "destroy", Chunk_destroy, 0);
|
1121
|
+
rb_define_method(cChunk, "destroy?", Chunk_destroy_p, 0);
|
1122
|
+
rb_define_method(cChunk, "volume", Chunk_volume, 0);
|
1123
|
+
rb_define_method(cChunk, "volume=", Chunk_set_volume, 1);
|
1124
|
+
rb_define_method(cChunk, "inspect", Chunk_inspect, 0);
|
1125
|
+
/* @return [String] The file name of the file from which the sound is loaded. */
|
1126
|
+
rb_define_attr(cChunk, "filename", 1, 0);
|
1127
|
+
|
1128
|
+
|
1129
|
+
cMusic = rb_define_class_under(mMixer, "Music", rb_cObject);
|
1130
|
+
rb_undef_alloc_func(cMusic);
|
1131
|
+
rb_define_singleton_method(cMusic, "decoders", Music_s_decoders, 0);
|
1132
|
+
rb_define_singleton_method(cMusic, "load", Music_s_load, 1);
|
1133
|
+
rb_define_method(cMusic, "destroy", Music_destroy, 0);
|
1134
|
+
rb_define_method(cMusic, "destroy?", Music_destroy_p, 0);
|
1135
|
+
rb_define_method(cMusic, "inspect", Music_inspect, 0);
|
1136
|
+
|
1137
|
+
|
1138
|
+
mChannels = rb_define_module_under(mMixer, "Channels");
|
1139
|
+
rb_define_module_function(mChannels, "allocate", Channels_s_allocate, 1);
|
1140
|
+
rb_define_module_function(mChannels, "reserve", Channels_s_reserve, 1);
|
1141
|
+
rb_define_module_function(mChannels, "volume", Channels_s_volume, 1);
|
1142
|
+
rb_define_module_function(mChannels, "set_volume", Channels_s_set_volume, 2);
|
1143
|
+
rb_define_module_function(mChannels, "play", Channels_s_play, -1);
|
1144
|
+
rb_define_module_function(mChannels, "fade_in", Channels_s_fade_in, -1);
|
1145
|
+
rb_define_module_function(mChannels, "pause", Channels_s_pause, 1);
|
1146
|
+
rb_define_module_function(mChannels, "resume", Channels_s_resume, 1);
|
1147
|
+
rb_define_module_function(mChannels, "halt", Channels_s_halt, 1);
|
1148
|
+
rb_define_module_function(mChannels, "expire", Channels_s_expire, 1);
|
1149
|
+
rb_define_module_function(mChannels, "fade_out", Channels_s_fade_out, 2);
|
1150
|
+
rb_define_module_function(mChannels, "play?", Channels_s_play_p, 1);
|
1151
|
+
rb_define_module_function(mChannels, "pause?", Channels_s_pause_p, 1);
|
1152
|
+
rb_define_module_function(mChannels, "fading", Channels_s_fading, 1);
|
1153
|
+
rb_define_module_function(mChannels, "playing_chunk", Channels_s_playing_chunk, 1);
|
1154
|
+
|
1155
|
+
|
1156
|
+
cGroup = rb_define_class_under(mChannels, "Group", rb_cObject);
|
1157
|
+
rb_define_method(cGroup, "initialize", Group_initialize, 1);
|
1158
|
+
rb_define_singleton_method(cGroup, "default", Group_s_default, 0);
|
1159
|
+
/* @return [Integer] tag id */
|
1160
|
+
rb_define_attr(cGroup, "tag", 1, 0);
|
1161
|
+
rb_define_method(cGroup, "==", Group_eq, 1);
|
1162
|
+
rb_define_method(cGroup, "add", Group_add, 1);
|
1163
|
+
rb_define_method(cGroup, "count", Group_count, 0);
|
1164
|
+
rb_define_method(cGroup, "available", Group_available, 0);
|
1165
|
+
rb_define_method(cGroup, "newer", Group_newer, 0);
|
1166
|
+
rb_define_method(cGroup, "oldest", Group_oldest, 0);
|
1167
|
+
rb_define_method(cGroup, "fade_out", Group_fade_out, 1);
|
1168
|
+
rb_define_method(cGroup, "halt", Group_halt, 0);
|
1169
|
+
|
1170
|
+
|
1171
|
+
mMusicChannel = rb_define_module_under(mMixer, "MusicChannel");
|
1172
|
+
rb_define_module_function(mMusicChannel, "play", MusicChannel_s_play, 2);
|
1173
|
+
rb_define_module_function(mMusicChannel, "fade_in", MusicChannel_s_fade_in, -1);
|
1174
|
+
rb_define_module_function(mMusicChannel, "volume", MusicChannel_s_volume, 0);
|
1175
|
+
rb_define_module_function(mMusicChannel, "volume=", MusicChannel_s_set_volume, 1);
|
1176
|
+
rb_define_module_function(mMusicChannel, "pause", MusicChannel_s_pause, 0);
|
1177
|
+
rb_define_module_function(mMusicChannel, "resume", MusicChannel_s_resume, 0);
|
1178
|
+
rb_define_module_function(mMusicChannel, "rewind", MusicChannel_s_rewind, 0);
|
1179
|
+
rb_define_module_function(mMusicChannel, "set_position", MusicChannel_s_set_position, 1);
|
1180
|
+
rb_define_module_function(mMusicChannel, "halt", MusicChannel_s_halt, 0);
|
1181
|
+
rb_define_module_function(mMusicChannel, "fade_out", MusicChannel_s_fade_out, 1);
|
1182
|
+
rb_define_module_function(mMusicChannel, "play?", MusicChannel_s_play_p, 0);
|
1183
|
+
rb_define_module_function(mMusicChannel, "pause?", MusicChannel_s_pause_p, 0);
|
1184
|
+
rb_define_module_function(mMusicChannel, "fading", MusicChannel_s_fading, 0);
|
1185
|
+
rb_define_module_function(mMusicChannel, "playing_music", MusicChannel_s_playing_music, 0);
|
1186
|
+
|
1187
|
+
|
1188
|
+
rb_gc_register_address(&playing_chunks);
|
1189
|
+
rb_gc_register_address(&playing_music);
|
1190
|
+
}
|
1191
|
+
|
1192
|
+
#else /* HAVE_SDL_MIXER_H */
|
1193
|
+
void rubysdl2_init_mixer(void)
|
1194
|
+
{
|
1195
|
+
}
|
1196
|
+
#endif
|