Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 244 | chris | 1 | #include "BassMusicInterface.h" |
| 2 | #include "BassLoader.h" |
||
| 3 | #include "..\PakLib\PakInterface.h" |
||
| 4 | |||
| 5 | using namespace Sexy; |
||
| 6 | |||
| 7 | #define BASS2_MUSIC_RAMP BASS_MUSIC_RAMP // normal ramping |
||
| 8 | |||
| 9 | #define BASS_CONFIG_BUFFER 0 |
||
| 10 | |||
| 11 | BassMusicInfo::BassMusicInfo() |
||
| 12 | { |
||
| 13 | mVolume = 0.0; |
||
| 14 | mVolumeAdd = 0.0; |
||
| 15 | mVolumeCap = 1.0; |
||
| 16 | mStopOnFade = false; |
||
| 17 | mHMusic = NULL; |
||
| 18 | mHStream = NULL; |
||
| 19 | } |
||
| 20 | |||
| 21 | BassMusicInterface::BassMusicInterface(HWND theHWnd) |
||
| 22 | { |
||
| 23 | LoadBassDLL(); |
||
| 24 | |||
| 25 | MIXERCONTROLDETAILS mcd; |
||
| 26 | MIXERCONTROLDETAILS_UNSIGNED mxcd_u; |
||
| 27 | MIXERLINECONTROLS mxlc; |
||
| 28 | MIXERCONTROL mlct; |
||
| 29 | MIXERLINE mixerLine; |
||
| 30 | HMIXEROBJ phmx; |
||
| 31 | MIXERCAPS pmxcaps; |
||
| 32 | |||
| 33 | mixerOpen((HMIXER*) &phmx, 0, 0, 0, MIXER_OBJECTF_MIXER); |
||
| 34 | mixerGetDevCaps(0, &pmxcaps, sizeof(pmxcaps)); |
||
| 35 | |||
| 36 | mxlc.cbStruct = sizeof(mxlc); |
||
| 37 | mxlc.cbmxctrl = sizeof(mlct); |
||
| 38 | mxlc.pamxctrl = &mlct; |
||
| 39 | mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME; |
||
| 40 | mixerLine.cbStruct = sizeof(mixerLine); |
||
| 41 | mixerLine.dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT; |
||
| 42 | mixerGetLineInfo(phmx, &mixerLine, MIXER_GETLINEINFOF_COMPONENTTYPE); |
||
| 43 | mxlc.dwLineID = mixerLine.dwLineID; |
||
| 44 | mixerGetLineControls(phmx, &mxlc, MIXER_GETLINECONTROLSF_ONEBYTYPE); |
||
| 45 | |||
| 46 | mcd.cbStruct = sizeof(mcd); |
||
| 47 | mcd.dwControlID = mlct.dwControlID; |
||
| 48 | mcd.cChannels = 1; |
||
| 49 | mcd.cMultipleItems = 0; |
||
| 50 | mcd.cbDetails = sizeof(mxcd_u); |
||
| 51 | mcd.paDetails = &mxcd_u; |
||
| 52 | |||
| 53 | mixerGetControlDetails(phmx, &mcd, 0L); |
||
| 54 | |||
| 55 | //return mxcd_u.dwValue; |
||
| 56 | |||
| 57 | BOOL success; |
||
| 58 | |||
| 59 | if (gBass->mVersion2) |
||
| 60 | { |
||
| 61 | success = gBass->BASS_Init2(1, 44100, 0, theHWnd, NULL); |
||
| 62 | gBass->BASS_SetConfig(BASS_CONFIG_BUFFER, 2000); |
||
| 63 | } |
||
| 64 | else |
||
| 65 | success = gBass->BASS_Init(-1, 44100, 0, theHWnd); |
||
| 66 | |||
| 67 | mixerSetControlDetails(phmx, &mcd, 0L); |
||
| 68 | |||
| 69 | gBass->BASS_Start(); |
||
| 70 | |||
| 71 | mixerClose((HMIXER) phmx); |
||
| 72 | |||
| 73 | mMaxMusicVolume = 40; |
||
| 74 | |||
| 75 | mMusicLoadFlags = gBass->mVersion2 ? BASS_MUSIC_LOOP | BASS2_MUSIC_RAMP : BASS_MUSIC_LOOP; |
||
| 76 | } |
||
| 77 | |||
| 78 | BassMusicInterface::~BassMusicInterface() |
||
| 79 | { |
||
| 80 | gBass->BASS_Stop(); |
||
| 81 | gBass->BASS_Free(); |
||
| 82 | |||
| 83 | FreeBassDLL(); |
||
| 84 | } |
||
| 85 | |||
| 86 | bool BassMusicInterface::LoadMusic(int theSongId, const std::string& theFileName) |
||
| 87 | { |
||
| 88 | HMUSIC aHMusic = NULL; |
||
| 89 | HSTREAM aStream = NULL; |
||
| 90 | |||
| 91 | std::string anExt; |
||
| 92 | int aDotPos = theFileName.find_last_of('.'); |
||
| 93 | if (aDotPos!=std::string::npos) |
||
| 94 | anExt = StringToLower(theFileName.substr(aDotPos+1)); |
||
| 95 | |||
| 96 | if (anExt=="wav" || anExt=="ogg" || anExt=="mp3") |
||
| 97 | aStream = gBass->BASS_StreamCreateFile(FALSE, (void*) theFileName.c_str(), 0, 0, 0); |
||
| 98 | else |
||
| 99 | { |
||
| 100 | PFILE* aFP = p_fopen(theFileName.c_str(), "rb"); |
||
| 101 | if (aFP == NULL) |
||
| 102 | return false; |
||
| 103 | |||
| 104 | p_fseek(aFP, 0, SEEK_END); |
||
| 105 | int aSize = p_ftell(aFP); |
||
| 106 | p_fseek(aFP, 0, SEEK_SET); |
||
| 107 | |||
| 108 | uchar* aData = new uchar[aSize]; |
||
| 109 | p_fread(aData, 1, aSize, aFP); |
||
| 110 | p_fclose(aFP); |
||
| 111 | |||
| 112 | if (gBass->mVersion2) |
||
| 113 | aHMusic = gBass->BASS_MusicLoad2(FALSE, (void*) theFileName.c_str(), 0, 0, BASS_MUSIC_LOOP | BASS2_MUSIC_RAMP, 0); |
||
| 114 | else |
||
| 115 | aHMusic = gBass->BASS_MusicLoad(FALSE, (void*) theFileName.c_str(), 0, 0, BASS_MUSIC_LOOP); |
||
| 116 | |||
| 117 | delete aData; |
||
| 118 | } |
||
| 119 | |||
| 120 | if (aHMusic==NULL && aStream==NULL) |
||
| 121 | return false; |
||
| 122 | |||
| 123 | BassMusicInfo aMusicInfo; |
||
| 124 | aMusicInfo.mHMusic = aHMusic; |
||
| 125 | aMusicInfo.mHStream = aStream; |
||
| 126 | mMusicMap.insert(BassMusicMap::value_type(theSongId, aMusicInfo)); |
||
| 127 | |||
| 128 | return true; |
||
| 129 | } |
||
| 130 | |||
| 131 | void BassMusicInterface::PlayMusic(int theSongId, int theOffset, bool noLoop) |
||
| 132 | { |
||
| 133 | BassMusicMap::iterator anItr = mMusicMap.find(theSongId); |
||
| 134 | if (anItr != mMusicMap.end()) |
||
| 135 | { |
||
| 136 | BassMusicInfo* aMusicInfo = &anItr->second; |
||
| 137 | aMusicInfo->mVolume = aMusicInfo->mVolumeCap; |
||
| 138 | aMusicInfo->mVolumeAdd = 0.0; |
||
| 139 | aMusicInfo->mStopOnFade = noLoop; |
||
| 140 | gBass->BASS_ChannelSetAttributes(aMusicInfo->GetHandle(), -1, (int) (aMusicInfo->mVolume*100), -101); |
||
| 141 | |||
| 142 | gBass->BASS_ChannelStop(aMusicInfo->GetHandle()); |
||
| 143 | if (aMusicInfo->mHMusic) |
||
| 144 | { |
||
| 145 | if (gBass->mVersion2) |
||
| 146 | gBass->BASS_MusicPlayEx(aMusicInfo->mHMusic, theOffset, BASS_MUSIC_POSRESET | BASS2_MUSIC_RAMP | (noLoop ? 0 : BASS_MUSIC_LOOP), TRUE); |
||
| 147 | else |
||
| 148 | gBass->BASS_MusicPlayEx(aMusicInfo->mHMusic, theOffset, noLoop ? 0 : BASS_MUSIC_LOOP, TRUE); |
||
| 149 | } |
||
| 150 | else |
||
| 151 | { |
||
| 152 | BOOL flush = theOffset == -1 ? FALSE : TRUE; |
||
| 153 | gBass->BASS_StreamPlay(aMusicInfo->mHStream, flush, noLoop ? 0 : BASS_MUSIC_LOOP); |
||
| 154 | if (theOffset > 0) |
||
| 155 | gBass->BASS_ChannelSetPosition(aMusicInfo->mHStream, theOffset); |
||
| 156 | } |
||
| 157 | } |
||
| 158 | } |
||
| 159 | |||
| 160 | void BassMusicInterface::StopMusic(int theSongId) |
||
| 161 | { |
||
| 162 | BassMusicMap::iterator anItr = mMusicMap.find(theSongId); |
||
| 163 | if (anItr != mMusicMap.end()) |
||
| 164 | { |
||
| 165 | BassMusicInfo* aMusicInfo = &anItr->second; |
||
| 166 | aMusicInfo->mVolume = 0.0; |
||
| 167 | gBass->BASS_ChannelStop(aMusicInfo->GetHandle()); |
||
| 168 | } |
||
| 169 | } |
||
| 170 | |||
| 171 | void BassMusicInterface::StopAllMusic() |
||
| 172 | { |
||
| 173 | BassMusicMap::iterator anItr = mMusicMap.begin(); |
||
| 174 | while (anItr != mMusicMap.end()) |
||
| 175 | { |
||
| 176 | BassMusicInfo* aMusicInfo = &anItr->second; |
||
| 177 | aMusicInfo->mVolume = 0.0; |
||
| 178 | gBass->BASS_ChannelStop(aMusicInfo->GetHandle()); |
||
| 179 | ++anItr; |
||
| 180 | } |
||
| 181 | } |
||
| 182 | |||
| 183 | void BassMusicInterface::UnloadMusic(int theSongId) |
||
| 184 | { |
||
| 185 | StopMusic(theSongId); |
||
| 186 | |||
| 187 | BassMusicMap::iterator anItr = mMusicMap.find(theSongId); |
||
| 188 | if (anItr != mMusicMap.end()) |
||
| 189 | { |
||
| 190 | BassMusicInfo* aMusicInfo = &anItr->second; |
||
| 191 | if (aMusicInfo->mHStream) |
||
| 192 | gBass->BASS_StreamFree(aMusicInfo->mHStream); |
||
| 193 | else if (aMusicInfo->mHMusic) |
||
| 194 | gBass->BASS_MusicFree(aMusicInfo->mHMusic); |
||
| 195 | |||
| 196 | mMusicMap.erase(anItr); |
||
| 197 | } |
||
| 198 | } |
||
| 199 | |||
| 200 | void BassMusicInterface::UnloadAllMusic() |
||
| 201 | { |
||
| 202 | StopAllMusic(); |
||
| 203 | for (BassMusicMap::iterator anItr = mMusicMap.begin(); anItr != mMusicMap.end(); ++anItr) |
||
| 204 | { |
||
| 205 | BassMusicInfo* aMusicInfo = &anItr->second; |
||
| 206 | if (aMusicInfo->mHStream) |
||
| 207 | gBass->BASS_StreamFree(aMusicInfo->mHStream); |
||
| 208 | else if (aMusicInfo->mHMusic) |
||
| 209 | gBass->BASS_MusicFree(aMusicInfo->mHMusic); |
||
| 210 | } |
||
| 211 | mMusicMap.clear(); |
||
| 212 | } |
||
| 213 | |||
| 214 | void BassMusicInterface::PauseMusic(int theSongId) |
||
| 215 | { |
||
| 216 | BassMusicMap::iterator anItr = mMusicMap.find(theSongId); |
||
| 217 | if (anItr != mMusicMap.end()) |
||
| 218 | { |
||
| 219 | BassMusicInfo* aMusicInfo = &anItr->second; |
||
| 220 | gBass->BASS_ChannelPause(aMusicInfo->GetHandle()); |
||
| 221 | } |
||
| 222 | } |
||
| 223 | |||
| 224 | void BassMusicInterface::PauseAllMusic() |
||
| 225 | { |
||
| 226 | for (BassMusicMap::iterator anItr = mMusicMap.begin(); anItr != mMusicMap.end(); ++anItr) |
||
| 227 | { |
||
| 228 | BassMusicInfo* aMusicInfo = &anItr->second; |
||
| 229 | if (gBass->BASS_ChannelIsActive(aMusicInfo->GetHandle()) == BASS_ACTIVE_PLAYING) |
||
| 230 | gBass->BASS_ChannelPause(aMusicInfo->GetHandle()); |
||
| 231 | } |
||
| 232 | } |
||
| 233 | |||
| 234 | void BassMusicInterface::ResumeAllMusic() |
||
| 235 | { |
||
| 236 | for (BassMusicMap::iterator anItr = mMusicMap.begin(); anItr != mMusicMap.end(); ++anItr) |
||
| 237 | { |
||
| 238 | BassMusicInfo* aMusicInfo = &anItr->second; |
||
| 239 | |||
| 240 | if (gBass->BASS_ChannelIsActive(aMusicInfo->GetHandle()) == BASS_ACTIVE_PAUSED) |
||
| 241 | gBass->BASS_ChannelResume(aMusicInfo->GetHandle()); |
||
| 242 | } |
||
| 243 | } |
||
| 244 | |||
| 245 | void BassMusicInterface::ResumeMusic(int theSongId) |
||
| 246 | { |
||
| 247 | BassMusicMap::iterator anItr = mMusicMap.find(theSongId); |
||
| 248 | if (anItr != mMusicMap.end()) |
||
| 249 | { |
||
| 250 | BassMusicInfo* aMusicInfo = &anItr->second; |
||
| 251 | gBass->BASS_ChannelResume(aMusicInfo->GetHandle()); |
||
| 252 | } |
||
| 253 | } |
||
| 254 | |||
| 255 | void BassMusicInterface::FadeIn(int theSongId, int theOffset, double theSpeed, bool noLoop) |
||
| 256 | { |
||
| 257 | BassMusicMap::iterator anItr = mMusicMap.find(theSongId); |
||
| 258 | if (anItr != mMusicMap.end()) |
||
| 259 | { |
||
| 260 | BassMusicInfo* aMusicInfo = &anItr->second; |
||
| 261 | |||
| 262 | aMusicInfo->mVolumeAdd = theSpeed; |
||
| 263 | aMusicInfo->mStopOnFade = noLoop; |
||
| 264 | |||
| 265 | gBass->BASS_ChannelStop(aMusicInfo->GetHandle()); |
||
| 266 | gBass->BASS_ChannelSetAttributes(aMusicInfo->GetHandle(), -1, (int) (aMusicInfo->mVolume*100), -101); |
||
| 267 | if (aMusicInfo->mHMusic) |
||
| 268 | { |
||
| 269 | if (theOffset == -1) |
||
| 270 | gBass->BASS_MusicPlay(aMusicInfo->mHMusic); |
||
| 271 | else |
||
| 272 | { |
||
| 273 | if (gBass->mVersion2) |
||
| 274 | gBass->BASS_MusicPlayEx(aMusicInfo->mHMusic, theOffset, BASS2_MUSIC_RAMP | (noLoop ? 0 : BASS_MUSIC_LOOP), TRUE); |
||
| 275 | else |
||
| 276 | gBass->BASS_MusicPlayEx(aMusicInfo->mHMusic, theOffset, noLoop ? 0 : BASS_MUSIC_LOOP, TRUE); |
||
| 277 | } |
||
| 278 | } |
||
| 279 | else |
||
| 280 | { |
||
| 281 | BOOL flush = theOffset == -1 ? FALSE : TRUE; |
||
| 282 | gBass->BASS_StreamPlay(aMusicInfo->mHStream, flush, noLoop ? 0 : BASS_MUSIC_LOOP); |
||
| 283 | if (theOffset > 0) |
||
| 284 | gBass->BASS_ChannelSetPosition(aMusicInfo->mHStream, theOffset); |
||
| 285 | } |
||
| 286 | |||
| 287 | } |
||
| 288 | } |
||
| 289 | |||
| 290 | void BassMusicInterface::FadeOut(int theSongId, bool stopSong, double theSpeed) |
||
| 291 | { |
||
| 292 | BassMusicMap::iterator anItr = mMusicMap.find(theSongId); |
||
| 293 | if (anItr != mMusicMap.end()) |
||
| 294 | { |
||
| 295 | BassMusicInfo* aMusicInfo = &anItr->second; |
||
| 296 | |||
| 297 | if (aMusicInfo->mVolume != 0.0) |
||
| 298 | { |
||
| 299 | aMusicInfo->mVolumeAdd = -theSpeed; |
||
| 300 | } |
||
| 301 | |||
| 302 | aMusicInfo->mStopOnFade = stopSong; |
||
| 303 | } |
||
| 304 | } |
||
| 305 | |||
| 306 | void BassMusicInterface::FadeOutAll(bool stopSong, double theSpeed) |
||
| 307 | { |
||
| 308 | BassMusicMap::iterator anItr = mMusicMap.begin(); |
||
| 309 | while (anItr != mMusicMap.end()) |
||
| 310 | { |
||
| 311 | BassMusicInfo* aMusicInfo = &anItr->second; |
||
| 312 | |||
| 313 | aMusicInfo->mVolumeAdd = -theSpeed; |
||
| 314 | aMusicInfo->mStopOnFade = stopSong; |
||
| 315 | |||
| 316 | ++anItr; |
||
| 317 | } |
||
| 318 | } |
||
| 319 | |||
| 320 | void BassMusicInterface::SetVolume(double theVolume) |
||
| 321 | { |
||
| 322 | int aVolume = (int) (theVolume * mMaxMusicVolume); |
||
| 323 | |||
| 324 | if (gBass->mVersion2) |
||
| 325 | { |
||
| 326 | gBass->BASS_SetConfig(/*BASS_CONFIG_GVOL_MUSIC*/6, (int) (theVolume * 100)); |
||
| 327 | gBass->BASS_SetConfig(/*BASS_CONFIG_GVOL_STREAM*/5, (int) (theVolume * 100)); |
||
| 328 | } |
||
| 329 | else |
||
| 330 | gBass->BASS_SetGlobalVolumes(aVolume, aVolume, aVolume); |
||
| 331 | } |
||
| 332 | |||
| 333 | void BassMusicInterface::SetSongVolume(int theSongId, double theVolume) |
||
| 334 | { |
||
| 335 | BassMusicMap::iterator anItr = mMusicMap.find(theSongId); |
||
| 336 | if (anItr != mMusicMap.end()) |
||
| 337 | { |
||
| 338 | BassMusicInfo* aMusicInfo = &anItr->second; |
||
| 339 | |||
| 340 | aMusicInfo->mVolume = theVolume; |
||
| 341 | gBass->BASS_ChannelSetAttributes(aMusicInfo->GetHandle(), -1, (int) (aMusicInfo->mVolume*100), -101); |
||
| 342 | } |
||
| 343 | } |
||
| 344 | |||
| 345 | void BassMusicInterface::SetSongMaxVolume(int theSongId, double theMaxVolume) |
||
| 346 | { |
||
| 347 | BassMusicMap::iterator anItr = mMusicMap.find(theSongId); |
||
| 348 | if (anItr != mMusicMap.end()) |
||
| 349 | { |
||
| 350 | BassMusicInfo* aMusicInfo = &anItr->second; |
||
| 351 | |||
| 352 | aMusicInfo->mVolumeCap = theMaxVolume; |
||
| 353 | aMusicInfo->mVolume = min(aMusicInfo->mVolume, theMaxVolume); |
||
| 354 | gBass->BASS_ChannelSetAttributes(aMusicInfo->GetHandle(), -1, (int) (aMusicInfo->mVolume*100), -101); |
||
| 355 | } |
||
| 356 | } |
||
| 357 | |||
| 358 | bool BassMusicInterface::IsPlaying(int theSongId) |
||
| 359 | { |
||
| 360 | BassMusicMap::iterator anItr = mMusicMap.find(theSongId); |
||
| 361 | if (anItr != mMusicMap.end()) |
||
| 362 | { |
||
| 363 | BassMusicInfo* aMusicInfo = &anItr->second; |
||
| 364 | return gBass->BASS_ChannelIsActive(aMusicInfo->GetHandle()) == BASS_ACTIVE_PLAYING; |
||
| 365 | } |
||
| 366 | |||
| 367 | return false; |
||
| 368 | } |
||
| 369 | |||
| 370 | void BassMusicInterface::SetMusicAmplify(int theSongId, double theAmp) |
||
| 371 | { |
||
| 372 | BassMusicMap::iterator anItr = mMusicMap.find(theSongId); |
||
| 373 | if (anItr != mMusicMap.end()) |
||
| 374 | { |
||
| 375 | BassMusicInfo* aMusicInfo = &anItr->second; |
||
| 376 | gBass->BASS_MusicSetAmplify(aMusicInfo->GetHandle(), (int) (theAmp * 100)); |
||
| 377 | } |
||
| 378 | } |
||
| 379 | |||
| 380 | void BassMusicInterface::Update() |
||
| 381 | { |
||
| 382 | BassMusicMap::iterator anItr = mMusicMap.begin(); |
||
| 383 | while (anItr != mMusicMap.end()) |
||
| 384 | { |
||
| 385 | BassMusicInfo* aMusicInfo = &anItr->second; |
||
| 386 | |||
| 387 | if (aMusicInfo->mVolumeAdd != 0.0) |
||
| 388 | { |
||
| 389 | aMusicInfo->mVolume += aMusicInfo->mVolumeAdd; |
||
| 390 | |||
| 391 | if (aMusicInfo->mVolume > aMusicInfo->mVolumeCap) |
||
| 392 | { |
||
| 393 | aMusicInfo->mVolume = aMusicInfo->mVolumeCap; |
||
| 394 | aMusicInfo->mVolumeAdd = 0.0; |
||
| 395 | } |
||
| 396 | else if (aMusicInfo->mVolume < 0.0) |
||
| 397 | { |
||
| 398 | aMusicInfo->mVolume = 0.0; |
||
| 399 | aMusicInfo->mVolumeAdd = 0.0; |
||
| 400 | |||
| 401 | if (aMusicInfo->mStopOnFade) |
||
| 402 | gBass->BASS_ChannelStop(aMusicInfo->GetHandle()); |
||
| 403 | } |
||
| 404 | |||
| 405 | gBass->BASS_ChannelSetAttributes(aMusicInfo->GetHandle(), -1, (int) (aMusicInfo->mVolume*100), -101); |
||
| 406 | } |
||
| 407 | |||
| 408 | ++anItr; |
||
| 409 | } |
||
| 410 | } |
||
| 411 | |||
| 412 | //////////////////////////////////////////////////////////////////// |
||
| 413 | //////////////////////////////////////////////////////////////////// |
||
| 414 | // MODs are broken up into several orders or patterns. This returns the current order a song is on. |
||
| 415 | int BassMusicInterface::GetMusicOrder(int theSongId) |
||
| 416 | { |
||
| 417 | BassMusicMap::iterator anItr = mMusicMap.find(theSongId); |
||
| 418 | if (anItr != mMusicMap.end()) |
||
| 419 | { |
||
| 420 | BassMusicInfo* aMusicInfo = &anItr->second; |
||
| 421 | int aPosition = gBass->BASS_MusicGetOrderPosition(aMusicInfo->GetHandle()); |
||
| 422 | return aPosition; |
||
| 423 | } |
||
| 424 | return -1; |
||
| 425 | } |