From d6bb375789821f4e4e175465f50e77e8a6b1aaf7 Mon Sep 17 00:00:00 2001
From: Alexander Nguyen <alexander.nguyen@stud.hfm-karlsruhe.de>
Date: Sun, 09 Mar 2025 18:42:11 +0100
Subject: [PATCH] feat: implemented encoding up to 7th order

---
 sources/classes/sox-hoaencode.lisp |  139 +++++++++++++++++++++++++++++++--------------
 1 files changed, 95 insertions(+), 44 deletions(-)

diff --git a/sources/classes/sox-hoaencode.lisp b/sources/classes/sox-hoaencode.lisp
index 16d7c1a..def1f08 100644
--- a/sources/classes/sox-hoaencode.lisp
+++ b/sources/classes/sox-hoaencode.lisp
@@ -38,28 +38,72 @@
 
 ;  ### Ambisonics ###
 
-(defun sox-hoaencode-sn3d-factor (order degree) ; andere Nomenklatur, "degree" w�re besser "order" um Verwechslung mit Winkeln zu vermeiden
+(defun sox-hoaencode-sn3d-factor (order degree)
+"This is a placeholder for documentation"
     (ecase order
         (0 1)
         (1 1)
         (2 
             (ecase (abs degree)
-                (2 (/ (sqrt 3) 6))
-                (1 (/ (sqrt 3) 3))
                 (0 1)
+                (1 (/ (sqrt 3) 3))
+                (2 (/ (sqrt 3) 6))
             ))
         (3 
             (ecase (abs degree)
-                (3 (/ (sqrt 10) 60))
-                (2 (/ (sqrt 15) 30))
-                (1 (/ (sqrt 6) 6))
                 (0 1)
+                (1 (/ (sqrt 6) 6))
+                (2 (/ (sqrt 15) 30))
+                (3 (/ (sqrt 10) 60))
+            )
+        )
+        (4 
+            (ecase (abs degree)
+                (0 1)
+                (1 (/ (sqrt 10) 10))
+                (2 (/ (sqrt 5) 30))
+                (3 (/ (sqrt 70) 420))
+                (4 (/ (sqrt 35) 840))
+            )
+        )
+        (5
+            (ecase (abs degree)
+                (0 1)
+                (1 (/ (sqrt 15) 15))
+                (2 (/ (sqrt 105) 210))
+                (3 (/ (sqrt 70) 840))
+                (4 (/ (sqrt 35) 2520))
+                (5 (/ (sqrt 14) 5040))
+            )
+        )
+        (6
+            (ecase (abs degree)
+                (0 1)
+                (1 (/ (sqrt 21) 21))
+                (2 (/ (sqrt 210) 420))
+                (3 (/ (sqrt 210) 2520))
+                (4 (/ (sqrt 7) 2520))
+                (5 (/ (sqrt 154) 55440))
+                (6 (/ (sqrt 462) 332640))
+            )
+        )
+        (7
+            (ecase (abs degree)
+                (0 1)
+                (1 (/ (sqrt 7) 14))
+                (2 (/ (sqrt 42) 252))
+                (3 (/ (sqrt 21) 1260))
+                (4 (/ (sqrt 231) 27720))
+                (5 (/ (sqrt 231) 166320))
+                (6 (/ (sqrt 6006) 4324320))
+                (7 (/ (sqrt 429) 4324320))
             )
         )
     )
 )
 
 (defun sox-hoaencode-azimuth-factor (degree theta_deg)
+"This is a placeholder for documentation"
     (let* 
         (
             (theta (sox-hoaencode-deg-to-rad theta_deg))
@@ -72,6 +116,7 @@
 )
 
 (defun sox-hoaencode-elevation-factor (order degree phi_deg)
+"This is a placeholder for documentation"
     (let* 
         (
             (phi (sox-hoaencode-deg-to-rad phi_deg))
@@ -86,7 +131,7 @@
             (2 
                 (ecase (abs degree)
                     (0 (- (/ (* 3 (expt (sin phi) 2)) 2) (/ 1 2)))
-                    (1 (/ (* 3 (expt (sin phi) 2)) 2))
+                    (1 (/ (* 3 (* (sin phi) 2)) 2))
                     (2 (* 3 (expt (cos phi) 2)))
                 ))
             (3 
@@ -96,42 +141,46 @@
                     (2 (* -15 (sin phi) (- (expt (sin phi) 2) 1)))
                     (3 (* 15 (expt (cos phi) 3)))
                 ))
+            (4 
+                (ecase (abs degree)
+                    (0 (+ (/ (* 35 (expt (cos phi) 4)) 8) (- (* 5 (expt (cos phi) 2))) 1))
+                    (1 (- (/ (* (sin (* 2 phi)) (- (/ (* 35 (expt (cos phi) 2)) 2) 10)) 2)))
+                    (2 (- (/ (* (* 15 (expt (cos phi) 2)) (- (* 7 (expt (cos phi) 2)) 6)) 2)))
+                    (3 (* 105 (expt (cos phi) 3) (sin phi) ))
+                    (4 (* 105 (expt (cos phi) 4)))
+                ))
+            (5 
+                (ecase (abs degree)
+                    (0    (/ (*     (sin phi) (+ (- (* 63 (expt (sin phi) 4)) (* 70 (expt (sin phi) 2))) 15)) 8))
+                    (1    (/ (*  15 (sin phi) (+ (- (* 21 (expt (cos phi) 4)) (* 28 (expt (cos phi) 2)))  8)) 8))
+                    (2 (- (/ (* 105 (sin phi) (+ (- (*  3 (expt (sin phi) 4)) (*  4 (expt (sin phi) 2)))  1)) 2)))
+                    (3 (- (/ (* 105 (expt (cos phi) 3) (- (* 9 (expt (cos phi) 2)) 8))                        2)))
+                    (4       (* 945 (sin phi) (expt (- (expt (sin phi) 2) 1) 2)))
+                    (5       (* 945 (expt (cos phi) 5)))
+                ))
+            (6 
+                (ecase (abs degree)
+                    (0 (+ (- (/ (* 231 (expt (cos phi) 6)) 16)) (/ (* 189 (expt (cos phi) 4)) 8) (- (/ (* 21 (expt (cos phi) 2)) 2)) 1))
+                    (1 (/ (* 21 (sin (* 2 phi)) (+ (* 33 (expt (sin phi) 4)) (- (* 30 (expt (sin phi) 2))) 5)) 16))
+                    (2 (/ (* 105 (expt (cos phi) 2) (+ (* 33 (expt (cos phi) 4)) (- (* 48 (expt (cos phi) 2))) 16)) 8))
+                    (3 (- (/ (* 315 (expt (cos phi) 3) (sin phi)) (- (* 11 (expt (cos phi) 2)) 8)) 2))
+                    (4 (- (/ (* 945 (expt (cos phi) 4) (- (* 11 (expt (cos phi) 2)) 10)) 2)))
+                    (5 (* 10395 (expt (cos phi) 5) (sin phi)))
+                    (6 (* 10395 (expt (cos phi) 6)))
+                ))
+            (7
+                (ecase (abs degree)
+                    (0    (/ (* (sin phi) (+ (* 429 (expt (sin phi) 6)) (- (* 693 (expt (sin phi) 4))) (* 315 (expt (sin phi) 2)) (- 35))) 16))
+                    (1 (- (/ (* (* 7 (cos phi)) (+ (* 429 (expt (cos phi) 6)) (- (* 792 (expt (cos phi) 4))) (* 432 (expt (cos phi) 2)) (- 64))) 16)))
+                    (2 (- (/ (* 63 (sin phi) (- (expt (sin phi) 2) 1) (+ (* 143 (expt (sin phi) 4)) (- (* 110 (expt (sin phi) 2))) 15)) 8)))
+                    (3    (/ (* (* 315 (expt (cos phi) 3)) (+ (* 143 (expt (cos phi) 4)) (- (* 220 (expt (cos phi) 2))) 80)) 8))
+                    (4    (/ (* 3465 (sin phi) (- (* 13 (expt (sin phi) 2)) 3) (expt (- (expt (sin phi) 2) 1) 2)) 2))
+                    (5 (- (/ (* 10395 (expt (cos phi) 5) (- (* 13 (expt (cos phi) 2)) 12)) 2)))
+                    (6 (* -135135 (sin phi) (expt (- (expt (sin phi) 2) 1) 3)))
+                    (7 (* 135135 (expt (cos phi) 7)))
+                ))
         )
     ))
-
-; #### Utility functions ####
-
-(defun sox-hoaencode-auto-convert-positions (positions)
-"Ensures that positions are given as '((azimuth elevation) ...) (in degrees), i.e.
-1) if list of list of three values, input is assumed to be '(x y z) coordinates and will be transformed to '(azimuth elevation) coordinates (in the navigational spherical coordinate system).
-2) if list of list of two values, input is assumed to be '(azimuth elevation) coordinates and won't be transformed any further.
-3) if 3dc, input is transformed to '(azimuth elevation) coordinates.
-"
-    (cond 
-        ((subtypep (type-of positions) '3dc)  
-            (progn ; convert xyz->aed, keep azimuth and elevation only.
-                (mat-trans 
-                    (butlast 
-                        (mat-trans 
-                            (mapcar 
-                                (lambda (xyz) (multiple-value-list (om:xyz->aed (first xyz) (second xyz) (third xyz)))) 
-                                (mat-trans (list (x-points positions) (y-points positions) (z-points positions)))
-                            ))))))
-        ((subtypep (type-of positions) 'list) 
-            (cond
-                ((= 2 (length (first positions)))
-                    positions)
-                ((= 3 (length (first positions))) 
-                    (mat-trans 
-                        (butlast 
-                            (mat-trans 
-                                (mapcar 
-                                    (lambda (xyz) (multiple-value-list (om:xyz->aed (first xyz) (second xyz) (third xyz)))) 
-                                    positions
-                                )))))
-                (t (error "Positions must consist of lists of length 2 (ae) or 3 (xyz)."))
-            ))
-        (t (error "Positions must be of type 3dc or list."))))
 
 
 
@@ -155,7 +204,7 @@
     )
 
 ; (sox-hoaencode-gain-single-component 1 1 45 0)
-; what is the difference between "order" and "degree"?
+; @AN: what is the difference between "order" and "degree"?
 
 
 (defun sox-hoaencode-gains-by-order (order azimuth_deg elevation_deg)
@@ -174,8 +223,10 @@
 
 (defclass! sox-hoaencode (sox-input)
     (
-        (positions :accessor positions :initarg :positions :initform '(0 0) :documentation *sox-hoaencode-positions-doc*)
-        (order :accessor order :initarg :order :initform 3 :documentation *sox-hoaencode-order-doc*)
+     (gains :accessor gains :initarg :gains :initform nil :documentation *sox-gain-doc*)
+     (azimuth :accessor azimuth :initarg :azimuth :initform 0 :documentation "azimuth angle in degrees")
+     (elevation :accessor elevation :initarg :elevation :initform 0 :documentation "elevation angle in degrees")
+     (order :accessor order :initarg :order :initform 3 :documentation *sox-hoaencode-order-doc*)
     )
     (:icon 100)
     (:documentation "Sox-hoaencode encodes <sound> into a <order>-th ambisonic (HOA) signal at <positions>.

--
Gitblit v1.9.1