Skip to main content

rpfm_lib/files/sound_bank_database/
mod.rs

1//---------------------------------------------------------------------------//
2// Copyright (c) 2017-2026 Ismael Gutiérrez González. All rights reserved.
3//
4// This file is part of the Rusted PackFile Manager (RPFM) project,
5// which can be found here: https://github.com/Frodo45127/rpfm.
6//
7// This file is licensed under the MIT license, which can be found here:
8// https://github.com/Frodo45127/rpfm/blob/master/LICENSE.
9//---------------------------------------------------------------------------//
10
11//! Sound bank database for older Total War games.
12//!
13//! This module handles the `sound_bank_database` file found in Shogun 2 (and possibly
14//! Napoleon and Empire). This file maps game events to sound bank event records,
15//! allowing the game to trigger appropriate sounds based on gameplay actions.
16//!
17//! The database contains multiple categories of bank events, each linking event record
18//! indices to various parameters that control when and how sounds are triggered.
19//!
20//! These files are not versioned, so only the latest format per game is supported.
21//!
22//! Note: Most of this format is not fully understood. Only `BankEventProjectileFire`
23//! has partially identified fields.
24
25use getset::*;
26use serde_derive::{Serialize, Deserialize};
27
28use crate::binary::{ReadBytes, WriteBytes};
29use crate::error::{Result, RLibError};
30use crate::files::{DecodeableExtraData, Decodeable, EncodeableExtraData, Encodeable};
31use crate::games::supported_games::KEY_SHOGUN_2;
32use crate::utils::check_size_mismatch;
33
34/// Path to the sound bank database file within a pack.
35pub const PATH: &str = "sounds_packed/sound_bank_database";
36
37mod games;
38
39#[cfg(test)] mod sound_bank_database_test;
40
41//---------------------------------------------------------------------------//
42//                              Enum & Structs
43//---------------------------------------------------------------------------//
44
45/// Sound bank database mapping game events to sound events.
46///
47/// Contains multiple categories of bank events that link event record indices
48/// (referencing the sound_events file) to parameter sets that control sound triggering.
49///
50/// Note: Most fields in this format are not fully understood and are marked as `uk_*`
51/// or have generic parameter names.
52#[derive(Default, PartialEq, Clone, Debug, Getters, MutGetters, Setters, Serialize, Deserialize)]
53#[getset(get = "pub", get_mut = "pub", set = "pub")]
54pub struct SoundBankDatabase {
55    /// Unknown float parameters.
56    uk_1: Vec<f32>,
57
58    /// Bank event category 0 (unknown purpose).
59    bank_event_uk_0: Vec<BankEventUk0>,
60    /// Bank events for projectile firing sounds.
61    bank_event_projectile_fire: Vec<BankEventProjectileFire>,
62    /// Bank event category 2 (unknown purpose).
63    bank_event_uk_2: Vec<BankEventUk2>,
64    /// Bank event category 3 (unknown purpose).
65    bank_event_uk_3: Vec<BankEventUk3>,
66    /// Bank event category 4 (unknown purpose).
67    bank_event_uk_4: Vec<BankEventUk4>,
68    /// Bank event category 5 (unknown purpose).
69    bank_event_uk_5: Vec<BankEventUk5>,
70    /// Bank event category 6 (unknown purpose).
71    bank_event_uk_6: Vec<BankEventUk6>,
72    /// Bank event category 7 (unknown purpose).
73    bank_event_uk_7: Vec<BankEventUk7>,
74    /// Bank event category 8 (unknown purpose).
75    bank_event_uk_8: Vec<BankEventUk8>,
76    /// Bank event category 9 (unknown purpose).
77    bank_event_uk_9: Vec<BankEventUk9>,
78    /// Bank event category 10 (unknown purpose).
79    bank_event_uk_10: Vec<BankEventUk10>,
80    /// Bank event category 11 (unknown purpose).
81    bank_event_uk_11: Vec<BankEventUk11>,
82    /// Bank event category 12 (unknown purpose).
83    bank_event_uk_12: Vec<BankEventUk12>,
84    /// Bank event category 13 (unknown purpose).
85    bank_event_uk_13: Vec<BankEventUk13>,
86    /// Bank event category 14 (unknown purpose).
87    bank_event_uk_14: Vec<BankEventUk14>,
88    /// Bank event category 15 (unknown purpose).
89    bank_event_uk_15: Vec<BankEventUk15>,
90    /// Bank event category 16 (unknown purpose).
91    bank_event_uk_16: Vec<BankEventUk16>,
92    /// Bank event category 17 (unknown purpose).
93    bank_event_uk_17: Vec<BankEventUk17>,
94    /// Bank event category 18 (unknown purpose).
95    bank_event_uk_18: Vec<BankEventUk18>,
96    /// Bank event category 19 (unknown purpose).
97    bank_event_uk_19: Vec<BankEventUk19>,
98    /// Bank event category 20 (unknown purpose).
99    bank_event_uk_20: Vec<BankEventUk20>,
100    /// Bank event category 21 (unknown purpose).
101    bank_event_uk_21: Vec<BankEventUk21>,
102    /// Bank event category 22 (unknown purpose).
103    bank_event_uk_22: Vec<BankEventUk22>,
104    /// Bank event category 23 (unknown purpose).
105    bank_event_uk_23: Vec<BankEventUk23>,
106    /// Bank event category 24 (unknown purpose).
107    bank_event_uk_24: Vec<BankEventUk24>,
108
109    /// Unknown data section.
110    uk_2: Vec<Uk1>,
111}
112
113/// Bank event with unknown purpose (category 0).
114#[derive(Default, PartialEq, Clone, Debug, Getters, MutGetters, Setters, Serialize, Deserialize)]
115#[getset(get = "pub", get_mut = "pub", set = "pub")]
116pub struct BankEventUk0 {
117    /// Index into the sound_events event_records array.
118    event_record_index: u32,
119    /// Parameter set 1.
120    params_1: Vec<u32>,
121    /// Parameter set 2.
122    params_2: Vec<u32>,
123    /// Parameter set 3.
124    params_3: Vec<u32>,
125    /// Parameter set 4.
126    params_4: Vec<u32>,
127}
128
129/// Bank event for projectile firing sounds.
130///
131/// This is the only partially understood bank event type. It maps projectile
132/// firing actions to sound events based on weapon and projectile characteristics.
133#[derive(Default, PartialEq, Clone, Debug, Getters, MutGetters, Setters, Serialize, Deserialize)]
134#[getset(get = "pub", get_mut = "pub", set = "pub")]
135pub struct BankEventProjectileFire {
136    /// Index into the sound_events event_records array.
137    event_record_index: u32,
138    /// Gun type identifiers that trigger this sound.
139    gun_types: Vec<u32>,
140    /// Shot type identifiers.
141    shot_types: Vec<u32>,
142    /// Projectile size categories.
143    projectile_sizes: Vec<u32>,
144    /// Unknown parameter set 4.
145    params_4: Vec<u32>,
146    /// Unit indices that use this sound.
147    unit_indexes: Vec<u32>,
148}
149
150/// Bank event with unknown purpose (category 2).
151#[derive(Default, PartialEq, Clone, Debug, Getters, MutGetters, Setters, Serialize, Deserialize)]
152#[getset(get = "pub", get_mut = "pub", set = "pub")]
153pub struct BankEventUk2 {
154    /// Index into the sound_events event_records array.
155    event_record_index: u32,
156    /// Parameter set 1.
157    params_1: Vec<u32>,
158    /// Parameter set 2.
159    params_2: Vec<u32>,
160    /// Parameter set 3.
161    params_3: Vec<u32>,
162    /// Parameter set 4.
163    params_4: Vec<u32>,
164}
165
166/// Bank event with unknown purpose (category 3).
167#[derive(Default, PartialEq, Clone, Debug, Getters, MutGetters, Setters, Serialize, Deserialize)]
168#[getset(get = "pub", get_mut = "pub", set = "pub")]
169pub struct BankEventUk3 {
170    /// Index into the sound_events event_records array.
171    event_record_index: u32,
172    /// Parameter set 1.
173    params_1: Vec<u32>,
174    /// Parameter set 2.
175    params_2: Vec<u32>,
176    /// Parameter set 3.
177    params_3: Vec<u32>,
178}
179
180/// Bank event with unknown purpose (category 4).
181#[derive(Default, PartialEq, Clone, Debug, Getters, MutGetters, Setters, Serialize, Deserialize)]
182#[getset(get = "pub", get_mut = "pub", set = "pub")]
183pub struct BankEventUk4 {
184    /// Index into the sound_events event_records array.
185    event_record_index: u32,
186    /// Parameter set 1.
187    params_1: Vec<u32>,
188    /// Parameter set 2.
189    params_2: Vec<u32>,
190}
191
192/// Bank event with unknown purpose (category 5).
193#[derive(Default, PartialEq, Clone, Debug, Getters, MutGetters, Setters, Serialize, Deserialize)]
194#[getset(get = "pub", get_mut = "pub", set = "pub")]
195pub struct BankEventUk5 {
196    /// Index into the sound_events event_records array.
197    event_record_index: u32,
198    /// Parameter set 1.
199    params_1: Vec<u32>,
200    /// Parameter set 2.
201    params_2: Vec<u32>,
202    /// Parameter set 3.
203    params_3: Vec<u32>,
204    /// Parameter set 4.
205    params_4: Vec<u32>,
206}
207
208/// Bank event with unknown purpose (category 6).
209#[derive(Default, PartialEq, Clone, Debug, Getters, MutGetters, Setters, Serialize, Deserialize)]
210#[getset(get = "pub", get_mut = "pub", set = "pub")]
211pub struct BankEventUk6 {
212    /// Index into the sound_events event_records array.
213    event_record_index: u32,
214    /// Parameter set 1.
215    params_1: Vec<u32>,
216    /// Parameter set 2.
217    params_2: Vec<u32>,
218    /// Parameter set 3.
219    params_3: Vec<u32>,
220    /// Parameter set 4.
221    params_4: Vec<u32>,
222    /// Parameter set 5 (byte values).
223    params_5: Vec<u8>,
224    /// Parameter set 6 (byte values).
225    params_6: Vec<u8>,
226    /// Parameter set 7.
227    params_7: Vec<u32>,
228}
229
230/// Bank event with unknown purpose (category 7).
231#[derive(Default, PartialEq, Clone, Debug, Getters, MutGetters, Setters, Serialize, Deserialize)]
232#[getset(get = "pub", get_mut = "pub", set = "pub")]
233pub struct BankEventUk7 {
234    /// Index into the sound_events event_records array.
235    event_record_index: u32,
236    /// Parameter set 1.
237    params_1: Vec<u32>,
238    /// Parameter set 2.
239    params_2: Vec<u32>,
240    /// Parameter set 3.
241    params_3: Vec<u32>,
242    /// Parameter set 4.
243    params_4: Vec<u32>,
244    /// Parameter set 5.
245    params_5: Vec<u32>,
246}
247
248/// Bank event with unknown purpose (category 8).
249#[derive(Default, PartialEq, Clone, Debug, Getters, MutGetters, Setters, Serialize, Deserialize)]
250#[getset(get = "pub", get_mut = "pub", set = "pub")]
251pub struct BankEventUk8 {
252    /// Index into the sound_events event_records array.
253    event_record_index: u32,
254    /// Parameter set 1.
255    params_1: Vec<u32>,
256    /// Parameter set 2.
257    params_2: Vec<u32>,
258    /// Parameter set 3.
259    params_3: Vec<u32>,
260    /// Parameter set 4.
261    params_4: Vec<u32>,
262}
263
264/// Bank event with unknown purpose (category 9).
265#[derive(Default, PartialEq, Clone, Debug, Getters, MutGetters, Setters, Serialize, Deserialize)]
266#[getset(get = "pub", get_mut = "pub", set = "pub")]
267pub struct BankEventUk9 {
268    /// Index into the sound_events event_records array.
269    event_record_index: u32,
270    /// Parameter set 1.
271    params_1: Vec<u32>,
272    /// Parameter set 2.
273    params_2: Vec<u32>,
274}
275
276/// Bank event with unknown purpose (category 10).
277#[derive(Default, PartialEq, Clone, Debug, Getters, MutGetters, Setters, Serialize, Deserialize)]
278#[getset(get = "pub", get_mut = "pub", set = "pub")]
279pub struct BankEventUk10 {
280    /// Index into the sound_events event_records array.
281    event_record_index: u32,
282    /// Parameter set 1.
283    params_1: Vec<u32>,
284    /// Parameter set 2.
285    params_2: Vec<u32>,
286}
287
288/// Bank event with unknown purpose (category 11).
289#[derive(Default, PartialEq, Clone, Debug, Getters, MutGetters, Setters, Serialize, Deserialize)]
290#[getset(get = "pub", get_mut = "pub", set = "pub")]
291pub struct BankEventUk11 {
292    /// Index into the sound_events event_records array.
293    event_record_index: u32,
294    /// Parameter set 1.
295    params_1: Vec<u32>,
296}
297
298/// Bank event with unknown purpose (category 12).
299#[derive(Default, PartialEq, Clone, Debug, Getters, MutGetters, Setters, Serialize, Deserialize)]
300#[getset(get = "pub", get_mut = "pub", set = "pub")]
301pub struct BankEventUk12 {
302    /// Index into the sound_events event_records array.
303    event_record_index: u32,
304    /// Parameter set 1.
305    params_1: Vec<u32>,
306    /// Parameter set 2.
307    params_2: Vec<u32>,
308    /// Parameter set 3.
309    params_3: Vec<u32>,
310    /// Parameter set 4.
311    params_4: Vec<u32>,
312    /// Parameter set 5.
313    params_5: Vec<u32>,
314    /// Parameter set 6.
315    params_6: Vec<u32>,
316}
317
318/// Bank event with unknown purpose (category 13).
319#[derive(Default, PartialEq, Clone, Debug, Getters, MutGetters, Setters, Serialize, Deserialize)]
320#[getset(get = "pub", get_mut = "pub", set = "pub")]
321pub struct BankEventUk13 {
322    /// Index into the sound_events event_records array.
323    event_record_index: u32,
324    /// Parameter set 1.
325    params_1: Vec<u32>,
326    /// Parameter set 2.
327    params_2: Vec<u32>,
328    /// Parameter set 3.
329    params_3: Vec<u32>,
330    /// Parameter set 4.
331    params_4: Vec<u32>,
332}
333
334/// Bank event with unknown purpose (category 14).
335#[derive(Default, PartialEq, Clone, Debug, Getters, MutGetters, Setters, Serialize, Deserialize)]
336#[getset(get = "pub", get_mut = "pub", set = "pub")]
337pub struct BankEventUk14 {
338    /// Index into the sound_events event_records array.
339    event_record_index: u32,
340    /// Parameter set 1.
341    params_1: Vec<u32>,
342    /// Parameter set 2.
343    params_2: Vec<u32>,
344    /// Parameter set 3.
345    params_3: Vec<u32>,
346    /// Parameter set 4.
347    params_4: Vec<u32>,
348}
349
350/// Bank event with unknown purpose (category 15).
351#[derive(Default, PartialEq, Clone, Debug, Getters, MutGetters, Setters, Serialize, Deserialize)]
352#[getset(get = "pub", get_mut = "pub", set = "pub")]
353pub struct BankEventUk15 {
354    /// Index into the sound_events event_records array.
355    event_record_index: u32,
356    /// Parameter set 1.
357    params_1: Vec<u32>,
358    /// Parameter set 2.
359    params_2: Vec<u32>,
360    /// Parameter set 3.
361    params_3: Vec<u32>,
362    /// Parameter set 4.
363    params_4: Vec<u32>,
364    /// Parameter set 5.
365    params_5: Vec<u32>,
366    /// Parameter set 6.
367    params_6: Vec<u32>,
368}
369
370/// Bank event with unknown purpose (category 16).
371#[derive(Default, PartialEq, Clone, Debug, Getters, MutGetters, Setters, Serialize, Deserialize)]
372#[getset(get = "pub", get_mut = "pub", set = "pub")]
373pub struct BankEventUk16 {
374    /// Index into the sound_events event_records array.
375    event_record_index: u32,
376    /// Parameter set 1.
377    params_1: Vec<u32>,
378    /// Parameter set 2.
379    params_2: Vec<u32>,
380}
381
382/// Bank event with unknown purpose (category 17).
383#[derive(Default, PartialEq, Clone, Debug, Getters, MutGetters, Setters, Serialize, Deserialize)]
384#[getset(get = "pub", get_mut = "pub", set = "pub")]
385pub struct BankEventUk17 {
386    /// Index into the sound_events event_records array.
387    event_record_index: u32,
388    /// Parameter set 1.
389    params_1: Vec<u32>,
390    /// Parameter set 2.
391    params_2: Vec<u32>,
392    /// Parameter set 3.
393    params_3: Vec<u32>,
394}
395
396/// Bank event with unknown purpose (category 18).
397#[derive(Default, PartialEq, Clone, Debug, Getters, MutGetters, Setters, Serialize, Deserialize)]
398#[getset(get = "pub", get_mut = "pub", set = "pub")]
399pub struct BankEventUk18 {
400    /// Index into the sound_events event_records array.
401    event_record_index: u32,
402    /// Parameter set 1.
403    params_1: Vec<u32>,
404    /// Parameter set 2.
405    params_2: Vec<u32>,
406    /// Parameter set 3.
407    params_3: Vec<u32>,
408}
409
410/// Bank event with unknown purpose (category 19).
411#[derive(Default, PartialEq, Clone, Debug, Getters, MutGetters, Setters, Serialize, Deserialize)]
412#[getset(get = "pub", get_mut = "pub", set = "pub")]
413pub struct BankEventUk19 {
414    /// Index into the sound_events event_records array.
415    event_record_index: u32,
416    /// Parameter set 1.
417    params_1: Vec<u32>,
418    /// Parameter set 2.
419    params_2: Vec<u32>,
420}
421
422/// Bank event with unknown purpose (category 20).
423#[derive(Default, PartialEq, Clone, Debug, Getters, MutGetters, Setters, Serialize, Deserialize)]
424#[getset(get = "pub", get_mut = "pub", set = "pub")]
425pub struct BankEventUk20 {
426    /// Index into the sound_events event_records array.
427    event_record_index: u32,
428    /// Parameter set 1.
429    params_1: Vec<u32>,
430    /// Parameter set 2.
431    params_2: Vec<u32>,
432}
433
434/// Bank event with unknown purpose (category 21).
435#[derive(Default, PartialEq, Clone, Debug, Getters, MutGetters, Setters, Serialize, Deserialize)]
436#[getset(get = "pub", get_mut = "pub", set = "pub")]
437pub struct BankEventUk21 {
438    /// Index into the sound_events event_records array.
439    event_record_index: u32,
440    /// Parameter set 1.
441    params_1: Vec<u32>,
442    /// Parameter set 2.
443    params_2: Vec<u32>,
444}
445
446/// Bank event with unknown purpose (category 22).
447#[derive(Default, PartialEq, Clone, Debug, Getters, MutGetters, Setters, Serialize, Deserialize)]
448#[getset(get = "pub", get_mut = "pub", set = "pub")]
449pub struct BankEventUk22 {
450    /// Index into the sound_events event_records array.
451    event_record_index: u32,
452    /// Parameter set 1.
453    params_1: Vec<u32>,
454    /// Parameter set 2.
455    params_2: Vec<u32>,
456}
457
458/// Bank event with unknown purpose (category 23).
459#[derive(Default, PartialEq, Clone, Debug, Getters, MutGetters, Setters, Serialize, Deserialize)]
460#[getset(get = "pub", get_mut = "pub", set = "pub")]
461pub struct BankEventUk23 {
462    /// Index into the sound_events event_records array.
463    event_record_index: u32,
464    /// Parameter set 1.
465    params_1: Vec<u32>,
466    /// Parameter set 2.
467    params_2: Vec<u32>,
468}
469
470/// Bank event with unknown purpose (category 24).
471#[derive(Default, PartialEq, Clone, Debug, Getters, MutGetters, Setters, Serialize, Deserialize)]
472#[getset(get = "pub", get_mut = "pub", set = "pub")]
473pub struct BankEventUk24 {
474    /// Index into the sound_events event_records array.
475    event_record_index: u32,
476    /// Parameter set 1.
477    params_1: Vec<u32>,
478    /// Parameter set 2.
479    params_2: Vec<u32>,
480}
481
482/// Unknown data structure.
483#[derive(Default, PartialEq, Clone, Debug, Getters, MutGetters, Setters, Serialize, Deserialize)]
484#[getset(get = "pub", get_mut = "pub", set = "pub")]
485pub struct Uk1 {
486    /// Unknown parameter set.
487    uk_1: Vec<u32>,
488}
489
490//---------------------------------------------------------------------------//
491//                              Implementations
492//---------------------------------------------------------------------------//
493
494impl Decodeable for SoundBankDatabase {
495
496    fn decode<R: ReadBytes>(data: &mut R, extra_data: &Option<DecodeableExtraData>) -> Result<Self> {
497        let extra_data = extra_data.as_ref().ok_or(RLibError::DecodingMissingExtraData)?;
498        let game_info = extra_data.game_info.ok_or_else(|| RLibError::DecodingMissingExtraDataField("game_info".to_owned()))?;
499
500        let mut sound_bank = Self::default();
501
502        match game_info.key() {
503            KEY_SHOGUN_2 => sound_bank.read_sho2(data)?,
504            //KEY_NAPOLEON => {},
505            //KEY_EMPIRE => sound_bank.read_emp(data)?,
506            _ => return Err(RLibError::DecodingSoundPackedUnsupportedGame(game_info.key().to_string())),
507        }
508
509        // If we are not in the last byte, it means we didn't parse the entire file, which means this file is corrupt.
510        check_size_mismatch(data.stream_position()? as usize, data.len()? as usize)?;
511
512        Ok(sound_bank)
513    }
514}
515
516impl Encodeable for SoundBankDatabase {
517
518    fn encode<W: WriteBytes>(&mut self, buffer: &mut W, extra_data: &Option<EncodeableExtraData>) -> Result<()> {
519        let extra_data = extra_data.as_ref().ok_or(RLibError::EncodingMissingExtraData)?;
520        let game_info = extra_data.game_info.ok_or_else(|| RLibError::DecodingMissingExtraDataField("game_info".to_owned()))?;
521
522        match game_info.key() {
523            KEY_SHOGUN_2 => self.write_sho2(buffer),
524            //KEY_NAPOLEON => {},
525            //KEY_EMPIRE => self.write_emp(buffer),
526            _ => Err(RLibError::EncodingSoundPackedUnsupportedGame(game_info.key().to_string())),
527        }
528    }
529}