[haiku-commits] r38037 - haiku/trunk/src/add-ons/media/media-add-ons/mixer

  • From: pulkomandy@xxxxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Thu, 12 Aug 2010 12:18:38 +0200 (CEST)

Author: pulkomandy
Date: 2010-08-12 12:18:38 +0200 (Thu, 12 Aug 2010)
New Revision: 38037
Changeset: http://dev.haiku-os.org/changeset/38037

Added:
   haiku/trunk/src/add-ons/media/media-add-ons/mixer/Interpolate.cpp
   haiku/trunk/src/add-ons/media/media-add-ons/mixer/Interpolate.h
Modified:
   haiku/trunk/src/add-ons/media/media-add-ons/mixer/Jamfile
   haiku/trunk/src/add-ons/media/media-add-ons/mixer/MixerCore.cpp
   haiku/trunk/src/add-ons/media/media-add-ons/mixer/MixerInput.cpp
Log:
 * Add a resampler that interpolates instead of dropping/copying samples.
 * Not plugged anywhere yet.
 * I'm not sure the downsampling is done properly, either.


Added: haiku/trunk/src/add-ons/media/media-add-ons/mixer/Interpolate.cpp
===================================================================
--- haiku/trunk/src/add-ons/media/media-add-ons/mixer/Interpolate.cpp           
                (rev 0)
+++ haiku/trunk/src/add-ons/media/media-add-ons/mixer/Interpolate.cpp   
2010-08-12 10:18:38 UTC (rev 38037)
@@ -0,0 +1,559 @@
+/*
+ * Copyright 2010 Adrien Destugues <pulkomandy@xxxxxxxxxxxxxxxxx>
+ * Distributed under the terms of the MIT Licence.
+ */
+
+
+#include "Interpolate.h"
+
+#include <cmath>
+
+
+/*! Resampling class doing linear interpolation.
+*/
+
+
+Interpolate::Interpolate(uint32 src_format, uint32 dst_format)
+       :
+       Resampler(src_format, dst_format)
+{
+}
+
+Interpolate::~Interpolate()
+{
+}
+
+
+void
+Interpolate::float_to_float(const void *_src, int32 srcSampleOffset,
+       int32 srcSampleCount, void *_dest, int32 destSampleOffset,
+       int32 destSampleCount, float _gain)
+{
+       register const char * src = (const char *)_src;
+       register char * dest = (char *)_dest;
+       register int32 count = destSampleCount;
+       register float gain = _gain;
+
+       if (srcSampleCount == destSampleCount) {
+               // optimized case for no resampling
+               while (count--) {
+                       *(float *)dest = *(const float *)src * gain;
+                       src += srcSampleOffset;
+                       dest += destSampleOffset;
+               }
+               return;
+       }
+
+       register float delta = float(srcSampleCount) / float(destSampleCount);
+       register float current = 0.0f;
+
+       #define SRC(n) *(const float*)(src + n * srcSampleOffset)
+
+       if (delta < 1.0) {
+               // upsample
+               while (count--) {
+                       *(float*)dest = gain * (SRC(0) + (SRC(1) - SRC(0)) * 
current) ;
+                       dest += destSampleOffset;
+                       current += delta;
+                       if (current >= 1.0f) {
+                               current -= 1.0f;
+                               src += srcSampleOffset;
+                       }
+               }
+       } else {
+               // downsample
+               while (count--) {
+                       register double skipcount;
+                       register float offset = modf(current, &skipcount);
+                       *(float*)dest = gain
+                               * (SRC(0) + (SRC((int)skipcount) - SRC(0)) * 
offset);
+                       dest += destSampleOffset;
+                       current += delta - skipcount;
+                       src += (int)skipcount * srcSampleOffset;
+               }
+       }
+}
+
+
+void
+Interpolate::int32_to_float(const void *_src, int32 srcSampleOffset,
+       int32 srcSampleCount, void *_dest, int32 destSampleOffset,
+       int32 destSampleCount, float _gain)
+{
+       register const char * src = (const char *)_src;
+       register char * dest = (char *)_dest;
+       register int32 count = destSampleCount;
+       register float gain = _gain / 2147483647.0;
+
+       if (srcSampleCount == destSampleCount) {
+               // optimized case for no resampling
+               while (count--) {
+                       *(float *)dest = *(const int32 *)src * gain;
+                       src += srcSampleOffset;
+                       dest += destSampleOffset;
+               }
+               return;
+       }
+
+       register float delta = float(srcSampleCount) / float(destSampleCount);
+       register float current = 0.0f;
+
+       #undef SRC
+       #define SRC(n) *(const int32*)(src + n * srcSampleOffset)
+
+       if (delta < 1.0) {
+               // upsample
+               while (count--) {
+                       *(float*)dest = gain * (SRC(0) + (SRC(1) - SRC(0)) * 
current) ;
+                       dest += destSampleOffset;
+                       current += delta;
+                       if (current >= 1.0f) {
+                               current -= 1.0f;
+                               src += srcSampleOffset;
+                       }
+               }
+       } else {
+               // downsample
+               while (count--) {
+                       register double skipcount;
+                       register float offset = modf(current, &skipcount);
+                       *(float*)dest = gain * (SRC(0) + (SRC((int)skipcount) - 
SRC(0))
+                               * offset);
+                       dest += destSampleOffset;
+                       current += delta - skipcount;
+                       src += (int)skipcount * srcSampleOffset;
+               }
+       }
+}
+
+
+void
+Interpolate::int16_to_float(const void *_src, int32 srcSampleOffset,
+       int32 srcSampleCount, void *_dest, int32 destSampleOffset,
+       int32 destSampleCount, float _gain)
+{
+       register const char * src = (const char *)_src;
+       register char * dest = (char *)_dest;
+       register int32 count = destSampleCount;
+       register float gain = _gain / 32767.0;
+
+       if (srcSampleCount == destSampleCount) {
+               // optimized case for no resampling
+               while (count--) {
+                       *(float *)dest = *(const int16 *)src * gain;
+                       src += srcSampleOffset;
+                       dest += destSampleOffset;
+               }
+               return;
+       }
+
+       register float delta = float(srcSampleCount) / float(destSampleCount);
+       register float current = 0.0f;
+
+       #undef SRC
+       #define SRC(n) *(const int16*)(src + n * srcSampleOffset)
+
+       if (delta < 1.0) {
+               // upsample
+               while (count--) {
+                       *(float*)dest = gain * (SRC(0) + (SRC(1) - SRC(0)) * 
current);
+                       dest += destSampleOffset;
+                       current += delta;
+                       if (current >= 1.0f) {
+                               current -= 1.0f;
+                               src += srcSampleOffset;
+                       }
+               }
+       } else {
+               // downsample
+               while (count--) {
+                       register double skipcount;
+                       register float offset = modf(current, &skipcount);
+                       *(float*)dest = gain * (SRC(0) + (SRC((int)skipcount) - 
SRC(0))
+                               * offset);
+                       dest += destSampleOffset;
+                       current += delta - skipcount;
+                       src += (int)skipcount * srcSampleOffset;
+               }
+       }
+}
+
+
+void
+Interpolate::int8_to_float(const void *_src, int32 srcSampleOffset,
+       int32 srcSampleCount, void *_dest, int32 destSampleOffset,
+       int32 destSampleCount, float _gain)
+{
+       register const char * src = (const char *)_src;
+       register char * dest = (char *)_dest;
+       register int32 count = destSampleCount;
+       register float gain = _gain / 127.0;
+
+       if (srcSampleCount == destSampleCount) {
+               // optimized case for no resampling
+               while (count--) {
+                       *(float *)dest = *(const int8 *)src * gain;
+                       src += srcSampleOffset;
+                       dest += destSampleOffset;
+               }
+               return;
+       }
+
+       register float delta = float(srcSampleCount) / float(destSampleCount);
+       register float current = 0.0f;
+
+       #undef SRC
+       #define SRC(n) *(const int8*)(src + n * srcSampleOffset)
+
+       if (delta < 1.0) {
+               // upsample
+               while (count--) {
+                       *(float*)dest = gain * (SRC(0) + (SRC(1) - SRC(0)) * 
current) ;
+                       dest += destSampleOffset;
+                       current += delta;
+                       if (current >= 1.0f) {
+                               current -= 1.0f;
+                               src += srcSampleOffset;
+                       }
+               }
+       } else {
+               // downsample
+               while (count--) {
+                       register double skipcount;
+                       register float offset = modf(current, &skipcount);
+                       *(float*)dest = gain * (SRC(0) + (SRC((int)skipcount) - 
SRC(0))
+                               * offset);
+                       dest += destSampleOffset;
+                       current += delta - skipcount;
+                       src += (int)skipcount * srcSampleOffset;
+               }
+       }
+}
+
+
+void
+Interpolate::uint8_to_float(const void *_src, int32 srcSampleOffset,
+       int32 srcSampleCount, void *_dest, int32 destSampleOffset,
+       int32 destSampleCount, float _gain)
+{
+       register const char * src = (const char *)_src;
+       register char * dest = (char *)_dest;
+       register int32 count = destSampleCount;
+       register float gain = _gain / 127.0;
+
+       if (srcSampleCount == destSampleCount) {
+               // optimized case for no resampling
+               while (count--) {
+                       *(float *)dest = (((int32) *(const uint8 *)src) - 128) 
* gain;
+                       src += srcSampleOffset;
+                       dest += destSampleOffset;
+               }
+               return;
+       }
+
+       register float delta = float(srcSampleCount) / float(destSampleCount);
+       register float current = 0.0f;
+
+       #undef SRC
+       #define SRC(n) ( *(const uint8*)(src + n * srcSampleOffset) - 128)
+
+       if (delta < 1.0) {
+               // upsample
+               while (count--) {
+                       *(float*)dest = gain * (SRC(0) + (SRC(1) - SRC(0)) * 
current);
+                       dest += destSampleOffset;
+                       current += delta;
+                       if (current >= 1.0f) {
+                               current -= 1.0f;
+                               src += srcSampleOffset;
+                       }
+               }
+       } else {
+               // downsample
+               while (count--) {
+                       register double skipcount;
+                       register float offset = modf(current, &skipcount);
+                       *(float*)dest = gain * (SRC(0) + (SRC((int)skipcount) - 
SRC(0))
+                               * offset);
+                       dest += destSampleOffset;
+                       current += delta - skipcount;
+                       src += (int)skipcount * srcSampleOffset;
+               }
+       }
+}
+
+
+void
+Interpolate::float_to_int32(const void *_src, int32 srcSampleOffset,
+       int32 srcSampleCount, void *_dest, int32 destSampleOffset,
+       int32 destSampleCount, float _gain)
+{
+       register const char * src = (const char *)_src;
+       register char * dest = (char *)_dest;
+       register int32 count = destSampleCount;
+       register float gain = _gain * 2147483647.0;
+
+       if (srcSampleCount == destSampleCount) {
+               // optimized case for no resampling
+               while (count--) {
+                       register float sample = *(const float *)src * gain;
+                       if (sample > 2147483647.0f)
+                               *(int32 *)dest = 2147483647L;
+                       else if (sample < -2147483647.0f)
+                               *(int32 *)dest = -2147483647L;
+                       else
+                               *(int32 *)dest = (int32)sample;
+                       src += srcSampleOffset;
+                       dest += destSampleOffset;
+               }
+               return;
+       }
+
+       register float delta = float(srcSampleCount) / float(destSampleCount);
+       register float current = 0.0f;
+
+       #undef SRC
+       #define SRC(n) *(const float*)(src + n * srcSampleOffset)
+
+       if (delta < 1.0) {
+               // upsample
+               while (count--) {
+                       register float sample = gain * (SRC(0) + (SRC(1) - 
SRC(0))
+                               * current);
+                       if (sample > 2147483647.0f)
+                               *(int32 *)dest = 2147483647L;
+                       else if (sample < -2147483647.0f)
+                               *(int32 *)dest = -2147483647L;
+                       else
+                               *(int32 *)dest = (int32)sample;
+                       dest += destSampleOffset;
+                       current += delta;
+                       if (current >= 1.0f) {
+                               current -= 1.0f;
+                               src += srcSampleOffset;
+                       }
+               }
+       } else {
+               // downsample
+               while (count--) {
+                       register double skipcount;
+                       register float offset = modf(current, &skipcount);
+                       register float sample = gain * (SRC(0) + 
(SRC((int)skipcount)
+                               - SRC(0)) * offset);
+                       if (sample > 2147483647.0f)
+                               *(int32 *)dest = 2147483647L;
+                       else if (sample < -2147483647.0f)
+                               *(int32 *)dest = -2147483647L;
+                       else
+                               *(int32 *)dest = (int32)sample;
+                       dest += destSampleOffset;
+                       current += delta - skipcount;
+                       src += (int)skipcount * srcSampleOffset;
+               }
+       }
+}
+
+
+void
+Interpolate::float_to_int16(const void *_src, int32 srcSampleOffset,
+       int32 srcSampleCount, void *_dest, int32 destSampleOffset,
+       int32 destSampleCount, float _gain)
+{
+       register const char * src = (const char *)_src;
+       register char * dest = (char *)_dest;
+       register int32 count = destSampleCount;
+       register float gain = _gain * 32767.0;
+
+       if (srcSampleCount == destSampleCount) {
+               // optimized case for no resampling
+               while (count--) {
+                       register float sample = *(const float *)src * gain;
+                       if (sample > 32767.0f)
+                               *(int16 *)dest = 32767;
+                       else if (sample < -32767.0f)
+                               *(int16 *)dest = -32767;
+                       else
+                               *(int16 *)dest = (int16)sample;
+                       src += srcSampleOffset;
+                       dest += destSampleOffset;
+               }
+               return;
+       }
+
+       register float delta = float(srcSampleCount) / float(destSampleCount);
+       register float current = 0.0f;
+
+       if (delta < 1.0) {
+               // upsample
+               while (count--) {
+                       register float sample = gain * (SRC(0) + (SRC(1) - 
SRC(0))
+                               * current);
+                       if (sample > 32767.0f)
+                               *(int16 *)dest = 32767;
+                       else if (sample < -32767.0f)
+                               *(int16 *)dest = -32767;
+                       else
+                               *(int16 *)dest = (int16)sample;
+                       dest += destSampleOffset;
+                       current += delta;
+                       if (current >= 1.0f) {
+                               current -= 1.0f;
+                               src += srcSampleOffset;
+                       }
+               }
+       } else {
+               // downsample
+               while (count--) {
+                       register double skipcount;
+                       register float offset = modf(current, &skipcount);
+                       register float sample = gain * (SRC(0) + 
(SRC((int)skipcount)
+                               - SRC(0)) * offset);
+                       if (sample > 32767.0f)
+                               *(int16 *)dest = 32767;
+                       else if (sample < -32767.0f)
+                               *(int16 *)dest = -32767;
+                       else
+                               *(int16 *)dest = (int16)sample;
+                       dest += destSampleOffset;
+                       current += delta - skipcount;
+                       src += (int)skipcount * srcSampleOffset;
+               }
+       }
+}
+
+
+void
+Interpolate::float_to_int8(const void *_src, int32 srcSampleOffset,
+       int32 srcSampleCount, void *_dest, int32 destSampleOffset,
+       int32 destSampleCount, float _gain)
+{
+       register const char * src = (const char *)_src;
+       register char * dest = (char *)_dest;
+       register int32 count = destSampleCount;
+       register float gain = _gain * 127.0;
+
+       if (srcSampleCount == destSampleCount) {
+               // optimized case for no resampling
+               while (count--) {
+                       register float sample = *(const float *)src * gain;
+                       if (sample > 127.0f)
+                               *(int8 *)dest = 127;
+                       else if (sample < -127.0f)
+                               *(int8 *)dest = -127;
+                       else
+                               *(int8 *)dest = (int8)sample;
+                       src += srcSampleOffset;
+                       dest += destSampleOffset;
+               }
+               return;
+       }
+
+       register float delta = float(srcSampleCount) / float(destSampleCount);
+       register float current = 0.0f;
+
+       if (delta < 1.0) {
+               // upsample
+               while (count--) {
+                       register float sample = gain * (SRC(0) + (SRC(1) - 
SRC(0))
+                               * current);
+                       if (sample > 127.0f)
+                               *(int8 *)dest = 127;
+                       else if (sample < -127.0f)
+                               *(int8 *)dest = -127;
+                       else
+                               *(int8 *)dest = (int8)sample;
+                       dest += destSampleOffset;
+                       current += delta;
+                       if (current >= 1.0f) {
+                               current -= 1.0f;
+                               src += srcSampleOffset;
+                       }
+               }
+       } else {
+               // downsample
+               while (count--) {
+                       register double skipcount;
+                       register float offset = modf(current, &skipcount);
+                       register float sample = gain * (SRC(0) + 
(SRC((int)skipcount)
+                               - SRC(0)) * offset);
+                       if (sample > 127.0f)
+                               *(int8 *)dest = 127;
+                       else if (sample < -127.0f)
+                               *(int8 *)dest = -127;
+                       else
+                               *(int8 *)dest = (int8)sample;
+                       dest += destSampleOffset;
+                       current += delta - skipcount;
+                       src += (int)skipcount * srcSampleOffset;
+               }
+       }
+}
+
+
+void
+Interpolate::float_to_uint8(const void *_src, int32 srcSampleOffset,
+       int32 srcSampleCount, void *_dest, int32 destSampleOffset,
+       int32 destSampleCount, float _gain)
+{
+       register const char * src = (const char *)_src;
+       register char * dest = (char *)_dest;
+       register int32 count = destSampleCount;
+       register float gain = _gain * 127.0;
+
+       if (srcSampleCount == destSampleCount) {
+               // optimized case for no resampling
+               while (count--) {
+                       register float sample = 128.0f + *(const float *)src * 
gain;
+                       if (sample > 255.0f)
+                               *(uint8 *)dest = 255;
+                       else if (sample < 1.0f)
+                               *(uint8 *)dest = 1;
+                       else
+                               *(uint8 *)dest = (uint8)sample;
+                       src += srcSampleOffset;
+                       dest += destSampleOffset;
+               }
+               return;
+       }
+
+       register float delta = float(srcSampleCount) / float(destSampleCount);
+       register float current = 0.0f;
+
+       if (delta < 1.0) {
+               // upsample
+               while (count--) {
+                       register float sample = gain * (SRC(0) + (SRC(1) - 
SRC(0))
+                               * current);
+                       if (sample > 255.0f)
+                               *(uint8 *)dest = 255;
+                       else if (sample < 1.0f)
+                               *(uint8 *)dest = 1;
+                       else
+                               *(uint8 *)dest = (uint8)sample;
+                       dest += destSampleOffset;
+                       current += delta;
+                       if (current >= 1.0f) {
+                               current -= 1.0f;
+                               src += srcSampleOffset;
+                       }
+               }
+       } else {
+               // downsample
+               while (count--) {
+                       register double skipcount;
+                       register float offset = modf(current, &skipcount);
+                       register float sample = gain * (SRC(0) + 
(SRC((int)skipcount)
+                               - SRC(0)) * offset) + 128.0f;
+                       if (sample > 255.0f)
+                               *(uint8 *)dest = 255;
+                       else if (sample < 1.0f)
+                               *(uint8 *)dest = 1;
+                       else
+                               *(uint8 *)dest = (uint8)sample;
+                       dest += destSampleOffset;
+                       current += delta - skipcount;
+                       src += (int)skipcount * srcSampleOffset;
+               }
+       }
+}
+

Added: haiku/trunk/src/add-ons/media/media-add-ons/mixer/Interpolate.h
===================================================================
--- haiku/trunk/src/add-ons/media/media-add-ons/mixer/Interpolate.h             
                (rev 0)
+++ haiku/trunk/src/add-ons/media/media-add-ons/mixer/Interpolate.h     
2010-08-12 10:18:38 UTC (rev 38037)
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2010, Adrien Destugues <pulkomandy@xxxxxxxxxxxxxxxxx>
+ * Distributed under the terms of the MIT Licence.
+ */
+#ifndef _INTERPOLATE_H
+#define _INTERPOLATE_H
+
+
+#include "Resampler.h"
+
+
+class Interpolate: public Resampler {
+public:
+                                                       Interpolate(uint32 
sourceFormat,
+                                                               uint32 
destFormat);
+       virtual                                 ~Interpolate();
+private:
+       virtual void                            float_to_float(const void* src,
+                                                                       int32 
srcSampleOffset, int32 srcSampleCount,
+                                                                       void* 
dest, int32 destSampleOffset,
+                                                                       int32 
destSampleCount, float gain);
+       virtual void                            int32_to_float(const void* src,
+                                                                       int32 
srcSampleOffset, int32 srcSampleCount,
+                                                                       void* 
dest, int32 destSampleOffset,
+                                                                       int32 
destSampleCount, float gain);
+       virtual void                            int16_to_float(const void* src,
+                                                                       int32 
srcSampleOffset, int32 srcSampleCount,
+                                                                       void* 
dest, int32 destSampleOffset,
+                                                                       int32 
destSampleCount, float gain);
+       virtual void                            int8_to_float(const void* src,
+                                                                       int32 
srcSampleOffset, int32 srcSampleCount,
+                                                                       void* 
dest, int32 destSampleOffset,
+                                                                       int32 
destSampleCount, float gain);
+       virtual void                            uint8_to_float(const void* src,
+                                                                       int32 
srcSampleOffset, int32 srcSampleCount,
+                                                                       void* 
dest, int32 destSampleOffset,
+                                                                       int32 
destSampleCount, float gain);
+       virtual void                            float_to_int32(const void* src,
+                                                                       int32 
srcSampleOffset, int32 srcSampleCount,
+                                                                       void* 
dest, int32 destSampleOffset,
+                                                                       int32 
destSampleCount, float gain);
+       virtual void                            float_to_int16(const void* src,
+                                                                       int32 
srcSampleOffset, int32 srcSampleCount,
+                                                                       void* 
dest, int32 destSampleOffset,
+                                                                       int32 
destSampleCount, float gain);
+       virtual void                            float_to_int8(const void* src,
+                                                                       int32 
srcSampleOffset, int32 srcSampleCount,
+                                                                       void* 
dest, int32 destSampleOffset,
+                                                                       int32 
destSampleCount, float gain);
+       virtual void                            float_to_uint8(const void* src,
+                                                                       int32 
srcSampleOffset, int32 srcSampleCount,
+                                                                       void* 
dest, int32 destSampleOffset,
+                                                                       int32 
destSampleCount, float gain);
+
+};
+
+
+#endif

Modified: haiku/trunk/src/add-ons/media/media-add-ons/mixer/Jamfile
===================================================================
--- haiku/trunk/src/add-ons/media/media-add-ons/mixer/Jamfile   2010-08-12 
08:01:05 UTC (rev 38036)
+++ haiku/trunk/src/add-ons/media/media-add-ons/mixer/Jamfile   2010-08-12 
10:18:38 UTC (rev 38037)
@@ -5,6 +5,7 @@
 Addon mixer.media_addon :
        AudioMixer.cpp
        ByteSwap.cpp
+       Interpolate.cpp
        MixerAddOn.cpp
        MixerCore.cpp
        MixerInput.cpp

Modified: haiku/trunk/src/add-ons/media/media-add-ons/mixer/MixerCore.cpp
===================================================================
--- haiku/trunk/src/add-ons/media/media-add-ons/mixer/MixerCore.cpp     
2010-08-12 08:01:05 UTC (rev 38036)
+++ haiku/trunk/src/add-ons/media/media-add-ons/mixer/MixerCore.cpp     
2010-08-12 10:18:38 UTC (rev 38037)
@@ -296,6 +296,7 @@
 
        fResampler = new Resampler * [fMixBufferChannelCount];
        for (int i = 0; i < fMixBufferChannelCount; i++) {
+               // TODO create Interpolate instead of Resampler if the settings 
say so
                fResampler[i] = new 
Resampler(media_raw_audio_format::B_AUDIO_FLOAT,
                        format.format);
        }

Modified: haiku/trunk/src/add-ons/media/media-add-ons/mixer/MixerInput.cpp
===================================================================
--- haiku/trunk/src/add-ons/media/media-add-ons/mixer/MixerInput.cpp    
2010-08-12 08:01:05 UTC (rev 38036)
+++ haiku/trunk/src/add-ons/media/media-add-ons/mixer/MixerInput.cpp    
2010-08-12 10:18:38 UTC (rev 38037)
@@ -76,6 +76,7 @@
        // create resamplers
        fResampler = new Resampler * [fInputChannelCount];
        for (int i = 0; i < fInputChannelCount; i++)
+               // TODO create Interpolate instead of Resampler if the settings 
says so
                fResampler[i] = new Resampler(fInput.format.u.raw_audio.format, 
media_raw_audio_format::B_AUDIO_FLOAT);
 
        // fMixerChannelInfo and fMixerChannelCount will be initialized by 
UpdateInputChannelDestinations()


Other related posts: