Spectrogram csound output buffer

@TetsuyaMiwa you are right. Although Pyqtgraph should be significantly more performant then matplotlib, performance with both libraries is poor because there is another bottleneck in play. I think the slowest operation here is a cs.tableCopyOut() command. I benchedmarked it and it takes a lot of time and that time is also not deterministic. It varies from 0.05 to 3.0 seconds. This is definitely an interesting point. Does anyone know why is that?

code for benchmarking:

from timeit import default_timer as timer
.
.
    start = timer()
    cs.tableCopyOut(1,fftArray)
    end = timer()
    print(end - start)

I mean, I understand that running Csound in its own thread (a process would be maybe a more correct term here) gives a significant gain on audio performance in a cost of a more expensive communication (data input/output) between python and csound threads but those times are extreme.

On the other hand, if we run csound inside the python process we can expect audio performance issues but communication is much much faster. Here is a code how you can implement it. This code uses Matplotlib but same thing can be of course implemented with pyqtgraph also.

import ctcsound as csound
from matplotlib import pyplot as plt
from matplotlib import animation
import numpy as np
import threading

fftSize = 1024 # this needs to match gifftsiz in orc
fs = 48000 # sample rate

orc = """
0dbfs = 1
ksmps = 128

;general values for fourier transform
gifftsiz  =         1024   ; this needs to match above defined fftSize
gioverlap =         256
giwintyp  =         1 ;von hann window

;an 'empty' function table
giTable ftgen   1, 0, -(gifftsiz+2), 2, 0

instr 1
    aout	oscili 0.5, 500
	aout	*= linseg(0, 1, 1, p3-1, 0)

    out aout

    fsig	pvsanal aout, gifftsiz, gioverlap, gifftsiz, giwintyp
    kflag pvsftw fsig, giTable
endin
"""

def csound_function(name):
    cs = csound.Csound()
    cs.setOption('-odac')
    cs.compileOrc(orc)
    sco = "i1 0 5\n" 
    cs.readScore(sco)
    cs.start()

    while not cs.performKsmps():
        cs.tableCopyOut(1,fftArray)

    cs.reset()


x = threading.Thread(target=csound_function, args=(1,))
x.start()


fig, ax = plt.subplots()
ax.set(xlim=(0,fs/2), ylim=(0,1))
line, = ax.plot([], [], lw=2)

f_axis_delta = fs/fftSize
f_axis = np.arange(0,fs/2 + f_axis_delta,f_axis_delta)
fftArray = np.zeros(fftSize + 2) # array length must be fftSize+2

def animate(i, f_axis_cs=[], amp_vals=[]):
    amp_vals = fftArray[0::2] # fft amplitude values
    line.set_data(f_axis, amp_vals)


anim = animation.FuncAnimation(fig, animate, interval=100)
plt.show()

@TetsuyaMiwa Please post your code directly whenever possible instead of uploading files, especially zip files (in some forums this is explicitly forbidden), as they can contain many surprises :bug: :fly: :worm:

@Lovre Thank you for the important update - threading. It is an element not found in pure Csound programming.

My apologies for file attachment.