1use 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), }
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>, }
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}