diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/foosdk/sdk/foobar2000/helpers/cuesheet_index_list.cpp	Mon Jan 05 02:15:46 2026 -0500
@@ -0,0 +1,145 @@
+#include "StdAfx.h"
+#include "cuesheet_index_list.h"
+
+#include "cue_parser.h" // exception_bad_cuesheet
+
+bool t_cuesheet_index_list::is_valid() const {
+	if (m_positions[1] < m_positions[0]) return false;
+	for(t_size n = 2; n < count && m_positions[n] > 0; n++) {
+		if (m_positions[n] < m_positions[n-1]) return false;
+	}
+	return true;
+}
+
+void t_cuesheet_index_list::to_infos(file_info & p_out) const
+{
+	double base = m_positions[1];
+
+	if (base > 0) {
+		p_out.info_set("referenced_offset",cuesheet_format_index_time(base));
+	}
+	
+	if (m_positions[0] < base)
+		p_out.info_set("pregap",cuesheet_format_index_time(base - m_positions[0]));
+	else
+		p_out.info_remove("pregap");
+
+	p_out.info_remove("index 00");	
+	p_out.info_remove("index 01");
+	
+	for(unsigned n=2;n<count;n++)
+	{
+		char namebuffer[16];
+		snprintf(namebuffer, std::size(namebuffer), "index %02u",n);
+		double position = m_positions[n] - base;
+		if (position > 0)
+			p_out.info_set(namebuffer,cuesheet_format_index_time(position));
+		else
+			p_out.info_remove(namebuffer);
+	}
+}
+
+static bool parse_value(const char * p_name,double & p_out)
+{
+	if (p_name == NULL) return false;
+	try {
+		p_out = cuesheet_parse_index_time_e(p_name,strlen(p_name));
+	} catch(std::exception const &) {return false;}
+	return true;
+}
+
+bool t_cuesheet_index_list::from_infos(file_info const & p_in,double p_base)
+{
+	double pregap;
+	bool found = false;
+	if (!parse_value(p_in.info_get("pregap"),pregap)) pregap = 0;
+	else found = true;
+	m_positions[0] = p_base - pregap;
+	m_positions[1] = p_base;
+	for(unsigned n=2;n<count;n++)
+	{
+		char namebuffer[16];
+		snprintf(namebuffer, std::size(namebuffer),"index %02u",n);
+		double temp;
+		if (parse_value(p_in.info_get(namebuffer),temp)) {
+			m_positions[n] = temp + p_base; found = true;
+		} else {
+			m_positions[n] = 0;
+		}
+	}
+	return found;	
+}
+
+bool t_cuesheet_index_list::is_empty() const {
+	for(unsigned n=0;n<count;n++) if (m_positions[n] != m_positions[1]) return false;
+	return true;
+}
+
+
+
+
+
+
+cuesheet_format_index_time::cuesheet_format_index_time(double p_time)
+{
+	t_uint64 ticks = audio_math::time_to_samples(p_time,75);
+	t_uint64 seconds = ticks / 75; ticks %= 75;
+	t_uint64 minutes = seconds / 60; seconds %= 60;
+	m_buffer << pfc::format_uint(minutes,2) << ":" << pfc::format_uint(seconds,2) << ":" << pfc::format_uint(ticks,2);
+}
+
+double cuesheet_parse_index_time_e(const char * p_string,t_size p_length)
+{
+	return (double) cuesheet_parse_index_time_ticks_e(p_string,p_length) / 75.0;
+}
+
+unsigned cuesheet_parse_index_time_ticks_e(const char * p_string,t_size p_length)
+{
+	p_length = pfc::strlen_max(p_string,p_length);
+	t_size ptr = 0;
+	t_size splitmarks[2];
+	t_size splitptr = 0;
+	for(ptr=0;ptr<p_length;ptr++)
+	{
+		if (p_string[ptr] == ':')
+		{
+			if (splitptr >= 2) 
+				pfc::throw_exception_with_message< cue_parser::exception_bad_cuesheet >("invalid INDEX time syntax");
+			splitmarks[splitptr++] = ptr;
+		}
+		else if (!pfc::char_is_numeric(p_string[ptr])) 
+			pfc::throw_exception_with_message< cue_parser::exception_bad_cuesheet >("invalid INDEX time syntax");
+	}
+	
+	t_size minutes_base = 0, minutes_length = 0, seconds_base = 0, seconds_length = 0, frames_base = 0, frames_length = 0;
+
+	switch(splitptr)
+	{
+	case 0:
+		frames_base = 0;
+		frames_length = p_length;
+		break;
+	case 1:
+		seconds_base = 0;
+		seconds_length = splitmarks[0];
+		frames_base = splitmarks[0] + 1;
+		frames_length = p_length - frames_base;
+		break;
+	case 2:
+		minutes_base = 0;
+		minutes_length = splitmarks[0];
+		seconds_base = splitmarks[0] + 1;
+		seconds_length = splitmarks[1] - seconds_base;
+		frames_base = splitmarks[1] + 1;
+		frames_length = p_length - frames_base;
+		break;
+	}
+
+	unsigned ret = 0;
+
+	if (frames_length > 0) ret += pfc::atoui_ex(p_string + frames_base,frames_length);
+	if (seconds_length > 0) ret += 75 * pfc::atoui_ex(p_string + seconds_base,seconds_length);
+	if (minutes_length > 0) ret += 60 * 75 * pfc::atoui_ex(p_string + minutes_base,minutes_length);
+
+	return ret;	
+}