Comments (9)
@ar1st0crat
Just a reminder that theres a bug in resampler where if you pass in a filter to the Resample method, it doesn't get used.
NWaves/NWaves/Operations/Resampler.cs
Lines 115 to 121 in 0728ca6
There is no else condition to use a provided filter if it is not null.
from nwaves.
Just a small update, it turns out the signal quality degrades constantly over time. Even before 36 hours, the signal is starting to look more 'square' compared to at the beginning. Is this an error accumulating and eventually overflowing perhaps?
from nwaves.
The fix for me at the moment is to reset the filter after short sections of data with lpFilter.Reset(); but it does cause some aliasing at each boundary. Do you know if you'll have a chance to take a look at this @ar1st0crat ?
from nwaves.
Hi!
Thank you for the kind words about the library :-)
Unfortunately, at the moment I don't have much time for reviewing issues regarding NWaves.
Anyway, from what I see already, you're using high-pass filter in resampling operation. The purpose of FIR filter in resampling methods is antialising, so it must be a low-pass filter (with the cut-off frequency 0.5 / resample_factor
). If you need to remove the baseline wander, then you should apply your highpass filter separately. Currently, you're applying the high-pass filter. (In NWaves cut-off frequency 0.5 is equivalent to 1.0 in sciPy/MATLAB). So, esentially you filter is HP, although you're constructing it as BP.
Hence, there are two options:
// 1) solution similar to yours:
// the filter will be essentially LP (although, technically it's BP):
var lowCutoff = 0.5 / newSr; // high pass to remove baseline wander
var highCutoff = 0.5 / 3; // 3 because greatest_common_divisor(128, 192) = 3
var filterOrder = 11;
var resampler = new Resampler();
var lpFilter = new FirFilter(DesignFilter.FirWinBp(filterOrder, lowCutoff, highCutoff));
var resampled = resampler.Resample(new NWaves.Signals.DiscreteSignal(oldSr, data), newSr, lpFilter);
return resampled.Samples;
// 2) slighly-less efficient, but more readable
var cutoff = 0.5 / newSr; // high pass to remove baseline wander
var filterOrder = 11;
// filter to remove baseline wander, first:
var hpFilter = new FirFilter(DesignFilter.FirWinHp(filterOrder, cutoff));
var filtered = hpFilter.ApplyTo(new NWaves.Signals.DiscreteSignal(oldSr, data));
var resampler = new Resampler();
// resampling antialiasing LP filter will be constructed automatically inside Resample() function:
var resampled = resampler.Resample(filtered, newSr);
return resampled.Samples;
PS. Btw, is filter order=11 OK? Perhaps, it's too small. You can try bigger values. Like 101 for example. Filtering will be automatically be carried out via block convolution, so it's going to be quite fast.
from nwaves.
I just noticed, if you pass in a filter it doesn't actually get used at all which is probably why I was getting such bad aliasing
NWaves/NWaves/Operations/Resampler.cs
Line 115 in 726d8dd
The if's need to be split up into something like:
if (g < 1)
{
if (filter == null)
{
filter = new FirFilter(DesignFilter.FirWinLp(MinResamplingFilterOrder, g / 2));
}
input = filter.ApplyTo(signal).Samples;
}
otherwise the low pass filter you pass in won't be used.
from nwaves.
No, AFAIR, filtering is not needed for band-limited upsampling, so my code is correct.
I've just noticed - you're calling Resample()
method. This method implements the so called band-limited resampling. It's quite slow and intended to be used for "complicated" resamplings (like 44.1kHz to 16 kHz, for example). In your case (128 -> 192) you have upsampling factor 3 and downsampling factor 2, so I would recommend calling ResampleUpDown()
:
// 1)
var lowCutoff = 0.5 / newSr; // high pass to remove baseline wander
var highCutoff = 0.5 / 3; // 3 because greatest_common_divisor(128, 192) = 3
var filterOrder = 99;
var filter = new FirFilter(DesignFilter.FirWinBp(filterOrder, lowCutoff, highCutoff));
var resampler = new Resampler();
var resampled = resampler.ResampleUpDown(new NWaves.Signals.DiscreteSignal(oldSr, data), 3, 2, filter);
return resampled.Samples;
// 2) this is the most correct version (but it will create intermediate HP-filtered signal):
var cutoff = 0.5 / newSr; // high pass to remove baseline wander
var filterOrder = 11;
// filter to remove baseline wander, first:
var hpFilter = new FirFilter(DesignFilter.FirWinHp(filterOrder, cutoff));
var filtered = hpFilter.ApplyTo(new NWaves.Signals.DiscreteSignal(oldSr, data));
var resampler = new Resampler();
// resampling antialiasing LP filter will be constructed automatically inside ResampleUpDown() function:
var resampled = resampler.ResampleUpDown(filtered, 3, 2);
return resampled.Samples;
from nwaves.
This is just one example, my input data sample rate varies and often the resample ratio is not a nice integer, like 200=>192, 250=>192 etc.
The code for Resample() is still not working correctly if downsampling though right? If you pass in a filter yourself, it won't be used even in the case of downsampling, because it checks if the filter is null to do the filtering step.
from nwaves.
Yes, you're right. I remember about this issue and I keep it open. I wanted to revise the entire resampling part of NWaves, but unfortunately at the moment I have no time for it.
from nwaves.
I've figured out the source of the noise, its actually caused by poor floating point precision at large values here:
NWaves/NWaves/Operations/Resampler.cs
Line 126 in c1a6a4a
It's especially bad in my case because signal values are small, so the lack of precision is relatively quite large.
I fixed it by changing the resample code to
// eliminate any floating point quantization errors for very large sample counts
decimal step = 1 / (decimal)g;
for (var n = 0; n < output.Length; n++)
{
var x = n * step;
for (var i = -order; i < order; i++)
{
var j = (int)Math.Floor(x) - i;
if (j < 0 || j >= input.Length)
{
continue;
}
var t = (double)(x - j); // at this point we are back to a small scale, safe to return to double type
from nwaves.
Related Issues (20)
- Playing saved audio HOT 2
- FeatureExtractor ComputeFrom FastCopy bug HOT 3
- Is there method for series filter? or parallel filter? HOT 2
- How to obtain digital SOS filter from analog zeros and poles? HOT 1
- FFT compatible with OpenAI Whisper features HOT 1
- Help with realtime resampling HOT 3
- Analog poles and zeros of elliptic filter are different from scipy HOT 2
- How to use the polyphase filters implementation
- Buggy RLS filter implementation HOT 3
- how to use stft like scipy.signal "f, t, tf_data = signal.stft(wavedata, fs=fs, window='hamming', nperseg=N_fft, noverlap=int(N_fft*0.8))"? Now we cannot get f,t value. The tf_data is different from var spectrogram = stft.Spectrogram(discreteSignal, normalize: true). HOT 2
- Question: Pitch Patterns
- out of memory using Stft.Spectrogram function HOT 1
- WaveFile: Compiler Warning (level 2) CS0652 @ line 134
- PowerSpectrum and Magnitude spectrum missing from FFT64, RealFFT, RealFFT64
- Order of instruction wrong on wiki page HOT 1
- Pitch shifter produces garbled noise HOT 1
- python speech features fbanks HOT 4
- DiscreteSignal.Samples contain more samples than the original signal HOT 2
- Pitch.FromYin triggers exception for certain sample rates and pitch ranges HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from nwaves.