ym2149_common/
metadata.rs

1//! Unified playback metadata trait.
2//!
3//! This module provides a common interface for metadata across different
4//! chiptune file formats (YM, AKS, AY).
5
6/// Unified metadata trait for chiptune playback.
7///
8/// Implementations of this trait provide a common interface to access
9/// song metadata regardless of the underlying file format.
10pub trait MetadataFields {
11    /// Get the song title.
12    fn title(&self) -> &str;
13
14    /// Get the author/composer name.
15    fn author(&self) -> &str;
16
17    /// Get additional comments or description.
18    ///
19    /// Returns an empty string if no comments are available.
20    fn comments(&self) -> &str {
21        ""
22    }
23
24    /// Get the file format identifier.
25    ///
26    /// Examples: "YM6", "AKS", "AY"
27    fn format(&self) -> &str;
28
29    /// Get the total frame count, if known.
30    fn frame_count(&self) -> Option<usize> {
31        None
32    }
33
34    /// Get the playback frame rate in Hz.
35    ///
36    /// Typical values: 50 (PAL) or 60 (NTSC).
37    fn frame_rate(&self) -> u32 {
38        50
39    }
40
41    /// Get the song duration in seconds, if known.
42    fn duration_seconds(&self) -> Option<f32> {
43        self.frame_count()
44            .map(|fc| fc as f32 / self.frame_rate() as f32)
45    }
46
47    /// Get the loop start frame, if the song loops.
48    fn loop_frame(&self) -> Option<usize> {
49        None
50    }
51}
52
53/// Unified metadata trait for chiptune playback.
54///
55/// This is a thin marker over [`MetadataFields`], provided for compatibility
56/// with the existing public API.
57pub trait PlaybackMetadata: MetadataFields {}
58
59impl<T: MetadataFields> PlaybackMetadata for T {}
60
61/// Basic metadata container implementing `PlaybackMetadata`.
62///
63/// This is a simple struct that can be used when you need to store
64/// metadata without the original parser structures.
65#[derive(Debug, Clone, Default, PartialEq, Eq)]
66pub struct BasicMetadata {
67    /// Song title.
68    pub title: String,
69    /// Author/composer name.
70    pub author: String,
71    /// Additional comments.
72    pub comments: String,
73    /// File format identifier (e.g., "YM6", "AKS").
74    pub format: String,
75    /// Total frame count.
76    pub frame_count: Option<usize>,
77    /// Playback frame rate in Hz.
78    pub frame_rate: u32,
79    /// Loop start frame.
80    pub loop_frame: Option<usize>,
81}
82
83impl MetadataFields for BasicMetadata {
84    fn title(&self) -> &str {
85        &self.title
86    }
87
88    fn author(&self) -> &str {
89        &self.author
90    }
91
92    fn comments(&self) -> &str {
93        &self.comments
94    }
95
96    fn format(&self) -> &str {
97        &self.format
98    }
99
100    fn frame_count(&self) -> Option<usize> {
101        self.frame_count
102    }
103
104    fn frame_rate(&self) -> u32 {
105        self.frame_rate
106    }
107
108    fn loop_frame(&self) -> Option<usize> {
109        self.loop_frame
110    }
111}
112
113impl BasicMetadata {
114    /// Create a new `BasicMetadata` with default values.
115    pub fn new() -> Self {
116        Self {
117            frame_rate: 50,
118            ..Default::default()
119        }
120    }
121
122    /// Create metadata from title and author.
123    pub fn with_title_author(title: impl Into<String>, author: impl Into<String>) -> Self {
124        Self {
125            title: title.into(),
126            author: author.into(),
127            frame_rate: 50,
128            ..Default::default()
129        }
130    }
131}