Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[switch~] block computation issue #2134

Closed
Lucarda opened this issue Nov 16, 2023 · 11 comments
Closed

[switch~] block computation issue #2134

Lucarda opened this issue Nov 16, 2023 · 11 comments

Comments

@Lucarda
Copy link
Contributor

Lucarda commented Nov 16, 2023

I would expect this simple patch to send a block to an array from inside a switched off and re-blocked sub-patch but there are errors in the array.

Not sure if it's legal to do one block computation via a bang to [switch~] from an [inlet~].

here's a simple example patch:

switch~bug.zip

and to put it graphically:

swich~bug

@Lucarda Lucarda changed the title [switch~] bug. [switch~] block computation issue Nov 16, 2023
@Spacechild1
Copy link
Contributor

Spacechild1 commented Nov 17, 2023

If you bang a switched off subpatch, you only force DSP computation in that subpatch (and all its subpatches). However, this does not affect DSP computation of the parent patch.

AFAICT, it is always(?) a mistake to use single-step DSP in a subpatch that exchanges audio data with an outer canvas.

@Lucarda
Copy link
Contributor Author

Lucarda commented Nov 17, 2023

I think there's a problem with [switch~]. turning DSP on or off (in the subpatch (which is legal)) gives errors also.

swich~bug2

@Spacechild1
Copy link
Contributor

Spacechild1 commented Nov 17, 2023

Ok, the actual problem is this: if a subpatch is reblocked to a larger blocksize, DSP is triggered every time the inlet~ buffer have been filled. When you send a "bang" to [switch~], you effectively force DSP right now - even if the buffers have not been filled and still contain garbage from previous cycles.

In practice this shouldn't be a problem; it doesn't really make sense to use single-step DSP with signals that come from outside the subpatch, even less so when reblocking.

This behavior could be mentioned in the help patch, but it is such an edge case that I'm not sure it's worth it. It might even cause more confusion than it would help to solve.

In danger of stating the obvious: you typically wouldn't reblock the subpatch to 4096 to compute 4096 samples; instead you would just bang 64 times in a row (64 * 64 = 4096).

turning DSP on or off (in the subpatch (which is legal)) gives errors also.

Now here you actually hit a real bug! I have opened dedicated ticket (#2136) as it is only tangentially related to this issue.

@Lucarda
Copy link
Contributor Author

Lucarda commented Nov 18, 2023

Ok, the actual problem is this: if a subpatch is reblocked to a larger blocksize, DSP is triggered every time the inlet~ buffer have been filled.

if this is correct I would exploit that and use the "correctly triggered and filled" buffer. this was my initial intention.

When you send a "bang" to [switch~], you effectively force DSP right now - even if the buffers have not been filled and still contain garbage from previous cycles.

I would want DSP to start once inlet~ was filled (as if done it via a [bang~]).

In practice this shouldn't be a problem; it doesn't really make sense to use single-step DSP with signals that come from outside the subpatch, even less so when reblocking.

say I want to reverse a bunch of 4096 samples (not a bunch of 64 samples). I would want to use single-step DSP.

This behavior could be mentioned in the help patch, but it is such an edge case that I'm not sure it's worth it. It might even cause more confusion than it would help to solve.

In danger of stating the obvious: you typically wouldn't reblock the subpatch to 4096 to compute 4096 samples; instead you would just bang 64 times in a row (64 * 64 = 4096).

but if I want to fill a 4096 array? (see above).

turning DSP on or off (in the subpatch (which is legal)) gives errors also.

Now here you actually hit a real bug! I have opened dedicated ticket (#2136) as it is only tangentially related to this issue.

thanks for looking at it.


Unneeded explanation:

I'm not at home with my computers but essentially I grabbed [tabsend~] code and inserted something I want to do in the perform routine. I need the array to be larger than a 20hz period and I need to fill 3 or 4 4096 arrays but each one 512 samples after the other (in cycles). It's a first attempt to have a pulqui~ version (high latency creation of the side-chain signal) of pulqui. I'm not sure if it will work. :)

@Spacechild1
Copy link
Contributor

I would want DSP to start once inlet~ was filled (as if done it via a [bang~]).

But then the "bang" message wouldn't be synchronous. Even worse: since you can't know the current phase, you wouldn't even know when DSP has finished.

say I want to reverse a bunch of 4096 samples (not a bunch of 64 samples). I would want to use single-step DSP.

I'm not sure you would want to use single-step DSP for this task in the first place...

but if I want to fill a 4096 array? (see above).

If you want to fill a 4096 point array with a signal from outside the subpatch, just write it to an array with [tabwrite~], and once that has finished, do your single-step DSP.

I'm tempted to close this issue as "not a bug". We could document that you can't really use input/output signals from parent canvases in single-step DSP, but for me at least that has always been obvious... @porres What do you think?


Unneeded explanation:

I would suggest writing to the Pd list and describing in detail what you want to achieve. People may come up with various solutions. All I can say is: single-step DSP in a reblocked subpatch isn't one of them :)

It's a first attempt to have a pulqui~ version (high latency creation of the side-chain signal) of pulqui. I'm not sure if it will work. :)

I might be wrong, but wouldn't that be a simple look-ahead limiter? The idea is to delay the input signal, so you can analyze it ahead of time and then apply precise compression to the delayed signal.

@Lucarda
Copy link
Contributor Author

Lucarda commented Nov 18, 2023

I'm rather confused. You seem to be saying to me avoid "single-step DSP" but then you tell me to do so:

If you want to fill a 4096 point array with a signal from outside the subpatch, just write it to an array with [tabwrite~], and once that has finished, do your single-step DSP.

I'm tempted to close this issue as "not a bug". We could document that you can't really use input/output signals from parent canvases in single-step DSP, but for me at least that has always been obvious... @porres What do you think?

I know that a bang might be out of sync but it would be nice if we can put it (force it) in sync in a way that we can use it with inlet~. this would allow us to have a perform routine at patch level. It shouldn't be so hard to support inlet~/outlet~ i think (i might be wrong).

We can close this issue anyway if there's nothing more to say :)


off-topic and not suitable for the ticket system.

I might be wrong, but wouldn't that be a simple look-ahead limiter? The idea is to delay the input signal, so you can analyze it ahead of time and then apply precise compression to the delayed signal.

yes. but here in a simple look ahead (each 4096 samples) the side-chain generation fails (or naturally breaks) at the beginning and ending of the scan. This is still unresolved. may be some overlapped arrays stuff might help.

array1 is just one sample and inlet~ has a 20hz sine fade in.

block

wave

@Spacechild1
Copy link
Contributor

Spacechild1 commented Nov 18, 2023

You seem to be saying to me avoid "single-step DSP"

I'm not sure how you got this impression. I only said that you shouldn't use reblocking where it isn't necessary.

Again, if you want to grab audio from outside the subpatch, just write it into a table with tabwrite~; this way you know exactly when the data is ready for DSP.

Reblocking is just the wrong tool for the job here. (Even if it did work, it would artificially limit yourself to power-of-two samples sizes and it would only work for a single DSP step.)

this would allow us to have a perform routine at patch level.

I'm not sure what you mean by this...

It shouldn't be so hard to support inlet~/outlet~ i think (i might be wrong).

Again, this does not work on a fundamental level because while you bang a switch~ object, the outer canvases "stand still".

@Lucarda
Copy link
Contributor Author

Lucarda commented Nov 20, 2023

I'm totally confused and I lost the 2023 argentine ballotage. I'll do a confusion transfer in reverse order.

It shouldn't be so hard to support inlet~/outlet~ i think (i might be wrong).

Again, this does not work on a fundamental level because while you bang a switch~ object, the outer canvases "stand still".

How is that? I just "switched" a sub patch.

this would allow us to have a perform routine at patch level.

I'm not sure what you mean by this...

For my example above i'll do this pseudo-code[*] in C and it will take place in the perform routine but I could do it without any C code and just using Pd objects (or Pd language):

[*]: no implementation details at all (you should understand the following (i know you do))

// 4096 block size.

do the scan of [--a+b--] 

pass [--a--] to [--c--] and [--b--] to [--a--]

play [--c--] while getting [--new b--]

EDIT: did't test this neither in C or Pd but in theory it should work on any of both.

@porres
Copy link
Contributor

porres commented Nov 20, 2023

I lost the 2023 argentine ballotage

so sorry :(

@Spacechild1
Copy link
Contributor

How is that? I just "switched" a sub patch.

Again, while you single-step DSP, the outer canvas stands still, i.e. there is nothing to get from the inlets. Reblocking is a bit of a special case in that you have access to the buffered content. However, when you find yourself triggering single-step DSP in regular intervals, you might just as well either a) use regular reblocking and do everything in the audio domain or b) just do everything in the control domain.

Anyway, to me it seems you are trying to implement a look-ahead peek limiter. This can be done entirely in the audio domain. I have the feeling you are trying to use single-step DSP for something that shouldn't require it in the first place...

Let's continue the discussion in the Pd list. I'll go ahead and close this issue now.

@Lucarda
Copy link
Contributor Author

Lucarda commented Nov 20, 2023

Ok my confusion came where I thought that on inlet~ and outlet~ we have access to the buffer t_int *w. so i took for granted that we can manipulate that at the speed of the machine (like in the perform routine).

Anyway, to me it seems you are trying to implement a look-ahead peek limiter. This can be done entirely in the audio domain. I have the feeling you are trying to use single-step DSP for something that shouldn't require it in the first place...

Ok. Well it is my first DSP object :)

Let's continue the discussion in the Pd list. I'll go ahead and close this issue now.

Thanks for any insight on the object. I'll post to the list and already move the object to this repo.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants