diff foosdk/sdk/foobar2000/SDK/replaygain_info.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/SDK/replaygain_info.cpp	Mon Jan 05 02:15:46 2026 -0500
@@ -0,0 +1,172 @@
+#include "foobar2000-sdk-pch.h"
+
+#ifdef _MSC_VER
+#include <pfc/fpu.h>
+#define RG_FPU() fpu_control_roundnearest bah;
+#else
+#define RG_FPU()
+#endif
+
+bool replaygain_info::g_format_gain(float p_value,char p_buffer[text_buffer_size])
+{
+	RG_FPU();
+	if (p_value == gain_invalid)
+	{
+		p_buffer[0] = 0;
+		return false;
+	}
+	else
+	{
+		pfc::float_to_string(p_buffer,text_buffer_size - 4,p_value,2,true);
+#ifdef _MSC_VER
+		strcat_s(p_buffer, text_buffer_size, " dB");
+#else
+		strcat(p_buffer, " dB");
+#endif
+		return true;
+	}
+}
+
+bool replaygain_info::g_format_peak_db(float p_value, char p_buffer[text_buffer_size]) {
+	const float lo = 1.0 / (float)(1 << 24);
+	if ( p_value == peak_invalid || p_value < lo ) return false;
+	return g_format_gain((float)audio_math::scale_to_gain(p_value), p_buffer);
+
+}
+
+bool replaygain_info::g_format_peak(float p_value,char p_buffer[text_buffer_size])
+{
+	RG_FPU();
+	if (p_value == peak_invalid)
+	{
+		p_buffer[0] = 0;
+		return false;
+	}
+	else
+	{
+		pfc::float_to_string(p_buffer,text_buffer_size,p_value,6,false);
+		return true;
+	}
+}
+
+void replaygain_info::reset()
+{
+	*this = replaygain_info();
+}
+
+#define meta_album_gain "replaygain_album_gain"
+#define meta_album_peak "replaygain_album_peak"
+#define meta_track_gain "replaygain_track_gain"
+#define meta_track_peak "replaygain_track_peak"
+
+bool replaygain_info::g_is_meta_replaygain(const char * p_name,t_size p_name_len)
+{
+	return 
+		stricmp_utf8_ex(p_name,p_name_len,meta_album_gain,SIZE_MAX) == 0 ||
+		stricmp_utf8_ex(p_name,p_name_len,meta_album_peak,SIZE_MAX) == 0 ||
+		stricmp_utf8_ex(p_name,p_name_len,meta_track_gain,SIZE_MAX) == 0 ||
+		stricmp_utf8_ex(p_name,p_name_len,meta_track_peak,SIZE_MAX) == 0;
+}
+
+bool replaygain_info::set_from_meta_ex(const char * p_name,t_size p_name_len,const char * p_value,t_size p_value_len)
+{
+	RG_FPU();
+	if (stricmp_utf8_ex(p_name,p_name_len,meta_album_gain,SIZE_MAX) == 0)
+	{
+		m_album_gain = (float)pfc::string_to_float(p_value,p_value_len);
+		return true;
+	}
+	else if (stricmp_utf8_ex(p_name,p_name_len,meta_album_peak,SIZE_MAX) == 0)
+	{
+		m_album_peak = (float)pfc::string_to_float(p_value,p_value_len);
+		if (m_album_peak < 0) m_album_peak = 0;
+		return true;
+	}
+	else if (stricmp_utf8_ex(p_name,p_name_len,meta_track_gain,SIZE_MAX) == 0)
+	{
+		m_track_gain = (float)pfc::string_to_float(p_value,p_value_len);
+		return true;
+	}
+	else if (stricmp_utf8_ex(p_name,p_name_len,meta_track_peak,SIZE_MAX) == 0)
+	{
+		m_track_peak = (float)pfc::string_to_float(p_value,p_value_len);
+		if (m_track_peak < 0) m_track_peak = 0;
+		return true;
+	}
+	else return false;
+}
+
+
+t_size replaygain_info::get_value_count()
+{
+	t_size ret = 0;
+	if (is_album_gain_present()) ret++;
+	if (is_album_peak_present()) ret++;
+	if (is_track_gain_present()) ret++;
+	if (is_track_peak_present()) ret++;
+	return ret;
+}
+
+float replaygain_info::anyGain(bool bPreferAlbum) const {
+	if ( bPreferAlbum ) {
+		if ( this->is_album_gain_present() ) return this->m_album_gain;
+		return this->m_track_gain;
+	} else {
+		if ( this->is_track_gain_present() ) return this->m_track_gain;
+		return this->m_album_gain;
+	}
+}
+
+float replaygain_info::g_parse_gain_text(const char * p_text, t_size p_text_len) {
+	RG_FPU();
+	if (p_text != 0 && p_text_len > 0 && *p_text != 0)
+		return (float)pfc::string_to_float(p_text, p_text_len);
+	else
+		return gain_invalid;
+}
+
+void replaygain_info::set_album_gain_text(const char * p_text,t_size p_text_len) {
+	m_album_gain = g_parse_gain_text(p_text, p_text_len);
+}
+
+void replaygain_info::set_track_gain_text(const char * p_text,t_size p_text_len)
+{
+	m_track_gain = g_parse_gain_text(p_text, p_text_len);
+}
+
+void replaygain_info::set_album_peak_text(const char * p_text,t_size p_text_len)
+{
+	RG_FPU();
+	if (p_text != 0 && p_text_len > 0 && *p_text != 0)
+		m_album_peak = (float)pfc::string_to_float(p_text,p_text_len);
+	else
+		remove_album_peak();
+}
+
+void replaygain_info::set_track_peak_text(const char * p_text,t_size p_text_len)
+{
+	RG_FPU();
+	if (p_text != 0 && p_text_len > 0 && *p_text != 0)
+		m_track_peak = (float)pfc::string_to_float(p_text,p_text_len);
+	else
+		remove_track_peak();
+}
+
+replaygain_info replaygain_info::g_merge(replaygain_info r1,replaygain_info r2)
+{
+	replaygain_info ret = r1;
+	if (!ret.is_album_gain_present()) ret.m_album_gain = r2.m_album_gain;
+	if (!ret.is_album_peak_present()) ret.m_album_peak = r2.m_album_peak;
+	if (!ret.is_track_gain_present()) ret.m_track_gain = r2.m_track_gain;
+	if (!ret.is_track_peak_present()) ret.m_track_peak = r2.m_track_peak;
+	return ret;
+}
+
+
+void replaygain_info::for_each(for_each_t f) const {
+	t_text_buffer buffer;
+	if (format_track_gain(buffer)) f(meta_track_gain, buffer);
+	if (format_track_peak(buffer)) f(meta_track_peak, buffer);
+	if (format_album_gain(buffer)) f(meta_album_gain, buffer);
+	if (format_album_peak(buffer)) f(meta_album_peak, buffer);
+}
\ No newline at end of file