Two fixes surfaced by run #55: 1. veza-stream-server (47 files): cargo fmt had been run locally but never committed — the working tree was clean locally while HEAD had unformatted code. CI's `cargo fmt -- --check` caught the drift. This commit lands the formatting that was already staged. 2. ci.yml Install Go tools: `go install .../cmd/golangci-lint@latest` resolves to v1.64.8 (the old /cmd/ module path). The repo's .golangci.yml is v2-format, so v1 refuses with: "you are using a configuration file for golangci-lint v2 with golangci-lint v1: please use golangci-lint v2" Switch to the /v2/cmd/ path so @latest actually gets v2.x.
203 lines
6 KiB
Rust
203 lines
6 KiB
Rust
use crate::codecs::{
|
|
AudioDecoder, AudioEncoder, DecodedAudio, DecoderConfig, DecoderInfo, EncoderConfig,
|
|
EncoderInfo, EncoderMetrics,
|
|
};
|
|
use crate::error::AppError;
|
|
use std::time::Instant;
|
|
|
|
/// Implémentation FLAC Encoder
|
|
#[derive(Debug)]
|
|
pub struct FlacEncoderImpl {
|
|
config: EncoderConfig,
|
|
metrics: EncoderMetrics,
|
|
compression_level: u8,
|
|
block_size: u16,
|
|
sample_count: u64,
|
|
frame_count: u64,
|
|
start_time: Instant,
|
|
}
|
|
|
|
impl FlacEncoderImpl {
|
|
pub fn new(config: EncoderConfig) -> Result<Self, AppError> {
|
|
let compression_level = match config.quality {
|
|
crate::codecs::CodecQuality::Low => 1,
|
|
crate::codecs::CodecQuality::Medium => 3,
|
|
crate::codecs::CodecQuality::High => 5,
|
|
crate::codecs::CodecQuality::VeryHigh => 8,
|
|
crate::codecs::CodecQuality::Custom(level) => (level * 8.0) as u8,
|
|
};
|
|
|
|
Ok(Self {
|
|
config,
|
|
metrics: EncoderMetrics::default(),
|
|
compression_level,
|
|
block_size: 4096,
|
|
sample_count: 0,
|
|
frame_count: 0,
|
|
start_time: Instant::now(),
|
|
})
|
|
}
|
|
}
|
|
|
|
impl AudioEncoder for FlacEncoderImpl {
|
|
fn encode(
|
|
&mut self,
|
|
samples: &[f32],
|
|
_sample_rate: u32,
|
|
_channels: u8,
|
|
) -> Result<Vec<u8>, AppError> {
|
|
let start_time = Instant::now();
|
|
|
|
// Simulation d'encodage FLAC
|
|
let samples_per_channel = samples.len() / self.config.channels as usize;
|
|
let estimated_size = samples_per_channel * 2; // Estimation compression ratio 2:1
|
|
let mut output = Vec::with_capacity(estimated_size);
|
|
|
|
// Header FLAC simplifié
|
|
if self.frame_count == 0 {
|
|
output.extend_from_slice(b"fLaC");
|
|
output.extend_from_slice(&[0x00, 0x00, 0x00, 0x22]); // STREAMINFO block
|
|
}
|
|
|
|
// Frame data simulation
|
|
for chunk in samples.chunks(self.block_size as usize) {
|
|
let compressed_size = chunk.len() / 2; // Simulation compression lossless
|
|
output.extend(vec![0u8; compressed_size]);
|
|
}
|
|
|
|
// Mettre à jour métriques
|
|
self.metrics.frames_encoded += 1;
|
|
self.metrics.bytes_output += output.len() as u64;
|
|
self.metrics.encoding_time_ms += start_time.elapsed().as_millis() as u64;
|
|
|
|
self.frame_count += 1;
|
|
self.sample_count += samples_per_channel as u64;
|
|
|
|
Ok(output)
|
|
}
|
|
|
|
fn finalize(&mut self) -> Result<Vec<u8>, AppError> {
|
|
self.metrics.compression_ratio = if self.sample_count > 0 {
|
|
let input_size = self.sample_count * self.config.channels as u64 * 4;
|
|
input_size as f32 / self.metrics.bytes_output as f32
|
|
} else {
|
|
1.5 // Typical FLAC compression ratio
|
|
};
|
|
|
|
self.metrics.quality_score = 1.0; // Lossless = perfect quality
|
|
Ok(Vec::new())
|
|
}
|
|
|
|
fn reset(&mut self) -> Result<(), AppError> {
|
|
self.metrics = EncoderMetrics::default();
|
|
self.sample_count = 0;
|
|
self.frame_count = 0;
|
|
self.start_time = Instant::now();
|
|
Ok(())
|
|
}
|
|
|
|
fn set_bitrate(&mut self, _bitrate: u32) -> Result<(), AppError> {
|
|
Ok(()) // FLAC est lossless, pas de bitrate fixe
|
|
}
|
|
|
|
fn info(&self) -> EncoderInfo {
|
|
EncoderInfo {
|
|
codec_name: "FLAC".to_string(),
|
|
version: "1.3.4-simulation".to_string(),
|
|
bitrate: 0, // Variable
|
|
sample_rate: self.config.sample_rate,
|
|
channels: self.config.channels,
|
|
bit_depth: 16,
|
|
frame_size: self.block_size as usize,
|
|
latency_ms: 40.0,
|
|
quality_mode: format!("Compression Level {}", self.compression_level),
|
|
}
|
|
}
|
|
|
|
fn metrics(&self) -> EncoderMetrics {
|
|
self.metrics.clone()
|
|
}
|
|
}
|
|
|
|
/// Implémentation FLAC Decoder
|
|
#[derive(Debug)]
|
|
pub struct FlacDecoderImpl {
|
|
config: DecoderConfig,
|
|
frame_count: u64,
|
|
sample_count: u64,
|
|
}
|
|
|
|
impl FlacDecoderImpl {
|
|
pub fn new(config: DecoderConfig) -> Result<Self, AppError> {
|
|
Ok(Self {
|
|
config,
|
|
frame_count: 0,
|
|
sample_count: 0,
|
|
})
|
|
}
|
|
}
|
|
|
|
impl AudioDecoder for FlacDecoderImpl {
|
|
fn decode(&mut self, data: &[u8]) -> Result<DecodedAudio, AppError> {
|
|
// Simulation de décodage FLAC
|
|
let samples_per_channel = 4096; // Block size typique
|
|
let total_samples = samples_per_channel * self.config.channels as usize;
|
|
|
|
// Simulation : générer des échantillons basés sur les données d'entrée
|
|
let mut samples = Vec::with_capacity(total_samples);
|
|
for i in 0..total_samples {
|
|
let value = if !data.is_empty() {
|
|
(data[i % data.len()] as f32 - 128.0) / 128.0
|
|
} else {
|
|
0.0
|
|
};
|
|
samples.push(value * 0.1); // Amplitude réduite
|
|
}
|
|
|
|
self.frame_count += 1;
|
|
self.sample_count += samples_per_channel as u64;
|
|
|
|
let duration_ms =
|
|
(samples_per_channel as f32 / self.config.sample_rate as f32 * 1000.0) as u32;
|
|
|
|
Ok(DecodedAudio {
|
|
samples,
|
|
sample_rate: self.config.sample_rate,
|
|
channels: self.config.channels,
|
|
duration_ms,
|
|
format: self.config.output_format.clone(),
|
|
})
|
|
}
|
|
|
|
fn reset(&mut self) -> Result<(), AppError> {
|
|
self.frame_count = 0;
|
|
self.sample_count = 0;
|
|
Ok(())
|
|
}
|
|
|
|
fn info(&self) -> DecoderInfo {
|
|
DecoderInfo {
|
|
codec_name: "FLAC".to_string(),
|
|
version: "1.3.4-simulation".to_string(),
|
|
sample_rate: self.config.sample_rate,
|
|
channels: self.config.channels,
|
|
bit_depth: 16,
|
|
frame_size: 4096,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_flac_encoder() {
|
|
let config = EncoderConfig::default();
|
|
let mut encoder = FlacEncoderImpl::new(config).unwrap();
|
|
let samples = vec![0.1, -0.1, 0.2, -0.2];
|
|
|
|
let result = encoder.encode(&samples, 44100, 2);
|
|
assert!(result.is_ok());
|
|
}
|
|
}
|