Avionics
Dropship Simulator
BASS.cpp
Go to the documentation of this file.
1 #include "BASS.h"
2 
3 namespace Devices
4 {
5  void Bass::EnumerateDevices() const
6  {
7  BASS_DEVICEINFO info;
8  for (int a = 1; BASS_GetDeviceInfo(a, &info); a++)
9  {
10  if (info.flags & BASS_DEVICE_ENABLED) // device is enabled
11  {
12  char msg[99];
13  sprintf_s(msg, 99, "Bass::Initialize Device Enumeration %i: %s", a, info.name);
14  logger->Log(msg);
15  }
16  }
17  }
18 
19  void Bass::Initialize(Logger* prmLogger, BassConfig* prmConfig, Bus* prmBus)
20  {
21  config = prmConfig;
22  bus = prmBus;
23  logger = prmLogger;
24 
25  if (config->soundDevice == -1)
26  {
28  }
29 
30  if (!BASS_Init(config->soundDevice, 44100, 0, nullptr, nullptr))
31  {
32  char msg[99];
33  sprintf_s(msg, 99, "Bass::Initialize BASS_Init failed: %i", config->soundDevice);
34  logger->Log(msg, Logger::Error, BASS_ErrorGetCode());
35  config->soundDevice = 0;
37  return;
38  }
39  else
40  {
41  char msg[99];
42  sprintf_s(msg, 99, "Bass::Initialize BASS_Init success for device %i", config->soundDevice);
43  logger->Log(msg);
44  }
45 
46  if (!BASS_SetVolume(config->initialVolume))
47  {
48  logger->Log("Bass::Initialize BASS_SetVolume failed", Logger::Error, BASS_ErrorGetCode());
49  config->soundDevice = 0;
50  return;
51  }
52 
53  for (UINT i = 0; i < config->sounds.size(); i++)
54  {
55  DWORD flags = 0;
56  if (config->sounds.at(i).loop) flags |= BASS_SAMPLE_LOOP ;
57  if (config->sounds.at(i).mono) flags |= BASS_SAMPLE_MONO ;
58 
59  config->sounds.at(i).sample = BASS_SampleLoad(false, config->sounds.at(i).path.c_str(), 0L, 0L, 1L, flags);
60  if (!config->sounds.at(i).sample)
61  {
62  char msg[99];
63  sprintf_s(msg, sizeof(msg), "Bass::Initialize BASS_SampleLoad failed: %s", config->sounds.at(i).path.c_str());
64  logger->Log(msg, Logger::Error, BASS_ErrorGetCode());
65  }
66  }
67  }
68 
70  {
71  if (config->soundDevice > 0)
72  {
73  if (!BASS_SetDevice(config->soundDevice))
74  {
75  logger->Log("Bass::FrameMove BASS_SetDevice failed", Logger::Error, BASS_ErrorGetCode());
76  return;
77  }
78  }
79 
80  if (lastPlaying && BASS_ChannelIsActive(lastPlaying) == BASS_ACTIVE_STOPPED)
81  lastPlaying = NULL;
82 
83  for (UINT i = 0; i < bus->commandStream.size(); i++)
84  {
85  Command command = bus->commandStream.at(i);
86  if (command.delay != 0.0f) continue;
87 
88  bool processedOne = false;
89  for (UINT j = 0; j < config->sounds.size(); j++)
90  {
91  if (command.name == config->sounds.at(j).trigger)
92  {
93  char msg[99];
94  sprintf_s(msg, 99, "Bass::FrameMove Playing sample: %s (device %i)", command.name.c_str(), config->soundDevice);
95  logger->Log(msg);
96 
97  Play(command.name);
98 
99  bus->commandStream.erase(bus->commandStream.begin() + i);
100  processedOne = true;
101  break;
102  }
103  }
104 
105  if (processedOne)
106  break;
107  }
108  }
109 
110  void Bass::Destroy() const
111  {
112  logger->Log("Bass::Destroy...");
113  if (config->soundDevice > 0)
114  {
115  if (!BASS_SetDevice(config->soundDevice))
116  {
117  logger->Log("Bass::Destroy BASS_SetDevice failed!", Logger::Error, BASS_ErrorGetCode());
118  }
119  }
120  if (!BASS_Free())
121  {
122  logger->Log("Bass::Destroy BASS_Free failed!", Logger::Error, BASS_ErrorGetCode());
123  }
124  }
125 
126  void Bass::Play(std::string trigger, float freq, float vol)
127  {
128  if (config->soundDevice > 0)
129  {
130  if (!BASS_SetDevice(config->soundDevice))
131  {
132  logger->Log("Bass::Play BASS_SetDevice failed", Logger::Error, BASS_ErrorGetCode());
133  return;
134  }
135  }
136  else if (config->soundDevice == 0)
137  return;
138 
139  for (UINT j = 0; j < config->sounds.size(); j++)
140  {
141  if (config->sounds.at(j).trigger == trigger)
142  {
143  // create channel if we don't have one
144  if (!config->sounds.at(j).channel)
145  {
146  char msg[99];
147  sprintf_s(msg, 99, "Bass::Play Need channel for sample: %s (device %i)", config->sounds.at(j).trigger.c_str(), config->soundDevice);
148  logger->Log(msg);
149  config->sounds.at(j).channel = BASS_SampleGetChannel(config->sounds.at(j).sample, false);
150  }
151  // make sure we created one
152  if (!config->sounds.at(j).channel)
153  {
154  logger->Log("Bass::Play BASS_SampleGetChannel failed!", Logger::Error, BASS_ErrorGetCode());
155  return;
156  }
157  // new channel needs to be initialized with constant settings
158  else if (!BASS_ChannelSetAttribute(config->sounds.at(j).channel, BASS_ATTRIB_PAN, config->sounds.at(j).pan))
159  {
160  if (BASS_ErrorGetCode() == BASS_ERROR_HANDLE)
161  {
162  config->sounds.at(j).channel = BASS_SampleGetChannel(config->sounds.at(j).sample, false);
163  if (!config->sounds.at(j).channel)
164  {
165  logger->Log("Bass::Play BASS_SampleGetChannel failed!", Logger::Error, BASS_ErrorGetCode());
166  return;
167  }
168  }
169  else
170  {
171  char msg[199];
172  sprintf_s(msg, 199, "Bass::Play BASS_ChannelSetAttribute BASS_ATTRIB_PAN failed: %s (%.1f)", config->sounds.at(j).trigger.c_str(), config->sounds.at(j).pan);
173  logger->Log(msg, Logger::Warn, BASS_ErrorGetCode());
174  return;
175  }
176  }
177 
178  // freq
179  if (freq != -1.0f && !BASS_ChannelSetAttribute(config->sounds.at(j).channel, BASS_ATTRIB_FREQ, max(100, freq*config->sounds.at(j).baseHz)))
180  {
181  logger->Log("Bass::Play BASS_ChannelSetAttribute BASS_ATTRIB_FREQ failed!", Logger::Error, BASS_ErrorGetCode());
182  return;
183  }
184 
185  // volume
186  if (!BASS_ChannelSetAttribute(config->sounds.at(j).channel, BASS_ATTRIB_VOL, vol))
187  {
188  logger->Log("Bass::Play BASS_ChannelSetAttribute BASS_ATTRIB_VOL failed!", Logger::Error, BASS_ErrorGetCode());
189  return;
190  }
191  // if it loops do we have to call "play"?
192  int channelIsActive = BASS_ChannelIsActive(config->sounds.at(j).channel);
193  if (!config->sounds.at(j).loop || channelIsActive == BASS_ACTIVE_STOPPED || channelIsActive == BASS_ACTIVE_PAUSED || config->sounds.at(j).restart)
194  {
195  if (!BASS_ChannelPlay(config->sounds.at(j).sample, config->sounds.at(j).restart))
196  {
197  logger->Log("Bass::Play BASS_ChannelPlay failed!", Logger::Error, BASS_ErrorGetCode());
198  return;
199  }
200  else
201  {
202  lastPlaying = config->sounds.at(j).channel;
203  }
204  }
205  return;
206  }
207  }
208  char msg[99];
209  sprintf_s(msg, 99, "Bass::Play Could not find sound for trigger: %s (device %i)", trigger.c_str(), config->soundDevice);
210  logger->Log(msg);
211  }
212 
213  bool Bass::IsPlaying() const
214  {
215  return lastPlaying != NULL;
216  }
217 
218  void Bass::StopAll() const
219  {
220  for (UINT i = 0; i < config->sounds.size(); i++)
221  {
222  BASS_ChannelStop(config->sounds.at(i).channel);
223  }
224  }
225 
226  HSTREAM Bass::PlayStream(std::string filename) const
227  {
228  if (config->soundDevice > 0)
229  {
230  if (!BASS_SetDevice(config->soundDevice))
231  {
232  logger->Log("Bass::PlayStream BASS_SetDevice failed", Logger::Error, BASS_ErrorGetCode());
233  return 0;
234  }
235  }
236  else if (config->soundDevice == 0)
237  return 0;
238 
239  HSTREAM streamHandle = BASS_StreamCreateFile(false, filename.c_str(), 0, 0, BASS_SAMPLE_MONO);
240  if (!streamHandle)
241  logger->Log("Bass::PlayStream BASS_StreamCreateFile error", Logger::Error, BASS_ErrorGetCode());
242  else if (!BASS_ChannelPlay(streamHandle, FALSE))
243  logger->Log("Bass::PlayStream BASS_ChannelPlay error", Logger::Error, BASS_ErrorGetCode());
244  return streamHandle;
245  }
246 
247  bool Bass::StreamIsPlaying(HSTREAM streamHandle) const
248  {
249  if (config->soundDevice > 0)
250  {
251  if (!BASS_SetDevice(config->soundDevice))
252  {
253  logger->Log("Bass::StreamIsPlaying BASS_SetDevice failed", Logger::Error, BASS_ErrorGetCode());
254  return false;
255  }
256  }
257  else if (config->soundDevice == 0)
258  return false;
259 
260  int isActive = BASS_ChannelIsActive(streamHandle);
261  if (isActive == BASS_ACTIVE_PLAYING)
262  return true;
263  if (!BASS_StreamFree(streamHandle))
264  logger->Log("Bass::PlayStream BASS_StreamFree error", Logger::Error, BASS_ErrorGetCode());
265  return false;
266  }
267 }
std::vector< Command > commandStream
Definition: Bus.h:20
Logger * logger
Definition: BASS.h:40
Definition: Logger.h:5
void FrameMove()
Definition: BASS.cpp:69
okay, the portable keyboard numbers don&#39;t work like the outside keypad because the outside keypad is ...
Definition: Analog.cpp:3
std::vector< Sound > sounds
Definition: BASS.h:34
Definition: Bus.h:12
std::string name
command name
Definition: Command.h:11
BassConfig * config
Definition: BASS.h:41
HCHANNEL lastPlaying
Definition: BASS.h:44
float initialVolume
Definition: BASS.h:17
Definition: Command.h:5
HSTREAM PlayStream(std::string filename) const
Definition: BASS.cpp:226
void Log(const char *msg, Level level=Info, int errorCode=0)
These have to be in this order.
Definition: Logger.cpp:16
void Play(std::string trigger, float freq=-1.0f, float vol=1.0f)
Definition: BASS.cpp:126
void Initialize(Logger *prmLogger, BassConfig *prmConfig, Bus *prmBus)
Definition: BASS.cpp:19
bool StreamIsPlaying(HSTREAM streamHandle) const
Definition: BASS.cpp:247
float delay
wait number of seconds before executing command
Definition: Command.h:8
int soundDevice
The device to use... -1 = default device, 0 = no sound, 1 = first real output device. BASS_GetDeviceInfo can be used to enumerate the available devices.
Definition: BASS.h:16
Bus * bus
Definition: BASS.h:42
bool IsPlaying() const
Definition: BASS.cpp:213
void EnumerateDevices() const
Definition: BASS.cpp:5
void StopAll() const
Definition: BASS.cpp:218
void Destroy() const
Definition: BASS.cpp:110