xoreos  0.0.5
fevfile.cpp
Go to the documentation of this file.
1 /* xoreos - A reimplementation of BioWare's Aurora engine
2  *
3  * xoreos is the legal property of its developers, whose names
4  * can be found in the AUTHORS file distributed with this source
5  * distribution.
6  *
7  * xoreos is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 3
10  * of the License, or (at your option) any later version.
11  *
12  * xoreos is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with xoreos. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
25 #include "src/common/endianness.h"
26 
27 #include "src/aurora/fevfile.h"
28 #include "src/aurora/resman.h"
29 
30 namespace Aurora {
31 
32 static const uint32 kFEVID = MKTAG('F', 'E', 'V', '1');
33 
36 
37  if (!fev)
38  throw Common::Exception("FEVFile::FEVFile(): Resource %s not found", resRef.c_str());
39 
40  load(*fev);
41 }
42 
44  load(fev);
45 }
46 
48  return _bankName;
49 }
50 
51 const std::vector<FEVFile::WaveBank> &FEVFile::getWaveBanks() {
52  return _waveBanks;
53 }
54 
55 const std::vector<FEVFile::Category> &FEVFile::getCategories() {
56  return _categories;
57 }
58 
60  const uint32 magic = fev.readUint32BE();
61  if (magic != kFEVID)
62  throw Common::Exception("FEVFile::load(): Invalid magic number");
63 
64  fev.skip(12); // Unknown values
65 
67 
68  const uint32 numWaveBanks = fev.readUint32LE();
69  _waveBanks.resize(numWaveBanks);
70  for (uint32 i = 0; i < numWaveBanks; ++i) {
71  WaveBank wb;
72 
73  wb.maxStreams = fev.readUint32LE();
74  const uint32 streamingType = fev.readUint32LE();
75 
76  switch (streamingType) {
77  default:
78  case 0x00010000:
80  break;
81  case 0x00020000:
83  break;
84  case 0x0B000000:
86  break;
87  }
88 
90 
91  _waveBanks[i] = wb;
92  }
93 
94  readCategory(fev);
95 
96  uint32 numEventGroups = fev.readUint32LE();
97  for (uint32 i = 0; i < numEventGroups; ++i) {
98  readEventCategory(fev);
99  }
100 
101  uint32 numSoundDefinitionTemplates = fev.readUint32LE();
102  std::vector<SoundDefinition> definitions(numSoundDefinitionTemplates);
103  for (uint32 i = 0; i < numSoundDefinitionTemplates; ++i) {
104  definitions[i].playMode = PlayMode(fev.readUint32LE());
105  definitions[i].spawnTimeMin = fev.readUint32LE();
106  definitions[i].spawnTimeMax = fev.readUint32LE();
107  definitions[i].maximumSpawnedSounds = fev.readUint32LE();
108  definitions[i].volume = fev.readIEEEFloatLE();
109 
110  fev.skip(12);
111 
112  definitions[i].volumeRandomization = fev.readIEEEFloatLE();
113  definitions[i].pitch = fev.readIEEEFloatLE();
114 
115  fev.skip(12);
116 
117  definitions[i].pitchRandomization = fev.readIEEEFloatLE();
118  definitions[i].position3DRandomization = fev.readIEEEFloatLE();
119  }
120 
121  uint32 numSoundDefinitions = fev.readUint32LE();
122  _definitions.resize(numSoundDefinitions);
123  for (uint32 i = 0; i < numSoundDefinitions; ++i) {
125  fev.skip(4);
126  uint32 templateId = fev.readUint32LE();
127 
128  SoundDefinition definition = definitions[templateId];
129 
130  definition.name = name;
131 
132  _definitions.push_back(definition);
133  }
134 }
135 
137  const Common::UString name = readLengthPrefixedString(fev);
138 
139  Category category;
140  category.volume = fev.readIEEEFloatLE();
141  category.pitch = fev.readIEEEFloatLE();
142 
143  fev.skip(8); // Unknown values
144 
145  const uint32 numSubCategories = fev.readUint32LE();
146  for (uint32 i = 0; i < numSubCategories; ++i) {
147  readCategory(fev);
148  }
149 
150  _categories.push_back(category);
151 }
152 
155 
156  // Read user properties
157  readProperties(fev);
158 
159  const uint32 numSubEventCategories = fev.readUint32LE();
160  const uint32 numEvents = fev.readUint32LE();
161 
162  for (uint32 i = 0; i < numSubEventCategories; ++i) {
163  readEventCategory(fev);
164  }
165 
166  for (uint32 i = 0; i < numEvents; ++i) {
167  readEvent(fev);
168  }
169 }
170 
172  Event event;
173 
174  fev.skip(4);
175 
176  event.name = readLengthPrefixedString(fev);
177 
178  event.volume = fev.readIEEEFloatLE();
179  event.pitch = fev.readIEEEFloatLE();
180  event.pitchRandomization = fev.readIEEEFloatLE();
181  event.volumeRandomization = fev.readIEEEFloatLE();
182  event.priority = fev.readUint32LE();
183  event.mode = fev.readUint32LE();
184  event.maxPlaybacks = fev.readUint32LE();
185 
186  fev.skip(12);
187 
188  event.Speaker2DL = fev.readIEEEFloatLE();
189  event.Speaker2DR = fev.readIEEEFloatLE();
190  event.Speaker2DC = fev.readIEEEFloatLE();
191 
192  event.SpeakerLFE = fev.readIEEEFloatLE();
193 
194  event.Speaker2DLR = fev.readIEEEFloatLE();
195  event.Speaker2DRR = fev.readIEEEFloatLE();
196  event.Speaker2DLS = fev.readIEEEFloatLE();
197  event.Speaker2DRS = fev.readIEEEFloatLE();
198 
199  fev.skip(20);
200 
201  event.ReverbDryLevel = fev.readIEEEFloatLE();
202  event.ReverbWetLevel = fev.readIEEEFloatLE();
203 
204  fev.skip(4);
205 
206  event.fadeInTime = fev.readUint32LE();
207  event.fadeOutTime = fev.readUint32LE();
208 
209  event.spawnIntensity = fev.readIEEEFloatLE();
210  event.spawnIntensityRandomization = fev.readIEEEFloatLE();
211 
212  fev.skip(26);
213 
214  event.userProperties = readProperties(fev);
215 
216  fev.skip(4); // Always 1?
217 
218  event.category = readLengthPrefixedString(fev);
219 
220  _events.push_back(event);
221 }
222 
223 std::map<Common::UString, FEVFile::Property> FEVFile::readProperties(Common::SeekableReadStream &fev) {
224  const uint32 numUserProperties = fev.readUint32LE();
225  std::map<Common::UString, FEVFile::Property> properties;
226  for (uint32 i = 0; i < numUserProperties; ++i) {
227  Common::UString propertyName = readLengthPrefixedString(fev);
228  Property property;
229  property.type = PropertyType(fev.readUint32LE());
230  switch (property.type) {
231  case kPropertyInt: // Integer value
232  property.value = fev.readSint32LE();
233  break;
234  case kPropertyFloat: // Floating point value
235  property.value = fev.readIEEEFloatLE();
236  break;
237  case kPropertyString: // String value
238  property.value = readLengthPrefixedString(fev);
239  break;
240  default:
241  throw Common::Exception("FEVFile::readEventCategory() Invalid property type %i", property.type);
242  }
243 
244  properties.insert(std::make_pair(propertyName, property));
245  }
246 
247  return properties;
248 }
249 
251  const uint32 length = fev.readUint32LE();
252  return Common::readStringFixed(fev, Common::kEncodingASCII, length);
253 }
254 
255 } // End of namespace Aurora
PropertyType
Possible Property types.
Definition: fevfile.h:63
void readEventCategory(Common::SeekableReadStream &fev)
Read a category for events.
Definition: fevfile.cpp:153
#define ResMan
Shortcut for accessing the sound manager.
Definition: resman.h:557
#define MKTAG(a0, a1, a2, a3)
A wrapper macro used around four character constants, like &#39;DATA&#39;, to ensure portability.
Definition: endianness.h:140
uint32 readUint32LE()
Read an unsigned 32-bit word stored in little endian (LSB first) order from the stream and return it...
Definition: readstream.h:133
PropertyType type
Definition: fevfile.h:71
const std::vector< Category > & getCategories()
Definition: fevfile.cpp:55
A class holding an UTF-8 string.
Definition: ustring.h:48
Some objects in FMOD can have generic properties.
Definition: fevfile.h:70
An FMOD event.
Definition: fevfile.h:101
std::vector< SoundDefinition > _definitions
Definition: fevfile.h:180
Low-level macros and functions to handle different endianness portably.
Common::UString _bankName
Definition: fevfile.h:175
Common::UString name
Definition: fevfile.h:79
A sound definition.
Definition: fevfile.h:137
FORCEINLINE int32 readSint32LE()
Read a signed 32-bit word stored in little endian (LSB first) order from the stream and return it...
Definition: readstream.h:195
A category which is organized hierarchically.
Definition: fevfile.h:83
const char * c_str() const
Return the (utf8 encoded) string data.
Definition: ustring.cpp:249
StreamingType streamingType
Definition: fevfile.h:78
virtual size_t skip(ptrdiff_t offset)
Skip the specified number of bytes, adding that offset to the current position in the stream...
Definition: readstream.h:317
A loader for FEV (FMOD Event) files.
StackException Exception
Definition: error.h:59
Reference to an external wave bank.
Definition: fevfile.h:76
std::map< Common::UString, Property > readProperties(Common::SeekableReadStream &fev)
Read properties.
Definition: fevfile.cpp:223
std::vector< Category > _categories
Definition: fevfile.h:178
FEVFile(const Common::UString &resRef)
Definition: fevfile.cpp:34
std::vector< Event > _events
Definition: fevfile.h:179
std::vector< WaveBank > _waveBanks
Definition: fevfile.h:177
uint32 readUint32BE()
Read an unsigned 32-bit word stored in big endian (MSB first) order from the stream and return it...
Definition: readstream.h:166
FORCEINLINE float readIEEEFloatLE()
Read a 32-bit IEEE float stored in little endian (LSB first) order from the stream and return it...
Definition: readstream.h:230
Plain, unextended ASCII (7bit clean).
Definition: encoding.h:40
FMOD Event.
Definition: types.h:309
static const uint32 kFEVID
Definition: fevfile.cpp:32
Common::UString readLengthPrefixedString(Common::SeekableReadStream &fev)
Read an FEV length prefixed string.
Definition: fevfile.cpp:250
uint32_t uint32
Definition: types.h:204
void load(Common::SeekableReadStream &fev)
Definition: fevfile.cpp:59
const std::vector< WaveBank > & getWaveBanks()
Definition: fevfile.cpp:51
UString readStringFixed(SeekableReadStream &stream, Encoding encoding, size_t length)
Read length bytes as a string with the given encoding out of a stream.
Definition: encoding.cpp:297
void readCategory(Common::SeekableReadStream &fev)
Read a general category.
Definition: fevfile.cpp:136
PlayMode
Possible Play modes.
Definition: fevfile.h:53
Interface for a seekable & readable data stream.
Definition: readstream.h:265
const Common::UString & getBankName()
Definition: fevfile.cpp:47
The global resource manager for Aurora resources.
void readEvent(Common::SeekableReadStream &fev)
Read an event.
Definition: fevfile.cpp:171