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);
}