• jameslo

    @hollandmusictech Maybe you could turn the envelope subpatch into an abstraction (i.e. save it in its own file) and then use arguments to the abstraction? Even more conveniently you could use [clone] to replicate each abstraction and then use $1 (the clone identifier) as the unique suffix?

    posted in technical issues read more
  • jameslo

    @whale-av @ddw_music I've written assembler for at least 3 different processors and I remember all of them being easier to learn than Pd due to their regularity, completeness, consistency, and sometimes orthogonality, but I was also way younger, in my 20s. Regardless, I don't think any of it is deep knowledge, just interchangeable arcana. Programming in the abstract, transcending any particular language, is a substantial thing though. I wonder if @ddw_music is trying to teach that to students who don't view it as their primary objective, using a language that's particularly bad at conveying it? No offense intended, just a sympathetic question.

    posted in technical issues read more
  • jameslo

    @vobb Here's a version with only the latency incurred by the FFT window, see what you think. I added the ability to change window sizes on the fly and did the pitch shifting in a delay line instead.
    pitch shifting to match FFT f0 v3.pd

    Screenshot 2022-05-18 130211.png
    (I revised this post, too many mistakes in the last one)

    posted in technical issues read more
  • jameslo

    @vobb If you can tolerate a little latency, maybe you could turn the problem around and instead pitch shift the signal down so that its period is the same as the next larger power-of-2 FFT frame?
    pitch shifting to match FFT f0.pd

    posted in technical issues read more
  • jameslo

    @ddw_music By "straightforward" I don't mean to say that everything's convenient, only that the complications aren't rocket science. I think of it like picking crab meat--potentially annoying, but anyone can do it (and will do it well if they like crab enough). But maybe I'm wrong, gimme examples.

    I'll start with ipoke~.c which is really simple because it only consists of loops and branching. ipoke~.c
    ipoke~ port.png

    In section 1 you can see the algorithm processing each sample of the audio and position vector in turn, and I decided to hard-code 64 sample blocks to reduce the number of things that I could screw up. Section 2 is a simple branch based on a test, which you could translate as a [select] or [route] among other ways. To make it run AFAP I think the author avoided function calls in favor of nested if-then-else statements, but to me they're hard to read and understand so I made sections 3 and 4 subpatches, which are like subroutines in that they hide distracting details. (No disrespect to the author implied--the code is beautifully formatted and commented) Finally, if you can find the end of that first if-then-else you will see that there is some post processing for both cases--the current index is copied into the last index in preparation for the next iteration. That's section 5.

    Porting loops is just a little complicated by the fact that Pd only has one looping construct with which to make for, while, and do-while loops. Pd is kind of spartan that way.

    Moving on to recursion, if you've ever programmed in assembler, you'd know exactly what to do because assembler doesn't have function calls. If you want them you have to make them yourself or write a macro to generate them. The way I learned is to start by pushing the address of the next instruction after the call, then push the function arguments, and then jump to the beginning of the function code. The function code then can pop args off the stack (or just read them in place), and to return it simply jumps to the return address that the caller pushed on the stack and restores the stack to its original state.

    Since there's no return mechanism in Pd (@ddw_music pondered that earlier in this forum) we just need to push and pop the arguments at the appropriate points. Here's my port of quicksort: quicksort hoare.pd
    quicksort port.png

    First, look at the circled Pd section in the upper right. That's the top call of quicksort(). You can see I'm pushing the low and high indexes of the entire array, and then banging the quicksort graph--that's how you "call" that Pd function with args. Section 1 is the entry into the function--it gets its arguments from the stack and then proceeds with its processing. Phrases 2 and 3 are the "tail recursion" calls, and since their order doesn't matter, I didn't use a [trigger] on the output of [pd partition]. First, the partitioned boundaries are pushed for each recursive call, and then we just let [until] bang the quicksort graph again. When there are no more args on the stack, there are no more recursive calls to process, and so we bang "done" to stop [until]. Rewriting tail recursion as iteration is one of those exercises they give CS undergrads.

    If you can guarantee that the recursion is very shallow, then you can simply use message feedback to implement it, but the way I just demonstrated is full-strength; the recursive depth is limited only by the maximum list length.

    So in both cases you can see that I'm just creating equivalent graphs in Pd on the right for the procedural textual code on the left. No refactoring, no use of special Pd facilities, no particular creative insight into the algorithms.

    posted in technical issues read more
  • jameslo

    @Johnny-Mauser What about the serial port stuff like baud rate, start & stop bits, etc? Is that all set to what the camera expects? Do you have the right port #?

    posted in technical issues read more
  • jameslo

    @whale-av I'm dying to show you how straightforward it is to port procedural algorithms to Pd but I want to enjoy your admiration a little longer :)

    posted in technical issues read more
  • jameslo

    @Johnny-Mauser If it's just those 7 numbers you need to convert to decimal, why not just Google it? Or if you are on Windows 10, you can use the built-in calculator in programmer mode, select hex, type in the number, and read out the decimal representation.

    posted in technical issues read more
  • jameslo

    @whale-av Thank you sir, I am literally counting down the minutes.

    PS I've tried several different "optimizations" of vipoke~ and they all either run even more slowly or are inexplicably broken. Externals clearly exist for a reason.

    posted in technical issues read more
  • jameslo

    @oid Ha! I should've seen that coming. In addition to being old, I only have access to ancient synths.... :)

    posted in technical issues read more

Internal error.

Oops! Looks like something went wrong!