Get Fourier analysis data from spectrum()

19 views
Skip to first unread message

dennis

unread,
Feb 28, 2024, 8:53:27 AM2/28/24
to pyo-discuss
Hi,

In the doc it is said about the Spectrum() method that we can use a function to retrieve de data in a text file. Do you have any idea how to make that works ? 

All I want is the components frequencies of my signal (Or I can read it directly in the spectrum if maybe there is a way to add more numbers on the axes of the window ?).



Thanks,

Dennis

Alexandros Drymonitis

unread,
Feb 28, 2024, 9:41:34 AM2/28/24
to pyo-d...@googlegroups.com

It's documentation is clear about it. Create a function with one argument (a list of lists, one for each channel in the spectrum), and do whatever you want with that list. To test it, here's a modified version of the code in the docs:

```
from pyo import *
s = Server(audio="jack").boot().start()
a = SuperSaw(freq=[500,750], detune=.6, bal=.7, mul=.5).out()
prnt = False

def printSpec(lst):
    global prnt
    if prnt:
        print(lst)
        prnt = False

spec = Spectrum(a, size=1024, function=printSpec)
```

Set prnt to True, and you'll get a list of two lists printed once. If you want to store that to a file, you'll have to open a text file with open(), like you'd do for any other file in Python.

--
You received this message because you are subscribed to the Google Groups "pyo-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pyo-discuss...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/pyo-discuss/6d28148f-6459-40ce-aa5b-eec543092e2an%40googlegroups.com.

dennis

unread,
Feb 29, 2024, 5:15:51 AM2/29/24
to pyo-discuss
Thanks Alexandros, it works though the output is not clear. I don't see any similarity with the spectrum of my signal:

I have a SuperSaw(freq=65.4,detune=.5, bal=.5, mul=a)  so I would expect to see numbers around 65, and some harmonics related numbers but I get (with a window size = 4096) but I get:

[[(0, 400), (0, 400), (1, 400), (2, 400), (3, 400),...until ,(500,400)]] 

If the analysis makes no selection in the signal, wouldn't we expect a list of fs/2 numbers ?

Bibiko

unread,
Feb 29, 2024, 9:16:55 AM2/29/24
to pyo-discuss
Hi,

you receive the (x,y) coordinates for plotting the spectrum. You have to transform these coordinates first, à la the following quick&dirty written example:

----
from pyo import *
from pyo.lib._wxwidgets import (tFromValue, interpFloat)

s = Server().boot().start()
a = SuperSaw(freq=[500,750], detune=.6, bal=.7, mul=.5).mix(1).out()
sr = s.getSamplingRate()
cnt = 0
prnt = True

def printSpec(lst):
    global cnt, prnt, win_width, win_height, lowBound, highBound
    if not prnt:
        return
    for a in lst:
        # start after the 5th run
        if cnt > 5:
            for x in a:
                # normalize to range 0..1
                mag = round(tFromValue(win_height-x[1], 0, win_height), 3)
                if mag > .1:
                    # interpolate x (freq) between low and high bound freq
                    f = round(interpFloat(tFromValue(x[0], 0, win_width), lowBound, highBound))
                    print(f'{f}Hz -> {mag}')
            print()
        cnt += 1
        if cnt > 20:
            prnt = False

sp = Spectrum(a, size=2**12, function=printSpec)

sp.setFscaling(False)  # freq linear!

# set display/calc size
sp.width = 3000
sp.height = 2000

# freq range of analysis
lowBound = sp.lowbound * sr
highBound = sp.highbound * sr

win_width = sp.width
win_height = sp.height

s.gui(locals())


-------
Best, Hans

dennis

unread,
Mar 2, 2024, 1:53:45 PM3/2/24
to pyo-discuss

Thanks Hans, I imagined the data were more directly available, that's clear now, it's perfect !

Dennis
Reply all
Reply to author
Forward
0 new messages