Develop and Download Open Source Software

Browse Subversion Repository

Contents of /sound/SoundEffectManager.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 364 - (show annotations) (download) (as text)
Tue Apr 22 21:18:06 2008 UTC (16 years, 1 month ago) by satofumi
File MIME type: text/x-c++src
File size: 5478 byte(s)
what() を追加
1 /*!
2 \file
3 \brief Œř‰Ę‰š‚ĚŠÇ—
4
5 \author Satofumi KAMIMURA
6
7 $Id$
8
9 \todo I—šŽž‚É‚ÍAŽ‘Œš‚đ‰đ•ú‚ľ‚Ä Mix_ChannelFinished() ‚đ–łŒř‰ť‚ľ‚Ä‚¨‚­
10 */
11
12 #include "SoundEffectManager.h"
13 #include "MixerInit.h"
14 #include "LockGuard.h"
15 #include "ExistFile.h"
16 #include <SDL_mixer.h>
17 #include <string>
18 #include <vector>
19 #include <map>
20
21 using namespace beego;
22
23
24 struct SoundEffectManager::pImpl : private MixerInit {
25
26 class EffectInfo {
27 public:
28 std::string file_path;
29 Mix_Chunk* effect;
30
31 EffectInfo(void) : file_path(""), effect(NULL) {
32 }
33 };
34
35 std::string error_message_;
36 bool initialized;
37 SDL_mutex* mutex;
38 typedef std::map<int,EffectInfo> EffectMap;
39 EffectMap effect_map;
40 static size_t play_id;
41 std::vector<size_t> channel_id;
42
43 pImpl(void) :
44 error_message_("no error"), initialized(false), mutex(SDL_CreateMutex()) {
45
46 if (! isInitialized()) {
47 return;
48 }
49
50 channel_id.resize(ChannelNum, InvalidId);
51 Mix_ChannelFinished(channelDone);
52 initialized = true;
53 }
54
55 ~pImpl(void) {
56 if (! isInitialized()) {
57 return;
58 }
59 Mix_HaltChannel(-1);
60 }
61
62 static pImpl* getObject(void) {
63 static pImpl obj;
64 return &obj;
65 }
66
67 static void freeMusResource(EffectMap& effect_maps, int effect_id,
68 bool erase = false) {
69 EffectMap::iterator p = effect_maps.find(effect_id);
70 if (p != effect_maps.end()) {
71 if (p->second.effect) {
72 Mix_FreeChunk(p->second.effect);
73 p->second.effect = NULL;
74 }
75 if (erase) {
76 effect_maps.erase(p);
77 }
78 }
79 }
80
81 static void channelDone(int channel) {
82 static pImpl* obj = getObject();
83
84 LockGuard guard(obj->mutex);
85 obj->channel_id[channel] = InvalidId;
86 }
87 };
88 size_t SoundEffectManager::pImpl::play_id = 1;
89
90
91 SoundEffectManager::SoundEffectManager(void) : pimpl(pImpl::getObject()) {
92 }
93
94
95 SoundEffectManager::~SoundEffectManager(void) {
96 }
97
98
99 const char* SoundEffectManager::what(void) {
100 return pimpl->error_message_.c_str();
101 }
102
103
104 bool SoundEffectManager::isInitialized(void) {
105 return pimpl->initialized;
106 }
107
108
109 bool SoundEffectManager::registerEffect(int effect_id, const char* file_path) {
110 if (! isInitialized()) {
111 return false;
112 }
113
114 // ƒtƒ@ƒCƒ‹‚Ě‘śÝƒ`ƒFƒbƒN
115 if (! existFile(file_path)) {
116 pimpl->error_message_ = std::string(file_path) + " no such file";
117 return false;
118 }
119
120 // Šů‘ś‚Ě‚ŕ‚Ě‚Ć“Ż‚ś ID ‚ŞŽw’肳‚ę‚˝ę‡AŠů‘śƒŠƒ\[ƒX‚đíœ‚ˇ‚é
121 LockGuard guard(pimpl->mutex);
122 pImpl::freeMusResource(pimpl->effect_map, effect_id);
123
124 // Ž‘Œš‚Ě‚ ‚éęŠ‚Ě“o˜^‚Ćƒ[ƒh
125 pImpl::EffectInfo effect_info;
126 effect_info.file_path = file_path;
127 Mix_Chunk* effect = Mix_LoadWAV(file_path);
128 if (! effect) {
129 pimpl->error_message_ = Mix_GetError();
130 return false;
131 }
132 effect_info.effect = effect;
133 pimpl->effect_map[effect_id] = effect_info;
134
135 return true;
136 }
137
138
139 void SoundEffectManager::unregisterEffect(int effect_id) {
140 if (! isInitialized()) {
141 // !!!
142 return;
143 }
144
145 // Ž‘Œš‚̉đ•ú
146 pImpl::freeMusResource(pimpl->effect_map, effect_id);
147 }
148
149
150 void SoundEffectManager::updateVolume(size_t percent, int channel_id) {
151 if (! isInitialized()) {
152 // !!!
153 return;
154 }
155
156 if (percent > 100) {
157 percent = 100;
158 } else if (percent < 0) {
159 percent = 0;
160 }
161 if (channel_id != AllChannel) {
162 Mix_Volume(channel_id, MIX_MAX_VOLUME * percent / 100);
163 } else {
164 for (size_t i = 0; i < MixerInit::ChannelNum; ++i) {
165 Mix_Volume(i, MIX_MAX_VOLUME * percent / 100);
166 }
167 }
168 }
169
170
171 int SoundEffectManager::play(int effect_id,
172 size_t fade_in_msec, int volume_percent) {
173 if (! isInitialized()) {
174 // !!!
175 return InvalidId;
176 }
177
178 // !!! ‚Ƃ肠‚Ś‚¸AÄś‚ˇ‚é
179 pImpl::EffectMap::iterator it = pimpl->effect_map.find(effect_id);
180 if (it == pimpl->effect_map.end()) {
181 // !!!
182 //pimpl->error_message_ = "no sound effect: %d\n", effect_id);
183 return -1;
184 }
185
186 int id = Mix_PlayChannel(-1, it->second.effect, 0);
187 if (id < 0) {
188 // !!!
189 return id;
190 }
191
192 LockGuard guard(pimpl->mutex);
193 size_t playing_id = pImpl::play_id;
194 pimpl->channel_id[id] = pImpl::play_id;
195 ++pImpl::play_id;
196
197 return playing_id;
198 }
199
200
201 void SoundEffectManager::stop(int serial_id, size_t fade_out_msec) {
202 if (! isInitialized()) {
203 // !!!
204 return;
205 }
206
207 if (serial_id < 0) {
208 Mix_FadeOutChannel(-1, fade_out_msec);
209 return;
210 }
211
212 // Žw’č ID ‚ĚŒř‰Ę‰š‚đ’âŽ~
213 int channel_id = -1;
214 // !!! ˆČ‰şAd•Ą‚ľ‚Ä‚˘‚é‚̂ł­‚­‚é‚ׂŤ
215 for (size_t i = 0; i < MixerInit::ChannelNum; ++i) {
216 if (pimpl->channel_id[i] == static_cast<size_t>(serial_id)) {
217 channel_id = i;
218 break;
219 }
220 }
221 Mix_FadeOutChannel(channel_id, fade_out_msec);
222 }
223
224
225 bool SoundEffectManager::nowPlaying(int serial_id) {
226 if (! isInitialized()) {
227 // !!!
228 return false;
229 }
230
231 int channel_id = -1; // -1 ‚̂ƂŤAMix_Playing() ‚͂ǂꂊ‚ލĐś’†‚Č‚ç‚ΐ^
232 if (serial_id >= InvalidId) {
233
234 LockGuard guard(pimpl->mutex);
235 // !!! find ‚É‚ˇ‚ׂŤ‚ЁH
236 for (size_t i = 0; i < MixerInit::ChannelNum; ++i) {
237 if (pimpl->channel_id[i] == static_cast<size_t>(serial_id)) {
238 channel_id = i;
239 break;
240 }
241 }
242 }
243 return (Mix_Playing(channel_id) == 0) ? false : true;
244 }
245
246 #if 0
247 // !!! ~pImpl ‚ł̒âŽ~‘Ň‚ż‚Ĺ–â‘č‚Č‚ł‚ť‚¤
248 // !!! GuiManager ‚ĆˆŮ‚Č‚čAŽ‘Œš‚Ş“ŕ•”‚ĹŠŽŒ‹‚ľ‚Ä‚˘‚é‚˝‚ßx1
249 void SoundEffectManager::terminate(void) {
250 }
251 #endif
252
253
254 void SoundEffectManager::setEachVolume(size_t effect_id, size_t percent) {
255
256 // !!!
257 // !!! –˘ŽŔ‘•
258 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26