Skip to content

Commit 431e61b

Browse files
committed
move voice decoding to users
1 parent a344aae commit 431e61b

14 files changed

Lines changed: 242 additions & 207 deletions

File tree

examples/voice_to_wav/index.js

Lines changed: 0 additions & 12 deletions
This file was deleted.

examples/voice_to_wav/main.py

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,28 @@
11
from demoparser2 import DemoParser
2+
import wave
3+
import opuslib
4+
import time
5+
# pip install opuslib
6+
# pip install wave
27

8+
9+
# Writes one wav per player
10+
11+
decoder = opuslib.Decoder(48000, 1)
312
parser = DemoParser("path/to/demo.dem")
4-
# returns steamid, bytes
5-
# bytes include a wav header in the beginning so
6-
# it can be written directly
7-
steamid_bytes_dict = parser.parse_voice()
8-
9-
for steamid, raw_bytes in steamid_bytes_dict.items():
10-
with open(f"{steamid}.wav", "wb") as f:
11-
f.write(raw_bytes)
13+
out = parser.parse_voice()
14+
15+
unique_players = set([p["steamid"] for p in out])
16+
for player in unique_players:
17+
bytes_this_player = [x["bytes"] for x in out if x["steamid"] == player]
18+
19+
frames = []
20+
for b in bytes_this_player:
21+
frames.append(decoder.decode(b, frame_size=960, decode_fec=False))
22+
pcm_data = b"".join(frames)
23+
24+
with wave.open(f"{player}.wav", "wb") as f:
25+
f.setnchannels(1)
26+
f.setsampwidth(2)
27+
f.setframerate(48000)
28+
f.writeframes(pcm_data)

src/csgoproto/src/maps.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10908,6 +10908,26 @@ pub static STICKER_ID_TO_NAME: phf::Map<u32, &'static str> = phf_map! {
1090810908
9428_u32 => "paper_drukhari_2",
1090910909
9429_u32 => "paper_aeldari_1",
1091010910
9430_u32 => "paper_aeldari_2",
10911+
9431_u32 => "aus2025_signature_apex_32",
10912+
9432_u32 => "aus2025_signature_apex_32_foil",
10913+
9433_u32 => "aus2025_signature_apex_32_holo",
10914+
9434_u32 => "aus2025_signature_apex_32_gold",
10915+
9435_u32 => "aus2025_signature_zywoo_32",
10916+
9436_u32 => "aus2025_signature_zywoo_32_foil",
10917+
9437_u32 => "aus2025_signature_zywoo_32_holo",
10918+
9438_u32 => "aus2025_signature_zywoo_32_gold",
10919+
9439_u32 => "aus2025_signature_flamez_32",
10920+
9440_u32 => "aus2025_signature_flamez_32_foil",
10921+
9441_u32 => "aus2025_signature_flamez_32_holo",
10922+
9442_u32 => "aus2025_signature_flamez_32_gold",
10923+
9443_u32 => "aus2025_signature_mezii_32",
10924+
9444_u32 => "aus2025_signature_mezii_32_foil",
10925+
9445_u32 => "aus2025_signature_mezii_32_holo",
10926+
9446_u32 => "aus2025_signature_mezii_32_gold",
10927+
9447_u32 => "aus2025_signature_ropz_32",
10928+
9448_u32 => "aus2025_signature_ropz_32_foil",
10929+
9449_u32 => "aus2025_signature_ropz_32_holo",
10930+
9450_u32 => "aus2025_signature_ropz_32_gold",
1091110931
};
1091210932

1091310933
pub static WEAPINDICIES: phf::Map<u32, &'static str> = phf_map! {

src/csgoproto/src/message_type.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,6 @@ pub enum NetMessageType {
8484
UM_AnimGraphUpdate,
8585
UM_HapticsManagerPulse,
8686
UM_HapticsManagerEffect,
87-
UM_CommandQueueState,
8887
UM_UpdateCssClasses,
8988
UM_ServerFrameTime,
9089
UM_LagCompensationError,
@@ -276,7 +275,6 @@ impl From<i32> for NetMessageType {
276275
149 => UM_AnimGraphUpdate,
277276
150 => UM_HapticsManagerPulse,
278277
151 => UM_HapticsManagerEffect,
279-
152 => UM_CommandQueueState,
280278
153 => UM_UpdateCssClasses,
281279
154 => UM_ServerFrameTime,
282280
155 => UM_LagCompensationError,

src/csgoproto/src/protobuf.rs

Lines changed: 158 additions & 23 deletions
Large diffs are not rendered by default.

src/node/src/lib.rs

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ use parser::second_pass::variants::soa_to_aos;
2020
use parser::second_pass::variants::BytesVariant;
2121
use parser::second_pass::variants::OutputSerdeHelperStruct;
2222
use parser::second_pass::variants::Variant;
23-
use parser::second_pass::voice_data::convert_voice_data_to_wav;
2423
use serde_json::Value;
2524
use std::collections::HashMap;
2625
use std::fs::File;
@@ -141,8 +140,15 @@ fn parse_demo(bytes: BytesVariant, parser: &mut Parser) -> Result<DemoOutput, Er
141140
},
142141
}
143142
}
143+
#[napi(object)]
144+
pub struct VoiceData {
145+
pub tick: i32,
146+
pub data: Buffer,
147+
pub steamid: String,
148+
}
149+
144150
#[napi]
145-
pub fn parse_voice(path_or_buf: Either<String, Buffer>) -> napi::Result<HashMap<String, Vec<u8>>> {
151+
pub fn parse_voice(path_or_buf: Either<String, Buffer>) -> napi::Result<Vec<VoiceData>> {
146152
let bytes = resolve_byte_type(path_or_buf).unwrap();
147153
let settings = ParserInputs {
148154
wanted_players: vec![],
@@ -164,15 +170,18 @@ pub fn parse_voice(path_or_buf: Either<String, Buffer>) -> napi::Result<HashMap<
164170
};
165171
let mut parser = Parser::new(settings, parser::parse_demo::ParsingMode::Normal);
166172
let output = parse_demo(bytes, &mut parser)?;
167-
let out = match convert_voice_data_to_wav(output.voice_data) {
168-
Ok(out) => out,
169-
Err(e) => return Err(Error::new(Status::InvalidArg, format!("{}", e).to_owned())),
170-
};
171-
let mut out_hm = HashMap::default();
172-
for (steamid, bytes) in out {
173-
out_hm.insert(steamid, bytes);
173+
let mut out = vec![];
174+
175+
for (tick, packet) in output.voice_data {
176+
if let Some(data) = &packet.audio {
177+
out.push(VoiceData {
178+
data: data.voice_data().into(),
179+
steamid: packet.xuid().to_string(),
180+
tick: tick,
181+
});
182+
}
174183
}
175-
Ok(out_hm)
184+
return Ok(out);
176185
}
177186

178187
#[napi]

src/parser/src/parse_demo.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ pub struct DemoOutput {
3535
pub game_events_counter: AHashSet<String>,
3636
pub uniq_prop_names: Vec<String>,
3737
pub projectiles: Vec<ProjectileRecord>,
38-
pub voice_data: Vec<CsvcMsgVoiceData>,
38+
pub voice_data: Vec<(i32, CsvcMsgVoiceData)>,
3939
pub prop_controller: PropController,
4040
pub df_per_player: AHashMap<u64, AHashMap<u32, PropColumn>>,
4141
}

src/parser/src/second_pass/entities.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -281,9 +281,7 @@ impl<'a> SecondPassParser<'a> {
281281
_entity_id: &i32,
282282
) {
283283
if let Field::Value(_v) = field {
284-
if _v.full_name.contains("Angl") && _v.full_name != "CCSPlayerPawn.m_angEyeAngles" {
285-
println!("{:?} {:?} {:?} {:?} {:?}", _path, field_info, _v.full_name, _result, _cls.name);
286-
}
284+
println!("{:?} {:?} {:?} {:?} {:?}", _path, field_info, _v.full_name, _result, _cls.name);
287285
}
288286
}
289287

src/parser/src/second_pass/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,3 @@ pub mod parser;
77
pub mod parser_settings;
88
pub mod path_ops;
99
pub mod variants;
10-
pub mod voice_data;

src/parser/src/second_pass/parser.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ pub struct SecondPassOutput {
5050
pub prop_info: PropController,
5151
pub projectiles: Vec<ProjectileRecord>,
5252
pub ptr: usize,
53-
pub voice_data: Vec<CsvcMsgVoiceData>,
53+
pub voice_data: Vec<(i32, CsvcMsgVoiceData)>,
5454
pub df_per_player: AHashMap<u64, AHashMap<u32, PropColumn>>,
5555
pub entities: Vec<Option<Entity>>,
5656
pub last_tick: i32,
@@ -62,7 +62,9 @@ impl<'a> SecondPassParser<'a> {
6262
let mut buf = vec![0_u8; INNER_BUF_DEFAULT_LEN];
6363
let mut buf2 = vec![0_u8; OUTER_BUF_DEFAULT_LEN];
6464
loop {
65-
if demo_bytes.len() < self.ptr { break; }
65+
if demo_bytes.len() < self.ptr {
66+
break;
67+
}
6668
let frame = self.read_frame(demo_bytes)?;
6769
if frame.demo_cmd == DemAnimationData || frame.demo_cmd == DemSendTables || frame.demo_cmd == DemStringTables {
6870
self.ptr += frame.size as usize;
@@ -289,7 +291,7 @@ impl<'a> SecondPassParser<'a> {
289291

290292
pub fn parse_voice_data(&mut self, bytes: &[u8]) -> Result<(), DemoParserError> {
291293
if let Ok(m) = CsvcMsgVoiceData::decode(bytes) {
292-
self.voice_data.push(m);
294+
self.voice_data.push((self.tick, m));
293295
}
294296
Ok(())
295297
}

0 commit comments

Comments
 (0)