Recursive programming in MSP. Impossible?


    Dec 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?
    -- Jean-Yves Bernier http://www.pescadoo.net/

    • Dec 28 2005 | 11:28 am
      use send~ + receive~ or insert pause~ in the feedback loop...
    • Dec 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_
    • Dec 28 2005 | 1:02 pm
      hi Junior,
      You said pause~ ? I didn't knew that object.
      Philippe.
    • Dec 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.
    • Dec 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/
    • Dec 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/
    • Dec 28 2005 | 1:32 pm
      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.
    • Dec 28 2005 | 2:18 pm
    • Dec 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:
      >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/
    • Dec 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
      --
      e-mail: franzrosati@yahoo.it
    • Dec 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
    • Dec 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
    • Dec 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/
    • Dec 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
    • Dec 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:
    • Dec 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
    • Jan 01 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/
    • Jan 01 2006 | 6:15 pm
      Okay Jean-Yves, below is the patch saved-as-text. Enjoy!
      Ben
    • Jan 05 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 .
      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/
    • Jan 05 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
    • Jan 05 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)
      I'm trying to use it as a local oscillator.
      -- Jean-Yves Bernier http://www.pescadoo.net/
    • Jan 05 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:
    • Jan 05 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:
      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/
    • Jan 05 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
    • Jan 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
    • Jan 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/