Oh oh probably shouldn’t be re-setting the buffer every processing block like index~ does?

Gotta take better look at buffer functions in sdk

like i assumed buffer_locksamples always returns same address but that assumption is worth checking

1 Like

rad rad, this is all great info for me to dive back in with. the processing block thing makes sense - that’s why we got terraces instead of slopes !

1 Like

ok ! so I have it working, but just at a specific buffer size. the test patch plays through included long sample just fine, and recording looks good so far as well.

looks like the problem was softcut needing the buffer framecount as a power of 2 (?), so here I’m just setting framecount manually and sticking with a buffer size that rounds up a bit higher (rolling with 2^23 atm). since the buffer size is set in ms in max the conversion never comes out to a rational, so I’m guessing I have to set framecount internally in samples, then just make sure the max buffer is higher.

aaaaanyway this definitely feels good enough to use - I think I will go ahead and publish !

1 Like

ah ok. if that is really the issue, then the fix is pretty easy: wrapping the buffer frame index is broken out to a utility function for exactly this reason:

change it to use a while-loop instead of a bitmask. (and bufMask_ variable should then not be needed.) (and yea, the assert we disabled would have caught this! woops)

using a bitmask is a tiny optimization that is not worth it in MSP world. (but i’m used to SuperCollider world where buffer allocation uses frames and it’s normal to use nextPowerOfTwo and bitmask tricks. sorry about that.)

but, i am not 100% convinced this is the problem really… when i tried with large buffers in MSP, i saw a very consitent artifact that didn’t just “kick in” when the buffer was wrapped.

(i’m sorry i’m armchair right now, i’m away from a Mac.)

if that works, seems like a fine workaround and definitely indicates that the wrapping func is the issue. you could just set internal framecount to the next highest power-of-two smaller than the actual buffer size:

int highestPowerof2(int n) 
{ 
    int res = 0; 
    for (int i=n; i>=1; i--) 
    { 
        // If i is a power of 2 
        if ((i & (i-1)) == 0) 
        { 
            res = i; 
            break; 
        } 
    } 
    return res; 
} 
1 Like

I’ll let this lovely response evolve and look into it some more, but for reference, the bug I was fighting actually granulated the buffer in a specific way. output was quite beautiful at times. only artifacts I noticed were clicks between those grains.

5 Likes

andrew! this rocks! can’t wait to see where this ends up.

2 Likes

kyle! no way I’m eating kimchi rn !!!

3 Likes

yeah, damn, this is gorgeous. able to pass a non-xcode-havin’ bud the max-sdk-8.0.3 folder you built all this in?

do you mean you want the broken one or the working one?? I can just send the compiled external??? will probably end up with something in the library tonight

till tonight then — :pray:

1 Like

@andrew i opened a PR with a number of fixes (and some TODOs.)

1 Like

lovely! updated top post, added a new release for the non-building, did some clearer roadmapping

if anyone did download the last version (1.0) you’ll probably want to update (aka I probably shouldn’t have made that a release w/o testing)

How difficult or different would the process be in porting Softcut to Pure Data?

should be pretty easy

Nice, I’m relatively new to Pure Data, but this may be a good way to learn about creating externals. Sorry to interrupt your thread @Andrew. :slight_smile:

haha - I feel like this would be a decent location to work on the pd external. might make sense to share the repo too. anyway I imagine there’s like 200 max external to pd external guides. I wonder if any part of the cyclone source is useful for this? or were those all manual ports?

i have a c++ template to dig up and then its just replacing the wrapper file

[update]

i added a puredata c++ template here. it’s rough and ready but should help getting started. tested on linux only here but it should be ok on other platforms.

[ https://github.com/catfact/audio-externals/tree/master/pd_cpp_template ]

haven’t worked out tabread~ style table access, never did it before.

(of course there well be better resources out there)

1 Like

anyway just a mega-appreciation post for the max port.

I’ve been experimenting today with feedback loops between multiple voices and downsamplers (which also use the source) and it’s been incredibly beautiful/inspiring/getting me out of a creative block with performance. softcut embodies so much of what I want to express.

12 Likes

Thanks @zebra for the pointer. I’ve been looking over the code as well as this repo: https://github.com/pure-data/externals-howto

So we would need to use these but not the other header files (those seem to be max specific)?

#include "m_pd.h"
#include "src/SoftCutVoice.h"
#include "src/FadeCurves.h"

The format of the Max SDK and Puredata wrappers is very similar, which makes me think I’d be better starting from scratch.

Also, would we keep the src code changes you made for Andrew’s repo?

hey sorry for late response been busy

yes, that is certainly the best resource for actually learing the PD api.

the main reason for me to make that template is just to have a simple makefile with all the right linker invocations for c++ shared lib and no addditional fuss in the build setup

yes

yes. at least some should be upstreamed also. likewise i have some changes in pipeline for norns version that should be propagated down. so it seems well past time for softcut to be factored out into its own repo, built as an external lib with an actual public header and stuff. (realistically, i don’t think i’m gonna get to that this week, but it’s not impossible.)

if things like customizing the xfade shapes is wanted that can be exposed. (bearing in mind that the tricky part is how the xfade applies to rec/pre levels. i made some posts on GH describing the issue, and the compromise i arrived at; the parameters of this scheme (call it “delayed raised-cosine”) are those exposed in FadeCurves etc.

1 Like