1
2use fraction::ToPrimitive;
3
4use crate::enums::*;
5use crate::io::*;
6use crate::headers::*;
7use crate::page::*;
8use crate::track::*;
9use crate::key_signature::*;
10use crate::lyric::*;
11use crate::midi::*;
12use crate::rse::*;
13
14
15#[derive(Debug,Clone)]
17pub struct Song {
18 pub version: Version,
19 pub clipboard: Option<Clipboard>,
20
21 pub name: String,
22 pub subtitle: String, pub artist: String,
24 pub album: String,
25 pub words: String, pub author: String, pub date: String,
28 pub copyright: String,
29 pub writer: String,
31 pub transcriber: String,
32 pub instructions: String,
33 pub comments: String,
34 pub notice: Vec<String>,
35
36 pub tracks: Vec<Track>,
37 pub measure_headers: Vec<MeasureHeader>,
38 pub channels: Vec<MidiChannel>,
39 pub lyrics: Lyrics,
40 pub tempo: i16,
41 pub hide_tempo: bool,
42 pub tempo_name:String,
43 pub key: KeySignature,
44
45 pub triplet_feel: TripletFeel,
46 pub master_effect: RseMasterEffect,
47
48 pub page_setup: PageSetup,
49
50 pub current_measure_number: Option<usize>,
52 pub current_track: Option<usize>,
53 pub current_voice_number: Option<usize>,
54 pub current_beat_number: Option<usize>,
55}
56
57impl Default for Song {
58 fn default() -> Self { Song {
59 version: Version {data: String::with_capacity(30), clipboard: false, number: (5,1,0)}, clipboard: None,
60 name:String::new(), subtitle: String::new(), artist:String::new(), album: String::new(),
61 words: String::new(), author:String::new(), date:String::new(),
62 copyright:String::new(), writer:String::new(), transcriber:String::new(), comments:String::new(),
63 notice:Vec::new(),
64 instructions: String::new(),
65 tracks:Vec::new(),
66 measure_headers:Vec::new(),
67 channels:Vec::with_capacity(64),
68 lyrics: Lyrics::default(),
69 tempo: 120, hide_tempo: false, tempo_name:String::from("Moderate"),
70 key: KeySignature::default(),
71
72 triplet_feel: TripletFeel::None,
73 current_measure_number: None, current_track: None, current_voice_number: None, current_beat_number: None,
74
75 page_setup: PageSetup::default(),
76
77 master_effect: RseMasterEffect::default(),
78 }}
79}
80impl Song {
81 pub fn read_gp3(&mut self, data: &[u8]) {
94 let mut seek: usize = 0;
95 self.version = read_version_string(data, &mut seek);
96 self.read_info(data, &mut seek);
97 self.triplet_feel = if read_bool(data, &mut seek) {TripletFeel::Eighth} else {TripletFeel::None};
98 self.tempo = read_int(data, &mut seek).to_i16().unwrap();
100 self.key.key = read_int(data, &mut seek).to_i8().unwrap();
101 self.read_midi_channels(data, &mut seek);
103 let measure_count = read_int(data, &mut seek).to_usize().unwrap();
104 let track_count = read_int(data, &mut seek).to_usize().unwrap();
105 self.read_measure_headers(data, &mut seek, measure_count);
108 self.current_measure_number = Some(0);
109 self.read_tracks(data, &mut seek, track_count);
110 self.read_measures(data, &mut seek);
111 }
112 pub fn read_gp4(&mut self, data: &[u8]) {
127 let mut seek: usize = 0;
128 self.version = read_version_string(data, &mut seek);
129 self.read_clipboard(data, &mut seek);
130 self.read_info(data, &mut seek);
131 self.triplet_feel = if read_bool(data, &mut seek) {TripletFeel::Eighth} else {TripletFeel::None};
132 self.lyrics = self.read_lyrics(data, &mut seek); self.tempo = read_int(data, &mut seek).to_i16().unwrap();
135 self.key.key = read_int(data, &mut seek).to_i8().unwrap();
136 read_signed_byte(data, &mut seek); self.read_midi_channels(data, &mut seek);
139 let measure_count = read_int(data, &mut seek).to_usize().unwrap();
140 let track_count = read_int(data, &mut seek).to_usize().unwrap();
141 self.read_measure_headers(data, &mut seek, measure_count);
144 self.read_tracks(data, &mut seek, track_count);
146 self.read_measures(data, &mut seek);
147 }
148 pub fn read_gp5(&mut self, data: &[u8]) {
149 let mut seek: usize = 0;
150 self.version = read_version_string(data, &mut seek);
151 self.read_clipboard(data, &mut seek);
152 self.read_info(data, &mut seek);
153 self.lyrics = self.read_lyrics(data, &mut seek); self.master_effect = self.read_rse_master_effect(data, &mut seek);
155 self.read_page_setup(data, &mut seek);
156 self.tempo_name = read_int_size_string(data, &mut seek);
157 self.tempo = read_int(data, &mut seek).to_i16().unwrap();
158 self.hide_tempo = if self.version.number > (5,0,0) {read_bool(data, &mut seek)} else {false};
159 self.key.key = read_signed_byte(data, &mut seek);
160 read_int(data, &mut seek); self.read_midi_channels(data, &mut seek);
162 let directions = self.read_directions(data, &mut seek);
163 self.master_effect.reverb = read_int(data, &mut seek).to_f32().unwrap();
164 let measure_count = read_int(data, &mut seek).to_usize().unwrap();
165 let track_count = read_int(data, &mut seek).to_usize().unwrap();
166 println!("Track count: {} \t Measure count: {}", track_count, measure_count); self.read_measure_headers_v5(data, &mut seek, measure_count, &directions);
169 self.read_tracks_v5(data, &mut seek, track_count);
170 println!("read_gp5(), after tracks \t seek: {}", seek);
171 self.read_measures(data, &mut seek);
172 println!("read_gp5(), after measures \t seek: {}", seek);
173 }
174
175 fn read_info(&mut self, data: &[u8], seek: &mut usize) {
177 self.name = read_int_byte_size_string(data, seek);self.subtitle = read_int_byte_size_string(data, seek);
179 self.artist = read_int_byte_size_string(data, seek);
180 self.album = read_int_byte_size_string(data, seek);
181 self.words = read_int_byte_size_string(data, seek); self.author = if self.version.number.0 < 5 {self.words.clone()} else {read_int_byte_size_string(data, seek)};
183 self.copyright = read_int_byte_size_string(data, seek);
184 self.writer = read_int_byte_size_string(data, seek); self.instructions= read_int_byte_size_string(data, seek); let nc = read_int(data, seek).to_usize().unwrap(); if nc > 0 { for i in 0..nc { self.notice.push(read_int_byte_size_string(data, seek)); println!(" {}\t\t{}",i, self.notice[self.notice.len()-1]); }}
189 }
190
191 pub fn write(&self, version: (u8,u8,u8), clipboard: Option<bool>) ->Vec<u8> {
198 let mut data: Vec<u8> = Vec::with_capacity(8388608); write_version(&mut data, version);
200 if clipboard.is_some() && clipboard.unwrap() && version.0 >= 4 {self.write_clipboard(&mut data, &version);}
201 self.write_info(&mut data, version);
202 if version.0 < 5 {write_bool(&mut data, self.triplet_feel != TripletFeel::None);}
203 if version.0 >= 4 {self.write_lyrics(&mut data);}
204 if version > (5,0,0) {self.write_rse_master_effect(&mut data);}
205 if version.0 >= 5 {
206 self.write_page_setup(&mut data);
207 write_int_byte_size_string(&mut data, &self.tempo_name);
208 }
209 write_i32(&mut data, self.tempo.to_i32().unwrap());
210 if version > (5,0,0) {write_bool(&mut data, self.hide_tempo);}
211 write_i32(&mut data, self.key.key.to_i32().unwrap());
212
213 if version.0 >= 4 {write_signed_byte(&mut data, 0);} self.write_midi_channels(&mut data); if version.0 == 5 {
218 self.write_directions(&mut data);
219 self.write_master_reverb(&mut data);
220 }
221
222 write_i32(&mut data, self.tracks[0].measures.len().to_i32().unwrap());
223 write_i32(&mut data, self.tracks.len().to_i32().unwrap());
224 self.write_measure_headers(&mut data, &version);
225 self.write_tracks(&mut data, &version);
226 self.write_measures(&mut data, &version);
227 write_i32(&mut data, 0);
228 data
229 }
230 fn write_info(&self, data: &mut Vec<u8>, version: (u8,u8,u8)) {
231 write_int_byte_size_string(data, &self.name);
232 write_int_byte_size_string(data, &self.subtitle);
233 write_int_byte_size_string(data, &self.artist);
234 write_int_byte_size_string(data, &self.album);
235 if version.0 < 5 {write_int_byte_size_string(data, &self.pack_author());}
236 else {
237 write_int_byte_size_string(data, &self.words);
238 write_int_byte_size_string(data, &self.author);
239 }
240 write_int_byte_size_string(data, &self.copyright);
241 write_int_byte_size_string(data, &self.writer);
242 write_int_byte_size_string(data, &self.instructions);
243 write_i32(data, self.notice.len().to_i32().unwrap());
244 for i in 0..self.notice.len() {write_int_byte_size_string(data, &self.notice[i]);}
245 }
246 fn pack_author(&self) -> String {
247 if !self.words.is_empty() && !self.author.is_empty() {
248 if self.words != self.author {
249 let mut s = self.words.clone();
250 s.push_str(", ");
251 s.push_str(&self.author);
252 s
253 } else {self.words.clone()}
254 } else {
255 let mut s = self.words.clone();
256 s.push_str(&self.author);
257 s
258 }
259 }
260}