Recursive programming in MSP. Impossible?
In the enclosed patch, a delayed audio signal is added to the input.
Every attempt to implement such a structure fails. Tha audio network simply
don't work. Cut the feedback wire and you hear the oscillator again. Why?
--
Jean-Yves Bernier
http://www.pescadoo.net/
use send~ + receive~ or insert pause~ in the feedback loop...
Try this patch. I think it has to do with vector processing. You'll have to
avoid msp is processing the output of an audio vector with the same vector,
creating a endless processing loop. It's something like the "stack overflow"
for msp. Maybe someone can give a proper technical explanation;-)
t_
hi Junior,
You said pause~ ?
I didn't knew that object.
Philippe.
hi,
it's in the percolate bundle. you don't really need it, a
send~/receive~pair does the same thing, namely introducing a small
delay to prevent msp from blocking.
At 12:33 +0100 28/12/2005, Thijs Koerselman wrote:
> Try this patch.
For some unknown reason, I can't open this text file in Max (4.1).
> You'll have to avoid msp is processing the output of an audio vector
> with the same vector, creating a endless processing loop.
It is not an endless loop, it is recursive programming. I'm computing
biphase codes from NRZ and clock. The coder and decoder have
forward/backward terms (similar to a recursive filter). I guess MSP can't
compile an audio network with loops.
--
Jean-Yves Bernier
http://www.pescadoo.net/
At 14:11 +0100 28/12/2005, junior wrote:
>it's in the percolate bundle. you don't really need it, a
>send~/receive~pair does the same thing, namely introducing a small
>delay to prevent msp from blocking.
Yes, I've noticed that send~/receive~ works. But they add an extra delay
wich depends on scheduling (I think) and the phase relationship is lost.
--
Jean-Yves Bernier
http://www.pescadoo.net/
hi Jean-Yves,
add
max v2;
at the beginning
and
at the end of the text and you will be able to open the patch...
Philippe.
At 15:18 +0100 28/12/2005, Peter Castine wrote:
>In terms of DSP, what you have *is* a loop. It's a feedback loop.
>Period.
Ok. This is what I suspected.
>Googling, for instance, on
> loop "no audio" site:synthesisters.com
I found this one:
>1) in order to get the 1 sample delay needed for your filter in MSP,
>you need to set the signal vectorsize to 1, then use a send~ and
>receive~ pair to copy and delay the output signal y[n-1] back to the
>top of the dsp-chain.
So, a pair of send~/receive~ delays for exactly 'vectorsize' samples. This
is a workaround for my problem. Thanks.
--
Jean-Yves Bernier
http://www.pescadoo.net/
hi all
stupid question: how much cpu utilization could change using a
subpatcher and not an external for the same content?
thank you all
--
homepage: http://franz.impattosonoro.it
e-mail: franzrosati@yahoo.it
When I have to do things that deal with samples themselves (and I
need to pop vectors apart) I start thinking about java and or c
externals.
You could probably bang out a java extern that does exactly what you
want way faster than hacking your way through msp.
I use msp for all non-sample based stuff, i.e. milliseconds or stuff
that is vector-size agnostic.
_Mark
> I'm computing
> biphase codes from NRZ and clock. The coder and decoder have
> forward/backward terms (similar to a recursive filter).
For the encoder going from NRZ/clock to biphase, how about using
cycle~ in combination with a custom buffer~ and a *~ object that flips
its argument between -1 and 1 depending on that input? And if you
have clock for the decoder, how about a multiplication of the input
with a similar custom cycle~ running in sync, followed by a
thresholder and a factor of 2 downsampled poly~ to extract the proper
samples? These techniques do not require feedback, although if you do
not have clock for the decoding a PLL requires feedback.
Ben
At 0:33 -0800 29/12/2005, Ben Nevile wrote:
>These techniques do not require feedback
Biphase said "L" (Level) transmitter does not require feedback (it's a XOR
between NRZ and clock). But receiver does, as other varieties of biphase
(biphase "mark", differential biphase). See
http://zone.ni.com/devzone/conceptd.nsf/2d17d611efb58b228625 67a9006ffe76/9ce4dbed595b119a86256e6f00704a7a/Content3/0.A90 6?OpenElement&FieldElemFormat=gif
level during 1's of message depends on level at end of _previous_ bit. LTC
is biphase-M, as is the code I'm dealing with, a Bassgen dissolve unit
audio signal.
>if you do not have clock for the decoding a PLL requires feedback.
Yes ;(
--
Jean-Yves Bernier
http://www.pescadoo.net/
> level during 1's of message depends on level at end of _previous_ bit.
There is a transition in the middle of a 1, but no transition in the
middle of a 0, so with a locked clock I don't understand why the
decoding would require feedback. A phase-locked loop requires
feedback, but if you're willing to lock "slowly" the feedback does not
have to be single-sample.
Ben
Re: [max-msp] Recursive programming in MSP.
Impossible
At 11:10 -0800 30/12/2005, Ben Nevile wrote:
>There is a transition in the middle of a 1, but no
transition in the
>middle of a 0, so with a locked clock I don't understand why
the
>decoding would require feedback.
Because MSP is not C, and you can't express such a thing as
"flip at the middle of bit cell if message is one". But
there is an arithmetic form, in ascii art:
> Because MSP is not C, and you can't express such a thing as "flip at the
> middle of bit cell if message is one".
I present the below patch as proof that you can express such a thing
in MSP. It contains both a biphase-M encoder and decoder programmed
completely in MSP. Some important ingredients are selector~, +=~,
count~, delay~, and a loose send~ and receive~ feedback loop to keep
the accumulator from overflowing. The graphing of the results is done
using Jitter, so if you don't have version 1.5 installed you may want
to download and install it (it will work free for 30 days.)
Ben
At 12:14 -0800 31/12/2005, Ben Nevile wrote:
>I present the below patch as proof that you can express such a thing
>in MSP. It contains both a biphase-M encoder and decoder programmed
>completely in MSP. Some important ingredients are selector~, +=~,
>count~, delay~, and a loose send~ and receive~ feedback loop to keep
>the accumulator from overflowing. The graphing of the results is done
>using Jitter, so if you don't have version 1.5 installed you may want
>to download and install it (it will work free for 30 days.)
Ben,
I'm extremely interested in looking at your solution but your patch, as
many other patches presented here, are Max 4.5.5 clipboards
("copy-as-text").
At 12:02 +0200 07/10/2005, Jeremy Bernstein wrote:
>This new format is the result of the copy-as-text feature in Max
>4.5.5 - patches pasted like this can only be opened in Max 4.5.5 or
>later (without a lot of work).
I'm using Max 4.1 since I'm bound to OS/9 for a while. Installing 4.5.5
requires me to go on an OS/X machine (with no audio and no MIDI), asking
for a new authorization or being disabled again in 30 days.
In the meantime, could you please "save as text"?
>The graphing of the results is done using Jitter, so if you don't have
>version 1.5
>installed you may want to download and install it (it will work free for
>30 days.)
I graph with poke~ing to a buffer linked to a waveform display. Think it
can do it. I also can dac~ to a real multi-trace scope.
Happy new year to all.
--
Jean-Yves Bernier
http://www.pescadoo.net/
Okay Jean-Yves, below is the patch saved-as-text. Enjoy!
Ben
At 10:15 -0800 01/01/2006, Ben Nevile wrote:
>Okay Jean-Yves, below is the patch saved-as-text. Enjoy!
Thanks, Ben.
I'm still de-engineering your patch. Tricky! The accumulator is a
five-state logic, is it?
Your bit clock is half the audio sample rate. I use a different technique
in order to match various bit rates. Due to tapin~/tapout~ use, I'm limited
to the set of periods equal to VectorSize/SampleFreq. For example, 64/44.1
= 1.45mS, 32/44.1 = 0.72mS, and it is unlikely that an external device will
sync. It's even less likely to sync on an external signal, assuming that
the PLL problem had been solved, wich is a project left for a next rainy
week-end, if any. So, I end with yet another proof of concept, but nothing
really usable.
Let me, in turn, present some patches. In order to keep this mail short,
rendez-vous at .
Figure 1 is the arithmetic (boolean), rather than algorithmic description
of the coder and decoder. Two kinds of biphase code are represented :
"level" and differential. They are derived from the definition:
1 -> a'(i) = -a'(i-1), a''(i) = -a'(i)
0 -> a'(i) = +a'(i-1), a''(i) = -a'(i)
where a', a'' are the two consecutive voltage values in a bit cell.
biphase-M is slightly different, i've not finished the decoder.
Some background : I have to deal with a variety of audio-visual tape codes
(Simda, Bassgen, Dataton...). The idea is to recover old programs ans
transcode them in a standard protocole, as MIDI or Kodak P-bus. Some are
FM, some are baseband.
It was really simple for FM codes and was first implemented using N.I.
Reaktor. I thank Mac/MSP was more suitable. Since SMPTE LTC is biphase-M,
is well documented and available in the studio, the program should pass
the LTC test (some a/v codes are very close to LTC).
The test patch would work for 3 codes, generate and recover a known cyclic
bit pattern (and known matching line codes). I use a buffer~ between Max
and MSP. bits2buf loads the pattern in the buffer. buf2NRZ~ reads this
buffer (index~). CLK~ is a simple train~.
It works "sometimes". When the DSP starts, you get randomly one of three
conditions for the recovered NRZ:
- line code (wrong)
- inverted NRZ (wrong)
- original NRZ (good)
This, I think, is due to the way tapin~/tapout~ are initialized or
flushed. Display is with scope~ and is readable with only a small set of
parameters. preset~ #1 works well with a 128 samples vector size. It's
better to reload the patch if you change the vector size.
Enjoy.
--
Jean-Yves Bernier
http://www.pescadoo.net/
> Your bit clock is half the audio sample rate. I use a different technique
> in order to match various bit rates. Due to tapin~/tapout~ use, I'm limited
> to the set of periods equal to VectorSize/SampleFreq...
Hm. I don't think I understand why your project has to be done in a
real-time mode. It seems to me an easier method would be to record~
all of the data and then analyze off-line. The first stage of this
analysis would probably be a resampling of the data down to its
"natural" sampling rate. You could then use your MSP network to
decode the data (in real time, if you liked.)
Ben
At 18:27 -0800 04/01/2006, Ben Nevile wrote:
[Changing the title]
>Hm. I don't think I understand why your project has to be done in a
>real-time mode. It seems to me an easier method would be to record~
>all of the data and then analyze off-line.
It has not.
>The first stage of this analysis would probably be a resampling of the data
>down to its "natural" sampling rate.
The natural sampling rate is the recovered bit stream clock. So, who/what
procures the clock? There is a nice synchronizable phaser~ here
(oscsync.txt)
I'm trying to use it as a local oscillator.
--
Jean-Yves Bernier
http://www.pescadoo.net/
On Dec 28, 2005, at 10:41 AM, Peter Castine wrote:
> Look at Jean-Yves' patch:
thanks for posting that image, Peter. A lot easier to understand that
reading the patch as text!! ;)
You can often find the right object to make what you want, even if it's
not obvious. Jean-Yves' example patch is a type of comb filter, so
instead of writing it as a patch using delay~ (which, as has been
pointed out, is impossible unless you use the send~/receive~ trick to
break the loop) it might be easier to just use the comb~ object. Check
out the little diagram in the comb~ object's help file and you'll see
that it's just an N-sample delay with optional feedforward and feedback
delay. (I say optional because you can set either coefficient to zero
to turn it off, and by default the coefficients are set to zero.)
Remember that biquad~, comb~, teeth~ and allpass~ are not just filter
objects but also delay lines with some bells and whistles. They can
therefore be used to make these sorts of delay-with-feedback networks.
Now, you can't embed an allpass filter (or any other dsp) *within* the
feedback loop of a comb~ -- something which some reverb algorithms use
-- but in a lot of those cases you're dealing with larger delay times
and can implement the thing as a patch using tapin~/tapout~ instead.
Here's my comb~ example patch:
At 1:24 +0100 05/01/2006, Jean-Yves Bernier wrote:
> it is unlikely that an external device will sync.
I was underestimating the wonderful sync ability of the MIDI TimePiece:
So, it is now a bit more than a proof of concept. Max/MSP generating LTC.
Perftectly useless, but I like it :))
--
Jean-Yves Bernier
http://www.pescadoo.net/
> The natural sampling rate is the recovered bit stream clock. So, who/what
> procures the clock?
hm. Since there's no clock synchronization time or anything I guess
the best way would be to use an algorithm that optimizes an estimate
of the clock period and phase offset with repetetive passes over the
data. ie,
1. identify the zero-crossings in the signal
2. make an intelligent guess at the phase offset and period
3. calculate the difference between the estimated and identified zero-crossings
4. if differences are larger than some threshold, revise estimate and
go back to 3.
You can do all of this with buffer~ objects and uzi and counter
objects and what not. This algorithm assumes that the tape wow and
flutter will be minimal - ie, the input signal is reasonably steady.
If not you have a more complicated problem.
Once you've got a reasonable offset and frequency you can do a pass
with an FIR lowpass filter of the appropriate length to reduce the
bit-rate of the signal to the natural rate of one sample per clock
pulse.
Ben
Jean-Yves Bernier wrote:
> I was underestimating the wonderful sync ability of the MIDI TimePiece:
>
> http://www2.pescadoo.net/Max-LTC-to-MTP.png
>
>
> So, it is now a bit more than a proof of concept. Max/MSP generating LTC.
> Perftectly useless, but I like it :))
It's not useless at all, not everybody does have a MIDI TimePiece...
Stefan
--
[][] [][][] [][] [][][] [][] [][][] [][] [][][]
[][][][][][][][][][][][][][][][][][][][][][][][][][][][]
Stefan Tiedje
Klanggestalter
Electronic Composition
&
Improvisation
/~~~~~
\ /|() ()|
))))) )| | |( \
/// _/)/ )))))
___/ ///
-------------------------x---
--_____-----------|----------
--(_|_ ----|-----|-----()---
-- _|_)----|-----()----------
----------()------------x----
14, Av. Pr. Franklin Roosevelt, 94320 Thiais, France
Phone at CCMIX +33-1-49 77 51 72
At 13:08 +0100 16/01/2006, Stefan Tiedje wrote:
>It's not useless at all, not everybody does have a MIDI TimePiece...
Hi Stefan.
Although replacing a MTP/AV is not my goal, it may be a by-product of the
current project (http://www.pescadoo.net/annexe/max/ltc/ltcblocks.html)
I'm currently working on phase-locking to an external signal.
To close this thread on recursive programming, I've learned to use
tapin~/tapout~ as well as teeth~ as recursive operators. But I came to a
better solution, non recursive, non vector size-dependant. So, solving the
problem was thinking different.
Sounds familiar, huh...
--
Jean-Yves Bernier
http://www.pescadoo.net/
Seems like pause~ is no longer included in Percolate. Anyone know why? Is it not working on 64-bit or something? Anyone have a working copy of pause~?
pause~ used to be an abstraction... one which almost everyone has in its own fundus sooner or later anyway... mine is called [110.vecdel~]... i dont even know the later external.
inlet
send~ #0
receive~ #0
outlet
in the context of this thread... recursive signal processes... make sure not to forget that it is vectorsize dependent.
Oh, i see. Then I can make my own pause~ in no time. I thought it was more involved and took arguments and further options.
wasnt so sure yesterday... now i looked... it might be more wise not to only use a 4 digit number for a s/r... in fact i am using #0_abstractionname and not just #0
for 2 vectors use 2 copies.
and mind the 8999 instances limit (if i am not mistaken)