# Flexible reading back

**URL:** <https://forum.csound.com/t/flexible-reading-back/1558>\
**Category:** General\
**Created:** [February 26, 2024, 11:07am UTC](https://forum.csound.com/t/flexible-reading-back/1558 "2024-02-26T11:07:28Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![tjingboem](https://forum.csound.com/user_avatar/forum.csound.com/tjingboem/32/44_2.png) [@tjingboem](https://forum.csound.com/u/tjingboem)\
**Post date:** [February 26, 2024, 11:07am UTC](https://forum.csound.com/t/flexible-reading-back/1558/1 "2024-02-26T11:07:28Z")

</div>

Hi all,  
i am trying to build a generic midi data recorder and midi player.  
In the first instrument, these midi data are written to a text file in packages of 4: status (for example: controller only = 176), midi channel, CC number and value.  
Then, in a second instrument that plays back the midi data, this playback should be flexible in its playback speed. And this is the issue that i do not know how to solve…

Right now, my code is not really using real midi data, but mimicking it. When this flexible issue is resolved, i can then move on and add the midi input ports and record different controller numbers etc.

This is my code:

```csound
<CsoundSynthesizer>
<CsOptions>
; Select audio/midi flags here according to platform
-odac ;--displays ;;;realtime audio out
;-iadc ;;;uncomment -iadc if realtime audio input is needed too
; For Non-realtime ouput leave only the line below:
; -o gen02.wav -W ;;; for file output any platform
</CsOptions>
<CsInstruments>

sr = 48000 
ksmps = 128 
nchnls = 2 
0dbfs = 1 

giFt ftgen 0, 0, kr*4, -2, 0 ; kr = 375
giFtable ftgen 0, 0, kr*4, -2, 0
seed 0

instr 1 ; mimic CC midi controller

kndx init 0
;kndx linseg 0, 1, ftlen(giFt) ; move through table in 1 second
kvalue linseg 100, p3*.5, 0, p3 *.5, 100 ; 100 Hz, back to 0, up to 100
kstatus = 176 ; CC
kchan = 1 ; midi channel 1
kCC = 7 ; controller 7

tablew kstatus, kndx, giFt ; load CC
tablew kchan, kndx+1, giFt ; load midi channel
tablew kCC, kndx+2, giFt ; load controller 7
tablew int(kvalue), kndx+3, giFt ; value 0 - 127
kndx += 4
ares poscil3 .5, 100+int(kvalue) ; sine, add 100Hz and back down
outs ares, ares

krel release ; write in last k cycle
if (krel == 1) then
    ftsavek "/home/menno/MidiData2.txt", 1, 1, giFt ; write as text file to disk (k rate)
endif
endin

instr 2 ; play back

ftload "/home/menno/MidiData2.txt", 1, giFtable ; load textfile in new table (i rate)
kndx init 0
;kval0 table3 kndx, giFtable
;kval1 table3 kndx+1, giFtable
;kval2 table3 kndx+2, giFtable
kval3 table3 kndx+3, giFtable ; use only these values in vco2

;printsk "status = %d channel = %d controller = %d value = %d\n", kval0, kval1, kval2, kval3

printk2 kval3

ares vco2 .3, 100+(kval3) ; saw, add 100Hz and back down
outs ares, ares
kndx += 4
endin
</CsInstruments>
<CsScore>

i1 0 1 1 ; 1 sec.
i2 2 1 1 ; 1 sec, as recorded
i2 4 2 .5 ; trying to stretch 2 x ....
e
</CsScore>
</CsoundSynthesizer>

```

What happens now is that only the changing value of every 4th index is read; the changing value of the controller 7. How can i influence the speed of the reading back of the file, relative to p3?

---

<div class="post-metadata">

**Author:** ![joachim](https://forum.csound.com/letter_avatar_proxy/v4/letter/j/a87d85/32.png) [@joachim](https://forum.csound.com/u/joachim)\
**Post date:** [February 26, 2024, 8:05pm UTC](https://forum.csound.com/t/flexible-reading-back/1558/2 "2024-02-26T20:05:01Z")

</div>

hi menno -

if i get it right, you want to record signals in real-time which you  
then want to play back say twice as slow.

if this is correct, i think it is very hard to to with one table which  
holds four different signals. because:

when you have one signal in one table, you can just ready more slow, or  
fast, and interpolate between the values.

but if you have four signals in one table, you cannot, because you have  
to interpolate between index 0 and 4 in ignoring index 1-3.

perhaps others find a solution, but i’d recommend to either write in  
four tables, or split the interpolating table in four when you read it.

joachim

---

<div class="post-metadata">

**Author:** ![tjingboem](https://forum.csound.com/user_avatar/forum.csound.com/tjingboem/32/44_2.png) [@tjingboem](https://forum.csound.com/u/tjingboem)\
**Post date:** [February 27, 2024, 12:53pm UTC](https://forum.csound.com/t/flexible-reading-back/1558/3 "2024-02-27T12:53:13Z")

</div>

thanks, Joachim, this feedback is welcome and challenging.  
I see your point in having several tables, so one can later choose which one to do the interpolation on.  
If i were to record 3 different controllers (7, 8, 9 for example) that would mean writing 3 (x 4 midi data sets) files. Or, alternatively, write 3 files with the 4 midi data sets, and later when reading, splitting those up to 3 x 4 =12 files at i rate. Or perhaps in memory only?

Once in memory, the interpolation can begin when reading them at k-rate.

Nice puzzle this one.  
(It also shows that the Csound Midi system is not a very developed one. I am so used to programs like Reaper and Cubase that i take all for granted how this is organized. )

---

<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:** [February 27, 2024, 1:33pm UTC](https://forum.csound.com/t/flexible-reading-back/1558/4 "2024-02-27T13:33:59Z")

</div>

> [@tjingboem](#):
>
> (It also shows that the Csound Midi system is not a very developed one. I am so used to programs like Reaper and Cubase that i take all for granted how this is organized. )

This is true. Cabbage has its own [MIDI file reading opcode](https://forum.cabbageaudio.com/t/new-midi-file-opcodes/3586) that lets you read a MIDI file from disk at various speeds. I initially looked at writing them with portmidi but it looked like too much work. In the end I just used JUCE. The code is pretty simple though and could be ported to a standalone plugin opcode.

---

<div class="post-metadata">

**Author:** ![tjingboem](https://forum.csound.com/user_avatar/forum.csound.com/tjingboem/32/44_2.png) [@tjingboem](https://forum.csound.com/u/tjingboem)\
**Post date:** [February 29, 2024, 12:51pm UTC](https://forum.csound.com/t/flexible-reading-back/1558/5 "2024-02-29T12:51:36Z")

</div>

> [@rory](#):
>
> Cabbage has its own [MIDI file reading opcode](https://forum.cabbageaudio.com/t/new-midi-file-opcodes/3586) that lets you read a MIDI file from disk at various speeds. In the end I just used JUCE. The code is pretty simple though and could be ported to a standalone plugin opcode.

Understandable that you choose the most “easy” way out: the MIDI file reading through JUCE.  
But it is a pity that the Midi situation is not attacked at the most basic level, in Csound itself.  
On the other hand, i do see the lack of developers and the ones that do develop Csound, are already working hard…

Opcodes like:  
**midirecord**  
and  
**midiplay**  
…of course, MIDI2 compatible 😁
