![]() |
![]() ![]() ![]() ![]() ![]()
|
next newest topic | next oldest topic |
Author | Topic: RealTimeStretching | |
gustl Member |
![]() ![]() ![]() Hi there, Recently I've been thinking about TimeStretching a live input. I have come this far: Write a frame of spectral data using the memorywriter (cyclic). Use a waveshaper and a FullRamp to read out the frames continously at double speed using framelength (e.g. 256) * 0.5 for the fullramp frequency. Write that to the ram with another memorywriter. Read out with a sample module with default * 0.5 for the frequency field. Now I can do a realtime halfspeed timestretch because I'm effectively playing each frame twice. I could do the same for quarterspeed using 0.25 instead of 0.5. However I can't do any stretches in between because then the frames get out of sync and/or are just partially written. I also messed a little bit with the interpolate module to generate the frames "between" frames if you know what I mean. I think I can also figure that out for half or quarterspeed but what I really want to do is a smooth timestretch up to freezing and back (to the future? Any clues? I've been thinking about reading out the second memory writer with a waveshaper + fullramp (or another control function?) combo again but my mind is twisted now Thanks! IP: Logged | |
pete Member |
![]() ![]() ![]() Hi Gustl This is one of those things that is so easy in DSP assembly and I have a module called SOSstretch for the cappy. I think it may be one of the modules SSC will remake for paca but not sure. Anyway for the paca as it stands, the main thing to think about here is that there is a limit to how much time stretching you can do (unless you had infinite ram). Lets say we chose a max of 2048 frames and the frame length was 256. If we start with a cyclic memory writer of (256*2048) samp, then we need a reading wave shaper to match. We need to feed the index of the wave shaper with a tiny ramp and a big ramp added together, where the tiny ramp is 1/2048 in size and running at a fix 256 samp period to match the frame rate. It has to be offset to start at zero (not a minus number) so a scale and offset module can do both the size reduction and the offset. The big ramp will move from -1 to +1 but must be staircase in shape such that it will only ever give values that equate to the first partial in the frame. By removing the 8 lowest bits from the ramp we can guarantee that the nearest/lower partial numbered one will be outputted. You can do this with a bit crusher which is simply putting the ramp through a mixer with gain set to 1/256 and then through a gain module which is set to 256, to get the ramp back to full size -1 to+1. The rate of the big ramp will be at normal speed if the period is set to (256*1048) samples , but can be slowed down to make the time stretch (or sped up if it has been slow for a while). It is probably a good idea to make an indicator on the VCS using a second big ramp fixed at (256*1048) samples period as a reference, so that it can be compared with the variable big ramp time controller and feed to a StoGC to display where you are as far as offset to real time. Don't forget to compensate for wrap around. This can be done in capytalk inside the StoGC. To do this, half the size of both ramps before subtracting one from the other and if the value goes below 0.5 add one to it, other wise just output the value. Interpolating between frames is a bit harder but the general idea is to have two waveshapers ones index offset by one frame (+1/1048). Then by subtracting the bit crushed big ramp from the un bit crushed big ramp and scaling it up to a range of 0 to 1. You can then use it to control a sample rate interpolator (as used in the sample rate smoother we did before) to interpolate between the two waveshapers outputs. The only problem is the wrap around that happens when the big ramp reaches +1. We had sample rate wrap around mixers for the capybara in pete's DSP code that could have dealt with this, but not in the paca. I've posted some sample rate wrap around sounds for pacarana but I can't guarantee their integrity. I hope this makes sense. IP: Logged | |
gustl Member |
![]() ![]() ![]()
quote: I guess it's easy, actually there's nothing too special about it. Maybe there's no need for a remake as one can do it with the modules available.
quote: I already thought about the limit. Adding 2 ramps is very clever ![]() Anyway I tried to do that but the spectrum will slowly drift when using a big ramp to read out. I've attached a simple example. Seems like a bug to me?
quote: I see. Wouldn't a sampleAndHold of 256 samp also work?
quote: I had this in mind, thanks! There seems to be a typo here, you mean (256*2048) not (256*1048) right?
quote: I remember having a SR Interpolator around, just need to find it ![]() Except from the drifting I guess it would work that way! Thanks! IP: Logged | |
pete Member |
![]() ![]() ![]() Hi Gustl I don't have a pacarana at the moment so can't check the drifting but try one extra or one less sample in the number of samples in the writer and see if it pulls it in?
I've just realised that removing the 8 lowest bits won't guarantee a frame edge. To do that we need to remove a lot more of the lower bits to ensure that there are only 2048 possible results/values from the big ramp, and every one of those values will be the frame edge in RAM. In other words we need to leave only the 11 MSbits, and if the paca is using 32 bit we need to remove 21 of the lower bits. This will need some experimentation. A 256 sample and hold could be used here in addition so as to stop the jump between frames mid frame. Your correct it is a typo and your guess is right. Actually I've got the interpolating a bit wrong. This would need an additional sample and hold at 256 samp to lock the stair case at a fixed frame for the duration of the frame. IP: Logged | |
gustl Member |
![]() ![]() ![]() Hi Pete, I'll check that tomorrow, hope it removes the drifting! You're right, I haven't thought about changing the frequency of the big ramp. It only works as long as I'm using the big ramp at (256*2048) samp hz. One way would be to record the big ramp with a sampleAndHold (256 samp) with a memorywriter (not cyclic) and use that as a wavetable for another oscillator with interpolation unchecked. Definitely some sampleAndHolds at 256 samp need to be used to avoid mid-frame jumps and/or interpolation. BTW I found the SR interpolate Thank you! Your posts are really helpful - and totally make sense IP: Logged | |
pete Member |
![]() ![]() ![]() Recording the processed big ramp is a good idea and to save processing you could record it to disc play it back with a looped sample player (if you can turn interpolate off that is. May be this is where the frame sync delay is needed? IP: Logged | |
pete Member |
![]() ![]() ![]() BTW you may find mid frame jump is not as bad as it seems (in many cases). IP: Logged | |
gustl Member |
![]() ![]() ![]() The closest I get without drifting is by adding 97 samp to the big ramp's frequency. But still it is drifting, you can hear it when you use a synthetic spectrum (some killer sounds BTW ![]() ![]() About the interpolation: I think it is the other way around, I have to subtract the un-bitcrushed from the bit-crushed. Also there's no need for wrapping [This message has been edited by gustl (edited 27 January 2015).] IP: Logged | |
pete Member |
![]() ![]() ![]() May be the ramp is exactly on the border between the samples and randomly selects either one. You may need to subtract half of 1/(256*2048) to get them more central or just adjust the gain of the big ramp or the small ramp by a tiny tiny amount. How does it drift. Does it come back in sync after a (256*2048) cycle? i don't know how you are going to get around the wrapping problem as the interpolation needs to be done on neighbouring frames, so one frame after reaching the top of the big staircase you are interpolating between two frames that are at opposite ends of the ramp? Delaying the big ramp won't have the same effect as you may want to interpolate such a slow movement that five consecutive frames could all be using the same pair of frames to interpolate between. IP: Logged | |
gustl Member |
![]() ![]() ![]() Maybe adjusting the gain a little bit helps, I'll try that. I don't think it can be solved by subtracting or adding something to the frequency of the ramp because it is drifting but always comes back in sync after 1 cycle of (256*2048) samp. So I think overall it is in sync. Right? Oh, now I see why I need the wrapping! I haven't thought that through because I'm still struggling with the drift. I think I can do that with your SRWrapModules. I've looked at them today and except for the equality bug everything is fine! Have you tried using the Waveshaper for SR wrapping? Thanks! IP: Logged | |
pete Member |
![]() ![]() ![]() No you don't want to add or subtract from the frequency as that is correct nut you probably need to add / subtract or multiply to the ramp output itself, levels not frequency. IP: Logged | |
gustl Member |
![]() ![]() ![]() Alright, let's see if that works! Thanks! IP: Logged |
All times are CT (US) | next newest topic | next oldest topic |
![]() ![]() |
This forum is provided solely for the support and edification of the customers of Symbolic Sound Corporation.