1 /* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */
2
3 #include "SoundItem.h"
4
5 #include <sstream>
6 #include <stdexcept>
7 #include <cfloat>
8
9 #include "SoundBuffer.h"
10 #include "System/UnsyncedRNG.h"
11
12 namespace
13 {
14 UnsyncedRNG randnum; // no need for strong randomness here, so default seed is ok
15
16 template <typename T>
MapEntryValExtract(const std::map<std::string,std::string> & map,const std::string & key,T & t)17 inline bool MapEntryValExtract(const std::map<std::string, std::string>& map, const std::string& key, T& t)
18 {
19 std::map<std::string, std::string>::const_iterator it = map.find(key);
20 if (it != map.end())
21 {
22 std::istringstream stream(it->second);
23 stream >> t;
24 return true;
25 }
26 else
27 return false;
28 }
29
30 template <typename T>
FitInIntervall(const T & lower,T & val,const T & upper)31 void FitInIntervall(const T& lower, T& val, const T& upper)
32 {
33 val = std::max(std::min(val, upper), lower);
34 }
35 }
36
SoundItem(boost::shared_ptr<SoundBuffer> _buffer,const std::map<std::string,std::string> & items)37 SoundItem::SoundItem(boost::shared_ptr<SoundBuffer> _buffer, const std::map<std::string, std::string>& items)
38 : buffer(_buffer)
39 , gain(1.0)
40 , gainMod(0)
41 , pitch(1.0)
42 , pitchMod(0)
43 , dopplerScale(1.0)
44 , maxDist(FLT_MAX)
45 , rolloff(1.0f)
46 , priority(0)
47 , maxConcurrent(16)
48 , currentlyPlaying(0)
49 , loopTime(0)
50 , in3D(true)
51 {
52 if (!MapEntryValExtract(items, "name", name))
53 name = buffer->GetFilename();
54
55 MapEntryValExtract(items, "gain", gain);
56 MapEntryValExtract(items, "gainmod", gainMod);
57 FitInIntervall(0.f, gainMod, 1.f);
58 MapEntryValExtract(items, "pitch", pitch);
59 MapEntryValExtract(items, "pitchmod", pitchMod);
60 FitInIntervall(0.f, pitchMod, 1.f);
61 MapEntryValExtract(items, "dopplerscale", dopplerScale);
62 MapEntryValExtract(items, "priority", priority);
63 MapEntryValExtract(items, "maxconcurrent", maxConcurrent);
64 MapEntryValExtract(items, "maxdist", maxDist);
65 MapEntryValExtract(items, "rolloff", rolloff);
66 MapEntryValExtract(items, "in3d", in3D);
67 MapEntryValExtract(items, "looptime", loopTime);
68 }
69
PlayNow()70 bool SoundItem::PlayNow()
71 {
72 if (maxConcurrent >= currentlyPlaying)
73 {
74 currentlyPlaying++;
75 return true;
76 }
77 else
78 {
79 return false;
80 }
81 }
82
StopPlay()83 void SoundItem::StopPlay()
84 {
85 assert(currentlyPlaying > 0);
86 --currentlyPlaying;
87 }
88
GetGain() const89 float SoundItem::GetGain() const
90 {
91 float tgain = 0;
92 if (gainMod > 0)
93 tgain = (float(randnum(200))/100.f - 1.f)*gainMod;
94 return gain * (1.f + tgain);
95 }
96
GetPitch() const97 float SoundItem::GetPitch() const
98 {
99 float tpitch = 0;
100 if (pitchMod > 0)
101 tpitch = (float(randnum(200))/100.f - 1.f)*pitchMod;
102 return pitch * (1.f + tpitch);
103 }
104