1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
/* ScummVM - Scumm Interpreter
* Copyright (C) 2003 The ScummVM project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Header$
*
*/
// todo: add fadeout, crossfading.
// this code always loops. make it depend on _loopFlag
#include "stdafx.h"
#include "music.h"
#include "sound/mixer.h"
#include "common/util.h"
#include "common/file.h"
SwordMusic::SwordMusic(OSystem *system, SoundMixer *pMixer) {
_system = system;
_mixer = pMixer;
_mixer->setupPremix(passMixerFunc, this);
_fading = 0;
_playing = false;
_loop = false;
_mutex = _system->create_mutex();
_waveSize = _wavePos = _bufPos = _smpInBuf = 0;
assert(_mixer->getOutputRate() == 22050);
}
void SwordMusic::passMixerFunc(void *param, int16 *buf, uint len) {
((SwordMusic*)param)->mixer(buf, len);
}
void SwordMusic::mixer(int16 *buf, uint len) {
if (!_playing)
memset(buf, 0, 2 * len * sizeof(int16));
else {
_system->lock_mutex(_mutex);
len >>= 1;
if (len > _smpInBuf)
warning("SwordMusic::mixer: sample buffer underrun");
else {
uint32 maxLen = BUFSIZE - _bufPos;
if (len >= maxLen) {
for (uint32 cnt = 0; cnt < maxLen; cnt++)
buf[(cnt << 2) | 0] = buf[(cnt << 2) | 1] =
buf[(cnt << 2) | 2] = buf[(cnt << 2) | 3] = _musicBuf[_bufPos + cnt];
_smpInBuf -= maxLen;
_bufPos = 0;
len -= maxLen;
buf += maxLen * 4;
}
if (len) {
for (uint32 cnt = 0; cnt < len; cnt++)
buf[(cnt << 2) | 0] = buf[(cnt << 2) | 1] =
buf[(cnt << 2) | 2] = buf[(cnt << 2) | 3] = _musicBuf[_bufPos + cnt];
_smpInBuf -= len;
_bufPos += len;
}
}
_system->unlock_mutex(_mutex);
}
}
void SwordMusic::stream(void) {
// make sure we've got enough samples in buffer.
if ((_smpInBuf < SAMPLERATE) && _playing) {
_system->lock_mutex(_mutex);
uint32 loadTotal = BUFSIZE - _smpInBuf;
while (uint32 doLoad = loadTotal) {
if (BUFSIZE - ((_bufPos + _smpInBuf) % BUFSIZE) < loadTotal)
doLoad = BUFSIZE - (_bufPos + _smpInBuf) % BUFSIZE;
if (_waveSize - _wavePos < doLoad)
doLoad = _waveSize - _wavePos;
int16 *dest = _musicBuf + ((_bufPos + _smpInBuf) % BUFSIZE);
_musicFile.read(dest, doLoad * 2);
_wavePos += doLoad;
if (_wavePos == _waveSize) {
_wavePos = 0;
_musicFile.seek(WAVEHEADERSIZE);
}
loadTotal -= doLoad;
_smpInBuf += doLoad;
}
_system->unlock_mutex(_mutex);
}
}
void SwordMusic::startMusic(int32 tuneId, int32 loopFlag) {
_system->lock_mutex(_mutex);
_loop = (loopFlag > 0);
if (tuneId) {
if (_musicFile.isOpen())
_musicFile.close();
char fName[20];
sprintf(fName, "music/%s.wav", _tuneList[tuneId]);
_musicFile.open(fName);
if (_musicFile.isOpen()) {
_musicFile.seek(0x28);
_waveSize = _musicFile.readUint32LE() / 2;
_wavePos = 0;
_smpInBuf = 0;
_bufPos = 0;
_playing = true;
} else
_playing = false;
} else
_playing = false;
_system->unlock_mutex(_mutex);
stream();
}
void SwordMusic::fadeDown(void) {
warning("stub: SwordMusic::fadeDown");
}
|