# Plotting Csound data in Python

**URL:** <https://forum.csound.com/t/plotting-csound-data-in-python/834>\
**Category:** General\
**Created:** [September 7, 2022, 4:37am UTC](https://forum.csound.com/t/plotting-csound-data-in-python/834 "2022-09-07T04:37:14Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![JasonHallen](https://forum.csound.com/user_avatar/forum.csound.com/jasonhallen/32/32_2.png) [@JasonHallen](https://forum.csound.com/u/JasonHallen)\
**Post date:** [September 7, 2022, 4:37am UTC](https://forum.csound.com/t/plotting-csound-data-in-python/834/1 "2022-09-07T04:37:14Z")

</div>

Hi all,

I’m working with PyQt5 to make a GUI for a Csound instrument, and I’m looking for a good solution for plotting real-time audio signal data. Plotting the waveform of a microphone input is an example.

It appears I have the options of either 1) pulling the microphone signal data out of Csound into Python for plotting or 2) using a Python package like [PyAudio](https://people.csail.mit.edu/hubert/pyaudio/docs/) or [sounddevice](https://python-sounddevice.readthedocs.io/en/0.4.5/) to pull data directly from the system audio inputs.

For those of you with experience making Csound GUIs, which of these options would you prefer and why?

Thanks!  
Jason

---

<div class="post-metadata">

**Author:** ![rory](https://forum.csound.com/user_avatar/forum.csound.com/rory/32/7_2.png) [@rory](https://forum.csound.com/u/rory)\
**Post date:** [September 9, 2022, 10:53am UTC](https://forum.csound.com/t/plotting-csound-data-in-python/834/2 "2022-09-09T10:53:27Z")

</div>

I’m not much of a Python guy, but I would definitely grab the data directly from Csound using [ctcsound](https://csound.com/docs/ctcsound/ctcsound-API.html). Once you have the data you can plot it any way you like. The beauty of this approach is you can plot any signal, not just that which is going to the audio devices.

---

<div class="post-metadata">

**Author:** ![JasonHallen](https://forum.csound.com/user_avatar/forum.csound.com/jasonhallen/32/32_2.png) [@JasonHallen](https://forum.csound.com/u/JasonHallen)\
**Post date:** [September 10, 2022, 8:15pm UTC](https://forum.csound.com/t/plotting-csound-data-in-python/834/3 "2022-09-10T20:15:49Z")

</div>

Thanks so much for the response, Rory. Your reasoning makes good sense. I took your suggestion and have been pulling data from Csound with ctcsound. So far I’ve been able to plot a scrolling waveform of the microphone input by with the `.controlChannel()` method. Works beautifully!

What if I wanted to plot audio data based on arrays in the current buffer rather than from `.controlChannel()`? This would give me more visualization options.

Can anyone recommend ways to do that with ctcsound running Csound in a performance thread? I know the ctcsound cookbooks offer examples of how to do various things, but I haven’t seen examples that pull data from the audio buffer to make visualizations.

Thanks!  
Jason

---

<div class="post-metadata">

**Author:** ![rory](https://forum.csound.com/user_avatar/forum.csound.com/rory/32/7_2.png) [@rory](https://forum.csound.com/u/rory)\
**Post date:** [September 12, 2022, 8:20am UTC](https://forum.csound.com/t/plotting-csound-data-in-python/834/4 "2022-09-12T08:20:00Z")

</div>

I think the best person to ask here is @fggp who wrote ctcsound 🙂

---

<div class="post-metadata">

**Author:** ![JasonHallen](https://forum.csound.com/user_avatar/forum.csound.com/jasonhallen/32/32_2.png) [@JasonHallen](https://forum.csound.com/u/JasonHallen)\
**Post date:** [September 12, 2022, 12:53pm UTC](https://forum.csound.com/t/plotting-csound-data-in-python/834/5 "2022-09-12T12:53:50Z")

</div>

Here’s an update. I’m using PyQt5 to build the GUI and [pyqtgraph](https://www.pyqtgraph.org) to handle the plotting, which is supposed to be more performant than matplotlib in a real-time context.

 ![plotting_csoud_data_in_python](https://forum.csound.com/uploads/default/original/1X/b0a4749554e67b02be6c90a5ba4735f409a8783f.png)

Above is a screenshot. The **first plot** is a scrolling waveform that pulls amplitude data out of Csound with `.controlChannel()` about 100 times/second. It works very well.

The **second plot** is also a waveform, but the amplitude data is pulled from Csound with `.inputBuffer()` about 100 times/second. It also works well, but my Csound buffer is set to 64 samples to reduce latency for live performance. As a result, a very small snippet of the waveform is displayed. It would be preferable to have a longer array of samples to display.

The **third plot** is a spectrum analysis. It uses the same `.inputBuffer()` data as plot #2 but runs an FFT calculation on it with numpy. This seems to work, although I’m not sure I’m doing it correctly because I haven’t worked with FFT and plotting before. However, I’m wondering if a 64 sample array is good for a spectrum analysis. It seems small to me. Would a larger array be preferable?

Let’s say I want access to larger continuous sample arrays but I can’t increase the buffer size for latency reasons. Is this the best option? Or maybe there’s a better way?

- Write audio arrays in Csound to an array of size 1024, for example.
- Once the 1024th sample is written to the array, send it out through a control channel.
- Start writing to the array again from the beginning. Send out when full again. Repeat.
- In Python, periodically pull the array from the control channel and plot accordingly.

Thanks for your help!  
Jason

---

<div class="post-metadata">

**Author:** ![rory](https://forum.csound.com/user_avatar/forum.csound.com/rory/32/7_2.png) [@rory](https://forum.csound.com/u/rory)\
**Post date:** [September 12, 2022, 1:35pm UTC](https://forum.csound.com/t/plotting-csound-data-in-python/834/6 "2022-09-12T13:35:51Z")

</div>

I wouldn’t be surprised if you can access array data directly in ctcsound. I’m almost certain you can access tables, so if you keep writing the data to a table you should be able to access it in realtime.

---

<div class="post-metadata">

**Author:** ![JasonHallen](https://forum.csound.com/user_avatar/forum.csound.com/jasonhallen/32/32_2.png) [@JasonHallen](https://forum.csound.com/u/JasonHallen)\
**Post date:** [September 12, 2022, 2:49pm UTC](https://forum.csound.com/t/plotting-csound-data-in-python/834/7 "2022-09-12T14:49:23Z")

</div>

Yes, I see that there’s a `.table()` method in ctcsound that accesses the values in a table. Maybe this is a better approach:

- Create a table of size 1024, set initial values to zero.
- Every k-cycle, shift the table to the left by `ksmps` (i.e. remove the first `ksmps` values) and write the k-cycle’s audio array to the end of the table.

That means that at any given moment it’s safe for Python to access and display the table, right? My concern with the previous approach I outlined was that I’d have to be careful about when Python could access the array. If I accessed it before it was fully written I’d get discontinuous audio signal data.

Thanks,  
Jason

---

<div class="post-metadata">

**Author:** ![JasonHallen](https://forum.csound.com/user_avatar/forum.csound.com/jasonhallen/32/32_2.png) [@JasonHallen](https://forum.csound.com/u/JasonHallen)\
**Post date:** [September 13, 2022, 1:40pm UTC](https://forum.csound.com/t/plotting-csound-data-in-python/834/8 "2022-09-13T13:40:54Z")

</div>

For future reference, this approach is working very well. Here’s how I write the microphone input to the table in Csound.

```csound
sr = 44100
nchnls = 1
ksmps = 32
0dbfs = 1
gibuffer_size = 1024
gibuffer_offet = gibuffer_size - ksmps

ginput_buffer ftgen 1, 0, -gibuffer_size, 2, 0

instr 1
    amic_input inch 1
    ftslice 1, 1, ksmps
    kindex = 0
    while kindex < ksmps do
        tablew amic_input[kindex], kindex, 1, 0, gibuffer_offet
        kindex += 1
    od
endin

```

In Python I then access the table data with ctcsound’s `.table()` method. An array of 1024 samples does indeed produce much better waveform and frequency spectrum plots than the 64-sample array I was pulling from the input buffer earlier, and the plotting speed with PyQt5 and pyqtgraph is very fast.

 ![plotting_csound2](https://forum.csound.com/uploads/default/original/1X/920eab992c42d3adfbe6f5b02581fbfc515a1d18.jpeg)

Thanks for your guidance, Rory!  
Jason

---

<div class="post-metadata">

**Author:** ![rory](https://forum.csound.com/user_avatar/forum.csound.com/rory/32/7_2.png) [@rory](https://forum.csound.com/u/rory)\
**Post date:** [September 13, 2022, 2:40pm UTC](https://forum.csound.com/t/plotting-csound-data-in-python/834/9 "2022-09-13T14:40:08Z")

</div>

Looks very nice. I wish I had more time to go through the ctcsound stuff. I was following it using Victor’s book a while back and was very impressed, but Python is just not a language I have time to invest in these days ☹

---

<div class="post-metadata">

**Author:** ![JasonHallen](https://forum.csound.com/user_avatar/forum.csound.com/jasonhallen/32/32_2.png) [@JasonHallen](https://forum.csound.com/u/JasonHallen)\
**Post date:** [September 13, 2022, 3:19pm UTC](https://forum.csound.com/t/plotting-csound-data-in-python/834/10 "2022-09-13T15:19:29Z")

</div>

As a novice programmer Python is great for me, and ctcsound makes controlling Csound so accessible. I actually wish I could work in C++ because that seems to be the standard language for audio software, but the learning curve drives me away. We’ll see how much mileage I get out of Python and ctcsound. Might be all I need.

---

<div class="post-metadata">

**Author:** ![Lovre](https://forum.csound.com/letter_avatar_proxy/v4/letter/l/bbce88/32.png) [@Lovre](https://forum.csound.com/u/Lovre)\
**Post date:** [September 17, 2022, 5:45am UTC](https://forum.csound.com/t/plotting-csound-data-in-python/834/11 "2022-09-17T05:45:56Z")

</div>

I’m jumping into discussion a bit late but it is possible to access Csound input and output audio buffers directly via ctcsound using _spin()_ and _spout()_ respectfully. But using table as you did (@JasonHallen) has its own advantages I would say.

And just 2 tips for performance:

1. Drive Csound inside _CsoundPerformanceThread_ ([ctcsound/03-threading.ipynb at master · csound/ctcsound · GitHub](https://github.com/csound/ctcsound/blob/master/cookbook/03-threading.ipynb))
2. Calculate as much as you can in Csound and then use Python for plotting the results

There are some nice frontends that are a good choice for designing GUI when working with Csound ([Frontends | Csound Community](https://csound.com/frontends.html)) but this also depends on application that you are building 🙂

---

<div class="post-metadata">

**Author:** ![JasonHallen](https://forum.csound.com/user_avatar/forum.csound.com/jasonhallen/32/32_2.png) [@JasonHallen](https://forum.csound.com/u/JasonHallen)\
**Post date:** [September 17, 2022, 11:19am UTC](https://forum.csound.com/t/plotting-csound-data-in-python/834/12 "2022-09-17T11:19:42Z")

</div>

Hi Lovre,

Thanks for chiming in! It’s nice to have discussion here.

- I had tried using `.spin()` and `.spout()` as well, but in my case those have a size of 32 samples, which is still too small for what I wanted to do. Creating an internal buffer of continuous audio data of whatever size I choose was the best solution I could think of, but I’m still open to other solutions!

- Yes, `CsoundPerformanceThread` is crucial in my case because I’m building a GUI for real-time interaction with Csound and need to run Csound in a non-blocking way.

- For your second point, I’m currently calculating the FFT with [SciPy](https://scipy.org) in Python, so it may be faster to calculate the FFT in Csound and pull that data into Python. I’ll look into that. For now, my Python GUI is running really fast. I’m getting just under 60 frames per second with the plotting. However, we’ll see how fast the program is once the complexity grows. I expect to run into speed issues down the line.

- I’ve worked a lot with CsoundQt and Cabbage in the past and love them. Especially for building GUIs Cabbage is incredible. Plus, Rory is the patron saint of Csound newbies and has been so helpful to me, this thread being no exception. In my case I’ve switched to building my own GUIs for complete control and flexibility. And also as an exercise in learning more about programming and application design.

Thanks!  
Jason
