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

  • From: pulkomandy@xxxxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sat, 16 Jul 2011 11:15:21 +0200 (CEST)

Author: pulkomandy
Date: 2011-07-16 11:15:21 +0200 (Sat, 16 Jul 2011)
New Revision: 42435
Changeset: https://dev.haiku-os.org/changeset/42435
Ticket: https://dev.haiku-os.org/ticket/1351

Modified:
   haiku/trunk/src/add-ons/media/media-add-ons/mixer/Interpolate.cpp
Log:
fix bugs in interpolating resampler :
 * I got the downsampling version completely wrong. It should now be much 
better.
 * A small bug in the delta calculation sometimes caused an off-by-one read to 
the source and a crash of the media add-on server

Effect of this resampler can be heard very clearly using the following setup in 
Cortex :
 * Demo Audio producer producing a sinewave at any frequency (sampling rate is 
hardcoded at 44100Hz)
 * Audio output set to 48000 Hz
 * system mixer in between
select either resampler in the mixer and you'll hear the difference immediately.

Should finally fix #1351.


Modified: haiku/trunk/src/add-ons/media/media-add-ons/mixer/Interpolate.cpp
===================================================================
--- haiku/trunk/src/add-ons/media/media-add-ons/mixer/Interpolate.cpp   
2011-07-16 03:01:21 UTC (rev 42434)
+++ haiku/trunk/src/add-ons/media/media-add-ons/mixer/Interpolate.cpp   
2011-07-16 09:15:21 UTC (rev 42435)
@@ -44,33 +44,20 @@
                return;
        }
 
-       register float delta = float(srcSampleCount) / float(destSampleCount);
+       register float delta = float(srcSampleCount - 1) / 
float(destSampleCount - 1);
        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;
-                       }
+       while (count--) {
+               *(float*)dest = gain * (SRC(0) + (SRC(1) - SRC(0)) * current) ;
+               dest += destSampleOffset;
+               current += delta;
+               if (current >= 1.0f) {
+                       double ipart;
+                       current = modf(current, &ipart);
+                       src += srcSampleOffset * (int)ipart;
                }
-       } else {
-               // downsample
-               while (count--) {
-                       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;
-               }
        }
 }
 
@@ -95,34 +82,21 @@
                return;
        }
 
-       register float delta = float(srcSampleCount) / float(destSampleCount);
+       register float delta = float(srcSampleCount - 1) / 
float(destSampleCount - 1);
        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;
-                       }
+       while (count--) {
+               *(float*)dest = gain * (SRC(0) + (SRC(1) - SRC(0)) * current) ;
+               dest += destSampleOffset;
+               current += delta;
+               if (current >= 1.0f) {
+                       double ipart;
+                       current = modf(current, &ipart);
+                       src += srcSampleOffset * (int)ipart;
                }
-       } else {
-               // downsample
-               while (count--) {
-                       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;
-               }
        }
 }
 
@@ -147,34 +121,21 @@
                return;
        }
 
-       register float delta = float(srcSampleCount) / float(destSampleCount);
+       register float delta = float(srcSampleCount - 1) / 
float(destSampleCount - 1);
        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;
-                       }
+       while (count--) {
+               *(float*)dest = gain * (SRC(0) + (SRC(1) - SRC(0)) * current);
+               dest += destSampleOffset;
+               current += delta;
+               if (current >= 1.0f) {
+                       double ipart;
+                       current = modf(current, &ipart);
+                       src += srcSampleOffset * (int)ipart;
                }
-       } else {
-               // downsample
-               while (count--) {
-                       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;
-               }
        }
 }
 
@@ -199,34 +160,21 @@
                return;
        }
 
-       register float delta = float(srcSampleCount) / float(destSampleCount);
+       register float delta = float(srcSampleCount - 1) / 
float(destSampleCount - 1);
        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;
-                       }
+       while (count--) {
+               *(float*)dest = gain * (SRC(0) + (SRC(1) - SRC(0)) * current) ;
+               dest += destSampleOffset;
+               current += delta;
+               if (current >= 1.0f) {
+                       double ipart;
+                       current = modf(current, &ipart);
+                       src += srcSampleOffset * (int)ipart;
                }
-       } else {
-               // downsample
-               while (count--) {
-                       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;
-               }
        }
 }
 
@@ -251,34 +199,21 @@
                return;
        }
 
-       register float delta = float(srcSampleCount) / float(destSampleCount);
+       register float delta = float(srcSampleCount - 1) / 
float(destSampleCount - 1);
        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;
-                       }
+       while (count--) {
+               *(float*)dest = gain * (SRC(0) + (SRC(1) - SRC(0)) * current);
+               dest += destSampleOffset;
+               current += delta;
+               if (current >= 1.0f) {
+                       double ipart;
+                       current = modf(current, &ipart);
+                       src += srcSampleOffset * (int)ipart;
                }
-       } else {
-               // downsample
-               while (count--) {
-                       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;
-               }
        }
 }
 
@@ -309,47 +244,28 @@
                return;
        }
 
-       register float delta = float(srcSampleCount) / float(destSampleCount);
+       register float delta = float(srcSampleCount - 1) / 
float(destSampleCount - 1);
        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;
-                       }
+       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) {
+                       double ipart;
+                       current = modf(current, &ipart);
+                       src += srcSampleOffset * (int)ipart;
                }
-       } else {
-               // downsample
-               while (count--) {
-                       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;
-               }
        }
 }
 
@@ -380,44 +296,25 @@
                return;
        }
 
-       register float delta = float(srcSampleCount) / float(destSampleCount);
+       register float delta = float(srcSampleCount - 1) / 
float(destSampleCount - 1);
        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;
-                       }
+       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) {
+                       double ipart;
+                       current = modf(current, &ipart);
+                       src += srcSampleOffset * (int)ipart;
                }
-       } else {
-               // downsample
-               while (count--) {
-                       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;
-               }
        }
 }
 
@@ -448,44 +345,25 @@
                return;
        }
 
-       register float delta = float(srcSampleCount) / float(destSampleCount);
+       register float delta = float(srcSampleCount - 1) / 
float(destSampleCount - 1);
        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;
-                       }
+       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) {
+                       double ipart;
+                       current = modf(current, &ipart);
+                       src += srcSampleOffset * (int)ipart;
                }
-       } else {
-               // downsample
-               while (count--) {
-                       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;
-               }
        }
 }
 
@@ -516,44 +394,25 @@
                return;
        }
 
-       register float delta = float(srcSampleCount) / float(destSampleCount);
+       register float delta = float(srcSampleCount - 1) / 
float(destSampleCount - 1);
        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;
-                       }
+       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) {
+                       double ipart;
+                       current = modf(current, &ipart);
+                       src += srcSampleOffset * (int)ipart;
                }
-       } else {
-               // downsample
-               while (count--) {
-                       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;
-               }
        }
 }
 


Other related posts:

  • » [haiku-commits] r42435 - haiku/trunk/src/add-ons/media/media-add-ons/mixer - pulkomandy