banging [switch~] performs audio computations offline!
According to block~ help, if you bang [switch~] it runs one block of DSP computations, which is useful for performing computations that are more easily expressed as audio processing. Something I read (which I can't find now) left me with the impression that it runs faster than normal audio computations, i.e. as if it were in control domain. Here are some tests that confirm it, I think: switch~ bang how fast.pd
The key to this test is that all of the bangs sequenced by [t b b b b] run in the same gap between audio block computations. When [switch~] is banged, [osc~] fills array1, but you can see that element 63 of array1 changes after [switch~] is banged. Furthermore, no logical time has elapsed. So it appears that one block of audio processing has occurred between normal audio blocks. [bang~] outputs when that accelerated audio block processing is complete.
This next test takes things further and bangs [switch~] 10 times at control rate. Still, no logical time elapses, and [bang~] only outputs when all 10 bangs of [switch~] are complete. [rzero_rev~ 0] is just an arcane way of delaying by one sample, so this patch rotates the contents of array1 10 samples to the right. switch~ bang how fast2.pd
(There are better ways to rotate a table than this, but I just needed something to test with. Plus I never pass up a chance to use [rzero_rev~ 0] )
Finally, I've seen some code that sends a 1 to [switch~] and then sends 0 after one block of processing. In this test you can see that one block of audio is processed in one block of logical time, i.e. the normal way. switch~ bang how fast3.pd
But that second test suggests how you could embed arbitrary offline audio processing in a patch that's not being run with Pd's -batch flag or fast-forwarded with the fast-forward message introduced in Pd 0.51-1. Maybe it's an answer to two questions I've seen posted here: Offline analysis on a song and Insant pitch shift. Here's a patch that writes 20s of 440 Hz to a file as fast as possible (adapted from @solipp's patch for the first topic). You just compute how many blocks you need and bang away. write440File.zip
Here's another that computes the real FFT of an audio file as fast as possible: loadFFT.zip
But as with any control rate processing, if you try to do too much this way, Pd will fall behind in normal audio processing and stutter (e.g. listen to the output while running that last patch on a >1 minute file). So no free lunch, just a little subsidy.
Too many bangs or wrong note on onset for granular synth
@morpheu5 Your clones are identical. There are two incoming messages that change their operation.
[next $1( and [r $1-grainSpeed].
But [s $0-grainSpeed] sends to all of them so they all have their speed settings changed at the same time as a note is played (except that they do not without the "cursed" bang..)
With the cursed bang they are all updated for an incoming note...... but all the [vline~] are restarted causing an overload.
Without the cursed bang none are updated until the metro bangs again....... but there will be an indeterminate delay until the metro bangs........ during which time the tail of the previous grain will still be playing the previous note..... and then none of the others will be updated......
Assuming you want all the grain tails to be updated by the note but not be restarted..... (that is how it looks at the moment....... Monophonic.... if not then everything below is untrue).......
........ you will need to bang [vline~] only from the [next $1] message and modify the output of [vline~] before [tabread4~ $1-grainData] with a [x~] for all the other clones..... the value for the [x~] being the relationship between the current and the previous note.
..... And the new note needs to bang the [next $1( message...... not the [metro]
BUT you will not want the multiplier for the newly banged [vline~]....... and your clones are identical...... aargh.
SO in fact you need to get the grainSpeed into the clone as a modifier of the output of [vline~] and not as part of it's received message (so that they all change)....... and only bang one clone to restart one [vline~] at the same time through the [next $1] message..
Doing that you will only need to set the modifier as a value for the note and you will not need to mess around with relative values between notes.......
I think that is it in summary.....
David.
Purr Data GSoC and Dictionaries in Pd
@whale-av said:
@ingox Solving the users problem it seemed to me that Pd is seething with key/value pairs.
To be clear, I'm talking about dictionaries which are collections of key/value pairs. You can use a list, a symbol or even a float as a single makeshift key/value pair, but that's different than a dictionary. (Also known as an associative array.)
The headers/tags float, symbol etc. are used extensively as key/value for message routing.
This is a flat list where the first atom of the list acts as a selector. That's definitely a powerful data structure but it isn't an associative array.
[list] permits longer value strings.
These are variable-length lists, not associative arrays.
The problem for the OP was only that a series of key/value pairs had been stored as a list and that needed splitting.... but it's not a common problem..... and luckily the key was not also a float.
The OP's problem is instructive:
- If you need to send a single key/value(s) pair somewhere in Pd, a Pd message will suffice.
- If you need to store a bunch of key/value(s) pairs as a group (like an associative array does), a
[text]
object will allow you to do that with semi-colon separated messages. The important thing here is that the semi-colon has a special syntactic meaning in Pd, so you don't have to manually parse atoms in order to fetch a "line" of text. - If you want to send a group of key/value(s) pairs downstream, or you want to keep a history of key/value(s) pair groups, you have to start building your own solution and manually parsing Pd messages, which is a pain.
After doing a lot of front end work with Javascript in Purr Data, I can say that associative arrays help not only with number 3 but also number 2. For example, you don't have to search a Javascript object for a key-- you just append the key name after a "." and it spits out the value.
It may be that number 3 isn't so common in Pd-- I'm not sure tbh. But the design of the OP's data storage thingy doesn't look unreasonable. It may just be that those of us used to Pd's limitations tend to work around this problem from the outset.
The old [moonlib/slist] shared keys throughout a patch.
I used to use [slist] extensively as a dictionary, loading it from text files as necessary.
I'll have to play around with that one-- I'm not entirely sure what it does yet.
Keys are already a fundamental part of message passing/parsing.
And the correct way to store them as a string in Pd would have been with comma separators.
(I think...!! ...??)
I tend to use [foo bar, bar 1 2 3, bee 1 2 3 4 5 6 7(
as a substitute for an associative array. But again, there's a limitation because you stream each message separately. E.g., if you have a situation where you route your "foo... bar... bee" thingy to some other part of the chain based on some condition, it's way easier to do that with a single message. But again, perhaps we're used to these workarounds and plan our object chains to deal with it.
David.
[bang~] bangs before the end of a dsp block at startup
I was hoping to use [bang~] to tell me when a 1024 sample FFT was finished so I could process the results ASAP, but it often bangs after only 64 samples when DSP is first turned on. Here's my test patch after one such run:
And here's what's inside the reblocked subpatch:
bang~runsAtTheEndOfEachDSPblock2.pd
After the first run it consistently reports 1024 as expected, but that first run usually shows 64, and only occasionally 1024. I saw 128 once, but haven't been able to reproduce it. I tried connecting the signal inlets and outlets in various ways but it didn't seem to matter. Am I overlooking something?
Update: I get similar results using [switch~]:
And the switched subpatch:
switch~ vs bang~.pd
Update #2: I added another test to the switch test and it contradicts the other two tests When viewed from inside [pd switchedSubPatch2], [bang~] happens at the right time, But if I run the original test immediately afterward, it still shows 64. There must be something about reblocking I don't understand.
switchedSubPatch2:
switch~ vs bang~.pd
Toggle with multiple inputs
Hi,
I tried to manage 2 bang with a toggle (bang 1 and bang 2). It worked fine until there are 2 more bangs (bang 3 and bang 4)
How to create a logic if the bang 3 or bang 4 is executed the next bang from of bang 1 and 2 are the opposite?
[text sequence] access wait times in 'auto' mode?
@whale-av Ah, right -- I didn't explain clearly. So maybe it's time to "begin at the beginning."
Where I'm coming from: In SuperCollider, it's easy to express the idea of an event now, with a duration of 100 ms (time until the next event), with the gate open for the first 40% of that time:
(midinote: 60, dur: 0.1, legato: 0.4)
... producing control messages (0.04 is indeed 40% of 0.1 sec):
[ 0.0, [ 9, default, 1000, 0, 1, out, 0, freq, 261.6255653006, amp, 0.1, pan, 0.0 ] ]
[ 0.04, [ 15, 1000, gate, 0 ] ]
That is, an event is conceived as a span of time, with the action occurring at the beginning of the time span.
By contrast:
reset: line 0
reset: bang
w: 100
What is the data point that should occur at the beginning of this 100 ms span?
OK, never mind, continuing...
bang: bang
d: 60
w: 200
Ohhhh... it's really 200 ms for midinote 60. But you didn't know that at the time the data came out of the left outlet. Normally we assume right to left, but at the moment of requesting the next data from the sequencer, it's actually left to right.
bang: bang
d: 62
w: 300
bang: bang
d: 64
And... (the really unfortunate flaw in this design) -- how long is 64's time span? You... don't know. It's undefined. (You can add a duration without a data value at the end -- and I'll do that for the rest of the examples -- but... I'm going to have to explain this to students in a couple of days... if there are any clever ones in the lot, they will ask "Why is this note's duration on the next line? Why do we need an extra line?")
Let's try packing them:
reset: line 0
reset: bang
bang: bang
notedur: 60 100
bang: bang
notedur: 62 200
bang: bang
notedur: 64 300
bang: bang
notedur: 64 400 (this is with "400;" at the end of the seq)
bang: bang
Now, that "looks" like what I said I wanted -- but it's misleading, because the actual amount of time between 60 100
and 62 200
is 200 ms. The notes will be too short.
reset: line 0
reset: bang
notedur: 64 100 -- "64" is leftover data
bang: bang
notedur: 60 200 -- OK, matches sound
bang: bang
notedur: 62 300 -- OK
bang: bang
notedur: 64 400 -- OK
bang: bang
So the last version is closer -- just needs a little logic to suppress the first output (which I did in the abstraction).
Then, to run it as a sequence, it just needs [t b f f] coming from the wait outlet, and one of the f's goes to [delay] --> [s go]. So the completed 40% patch (minus first-row suppression) looks like this:
I guess part of my point is that it took me almost two hours to work this out yesterday... but sequencing is a basic function of any music environment... isn't there some way to make it simpler to handle the very common musical conception of a note with a (subsequent) duration? (Pd already has exactly that conception -- [makenote] -- so, why is the sequencer at odds with [makenote]?)
hjh
Spaghettis: Yet another fork of Pure Data
@Nicolas-Danet said:
QWERTY keyboard! Does it works if you add following code?
event add <<NewObject>> <$mod-Key-1> event add <<NewMessage>> <$mod-Key-2> event add <<NewAtom>> <$mod-Key-3> event add <<NewSymbol>> <$mod-Key-4> event add <<NewComment>> <$mod-Key-5> event add <<NewBang>> <$mod-Key-6> event add <<NewToggle>> <$mod-Key-7> event add <<NewDial>> <$mod-Key-8> event add <<NewArray>> <$mod-Key-9>
There < https://github.com/Spaghettis/Spaghettis/blob/master/tcl/ui_bind.tcl#L106 >.
Yes, that worked.
Spaghettis: Yet another fork of Pure Data
QWERTY keyboard! Does it works if you add following code?
event add <<NewObject>> <$mod-Key-1>
event add <<NewMessage>> <$mod-Key-2>
event add <<NewAtom>> <$mod-Key-3>
event add <<NewSymbol>> <$mod-Key-4>
event add <<NewComment>> <$mod-Key-5>
event add <<NewBang>> <$mod-Key-6>
event add <<NewToggle>> <$mod-Key-7>
event add <<NewDial>> <$mod-Key-8>
event add <<NewArray>> <$mod-Key-9>
[pix_share_read] and [pix_share_write] under windows
@whale-av, here is a log running pd with -lib Gem -verbose.
tried both 32bit and 64bit pd 0.48-1...
tried ./Gem.m_i386 and failed
tried ./Gem.dll and failed
tried ./Gem/Gem.m_i386 and failed
tried ./Gem/Gem.dll and failed
tried ./Gem.pd and failed
tried ./Gem.pat and failed
tried ./Gem/Gem.pd and failed
tried C:/Users/Raphael Isdant/Documents/Pd/externals/Gem.m_i386 and failed
tried C:/Users/Raphael Isdant/Documents/Pd/externals/Gem.dll and failed
tried C:/Users/Raphael Isdant/Documents/Pd/externals/Gem/Gem.m_i386 and failed
tried C:/Users/Raphael Isdant/Documents/Pd/externals/Gem/Gem.dll and failed
tried C:/Users/Raphael Isdant/Documents/Pd/externals/Gem.pd and failed
tried C:/Users/Raphael Isdant/Documents/Pd/externals/Gem.pat and failed
tried C:/Users/Raphael Isdant/Documents/Pd/externals/Gem/Gem.pd and failed
tried C:/Users/Raphael Isdant/AppData/Roaming/Pd/Gem.m_i386 and failed
tried C:/Users/Raphael Isdant/AppData/Roaming/Pd/Gem.dll and failed
tried C:/Users/Raphael Isdant/AppData/Roaming/Pd/Gem/Gem.m_i386 and failed
tried C:/Users/Raphael Isdant/AppData/Roaming/Pd/Gem/Gem.dll and failed
tried C:/Users/Raphael Isdant/AppData/Roaming/Pd/Gem.pd and failed
tried C:/Users/Raphael Isdant/AppData/Roaming/Pd/Gem.pat and failed
tried C:/Users/Raphael Isdant/AppData/Roaming/Pd/Gem/Gem.pd and failed
tried C:/Program Files/Common Files/Pd/Gem.m_i386 and failed
tried C:/Program Files/Common Files/Pd/Gem.dll and failed
tried C:/Program Files/Common Files/Pd/Gem/Gem.m_i386 and failed
tried C:/Program Files/Common Files/Pd/Gem/Gem.dll and failed
tried C:/Program Files/Common Files/Pd/Gem.pd and failed
tried C:/Program Files/Common Files/Pd/Gem.pat and failed
tried C:/Program Files/Common Files/Pd/Gem/Gem.pd and failed
tried D:/pd-0.48-1.windows.64bit/extra/Gem.m_i386 and failed
tried D:/pd-0.48-1.windows.64bit/extra/Gem.dll and failed
tried D:/pd-0.48-1.windows.64bit/extra/Gem/Gem.m_i386 and failed
tried D:/pd-0.48-1.windows.64bit/extra/Gem/Gem.dll and succeeded
D:\\pd-0.48-1.windows.64bit\\extra\\Gem\\Gem.dll: couldn't load
tried D:/pd-0.48-1.windows.64bit/extra/Gem.pd and failed
tried D:/pd-0.48-1.windows.64bit/extra/Gem.pat and failed
tried D:/pd-0.48-1.windows.64bit/extra/Gem/Gem.pd and failed
tried D:/pd-0.48-1.windows.64bit/doc/5.reference/Gem.m_i386 and failed
tried D:/pd-0.48-1.windows.64bit/doc/5.reference/Gem.dll and failed
tried D:/pd-0.48-1.windows.64bit/doc/5.reference/Gem/Gem.m_i386 and failed
tried D:/pd-0.48-1.windows.64bit/doc/5.reference/Gem/Gem.dll and failed
tried D:/pd-0.48-1.windows.64bit/doc/5.reference/Gem.pd and failed
tried D:/pd-0.48-1.windows.64bit/doc/5.reference/Gem.pat and failed
tried D:/pd-0.48-1.windows.64bit/doc/5.reference/Gem/Gem.pd and failed
Gem: can't load library```
true random..............?
Here's a neat exercise that relates to hashing and cryptocurrencies:
Take the following object chain:
|
[seed $1, bang, bang, bang, bang, bang, bang, bang, bang, bang, bang, bang, bang, bang, bang, bang, bang(
|
[random 2]
|
We'll collect the output stream and use it to set the state of a 16-step rhythm sequencer.
0 equals no drum hit. 1 equals drum hit.
Now, consider that the Amen chorus might look like this in our crude sequencer:
1 0 1 0 1 0 0 1 0 1 1 0 1 1 0 1
Question: what seed value should we give to $1 so that our [random 2]
outputs the Amen chorus?