View this PageEdit this PageUploads to this PageHistory of this PageTop of the SwikiRecent ChangesSearch the SwikiHelp Guide

Pmemo

sometimes one may want to acess one event back to compare
values etc.:
one example is aroh/avaroh in classical indian music
download: Pmemo.hqx



//jrh 2001
//access to last event, in the current event at the key \lastEvent

Pmemo : FilterPattern { 
        *new { arg pattern; 
                ^super.new(pattern) 
        } 
        asStream { 
                ^Routine({ arg inval; 
                        var lastEvent; 
                                        lastEvent = Event.protoEvent; 
                                pattern.asStream.collect({ arg event; 
                                var newevent; 
                                lastEvent.put(\lastEvent, nil); //wipe out the previous last event so that there is no chain back to all events. 
                                newevent = event.put(\lastEvent, lastEvent); 
                                lastEvent = event.copy.finishEvent; 
                                newevent 
                         }).embedInStream(inval); 
                }) 
        } 
} 

//basic implementation of the biscale scheme used in indian raga
//aroh: raising scale
//avaroh: falling scale

Pbiscale : Pmemo {
        var <>aroh, <>avaroh;
        *new { arg aroh, avaroh, pattern;
                 ^super.new(pattern).aroh_(aroh).avaroh_(avaroh)
        }
        asStream {
                ^super.asStream.collect({ arg item;
                        var delta;
                        delta = item.at(\degree) - item.at(\lastEvent).at(\degree);
                        if(delta.isKindOf(SequenceableCollection), { delta = delta.at(0) });
                        if(delta > 0, {
                                item.put(\scale, aroh)
                        }, {
                                item.put(\scale, avaroh)
                        });
                });
        }


}
//a test:
a = Pmemo(Pbind(\a, Prand([1, 2, 3], inf)));
s = a.asStream;

s.next(Event.new).postln;
s = s.collect({ arg item; item.at(\a) - item.at(\lastEvent).at(\a)  }); 
s.next(Event.new).postln;







the history of erroneous implementation:





Pmemo : FilterPattern {
        var <>lastEvent;
        new { arg pattern;
                ^super.new(pattern).lastEvent_(Event.protoEvent)
        }
        asStream {
                ^pattern.asStream.collect({ arg event;
                                var newevent;
                                newevent = event.put(\lastEvent, lastEvent);
                                lastEvent = event.finishEvent;
                                newevent
                })
        }
}


JMcC: The above stream modifies its pattern which is not good, because then two streams made from that pattern will overwrite each other's data. Better to write it this way. (untested)

Pmemo : FilterPattern {
        new { arg pattern;
                ^super.new(pattern)
        }
        asStream {
                ^Routine({ arg inval;
                        var lastEvent;
   lastEvent = Event.protoEvent;
                        pattern.asStream.collect({ arg event;
                                var newevent;
                                newevent = event.put(\lastEvent, lastEvent);
                                lastEvent = event.finishEvent;
                                newevent
                         }).embedInStream(inval);
                })
        }
}



JMcC: Actually this is VERY dangerous behaviour, since each event contains a pointer to the previous event via \lastEvent, you effectively have a linked list of ALL events. This would run you out of memory if you continued this indefinitely.


JRH:
the version on top is the new tested one.



Links to this Page