/*************************************************************************************************/
/*!
   	@file		BufferSampleFormat.h
	@author 	Fanzo
*/
/*************************************************************************************************/
#pragma		once

///////////////////////////////////////////////////////////////////////////////////////////////////
//include files
#include	"IFace/iAudioDevice.h"

#pragma pack( push , 8 )		//set align

namespace icubic_audio
{
using namespace icubic;
///////////////////////////////////////////////////////////////////////////////////////////////////
// preprocessor deifne

///////////////////////////////////////////////////////////////////////////////////////////////////
// type define
enum BufferSampleFormat
{
	Int8Align8	= 0 , 

	Int16Align16LSB , 
	Int16Align16MSB , 
	Int24Align24LSB , 
	Int24Align24MSB , 
	Int32Align32LSB , 
	Int32Align32MSB , 

	Float32Align32LSB , 		
	Float32Align32MSB , 		
	Float64Align64LSB , 		
	Float64Align64MSB , 

	Int16Align32LSB , 
	Int16Align32MSB , 
	Int18Align32LSB , 
	Int18Align32MSB , 
	Int20Align32LSB , 
	Int20Align32MSB , 
	Int24Align32LSB , 
	Int24Align32MSB , 
};
///////////////////////////////////////////////////////////////////////////////////////////////////
// global functions define

//=================================================================================================
cb_inline
int SampleFormat_to_Byte
		(
		BufferSampleFormat	fmt
		)
{
	switch( fmt )
	{
	case Int8Align8:
		return 1;
	case Int16Align16LSB:
	case Int16Align16MSB:
		return 2;
	case Int24Align24LSB:
	case Int24Align24MSB:
		return 3;
	case Int32Align32LSB:
	case Int32Align32MSB:
	case Float32Align32LSB:
	case Float32Align32MSB:
		return 4;
	case Float64Align64LSB:
	case Float64Align64MSB:
		return 8;

	case Int16Align32LSB:
	case Int16Align32MSB:
	case Int18Align32LSB:
	case Int18Align32MSB:
	case Int20Align32LSB:
	case Int20Align32MSB:
	case Int24Align32LSB:
	case Int24Align32MSB:
		return 4;
	default:
		return 0;
	}
}
//=================================================================================================
cb_inline
int32 Load_Int8Align8
		(
		const uint8*	s
		)
{
	return (int8)( (int32)( *s ) - 128 );
}
//=================================================================================================
cb_inline
int32 Load_Int16Align16LSB
		(
		const uint8*	s
		)
{
#ifdef cb_little_endian
	return *(const int16*)s;
#elif defined( cb_big_endian )
	uint8	v[]		= { p[1] , p[0] };
	return *(const int16*)v;
#else
	#error	unknown endian
#endif
}
//=================================================================================================
cb_inline
int32 Load_Int16Align16MSB
		(
		const uint8*	s
		)
{
#ifdef cb_little_endian
	uint8	v[]		= { s[1] , s[0] };
	return *(const int16*)v;
#elif defined( cb_big_endian )
	return *(const int16*)s;
#else
	#error	unknown endian
#endif
}
//=================================================================================================
cb_inline
int32 Load_Int24Align24LSB
		(
		const uint8*	s
		)
{
#ifdef cb_little_endian
	uint8	v[]		= { 0 , s[0] , s[1] , s[2] };
	return *(const int32*)v >> 8;
#elif defined( cb_big_endian )
	uint8	v[]		= { s[2] , s[1] , s[0] , 0 };
	return *(const int32*)v >> 8;
#else
	#error	unknown endian
#endif
}
//=================================================================================================
cb_inline
int32 Load_Int24Align24MSB
		(
		const uint8*	s
		)
{
#ifdef cb_little_endian
	uint8	v[]		= { 0 , s[2] , s[1] , s[0] };
	return *(const int32*)v >> 8;
#elif defined( cb_big_endian )
	uint8	v[]		= { s[0] , s[1] , s[2] , 0 };
	return *(const int32*)v >> 8;
#else
	#error	unknown endian
#endif
}
//=================================================================================================
cb_inline
int32 Load_Int32Align32LSB
		(
		const uint8*	s
		)
{
#ifdef cb_little_endian
	return *(const int32*)s;
#elif defined( cb_big_endian )
	uint8	v[]		= { s[3] , s[2] , s[1] , s[0] };
	return *(const int32*)v;
#else
	#error	unknown endian
#endif
}
//=================================================================================================
cb_inline
int32 Load_Int32Align32MSB
		(
		const uint8*	s
		)
{
#ifdef cb_little_endian
	uint8	v[]		= { s[3] , s[2] , s[1] , s[0] };
	return *(const int32*)v;
#elif defined( cb_big_endian )
	return *(const int32*)s;
#else
	#error	unknown endian
#endif
}
//=================================================================================================
cb_inline
float Load_Float32Align32LSB
		(
		const uint8*	s
		)
{
#ifdef cb_little_endian
	return *(const float*)s;
#elif defined( cb_big_endian )
	uint8	v[]		= { s[3] , s[2] , s[1] , s[0] };
	return *(const float*)v;
#else
	#error	unknown endian
#endif
}
//=================================================================================================
cb_inline
float Load_Float32Align32MSB
		(
		const uint8*	s
		)
{
#ifdef cb_little_endian
	uint8	v[]		= { s[3] , s[2] , s[1] , s[0] };
	return *(const float*)v;
#elif defined( cb_big_endian )
	return *(const float*)s;
#else
	#error	unknown endian
#endif
}
//=================================================================================================
cb_inline
double Load_Float64Align64LSB
		(
		const uint8*	s
		)
{
#ifdef cb_little_endian
	return *(const double*)s;
#elif defined( cb_big_endian )
	uint8	v[]		= { s[7] , s[6] , s[5] , s[4] , s[3] , s[2] , s[1] , s[0] };
	return *(const double*)v;
#else
	#error	unknown endian
#endif
}
//=================================================================================================
cb_inline
double Load_Float64Align64MSB
		(
		const uint8*	s
		)
{
#ifdef cb_little_endian
	uint8	v[]		= { s[7] , s[6] , s[5] , s[4] , s[3] , s[2] , s[1] , s[0] };
	return *(const double*)v;
#elif defined( cb_big_endian )
	return *(const double*)s;
#else
	#error	unknown endian
#endif
}
//=================================================================================================
cb_inline
int32 Load_Int16Align32LSB
		(
		const uint8*	s
		)
{
#ifdef cb_little_endian
	return ( ( int32 )( ( *( const uint32* )s ) << 16 ) ) >> 16;
#elif defined( cb_big_endian )
	uint8	v[]		= { s[3] , s[2] , s[1] , s[0] };
	return ( ( int32 )( ( *( const uint32* )v ) << 16 ) ) >> 16;
#else
	#error	unknown endian
#endif
}
//=================================================================================================
cb_inline
int32 Load_Int16Align32MSB
		(
		const uint8*	s
		)
{
#ifdef cb_little_endian
	uint8	v[]		= { s[3] , s[2] , s[1] , s[0] };
	return ( ( int32 )( ( *( const uint32* )v ) << 16 ) ) >> 16;
#elif defined( cb_big_endian )
	return ( ( int32 )( ( *( const uint32* )s ) << 16 ) ) >> 16;
#else
	#error	unknown endian
#endif
}
//=================================================================================================
cb_inline
int32 Load_Int18Align32LSB
		(
		const uint8*	s
		)
{
#ifdef cb_little_endian
	return ( ( int32 )( ( *( const uint32* )s ) << 14 ) ) >> 14;
#elif defined( cb_big_endian )
	uint8	v[]		= { s[3] , s[2] , s[1] , s[0] };
	return ( ( int32 )( ( *( const uint32* )v ) << 14 ) ) >> 14;
#else
	#error	unknown endian
#endif
}
//=================================================================================================
cb_inline
int32 Load_Int18Align32MSB
		(
		const uint8*	s
		)
{
#ifdef cb_little_endian
	uint8	v[]		= { s[3] , s[2] , s[1] , s[0] };
	return ( ( int32 )( ( *( const uint32* )v ) << 14 ) ) >> 14;
#elif defined( cb_big_endian )
	return ( ( int32 )( ( *( const uint32* )s ) << 14 ) ) >> 14;
#else
	#error	unknown endian
#endif
}
//=================================================================================================
cb_inline
int32 Load_Int20Align32LSB
		(
		const uint8*	s
		)
{
#ifdef cb_little_endian
	return ( ( int32 )( ( *( const uint32* )s ) << 12 ) ) >> 12;
#elif defined( cb_big_endian )
	uint8	v[]		= { s[3] , s[2] , s[1] , s[0] };
	return ( ( int32 )( ( *( const uint32* )v ) << 12 ) ) >> 12;
#else
	#error	unknown endian
#endif
}
//=================================================================================================
cb_inline
int32 Load_Int20Align32MSB
		(
		const uint8*	s
		)
{
#ifdef cb_little_endian
	uint8	v[]		= { s[3] , s[2] , s[1] , s[0] };
	return ( ( int32 )( ( *( const uint32* )v ) << 12 ) ) >> 12;
#elif defined( cb_big_endian )
	return ( ( int32 )( ( *( const uint32* )s ) << 12 ) ) >> 12;
#else
	#error	unknown endian
#endif
}
//=================================================================================================
cb_inline
int32 Load_Int24Align32LSB
		(
		const uint8*	s
		)
{
#ifdef cb_little_endian
	return ( ( int32 )( ( *( const uint32* )s ) << 8 ) ) >> 8;
#elif defined( cb_big_endian )
	uint8	v[]		= { s[3] , s[2] , s[1] , s[0] };
	return ( ( int32 )( ( *( const uint32* )v ) << 8 ) ) >> 8;
#else
	#error	unknown endian
#endif
}
//=================================================================================================
cb_inline
int32 Load_Int24Align32MSB
		(
		const uint8*	s
		)
{
#ifdef cb_little_endian
	uint8	v[]		= { s[3] , s[2] , s[1] , s[0] };
	return ( ( int32 )( ( *( const uint32* )v ) << 8 ) ) >> 8;
#elif defined( cb_big_endian )
	return ( ( int32 )( ( *( const uint32* )s ) << 8 ) ) >> 8;
#else
	#error	unknown endian
#endif
}
//=================================================================================================
cb_inline
void Store_Int8Align8
		(
		int32	v , 
		uint8*	t
		)
{
	*t	= (uint8)( (int32)v + 128 );
}
//=================================================================================================
cb_inline
void Store_Int16Align16LSB
		(
		int32	v , 
		uint8*	t
		)
{
#ifdef cb_little_endian
	*(int16*)t	= (int16)v;
#elif defined( cb_big_endian )
	uint8*	s = (uint8*)&v;
	t[0]	= s[3];
	t[1]	= s[2];
#else
	#error	unknown endian
#endif
}
//=================================================================================================
cb_inline
void Store_Int16Align16MSB
		(
		int32	v ,
		uint8*	t 
		)
{
#ifdef cb_little_endian
	uint8*	s = (uint8*)&v;
	t[0]	= s[1];
	t[1]	= s[0];
#elif defined( cb_big_endian )
	*(int16*)t	= (int16)v;
#else
	#error	unknown endian
#endif
}
//=================================================================================================
cb_inline
void Store_Int24Align24LSB
		(
		int32	v , 
		uint8*	t
		)
{
#ifdef cb_little_endian
	uint8*	s = (uint8*)&v;
	t[0]	= s[0];
	t[1]	= s[1];
	t[2]	= s[2];
#elif defined( cb_big_endian )
	uint8*	s = (uint8*)&v;
	t[0]	= s[3];
	t[1]	= s[2];
	t[2]	= s[1];
#else
	#error	unknown endian
#endif
}
//=================================================================================================
cb_inline
void Store_Int24Align24MSB
		(
		int32	v , 
		uint8*	t 
		)
{
#ifdef cb_little_endian
	uint8*	s = (uint8*)&v;
	t[0]	= s[2];
	t[1]	= s[1];
	t[2]	= s[0];
#elif defined( cb_big_endian )
	uint8*	s = (uint8*)&v;
	t[0]	= s[1];
	t[1]	= s[2];
	t[2]	= s[3];
#else
	#error	unknown endian
#endif
}
//=================================================================================================
cb_inline
void Store_Int32Align32LSB
		(
		int32	v , 
		uint8*	t
		)
{
#ifdef cb_little_endian
	*(int32*)t	= v;
#elif defined( cb_big_endian )
	uint8*	s = (uint8*)&v;
	t[0]	= s[3];
	t[1]	= s[2];
	t[2]	= s[1];
	t[3]	= s[0];
#else
	#error	unknown endian
#endif
}
//=================================================================================================
cb_inline
void Store_Int32Align32MSB
		(
		int32	v , 
		uint8*	t
		)
{
#ifdef cb_little_endian
	uint8*	s = (uint8*)&v;
	t[0]	= s[3];
	t[1]	= s[2];
	t[2]	= s[1];
	t[3]	= s[0];
#elif defined( cb_big_endian )
	*(int32*)t	= v;
#else
	#error	unknown endian
#endif
}
//=================================================================================================
cb_inline
void Store_Float32Align32LSB
		(
		float	v , 
		uint8*	t
		)
{
#ifdef cb_little_endian
	*(float*)t	= v;
#elif defined( cb_big_endian )
	uint8*	s = (uint8*)&v;
	t[0]	= s[3];
	t[1]	= s[2];
	t[2]	= s[1];
	t[3]	= s[0];
#else
	#error	unknown endian
#endif
}
//=================================================================================================
cb_inline
void Store_Float32Align32MSB
		(
		float	v , 
		uint8*	t
		)
{
#ifdef cb_little_endian
	uint8*	s = (uint8*)&v;
	t[0]	= s[3];
	t[1]	= s[2];
	t[2]	= s[1];
	t[3]	= s[0];
#elif defined( cb_big_endian )
	*(float*)t	= v;
#else
	#error	unknown endian
#endif
}
//=================================================================================================
cb_inline
void Store_Float64Align64LSB
		(
		double	v , 
		uint8*	t
		)
{
#ifdef cb_little_endian
	*(double*)t	= v;
#elif defined( cb_big_endian )
	uint8*	s = (uint8*)&v;
	t[0]	= s[7];
	t[1]	= s[6];
	t[2]	= s[5];
	t[3]	= s[4];
	t[4]	= s[3];
	t[5]	= s[2];
	t[6]	= s[1];
	t[7]	= s[0];
#else
	#error	unknown endian
#endif
}
//=================================================================================================
cb_inline
void Store_Float64Align64MSB
		(
		double	v , 
		uint8*	t
		)
{
#ifdef cb_little_endian
	uint8*	s = (uint8*)&v;
	t[0]	= s[7];
	t[1]	= s[6];
	t[2]	= s[5];
	t[3]	= s[4];
	t[4]	= s[3];
	t[5]	= s[2];
	t[6]	= s[1];
	t[7]	= s[0];
#elif defined( cb_big_endian )
	*(double*)t	= v;
#else
	#error	unknown endian
#endif
}
//=================================================================================================
cb_inline
void Store_Int16Align32LSB
		(
		int32	v , 
		uint8*	t
		)
{
#ifdef cb_little_endian
	*(int32*)t	= v;
#elif defined( cb_big_endian )
	uint8*	s = (uint8*)&v;
	t[0]	= s[3];
	t[1]	= s[2];
#else
	#error	unknown endian
#endif
}
//=================================================================================================
cb_inline
void Store_Int16Align32MSB
		(
		int32	v , 
		uint8*	t
		)
{
#ifdef cb_little_endian
	uint8*	s = (uint8*)&v;
	t[2]	= s[1];
	t[3]	= s[0];
#elif defined( cb_big_endian )
	*(int32*)t	= v;
#else
	#error	unknown endian
#endif
}
//=================================================================================================
cb_inline
void Store_Int18Align32LSB
		(
		int32	v , 
		uint8*	t
		)
{
#ifdef cb_little_endian
	*(int32*)t	= v;
#elif defined( cb_big_endian )
	uint8*	s = (uint8*)&v;
	t[0]	= s[3];
	t[1]	= s[2];
	t[2]	= s[1];
#else
	#error	unknown endian
#endif
}
//=================================================================================================
cb_inline
void Store_Int18Align32MSB
		(
		int32	v , 
		uint8*	t
		)
{
#ifdef cb_little_endian
	uint8*	s = (uint8*)&v;
	t[1]	= s[2];
	t[2]	= s[1];
	t[3]	= s[0];
#elif defined( cb_big_endian )
	*(int32*)t	= v;
#else
	#error	unknown endian
#endif
}
//=================================================================================================
cb_inline
void Store_Int20Align32LSB
		(
		int32	v , 
		uint8*	t
		)
{
#ifdef cb_little_endian
	*(int32*)t	= v;
#elif defined( cb_big_endian )
	uint8*	s = (uint8*)&v;
	t[0]	= s[3];
	t[1]	= s[2];
	t[2]	= s[1];
#else
	#error	unknown endian
#endif
}
//=================================================================================================
cb_inline
void Store_Int20Align32MSB
		(
		int32	v , 
		uint8*	t
		)
{
#ifdef cb_little_endian
	uint8*	s = (uint8*)&v;
	t[1]	= s[2];
	t[2]	= s[1];
	t[3]	= s[0];
#elif defined( cb_big_endian )
	*(int32*)t	= v;
#else
	#error	unknown endian
#endif
}
//=================================================================================================
cb_inline
void Store_Int24Align32LSB
		(
		int32	v , 
		uint8*	t
		)
{
#ifdef cb_little_endian
	*(int32*)t	= v;
#elif defined( cb_big_endian )
	uint8*	s = (uint8*)&v;
	t[0]	= s[3];
	t[1]	= s[2];
	t[2]	= s[1];
#else
	#error	unknown endian
#endif
}
//=================================================================================================
cb_inline
void Store_Int24Align32MSB
		(
		int32	v , 
		uint8*	t
		)
{
#ifdef cb_little_endian
	uint8*	s = (uint8*)&v;
	t[1]	= s[2];
	t[2]	= s[1];
	t[3]	= s[0];
#elif defined( cb_big_endian )
	*(int32*)t	= v;
#else
	#error	unknown endian
#endif
}
//=================================================================================================
#define cb_define_to_value( t_out_type , t_calc_type , t_bsf , t_min , t_max )					\
cb_inline																						\
t_out_type t_bsf##_to_##t_out_type																\
		(																						\
		const uint8*	t																		\
		)																						\
{																								\
	static const t_calc_type	min = (t_calc_type)t_min;										\
	static const t_calc_type	max = (t_calc_type)t_max;										\
	t_calc_type	v = (t_calc_type)Load_##t_bsf( t );												\
	return (t_out_type)(( v >= (t_calc_type)0 ) ? v / max : -v / min);							\
}
cb_define_to_value( float , float	, Int8Align8		, cb_int8_min , cb_int8_max )
cb_define_to_value( float , float	, Int16Align16LSB	, cb_int16_min , cb_int16_max )
cb_define_to_value( float , float	, Int16Align16MSB	, cb_int16_min , cb_int16_max )
cb_define_to_value( float , double	, Int24Align24LSB	, cb_int24_min , cb_int24_max )
cb_define_to_value( float , double	, Int24Align24MSB	, cb_int24_min , cb_int24_max )
cb_define_to_value( float , double	, Int32Align32LSB	, cb_int32_min , cb_int32_max )
cb_define_to_value( float , double	, Int32Align32MSB	, cb_int32_min , cb_int32_max )
cb_inline float Float32Align32LSB_to_float(const uint8*t){return Load_Float32Align32LSB( t );}
cb_inline float Float32Align32MSB_to_float(const uint8*t){return Load_Float32Align32MSB( t );}
cb_inline float Float64Align64LSB_to_float(const uint8*t){return (float)Load_Float64Align64LSB( t );}
cb_inline float Float64Align64MSB_to_float(const uint8*t){return (float)Load_Float64Align64MSB( t );}
cb_define_to_value( float , float	, Int16Align32LSB	, cb_int16_min , cb_int16_max )
cb_define_to_value( float , float	, Int16Align32MSB	, cb_int16_min , cb_int16_max )
cb_define_to_value( float , float	, Int18Align32LSB	, cb_int18_min , cb_int18_max )
cb_define_to_value( float , float	, Int18Align32MSB	, cb_int18_min , cb_int18_max )
cb_define_to_value( float , float	, Int20Align32LSB	, cb_int20_min , cb_int20_max )
cb_define_to_value( float , float	, Int20Align32MSB	, cb_int20_min , cb_int20_max )
cb_define_to_value( float , double	, Int24Align32LSB	, cb_int24_min , cb_int24_max )
cb_define_to_value( float , double	, Int24Align32MSB	, cb_int24_min , cb_int24_max )

//=================================================================================================
#define cb_define_value_to( t_in_type , t_out_type , t_calc_type , t_bsf , t_min , t_max )		\
cb_inline																						\
void t_in_type##_to_##t_bsf																		\
		(																						\
		t_in_type		v ,																		\
		uint8*			t																		\
		)																						\
{																								\
	v = clip( v , (t_in_type)-1.0 , (t_in_type)1.0 );											\
	static const t_calc_type	min = (t_calc_type)t_min;										\
	static const t_calc_type	max = (t_calc_type)t_max;										\
	Store_##t_bsf( (t_out_type)( v >= (t_calc_type)0 ? v * max : -v *min ) , t );				\
}
cb_define_value_to( float , int32	, float		, Int8Align8		, cb_int8_min	, cb_int8_max )
cb_define_value_to( float , int32	, float		, Int16Align16LSB	, cb_int16_min	, cb_int16_max )
cb_define_value_to( float , int32	, float		, Int16Align16MSB	, cb_int16_min	, cb_int16_max )
cb_define_value_to( float , int32	, double	, Int24Align24LSB	, cb_int24_min	, cb_int24_max )
cb_define_value_to( float , int32	, double	, Int24Align24MSB	, cb_int24_min	, cb_int24_max )
cb_define_value_to( float , int32	, double	, Int32Align32LSB	, cb_int32_min	, cb_int32_max )
cb_define_value_to( float , int32	, double	, Int32Align32MSB	, cb_int32_min	, cb_int32_max )
cb_inline void float_to_Float32Align32LSB(float	v , uint8* t){v = clip( v , -1.0f , 1.0f );Store_Float32Align32LSB( v , t );}
cb_inline void float_to_Float32Align32MSB(float	v ,	uint8* t){v = clip( v , -1.0f , 1.0f );Store_Float32Align32MSB( v , t );}
cb_inline void float_to_Float64Align64LSB(float	v , uint8* t){v = clip( v , -1.0f , 1.0f );Store_Float64Align64LSB( v , t );}
cb_inline void float_to_Float64Align64MSB(float	v ,	uint8* t){v = clip( v , -1.0f , 1.0f );Store_Float64Align64MSB( v , t );}
cb_define_value_to( float , int32	, float		, Int16Align32LSB	, cb_int16_min	, cb_int16_max )
cb_define_value_to( float , int32	, float		, Int16Align32MSB	, cb_int16_min	, cb_int16_max )
cb_define_value_to( float , int32	, float		, Int18Align32LSB	, cb_int18_min	, cb_int18_max )
cb_define_value_to( float , int32	, float		, Int18Align32MSB	, cb_int18_min	, cb_int18_max )
cb_define_value_to( float , int32	, float		, Int20Align32LSB	, cb_int20_min	, cb_int20_max )
cb_define_value_to( float , int32	, float		, Int20Align32MSB	, cb_int20_min	, cb_int20_max )
cb_define_value_to( float , int32	, double	, Int24Align32LSB	, cb_int24_min	, cb_int24_max )
cb_define_value_to( float , int32	, double	, Int24Align32MSB	, cb_int24_min	, cb_int24_max )

//=================================================================================================
cb_inline
float BufferSampleFormat_to_float
		(
		BufferSampleFormat	fmt , 
		const uint8*		t
		)
{
	typedef float (*FuncPtr)( const uint8* );
	static
	FuncPtr	funcs[] = 
	{
		Int8Align8_to_float , 
		Int16Align16LSB_to_float , 
		Int16Align16MSB_to_float , 
		Int24Align24LSB_to_float , 
		Int24Align24MSB_to_float , 
		Int32Align32LSB_to_float , 
		Int32Align32MSB_to_float , 
		Float32Align32LSB_to_float , 		
		Float32Align32MSB_to_float , 		
		Float64Align64LSB_to_float , 		
		Float64Align64MSB_to_float , 		
		Int16Align32LSB_to_float , 
		Int16Align32MSB_to_float , 
		Int18Align32LSB_to_float , 
		Int18Align32MSB_to_float , 
		Int20Align32LSB_to_float , 
		Int20Align32MSB_to_float , 
		Int24Align32LSB_to_float , 
		Int24Align32MSB_to_float , 
	};
	return ( *funcs[fmt] )( t );
}
//=================================================================================================
cb_inline
void float_to_BufferSampleFormat
		(
		float				v , 
		BufferSampleFormat	fmt , 
		uint8*				t
		)
{
	typedef void (*FuncPtr)( float , uint8* );
	static
	FuncPtr	funcs[] = 
	{
		float_to_Int8Align8 , 
		float_to_Int16Align16LSB , 
		float_to_Int16Align16MSB , 
		float_to_Int24Align24LSB , 
		float_to_Int24Align24MSB , 
		float_to_Int32Align32LSB , 
		float_to_Int32Align32MSB , 
		float_to_Float32Align32LSB , 		
		float_to_Float32Align32MSB , 		
		float_to_Float64Align64LSB , 		
		float_to_Float64Align64MSB , 		
		float_to_Int16Align32LSB , 
		float_to_Int16Align32MSB , 
		float_to_Int18Align32LSB , 
		float_to_Int18Align32MSB , 
		float_to_Int20Align32LSB , 
		float_to_Int20Align32MSB , 
		float_to_Int24Align32LSB , 
		float_to_Int24Align32MSB , 
	};
	( *funcs[fmt] )( v , t );
}
//=================================================================================================
cb_inline
void Interleave_to_float
		(
		int					channel , 
		int					samplenum , 
		BufferSampleFormat	fmt , 
		const uint8*		buffer , 
		float**				stream
		)
{
	int	samplebyte = SampleFormat_to_Byte( fmt );
	int	sampleoff;
	for( sampleoff = 0 ; sampleoff < samplenum ; sampleoff++ )
	{
		int	choff;
		for( choff = 0 ; choff < channel ; choff++ )
		{
			stream[choff][sampleoff] = BufferSampleFormat_to_float( fmt , buffer );
			buffer += samplebyte;
		}
	}
}
//=================================================================================================
cb_inline
void float_to_Interleave
		(
		int					channel , 
		int					samplenum , 
		float const*const*	stream , 
		BufferSampleFormat	fmt , 
		uint8*				buffer
		)
{
	int	samplebyte = SampleFormat_to_Byte( fmt );
	int	sampleoff;
	for( sampleoff = 0 ; sampleoff < samplenum ; sampleoff++ )
	{
		int	choff;
		for( choff = 0 ; choff < channel ; choff++ )
		{
			float_to_BufferSampleFormat( stream[choff][sampleoff] , fmt , buffer );
			buffer += samplebyte;
		}
	}
}
//=================================================================================================
cb_inline
void BufferSampleFormat_to_float
		(
		int					samplenum , 
		BufferSampleFormat	fmt , 
		const uint8*		buffer , 
		float*				stream
		)
{
#ifdef cb_little_endian
	if( fmt == Float32Align32LSB )
	{
		CopyMemory( stream , buffer , samplenum * sizeof( float ) );
		return;
	}
#elif defined( cb_big_endian )
	if( fmt == Float32Align32MSB )
	{
		CopyMemory( stream , buffer , samplenum * sizeof( float ) );
		return;
	}
#endif
	int	samplebyte = SampleFormat_to_Byte( fmt );
	int	sampleoff;
	for( sampleoff = 0 ; sampleoff < samplenum ; sampleoff++ )
	{
		stream[sampleoff] = BufferSampleFormat_to_float( fmt , buffer );
		buffer += samplebyte;
	}
}
//=================================================================================================
cb_inline
void float_to_BufferSampleFormat
		(
		int					samplenum , 
		const float*		stream , 
		BufferSampleFormat	fmt , 
		uint8*				buffer
		)
{
#ifdef cb_little_endian
	if( fmt == Float32Align32LSB )
	{
		CopyMemory( buffer , stream , samplenum * sizeof( float ) );
		return;
	}
#elif defined( cb_big_endian )
	if( fmt == Float32Align32MSB )
	{
		CopyMemory( buffer , stream , samplenum * sizeof( float ) );
		return;
	}
#endif
	int	samplebyte = SampleFormat_to_Byte( fmt );
	int	sampleoff;
	for( sampleoff = 0 ; sampleoff < samplenum ; sampleoff++ )
	{
		float_to_BufferSampleFormat( stream[sampleoff] , fmt , buffer );
		buffer += samplebyte;
	}
}

///////////////////////////////////////////////////////////////////////////////////////////////////
// classes define

///////////////////////////////////////////////////////////////////////////////////////////////////
// global variable define


};	//namespace


#pragma pack( pop )			//release align
