Skip to content

Commit 4b9104b

Browse files
committed
ChannelMixer: template for sum type
1 parent c21b737 commit 4b9104b

File tree

1 file changed

+56
-39
lines changed

1 file changed

+56
-39
lines changed

src/AudioTools/CoreAudio/BaseConverter.h

Lines changed: 56 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -938,6 +938,41 @@ class ChannelDiff : public BaseConverter {
938938
int bits = 16;
939939
};
940940

941+
942+
/**
943+
* @brief We mix all input channels in a datastream. E.g. if we have stereo input data
944+
* we end up with 2 identical mono channels.
945+
* @author Phil Schatzmann
946+
* @ingroup convert
947+
* @tparam T
948+
*/
949+
template <typename T = int16_t, typename SumT = float>
950+
class ChannelMixer : public BaseConverter {
951+
public:
952+
ChannelMixer(int channels = 2) { this->channels = channels; }
953+
size_t convert(uint8_t *data, size_t size) {
954+
if (channels <= 1) return size; // No mixing needed for single channel
955+
T *srcT = (T *)data;
956+
T *targetT = (T *)data;
957+
int samples = size / sizeof(T);
958+
assert(samples % channels == 0);
959+
for (int j = 0; j < samples; j += channels) {
960+
SumT sum = 0;
961+
for (int ch = 0; ch < channels; ch++) {
962+
sum += srcT[j + ch];
963+
}
964+
T avg = sum / channels;
965+
for (int ch = 0; ch < channels; ch++) {
966+
targetT[j + ch] = avg;
967+
}
968+
}
969+
return size;
970+
}
971+
972+
protected:
973+
int channels = 2;
974+
};
975+
941976
/**
942977
* @brief We average pairs of channels in a datastream.
943978
* E.g. if we have 4 channels we end up with 2 channels.
@@ -951,7 +986,7 @@ class ChannelDiff : public BaseConverter {
951986
* @ingroup convert
952987
* @tparam T
953988
*/
954-
template <typename T = int16_t>
989+
template <typename T = int16_t, typename AvgT = float>
955990
class ChannelAvgT : public BaseConverter {
956991
public:
957992
ChannelAvgT() {}
@@ -975,7 +1010,7 @@ class ChannelAvgT : public BaseConverter {
9751010
for (int i = 0; i < sample_count; i++) {
9761011
// *p_result++ = (*p_source++ + *p_source++) / 2; // Average the pair of
9771012
// channels
978-
auto tmp = *p_source++;
1013+
AvgT tmp = *p_source++;
9791014
tmp += *p_source++;
9801015
*p_result++ = tmp / 2;
9811016
}
@@ -986,39 +1021,6 @@ class ChannelAvgT : public BaseConverter {
9861021
}
9871022
};
9881023

989-
/**
990-
* @brief We mix all input channels in a datastream. E.g. if we have stereo input data
991-
* we end up with 2 identical mono channels.
992-
* @author Phil Schatzmann
993-
* @ingroup convert
994-
* @tparam T
995-
*/
996-
template <typename T = int16_t, typename SumT = float>
997-
class ChannelMixer : public BaseConverter {
998-
public:
999-
ChannelMixer(int channels = 2) { this->channels = channels; }
1000-
size_t convert(uint8_t *data, size_t size) {
1001-
if (channels <= 1) return size; // No mixing needed for single channel
1002-
T *srcT = (T *)data;
1003-
T *targetT = (T *)data;
1004-
int samples = size / sizeof(T);
1005-
assert(samples % channels == 0);
1006-
for (int j = 0; j < samples; j += channels) {
1007-
SumT sum = 0;
1008-
for (int ch = 0; ch < channels; ch++) {
1009-
sum += srcT[j + ch];
1010-
}
1011-
T avg = sum / channels;
1012-
for (int ch = 0; ch < channels; ch++) {
1013-
targetT[j + ch] = avg;
1014-
}
1015-
}
1016-
return size;
1017-
}
1018-
1019-
protected:
1020-
int channels = 2;
1021-
};
10221024

10231025
/**
10241026
* @brief We average pairs of channels in a datastream.
@@ -1042,20 +1044,35 @@ class ChannelAvg : public BaseConverter {
10421044
size_t convert(uint8_t *src, size_t size) { return convert(src, src, size); }
10431045
size_t convert(uint8_t *target, uint8_t *src, size_t size) {
10441046
switch (bits) {
1047+
#ifdef PREFER_FIXEDPOINT
1048+
case 8: {
1049+
ChannelAvgT<int8_t, int16_t> ca8;
1050+
return ca8.convert(target, src, size);
1051+
}
1052+
case 16: {
1053+
ChannelAvgT<int16_t, int32_t> ca16;
1054+
return ca16.convert(target, src, size);
1055+
}
1056+
case 24: {
1057+
ChannelAvgT<int24_t, int32_t> ca24;
1058+
return ca24.convert(target, src, size);
1059+
}
1060+
#else
10451061
case 8: {
1046-
ChannelAvgT<int8_t> ca8;
1062+
ChannelAvgT<int8_t, float> ca8;
10471063
return ca8.convert(target, src, size);
10481064
}
10491065
case 16: {
1050-
ChannelAvgT<int16_t> ca16;
1066+
ChannelAvgT<int16_t, float> ca16;
10511067
return ca16.convert(target, src, size);
10521068
}
10531069
case 24: {
1054-
ChannelAvgT<int24_t> ca24;
1070+
ChannelAvgT<int24_t, float> ca24;
10551071
return ca24.convert(target, src, size);
10561072
}
1073+
#endif
10571074
case 32: {
1058-
ChannelAvgT<int32_t> ca32;
1075+
ChannelAvgT<int32_t, float> ca32;
10591076
return ca32.convert(target, src, size);
10601077
}
10611078
default: {

0 commit comments

Comments
 (0)