diff --git a/src/session/stream/audio/capture/mod.rs b/src/session/stream/audio/capture/mod.rs index 00558c7..7adf89e 100644 --- a/src/session/stream/audio/capture/mod.rs +++ b/src/session/stream/audio/capture/mod.rs @@ -94,9 +94,11 @@ pub struct AudioCapture { } impl AudioCapture { - pub async fn new(audio_tx: Sender>) -> Result { + pub async fn new(audio_tx: Sender>) -> Result { + // TODO: Make configurable. let channels = 2u8; let sample_rate = 48000u32; + let sample_time_ms = 5; let default_sink_name = match get_default_sink_name() { Ok(name) => name, @@ -107,7 +109,7 @@ impl AudioCapture { let monitor_name = format!("{default_sink_name}.monitor"); let sample_spec = Spec { - format: pulse::sample::Format::S16le, + format: pulse::sample::Format::F32le, channels, rate: sample_rate, }; @@ -122,11 +124,11 @@ impl AudioCapture { &sample_spec, // Sample specification. None, // Use default channel map. Some(&BufferAttr { - maxlength: std::mem::size_of::() as u32 * sample_rate * channels as u32 * 5 / 1000, - tlength: std::u32::MAX, - prebuf: std::u32::MAX, - minreq: std::u32::MAX, - fragsize: std::u32::MAX, + maxlength: u32::MAX, + tlength: u32::MAX, + prebuf: u32::MAX, + minreq: u32::MAX, + fragsize: std::mem::size_of::() as u32 * sample_rate * channels as u32 * sample_time_ms / 1000, }), ).map_err(|e| tracing::error!("Failed to create audio capture device: {e}")); @@ -159,25 +161,32 @@ impl AudioCapture { struct AudioCaptureInner { /// Channel to communicate audio fragments over. - audio_tx: Sender>, + audio_tx: Sender>, } impl AudioCaptureInner { fn run(self, stream: pulse_simple::Simple) -> Result<(), ()> { + // TODO: Make configurable. + const SAMPLE_RATE: usize = 48000; + const SAMPLE_TIME_MS: usize = 5; + const FRAME_SIZE: usize = std::mem::size_of::() * SAMPLE_RATE * SAMPLE_TIME_MS / 1000; + // Start recording. loop { // Allocate uninitialized buffer for recording. - let buffer: Vec> = vec![MaybeUninit::uninit(); 480]; - let mut buffer = unsafe { std::mem::transmute::<_, Vec>(buffer) }; + let buffer: Vec> = vec![MaybeUninit::uninit(); FRAME_SIZE]; + let mut buffer = unsafe { + std::mem::transmute::>, std::vec::Vec>(buffer) + }; match stream.read(&mut buffer) { Ok(()) => { - // Convert Vec to Vec. + // Convert Vec to Vec. let samples = unsafe { Vec::from_raw_parts( - buffer.as_ptr() as *mut i16, - buffer.len() / std::mem::size_of::(), - buffer.len() / std::mem::size_of::(), + buffer.as_ptr() as *mut f32, + buffer.len() / std::mem::size_of::(), + buffer.len() / std::mem::size_of::(), ) }; diff --git a/src/session/stream/audio/encoder.rs b/src/session/stream/audio/encoder.rs index 55f55f0..9134a56 100644 --- a/src/session/stream/audio/encoder.rs +++ b/src/session/stream/audio/encoder.rs @@ -26,10 +26,13 @@ impl AudioEncoder { pub fn new( sample_rate: u32, channels: u8, - audio_rx: mpsc::Receiver>, + audio_rx: mpsc::Receiver>, keys: SessionKeys, packet_tx: mpsc::Sender> ) -> Result { + // TODO: Make this configurable. + let audio_bitrate = 512000; + tracing::debug!("Creating audio encoder with sample rate {} and {} channels.", sample_rate, channels); let mut encoder = opus::Encoder::new( sample_rate, @@ -41,6 +44,8 @@ impl AudioEncoder { // Moonlight expects a constant bitrate. encoder.set_vbr(false) .map_err(|e| tracing::error!("Failed to disable variable bitrate: {e}"))?; + encoder.set_bitrate(opus::Bitrate::Bits(audio_bitrate)) + .map_err(|e| tracing::error!("Failed to set audio bitrate: {e}"))?; let (command_tx, command_rx) = mpsc::channel(10); let inner = AudioEncoderInner { }; @@ -65,7 +70,7 @@ impl AudioEncoderInner { fn run( self, mut command_rx: mpsc::Receiver, - mut audio_rx: mpsc::Receiver>, + mut audio_rx: mpsc::Receiver>, mut encoder: opus::Encoder, mut keys: SessionKeys, packet_tx: mpsc::Sender>, @@ -98,7 +103,7 @@ impl AudioEncoderInner { // A buffer for an audio sample after it has been encoded. // TODO: Decide the correct size for this buffer. - let mut encoded_audio = vec![0u8; 1024]; + let mut encoded_audio = vec![0u8; 1400]; loop { // Check if there's a command. @@ -124,8 +129,9 @@ impl AudioEncoderInner { break; }; + // TODO: Figure out the 1000 / 90 value. let timestamp = ((std::time::Instant::now() - stream_start_time).as_micros() / (1000 / 90)) as u32; - let encoded_size = match encoder.encode(&audio_fragment, &mut encoded_audio) { + let encoded_size = match encoder.encode_float(&audio_fragment, &mut encoded_audio) { Ok(encoded_size) => encoded_size, Err(e) => { tracing::warn!("Failed to encode audio: {e}"); @@ -134,6 +140,7 @@ impl AudioEncoderInner { } }; + // Encrypt the audio data. // TODO: Check if we should, some clients (ie. Steam Link) don't support this. let iv = keys.remote_input_key_id as u32 + sequence_number as u32; diff --git a/src/session/stream/video/encoder.rs b/src/session/stream/video/encoder.rs index e65a3f5..265d5da 100644 --- a/src/session/stream/video/encoder.rs +++ b/src/session/stream/video/encoder.rs @@ -112,7 +112,7 @@ impl Encoder { encoder.set_time_base((framerate as i32, 1)); encoder.set_max_b_frames(0); encoder.set_bit_rate(bitrate); - encoder.set_gop(i32::max_value() as u32); + encoder.set_gop(i32::MAX as u32); unsafe { (*encoder.as_mut_ptr()).pix_fmt = Pixel::CUDA.into(); (*encoder.as_mut_ptr()).hw_frames_ctx = hw_frame_context.as_raw_mut();