• R/O
  • SSH
  • HTTPS

qrobosdk: コミット


コミットメタ情報

リビジョン1961 (tree)
日時2011-08-07 20:34:40
作者satofumi

ログメッセージ

fixed volume implementation.

変更サマリ

差分

--- trunk/libs/lua/luabindAudio.cpp (revision 1960)
+++ trunk/libs/lua/luabindAudio.cpp (revision 1961)
@@ -40,6 +40,7 @@
4040 .def("setMasterVolume", &SoundEffect::setMasterVolume)
4141 .def("setVolume", &SoundEffect::setVolume)
4242 .def("play", &SoundEffect::play)
43+ .def("stop", &SoundEffect::stop)
4344 .def("updatePosition", &SoundEffect::updatePosition)
4445 .def("isPlaying", &SoundEffect::isPlaying)
4546 ];
--- trunk/libs/gui/Font.cpp (revision 1960)
+++ trunk/libs/gui/Font.cpp (revision 1961)
@@ -37,7 +37,7 @@
3737 : ttf_font_(TTF_OpenFont(font_file, static_cast<int>(font_size))),
3838 error_message_("no error")
3939 {
40- if (! ttf_font_) {
40+ if (!ttf_font_) {
4141 error_message_ = TTF_GetError();
4242 //log_printf("%s\n", error_message_.c_str());
4343 }
@@ -86,7 +86,7 @@
8686 string key = string(buffer) + file_name;
8787
8888 FontMap::iterator it = ttf_fonts_.find(key);
89- if ((it != ttf_fonts_.end()) && (! it->second.expired())) {
89+ if ((it != ttf_fonts_.end()) && !it->second.expired()) {
9090 // 見つかれば、その資源を返す
9191 return shared_ptr<TtfFont>(it->second);
9292 }
@@ -131,7 +131,7 @@
131131 {
132132 // DefaultSize のフォントを生成し、フォントリソースが有効かを確認する
133133 pimpl->is_valid_ = (resource()) ? true : false;
134- if (! pimpl->is_valid_) {
134+ if (!pimpl->is_valid_) {
135135 pimpl->error_message_ = pimpl->resource_->what();
136136 }
137137 }
--- trunk/libs/audio/sdl_mixer/BackMusic.cpp (revision 1960)
+++ trunk/libs/audio/sdl_mixer/BackMusic.cpp (revision 1961)
@@ -8,6 +8,7 @@
88 */
99
1010 #include "BackMusic.h"
11+#include "Audio.h"
1112 #include <SDL_mixer.h>
1213 #include <map>
1314 #include <string>
@@ -22,12 +23,17 @@
2223 {
2324 typedef map<string, Mix_Music*> Musics;
2425
25- bool is_playing_;
26+ static Mix_Music* next_music_;
27+ static int next_fade_in_msec_;
28+ static int next_play_times_;
29+
30+ Audio audio_;
2631 Musics musics_;
2732
2833
29- pImpl(void) : is_playing_(false)
34+ pImpl(void)
3035 {
36+ Mix_HookMusicFinished(music_finished_callback);
3137 }
3238
3339
@@ -47,6 +53,36 @@
4753 }
4854
4955
56+ static void set_next_music(Mix_Music* music,
57+ int fade_in_msec, int play_times)
58+ {
59+ next_music_ = music;
60+ next_fade_in_msec_ = fade_in_msec;
61+ next_play_times_ = play_times;
62+ }
63+
64+
65+ static void music_finished_callback(void)
66+ {
67+ // 次の音楽が登録されているならば、再生を開始する
68+ if (next_music_) {
69+ play_music(next_music_, next_fade_in_msec_, next_play_times_);
70+ next_music_ = NULL;
71+ }
72+ }
73+
74+
75+ static bool play_music(Mix_Music* music, int fade_in_msec, int play_times)
76+ {
77+ int ret = Mix_FadeInMusic(music, play_times, fade_in_msec);
78+ if (ret == -1) {
79+ return false;
80+ } else {
81+ return true;
82+ }
83+ }
84+
85+
5086 Mix_Music* find_music(const char* file_path)
5187 {
5288 // Load に失敗した場合には musics_ に NULL を格納し、
@@ -68,7 +104,11 @@
68104 }
69105 };
70106
107+Mix_Music* BackMusic::pImpl::next_music_ = NULL;
108+int BackMusic::pImpl::next_fade_in_msec_ = 0;
109+int BackMusic::pImpl::next_play_times_ = 0;
71110
111+
72112 BackMusic::BackMusic(void) : pimpl(pImpl::object())
73113 {
74114 }
@@ -81,6 +121,10 @@
81121
82122 void BackMusic::free_music_resource(const char* file_path)
83123 {
124+ if (!pimpl->audio_.isInitialized()) {
125+ return;
126+ }
127+
84128 Mix_Music* music = pimpl->find_music(file_path);
85129 if (music) {
86130 Mix_FreeMusic(music);
@@ -91,9 +135,11 @@
91135
92136 void BackMusic::setVolume(size_t percent)
93137 {
94- fprintf(stderr, "BackMusic::setVolume: %d\n", percent);
138+ if (!pimpl->audio_.isInitialized()) {
139+ return;
140+ }
95141
96- int mix_volume = static_cast<int>(MIX_MAX_VOLUME * 100.0 / percent);
142+ int mix_volume = static_cast<int>(MIX_MAX_VOLUME * percent / 100.0);
97143 Mix_VolumeMusic(mix_volume);
98144 }
99145
@@ -101,39 +147,38 @@
101147 bool BackMusic::play(const char* file_path, int fade_in_msec,
102148 int play_times, int fade_out_msec)
103149 {
104- fprintf(stderr, "play %s\n", file_path);
105-
106- Mix_Music* music = pimpl->find_music(file_path);
107- if (!music) {
150+ if (!pimpl->audio_.isInitialized()) {
108151 return false;
109152 }
110153
111- // !!! 現在再生中の music の fade out を待ってから、
112- // !!! 指定された music を再生するように実装を変更する
113- (void)fade_out_msec;
154+ Mix_Music* music = pimpl->find_music(file_path);
114155
115- int ret = Mix_FadeInMusic(music, play_times, fade_in_msec);
116- if (ret == -1) {
117- return false;
156+ if (isPlaying()) {
157+ // 再生中の曲の fade out を待ってから次の曲の再生を開始させる
158+ pImpl::set_next_music(music, fade_in_msec, play_times);
159+ stop(fade_out_msec);
160+ return (music) ? true : false;
161+
162+ } else {
163+ return pImpl::play_music(music, fade_in_msec, play_times);
118164 }
119-
120- pimpl->is_playing_ = true;
121- return true;
122165 }
123166
124167
125168 void BackMusic::stop(int fade_out_msec)
126169 {
127- fprintf(stderr, "stop\n");
128-
170+ if (!pimpl->audio_.isInitialized()) {
171+ return;
172+ }
129173 Mix_FadeOutMusic(fade_out_msec);
130- pimpl->is_playing_ = false;
131174 }
132175
133176
134177 bool BackMusic::isPlaying(void) const
135178 {
136- // !!! 終了を監視するスレッドにて is_playing_ フラグを監視する
179+ if (!pimpl->audio_.isInitialized()) {
180+ return false;
181+ }
137182
138- return pimpl->is_playing_;
183+ return (Mix_PlayingMusic() == 0) ? false : true;
139184 }
--- trunk/libs/audio/sdl_mixer/samples/BackMusicSample.cpp (nonexistent)
+++ trunk/libs/audio/sdl_mixer/samples/BackMusicSample.cpp (revision 1961)
@@ -0,0 +1,21 @@
1+/*!
2+ \file
3+ \brief BackMusic の利用サンプル
4+
5+ \author Satofumi KAMIMURA
6+
7+ $Id$
8+*/
9+
10+#include "BackMusic.h"
11+
12+
13+int main(int argc, char *argv[])
14+{
15+ (void)argc;
16+ (void)argv;
17+
18+ // !!!
19+
20+ return 0;
21+}
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
--- trunk/libs/audio/sdl_mixer/samples/SoundEffectSample.cpp (revision 1960)
+++ trunk/libs/audio/sdl_mixer/samples/SoundEffectSample.cpp (revision 1961)
@@ -19,23 +19,23 @@
1919
2020 int main(int argc, char *argv[])
2121 {
22- const char* play_file = "effect.wav";
23- if (argc >= 2) {
24- play_file = argv[1];
25- }
22+ const char* play_file = "effect.wav";
23+ if (argc >= 2) {
24+ play_file = argv[1];
25+ }
2626
27- Audio audio;
28- if (! audio.initialize()) {
29- cout << audio.what() << endl;
30- exit(1);
31- }
27+ Audio audio;
28+ if (! audio.initialize()) {
29+ cout << audio.what() << endl;
30+ exit(1);
31+ }
3232
33- SoundEffect sound_effect(play_file);
34- sound_effect.play();
33+ SoundEffect sound_effect(play_file);
34+ sound_effect.play();
3535
36- while (sound_effect.isPlaying()) {
37- delay(100);
38- }
36+ while (sound_effect.isPlaying()) {
37+ delay(100);
38+ }
3939
40- return 0;
40+ return 0;
4141 }
--- trunk/libs/audio/sdl_mixer/samples/SdlMixerSample.cpp (revision 1960)
+++ trunk/libs/audio/sdl_mixer/samples/SdlMixerSample.cpp (revision 1961)
@@ -18,57 +18,57 @@
1818
1919 namespace
2020 {
21- bool initializeAudio(void)
22- {
23- if (SDL_Init(SDL_INIT_AUDIO) < 0) {
24- return false;
25- }
26- atexit(SDL_Quit);
21+ bool initializeAudio(void)
22+ {
23+ if (SDL_Init(SDL_INIT_AUDIO) < 0) {
24+ return false;
25+ }
26+ atexit(SDL_Quit);
2727
28- if (Mix_OpenAudio(MIX_DEFAULT_FREQUENCY,
29- MIX_DEFAULT_FORMAT, MIX_DEFAULT_CHANNELS, 1024) < 0) {
30- return false;
31- }
32- atexit(Mix_CloseAudio);
28+ if (Mix_OpenAudio(MIX_DEFAULT_FREQUENCY,
29+ MIX_DEFAULT_FORMAT, MIX_DEFAULT_CHANNELS, 1024) < 0) {
30+ return false;
31+ }
32+ atexit(Mix_CloseAudio);
3333
34- enum { ChannelSize = 8 };
35- Mix_AllocateChannels(ChannelSize);
36- // cleanup 時に Mix_AllocateChannels(0) を呼び出してクリアすべき
34+ enum { ChannelSize = 8 };
35+ Mix_AllocateChannels(ChannelSize);
36+ // cleanup 時に Mix_AllocateChannels(0) を呼び出してクリアすべき
3737
38- return true;
39- }
38+ return true;
39+ }
4040 }
4141
4242
4343 int main(int argc, char *argv[])
4444 {
45- static_cast<void>(argc);
46- static_cast<void>(argv);
45+ static_cast<void>(argc);
46+ static_cast<void>(argv);
4747
48- if (! initializeAudio()) {
49- cout << "Audio initialize: " << Mix_GetError() << endl;
50- }
48+ if (! initializeAudio()) {
49+ cout << "Audio initialize: " << Mix_GetError() << endl;
50+ }
5151
52- // 音楽の再生
53- // const char music_file[] = "music.mp3";
54- // !!!
52+ // 音楽の再生
53+ // const char music_file[] = "music.mp3";
54+ // !!!
5555
56- // 効果音の再生
57- // effect.wav というファイルを再生させる
58- const char effect_file[] = "effect.wav";
59- Mix_Chunk* chunk = Mix_LoadWAV(effect_file);
60- if (! chunk) {
61- cout << "Mix_LoadWAV: " << Mix_GetError() << endl;
62- exit(1);
63- }
56+ // 効果音の再生
57+ // effect.wav というファイルを再生させる
58+ const char effect_file[] = "effect.wav";
59+ Mix_Chunk* chunk = Mix_LoadWAV(effect_file);
60+ if (! chunk) {
61+ cout << "Mix_LoadWAV: " << Mix_GetError() << endl;
62+ exit(1);
63+ }
6464
65- int channel_id = Mix_PlayChannel(-1, chunk, 0);
65+ int channel_id = Mix_PlayChannel(-1, chunk, 0);
6666
67- // 効果音の再生が終わるまで待つ
68- do {
69- delay(100);
70- } while (Mix_Playing(channel_id));
67+ // 効果音の再生が終わるまで待つ
68+ do {
69+ delay(100);
70+ } while (Mix_Playing(channel_id));
7171
72- Mix_FreeChunk(chunk);
73- return 0;
72+ Mix_FreeChunk(chunk);
73+ return 0;
7474 }
--- trunk/libs/audio/sdl_mixer/samples/Makefile (revision 1960)
+++ trunk/libs/audio/sdl_mixer/samples/Makefile (revision 1961)
@@ -12,6 +12,7 @@
1212 TARGET = \
1313 SdlMixerSample \
1414 SoundEffectSample \
15+ BackMusicSample \
1516
1617 all : $(TARGET)
1718
--- trunk/libs/audio/sdl_mixer/SoundEffect.cpp (revision 1960)
+++ trunk/libs/audio/sdl_mixer/SoundEffect.cpp (revision 1961)
@@ -10,9 +10,13 @@
1010 #include "SoundEffect.h"
1111 #include "Audio.h"
1212 #include <SDL_mixer.h>
13+#include <boost/shared_ptr.hpp>
14+#include <boost/weak_ptr.hpp>
1315 #include <map>
16+#include <string>
1417
1518 using namespace qrk;
19+using namespace boost;
1620 using namespace std;
1721
1822
@@ -19,6 +23,7 @@
1923 namespace
2024 {
2125 typedef map<int, int*> Channels;
26+ typedef map<string, weak_ptr<Mix_Chunk> > ChunkMap;
2227 }
2328
2429
@@ -31,22 +36,25 @@
3136 {
3237 static bool initialized_;
3338 static Channels channels_;
39+ static size_t master_percent_;
40+ static ChunkMap mix_chunks_;
41+
3442 Audio audio_;
3543 int channel_id_;
36- Mix_Chunk* chunk_;
44+ int first_mix_volume_;
45+ size_t percent_;
46+ shared_ptr<Mix_Chunk> chunk_;
3747
38- size_t master_percent_;
3948
40-
4149 pImpl(const char* play_file)
42- : channel_id_(-1), chunk_(Mix_LoadWAV(play_file)),
43- master_percent_(DefaultVolumePercent)
50+ : channel_id_(-1), percent_(100),
51+ chunk_(load_mix_chunk(play_file))
4452 {
45- if (! initialized_) {
53+ if (!initialized_) {
4654 Mix_ChannelFinished(finished);
4755 initialized_ = true;
4856 }
49- fprintf(stderr, "SoundEffect:play_file: %s)\n", play_file);
57+ update_volume();
5058 }
5159
5260
@@ -55,13 +63,30 @@
5563 if (channel_id_ > 0) {
5664 finished(channel_id_);
5765 }
58- delete chunk_;
5966 }
6067
6168
69+ shared_ptr<Mix_Chunk> load_mix_chunk(const char* play_file)
70+ {
71+ ChunkMap::iterator it = mix_chunks_.find(play_file);
72+ if ((it != mix_chunks_.end()) && !it->second.expired()) {
73+ // 見つかれば、その資源を返す
74+ return shared_ptr<Mix_Chunk>(it->second);
75+ }
76+
77+ // 見つからなければ、新規に作成して返す
78+ shared_ptr<Mix_Chunk> chunk(Mix_LoadWAV(play_file));
79+ mix_chunks_[play_file] = chunk;
80+ return chunk;
81+ }
82+
83+
6284 void play(void)
6385 {
64- channel_id_ = Mix_PlayChannel(-1, chunk_, 0);
86+ channel_id_ = Mix_PlayChannel(-1, chunk_.get(), 0);
87+ update_volume();
88+ Mix_Volume(channel_id_, first_mix_volume_);
89+
6590 if (channel_id_ > 0) {
6691 channels_[channel_id_] = &channel_id_;
6792 }
@@ -82,10 +107,24 @@
82107 {
83108 channels_.erase(channel_id);
84109 }
110+
111+
112+ void update_volume(void)
113+ {
114+ int mix_volume = static_cast<int>(MIX_MAX_VOLUME *
115+ (percent_ / 100.0) *
116+ (master_percent_ / 100.0));
117+ first_mix_volume_ = mix_volume;
118+ if (isPlaying()) {
119+ Mix_Volume(channel_id_, mix_volume);
120+ }
121+ }
85122 };
86123
87124 bool SoundEffect::pImpl::initialized_ = false;
88125 Channels SoundEffect::pImpl::channels_;
126+ChunkMap SoundEffect::pImpl::mix_chunks_;
127+size_t SoundEffect::pImpl::master_percent_ = DefaultVolumePercent;
89128
90129
91130 SoundEffect::SoundEffect(const char* play_file) : pimpl(new pImpl(play_file))
@@ -100,25 +139,18 @@
100139
101140 void SoundEffect::setMasterVolume(size_t percent)
102141 {
103- fprintf(stderr, "SoundEffect::setMasterVolume: %d\n", percent);
104- static_cast<void>(percent);
105-
106- // Mix_Volume() を用いる
107-
108- // !!!
109- //pimpl->master_percent_ = max(percent, static_cast<size_t>(100));
142+ pimpl->master_percent_ = min(percent, static_cast<size_t>(100));
143+ pimpl->update_volume();
110144 }
111145
112146
113147 void SoundEffect::setVolume(size_t percent)
114148 {
115- if (! pimpl->audio_.isInitialized()) {
149+ if (!pimpl->audio_.isInitialized()) {
116150 return;
117151 }
118- percent = max(percent, static_cast<size_t>(100));
119-
120- static_cast<void>(percent);
121- // !!!
152+ pimpl->percent_ = min(percent, static_cast<size_t>(100));
153+ pimpl->update_volume();
122154 }
123155
124156
@@ -129,7 +161,9 @@
129161 static_cast<void>(y);
130162 static_cast<void>(z);
131163
132- if (! pimpl->audio_.isInitialized()) {
164+ // !!! 余力があれば SDL_mixer の Effect を適用してもよい
165+
166+ if (!pimpl->audio_.isInitialized()) {
133167 return;
134168 }
135169
@@ -137,6 +171,20 @@
137171 }
138172
139173
174+void SoundEffect::stop(void)
175+{
176+ if (!pimpl->audio_.isInitialized()) {
177+ return;
178+ }
179+
180+ if (!pimpl->isPlaying()) {
181+ return;
182+ }
183+
184+ Mix_HaltChannel(pimpl->channel_id_);
185+}
186+
187+
140188 // !attention x, y, z は無視される
141189 void SoundEffect::updatePosition(float x, float y, float z)
142190 {
@@ -144,7 +192,7 @@
144192 static_cast<void>(y);
145193 static_cast<void>(z);
146194
147- // !!! SDL_Mixer の Effect を利用すると再生位置の表現ができるかもしれない
195+ // !!! 余力があれば SDL_mixer の Effect を適用してもよい
148196
149197 // 実装しない
150198 }
@@ -152,7 +200,7 @@
152200
153201 bool SoundEffect::isPlaying(void) const
154202 {
155- if (! pimpl->audio_.isInitialized()) {
203+ if (!pimpl->audio_.isInitialized()) {
156204 return false;
157205 }
158206
--- trunk/libs/audio/SoundEffect.h (revision 1960)
+++ trunk/libs/audio/SoundEffect.h (revision 1961)
@@ -33,6 +33,7 @@
3333 void setVolume(size_t percent);
3434
3535 void play(float x = 0.0, float y = 0.0, float z = 0.1);
36+ void stop(void);
3637 void updatePosition(float x, float y, float z = 0.1);
3738 bool isPlaying(void) const;
3839
旧リポジトリブラウザで表示