Csound Csound-dev Csound-tekno Search About

[Csnd] pvstrace unique frequencies

Date2020-10-19 14:00
FromOeyvind Brandtsegg
Subject[Csnd] pvstrace unique frequencies
Hi
I seem to recall that someone (Joachim?) did some work with pvstrace, extracting the strongest unique frequencies from a spectrum. With a signal that contains only a few pure sines, pvsanal seems to "lump" the bins around those frequencies. I would like to set a minimum threshold of separation (in Hz), so that I could read the strongest partials of a spectrum with pvstrace. Before delving into doing this myself, I wanted to ask if someone had already come up with a solution?
all best
Oeyvind
Csound mailing list Csound@listserv.heanet.ie https://listserv.heanet.ie/cgi-bin/wa?A0=CSOUND Send bugs reports to https://github.com/csound/csound/issues Discussions of bugs and features can be posted here

Date2020-10-19 14:27
FromVictor Lazzarini
SubjectRe: [Csnd] [EXTERNAL] [Csnd] pvstrace unique frequencies
Not really a solution, more of a diagnostic. The lumping is due to the fact that windowing makes a sine component appear
at three or four bins (in the case of a Hanning window) around the peak. So I suppose, depending on the intensity of the peak 
relative to everything else, this would explain it. 
========================
Prof. Victor Lazzarini
Maynooth University
Ireland

> On 19 Oct 2020, at 14:00, Oeyvind Brandtsegg  wrote:
> 
> WARNINGThis email originated from outside of Maynooth University's Mail System. Do not reply, click links or open attachments unless you recognise the sender and know the content is safe.
> Hi
> I seem to recall that someone (Joachim?) did some work with pvstrace, extracting the strongest unique frequencies from a spectrum. With a signal that contains only a few pure sines, pvsanal seems to "lump" the bins around those frequencies. I would like to set a minimum threshold of separation (in Hz), so that I could read the strongest partials of a spectrum with pvstrace. Before delving into doing this myself, I wanted to ask if someone had already come up with a solution?
> all best
> Oeyvind
> Csound mailing list Csound@listserv.heanet.ie https://listserv.heanet.ie/cgi-bin/wa?A0=CSOUND Send bugs reports to https://github.com/csound/csound/issues Discussions of bugs and features can be posted here

Csound mailing list
Csound@listserv.heanet.ie
https://listserv.heanet.ie/cgi-bin/wa?A0=CSOUND
Send bugs reports to
        https://github.com/csound/csound/issues
Discussions of bugs and features can be posted here

Date2020-10-19 15:40
FromSteven Yi
SubjectRe: [Csnd] [EXTERNAL] [Csnd] pvstrace unique frequencies
I wonder if just searching for local maxima first would help? Quick
search yielded something similar with a threshold added:

https://www.dsprelated.com/showcode/217.php

Not my area of expertise at all, so take with a grain of salt. ;)

On Mon, Oct 19, 2020 at 9:27 AM Victor Lazzarini  wrote:
>
> Not really a solution, more of a diagnostic. The lumping is due to the fact that windowing makes a sine component appear
> at three or four bins (in the case of a Hanning window) around the peak. So I suppose, depending on the intensity of the peak
> relative to everything else, this would explain it.
> ========================
> Prof. Victor Lazzarini
> Maynooth University
> Ireland
>
> > On 19 Oct 2020, at 14:00, Oeyvind Brandtsegg  wrote:
> >
> > WARNINGThis email originated from outside of Maynooth University's Mail System. Do not reply, click links or open attachments unless you recognise the sender and know the content is safe.
> > Hi
> > I seem to recall that someone (Joachim?) did some work with pvstrace, extracting the strongest unique frequencies from a spectrum. With a signal that contains only a few pure sines, pvsanal seems to "lump" the bins around those frequencies. I would like to set a minimum threshold of separation (in Hz), so that I could read the strongest partials of a spectrum with pvstrace. Before delving into doing this myself, I wanted to ask if someone had already come up with a solution?
> > all best
> > Oeyvind
> > Csound mailing list Csound@listserv.heanet.ie https://listserv.heanet.ie/cgi-bin/wa?A0=CSOUND Send bugs reports to https://github.com/csound/csound/issues Discussions of bugs and features can be posted here
>
> Csound mailing list
> Csound@listserv.heanet.ie
> https://listserv.heanet.ie/cgi-bin/wa?A0=CSOUND
> Send bugs reports to
>         https://github.com/csound/csound/issues
> Discussions of bugs and features can be posted here

Csound mailing list
Csound@listserv.heanet.ie
https://listserv.heanet.ie/cgi-bin/wa?A0=CSOUND
Send bugs reports to
        https://github.com/csound/csound/issues
Discussions of bugs and features can be posted here

Date2020-10-19 21:24
FromOeyvind Brandtsegg
SubjectRe: [Csnd] [EXTERNAL] [Csnd] pvstrace unique frequencies
Thanks for the tip. It is much more elegant than what I had in mind.

Here's my implementation (skipped the low thresh in the original example):

<CsoundSynthesizer>
<CsOptions>
-n --displays
</CsOptions>
<CsInstruments>

ksmps = 64
nchnls = 2
0dbfs = 1

giShape ftgen 0, 0, 256, 10, .1, 0.5, 0.2, 0.1,0.7

;***************************************************
; find local maxima
; from matlab Author: sparafucile17 10/02/2003
; https://www.dsprelated.com/showcode/217.php
;***************************************************
opcode LocalMax, k[], i
giData xin
kndx init 1
kpeakindx init 0
kPeaks[] init ftlen(giData)/2
kprev_amp table 0, giData
kprev_slope init 1; allow a maxima point at the second sample
while kndx < ftlen(giData) do
kamp table kndx, giData
kslope = kamp - kprev_amp
if (kamp < kprev_amp) && (kprev_slope > 0) then
kPeaks[kpeakindx] = kndx-1
kpeakindx += 1
endif
kprev_amp = kamp
kprev_slope = kslope
kndx += 1
od
xout kPeaks
endop

instr 1
 kTest[] LocalMax giShape
 kndx init 0
 while kTest[kndx] > 0 do
   printf "amp %f at index %i \n", kndx+1, table(kTest[kndx],giShape), kTest[kndx]
   kndx += 1
 od
 endin

</CsInstruments>
<CsScore>
; start dur
i1 0 1
e
</CsScore>
</CsoundSynthesizer>


man. 19. okt. 2020 kl. 16:40 skrev Steven Yi <stevenyi@gmail.com>:
I wonder if just searching for local maxima first would help? Quick
search yielded something similar with a threshold added:

https://www.dsprelated.com/showcode/217.php

Not my area of expertise at all, so take with a grain of salt. ;)

On Mon, Oct 19, 2020 at 9:27 AM Victor Lazzarini <Victor.Lazzarini@mu.ie> wrote:
>
> Not really a solution, more of a diagnostic. The lumping is due to the fact that windowing makes a sine component appear
> at three or four bins (in the case of a Hanning window) around the peak. So I suppose, depending on the intensity of the peak
> relative to everything else, this would explain it.
> ========================
> Prof. Victor Lazzarini
> Maynooth University
> Ireland
>
> > On 19 Oct 2020, at 14:00, Oeyvind Brandtsegg <obrandts@gmail.com> wrote:
> >
> > WARNINGThis email originated from outside of Maynooth University's Mail System. Do not reply, click links or open attachments unless you recognise the sender and know the content is safe.
> > Hi
> > I seem to recall that someone (Joachim?) did some work with pvstrace, extracting the strongest unique frequencies from a spectrum. With a signal that contains only a few pure sines, pvsanal seems to "lump" the bins around those frequencies. I would like to set a minimum threshold of separation (in Hz), so that I could read the strongest partials of a spectrum with pvstrace. Before delving into doing this myself, I wanted to ask if someone had already come up with a solution?
> > all best
> > Oeyvind
> > Csound mailing list Csound@listserv.heanet.ie https://listserv.heanet.ie/cgi-bin/wa?A0=CSOUND Send bugs reports to https://github.com/csound/csound/issues Discussions of bugs and features can be posted here
>
> Csound mailing list
> Csound@listserv.heanet.ie
> https://listserv.heanet.ie/cgi-bin/wa?A0=CSOUND
> Send bugs reports to
>         https://github.com/csound/csound/issues
> Discussions of bugs and features can be posted here

Csound mailing list
Csound@listserv.heanet.ie
https://listserv.heanet.ie/cgi-bin/wa?A0=CSOUND
Send bugs reports to
        https://github.com/csound/csound/issues
Discussions of bugs and features can be posted here
Csound mailing list Csound@listserv.heanet.ie https://listserv.heanet.ie/cgi-bin/wa?A0=CSOUND Send bugs reports to https://github.com/csound/csound/issues Discussions of bugs and features can be posted here

Date2020-10-19 23:32
FromOeyvind Brandtsegg
SubjectRe: [Csnd] [EXTERNAL] [Csnd] pvstrace unique frequencies
Trying to implement this in my intended context, I get it to work well with synthetic signals (analysing simple sine tones). With acoustic signals, I get a more "jagged" spectrum, and the simple local maxima method picks up on those extra peaks. I tried to filter the spectrum with  pvsceps, which seems to help. But if I filter too much (fewer than approx 200 cepstrum coefficients, the exact number varies of course depending on the pvsanal fft size), then I get a frequency offset in the lower register (below approx 100 Hz). I think I understand that this occurs because the peaks of the spectrum have been subtly shifted because of the cepstrum liftering. The csd below seems to be a fair tradeoff between low frequency precision and cepstral smoothing. Still, it seems fuzzy in the low register. 
Any help to refine it is greatly appreciated
Øyvind

The below example also modifies the previous UDO I sent, to use a k-rate array instead of a table as the data for the local maxima.

<Cabbage>
form size(505, 520), caption("Display of strongest frequency components"), pluginID("fdis")
nslider channel("f1"), bounds(5, 10, 55, 20), text("f1"), range(0.0, 1000, 0, 1.0, 0.1)
nslider channel("f2"), bounds(65, 10, 55, 20), text("f2"), range(0.0, 1000, 0, 1.0, 0.1)
nslider channel("f3"), bounds(125, 10, 55, 20), text("f3"), range(0.0, 1000, 0, 1.0, 0.1)
nslider channel("a1"), bounds(5, 40, 55, 20), text("a1"), range(-96, 10000, -96, 1.0, 0.1)
nslider channel("a2"), bounds(65, 40, 55, 20), text("a2"), range(-96, 10000, -96, 1.0, 0.1)
nslider channel("a3"), bounds(125, 40, 55, 20), text("a3"), range(-96, 10000, -96, 1.0, 0.1)

gentable bounds(5, 80, 200, 200), identchannel("scopetable"), tablenumbers(1), tablecolours("lightblue"), amprange(-96,0,1), samplerange(0,256)
csoundoutput bounds(5,280,200,200)

</Cabbage>

<CsoundSynthesizer>
<CsOptions>
-n -d
</CsOptions>
<CsInstruments>

ksmps = 64
nchnls = 2
0dbfs = 1

gi_dispsize = 256
giShape ftgen 1, 0, gi_dispsize, 7, -1, gi_dispsize, 1

;***************************************************
; find local maxima
; from matlab Author: sparafucile17 10/02/2003
; https://www.dsprelated.com/showcode/217.php
;***************************************************
opcode LocalMax, k[], k[]
kData[] xin
kndx = 1
kpeakindx = 0
kPeaks[] init lenarray(kData)/2
kprev_amp = kData[0]
kprev_slope = 0; not allow a maxima point at the second sample
while kndx < lenarray(kData) do
kamp = kData[kndx]
kslope = kamp - kprev_amp
if (kamp < kprev_amp) && (kprev_slope > 0) then
kPeaks[kpeakindx] = kndx-1
kpeakindx += 1
endif
kprev_amp = kamp
kprev_slope = kslope
kndx += 1
od
xout kPeaks
endop

;***************************************************
; Analyze strongest frequency components, low freq range (10-1000 Hz)
;***************************************************
  instr 1
  a1, a2 ins
ifftsize = 4096
kAmps[] init (ifftsize/2)+1
kFreqs[] init (ifftsize/2)+1
iwtype = 1
f1 pvsanal a1, ifftsize, ifftsize/2, ifftsize, iwtype
f2 pvsmooth f1, 0.1, 0.1
kflag pvs2array kAmps, kFreqs, f2 ; export amps and freqs to array
kCeps[] pvsceps f2, 250
kAmps cepsinv kCeps
if kflag > 0 then
kndx = 0
 while kndx < gi_dispsize do
tabw dbfsamp(kAmps[kndx]), kndx, giShape
kndx += 1
od
chnset "tablenumber(1)", "scopetable" ; update table display

kPeaks[] LocalMax kAmps

chnset kFreqs[kPeaks[0]], "f1"
chnset kFreqs[kPeaks[1]], "f2"
chnset kFreqs[kPeaks[2]], "f3"
chnset dbfsamp(kAmps[kPeaks[0]]*2), "a1"
chnset dbfsamp(kAmps[kPeaks[1]]*2), "a2"
chnset dbfsamp(kAmps[kPeaks[2]]*2), "a3"

endif
  endin

</CsInstruments>
<CsScore>
; start dur
i1 0 86400 ; play for 24 hours
e
</CsScore>
</CsoundSynthesizer>


man. 19. okt. 2020 kl. 22:24 skrev Oeyvind Brandtsegg <obrandts@gmail.com>:
Thanks for the tip. It is much more elegant than what I had in mind.

Here's my implementation (skipped the low thresh in the original example):

<CsoundSynthesizer>
<CsOptions>
-n --displays
</CsOptions>
<CsInstruments>

ksmps = 64
nchnls = 2
0dbfs = 1

giShape ftgen 0, 0, 256, 10, .1, 0.5, 0.2, 0.1,0.7

;***************************************************
; find local maxima
; from matlab Author: sparafucile17 10/02/2003
; https://www.dsprelated.com/showcode/217.php
;***************************************************
opcode LocalMax, k[], i
giData xin
kndx init 1
kpeakindx init 0
kPeaks[] init ftlen(giData)/2
kprev_amp table 0, giData
kprev_slope init 1; allow a maxima point at the second sample
while kndx < ftlen(giData) do
kamp table kndx, giData
kslope = kamp - kprev_amp
if (kamp < kprev_amp) && (kprev_slope > 0) then
kPeaks[kpeakindx] = kndx-1
kpeakindx += 1
endif
kprev_amp = kamp
kprev_slope = kslope
kndx += 1
od
xout kPeaks
endop

instr 1
 kTest[] LocalMax giShape
 kndx init 0
 while kTest[kndx] > 0 do
   printf "amp %f at index %i \n", kndx+1, table(kTest[kndx],giShape), kTest[kndx]
   kndx += 1
 od
 endin

</CsInstruments>
<CsScore>
; start dur
i1 0 1
e
</CsScore>
</CsoundSynthesizer>


man. 19. okt. 2020 kl. 16:40 skrev Steven Yi <stevenyi@gmail.com>:
I wonder if just searching for local maxima first would help? Quick
search yielded something similar with a threshold added:

https://www.dsprelated.com/showcode/217.php

Not my area of expertise at all, so take with a grain of salt. ;)

On Mon, Oct 19, 2020 at 9:27 AM Victor Lazzarini <Victor.Lazzarini@mu.ie> wrote:
>
> Not really a solution, more of a diagnostic. The lumping is due to the fact that windowing makes a sine component appear
> at three or four bins (in the case of a Hanning window) around the peak. So I suppose, depending on the intensity of the peak
> relative to everything else, this would explain it.
> ========================
> Prof. Victor Lazzarini
> Maynooth University
> Ireland
>
> > On 19 Oct 2020, at 14:00, Oeyvind Brandtsegg <obrandts@gmail.com> wrote:
> >
> > WARNINGThis email originated from outside of Maynooth University's Mail System. Do not reply, click links or open attachments unless you recognise the sender and know the content is safe.
> > Hi
> > I seem to recall that someone (Joachim?) did some work with pvstrace, extracting the strongest unique frequencies from a spectrum. With a signal that contains only a few pure sines, pvsanal seems to "lump" the bins around those frequencies. I would like to set a minimum threshold of separation (in Hz), so that I could read the strongest partials of a spectrum with pvstrace. Before delving into doing this myself, I wanted to ask if someone had already come up with a solution?
> > all best
> > Oeyvind
> > Csound mailing list Csound@listserv.heanet.ie https://listserv.heanet.ie/cgi-bin/wa?A0=CSOUND Send bugs reports to https://github.com/csound/csound/issues Discussions of bugs and features can be posted here
>
> Csound mailing list
> Csound@listserv.heanet.ie
> https://listserv.heanet.ie/cgi-bin/wa?A0=CSOUND
> Send bugs reports to
>         https://github.com/csound/csound/issues
> Discussions of bugs and features can be posted here

Csound mailing list
Csound@listserv.heanet.ie
https://listserv.heanet.ie/cgi-bin/wa?A0=CSOUND
Send bugs reports to
        https://github.com/csound/csound/issues
Discussions of bugs and features can be posted here
Csound mailing list Csound@listserv.heanet.ie https://listserv.heanet.ie/cgi-bin/wa?A0=CSOUND Send bugs reports to https://github.com/csound/csound/issues Discussions of bugs and features can be posted here