Yes, that's right. You do not have to release your source, it's not GPL license.Tale wrote:Just to make sure I am correctly understanding how this library is licensed: If I use this in a (closed-source) project, say Combo Model F, you are happy as long as I credit you (as specified in other/License.txt) in the PDF documentation, right?
Open source high-quality pro audio sample rate converter library released from Voxengo
- KVRAF
- Topic Starter
- 4021 posts since 7 Sep, 2002
- KVRian
- 519 posts since 12 Apr, 2010 from The Netherlands
Cool, thanks! Of course I would share any improvements on r8brain itself (not very likely, because I have yet to figure out how the heck it works... ).Aleksey Vaneev wrote:Yes, that's right. You do not have to release your source, it's not GPL license.
- KVRian
- 519 posts since 12 Apr, 2010 from The Netherlands
I have fetched the latest changes (thanks for the fixes!), and I have now successfully tested r8brain on:
- Windows SDK v7.0 (MSVC 2008 compiler) targetting x86
- Windows SDK v7.1 (MSVC 2010 compiler) targetting x64
- Xcode 3.2.6 targetting i386 and x86-64 (and PPC, but I can't easily test if it actually works; it compiles just fine)
- KVRAF
- Topic Starter
- 4021 posts since 7 Sep, 2002
- KVRian
- 519 posts since 12 Apr, 2010 from The Netherlands
I have found a signed/unsigned bug (at least on my compiler) in getBitOccupancy(). If I call getBitOccupancy(2147483648) it returns 24, while it should return 32. Fix:
BTW, you could replace the OccupancyTable[] with a inline function, thus saving about 1 kB static memory. There is only a very, very small performance penalty, and I think getBitOccupancy() isn't a critical function anyway, so I'd say saving 1 kB is worth it. Patch:
Code: Select all
diff --git a/r8bbase.h b/r8bbase.h
index 1130e01..0009825 100644
--- a/r8bbase.h
+++ b/r8bbase.h
@@ -764,7 +764,7 @@ inline int getBitOccupancy( const int v )
if( tt != 0 )
{
- return(( t = v >> 24 ) ? 24 + OccupancyTable[ t ] :
+ return(( t = (unsigned int) v >> 24 ) ? 24 + OccupancyTable[ t ] :
16 + OccupancyTable[ tt & 0xFF ]);
}
else
Code: Select all
diff --git a/r8bbase.h b/r8bbase.h
index 1130e01..73c4b96 100644
--- a/r8bbase.h
+++ b/r8bbase.h
@@ -737,40 +737,31 @@ private:
* specified value. Function treats the input value as unsigned.
*/
+inline int _getBitOccupancy( const int v )
+{
+ if( v & 0x80 ) return 8;
+ if( v & 0x40 ) return 7;
+ if( v & 0x20 ) return 6;
+ if( v & 0x10 ) return 5;
+ if( v & 0x08 ) return 4;
+ if( v & 0x04 ) return 3;
+ if( v & 0x02 ) return 2;
+ return 1;
+}
inline int getBitOccupancy( const int v )
{
- static const int OccupancyTable[] =
- {
- 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8
- };
-
int t, tt;
tt = v >> 16;
if( tt != 0 )
{
- return(( t = v >> 24 ) ? 24 + OccupancyTable[ t ] :
- 16 + OccupancyTable[ tt & 0xFF ]);
+ return(( t = (unsigned int) v >> 24 ) ? 24 + _getBitOccupancy( t ) :
+ 16 + _getBitOccupancy( tt & 0xFF ));
}
else
{
- return(( t = v >> 8 ) ? 8 + OccupancyTable[ t ] :
- OccupancyTable[ v ]);
+ return(( t = v >> 8 ) ? 8 + _getBitOccupancy( t ) :
+ _getBitOccupancy( v ));
}
}
- KVRAF
- Topic Starter
- 4021 posts since 7 Sep, 2002
Thanks for the getBitOccupancy() fix, but I won't replace the table, the set of "if"s is less optimal. However, "static const int" can be changed to "static const char", that's the thing I've overlooked.
The 2147483648 value does not fit into 32-bit "int" range, so this function isn't applicable. While the -2147483648 works OK. The fix is not needed.
The 2147483648 value does not fit into 32-bit "int" range, so this function isn't applicable. While the -2147483648 works OK. The fix is not needed.
Last edited by Aleksey Vaneev on Sat Aug 24, 2013 11:09 am, edited 1 time in total.
- KVRian
- 519 posts since 12 Apr, 2010 from The Netherlands
Fair enough.Aleksey Vaneev wrote:Thanks for the getBitOccupancy() fix, but I won't replace the table, the set of "if"s is less optimal. However, "static const int" can be changed to "static const char", that's the thing I've overlooked.
- KVRian
- 519 posts since 12 Apr, 2010 from The Netherlands
I have been playing with r8brain-free-src some more, comparing it with my current linear interpolation resampling method, and the resampler in Cockos WDL. On average r8brain (with ReqTransBand=3 and ReqAtten=70) is ~19x slower than linear interpolation, and WDL's resampler (using defaults, which I think corresponds with REAPER's "Good" 64pt sinc mode) is ~14x slower. However, for the special case where I upsample 44.1 to 88.2 kHz (where r8brain uses its "power of 2" upsampling), r8brain is twice as fast as WDL's resampler. Note that I am not using IPP.
Also note that I am kinda comparing apples and oranges, as I haven't looked at the quality (I am resampling IRs, where quality seems less of an issue). Obviously both resamplers are better than my current linear interpolation method, but I guess r8brain (even with ReqAtten=70) is probably also better than WDL's resampler using defaults.
Also note that I am kinda comparing apples and oranges, as I haven't looked at the quality (I am resampling IRs, where quality seems less of an issue). Obviously both resamplers are better than my current linear interpolation method, but I guess r8brain (even with ReqAtten=70) is probably also better than WDL's resampler using defaults.
Reminder: I have just updated to the latest revision (r34), but the getBitOccupancy() bug is still there. BTW, the bug also manifests itself when using GCC.Aleksey Vaneev wrote:Thanks for the getBitOccupancy() fix
- KVRAF
- Topic Starter
- 4021 posts since 7 Sep, 2002
As I've replied earlier, 2147483648 does NOT fit into 32-bit "int" range. Your test was flawed.
I'm currently working on a better windowing function, and I think the number of taps can be reduced further down to 34 or 32 samples, that way it will be 10-15% faster.
With r8brain-free-src we are talking about constantly *excellent* quality, there is simply no much room for improvement left.
For a fair comparison you may also decrease ReqTransBand and increase ReqAtten if necessary - this won't make r8brain-free-src much slower.
I'm currently working on a better windowing function, and I think the number of taps can be reduced further down to 34 or 32 samples, that way it will be 10-15% faster.
With r8brain-free-src we are talking about constantly *excellent* quality, there is simply no much room for improvement left.
For a fair comparison you may also decrease ReqTransBand and increase ReqAtten if necessary - this won't make r8brain-free-src much slower.
Last edited by Aleksey Vaneev on Sun Aug 25, 2013 1:46 pm, edited 1 time in total.
-
AdmiralQuality AdmiralQuality https://www.kvraudio.com/forum/memberlist.php?mode=viewprofile&u=83902
- Banned
- 6657 posts since 10 Oct, 2005 from Toronto, Canada
Continuously variable rate?Aleksey Vaneev wrote:there is simply no much room for improvement left.
- KVRAF
- Topic Starter
- 4021 posts since 7 Sep, 2002
This was already done in the CDSPFracInterpolator class, except that low-pass filtering is non-dynamic. If you have a dynamic low-pass filter (with 2X oversampling) implementation, you can use that class for variable rate interpolation.AdmiralQuality wrote:Continuously variable rate?Aleksey Vaneev wrote:there is simply no much room for improvement left.
-
AdmiralQuality AdmiralQuality https://www.kvraudio.com/forum/memberlist.php?mode=viewprofile&u=83902
- Banned
- 6657 posts since 10 Oct, 2005 from Toronto, Canada
Oh? Sorry, I saw your earlier post saying this wasn't really suitable for continuous rate. Will check it out now if it is. Thanks!Aleksey Vaneev wrote:This was already done in the CDSPFracInterpolator class, except that low-pass filtering is non-dynamic. If you have a dynamic low-pass filter (with 2X oversampling) implementation, you can use that class for variable rate interpolation.AdmiralQuality wrote:Continuously variable rate?Aleksey Vaneev wrote:there is simply no much room for improvement left.
- KVRAF
- Topic Starter
- 4021 posts since 7 Sep, 2002
Well, you can continously change the rate in the current implementation, but it isn't smooth as, for example, usual chorus implementations that use an oscillator for stepping.AdmiralQuality wrote:Oh? Sorry, I saw your earlier post saying this wasn't really suitable for continuous rate. Will check it out now if it is. Thanks!
So, I will probably take CDSPFracInterpolator to the next step in the future: a fully continuous rate change, driven by an oscillator. Plus the input data can be supplied as a list of data blocks, with forward or backward reading (should be great for ping-pong and usual looping). The output length can be also limited. This way it will be really easy to put this interpolator into a soft-synth.
Last edited by Aleksey Vaneev on Sun Aug 25, 2013 2:01 pm, edited 1 time in total.
-
AdmiralQuality AdmiralQuality https://www.kvraudio.com/forum/memberlist.php?mode=viewprofile&u=83902
- Banned
- 6657 posts since 10 Oct, 2005 from Toronto, Canada
Oh. That would be what I'd want it for. Delay/chorus/flanger type stuff.Aleksey Vaneev wrote:Well, you can continously change the rate in the current implementation, but it isn't smooth as, for example, usual chorus implementations that use an oscillator for stepping.AdmiralQuality wrote:Oh? Sorry, I saw your earlier post saying this wasn't really suitable for continuous rate. Will check it out now if it is. Thanks!
And effects!
So, I will probably take CDSPFracInterpolator to the next step in the future: a fully continuous rate change, driven by an oscillator. Plus the input data can be supplied as a list of data blocks, with forward or backward reading. The output length can be also limited. This way it will be really easy to put this interpolator into a soft-synths.
- KVRian
- 519 posts since 12 Apr, 2010 from The Netherlands
Sorry, I seem to have missed your earlier reply. My confusion came from the "function treats the input value as unsigned", but you are absolutely right. Thanks for explaining (twice).Aleksey Vaneev wrote:As I've replied earlier, 2147483648 does NOT fit into 32-bit "int" range. Your test was flawed.