✨ Add StreamType for multi-client support and improved UPnP control
- Introduce `Streamtype` enum (Continuous vs Finite) to distinguish radio streams from finite tracks - Enrich `TrackBoundary` sync marker with stream type for proper pause behavior per mode (silence vs backpressure) - Update all sources and sinks to pass `StreamType` when creating track boundaries - Radio Paradise, HTTP source → Continuous (infinite) - Improve UPnP control architecture: pause sends silence for radio, blocks pipeline via backpressure for tracks - Prepare groundwork for multi-client DSP architecture with shared source and per-DSP pipelines
This commit is contained in:
@@ -3,7 +3,7 @@ use tokio::sync::RwLock;
|
||||
|
||||
use pmometadata::TrackMetadata;
|
||||
|
||||
use crate::{gain_db_from_linear, AudioChunk, AudioChunkData, BitDepth, SyncMarker};
|
||||
use crate::{gain_db_from_linear, AudioChunk, AudioChunkData, BitDepth, StreamType, SyncMarker};
|
||||
|
||||
pub enum _AudioSegment {
|
||||
Chunk(Arc<AudioChunk>),
|
||||
@@ -160,9 +160,11 @@ impl AudioSegment {
|
||||
order: u64,
|
||||
timestamp_sec: f64,
|
||||
metadata: Arc<RwLock<dyn TrackMetadata>>,
|
||||
stream_type: StreamType,
|
||||
) -> Arc<Self> {
|
||||
let marker = Arc::new(SyncMarker::TrackBoundary {
|
||||
metadata: Arc::clone(&metadata),
|
||||
stream_type,
|
||||
});
|
||||
Arc::new(Self {
|
||||
order,
|
||||
@@ -303,7 +305,18 @@ impl AudioSegment {
|
||||
pub fn as_track_metadata(&self) -> Option<&Arc<RwLock<dyn TrackMetadata>>> {
|
||||
match &self.segment {
|
||||
_AudioSegment::Sync(marker) => match &**marker {
|
||||
SyncMarker::TrackBoundary { metadata } => Some(metadata),
|
||||
SyncMarker::TrackBoundary { metadata, .. } => Some(metadata),
|
||||
_ => None,
|
||||
},
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Récupère le stream_type si c'est un TrackBoundary
|
||||
pub fn stream_type(&self) -> Option<StreamType> {
|
||||
match &self.segment {
|
||||
_AudioSegment::Sync(marker) => match &**marker {
|
||||
SyncMarker::TrackBoundary { stream_type, .. } => Some(*stream_type),
|
||||
_ => None,
|
||||
},
|
||||
_ => None,
|
||||
|
||||
@@ -95,7 +95,7 @@ pub mod bit_depth;
|
||||
pub mod dsp;
|
||||
|
||||
pub use audio_segment::{AudioSegment, _AudioSegment};
|
||||
pub use sync_marker::SyncMarker;
|
||||
pub use sync_marker::{StreamType, SyncMarker};
|
||||
|
||||
pub use audio_chunk::{
|
||||
gain_db_from_linear, gain_linear_from_db, AudioChunk, AudioChunkData, AudioFloatChunk,
|
||||
|
||||
@@ -2,7 +2,7 @@ use crate::{
|
||||
nodes::{AudioError, TypedAudioNode, DEFAULT_CHUNK_DURATION_MS},
|
||||
pipeline::{send_to_children, AudioPipelineNode, Node, NodeLogic},
|
||||
type_constraints::TypeRequirement,
|
||||
AudioChunk, AudioChunkData, AudioSegment, I24,
|
||||
AudioChunk, AudioChunkData, AudioSegment, I24, StreamType,
|
||||
};
|
||||
use pmoflac::{decode_audio_stream, AudioFileMetadata, StreamInfo};
|
||||
use pmometadata::{MemoryTrackMetadata, TrackMetadata};
|
||||
@@ -98,6 +98,7 @@ impl NodeLogic for FileSourceLogic {
|
||||
0,
|
||||
0.0,
|
||||
Arc::new(tokio::sync::RwLock::new(metadata)),
|
||||
StreamType::Finite,
|
||||
);
|
||||
send_to_children(std::any::type_name::<Self>(), &output, track_boundary).await?;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ use crate::{
|
||||
nodes::{AudioError, TypedAudioNode, DEFAULT_CHANNEL_SIZE},
|
||||
pipeline::{Node, NodeLogic},
|
||||
type_constraints::TypeRequirement,
|
||||
AudioChunk, AudioPipelineNode, AudioSegment, SyncMarker,
|
||||
AudioChunk, AudioPipelineNode, AudioSegment, SyncMarker, StreamType,
|
||||
};
|
||||
use pmoflac::{encode_flac_stream, EncoderOptions, PcmFormat};
|
||||
use std::{
|
||||
@@ -822,6 +822,7 @@ mod tests {
|
||||
0,
|
||||
0.0,
|
||||
std::sync::Arc::new(tokio::sync::RwLock::new(metadata)),
|
||||
crate::StreamType::Finite,
|
||||
);
|
||||
tx.send(track_boundary).await.unwrap();
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ use crate::{
|
||||
nodes::{AudioError, TypedAudioNode, DEFAULT_CHUNK_DURATION_MS},
|
||||
pipeline::{send_to_children, Node, NodeLogic},
|
||||
type_constraints::TypeRequirement,
|
||||
AudioChunk, AudioChunkData, AudioPipelineNode, AudioSegment, I24,
|
||||
AudioChunk, AudioChunkData, AudioPipelineNode, AudioSegment, I24, StreamType,
|
||||
};
|
||||
use futures_util::StreamExt;
|
||||
use pmoflac::{decode_audio_stream, StreamInfo};
|
||||
@@ -178,7 +178,7 @@ impl NodeLogic for HttpSourceLogic {
|
||||
|
||||
// Émettre TrackBoundary avec les métadonnées HTTP
|
||||
let track_boundary =
|
||||
AudioSegment::new_track_boundary(0, 0.0, Arc::new(tokio::sync::RwLock::new(metadata)));
|
||||
AudioSegment::new_track_boundary(0, 0.0, Arc::new(tokio::sync::RwLock::new(metadata)), StreamType::Continuous);
|
||||
send_to_children(std::any::type_name::<Self>(), &output, track_boundary).await?;
|
||||
|
||||
// Préparer la lecture des chunks audio
|
||||
|
||||
@@ -33,7 +33,7 @@ use crate::{
|
||||
nodes::{AudioError, TypedAudioNode},
|
||||
pipeline::{send_to_children, AudioPipelineNode, Node, NodeLogic},
|
||||
type_constraints::TypeRequirement,
|
||||
AudioChunk, AudioChunkData, AudioSegment, BitDepth, I24,
|
||||
AudioChunk, AudioChunkData, AudioSegment, BitDepth, I24, StreamType,
|
||||
};
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::mpsc;
|
||||
@@ -495,7 +495,7 @@ mod tests {
|
||||
let metadata = Arc::new(tokio::sync::RwLock::new(
|
||||
pmometadata::MemoryTrackMetadata::new(),
|
||||
));
|
||||
let boundary = AudioSegment::new_track_boundary(0, 0.0, metadata);
|
||||
let boundary = AudioSegment::new_track_boundary(0, 0.0, metadata, StreamType::Finite);
|
||||
|
||||
// Envoyer le boundary
|
||||
input_tx.send(boundary.clone()).await.unwrap();
|
||||
|
||||
@@ -3,9 +3,16 @@ use tokio::sync::RwLock;
|
||||
|
||||
use pmometadata::TrackMetadata;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum StreamType {
|
||||
Continuous,
|
||||
Finite,
|
||||
}
|
||||
|
||||
pub enum SyncMarker {
|
||||
TrackBoundary {
|
||||
metadata: Arc<RwLock<dyn TrackMetadata>>,
|
||||
stream_type: StreamType,
|
||||
},
|
||||
StreamMetadata {
|
||||
key: String,
|
||||
@@ -15,5 +22,4 @@ pub enum SyncMarker {
|
||||
Heartbeat,
|
||||
EndOfStream,
|
||||
Error(String),
|
||||
// autres cas à venir…
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user