Open source high-quality pro audio sample rate converter library released from Voxengo
- KVRAF
- Topic Starter
- 4021 posts since 7 Sep, 2002
I've just checked the "power of 2" downsampling - it is only marginally more efficient at the last step than fractional delay interpolation. Interpolator uses just 40 taps, that's why it can hardly be beaten by the "power of 2" resampling.
Can't tell about "power of 2" upsampling yet, but I think it won't be much different.
Can't tell about "power of 2" upsampling yet, but I think it won't be much different.
Last edited by Aleksey Vaneev on Wed Aug 21, 2013 4:01 pm, edited 2 times in total.
- KVRAF
- Topic Starter
- 4021 posts since 7 Sep, 2002
If you look at http://src.infinitewave.ca/ , Secret rabbit code is not that good, its "high dynamic range" applies to the upper part of the spectrum only.
r8brain-free-src achieves 260 dB SNR when resampling a sine-wave signal. But only 170 dB SNR when resampling white-noise signal (probably due to a simultaneous intermix of large and low-amplitude signals in the noise). It's a quirky thing - to benchmark SRC algorithms.
The maximal theoretical SNR of 64-bit "double" type (53-bit mantissa) is 319 dB, but in practice around 310 dB.
r8brain-free-src achieves 260 dB SNR when resampling a sine-wave signal. But only 170 dB SNR when resampling white-noise signal (probably due to a simultaneous intermix of large and low-amplitude signals in the noise). It's a quirky thing - to benchmark SRC algorithms.
The maximal theoretical SNR of 64-bit "double" type (53-bit mantissa) is 319 dB, but in practice around 310 dB.
- KVRAF
- 7890 posts since 12 Feb, 2006 from Helsinki, Finland
Well, it depends on what you want to vary the sample-rate for.. but in general continuous "audio-rate" sample-rate variation is a huge can of worms, because from the theoretical point of view the sinc-interpolation isn't really valid anymore (it's basically just the special case that you get with fixed-rate).Aleksey Vaneev wrote: r8brain-free-src does not offer continuous sample rate change, but I think for continuous change using a cross-fade technique is a lot better thing and does not compromise quality of SRC.
From when I last messed with that stuff (not that I have a really good solution, but I've spent some time trying to find one).. one trick one can do is to use band-limited zero-order-hold (or something similar, like interpolation of the approximated derivative) instead of sinc-reconstruction, to push the noise from the modulation to the high frequencies. It's still very much wrong from the theoretical point of view, but works reasonably.
In any case it's a whole different problem from just doing fixed-rate or "slowly-changing" sample-rate conversion (where "slowly-changing" basically comes down to "modulation isn't fast enough to introduce significant side-bands").
- KVRAF
- Topic Starter
- 4021 posts since 7 Sep, 2002
In my opinion, continuous sample rate changes can be done without issues, even by using r8brain-free-src if the destination sample rate is always higher than the source sample rate. The CDSPFracInterpolator class can be easily changed to non-constant sample step size.
Of course even slow changes to sample rate cause transient artifacts by itself, but the bank of fractional delay filters won't fail.
Of course even slow changes to sample rate cause transient artifacts by itself, but the bank of fractional delay filters won't fail.
-
- KVRian
- 756 posts since 3 Apr, 2013 from Belgium
Great ! Thanks for this, could you elaborate a little bit about why Reaper (or other's as I don't want to put the stigma on Reaper) resampling fails (in someway) ?
I was interested in this a few months before and someone gave me link a link to a website referencing most of audio applications (daws, wave editors, etc...) and showing graphically the differences between them while resampling (or changing bit depth) but I was not aware enough to understand. I was recommended to use r8brain to do my downsampling
EDIT : I should read thread more carefully before posting. Someone already posted a link to the website I was thinking of, and Aleksey already answered about Reaper's src. Anyway thanks !
I was interested in this a few months before and someone gave me link a link to a website referencing most of audio applications (daws, wave editors, etc...) and showing graphically the differences between them while resampling (or changing bit depth) but I was not aware enough to understand. I was recommended to use r8brain to do my downsampling
EDIT : I should read thread more carefully before posting. Someone already posted a link to the website I was thinking of, and Aleksey already answered about Reaper's src. Anyway thanks !
Last edited by Davias on Wed Aug 21, 2013 8:16 pm, edited 1 time in total.
- KVRAF
- Topic Starter
- 4021 posts since 7 Sep, 2002
- KVRAF
- Topic Starter
- 4021 posts since 7 Sep, 2002
-
- KVRian
- 1153 posts since 11 Aug, 2004 from Breuillet, France
- KVRAF
- Topic Starter
- 4021 posts since 7 Sep, 2002
I was lucky to find an even better, "Vaneev" windowing function for fractional delay filters. This allowed to reduce the number of taps from 40 to 38 and that strangely gave not just 5%, but around 9% more overall speed to the conversion, probably because windowing function is now more optimal, with less "near zero" values in the filter.
So, now even white-noise resampling achieves 220 dB SNR.
So, now even white-noise resampling achieves 220 dB SNR.
- KVRAF
- 23102 posts since 7 Jan, 2009 from Croatia
Hopefully at some point Cockos will include both r8b and SoX. SoX seems to be an even better solution than r8b, judging by infinitewave graphs...
- KVRAF
- Topic Starter
- 4021 posts since 7 Sep, 2002
- KVRAF
- Topic Starter
- 4021 posts since 7 Sep, 2002
- KVRian
- 519 posts since 12 Apr, 2010 from The Netherlands
Thanks for sharing this, especially so liberally licensed.
I have just quickly reimplemented Combo Model F's internal IR resampling, and it seems to work great. I did encounter a two minor issues:
1. My x86 build environment (MSVC 2008) seems to be missing <stdint.h>. However, <stdint.h> seems to be required only when using IPP, so I propose the following simple patch on r8bbase.h:
2. There seems to be some VOX_WIN #ifdefs left, which I guess should have been replaced with R8B_WIN, so here is another r8bbase.h patch:
I have just quickly reimplemented Combo Model F's internal IR resampling, and it seems to work great. I did encounter a two minor issues:
1. My x86 build environment (MSVC 2008) seems to be missing <stdint.h>. However, <stdint.h> seems to be required only when using IPP, so I propose the following simple patch on r8bbase.h:
Code: Select all
diff --git a/r8bbase.h b/r8bbase.h
index 4b820b1..71ed9a1 100644
--- a/r8bbase.h
+++ b/r8bbase.h
@@ -142,12 +142,15 @@
#ifndef R8BBASE_INCLUDED
#define R8BBASE_INCLUDED
-#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "r8bconf.h"
+#if R8B_IPP
+ #include <stdint.h>
+#endif // R8B_IPP
+
#if defined( R8B_WIN )
#include <windows.h>
#else // R8B_WIN
Code: Select all
diff --git a/r8bbase.h b/r8bbase.h
index 71ed9a1..34240e7 100644
--- a/r8bbase.h
+++ b/r8bbase.h
@@ -532,24 +532,24 @@ struct CSyncObject
public:
CSyncObject()
{
- #if defined( VOX_WIN )
+ #if defined( R8B_WIN )
InitializeCriticalSectionAndSpinCount( &CritSec, 4000 );
- #else // VOX_WIN
+ #else // R8B_WIN
pthread_mutexattr_t MutexAttrs;
pthread_mutexattr_init( &MutexAttrs );
pthread_mutexattr_settype( &MutexAttrs, PTHREAD_MUTEX_RECURSIVE );
pthread_mutex_init( &Mutex, &MutexAttrs );
pthread_mutexattr_destroy( &MutexAttrs );
- #endif // VOX_WIN
+ #endif // R8B_WIN
}
~CSyncObject()
{
- #if defined( VOX_WIN )
+ #if defined( R8B_WIN )
DeleteCriticalSection( &CritSec );
- #else // VOX_WIN
+ #else // R8B_WIN
pthread_mutex_destroy( &Mutex );
- #endif // VOX_WIN
+ #endif // R8B_WIN
}
/**
@@ -559,11 +559,11 @@ public:
void acquire()
{
- #if defined( VOX_WIN )
+ #if defined( R8B_WIN )
EnterCriticalSection( &CritSec );
- #else // VOX_WIN
+ #else // R8B_WIN
pthread_mutex_lock( &Mutex );
- #endif // VOX_WIN
+ #endif // R8B_WIN
}
/**
@@ -573,22 +573,22 @@ public:
void release()
{
- #if defined( VOX_WIN )
+ #if defined( R8B_WIN )
LeaveCriticalSection( &CritSec );
- #else // VOX_WIN
+ #else // R8B_WIN
pthread_mutex_unlock( &Mutex );
- #endif // VOX_WIN
+ #endif // R8B_WIN
}
private:
- #if defined( VOX_WIN )
+ #if defined( R8B_WIN )
CRITICAL_SECTION CritSec; ///< Standard Windows critical section
///< structure.
///<
- #else // VOX_WIN
+ #else // R8B_WIN
pthread_mutex_t Mutex; ///< pthread.h mutex object.
///<
- #endif // VOX_WIN
+ #endif // R8B_WIN
};
/**
- KVRAF
- Topic Starter
- 4021 posts since 7 Sep, 2002
Yes, VOX_WIN defs are an error, I will fix it.
I will remove <stdint.h> dependency completely by using unsigned char instead of uint8_t. stdint.h is a standard header for GCC, Mac OS X and Linux, and the latest Intel C++.
I also plan to add "filter phasing" option so that min-phase filters can be also used.
Thanks for checking!
I will remove <stdint.h> dependency completely by using unsigned char instead of uint8_t. stdint.h is a standard header for GCC, Mac OS X and Linux, and the latest Intel C++.
I also plan to add "filter phasing" option so that min-phase filters can be also used.
Thanks for checking!
- KVRian
- 519 posts since 12 Apr, 2010 from The Netherlands
It is a standard header for MSVC 2010 and 2012 as well. However, on x86 I still support WinXP SP1 (for now anyway), so I use an older compiler for that platform.Aleksey Vaneev wrote:stdint.h is a standard header for GCC, Mac OS X and Linux, and the latest Intel C++.
--
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?