Skip to main content

dff_meta/
model.rs

1//! DFF File Model
2
3use std::io;
4use std::collections::HashMap;
5
6use id3::Tag;
7
8use crate::DffFile;
9
10pub type Uchar = u8;
11pub type Ushort = u16;
12pub type Ulong = u32;
13pub type DoubleUlong = u64;
14pub type ID = u32;
15
16pub const CHUNK_HEADER_SIZE: DoubleUlong = 12;
17pub const DSD_LABEL: ID = u32::from_be_bytes(*b"DSD ");
18pub const FVER_LABEL: ID = u32::from_be_bytes(*b"FVER");
19pub const PROP_LABEL: ID = u32::from_be_bytes(*b"PROP");
20pub const SND_LABEL: ID = u32::from_be_bytes(*b"SND ");
21pub const FS_LABEL: ID = u32::from_be_bytes(*b"FS  ");
22pub const CHNL_LABEL: ID = u32::from_be_bytes(*b"CHNL");
23pub const COMP_LABEL: ID = u32::from_be_bytes(*b"CMPR");
24pub const ABS_TIME_LABEL: ID = u32::from_be_bytes(*b"ABSS");
25pub const LS_CONF_LABEL: ID = u32::from_be_bytes(*b"LSCO");
26pub const ID3_LABEL: ID = u32::from_be_bytes(*b"ID3 ");
27
28#[derive(Debug)]
29pub enum Error {
30    DsdChunkHeader,
31    DsdChunkSize,
32    Id3Error(id3::Error, DffFile),
33    IoError(io::Error),
34    FormChunkHeader,
35    FormTypeMismatch,
36    FverChunkHeader,
37    FverChunkSize,
38    FverUnsupportedVersion,
39    PropChunkHeader,
40    PropChunkType,
41    FsChunkHeader,
42    FsChunkSize,
43    ChnlChunkHeader,
44    ChnlChunkSize,
45    ChnlNumber,
46    CmprChunkHeader,
47    CmprChunkSize,
48    AbssChunkHeader,
49    AbssChunkSize,
50    LscoChunkHeader,
51    LscoChunkSize,
52    CmprTypeMismatch,
53    PrematureTagFound(String),
54    Eof,
55}
56
57#[derive(Debug, Clone)]
58pub enum LocalChunk {
59    FormatVersion(FormatVersionChunk),
60    Property(PropertyChunk),
61    SampleRate(SampleRateChunk),
62    Channels(ChannelsChunk),
63    CompressionType(CompressionTypeChunk),
64    AbsoluteStartTime(AbsoluteStartTimeChunk),
65    LoudspeakerConfig(LoudspeakerConfigChunk),
66    Dsd(DsdChunk),
67    Id3(Id3Chunk), // NEW
68}
69
70#[repr(C, packed)]
71#[derive(Debug, Copy, Clone)]
72pub struct ChunkHeader {
73    pub ck_id: ID,
74    pub ck_data_size: DoubleUlong,
75}
76
77#[derive(Debug, Clone)]
78pub struct Chunk {
79    pub header: ChunkHeader,
80    pub local_chunks: HashMap<ID, LocalChunk>,
81}
82
83#[derive(Debug, Clone)]
84pub struct FormDsdChunk {
85    pub chunk: Chunk,
86    pub form_type: ID,
87}
88
89#[derive(Debug, Clone)]
90pub struct FormatVersionChunk {
91    pub chunk: Chunk,
92    pub format_version: Ulong,
93}
94
95#[derive(Debug, Clone)]
96pub struct PropertyChunk {
97    pub chunk: Chunk,
98    pub property_type: ID,
99}
100
101#[derive(Debug, Clone)]
102pub struct SampleRateChunk {
103    pub chunk: Chunk,
104    pub sample_rate: Ulong,
105}
106
107#[derive(Debug, Clone)]
108pub struct ChannelsChunk {
109    pub chunk: Chunk,
110    pub num_channels: Ushort,
111    pub ch_id: Vec<ID>, // length = channel_count
112}
113
114#[derive(Debug, Clone)]
115pub struct CompressionTypeChunk {
116    pub chunk: Chunk,
117    pub compression_type: ID,
118    pub compression_name: String,
119}
120
121#[derive(Debug, Clone)]
122pub struct AbsoluteStartTimeChunk {
123    pub chunk: Chunk,
124    #[allow(dead_code)]
125    pub hours: Ushort,
126    #[allow(dead_code)]
127    pub minutes: Uchar,
128    #[allow(dead_code)]
129    pub seconds: Uchar,
130    #[allow(dead_code)]
131    pub samples: Ulong,
132}
133
134#[derive(Debug, Clone)]
135pub struct LoudspeakerConfigChunk {
136    pub chunk: Chunk,
137    #[allow(dead_code)]
138    pub ls_config: Ushort,
139}
140
141#[derive(Debug, Clone)]
142pub struct DsdChunk {
143    pub chunk: Chunk,
144}
145
146#[derive(Debug, Clone)]
147pub struct Id3Chunk {
148    #[allow(dead_code)]
149    pub chunk: Chunk,
150    pub tag: Option<Tag>,
151}