All pastes #383856 Raw Edit

Someone

public text v1 · immutable
·published 2007-03-06 17:29 UTC
rendered paste body

enum Endian {
	LittleEndian,
	BigEndian
};

template <typename T>
inline const T &qMin(const T &a, const T &b) { if (a < b) return a; return b; }
template <typename T>
inline const T &qMax(const T &a, const T &b) { if (a < b) return b; return a; }
template <typename T>
inline const T &qBound(const T &min, const T &val, const T &max)
{ return qMax(min, qMin(max, val)); }

typedef int qint32;
typedef short qint16;
typedef unsigned short quint16;
typedef char qint8;
typedef unsigned char quint8;

//--- expand ------------------------------------------------------------------

template<typename T>
inline qint32 expand(T sample);

template<>
inline qint32 expand<float>(float sample) {
	double tmp = sample * 2147483647.0 + 0.5;
	
	return (qint32)qBound(-2147483648.0, tmp, 2147483647.0) >> 16;
}

template<>
inline qint32 expand<qint16>(qint16 sample) {
	return (qint32)sample << 16;
}

template<>
inline qint32 expand<quint16>(quint16 sample) {
	return ((qint32)sample << 16) ^ (1 << 31);
}

template<>
inline qint32 expand<qint8>(qint8 sample) {
	return (qint32)sample << 24;
}

template<>
inline qint32 expand<quint8>(quint8 sample) {
	return ((qint32)sample << 24) ^ (1 << 31);
}

//--- compress ----------------------------------------------------------------

template<typename T>
inline T compress(qint32 sample);

template<>
inline float compress<float>(qint32 sample) {
	return (float)sample + 4.6566128752457969e-10;
}

template<>
inline qint16 compress<qint16>(qint32 sample) {
	return sample >> 16;
}

template<>
inline quint16 compress<quint16>(qint32 sample) {
	return (sample ^ (1 << 31)) >> 16;
}

template<>
inline qint8 compress<qint8>(qint32 sample) {
	return sample >> 24;
}

template<>
inline quint8 compress<quint8>(qint32 sample) {
	return (sample ^ (1 << 31)) >> 24;
}

//--- convert -----------------------------------------------------------------

template<typename T1, typename T2, Endian E1, Endian E2>
inline void convert(T1* input, T2* output, int size);

template<typename T1, typename T2>
inline void convert<T1, T2, LittleEndian, LittleEndian>(T1* input, T2* output, int size) {
	for (int i = 0; i < size; ++i) {
		*output++ = /*qToLittleEndian*/(compress<T2>(expand<T1>(/*qFromLittleEndian*/(*input++))));
	}
}

template<typename T1, typename T2>
inline void convert<T1, T2, BigEndian, BigEndian>(T1* input, T2* output, int size) {
	for (int i = 0; i < size; ++i) {
		*output++ = /*qToBigEndian*/(compress<T2>(expand<T1>(/*qFromBigEndian*/(*input++))));
	}
}

template<typename T1, typename T2>
inline void convert<T1, T2, LittleEndian, BigEndian>(T1* input, T2* output, int size) {
	for (int i = 0; i < size; ++i) {
		*output++ = /*qToLittleEndian*/(compress<T2>(expand<T1>(/*qFromBigEndian*/(*input++))));
	}
}

template<typename T1, typename T2>
inline void convert<T1, T2, BigEndian, LittleEndian>(T1* input, T2* output, int size) {
	for (int i = 0; i < size; ++i) {
		*output++ = /*qToBigEndian*/(compress<T2>(expand<T1>(/*qFromLittleEndian*/(*input++))));
	}
}

//--- main --------------------------------------------------------------------

typedef void (*FromAtoB)(void* input, void* output, int size);

static FromAtoB fromAtoB[] = {
	convert<float, float, LittleEndian, LittleEndian>, // F32 -> F32
	convert<float, qint16, LittleEndian, LittleEndian>, // F32 -> S16LE
	convert<float, qint16, LittleEndian, BigEndian> // F32 -> S16BLE
};

int main() {
	fromAtoB[0](0, 0, 0);
}