[Csnd] pvstrace unique frequencies
Date | 2020-10-19 14:00 |
From | Oeyvind Brandtsegg |
Subject | [Csnd] pvstrace unique frequencies |
Hi
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
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 |
Date | 2020-10-19 14:27 |
From | Victor Lazzarini |
Subject | Re: [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 |
Date | 2020-10-19 15:40 |
From | Steven Yi |
Subject | Re: [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 |
Date | 2020-10-19 21:24 |
From | Oeyvind Brandtsegg |
Subject | Re: [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 |
Date | 2020-10-19 23:32 |
From | Oeyvind Brandtsegg |
Subject | Re: [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>:
|