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.

Opusmodus 1.3.24769

Featured Replies

– New functions: 

   get-sieve-tree
   sieve-merge
   sieve-tree-series
   sieve-tree
   sieve
   pick-prob
   gen-prob
   create-osc-thread
   get-osc-thread-from-name
   send-osc-data
   osc-thread-alive?
   end-all-osc-threads
   end-osc-thread

– Howto Score/OSC/OSC Threads.opmo
– Changes to OSC functions, please check the new OSC documents if you use OSC.
– Musicxml display improvements.

 

SIEVE-TREE

This function returns a sequence of lengths symbols derived from tree-data in a given root, node and level number.
 

Examples:

Low density output:

(sieve-tree 32 2 3)

Pasted Graphic 4.png

 

With a smaller root number and a higher level number we increase the density:

(sieve-tree 8 2 5)

Pasted Graphic 3.png

 

In the following example we add probability values using lists of paired values to node, level and rest parameters. The first value in the rest lists is a percentage value of the length-rests in a node-level list.

(sieve-tree '(4 2)
            '((2 0.43) (3 0.37))
            '((3 0.47) (4 0.56) (5 0.68))
            :rest '((20 0.43) (80 0.6) (0 0.7))
            :quantize '(1 2 3 4 5 7))

 

Pasted Graphic 1.png

 

Here we are increasing the length-rest probability and set the quantize to quarter, eight and quintuplet only:

(sieve-tree '(4 2)
            '((2 0.43) (3 0.37))
            '((3 0.47) (4 0.56) (5 0.68))
            :rest '((20 0.43) (80 0.6) (90 0.7))
            :quantize '(1 2 5))

 

Pasted Graphic 5.png

 

The expression below will generate 96 bars of gradual increase in the density:

(sieve-tree 96 2 7 :seed 43)

 

Let's examine the original tree-data from the expression above. To do that we call the GET-SIEVE-TREE function with the same tree values:

(get-sieve-tree 96 2 7)

 

 

SIEVE-TREE-SERIES

SIEVE-TREE-SERIES returns a sequence of lengths symbols derived from a series of tree-data in a given root, node and level number. This function allows you to control individual tree-data parameters ie. density results. Please note, every parameter has a keyword, except the root number.

 

Examples:

(sieve-tree-series '((8 :node 2 :level ((3 0.47) (4 0.56) (5 0.68))
                        :rest ((40 0.43) (80 0.6) (0 0.7))
                        :quantize (1 2 4))
                     (3 :node 2 :level ((3 0.47) (4 0.56) (5 0.68))
                        :quantize (1 2 3 5 6))
                     (2 :node 3 :level ((4 0.46) (5 0.58)) :seed 23)))

Pasted Graphic.png

 

(sieve-tree-series '((2 :node 2 :level ((4 0.47) (5 0.66))
                        :rest ((40 0.43) (80 0.6) (0 0.7)))
                     (8 :node 2 :level ((3 0.47) (4 0.56))
                        :quantize (1 2 3 5 6))
                     (3 :node 3 :level ((4 0.46) (5 0.58))
                        :rest ((40 0.43) (80 0.6) (0 0.7)))))

Pasted Graphic 1.png

 

 

GET-SIEVE-TREE

GET-SIEVE-TREE returns a tree node degree data from a given root, node and level number.  This function is useful for analysis of the original tree-data used in the SIEVE-TREE function.

 

Examples:

(get-sieve-tree 96 2 1)
=> ((48 48))

(get-sieve-tree 96 3 1)
=> ((32 32 32))

(get-sieve-tree 96 2 2)
=> (((24 24) (16 16 16)))

(get-sieve-tree 96 3 2)
=> (((32) (16 16) (32/3 32/3 32/3)))

(get-sieve-tree 96 2 3)
=> (((12 12) (8 8 8)) ((16) (8 8) (16/3 16/3 16/3)))

(get-sieve-tree 96 3 3)
=> (((16 16)) ((8 8) (16/3 16/3 16/3)) ((32/3) (16/3 16/3) (32/9 32/9 32/9)))

(get-sieve-tree 96 2 5)
=> (((3 3) (2 2 2)) ((4) (2 2) (4/3 4/3 4/3)) ((4 4)) ((2 2) (4/3 4/3 4/3))
    ((8/3) (4/3 4/3) (8/9 8/9 8/9)) ((4 4) (8/3 8/3 8/3)) ((2 2) (4/3 4/3 4/3))
    ((8/3) (4/3 4/3) (8/9 8/9 8/9)) ((8/3 8/3)) ((4/3 4/3) (8/9 8/9 8/9))
    ((16/9) (8/9 8/9) (16/27 16/27 16/27)))

 

SIEVE-TREE example with root 8, node 2 and level 5:

(sieve-tree 8 2 5)

Pasted Graphic.png

 

Analysis of the above tree-data:

(get-sieve-tree 8 2 5)
=> (((1/4 1/4) (1/6 1/6 1/6)) ((1/3) (1/6 1/6) (1/9 1/9 1/9)) ((1/3 1/3))
    ((1/6 1/6) (1/9 1/9 1/9)) ((2/9) (1/9 1/9) (2/27 2/27 2/27))
    ((1/3 1/3) (2/9 2/9 2/9)) ((1/6 1/6) (1/9 1/9 1/9))
    ((2/9) (1/9 1/9) (2/27 2/27 2/27)) ((2/9 2/9)) ((1/9 1/9) (2/27 2/27 2/27))
    ((4/27) (2/27 2/27) (4/81 4/81 4/81)))

 

 

SIEVE

SIEVE returns a list of numbers to a given modulus, shift and maximum number. This function can be useful in generating root numbers for the SIEVE-TREE function.

(sieve 4 0 96)
=> (0 4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80 84 88 92 96)

 

Examples:

(sieve 2 0 60)
=> (0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32
    34 36 38 40 42 44 46 48 50 52 54 56 58 60)

(sieve 2 1 60)
=> (1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33
    35 37 39 41 43 45 47 49 51 53 55 57 59)

 

Example with SIEVE-TREE function:

(sieve-tree (sieve 3 4 14)
            '((2 0.43) (3 0.37))
            '((3 0.47) (4 0.56) (5 0.68))
            :rest '((20 0.43) (80 0.6) (90 0.7)))

Pasted Graphic 1.png

 

 

SIEVE-MERGE

SIEVE-MERGE returns a list of numbers derived from merging a number of sieve lists. This function can be useful in generating root numbers for the SIEVE-TREE function.

 

Examples:

Here we merge two sieve lists, one from (sieve 3 0 96) and one from (sieve 4 0 96):

(sieve-merge '(3 0 4 0) 96)
=> (0 3 4 6 8 9 12 15 16 18 20 21 24 27 28 30 32 33 36 39 40 42 44 45 48 51
    52 54 56 57 60 63 64 66 68 69 72 75 76 78 80 81 84 87 88 90 92 93 96)

 

Example with SIEVE-TREE and SIEVE-MERGE function:

(sieve-tree (sieve-merge '(3 2 4 2) 12)
            '((2 0.43) (3 0.37))
            '((3 0.47) (4 0.56) (5 0.68))
            :quantize '(1 2 4 8))

Pasted Graphic 1.png

 

 

PLEASE NOTE!

The changes to OSC implementation - see below - are thanks to Rangarajan Krishnamoorthy.

If you use OSC threads please revise your OSC files and make the necessary adjustments.

 

The CREATE-OSC-THREAD function creates the OSC thread with a given target.

Here we assign a name Reaktor to a remote-host: 127.0.0.1 and remote-port: 10000:

(defparameter reaktor '(127.0.0.1 10000))

Here we assign an variable to our OSC thread object, this is important for sending the data with the thread and for ending the thread:

(setf thd1 (create-osc-thread "thread1" reaktor))

To send OSC messages with the thread we call the SEND-OSC-DATA function:

(send-osc-data thd1 '((0.0 1/2) (0.0 1/2) (0.08238555 2)
                      (0.10876829 1) (0.12127061 11/2)))

To end the OSC thread and the sending of the OSC messages, we call the END-OSC-THREAD function:

(end-osc-thread thd1)

 

The SEND-OSC-THREAD function sends OSC data and performs a small amount of "background" processing on messages in the queue when the processor would otherwise be idle. This function can be called on a created thread any number of times during its lifetime.

(defparameter reaktor '(127.0.0.1 10000))
(defparameter time (rnd-sample 50 '(1/4 1/2 1/4)))
(defparameter values (vector-smooth 0.05 (gen-white-noise 500)))
(defparameter data (gen-osc-data 60 values :time time))

(setf thd1 (create-osc-thread "thread1" reaktor))
(send-osc-data thd1 data)

 

The GET-OSC-THREAD-FROM-NAME function returns the OSC thread from a given name. This function is useful if you don’t assign  a variable to the thread object.

 

Note we are not capturing the thread object returned from this function:

(create-osc-thread "thread1" reaktor)

We can get the thread object using its name when we want:

(send-osc-data (get-osc-thread-from-name "thread1")
               '((0.0 1/2) (0.3254655 1/2) (0.08238555 2)
                 (0.10876829 1) (0.12127061 11/2)))
(end-osc-thread (get-osc-thread-from-name "thread1"))

The OSC-THREAD-ALIVE? function checks if the given OSC thread object is still alive and returns T if true.

(setf thd1 (create-osc-thread "thread1" '(127.0.0.1 10000)))
(end-osc-thread thd1)
=> nil

Test:

(osc-thread-alive? thd1)
=> nil

 

The END-OSC-THREAD function will end and destroy a given OSC thread. After the thread is destroyed, you cannot send any messages to it.

(setf thd1 (create-osc-thread "thread1" '(127.0.0.1 10000)))
(end-osc-thread thd1)
=> nil

Test:

(osc-thread-alive? thd1)
=> nil

The END-ALL-OSC-THREADS function will end and destroy all OSC threads. You cannot send any messages to the threads once they are destroyed.

(defparameter reaktor '(127.0.0.1 10000))
(create-osc-thread "thread1" reaktor)
(create-osc-thread "thread2" reaktor)
(create-osc-thread "thread3" reaktor)
(create-osc-thread "thread4" reaktor)
(end-all-osc-threads)
=> nil

Best wishes,

Janusz


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.