Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Q-factor too high for frequencies #18

Open
ivanmkc opened this issue Jul 31, 2016 · 3 comments
Open

Q-factor too high for frequencies #18

ivanmkc opened this issue Jul 31, 2016 · 3 comments

Comments

@ivanmkc
Copy link

ivanmkc commented Jul 31, 2016

Hi,

Many thanks for this great package. I'm using it for musical note analysis and thus I'm putting in the minimum frequency as midi2hz(21) and the maximum as midi2hz(108). 21 and 108 are the lowest and highest notes on a piano respectively, in midi format, and midi2hz converts midi values to Hertz.

My code is thus:

Ls = len(segmentWindow)
numBins = int(np.ceil(108 - 21))
scl = LogScale(midi2hz(21), midi2hz(108), numBins)
nsgt = NSGT(scl, samplingRate, Ls, real=True, matrixform=True)

I'm getting the following warning:
UserWarning: Q-factor too high for frequencies 27.50,29.10,30.78,32.57,34.46,36.46,38.58,40.82,43.19,45.69,48.35,51.15,54.12,57.26,60.59,64.10,67.82,71.76,75.92,80.33,84.99,89.93,95.15,100.67,106.51,112.69,119.23,126.15,133.48,141.22,149.42,158.09,167.27,176.98,187.25 warn("Q-factor too high for frequencies %s"%",".join("%.2f"%fi for fi in f[q >= qneeded]))

  1. Do you know why this is?
  2. How would you recommend fixing this?

Thanks

@grrrr
Copy link
Owner

grrrr commented Jul 31, 2016

Hi Ivan, high Q factors (high spectral resolution) need large frame sizes
aka time support in mathematical terms. I need to formalize this sometime,
it's a reoccurring question. Obviously your "segment length" is about a
factor 6 or so too small to resolve your low frequency bins.

Am 31.07.2016 um 19:42 schrieb Ivan Cheung notifications@github.com:

Hi,

Many thanks for this great package. I'm using it for musical note analysis
and thus I'm putting in the minimum frequency as midi2hz(21) and the
maximum as midi2hz(108). 21 and 108 are the lowest and highest notes on a
piano respectively, in midi format, and midi2hz converts midi values to
Hertz.

My code is thus:
`
Ls = len(segmentWindow)

numBins = int(np.ceil(108 - 21))
scl = LogScale(midi2hz(21), midi2hz(108), numBins)
nsgt = NSGT(scl, samplingRate, Ls, real=True, matrixform=True)
`

I'm getting the following warning:
UserWarning: Q-factor too high for frequencies
27.50,29.10,30.78,32.57,34.46,36.46,38.58,40.82,43.19,45.69,48.35,51.15,54.12,57.26,60.59,64.10,67.82,71.76,75.92,80.33,84.99,89.93,95.15,100.67,106.51,112.69,119.23,126.15,133.48,141.22,149.42,158.09,167.27,176.98,187.25
warn("Q-factor too high for frequencies %s"%",".join("%.2f"%fi for fi in
f[q >= qneeded]))

  1. Do you know why this is?
  2. How would you recommend fixing this?

Thanks


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
#18, or mute the thread
https://github.com/notifications/unsubscribe-auth/AAJ-JvFi4mBhUEZAYqS6tLqYcYi4C7eeks5qbN6HgaJpZM4JZFLA
.

@ivanmkc
Copy link
Author

ivanmkc commented Jul 31, 2016

Hi Thomas,

Thanks for responding. I understand the need for more samples to support
more spectral resolution.

  1. I'm wondering if there's anything I can change besides reducing the number
    of bins. I tried reducing the number of bins by a factor of 4 and it worked to remove the warning, but it took 3 times longer to compute which was counter-intuitive for me. Shouldn't it take less time for less bins?
  2. How do I reduce the q factor? Can I set this?
  3. Also, in nsfgwin, there is the line of code:

qneeded = f_(Ls/(8._sr))

Where does the 8 come from? Is it kind of arbitrary right now?

Thanks

On Sun, Jul 31, 2016 at 3:47 PM, Thomas Grill notifications@github.com
wrote:

Hi Ivan, high Q factors (high spectral resolution) need large frame sizes
aka time support in mathematical terms. I need to formalize this sometime,
it's a reoccurring question. Obviously your "segment length" is about a
factor 6 or so too small to resolve your low frequency bins.

Am 31.07.2016 um 19:42 schrieb Ivan Cheung notifications@github.com:

Hi,

Many thanks for this great package. I'm using it for musical note analysis
and thus I'm putting in the minimum frequency as midi2hz(21) and the
maximum as midi2hz(108). 21 and 108 are the lowest and highest notes on a
piano respectively, in midi format, and midi2hz converts midi values to
Hertz.

My code is thus:
`
Ls = len(segmentWindow)

numBins = int(np.ceil(108 - 21))
scl = LogScale(midi2hz(21), midi2hz(108), numBins)
nsgt = NSGT(scl, samplingRate, Ls, real=True, matrixform=True)
`

I'm getting the following warning:
UserWarning: Q-factor too high for frequencies

27.50,29.10,30.78,32.57,34.46,36.46,38.58,40.82,43.19,45.69,48.35,51.15,54.12,57.26,60.59,64.10,67.82,71.76,75.92,80.33,84.99,89.93,95.15,100.67,106.51,112.69,119.23,126.15,133.48,141.22,149.42,158.09,167.27,176.98,187.25
warn("Q-factor too high for frequencies %s"%",".join("%.2f"%fi for fi in
f[q >= qneeded]))

  1. Do you know why this is?
  2. How would you recommend fixing this?

Thanks


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
#18, or mute the thread
<
https://github.com/notifications/unsubscribe-auth/AAJ-JvFi4mBhUEZAYqS6tLqYcYi4C7eeks5qbN6HgaJpZM4JZFLA

.


You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
#18 (comment), or mute
the thread
https://github.com/notifications/unsubscribe-auth/ABgzgQWXhx9p5d7agyZZr7zRpdWUM02fks5qbPvngaJpZM4JZFLA
.

@sevagh
Copy link

sevagh commented May 11, 2021

@grrrr what do you think of adding the following code to the nsgt Scale class - I can submit the PR

class Scale:
    dbnd = 1.e-8

    def __init__(self, bnds):
        self.bnds = bnds

    def __len__(self):
        return self.bnds

    def Q(self, bnd=None):
        # numerical differentiation (if self.Q not defined by sub-class)
        if bnd is None:
            bnd = np.arange(self.bnds)
        return self.F(bnd)*self.dbnd/(self.F(bnd+self.dbnd)-self.F(bnd-self.dbnd))

    def __call__(self):
        f = np.array([self.F(b) for b in range(self.bnds)],dtype=float)
        q = np.array([self.Q(b) for b in range(self.bnds)],dtype=float)
        return f,q

    def suggested_sllen(self, sr):
        f,q = self()

        Ls = int(np.ceil(max((q*8.*sr)/f)))

        # make sure its divisible by 4
        Ls = Ls + -Ls % 4

        return Ls

The way to use it is to get the suggested sllen that supports your desired frequencies and Q factors (from which you can get trlen for slicq) - the same should apply for the length argument to the non-sliced transform:

scl = LogScale(fmin, fs/2, fbins)

# use slice length required to support desired frequency scale/q factors
sllen = scl.suggested_sllen(fs)

# optional trlen for sliced-q, otherwise Ls=sllen
trlen = sllen//4
trlen = trlen + -trlen % 2 # make trlen divisible by 2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants