//! Exemples d'utilisation de l'API AudioChunk et AudioSegment //! //! Ce fichier démontre les différentes façons de créer et manipuler //! des chunks audio avec la nouvelle architecture générique. use pmoaudio::*; fn main() { println!("=== Exemples d'utilisation de l'API AudioChunk ===\n"); // ============ Création de chunks de différents types ============ example_create_chunks(); // ============ Conversions entre types ============ example_conversions(); // ============ Utilisation des macros ============ example_macros(); // ============ AudioSegment et helpers ============ example_audio_segments(); // ============ Manipulation du gain ============ example_gain_manipulation(); } fn example_create_chunks() { println!(">>> Création de chunks audio\n"); // Chunk I32 stéréo let stereo_i32 = vec![[1000i32, 2000i32], [3000i32, 4000i32]]; let chunk_i32 = AudioChunkData::new(stereo_i32, 48000, 0.0); println!( "Chunk I32: {} frames @ {}Hz", chunk_i32.len(), chunk_i32.get_sample_rate() ); // Chunk F32 stéréo (normalisé [-1.0, 1.0]) let stereo_f32 = vec![[0.5f32, -0.5f32], [0.8f32, -0.8f32]]; let chunk_f32 = AudioChunkData::new(stereo_f32, 48000, 0.0); println!( "Chunk F32: {} frames @ {}Hz", chunk_f32.len(), chunk_f32.get_sample_rate() ); // Chunk depuis canaux séparés let left = vec![100i32, 200i32, 300i32]; let right = vec![150i32, 250i32, 350i32]; let chunk_from_channels = AudioChunkData::::from_channels(left, right, 44100); println!("Chunk from channels: {} frames", chunk_from_channels.len()); // Chunk avec gain let chunk_with_gain = AudioChunkData::new( vec![[1000i32, 2000i32]], 48000, 6.0, // +6 dB ); println!("Chunk with gain: {} dB\n", chunk_with_gain.get_gain_db()); } fn example_conversions() { println!(">>> Conversions entre types\n"); // Créer un chunk I32 let i32_data = vec![[1_000_000i32, 2_000_000i32]]; let chunk_i32 = AudioChunkData::new(i32_data, 48000, 0.0); let audio_chunk = AudioChunk::I32(chunk_i32); println!("Type original: {}", audio_chunk.type_name()); // Conversion vers F32 let audio_chunk_f32 = audio_chunk.to_f32(); println!("Après conversion to_f32: {}", audio_chunk_f32.type_name()); // Conversion vers F64 let audio_chunk_f64 = audio_chunk_f32.to_f64(); println!("Après conversion to_f64: {}", audio_chunk_f64.type_name()); // Retour vers I32 let audio_chunk_back = audio_chunk_f64.to_i32(); println!("Après conversion to_i32: {}", audio_chunk_back.type_name()); // Utilisation des traits From/Into let chunk_i16 = AudioChunkData::new(vec![[1000i16, 2000i16]], 48000, 0.0); let chunk_i32_from_i16: std::sync::Arc> = (&*chunk_i16).into(); println!( "\nConversion I16 → I32 via Into: {} frames", chunk_i32_from_i16.len() ); println!(); } fn example_macros() { println!(">>> Utilisation des macros\n"); // Créer différents types de chunks let chunk_i32 = AudioChunk::I32(AudioChunkData::new(vec![[100i32, 200i32]], 48000, 0.0)); let chunk_f32 = AudioChunk::F32(AudioChunkData::new(vec![[0.5f32, -0.5f32]], 48000, 0.0)); // Macro is_chunk_type! println!("chunk_i32 is I32: {}", is_chunk_type!(&chunk_i32, I32)); println!("chunk_i32 is F32: {}", is_chunk_type!(&chunk_i32, F32)); println!("chunk_f32 is F32: {}", is_chunk_type!(&chunk_f32, F32)); // Macro extract_chunk_data! if let Some(data) = extract_chunk_data!(&chunk_i32, I32) { println!("\nExtracted I32 data: {} frames", data.len()); } // Macro match_chunk! pour traiter n'importe quel type let frame_count = match_chunk!(&chunk_i32, data => { data.len() }); println!("Frame count via match_chunk: {}", frame_count); // Macro map_chunk! pour transformer tout en préservant le type let chunk_with_gain = map_chunk!(&chunk_i32, data => { data.set_gain_db(6.0) }); println!("\nGain après map_chunk: {} dB", chunk_with_gain.gain_db()); println!(); } fn example_audio_segments() { println!(">>> AudioSegment et helpers\n"); // Créer un segment audio let segment = AudioSegment::new_chunk( 0, 0.0, vec![[1000i32, 2000i32], [3000i32, 4000i32]], 48000, BitDepth::B32, ); // Accès aux propriétés via les helpers println!("Segment info:"); println!(" - Type: {}", segment.chunk_type_name().unwrap()); println!(" - Sample rate: {} Hz", segment.sample_rate().unwrap()); println!(" - Frame count: {}", segment.frame_count().unwrap()); println!(" - Gain: {} dB", segment.gain_db().unwrap()); // Conversion du chunk if let Some(f32_chunk) = segment.to_f32_chunk() { println!("\nChunk converti en F32: {}", f32_chunk.type_name()); } // Créer un marqueur de sync let heartbeat = AudioSegment::new_hearbeat(1, 1.0); println!("\nHeartbeat segment:"); println!(" - Is audio: {}", heartbeat.is_audio_chunk()); println!(" - Is heartbeat: {}", heartbeat.is_heartbeat()); // Macro extract_audio_chunk! if let Some(chunk) = extract_audio_chunk!(&*segment) { println!("\nExtracted chunk type: {}", chunk.type_name()); } // Macro match_segment! let info = match_segment!(&*segment, chunk => format!("Audio chunk: {}", chunk.type_name()), _marker => "Sync marker".to_string() ); println!("Segment info via macro: {}", info); println!(); } fn example_gain_manipulation() { println!(">>> Manipulation du gain\n"); // Créer un segment let segment = AudioSegment::new_chunk(0, 0.0, vec![[1000i32, 2000i32]], 48000, BitDepth::B32); println!("Gain initial: {} dB", segment.gain_db().unwrap()); // Définir un gain absolu let segment_6db = segment.with_gain_db(6.0).unwrap(); println!( "Après with_gain_db(6.0): {} dB", segment_6db.gain_db().unwrap() ); // Ajuster le gain (relatif) let segment_9db = segment_6db.adjust_gain_db(3.0).unwrap(); println!( "Après adjust_gain_db(+3.0): {} dB", segment_9db.gain_db().unwrap() ); // Les segments originaux ne sont pas modifiés (immutabilité) println!( "Gain du segment original: {} dB", segment.gain_db().unwrap() ); // Conversion gain linéaire ↔ dB let linear_gain = gain_linear_from_db(6.0); let gain_db = gain_db_from_linear(linear_gain); println!("\n6 dB = {:.4}x (linéaire)", linear_gain); println!("{:.4}x = {:.2} dB", linear_gain, gain_db); println!(); }