desc:FuMa to AmbiX — FOA Converter (ICST)
tags: ambisonics fuma ambix convert foa b-format

// ============================================================
// FuMa (B-Format / FurseМalham) → AmbiX (ACN / SN3D)
// First Order Ambisonics — 4 Kanäle
//
// Kanalreihenfolge:
//   Input  (FuMa):   Ch1=W   Ch2=X   Ch3=Y   Ch4=Z
//   Output (AmbiX):  Ch1=W   Ch2=Y   Ch3=Z   Ch4=X
//                    ACN 0   ACN 1   ACN 2   ACN 3
//
// Normierung FuMa → SN3D:
//   W    : × √2      = × 1.41421  = +3.01 dB
//   X,Y,Z: × 1/√3   = × 0.57735  = −4.77 dB
//
// Institut für Computermusik und Klangtechnologie (ICST)
// Zürcher Hochschule der Künste (ZHdK)
// ============================================================

in_pin:W  (FuMa Ch1)
in_pin:X  (FuMa Ch2)
in_pin:Y  (FuMa Ch3)
in_pin:Z  (FuMa Ch4)

out_pin:W  (AmbiX ACN0)
out_pin:Y  (AmbiX ACN1)
out_pin:Z  (AmbiX ACN2)
out_pin:X  (AmbiX ACN3)

options:no-meter

@init
// Normierungs-Faktoren (konstant, einmal berechnet)
gain_W   = sqrt(2);       // W:   FuMa → SN3D: × √2    (+3.01 dB)
gain_XYZ = 1.0 / sqrt(3); // XYZ: FuMa → SN3D: × 1/√3  (−4.77 dB)

@sample
// Eingabe zwischenspeichern (vor dem Überschreiben der spl-Variablen)
tmp_W = spl0;   // FuMa Ch1 = W
tmp_X = spl1;   // FuMa Ch2 = X
tmp_Y = spl2;   // FuMa Ch3 = Y
tmp_Z = spl3;   // FuMa Ch4 = Z

// Ausgabe: neue Kanalreihenfolge + Gain-Korrektur
spl0 = tmp_W * gain_W;    // ACN 0 = W  (W   skaliert mit √2)
spl1 = tmp_Y * gain_XYZ;  // ACN 1 = Y  (Y   skaliert mit 1/√3)
spl2 = tmp_Z * gain_XYZ;  // ACN 2 = Z  (Z   skaliert mit 1/√3)
spl3 = tmp_X * gain_XYZ;  // ACN 3 = X  (X   skaliert mit 1/√3)
