⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 taklibxx.h

📁 foo_input_tak-0.4.2-20080408-src tak文件识别代码
💻 H
字号:
#ifndef __TAKLIBXX_H__
#define __TAKLIBXX_H__

/**
 * \file taklibxx.h
 * Low-level C++ wrapper for the TAK decoder.
 * \author Holger Stenger
 */

#ifndef __cplusplus
#error TAKLIB++ must be compiled as C++
#endif

#include "tak_deco_lib.h"

namespace taklibxx
{
	class tak_library
	{
	public:
		static TtakResult get_library_version(TtakInt32 &p_version, TtakInt32 &p_compatible_version)
		{
			return tak_GetLibraryVersion(&p_version, &p_compatible_version);
		}
	};

	/**
	 * Wrapper to access basic functions of the TAK seekable stream decoder (SSD).
	 */
	class tak_ssd_ptr_raw
	{
	private:
		TtakSeekableStreamDecoder m_ptr;

	public:
		tak_ssd_ptr_raw() {m_ptr = 0;}
		~tak_ssd_ptr_raw() {reset();}

		bool is_empty() const {return m_ptr == 0;}

		void reset() {if (m_ptr != 0) tak_SSD_Destroy(m_ptr); m_ptr = 0;}

		bool is_decoder_valid()
		{
			PFC_ASSERT(m_ptr != 0);
			return tak_SSD_Valid(m_ptr) != tak_False;
		}

		void attach(TtakSeekableStreamDecoder p_ptr) {reset(); m_ptr = p_ptr;}
		TtakSeekableStreamDecoder detach() {TtakSeekableStreamDecoder ptr = m_ptr; m_ptr = 0; return ptr;}

		bool create_from_file(const char * p_path, const TtakSSDOptions &p_options, TSSDDamageCallback p_callback, void * p_callback_data)
		{
			reset();

			m_ptr = tak_SSD_Create_FromFile(p_path, &p_options, p_callback, p_callback_data);

			return m_ptr != 0;
		}

		bool create_from_stream(TtakStreamIoInterface * p_stream, void * p_stream_data, const TtakSSDOptions &p_options, TSSDDamageCallback p_callback, void * p_callback_data)
		{
			reset();

			m_ptr = tak_SSD_Create_FromStream(p_stream, p_stream_data, &p_options, p_callback, p_callback_data);

			return m_ptr != 0;
		}

		TtakResult get_stream_info(Ttak_str_StreamInfo & p_info)
		{
			PFC_ASSERT(m_ptr != 0);
			return tak_SSD_GetStreamInfo(m_ptr, &p_info);
		}

		TtakResult get_stream_encoder_info(Ttak_str_MetaEncoderInfo &p_encoder_info)
		{
			PFC_ASSERT(m_ptr != 0);
			return tak_SSD_GetEncoderInfo(m_ptr, &p_encoder_info);
		}

		TtakResult seek(TtakInt64 p_sample_pos)
		{
			PFC_ASSERT(m_ptr != 0);
			return tak_SSD_Seek(m_ptr, p_sample_pos);
		}

		TtakResult read_audio(void * p_buffer, TtakInt32 p_samples, TtakInt32 & p_samples_read)
		{
			PFC_ASSERT(m_ptr != 0);
			return tak_SSD_ReadAudio(m_ptr, p_buffer, p_samples, &p_samples_read);
		}

		TtakInt32 get_last_frame_bitrate()
		{
			PFC_ASSERT(m_ptr != 0);
			return tak_SSD_GetCurFrameBitRate(m_ptr);
		}

		TtakAPEv2Tag get_tag()
		{
			PFC_ASSERT(m_ptr != 0);
			return tak_SSD_GetAPEv2Tag(m_ptr);
		}
	};

	class tak_tag_raw
	{
	private:
		TtakAPEv2Tag m_ptr;

	public:
		tak_tag_raw() {m_ptr = 0;}
		~tak_tag_raw() {reset();}

		bool is_empty() {return m_ptr != 0;}

		void reset() {m_ptr = 0;}

		void attach(TtakAPEv2Tag p_ptr) {reset(); m_ptr = p_ptr;}
		TtakAPEv2Tag detach() {TtakAPEv2Tag ptr = m_ptr; m_ptr = 0; return ptr;}


		bool is_tag_valid()
		{
			PFC_ASSERT(m_ptr != 0);
			return tak_APE_Valid(m_ptr) != tak_False;
		}
	};

	/**
	 * Template class that adds convenience methods to a TAK SSD wrapper.
	 * Usage: tak_ssd_ptr_helper<tak_ssd_ptr_without_helper_methods>
	 */
	template <class T>
	class tak_ssd_ptr_helper : public T
	{
	public:
		bool create_from_file(const char * p_path, TtakInt32 p_flags = 0, TtakCpuOptions p_cpu_options = tak_Cpu_Any)
		{
			TtakSSDOptions options;
			options.Cpu = p_cpu_options;
			options.Flags = p_flags;

			return T::create_from_file(p_path, options, 0, 0);
		}

		bool create_from_stream(TtakStreamIoInterface * p_stream, void * p_stream_data, TtakInt32 p_flags = 0, TtakCpuOptions p_cpu_options = tak_Cpu_Any)
		{
			TtakSSDOptions options;
			options.Cpu = p_cpu_options;
			options.Flags = p_flags;

			return T::create_from_stream(p_stream, p_stream_data, options, 0, 0);
		}
	};

	/**
	 * Template class that extends the seeking range to all reachable positions.
	 * The raw TAK SSD does not allow seeking to the position after the last sample.
	 * It can only reach this position through decoding. The wrapper makes this
	 * position a valid seek target.
	 * Usage: tak_ssd_ptr_eos_seek_fix<tak_ssd_ptr_with_normal_seek_range>
	 */
	template <class T>
	class tak_ssd_ptr_eos_seek_fix : public T
	{
	private:
		bool m_is_virtual_eof;
		TtakInt64 m_sample_count;

	public:
		tak_ssd_ptr_eos_seek_fix()
		{
			m_is_virtual_eof = false;
			m_sample_count = -1;
		}

		TtakResult seek(TtakInt64 p_sample_position)
		{
			PFC_ASSERT(!is_empty());
			TtakResult result = tak_res_Ok;
			if (m_sample_count == -1)
			{
				Ttak_str_StreamInfo info;
				TtakResult res = get_stream_info(info);
				m_sample_count = info.Sizes.SampleNum;
			}
			if (p_sample_position >= m_sample_count)
			{
				m_is_virtual_eof = true;
			}
			else
			{
				m_is_virtual_eof = false;
				result = T::seek(p_sample_position);
			}
			return result;
		}

		TtakResult read_audio(void * p_buffer, TtakInt32 p_samples, TtakInt32 & p_samples_read)
		{
			PFC_ASSERT(!is_empty());
			TtakResult result = tak_res_Ok;
			if (m_is_virtual_eof)
			{
				p_samples_read = 0;
			}
			else
			{
				result = T::read_audio(p_buffer, p_samples, p_samples_read);
			}
			return result;
		}
	};

#ifdef _FOOBAR2000_H_
	/**
	 * Template class that outputs trace information on the foobar2000 console
	 * Usage: tak_ssd_ptr_trace<tak_ssd_ptr_where_method_calls_should_be_traced>
	 */
	template <class T, char const * NAME = 0>
	class tak_ssd_ptr_trace : public T
	{
	private:
		class trace_formatter : public console::formatter
		{
		public:
			trace_formatter(const char * p_method, bool p_leaving)
			{
				if (NAME != 0)
					*this << "(" << NAME << ") ";
				*this << (p_leaving ? "leaving " : "entering ") << p_method;
			}
		};

	public:
		bool create_from_file(const char * p_path, const TtakSSDOptions &p_options, TSSDDamageCallback p_callback, void * p_callback_data)
		{
			trace_formatter("create_from_file", false);
			bool result = T::create_from_file(p_path, p_options, p_callback, p_callback_data);
			trace_formatter("create_from_file", true)
				<< ": result = " << (result ? "true" : "false");
			return result;
		}

		bool create_from_stream(TtakStreamIoInterface * p_stream, void * p_stream_data, const TtakSSDOptions &p_options, TSSDDamageCallback p_callback, void * p_callback_data)
		{
			trace_formatter("create_from_stream", false);
			bool result = T::create_from_stream(p_stream, p_stream_data, p_options, p_callback, p_callback_data);
			trace_formatter("create_from_stream", true)
				<< ": result = " << (result ? "true" : "false");
			return result;
		}

		TtakResult get_stream_info(Ttak_str_StreamInfo & p_info)
		{
			trace_formatter("get_stream_info", false);
			TtakResult result = T::get_stream_info(p_info);
			trace_formatter("get_stream_info", true)
				<< ": result = " << result;
			return result;
		}

		TtakResult get_stream_encoder_info(Ttak_str_EncoderInfo &p_encoder_info)
		{
			trace_formatter("get_stream_encoder_info", false);
			TtakResult result = T::get_stream_encoder_info(p_encoder_info);
			trace_formatter("get_stream_encoder_info", true)
				<< ": result = " << result;
			return result;
		}

		TtakResult seek(TtakInt64 p_sample_pos)
		{
			trace_formatter("seek", false)
				<< ": sample = " << p_sample_pos;

			TtakResult result = T::seek(p_sample_pos);

			trace_formatter("seek", true)
				<< ": result = " << result;

			return result;
		}

		TtakResult read_audio(void * p_buffer, TtakInt32 p_samples, TtakInt32 & p_samples_read)
		{
			trace_formatter("read_audio", false)
				<< ": requested samples = " << p_samples;

			TtakResult result = T::read_audio(p_buffer, p_samples, p_samples_read);

			trace_formatter("read_audio", true)
				<< ": result = " << result
				<< ", delivered samples = " << p_samples_read;

			return result;
		}

		TtakInt32 get_last_frame_bitrate()
		{
			trace_formatter("get_last_frame_bitrate", false);
			TtakInt32 result = T::get_last_frame_bitrate();
			trace_formatter("get_last_frame_bitrate", true)
				<< ": result = " << result;
			return result;
		}

		TtakAPEv2Tag get_tag()
		{
			trace_formatter("get_tag", false);
			TtakAPEv2Tag result = T::get_tag();
			trace_formatter("get_tag", true)
				<< ": result = " << ((result == 0) ? "<null>" : "<non-null>");
			return result;
		}

	};

	/**
	 * Template class that adds foobar2000 specific call tracking to methods.
	 * Usage: tak_ssd_ptr_trackcall<tak_ssd_ptr_without_call_tracking>
	 */
	template <class T>
	class tak_ssd_ptr_trackcall : public T
	{
	public:
		bool create_from_file(const char * p_path, const TtakSSDOptions &p_options, TSSDDamageCallback p_callback, void * p_callback_data)
		{
			TRACK_CALL_TEXT("tak_ssd::create_from_file");
			return T::create_from_file(p_path, p_options, p_callback, p_callback_data);
		}

		bool create_from_stream(TtakStreamIoInterface * p_stream, void * p_stream_data, const TtakSSDOptions &p_options, TSSDDamageCallback p_callback, void * p_callback_data)
		{
			TRACK_CALL_TEXT("tak_ssd::create_from_stream");
			return T::create_from_stream(p_stream, p_stream_data, p_options, p_callback, p_callback_data);
		}

		TtakResult get_stream_info(Ttak_str_StreamInfo & p_info)
		{
			TRACK_CALL_TEXT("tak_ssd::get_stream_info");
			return T::get_stream_info(p_info);
		}

		TtakResult get_stream_encoder_info(Ttak_str_MetaEncoderInfo &p_encoder_info)
		{
			TRACK_CALL_TEXT("tak_ssd::get_stream_encoder_info");
			return T::get_stream_encoder_info(p_encoder_info);
		}

		TtakResult seek(TtakInt64 p_sample_pos)
		{
			TRACK_CALL_TEXT("tak_ssd::seek");
			return T::seek(p_sample_pos);
		}

		TtakResult read_audio(void * p_buffer, TtakInt32 p_samples, TtakInt32 & p_samples_read)
		{
			TRACK_CALL_TEXT("tak_ssd::read_audio");
			return T::read_audio(p_buffer, p_samples, p_samples_read);
		}

		TtakInt32 get_last_frame_bitrate()
		{
			TRACK_CALL_TEXT("tak_ssd::get_last_frame_bitrate");
			return T::get_last_frame_bitrate();
		}

		TtakAPEv2Tag get_tag()
		{
			TRACK_CALL_TEXT("tak_ssd::get_tag");
			return T::get_tag();
		}
	};
#endif

} // namespace taklibxx

#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -