Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
716 | lvd | 1 | #include "std.h" |
2 | |||
3 | #include "emul.h" |
||
4 | #include "vars.h" |
||
5 | #include "bass.h" |
||
6 | #include "snd_bass.h" |
||
7 | #include "gshle.h" |
||
8 | #include "gs.h" |
||
9 | #include "init.h" |
||
10 | #include "util.h" |
||
11 | |||
12 | #ifdef MOD_GSBASS |
||
13 | void GSHLE::reportError(const char *err, bool fatal) |
||
14 | { |
||
15 | color(CONSCLR_ERROR); |
||
16 | printf("BASS library reports error in %s\n", err); |
||
17 | color(CONSCLR_ERRCODE); |
||
18 | printf("error code is 0x%04X\n", BASS::ErrorGetCode()); |
||
19 | if(fatal) |
||
20 | { |
||
21 | exit(); |
||
22 | } |
||
23 | } |
||
24 | |||
25 | void GSHLE::runBASS() |
||
26 | { |
||
27 | static bool Initialized = false; |
||
28 | |||
29 | if(Initialized) |
||
30 | return; |
||
31 | |||
32 | if (BASS::Init(-1, conf.sound.fq, BASS_DEVICE_LATENCY, wnd, 0)) |
||
33 | { |
||
34 | DWORD len = BASS::GetConfig(BASS_CONFIG_UPDATEPERIOD); |
||
35 | BASS_INFO info; |
||
36 | BASS::GetInfo(&info); |
||
37 | BASS::SetConfig(BASS_CONFIG_BUFFER, len + info.minbuf); |
||
38 | color(CONSCLR_HARDITEM); |
||
39 | printf("BASS device latency is "); |
||
40 | color(CONSCLR_HARDINFO); |
||
41 | printf("%lums\n", len + info.minbuf); |
||
42 | } |
||
43 | else |
||
44 | { |
||
45 | color(CONSCLR_WARNING); |
||
46 | printf("warning: can't use default BASS device, trying silence\n"); |
||
47 | if (!BASS::Init(-2, 11025, 0, wnd, 0)) |
||
48 | errexit("can't init BASS"); |
||
49 | } |
||
50 | |||
51 | Initialized = true; |
||
52 | hmod = 0; |
||
53 | for (int ch = 0; ch < 4; ch++) |
||
54 | chan[ch].bass_ch = 0; |
||
55 | } |
||
56 | |||
57 | void GSHLE::reset_sound() |
||
58 | { |
||
59 | // runBASS(); |
||
60 | // BASS_Stop(); // todo: move to silent state? |
||
61 | } |
||
62 | |||
63 | |||
64 | DWORD CALLBACK gs_render(HSTREAM handle, void *buffer, DWORD length, void *user); |
||
65 | |||
66 | void GSHLE::initChannels() |
||
67 | { |
||
68 | if (chan[0].bass_ch) |
||
69 | return; |
||
70 | for (int ch = 0; ch < 4; ch++) |
||
71 | { |
||
72 | chan[ch].bass_ch = BASS::StreamCreate(11025, 1, BASS_SAMPLE_8BITS, gs_render, &chan[ch]); |
||
73 | if (!chan[ch].bass_ch) |
||
74 | reportError("BASS_StreamCreate()"); |
||
75 | } |
||
76 | } |
||
77 | |||
78 | void GSHLE::setmodvol(unsigned vol) |
||
79 | { |
||
80 | if (!hmod) |
||
81 | return; |
||
82 | runBASS(); |
||
83 | float v = (vol * conf.sound.bass_vol) / float(8000 * 64); |
||
84 | assert(v<=1.0); |
||
85 | if (!BASS::ChannelSetAttribute(hmod, BASS_ATTRIB_VOL, v)) |
||
86 | reportError("BASS_ChannelSetAttribute() [music volume]"); |
||
87 | } |
||
88 | |||
89 | void GSHLE::init_mod() |
||
90 | { |
||
91 | runBASS(); |
||
92 | if (hmod) |
||
93 | BASS::MusicFree(hmod); |
||
94 | hmod = 0; |
||
95 | hmod = BASS::MusicLoad(1, mod, 0, modsize, BASS_MUSIC_LOOP | BASS_MUSIC_POSRESET | BASS_MUSIC_RAMP, 0); |
||
96 | if (!hmod) |
||
97 | reportError("BASS_MusicLoad()", false); |
||
98 | } |
||
99 | |||
100 | void GSHLE::restart_mod(unsigned order, unsigned row) |
||
101 | { |
||
102 | if (!hmod) |
||
103 | return; |
||
104 | if (!BASS::ChannelSetPosition(hmod, MAKELONG(order,row), BASS_POS_MUSIC_ORDER)) |
||
105 | reportError("BASS_ChannelSetPosition() [music]"); |
||
106 | if (!BASS::ChannelFlags(hmod, BASS_MUSIC_LOOP | BASS_MUSIC_POSRESET | BASS_MUSIC_RAMP, -1)) |
||
107 | reportError("BASS_ChannelFlags() [music]"); |
||
108 | BASS::Start(); |
||
109 | if (!BASS::ChannelPlay(hmod, FALSE/*TRUE*/)) |
||
110 | reportError("BASS_ChannelPlay() [music]"); //molodcov_alex 0.36.2 |
||
111 | |||
112 | mod_playing = 1; |
||
113 | } |
||
114 | |||
115 | void GSHLE::resetmod() |
||
116 | { |
||
117 | if (hmod) |
||
118 | BASS::MusicFree(hmod); |
||
119 | hmod = 0; |
||
120 | } |
||
121 | |||
122 | void GSHLE::resetfx() |
||
123 | { |
||
124 | runBASS(); |
||
125 | for (int i = 0; i < 4; i++) |
||
126 | { |
||
127 | if (chan[i].bass_ch) |
||
128 | { |
||
129 | BASS::StreamFree(chan[i].bass_ch); |
||
130 | chan[i].bass_ch = 0; |
||
131 | } |
||
132 | } |
||
133 | } |
||
134 | |||
135 | DWORD GSHLE::modgetpos() |
||
136 | { |
||
137 | runBASS(); |
||
138 | return (DWORD)BASS::ChannelGetPosition(hmod, BASS_POS_MUSIC_ORDER); |
||
139 | // return BASS_MusicGetOrderPosition(hmod); |
||
140 | } |
||
141 | |||
142 | void GSHLE::stop_mod() |
||
143 | { |
||
144 | runBASS(); |
||
145 | if (!hmod) |
||
146 | return; |
||
147 | if(BASS::ChannelIsActive(hmod) != BASS_ACTIVE_PLAYING) |
||
148 | return; |
||
149 | if (!BASS::ChannelPause(hmod)) |
||
150 | reportError("BASS_ChannelPause() [music]"); |
||
151 | } |
||
152 | |||
153 | void GSHLE::cont_mod() |
||
154 | { |
||
155 | runBASS(); |
||
156 | if (!hmod) |
||
157 | return; |
||
158 | if (!BASS::ChannelPlay(hmod, TRUE)) |
||
159 | reportError("BASS_ChannelPlay() [music]"); |
||
160 | } |
||
161 | |||
162 | void GSHLE::startfx(CHANNEL *ch, float pan) |
||
163 | { |
||
164 | initChannels(); |
||
165 | |||
166 | float vol = (ch->volume * conf.sound.gs_vol) / float(8000*64); |
||
167 | if (!BASS::ChannelSetAttribute(ch->bass_ch, BASS_ATTRIB_VOL, vol)) |
||
168 | reportError("BASS_ChannelSetAttribute() [vol]"); |
||
169 | if (!BASS::ChannelSetAttribute(ch->bass_ch, BASS_ATTRIB_FREQ, float(ch->freq))) |
||
170 | reportError("BASS_ChannelSetAttribute() [freq]"); |
||
171 | if (!BASS::ChannelSetAttribute(ch->bass_ch, BASS_ATTRIB_PAN, pan)) |
||
172 | reportError("BASS_ChannelSetAttribute() [pan]"); |
||
173 | |||
174 | if (!BASS::ChannelPlay(ch->bass_ch, FALSE)) |
||
175 | reportError("BASS_ChannelPlay()"); |
||
176 | } |
||
177 | |||
178 | void GSHLE::flush_gs_frame() |
||
179 | { |
||
180 | unsigned lvl; |
||
181 | if (!hmod || (lvl = BASS::ChannelGetLevel(hmod)) == -1) lvl = 0; |
||
182 | |||
183 | gsleds[0].level = LOWORD(lvl) >> (15-4); |
||
184 | gsleds[0].attrib = 0x0D; |
||
185 | gsleds[1].level = HIWORD(lvl) >> (15-4); |
||
186 | gsleds[1].attrib = 0x0D; |
||
187 | |||
188 | for (int ch = 0; ch < 4; ch++) |
||
189 | { |
||
190 | if (chan[ch].bass_ch && (lvl = BASS::ChannelGetLevel(chan[ch].bass_ch)) != -1) |
||
191 | { |
||
192 | lvl = max(HIWORD(lvl), LOWORD(lvl)); |
||
193 | lvl >>= (15-4); |
||
194 | } |
||
195 | else |
||
196 | lvl = 0; |
||
197 | gsleds[ch+2].level = lvl; |
||
198 | gsleds[ch+2].attrib = 0x0F; |
||
199 | } |
||
200 | } |
||
201 | |||
202 | void GSHLE::debug_note(unsigned i) |
||
203 | { |
||
204 | GSHLE::CHANNEL ch = { 0 }; |
||
205 | ch.volume = 64; ch.ptr = 0; |
||
206 | ch.start = sample[i].start; |
||
207 | ch.loop = sample[i].loop; |
||
208 | ch.end = sample[i].end; |
||
209 | unsigned note = sample[i].note; if (note == 60) note = 50; |
||
210 | ch.freq = note2rate[note]; |
||
211 | ch.bass_ch = BASS::StreamCreate(11025, 1, BASS_SAMPLE_8BITS, gs_render, &ch); |
||
212 | startfx(&ch, 0); |
||
213 | unsigned mx = (sample[i].loop < sample[i].end)? 5000 : 10000; |
||
214 | for (unsigned j = 0; j < mx/256; j++) |
||
215 | { |
||
216 | if (!ch.start) |
||
217 | break; |
||
218 | Sleep(256); |
||
219 | } |
||
220 | BASS::StreamFree(ch.bass_ch); |
||
221 | } |
||
222 | #endif |