diff foosdk/sdk/foobar2000/helpers/mp3_utils.h @ 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/mp3_utils.h	Mon Jan 05 02:15:46 2026 -0500
@@ -0,0 +1,71 @@
+#pragma once
+
+namespace mp3_utils
+{
+
+	enum {
+		MPG_MD_STEREO=0,
+		MPG_MD_JOINT_STEREO=1,
+		MPG_MD_DUAL_CHANNEL=2,
+		MPG_MD_MONO=3,
+	};
+
+	typedef t_uint8 byte;
+
+	enum {MPEG_1, MPEG_2, MPEG_25};
+
+	struct TMPEGFrameInfo
+	{
+		unsigned m_bytes;
+		unsigned m_bitrate_idx; // original bitrate index value
+		unsigned m_bitrate; // kbps
+		unsigned m_sample_rate_idx; // original samples per second index value
+		unsigned m_sample_rate; // samples per second
+		unsigned m_layer; // 1, 2 or 3
+		unsigned m_mpegversion; // MPEG_1, MPEG_2, MPEG_25
+		unsigned m_channels; // 1 or 2
+		unsigned m_duration; // samples
+		unsigned m_channel_mode; // MPG_MD_*
+		unsigned m_channel_mode_ext;
+		bool m_crc;
+	};
+
+
+	bool ParseMPEGFrameHeader(TMPEGFrameInfo & p_info,const t_uint8 p_header[4]);
+	bool ParseMPEGFrameHeader(TMPEGFrameInfo & p_info, const void * bytes, size_t bytesAvail);
+	bool IsValidMPEGFrameHeader(const void* fourbytes);
+	bool ValidateFrameCRC(const t_uint8 * frameData, t_size frameSize);
+	bool ValidateFrameCRC(const t_uint8 * frameData, t_size frameSize, TMPEGFrameInfo const & frameInfo);
+	
+	//! Assumes valid frame with CRC (frameInfo.m_crc set, frameInfo.m_bytes <= frameSize).
+	t_uint16 ExtractFrameCRC(const t_uint8 * frameData, t_size frameSize, TMPEGFrameInfo const & frameInfo);
+	//! Assumes valid frame with CRC (frameInfo.m_crc set, frameInfo.m_bytes <= frameSize).
+	t_uint16 CalculateFrameCRC(const t_uint8 * frameData, t_size frameSize, TMPEGFrameInfo const & frameInfo);
+	//! Assumes valid frame with CRC (frameInfo.m_crc set, frameInfo.m_bytes <= frameSize).
+	void RecalculateFrameCRC(t_uint8 * frameData, t_size frameSize, TMPEGFrameInfo const & frameInfo);
+
+	unsigned QueryMPEGFrameSize(const t_uint8 p_header[4]);
+	bool IsSameStream(TMPEGFrameInfo const & p_frame1,TMPEGFrameInfo const & p_frame2);
+};
+
+class mp3header
+{
+	t_uint8 bytes[4];
+public:
+
+	inline void copy(const mp3header & src) {memcpy(bytes,src.bytes,4);}
+	inline void copy_raw(const void * src) {memcpy(bytes,src,4);}
+
+	inline void get_bytes(void * out) {memcpy(out,bytes,4);}
+	inline unsigned get_frame_size() const {return mp3_utils::QueryMPEGFrameSize(bytes);}
+	inline bool decode(mp3_utils::TMPEGFrameInfo & p_out) {return mp3_utils::ParseMPEGFrameHeader(p_out,bytes);}
+
+	unsigned get_samples_per_frame();
+};
+
+static inline mp3header mp3header_from_buffer(const void * p_buffer)
+{
+	mp3header temp;
+	temp.copy_raw(p_buffer);
+	return temp;
+}
\ No newline at end of file