146 lines
3.7 KiB
C++
146 lines
3.7 KiB
C++
#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;
|
|
}
|