Forums > MaxMSP

Recursive programming in MSP. Impossible?

December 28, 2005 | 11:17 am

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?

max v2;
#N vpatcher 342 542 720 985;
#P newex 160 228 59 196617 delay~ 512;
#P newex 160 176 27 196617 -~;
#P newex 160 104 59 196617 cycle~ 100;
#P user ezdac~ 97 290 141 323 0;
#P connect 1 0 0 0;
#P connect 3 0 0 1;
#P connect 1 0 2 0;
#P connect 2 0 3 0;
#P fasten 3 0 2 1 165 271 234 271 234 160 182 160;
#P pop;


Jean-Yves Bernier

http://www.pescadoo.net/


December 28, 2005 | 11:28 am

use send~ + receive~ or insert pause~ in the feedback loop…


December 28, 2005 | 11:33 am

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_

#P window setfont "Sans Serif" 9.;
#P flonum 329 250 63 9 0 0 0 139 0 0 0 221 221 221 222 222 222 0 0 0;
#P window linecount 1;
#P newex 314 286 63 9109513 tapout~ 100;
#B color 10;
#P newex 314 222 63 9109513 tapin~ 1000;
#B color 5;
#P window setfont "Sans Serif" 9.;
#P newex 221 288 59 196617 delay~ 512;
#P newex 220 236 27 196617 -~;
#P newex 220 164 59 196617 cycle~ 100;
#P user ezdac~ 187 319 231 352 0;
#P connect 3 0 0 1;
#P connect 3 0 4 0;
#P connect 1 0 0 0;
#P connect 1 0 2 0;
#P connect 5 0 2 1;
#P connect 6 0 5 0;
#P connect 4 0 5 0;
#P connect 2 0 3 0;
#P window clipboard copycount 7;


December 28, 2005 | 1:02 pm

hi Junior,

You said pause~ ?
I didn’t knew that object.

Philippe.


December 28, 2005 | 1:11 pm

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.


December 28, 2005 | 1:19 pm

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/


December 28, 2005 | 1:19 pm

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/


December 28, 2005 | 1:32 pm

hi Jean-Yves,

add

max v2;

at the beginning

and

#P pop;

at the end of the text and you will be able to open the patch…
Philippe.


December 28, 2005 | 2:18 pm


December 28, 2005 | 2:41 pm

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:

http://www.synthesisters.com/hypermail/max-msp/Oct05/33323.h tml

>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/


December 28, 2005 | 3:57 pm

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


December 28, 2005 | 6:05 pm


December 29, 2005 | 12:04 am

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


December 29, 2005 | 8:33 am

> 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


December 30, 2005 | 4:34 pm

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/


December 30, 2005 | 7:10 pm

> 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


December 31, 2005 | 1:40 pm

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:


December 31, 2005 | 8:14 pm

> 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

#P window setfont "Fixedwidth Serif" 14.;
#P window linecount 1;
#P comment 298 216 182 9240590 encoder;
#P comment 92 531 80 9240590 decoder;
#P window linecount 2;
#P comment 691 821 80 9240590 data (decoded);
#P window linecount 1;
#P comment 694 767 80 9240590 biphase-M;
#P comment 693 697 48 9240590 data;
#P comment 695 631 48 9240590 clock;
#P newex 163 393 40 9240590 abs~;
#P newex 156 244 56 9240590 sig~ 1;
#P newex 86 245 40 9240590 +~ 1;
#P newex 121 297 96 9240590 selector~ 2;
#P newex 517 320 56 9240590 sig~ 0;
#P newex 560 357 64 9240590 sig~ -2;
#P newex 474 394 96 9240590 selector~ 2;
#P newex 474 288 40 9240590 +~ 1;
#P newex 474 257 40 9240590 >~ 0;
#P newex 474 224 144 9240590 receive~ feedback;
#P newex 478 431 120 9240590 send~ feedback;
#P newex 166 430 40 9240590 %~ 2;
#P newex 174 354 32 9240590 +=~;
#N vpatcher 15 55 615 455;
#P window setfont "Fixedwidth Serif" 14.;
#P newex 57 80 80 9240590 select 32;
#P newex 55 50 40 9240590 key;
#P toggle 50 120 50 0;
#P newex 50 175 72 9240590 qmetro 2;
#P outlet 50 204 15 0;
#P connect 4 0 2 0;
#P connect 2 0 1 0;
#P connect 1 0 0 0;
#P connect 3 0 4 0;
#P pop;
#P newobj 363 496 88 9240590 p spacebar;
#N vpatcher 15 55 615 455;
#P window setfont "Fixedwidth Serif" 14.;
#P window linecount 1;
#P newex 50 444 256 9240590 jit.expr @expr "in[0]*0.4-0.99";
#P window linecount 2;
#P newex 50 476 272 9240590 jit.graph @out_name lala @clearit 0 @frgb
255 100 255 255 @mode 0;
#P window linecount 1;
#P newex 82 335 248 9240590 jit.expr @expr "in[0]*0.4-0.5";
#P newex 113 225 248 9240590 jit.expr @expr "in[0]*0.4+0.0";
#P newex 144 133 248 9240590 jit.expr @expr "in[0]*0.4+0.5";
#P window linecount 2;
#P newex 113 260 336 9240590 jit.graph @out_name lala @clearit 0 @brgb
0 0 0 0 @frgb 255 100 255 100 @mode 0;
#P newex 144 164 336 9240590 jit.graph @out_name lala @clearit 1 @brgb
0 0 0 0 @frgb 255 255 100 100 @mode 0;
#P window linecount 1;
#P newex 82 50 104 9240590 jit.unpack 4;
#P window linecount 2;
#P newex 82 367 272 9240590 jit.graph @out_name lala @clearit 0 @frgb
255 100 100 255 @mode 0;
#P inlet 82 30 15 0;
#P outlet 50 523 15 0;
#P connect 3 0 10 0;
#P connect 10 0 9 0;
#P connect 9 0 0 0;
#P connect 1 0 3 0;
#P connect 3 1 8 0;
#P connect 8 0 2 0;
#P connect 3 2 7 0;
#P connect 7 0 5 0;
#P connect 3 3 6 0;
#P connect 6 0 4 0;
#P pop;
#P newobj 364 578 88 9240590 p graphing;
#P newex 162 641 48 9240590 ==~ 0;
#P comment 212 602 80 9240590 flip test;
#P newex 161 605 32 9240590 ==~;
#P newex 183 570 88 9240590 delay~ 1 1;
#P newex 44 647 40 9240590 +~ 1;
#P newex 89 798 96 9240590 selector~ 2;
#P newex 132 745 88 9240590 delay~ 1 1;
#P newex 45 609 48 9240590 ==~ 1;
#P comment 81 73 48 9240590 clock;
#P newex 236 114 40 9240590 +~ 1;
#P newex 237 155 96 9240590 selector~ 2;
#P newex 324 119 88 9240590 delay~ 1 1;
#P newex 41 96 120 9240590 count~ 0 2 1 1;
#P newex 279 68 40 9240590 >~ 0;
#P newex 279 36 56 9240590 noise~;
#P user ezdac~ 643 76 687 109 0;
#P user jit.pwindow 363 617 322 242 0 1 0 0 1 0;
#P newex 364 540 280 9240590 jit.catch~ 4 @mode 2 @framesize 32;
#P window linecount 3;
#P comment 349 47 182 9240590 randomly generated bit half-sample-rate
bit stream;
#P user panel 20 553 290 302;
#X brgb 191 191 191;
#X frgb 0 0 0;
#X border 1;
#X rounded 0;
#X shadow 0;
#X done;
#P user panel 72 234 643 216;
#X brgb 191 191 191;
#X frgb 0 0 0;
#X border 1;
#X rounded 0;
#X shadow 0;
#X done;
#P connect 8 0 13 0;
#P connect 8 0 33 0;
#P connect 8 0 11 0;
#P connect 8 0 3 3;
#P connect 7 0 10 1;
#P connect 7 0 9 0;
#P connect 23 0 35 0;
#P connect 23 0 25 0;
#P connect 24 0 18 0;
#P connect 24 0 17 0;
#P connect 24 0 3 1;
#P connect 10 0 32 2;
#P connect 10 0 3 2;
#P connect 13 0 16 0;
#P connect 16 0 15 0;
#P connect 33 0 32 0;
#P connect 20 0 14 0;
#P connect 14 0 15 1;
#P connect 18 0 20 0;
#P connect 34 0 32 1;
#P connect 35 0 24 0;
#P connect 32 0 23 0;
#P connect 29 0 23 0;
#P connect 20 0 15 2;
#P connect 17 0 18 1;
#P connect 11 0 10 0;
#P connect 6 0 7 0;
#P connect 9 0 10 2;
#P connect 22 0 3 0;
#P connect 15 0 3 0;
#P connect 3 0 21 0;
#P connect 21 0 4 0;
#P connect 26 0 27 0;
#P connect 27 0 28 0;
#P connect 28 0 29 0;
#P connect 31 0 29 1;
#P connect 30 0 29 2;
#P window clipboard copycount 42;


January 1, 2006 | 6:06 pm

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/


January 1, 2006 | 6:15 pm

Okay Jean-Yves, below is the patch saved-as-text. Enjoy!

Ben

max v2;
#N vpatcher 44 48 868 935;
#P window setfont "Fixedwidth Serif" 14.;
#P window linecount 1;
#P comment 298 216 182 9240590 encoder;
#P comment 92 531 80 9240590 decoder;
#P window linecount 2;
#P comment 691 821 80 9240590 data (decoded);
#P window linecount 1;
#P comment 694 767 80 9240590 biphase-M;
#P comment 693 697 48 9240590 data;
#P comment 695 631 48 9240590 clock;
#P newex 163 393 40 9240590 abs~;
#P newex 156 244 56 9240590 sig~ 1;
#P newex 86 245 40 9240590 +~ 1;
#P newex 121 297 96 9240590 selector~ 2;
#P newex 517 320 56 9240590 sig~ 0;
#P newex 560 357 64 9240590 sig~ -2;
#P newex 474 394 96 9240590 selector~ 2;
#P newex 474 288 40 9240590 +~ 1;
#P newex 474 257 40 9240590 >~ 0;
#P newex 474 224 144 9240590 receive~ feedback;
#P newex 478 431 120 9240590 send~ feedback;
#P newex 166 430 40 9240590 %~ 2;
#P newex 174 354 32 9240590 +=~;
#N vpatcher 15 55 615 455;
#P window setfont "Fixedwidth Serif" 14.;
#P newex 57 80 80 9240590 select 32;
#P newex 55 50 40 9240590 key;
#P toggle 50 120 50 0;
#P newex 50 175 72 9240590 qmetro 2;
#P outlet 50 204 15 0;
#P connect 4 0 2 0;
#P connect 2 0 1 0;
#P connect 1 0 0 0;
#P connect 3 0 4 0;
#P pop;
#P newobj 363 496 88 9240590 p spacebar;
#N vpatcher 15 55 615 455;
#P window setfont "Fixedwidth Serif" 14.;
#P window linecount 1;
#P newex 50 444 256 9240590 jit.expr @expr "in[0]*0.4-0.99";
#P window linecount 2;
#P newex 50 476 272 9240590 jit.graph @out_name lala @clearit 0 @frgb
255 100 255 255 @mode 0;
#P window linecount 1;
#P newex 82 335 248 9240590 jit.expr @expr "in[0]*0.4-0.5";
#P newex 113 225 248 9240590 jit.expr @expr "in[0]*0.4+0.0";
#P newex 144 133 248 9240590 jit.expr @expr "in[0]*0.4+0.5";
#P window linecount 2;
#P newex 113 260 336 9240590 jit.graph @out_name lala @clearit 0 @brgb
0 0 0 0 @frgb 255 100 255 100 @mode 0;
#P newex 144 164 336 9240590 jit.graph @out_name lala @clearit 1 @brgb
0 0 0 0 @frgb 255 255 100 100 @mode 0;
#P window linecount 1;
#P newex 82 50 104 9240590 jit.unpack 4;
#P window linecount 2;
#P newex 82 367 272 9240590 jit.graph @out_name lala @clearit 0 @frgb
255 100 100 255 @mode 0;
#P inlet 82 30 15 0;
#P outlet 50 523 15 0;
#P connect 3 0 10 0;
#P connect 10 0 9 0;
#P connect 9 0 0 0;
#P connect 1 0 3 0;
#P connect 3 1 8 0;
#P connect 8 0 2 0;
#P connect 3 2 7 0;
#P connect 7 0 5 0;
#P connect 3 3 6 0;
#P connect 6 0 4 0;
#P pop;
#P newobj 364 578 88 9240590 p graphing;
#P newex 162 641 48 9240590 ==~ 0;
#P comment 212 602 80 9240590 flip test;
#P newex 161 605 32 9240590 ==~;
#P newex 183 570 88 9240590 delay~ 1 1;
#P newex 44 647 40 9240590 +~ 1;
#P newex 89 798 96 9240590 selector~ 2;
#P newex 132 745 88 9240590 delay~ 1 1;
#P newex 45 609 48 9240590 ==~ 1;
#P comment 81 73 48 9240590 clock;
#P newex 236 114 40 9240590 +~ 1;
#P newex 237 155 96 9240590 selector~ 2;
#P newex 324 119 88 9240590 delay~ 1 1;
#P newex 41 96 120 9240590 count~ 0 2 1 1;
#P newex 279 68 40 9240590 >~ 0;
#P newex 279 36 56 9240590 noise~;
#P user ezdac~ 643 76 687 109 0;
#P user jit.pwindow 363 617 322 242 0 1 0 0 1 0;
#P newex 364 540 280 9240590 jit.catch~ 4 @mode 2 @framesize 32;
#P window linecount 3;
#P comment 349 47 182 9240590 randomly generated bit half-sample-rate
bit stream;
#P user panel 20 553 290 302;
#X brgb 191 191 191;
#X frgb 0 0 0;
#X border 1;
#X rounded 0;
#X shadow 0;
#X done;
#P user panel 72 234 643 216;
#X brgb 191 191 191;
#X frgb 0 0 0;
#X border 1;
#X rounded 0;
#X shadow 0;
#X done;
#P connect 13 0 16 0;
#P connect 8 0 13 0;
#P connect 8 0 33 0;
#P connect 16 0 15 0;
#P connect 33 0 32 0;
#P connect 20 0 14 0;
#P connect 14 0 15 1;
#P connect 24 0 18 0;
#P connect 18 0 20 0;
#P connect 23 0 35 0;
#P connect 34 0 32 1;
#P connect 35 0 24 0;
#P connect 29 0 23 0;
#P connect 32 0 23 0;
#P connect 20 0 15 2;
#P connect 24 0 17 0;
#P connect 17 0 18 1;
#P connect 10 0 32 2;
#P connect 8 0 11 0;
#P connect 11 0 10 0;
#P connect 6 0 7 0;
#P connect 7 0 10 1;
#P connect 9 0 10 2;
#P connect 7 0 9 0;
#P connect 15 0 3 0;
#P connect 22 0 3 0;
#P connect 3 0 21 0;
#P connect 21 0 4 0;
#P connect 24 0 3 1;
#P connect 26 0 27 0;
#P connect 27 0 28 0;
#P connect 28 0 29 0;
#P connect 23 0 25 0;
#P connect 31 0 29 1;
#P connect 10 0 3 2;
#P connect 30 0 29 2;
#P connect 8 0 3 3;
#P pop;


January 5, 2006 | 12:24 am

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 < http://www.pescadoo.net/annexe/max/biphase/index.html>.

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/


January 5, 2006 | 2:27 am

> 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


January 5, 2006 | 4:01 pm

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)

< http://web.apu.ac.uk/music/rhoadley/courses/tech_resources/max-msp/examples/wiggle/>

I’m trying to use it as a local oscillator.


Jean-Yves Bernier

http://www.pescadoo.net/


January 5, 2006 | 4:12 pm

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:

#P window setfont "Sans Serif" 9.;
#P window linecount 1;
#P newex 123 281 41 196617 *~ 0.2;
#P newex 71 275 41 196617 *~ 0.2;
#P user ezdac~ 71 300 115 333 0;
#P newex 140 130 48 196617 loadbang;
#P flonum 196 218 92 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P message 140 152 26 196617 512;
#P number 140 172 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P newex 140 192 66 196617 sampstoms~;
#P newex 123 100 61 196617 cycle~ 100;
#P newex 123 254 132 196617 comb~ 100 11.61 1 0 0.99;
#P connect 1 0 8 0;
#P connect 1 0 0 0;
#P connect 8 0 7 0;
#P connect 9 0 7 1;
#P connect 0 0 9 0;
#P connect 5 0 0 1;
#P connect 6 0 4 0;
#P connect 2 1 5 0;
#P connect 3 0 2 0;
#P connect 4 0 3 0;
#P window clipboard copycount 10;


January 5, 2006 | 6:36 pm

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:

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 :))


Jean-Yves Bernier

http://www.pescadoo.net/


January 5, 2006 | 6:46 pm

> 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


January 16, 2006 | 12:08 pm

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


January 17, 2006 | 9:43 pm

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/


Viewing 28 posts - 1 through 28 (of 28 total)