comparison foosdk/sdk/foobar2000/helpers/cuesheet_index_list.cpp @ 1:20d02a178406 default tip

*: check in everything else yay
author Paper <paper@tflc.us>
date Mon, 05 Jan 2026 02:15:46 -0500
parents
children
comparison
equal deleted inserted replaced
0:e9bb126753e7 1:20d02a178406
1 #include "StdAfx.h"
2 #include "cuesheet_index_list.h"
3
4 #include "cue_parser.h" // exception_bad_cuesheet
5
6 bool t_cuesheet_index_list::is_valid() const {
7 if (m_positions[1] < m_positions[0]) return false;
8 for(t_size n = 2; n < count && m_positions[n] > 0; n++) {
9 if (m_positions[n] < m_positions[n-1]) return false;
10 }
11 return true;
12 }
13
14 void t_cuesheet_index_list::to_infos(file_info & p_out) const
15 {
16 double base = m_positions[1];
17
18 if (base > 0) {
19 p_out.info_set("referenced_offset",cuesheet_format_index_time(base));
20 }
21
22 if (m_positions[0] < base)
23 p_out.info_set("pregap",cuesheet_format_index_time(base - m_positions[0]));
24 else
25 p_out.info_remove("pregap");
26
27 p_out.info_remove("index 00");
28 p_out.info_remove("index 01");
29
30 for(unsigned n=2;n<count;n++)
31 {
32 char namebuffer[16];
33 snprintf(namebuffer, std::size(namebuffer), "index %02u",n);
34 double position = m_positions[n] - base;
35 if (position > 0)
36 p_out.info_set(namebuffer,cuesheet_format_index_time(position));
37 else
38 p_out.info_remove(namebuffer);
39 }
40 }
41
42 static bool parse_value(const char * p_name,double & p_out)
43 {
44 if (p_name == NULL) return false;
45 try {
46 p_out = cuesheet_parse_index_time_e(p_name,strlen(p_name));
47 } catch(std::exception const &) {return false;}
48 return true;
49 }
50
51 bool t_cuesheet_index_list::from_infos(file_info const & p_in,double p_base)
52 {
53 double pregap;
54 bool found = false;
55 if (!parse_value(p_in.info_get("pregap"),pregap)) pregap = 0;
56 else found = true;
57 m_positions[0] = p_base - pregap;
58 m_positions[1] = p_base;
59 for(unsigned n=2;n<count;n++)
60 {
61 char namebuffer[16];
62 snprintf(namebuffer, std::size(namebuffer),"index %02u",n);
63 double temp;
64 if (parse_value(p_in.info_get(namebuffer),temp)) {
65 m_positions[n] = temp + p_base; found = true;
66 } else {
67 m_positions[n] = 0;
68 }
69 }
70 return found;
71 }
72
73 bool t_cuesheet_index_list::is_empty() const {
74 for(unsigned n=0;n<count;n++) if (m_positions[n] != m_positions[1]) return false;
75 return true;
76 }
77
78
79
80
81
82
83 cuesheet_format_index_time::cuesheet_format_index_time(double p_time)
84 {
85 t_uint64 ticks = audio_math::time_to_samples(p_time,75);
86 t_uint64 seconds = ticks / 75; ticks %= 75;
87 t_uint64 minutes = seconds / 60; seconds %= 60;
88 m_buffer << pfc::format_uint(minutes,2) << ":" << pfc::format_uint(seconds,2) << ":" << pfc::format_uint(ticks,2);
89 }
90
91 double cuesheet_parse_index_time_e(const char * p_string,t_size p_length)
92 {
93 return (double) cuesheet_parse_index_time_ticks_e(p_string,p_length) / 75.0;
94 }
95
96 unsigned cuesheet_parse_index_time_ticks_e(const char * p_string,t_size p_length)
97 {
98 p_length = pfc::strlen_max(p_string,p_length);
99 t_size ptr = 0;
100 t_size splitmarks[2];
101 t_size splitptr = 0;
102 for(ptr=0;ptr<p_length;ptr++)
103 {
104 if (p_string[ptr] == ':')
105 {
106 if (splitptr >= 2)
107 pfc::throw_exception_with_message< cue_parser::exception_bad_cuesheet >("invalid INDEX time syntax");
108 splitmarks[splitptr++] = ptr;
109 }
110 else if (!pfc::char_is_numeric(p_string[ptr]))
111 pfc::throw_exception_with_message< cue_parser::exception_bad_cuesheet >("invalid INDEX time syntax");
112 }
113
114 t_size minutes_base = 0, minutes_length = 0, seconds_base = 0, seconds_length = 0, frames_base = 0, frames_length = 0;
115
116 switch(splitptr)
117 {
118 case 0:
119 frames_base = 0;
120 frames_length = p_length;
121 break;
122 case 1:
123 seconds_base = 0;
124 seconds_length = splitmarks[0];
125 frames_base = splitmarks[0] + 1;
126 frames_length = p_length - frames_base;
127 break;
128 case 2:
129 minutes_base = 0;
130 minutes_length = splitmarks[0];
131 seconds_base = splitmarks[0] + 1;
132 seconds_length = splitmarks[1] - seconds_base;
133 frames_base = splitmarks[1] + 1;
134 frames_length = p_length - frames_base;
135 break;
136 }
137
138 unsigned ret = 0;
139
140 if (frames_length > 0) ret += pfc::atoui_ex(p_string + frames_base,frames_length);
141 if (seconds_length > 0) ret += 75 * pfc::atoui_ex(p_string + seconds_base,seconds_length);
142 if (minutes_length > 0) ret += 60 * 75 * pfc::atoui_ex(p_string + minutes_base,minutes_length);
143
144 return ret;
145 }