latest SDK
This commit is contained in:
145
foobar2000/helpers/cuesheet_index_list.cpp
Normal file
145
foobar2000/helpers/cuesheet_index_list.cpp
Normal file
@@ -0,0 +1,145 @@
|
||||
#include "stdafx.h"
|
||||
#include "cuesheet_index_list.h"
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#define sprintf_s sprintf
|
||||
#endif
|
||||
|
||||
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];
|
||||
sprintf_s(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];
|
||||
sprintf_s(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) throw std::runtime_error("invalid INDEX time syntax");
|
||||
splitmarks[splitptr++] = ptr;
|
||||
}
|
||||
else if (!pfc::char_is_numeric(p_string[ptr])) throw std::runtime_error("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;
|
||||
}
|
||||
Reference in New Issue
Block a user