Mercurial > foo_out_sdl
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 } |
