[Csnd] 'wrap around' looping with flooper2
Date | 2023-09-14 15:25 |
From | Philipp Neumann |
Subject | [Csnd] 'wrap around' looping with flooper2 |
Hello everybody! I’m working on a little instrument and i have some problems with it. More or less a question if this functioning with flooper2 or not: i want to to have flexible control over the loopstart point and loopend point. flooper2 seems to be the right opcode for this. i introduced the variable kLoopSize which multiplies the soundfile length with a factor between 0.1 and 1. this is then added to the loopstart point to define the loopend point. to keep these numbers in range i working with the modulo operation. so from time to time the loopstart point is higher then the loopend point. and it seems like flooper2 doesn’t like it like this. i call whit wrap around looping. is flooper2 not capable of doing this? or is there a problem with my code? Greetings, Philipp |
Date | 2023-09-14 15:58 |
From | "Jeanette C." |
Subject | Re: [Csnd] 'wrap around' looping with flooper2 |
Hi Philipp! Sep 14 2023, Philipp Neumann has written: ... > so from time to time the loopstart point is higher then the loopend point. and it seems like flooper2 doesn’t like it like this. If you want looping like that, flooper2 might not be your opcode. AFAIK it will loop from a start point (early) to an endpoint (late). You can use one of the table opcodes (table, tablei, table3, ...). You would have to manage your own crossfading then, but they can wrap around. If you read a file with GEN01 you can get all the information you need. With table opcodes, you best read one audio channel into one table. You can then use ftsr (find the samplerate) and nsamp (the number of samples/ table length) and then calculate the time of the audiofile. A table can be read by a phasor, which uses a frequency. Well Frequency = 1/duration of file. Then you can add an offset to your phasor and scale the phasor itself. The offset is your starting point, the scaling of the phasor tells you how much of the table is read. If you have 1000 sample in your table aPhasor * 1000 will read the whole table. That can be scaled with a factor between .1 and 1. The offset (loop start) in seconds must be multiplied by the tables samplerate. This approach should work to loop one audio channel without crossfade. If you want crossfades, you could loop through the table in parallel with a slight offset. Take into acount the crossfade time. There maybe better solutions. There are oscillators particularly geared towards samle reading, allowing even stereo tables. HTH. Best wishes, Jeanette -- * Website: http://juliencoder.de - for summer is a state of sound * Youtube: https://www.youtube.com/channel/UCMS4rfGrTwz8W7jhC1Jnv7g * Audiobombs: https://www.audiobombs.com/users/jeanette_c * GitHub: https://github.com/jeanette-c If only I could trade the fancy cars For a chance today, it's incomparable <3 (Britney Spears) 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 |
Date | 2023-09-14 18:20 |
From | Philipp Neumann |
Subject | Re: [Csnd] 'wrap around' looping with flooper2 |
Thanks, Jeanette! This one works perfectly fine now! Now i’m asking how to implement a windowing function to eleminate clicks while looping. Can someone help me a give me a hint? |
Date | 2023-09-14 21:03 |
From | "Jeanette C." |
Subject | Re: [Csnd] 'wrap around' looping with flooper2 |
Hi Philipp, a classic windowing function may not help. but perhaps construct a phasor of the same frequency, though just scheduled 0-1, i.e. the normal phasor output, and let it read a linear (GEN07) table, or something similar, that starts with a very short ramp up and ends with a very short ramp down. Not ideal, because when you change the frequency, i.e. the amount of the file you play, the fade time will change. I can't think of anything else though. If you adjust all the scaling and offsetting of your current phasor in a separate statement, you can even use the same phasor. Otherwise, if you can think of ways to do the proper calculations, you might try loopseg? Or if you can manage to set off triggers at the right time, you could use triglinseg. If you use a syncphasor (with 0 input for its sync input), you can get one trigger when the phasor starts at 0. HTH. Best wishes, Jeanette -- * Website: http://juliencoder.de - for summer is a state of sound * Youtube: https://www.youtube.com/channel/UCMS4rfGrTwz8W7jhC1Jnv7g * Audiobombs: https://www.audiobombs.com/users/jeanette_c * GitHub: https://github.com/jeanette-c Can't make you love me I'm just a girl with a crush on you <3 (Britney Spears) 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 |
Date | 2023-09-15 08:15 |
From | Philipp Neumann |
Subject | Re: [Csnd] 'wrap around' looping with flooper2 |
I guess this is the way to do it and i hope i calculated the speed of the window phasor correctly. It sounds right to me. Maybe someone want’s to try it out? Now i’m at the point where i want to avoid these clicking sounds when i change the reading offset or loopsize. I think they occur because i’m changing the values during the playback. So maybe i will have to implement the right time for updating the values. E.g. when the phasor is at 0. Or is there a other solution? opcode sndfl_looper, aaa, Skkkii SFile, kSpeed, kLoopStart, kLoopSize, iStereoOffset, iWndwFt xin ;; read data from soundfile iSndflSec filelen SFile iSndflSr filesr SFile iSndflSamps = iSndflSec*iSndflSr ;; create the tables for the soundfile iSndflNumChnls filenchnls SFile if iSndflNumChnls == 1 then iSndflTbl1 ftgen 0,0,0,1,SFile,0,0,1 iSndflTbl2 = iSndflTbl1 elseif iSndflNumChnls == 2 then iSndflTbl1 ftgen 0,0,0,1,SFile,0,0,1 iSndflTbl2 ftgen 0,0,0,1,SFile,0,0,2 endif ;; parameter for the table reading kSpeed = kSpeed kStart = (kLoopStart*iSndflSamps) kSize = kLoopSize*iSndflSamps kPhasorSpeed = kSpeed/(kSize/iSndflSr) aIndex1 phasor kPhasorSpeed aIndex2 phasor kPhasorSpeed,iStereoOffset aSndfl1 table3 (aIndex1*kSize)+kStart,iSndflTbl1,0,0,1 aSndfl2 table3 (aIndex2*kSize)+kStart,iSndflTbl2,0,0,1 aWin1 table3 aIndex1,iWndwFt,1 aWin2 table3 aIndex2,iWndwFt,1 ;; output aSndfl1 *= aWin1 aSndfl2 *= aWin2 xout aIndex1,aSndfl1,aSndfl2 endop > Am 14.09.2023 um 22:03 schrieb Jeanette C. |
Date | 2023-09-15 08:38 |
From | "Jeanette C." |
Subject | Re: [Csnd] 'wrap around' looping with flooper2 |
Hi Philipp, that's something I thought about yesterday night. If you use a syncphasor to go through your table, it will set off a sync impulse in one of its two outputs. You can use that to allow changes. You might have changes at any time to the variables you have and then at this sync point, copy them to something like kRealLoopStart and kRealLoopEnd. Given that, you can now avoid the window function and use a trigger envelope like triglinseg. Because you can trigger one envelope immediately and you can delay the sync impulse with some delay opcode by the current loop length. Since you don't allow update at any time, you will know the loop length at beginning of the loop. Then you can decide on a crossfade time and maybe on the exact shape of your envelope. Tip: I like to adapt such envelope shapes by passing them through logcurve or expcurve. Best wishes, Jeanette -- * Website: http://juliencoder.de - for summer is a state of sound * Youtube: https://www.youtube.com/channel/UCMS4rfGrTwz8W7jhC1Jnv7g * Audiobombs: https://www.audiobombs.com/users/jeanette_c * GitHub: https://github.com/jeanette-c And I love the way with just one whisper You tell me everything <3 (Britney Spears) 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 |
Date | 2023-09-15 12:53 |
From | Philipp Neumann |
Subject | [Csnd] WARNING: init phase truncation - 'wrap around' looping with flooper2 |
Thanks Jeanette again! Now this works perfectly fine and i have a lot of fun! Can someone tell me what this warning means? i implemented a reinit inside the udo so i can change the phase offset of one of the phasors. WARNING: init phase truncation And feel free to use this little UDO: opcode sndfl_looper, aa, Skkkki SFile, kSpeed, kLoopStart, kLoopSize, kStereoOffset, iWndwFt xin setksmps 1 ;; read data from soundfil iSndflSec filelen SFile iSndflSr filesr SFile iSndflSamps = iSndflSec*iSndflSr ;; create the tables for the soundfile iSndflNumChnls filenchnls SFile if iSndflNumChnls == 1 then iSndflTbl1 ftgen 0,0,0,1,SFile,0,0,1 iSndflTbl2 = iSndflTbl1 elseif iSndflNumChnls == 2 then iSndflTbl1 ftgen 0,0,0,1,SFile,0,0,1 iSndflTbl2 ftgen 0,0,0,1,SFile,0,0,2 endif ;; parameter for the table reading kChange changed kStereoOffset if kChange == 1 then reinit UPDATE endif kSpeed = kSpeed kStart = (kLoopStart*iSndflSamps) kSize = kLoopSize*iSndflSamps kPhasorSpeed = kSpeed/(kSize/iSndflSr) aSyncIn init 0 aSyncOut1 init 1 aSyncOut2 init 1 kPhasorSpeed1 = (k(aSyncOut1) == 1 ? kPhasorSpeed : kPhasorSpeed1) kPhasorSpeed2 = (k(aSyncOut2) == 1 ? kPhasorSpeed : kPhasorSpeed2) UPDATE: aIndex1,aSyncOut1 syncphasor kPhasorSpeed1,aSyncIn aIndex2,aSyncOut2 syncphasor kPhasorSpeed2,aSyncIn,i(kStereoOffset) kSize1 = (k(aSyncOut1) == 1 ? kSize : kSize1) kSize2 = (k(aSyncOut2) == 1 ? kSize : kSize2) kStart1 = (k(aSyncOut1) == 1 ? kStart : kStart1) kStart2 = (k(aSyncOut2) == 1 ? kStart : kStart2) aSndfl1 table3 (aIndex1*kSize1)+kStart1,iSndflTbl1,0,0,1 aSndfl2 table3 (aIndex2*kSize2)+kStart2,iSndflTbl2,0,0,1 aWin1 table3 aIndex1,iWndwFt,1 aWin2 table3 aIndex2,iWndwFt,1 ;; output aSndfl1 *= aWin1 aSndfl2 *= aWin2 xout aSndfl1,aSndfl2 endop > Am 15.09.2023 um 09:38 schrieb Jeanette C. |
Date | 2023-09-15 13:36 |
From | "Jeanette C." |
Subject | Re: [Csnd] WARNING: init phase truncation - 'wrap around' looping with flooper2 |
Hi Philipp, I can't exactly say why this is happening, I never really worked with reinit. But couldn't you solve the problem in a different way? aPhasor, aSyncOut syncphasor ... if (k(aSyncOut) == 1) then ; set new values kLoopStart = kLoopStartLiveInput ... endif With setksmps 1 you can do that and thus use standard flow control with if, while, etc. HTH. Best wishes, Jeanette -- * Website: http://juliencoder.de - for summer is a state of sound * Youtube: https://www.youtube.com/channel/UCMS4rfGrTwz8W7jhC1Jnv7g * Audiobombs: https://www.audiobombs.com/users/jeanette_c * GitHub: https://github.com/jeanette-c And when you say those words It's the sweetest thing I've ever heard <3 (Britney Spears) 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 |