1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
//! Vorbis validation for converted audio streams.
//!
//! This module provides validation for converted Ogg Vorbis audio by attempting
//! to decode the output and checking for common issues like wrong codebook selection.
//!
//! # Why Validate?
//!
//! When converting Wwise audio, using the wrong codebook library will produce
//! output that appears valid but contains garbled audio. Validation catches this
//! by actually decoding the audio and checking for corruption.
//!
//! # Example
//!
//! ```no_run
//! use std::fs::File;
//! use std::io::{BufReader, Read};
//! use ww2ogg::{WwiseRiffVorbis, CodebookLibrary, validate};
//!
//! fn convert_and_validate(wem_path: &str) -> Result<Vec<u8>, ww2ogg::WemError> {
//! let input = BufReader::new(File::open(wem_path)?);
//! let codebooks = CodebookLibrary::default_codebooks()?;
//! let mut converter = WwiseRiffVorbis::new(input, codebooks)?;
//!
//! let mut ogg_data = Vec::new();
//! converter.generate_ogg(&mut ogg_data)?;
//!
//! // Validate the output
//! validate(&ogg_data)?;
//!
//! Ok(ogg_data)
//! }
//! ```
//!
//! # Auto-Detection Pattern
//!
//! A common pattern is to try default codebooks first, then fall back to aoTuV:
//!
//! ```no_run
//! use std::io::Cursor;
//! use ww2ogg::{WwiseRiffVorbis, CodebookLibrary, validate};
//!
//! fn convert_with_auto_detect(wem_data: &[u8]) -> Result<Vec<u8>, ww2ogg::WemError> {
//! // Try default codebooks first
//! let input = Cursor::new(wem_data);
//! let codebooks = CodebookLibrary::default_codebooks()?;
//! let mut converter = WwiseRiffVorbis::new(input, codebooks)?;
//!
//! let mut ogg_data = Vec::new();
//! converter.generate_ogg(&mut ogg_data)?;
//!
//! if validate(&ogg_data).is_ok() {
//! return Ok(ogg_data);
//! }
//!
//! // Fall back to aoTuV codebooks
//! let input = Cursor::new(wem_data);
//! let codebooks = CodebookLibrary::aotuv_codebooks()?;
//! let mut converter = WwiseRiffVorbis::new(input, codebooks)?;
//!
//! let mut ogg_data = Vec::new();
//! converter.generate_ogg(&mut ogg_data)?;
//! validate(&ogg_data)?;
//!
//! Ok(ogg_data)
//! }
//! ```
use crate;
use OggStreamReader;
use ;
/// Validates an Ogg Vorbis stream by attempting to decode audio samples.
///
/// This function reads up to 10 packets of audio data and checks for:
/// - Valid Ogg/Vorbis stream structure
/// - Decodable audio samples (no NaN/Infinity values)
/// - Reasonable sample values (not clipping excessively)
///
/// If more than 10% of samples in any packet are invalid, validation fails.
///
/// # Arguments
///
/// * `data` - The Ogg Vorbis data to validate as a byte slice
///
/// # Returns
///
/// * `Ok(())` - The audio is valid and can be decoded
/// * `Err(WemError::Codebook)` - Validation failed (likely wrong codebook)
///
/// # Example
///
/// ```no_run
/// use ww2ogg::validate;
///
/// fn check_audio(ogg_data: &[u8]) {
/// match validate(ogg_data) {
/// Ok(()) => println!("Audio is valid!"),
/// Err(e) => println!("Validation failed: {}", e),
/// }
/// }
/// ```
/// Validates an Ogg Vorbis stream from a reader.
///
/// See [`validate`] for details on the validation process.