Subversion Repositories pentevo

Rev

Rev 883 | Details | Compare with Previous | Last modification | View Log | RSS feed

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