Hi List, Rick, as you might now, I'm using cm2 and try to somewhat maintain the code base on my github account (partly to keep "Notes on the Metalevel" alive), made it work in realtime with incudine and sc-collider and even programmed some extensions I use for my compositional work.
I don't know if it makes any sense to announce it here, as I guess hardly anybody is using it. Therefore my question: Is *anybody* using cm2 and interested in these posts? Otherwise it might make more sense not to make any noise at all here... For those interested: Recently I made a svg backend for cm2: https://github.com/ormf/cm-svg you'll also need this package doing the heavy lifting: https://github.com/ormf/svg-import-export With the code loaded it is now possible to write (events (...) "/tmp/test.svg") and it'll save the data into an svg file in some sort of a "piano-roll" representation including a piano-roll background pattern, cent-aligned staff systems and barlines in different layers. The svg can be opened and edited in inkscape and reimported into cm using #'import-events. The major advantage to a midi piano-roll editor is that the y-axis isn't restricted to halfsteps and scaling/stretching/skewing operations will be imported correctly, which makes it quite nice for microtonal/spectral work. This is a preliminary port as I'm intending to extend this into arbitrary data sets available for non-midi purposes (interfacing with incudine, etc.). In addition I made a recursion pattern class. Although this could also be modeled with the existing rewrite pattern, the specialized class is a little more straightforward to use. I attach the file to this mail as it is fairly small. @Rick: I found some bugs in the cm dictionary and am a little unsure how to go about extending the documentation. I really like the symbol-lookup from the editor and wrote some javascript to make the frames version work with modern browsers. I'd love to extend your dict but there are some issues: 1. I would like to annotate the extensions in the documentation to distinguish it from the "original" common music (although this is difficult anyway, as the original code already was a moving target), keeping the code as much backward compatible, as possible. How would you recommend to do it? 2. You probably used some sort of documentation system. Would it be possible to hook into that and extend it from there and you send me the sources or is that copyrighted/protected code? 3. I would prefer to keep all additional cm code which isn't related to bugfixes in its own repository and don't know how I should handle extentions to the documentation of this additional code. It might be possible to just host the differences to the dict in the new repository rather than forking the complete dict, but I fear this is asking for trouble. Maybe you can give me some advice although I'm aware cm2 is not very high on your priority list...
;;; patterns.lisp ;;; ;;; Copyright (c) 2018 Orm Finnendahl ;;; ;;; This program is free software; you can redistribute it and/or modify ;;; it under the terms of the GNU General Public License as published by ;;; the Free Software Foundation; either version 2 of the License, or ;;; (at your option) any later version. ;;; ;;; This program is distributed in the hope that it will be useful, ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;;; GNU General Public License for more details. ;;; ;;; You should have received a copy of the GNU General Public License ;;; along with this program; if not, write to the Free Software ;;; Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ;;; ;;; more pattern classes not existent in original cm2 ;;; (in-package #:cm) ;;; permutation pattern class ;;; ;;; repeatedly apply a permutation to a given list of items. ;;; ;;; :of keyword specifies the items to permutate. ;;; ;;; :idxs keyword is a list of permutation indexes. Make sure it has ;;; the same length as the item list and contains all indexes from 0 ;;; to length-1. ;;; ;;; :immediately specifies whether the permutation is immediately ;;; applied to the item list before accessing the first element of the ;;; pattern. If set to nil, next first returns one period of the ;;; original item list before applying the permutation. Default is t. ;;; ;;; ;;; #| Examples: (let ((seq (new permutation :of '(a b c d e) :idxs '(4 3 0 2 1) :immediately nil))) (loop for x below 6 collect (next seq t))) -> ((A B C D E) (E D A C B) (B C E A D) (D A B E C) (C E D B A) (A B C D E)) (let ((seq (new permutation :of '(a b c d e) :idxs '(4 3 0 2 1) :immediately t))) (loop for x below 6 collect (next seq t))) -> ((E D A C B) (B C E A D) (D A B E C) (C E D B A) (A B C D E) (E D A C B)) |# (progn (defclass permutation (cycle) ((idxs :initform 0 :initarg :idxs :accessor idxs) (immediately :initform t :initarg :immediately :accessor immediately))) (defparameter <permutation> (find-class 'permutation)) (finalize-class <permutation>) (values)) (defmethod pattern-external-inits ((obj permutation)) (let ((inits (call-next-method))) (append inits (if (equal (permutations obj) 0) (list) (list ':idxs (expand-pattern-value (idxs obj)) ':immediately (immediately obj)))))) (defmethod initialize-instance :after ((obj permutation) &rest args) args (let ((cyc (pattern-data obj))) (cycl-data-set! cyc (copy-list (cycl-data cyc))) (unless (immediately obj) (cycl-tail-set! cyc (copy-list (cycl-data cyc)))) (values))) (defmethod next-in-pattern ((obj permutation)) (flet ((perm-in-place (lis len perm) (block main (loop for i = 0 then (incf i) while (< i len) do (progn (loop while (< (elt perm i) 0) ;;; is elem lready done/accessed? do (progn (incf i) (if (= i len) (return-from main)))) (loop ;;; do a full cycle of replacements starting with the ith element of perm for from = i then to for to = (elt perm from) until (= to i) for tmp = (elt lis to) do (setf (elt lis to) (elt lis from) ;;; swap list elements (elt lis from) tmp (elt perm from) (+ -1 (* -1 (elt perm from)))) ;;; tag elem of perm as accessed/done. finally (setf (elt perm from) (+ -1 (* -1 (elt perm from)))))))) ;;; tag starting element of permutation cycle as accessed/done. (loop for i below len do (setf (elt perm i) (* -1 (+ 1 (elt perm i))))) ;;; restore all elements of permutation. lis)) (let ((cyc (pattern-data obj))) (if (null (cycl-tail cyc)) (cycl-tail-set! cyc (perm-in-place (cycl-data cyc) (pattern-length obj) (idxs obj)))) (pop-cycl cyc)))) (export 'permutation 'cm)
_______________________________________________ Cmdist mailing list Cmdist@ccrma.stanford.edu https://cm-mail.stanford.edu/mailman/listinfo/cmdist