Skip to content
View in the app

A better way to browse. Learn more.

Opusmodus

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

brownian bridge ornaments

Featured Replies

Here is a function (with subfunctions) that operates based on the principle of the Brownian bridge. You define the start and end, and with each generation, an extended embellishment emerges. The principle is simple and allows for the creation of ornaments. Attached are some examples — I’ve structured them this way to make the principle easier to understand.

Here is a small graphical model showing four generations. The start and end points remain the same, while new random points are added in between with each generation.

pic.png

The Code & Examples

(defun pick (a b &key (span 5))
  (let ((rnd1 (car (rnd-number 1 (+ a span) (- a span))))
        (rnd2  (car (rnd-number 1 (+ b span) (- b span))))
        (n))
    (progn
      (setf n (car (rnd-number 1 rnd1 rnd2)))     
      (if (or (= n a) (= n b))
        (+ (rnd-pick '(1 -1)) n)
        n))))


(defun gen-brownian-bridge (n startend &key (all-gen nil) (output 'integer) (span 5))
  (let ((seq)
        (liste startend))
    (progn
      (setf seq (append (list startend)
                        (loop repeat n
                              do (setf liste (filter-repeat 1 (loop repeat (1- (length liste))
                                                                    for cnt = 0 then (incf cnt)
                                                                    append (append (list (nth cnt liste) 
                                                                                         (pick (nth cnt liste) 
                                                                                               (nth (1+ cnt) liste) 
                                                                                               :span span)
                                                                                         (nth (1+ cnt) liste))))))
                              collect liste)))
      (setf seq (if (equal all-gen t)
                    seq
                  (car (last seq))))
      (if (equal output 'pitch)
          (integer-to-pitch seq)
        seq))))


(defun remove-duplicates-keep-edges (lst)
  "Entfernt innere Duplikate aus LST, behält aber den ersten und letzten Wert unabhängig von Wiederholungen."
  (let* ((first (first lst))
         (last (car (last lst)))
         (len (length lst))
         (result '())
         (seen '())
         (index 0))
    (dolist (el lst (reverse result))
      (cond
        ;; Ersten Wert immer behalten
        ((= index 0)
         (push el result)
         (push el seen))
        ;; Letzten Wert immer behalten
        ((= index (1- len))
         (push el result))
        ;; Innere Duplikate von first oder last überspringen
        ((or (and (eq el first) (/= index 0))
             (and (eq el last) (/= index (1- len))))
         ;; überspringen
         nil)
        ;; Andere Duplikate vermeiden
        ((not (member el seen))
         (push el result)
         (push el seen)))
      (setf index (1+ index)))))

;(remove-duplicates-keep-edges '(a b c a d e b c))

(defun reset-pitch-sequence (pitch-sequence pitch &key (type 'low))
  (let ((pitch1 (cond  ((equal type 'low)
                        (car (get-ambitus pitch-sequence :type :pitch)))
                       ((equal type 'high)
                        (cadr (get-ambitus pitch-sequence :type :pitch)))
                       ((equal type 'center) 
                        (center-position-in-list (sort-asc pitch-sequence) :get-value t)))))

    (if (not (omn-formp pitch-sequence))
      (pitch-transpose (car (pitch-to-interval (list (if (chordp pitch1)
                                                       (car (pitch-melodize pitch1))
                                                       (append pitch1))
                                                     pitch))) pitch-sequence)

      (omn-component-replace pitch-sequence
                             (pitch-transpose (car (pitch-to-interval (list (if (chordp pitch1)
                                                                              (car (pitch-melodize pitch1))
                                                     (append pitch1))
                                                                            pitch))) (omn :pitch pitch-sequence))))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;; only the main function, to see how it works
;;; 6 generations, start with 3 end with 2, span = max inteval/seps
;;; 

(list-plot
 (flatten (gen-brownian-bridge 6 '(3 2) :span 4  :all-gen t))
 :join-points nil :style :fill)


(gen-brownian-bridge 4 '(3 2) :span 3  :all-gen t)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;;; example with 6 generations
;;; every generation in an new bar to show how ith works

(omn-list-plot
(progn
  (setf seq (reset-integer-sequence (gen-brownian-bridge 6 '(3 2) :span 4  :all-gen t)))                               
  (setf pitchfield (make-scale 'c4 (find-max (flatten seq)) :alt '(1 1 2 4 7 4 2)))
  (setf pitch (position-filter seq pitchfield))

  (setf rhy 1/16)
  (setf lengths (loop for i in pitch
                        collect (length-rational-quantize (gen-length (gen-repeat (length i) 1) rhy) :round '10/4)))
  (make-omn
   :pitch pitch
   :length lengths))
:join-points nil :style :fill)


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;;; ALL DUPLCIATIONS INSIDE one PHRASE are removed!!!

;;; example with 6 generations
;;; every generation in an new bar to show how ith works
;;;


(omn-list-plot
(progn
  (setf seq (reset-integer-sequence (loop for i in (gen-brownian-bridge 6 '(3 2) :span 4  :all-gen t)
                                          collect (remove-duplicates-keep-edges i))))

  (setf pitchfield (make-scale 'c4 (find-max (flatten seq)) :alt '(1 1 2 4 7 4 2)))
  (setf pitch (position-filter seq pitchfield))

  (setf rhy 1/16)
  (setf lengths (loop for i in pitch
                        collect (length-rational-quantize (gen-length (gen-repeat (length i) 1) rhy) :round '6/4)))
  (make-omn
   :pitch pitch
   :length lengths))

:join-points nil :style :fill)

      

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

  • 4 weeks later...

seems to be a bug, maybe? does not work for me.

Error: Undefined operator reset-integer-sequence in form (reset-integer-sequence (gen-brownian-bridge 6 (quote (3 2)) :span 4 :all-gen t)).

  • Author
(defun reset-integer-sequence  (alist &key (offset 0) (flatten nil))
  (let ((min (find-min (flatten alist))))
    (progn 
      (setf alist (cond ((listp (car alist))
                         (loop for j in alist
                           collect (loop for i in j
                                     collect (+ (- i min) offset))))
                        (t (loop for i in alist
                             collect (+ (- i min) offset)))))
      (if (equal flatten t)
        (flatten alist)
        alist))))
  • 6 months later...

Apologies, I am very late to this thread.

I stumbled opon it, as I am looking for a solution to code the improvisational practice in Jazz to connect 2 guidetones from one chord to another in a few steps to build a melody (i.e. starting from guidetone for chord in bar 1 by approaching in 2nd half of bar 1 the guidetonetone which then in played 1st in bar 2).

There are many improv-techniques under Jazz soloists to do this, and I am far from having any experience nor a complete overview, but still I think all can be abstractly modeled as brownian bridge.

But practically so far I believe I may use the OM-built-in passing-intervals for this, using nested options to offer multiple options for bridges, see docu below.

Anything wrong in my thinking?

image.png

Create an account or sign in to comment


Copyright © 2014-2026 Opusmodus™ Ltd. All rights reserved.
Product features, specifications, system requirements and availability are subject to change without notice.
Opusmodus, the Opusmodus logo, and other Opusmodus trademarks are either registered trademarks or trademarks of Opusmodus Ltd.
All other trademarks contained herein are the property of their respective owners.

Powered by Invision Community

Important Information

Terms of Use Privacy Policy

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.