Subversion Repositories AndroidProjects

Rev

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
}