17 | function SoundMixer.new(customMt) |
18 | |
19 | local self = {} |
20 | setmetatable(self, customMt or SoundMixer_mt) |
21 | |
22 | g_messageCenter:subscribe(MessageType.GAME_STATE_CHANGED, self.onGameStateChanged, self) |
23 | |
24 | local xmlFilename = "dataS/soundMixer.xml" |
25 | local xmlFile = loadXMLFile("soundMixerXML", xmlFilename) |
26 | |
27 | self.volumeFactors = {} |
28 | for _, groupIndex in pairs(AudioGroup) do |
29 | self.volumeFactors[groupIndex] = 1 |
30 | end |
31 | |
32 | self.masterVolume = 1 |
33 | |
34 | self.gameStates = {} |
35 | |
36 | if xmlFile ~= nil and xmlFile ~= 0 then |
37 | local i = 0 |
38 | while true do |
39 | local key = string.format("soundMixer.gameState(%d)", i) |
40 | if not hasXMLProperty(xmlFile, key) then |
41 | break |
42 | end |
43 | |
44 | local gameStateName = getXMLString(xmlFile, key.."#name") |
45 | local gameStateIndex = g_gameStateManager:getGameStateIndexByName(gameStateName) |
46 | if gameStateIndex ~= nil then |
47 | local gameState = {} |
48 | gameState.audioGroups = {} |
49 | |
50 | local j = 0 |
51 | while true do |
52 | local audioGroupKey = string.format("%s.audioGroup(%d)", key, j) |
53 | if not hasXMLProperty(xmlFile, audioGroupKey) then |
54 | break |
55 | end |
56 | |
57 | local name = getXMLString(xmlFile, audioGroupKey.."#name") |
58 | local volume = getXMLFloat(xmlFile, audioGroupKey.."#volume") or 1.0 |
59 | local audioGroupIndex = AudioGroup.getAudioGroupIndexByName(name) |
60 | |
61 | if audioGroupIndex ~= nil then |
62 | local group = {} |
63 | group.index = audioGroupIndex |
64 | group.volume = volume |
65 | gameState.audioGroups[audioGroupIndex] = group |
66 | else |
67 | print(string.format("Warning: Audio-Group '%s' is not defined for audio-group '%s'!", tostring(name), key)) |
68 | end |
69 | |
70 | j = j + 1 |
71 | end |
72 | |
73 | self.gameStates[gameStateIndex] = gameState |
74 | else |
75 | print(string.format("Warning: Game-State '%s' is not defined for state '%s'!", tostring(gameStateName), key)) |
76 | end |
77 | |
78 | i = i + 1 |
79 | end |
80 | |
81 | delete(xmlFile) |
82 | |
83 | else |
84 | print("Error: SoundMixer could not load configuration file!") |
85 | end |
86 | |
87 | self.volumes = {} |
88 | local gameState = self.gameStates[GameState.LOADING] |
89 | if gameState ~= nil then |
90 | for _, groupIndex in ipairs(AudioGroup.groups) do |
91 | local volume = gameState.audioGroups[groupIndex].volume or 1 |
92 | self.volumes[groupIndex] = {volume = volume, listeners = {}} |
93 | setAudioGroupVolume(groupIndex, volume) |
94 | end |
95 | end |
96 | |
97 | return self |
98 | end |
108 | function SoundMixer:update(dt) |
109 | if self.isDirty then |
110 | local gameStateIndex = g_gameStateManager:getGameState() |
111 | local gameState = self.gameStates[gameStateIndex] |
112 | if gameState ~= nil then |
113 | local isDone = true |
114 | for audioGroupIndex, audioGroup in pairs(gameState.audioGroups) do |
115 | local currentVolume = self.volumes[audioGroupIndex].volume |
116 | local target = audioGroup.volume * self.volumeFactors[audioGroupIndex] |
117 | if currentVolume ~= target then |
118 | isDone = false |
119 | |
120 | local dir = 1 |
121 | local func = math.min |
122 | if currentVolume > target then |
123 | dir = -1 |
124 | func = math.max |
125 | end |
126 | |
127 | currentVolume = func(currentVolume + dir * dt/500, target) |
128 | setAudioGroupVolume(audioGroupIndex, currentVolume) |
129 | self.volumes[audioGroupIndex].volume = currentVolume |
130 | for _, listener in ipairs(self.volumes[audioGroupIndex].listeners) do |
131 | listener.func(listener.target, audioGroupIndex, currentVolume) |
132 | end |
133 | end |
134 | end |
135 | |
136 | if isDone then |
137 | self.isDirty = false |
138 | end |
139 | end |
140 | end |
141 | end |