ChucK

UAnae osztály

Unit Analyzer - a jelgenerátorokhoz hasonló concepciójú analizáló építő blokkok. Segítségükkel végrehajtható analízis az audio jeleken és/vagy metaadat inputon, a kiszámított analízis pedig metaadatként kerül a kimenetre. A jel analizátorok összekapcsolhatóak jelgenerátorokkal, hogy egy analizáló/szintetizáló hálózatot hozhassanak létre. A jelgenerátorokhoz hasonlóan az analizálók is független vezérléssel, időzítéssel használhatóak párhuzamosan is. Mivel az analizátorok között nem feltétlenül audio szignál a továbbított adat, ezért működési elvük az idő kezelés szempontjából lényegesen eltérhetnek a jelgenerátorokhoz képest (például audio szignál intervallumon végzett számításnál nem mintavételenként történik a számítás, hanem blokkonként vagy akár már korábban kiszámolt metaadaton). Az analizátorok kapcsolódása alapjaiban tér el a megszokott jelgenerátornál is használt => operátortól. Ezt a fajta eltérést kiemelesére új operátor került bevezetésre, az ún. "upChucK" operátor (=^). Másik lényeges különbség, hogy a jelgenerátorokkal ellentétben az analizátorok, csak akkor végeznek számítást, ha arra külön igény érkezik az upchuck() függvényt meghívva.

Deklarálás

Minden analizátor objektum, ezért példányosításuk szükséges.

// FFT analizátor példányosítása, referencia tárolása az f változóban FFT f;

Csatlakoztatás

Az upChucK operátor (=^) csak UAna objektumok összekötésére van értelmezve. Működése hasonló a megszokott ChucK operátoréhoz. Két UAna összekötése esetén, az első számításának eredményét dolgozza fel a második UAna.

// FFT és Flux analizátorok példányosítása // összekapcsolás kialakítása: az audio bemenet spektrumának kiszámításához // valamint a spektrális fluxus számításához adc => FFT fft =^ Flux flux => blackhole;

Megjegyzendő, hogy a lánc utolsó UAna objektuma mindenféleképpen a blackhole vagy dac UGen-hez csatlakozzanak, hogy legyen ami "szívja" a hálózat elejére kötött UGen-ektől a szignált.

Lehetséges több UAna objektumot egy kifejezésben láncba fűzni. A lenti példán a flux_capacitor-nak szüksége van a flux által kiszámított adatokra, emiatt a flux objektum mindig a flux_capacitor előtt fogja elvégezni a számításait.

// adc analízis, FFT objektum, spektrális fluxus és egy kitalált FluxCapacitor // analizátorral, ami a flux által számított értékek alapján végez számítást adc => FFT fft =^ Flux flux =^ FluxCapacitor flux_capacitor => blackhole;

Fontos megjegyezni, hogy létre lehet hozni olyan hálózatot, ami tartalmaz UGen és UAna objektumokat egyaránt. Az alábbi példában egy FFT két szinusz UGen inputjait (azok összegét) transzformálja, úgy hogy az egyiken zengetés (reverb) effekt van. Egy IFFT a spektrumot vissza transzformálja idő tartományba, amit egy erősítőnek küld, ami pedig a dac-ra (audio kimenet) csatlakozik. (Ez a példa zeneileg semmi érdekeset nem hajt végre. Elsősorban a szintaxis megismerését hivatott megkönnyíteni. Jól megfigyelhető, hogy ahol a => operátor szerepel, ott audio szignálok, ahol pedig az =^ operátor, ott pedig spektrum adatok kerülnek továbbításra).

// Hálózat kiépítése: szinusz oszcillátor => zengetés effekt => FFT transzformáció // => IFFT transzformáció => erősítő => audio kimenet SinOsc s => JCRev r => FFT f =^ IFFT i => Gain g => dac; // Második szinusz oszcillátor csatlakoztatása az FFT-re SinOsc s2 => f;

FFT, IFFT és más UAna, ami az audio tartomány és egy másik tartomány között végez transzformációkat, különleges szerepet töltenek be, ahogy az a fenti példán is látszik. FFT bemenetére audio jelek érkeznek, ezért UGen-ek csatlakoznak a bemenetére a => operátorral. A kimenete viszont a spektrális tartományban értelmezett, ezért kimenete más UAna objektumhoz csatlakoztatható az =^ operátorral. Ezzel ellentétben az IFFT spektrális tartományból vár bemenő adatot (csatlakoztatás =^-al) és audio tartományba generál kimenő adatot (csatlakoztatva =>-al).

UAna esetén is lehetőség van dinamikusan leválasztani már összekötött objektumokat, az UnChucK operátor (=< vagy !=>) segítségével.

Vezérlés (időben)

Bármely ChucK programban szükséges léptetni az időt, hogy hangmintákat lehessen szívni a szintetizáló hálózatból és a hangot kiadni. UAna esetén továbbá szükséges még az analízis végrehajtásának explicit kiváltása ahhoz, hogy bármilyen számítás is elkezdődhessen. A számítás explicit kiváltásához az adott időpillanatban a upchuck() függvény meghívásával történik. Az alábbi példában egy FTT transzformáció kiszámítása kerül kiváltásra minden 1024 hangminta után.

// hálózat létrehozása adc => FFT fft => dac; // FFT buffer méret beállítása 2048 => fft.size; while (true) { // teljen el 1024 hangmintányi idő 1024::samp => now; // meghívjuk a kiszámítást előidéző függvényt // ez az elmúlt 2048 (fft.size) mintára fog számítást végezni fft.upchuck(); }

A fenti példában, amiért az FTT mérete 2048 minta, a ciklus miatt egy csúszóablakos FTT számítást eredményez, ahol a lépésszám az ablak méretének a fele. ChucK-ban tetszőlegesen, akár dinamikusan is beállítható, hogy mekkora legyen a lépésszáma az adott analizátornak.

Metaadat reprezentáció: UAnaBlob

Az upchuck() függvény visszatérési értéke egy UAnaBlob típusú objektum. Az UAnaBlob tartalmazhat lebegőpontos vagy komplex számok sorozatait. Az adatok értelmezése és formázása függ az őt létrehozó UAna objektumtól.

// hálózat létrehozása adc => FFT fft => blackhole; // ... FFT beállítása UAnaBlob blob; UAnaBlob blob2; // teljen el 0,5 mp 500::ms => now; // eredmény tárolása blob2-be fft.upchuck() @=> blob2; while (true) { // teljen el 0,5 mp 500::ms => now; // eredmény tárolása blob-ba fft.upchuck() @=> blob; // !!! blob és blob2 ugyanarra az objektumra hivatkozik !!! // upchuck() hívásakor az új értékkekel íródik felül az UAnaBlob // kiszámított adatok elérése blob.fvals() @=> float mag_spec[]; blob.cvals() @=> complex spec[]; blob.when() @=> time when_computed; }

Beépített UAna referencia

A jelenleg implementált jel analizátorok referenciája itt található.