diff --git a/source/ATK/sc/Classes/ATK.sc b/source/ATK/sc/Classes/ATK.sc deleted file mode 100644 index 42aefaa2d2..0000000000 --- a/source/ATK/sc/Classes/ATK.sc +++ /dev/null @@ -1,1398 +0,0 @@ -/* - Copyright the ATK Community, Joseph Anderson, and Josh Parmenter, 2011 - J Anderson j.anderson[at]ambisonictoolkit.net - J Parmenter j.parmenter[at]ambisonictoolkit.net - - - This file is part of SuperCollider3 version of the Ambisonic Toolkit (ATK). - - The SuperCollider3 version of the Ambisonic Toolkit (ATK) is free software: - you can redistribute it and/or modify it under the terms of the GNU General - Public License as published by the Free Software Foundation, either version 3 - of the License, or (at your option) any later version. - - The SuperCollider3 version of the Ambisonic Toolkit (ATK) is distributed in - the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See - the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with the - SuperCollider3 version of the Ambisonic Toolkit (ATK). If not, see - . -*/ - - -//--------------------------------------------------------------------- -// The Ambisonic Toolkit (ATK) is a soundfield kernel support library. -// -// Class (UGen superclass): Foa -// -// Class (UGen): FoaPanB -// -// Class (UGen): FoaDirectO -// Class (UGen): FoaDirectX -// Class (UGen): FoaDirectZ -// Class (UGen): FoaRotate -// Class (UGen): FoaTilt -// Class (UGen): FoaTumble -// Class (UGen): FoaFocusX -// Class (UGen): FoaFocusY -// Class (UGen): FoaFocusZ -// Class (UGen): FoaPushX -// Class (UGen): FoaPushY -// Class (UGen): FoaPushZ -// Class (UGen): FoaPressX -// Class (UGen): FoaPressY -// Class (UGen): FoaPressZ -// Class (UGen): FoaZoomX -// Class (UGen): FoaZoomY -// Class (UGen): FoaZoomZ -// Class (UGen): FoaDominateX -// Class (UGen): FoaDominateY -// Class (UGen): FoaDominateZ -// Class (UGen): FoaAsymmetry -// -// Class: FoaRTT -// Class: FoaMirror -// Class: FoaDirect -// Class: FoaDominate -// Class: FoaZoom -// Class: FoaFocus -// Class: FoaPush -// Class: FoaPress -// -// Class (UGen): FoaProximity -// Class (UGen): FoaNFC -// Class (UGen): FoaPsychoShelf -// -// Class: AtkMatrixMix -// Class: AtkKernelConv -// -// Class: FoaDecode -// Class: FoaEncode -// -// Class: FoaXform -// Class: FoaTransform -// -// The Ambisonic Toolkit (ATK) is intended to bring together a number of tools and -// methods for working with Ambisonic surround sound. The intention is for the toolset -// to be both ergonomic and comprehensive, providing both classic and novel algorithms -// to creatively manipulate and synthesise complex Ambisonic soundfields. -// -// The tools are framed for the user to think in terms of the soundfield kernel. By -// this, it is meant the ATK addresses the holistic problem of creatively controlling a -// complete soundfield, allowing and encouraging the composer to think beyond the placement -// of sounds in a sound-space and instead attend to the impression and image of a soundfield. -// This approach takes advantage of the model the Ambisonic technology presents, and is -// viewed to be the idiomatic mode for working with the Ambisonic technique. -// -// -// We hope you enjoy the ATK! -// -// For more information visit http://ambisonictoolkit.net/ or -// email info[at]ambisonictoolkit.net -// -//--------------------------------------------------------------------- - -Atk { - classvar 0; - hasRelPath = usrPN.colonIndices.size > 0; - - mtxDirPath = if (searchExtensions) { - Atk.getMatrixExtensionSubPath('FOA', mtxType); // hard coded to 'FOA'.. - } { - Atk.getAtkMatrixSubPath('FOA', mtxType); // .. for now - }; - - relPath = mtxDirPath +/+ usrPN; - - if (hasRelPath, - { // search specific path within matrix directory - if (hasExtension, { - - if( relPath.isFile, { - srcPath = relPath; // valid relative path, with file extension - },{ - Error(format("No file found at\n\t%\n", relPath)).throw; - }); - - }, { // user gives a path, but no file extension - - relWithoutLast = PathName( relPath.fullPath.dirname ); - - if (relWithoutLast.isFolder, // test enclosing folder - { - foundCnt = 0; - name = usrPN.fileNameWithoutExtension; - // NOTE: filesDo searches recursively in the parent folder, - // so keep track of matches in case there are multiple - relWithoutLast.filesDo{ - |file| - if (file.fileNameWithoutExtension == name, { - srcPath = file; - foundCnt = foundCnt+1; - }); - }; - - if (foundCnt >1) { - Error( format( - "Found multiple matches in recursive search of\n\t%\nPlease provide a more specific path", - relWithoutLast.fullPath - ) ).throw; - }; - - },{ - Error( format( - "Parent directory isn't a folder:\n\t%\n", - relWithoutLast.fullPath ) - ).throw; - } - ) - } - ); - }, { // single filename, no other path - matches = []; - - // name = usrPN.fileNameWithoutExtension; - name = usrPN.fileName; - - // recursively search whole directory - mtxDirPath.filesDo { |file| - var test; - test = if (hasExtension) {file.fileName} {file.fileNameWithoutExtension}; - if (test == name, { matches = matches.add(file) }); - }; - - case - { matches.size == 1 } { srcPath = matches[0] } - { matches.size == 0 } { Error( format("No file found for %", name) ).throw } - { matches.size > 1 } { - str = format("Multiple matches found for filename:\t%\n", usrPN.fileName); - matches.do{|file| str = str ++ "\t" ++ file.asRelativePath( mtxDirPath ) ++ "\n" }; - str = str ++ format( - "Provide either an absolute path to the matrix, or one relative to\n\t%\n", - mtxDirPath); - Error( str ).throw; - }; - }); - } - ); - - if( srcPath.notNil, - { - // postf("Found matrix file: \n\t> %\n\t> %\n", srcPath.asRelativePath(mtxDirPath), srcPath); - ^srcPath - },{ Error("No matrix file found!").throw } - ); - } - - *checkSet { |set| - Atk.sets.includes(set.asString.toUpper.asSymbol).not.if {^Error("Invalid set").throw}; - } - - - // NOTE: could be generalized for other user extensions, e.g. kernels, etc. - // type: 'decoders', 'encoders', 'xformers' - *postMyMatrices { |set, type| - var postContents; - - block { |break| - - if (set.isNil) { - // no set provided, show all sets - Atk.sets.do{ |thisSet| - Atk.postMyMatrices(thisSet, type) - }; - break.() - } { - Atk.checkSet(set); - }; - - postf("~ %%% ~\n", set.asString.toUpper, type.notNil.if({" "},{""}), type ?? ""); - - postContents = { |folderPN, depth=1| - var offset, f_offset; - offset = ("\t"!depth).join; - f_offset = ("\t"!(depth-1)).join; - postf("%:: % ::\n", f_offset, folderPN.folderName); - - // folderPN.fileName.postln; - folderPN.entries.do{ |entry| - - offset = ("\t"!depth).join; - offset.post; - entry.isFolder.if( - { postContents.(entry, depth+1) }, - { postf("%%\n", offset, entry.fileName) } - ) - }; - }; - - postContents.( - type.isNil.if( - { Atk.getAtkOpPath('matrices', isExtension:true) +/+ set.asString.toUpper }, - { - if ( - [ - 'decoders', 'encoders', 'xformers', - 'decoder', 'encoder', 'xformer' // include singular - ].includes(type.asSymbol) - ) - { Atk.getMatrixExtensionSubPath(set, type) } - { Error("'type' must be 'decoder', 'encoder', 'xformer', or nil (to see all matrix directories)").throw; }; - } - ); - - ); - } - } - -} - - -FoaPanB : MultiOutUGen { - - *ar { arg in, azimuth=0, elevation=0, mul = 1, add = 0; - ^this.multiNew('audio', in, azimuth, elevation ).madd(mul, add); - } - - init { arg ... theInputs; - inputs = theInputs; - channels = [ OutputProxy(\audio,this,0), OutputProxy(\audio,this,1), - OutputProxy(\audio,this,2), OutputProxy(\audio,this,3) ]; - ^channels - } - - checkInputs { ^this.checkNInputs(1) } -} - -Foa : MultiOutUGen { - - init { arg ... theInputs; - inputs = theInputs; - channels = [ OutputProxy(\audio,this,0), OutputProxy(\audio,this,1), - OutputProxy(\audio,this,2), OutputProxy(\audio,this,3) ]; - ^channels - } - - checkInputs { ^this.checkNInputs(4) } - - *checkChans {arg in; - (in.size < 4).if({ - ^([in] ++ (4 - in.size).collect({Silent.ar})).flat; - }, { - ^in - }); - } - - } - -FoaDirectO : Foa { - *ar { arg in, angle = pi/2, mul = 1, add = 0; - var w, x, y, z; - in = this.checkChans(in); - #w, x, y, z = in; - ^this.multiNew('audio', w, x, y, z, angle).madd(mul, add); - } -} - - -FoaDirectX : Foa { - *ar { arg in, angle = pi/2, mul = 1, add = 0; - var w, x, y, z; - in = this.checkChans(in); - #w, x, y, z = in; - ^this.multiNew('audio', w, x, y, z, angle).madd(mul, add); - } -} - -FoaDirectY : FoaDirectX { } -FoaDirectZ : FoaDirectX { } - -FoaRotate : Foa { - *ar { arg in, angle = 0, mul = 1, add = 0; - var w, x, y, z; - in = this.checkChans(in); - #w, x, y, z = in; - ^this.multiNew('audio', w, x, y, z, angle).madd(mul, add); - } -} -FoaTilt : FoaRotate { } -FoaTumble : FoaRotate { } - -FoaFocusX : FoaRotate { } -FoaFocusY : FoaRotate { } -FoaFocusZ : FoaRotate { } - -FoaPushX : FoaRotate { } -FoaPushY : FoaRotate { } -FoaPushZ : FoaRotate { } - -FoaPressX : FoaRotate { } -FoaPressY : FoaRotate { } -FoaPressZ : FoaRotate { } - -FoaZoomX : FoaRotate { } -FoaZoomY : FoaRotate { } -FoaZoomZ : FoaRotate { } - -FoaBalance { - *ar { arg in, angle = 0, mul = 1, add = 0; - var w, x, y, z; - in = this.checkChans(in); - #w, x, y, z = in; - ^FoaZoomY.ar(w, x, y, z, angle, mul, add); - } -} - - -FoaDominateX : Foa { - *ar { arg in, gain = 0, mul = 1, add = 0; - var w, x, y, z; - in = this.checkChans(in); - #w, x, y, z = in; - ^this.multiNew('audio', w, x, y, z, gain).madd(mul, add); - } -} - -FoaDominateY : FoaDominateX { } -FoaDominateZ : FoaDominateX { } - -FoaAsymmetry : FoaRotate { } - - -FoaRTT { - *ar { arg in, rotAngle = 0, tilAngle = 0, tumAngle = 0, mul = 1, add = 0; - in = FoaRotate.ar(in, rotAngle); - in = FoaTilt.ar(in, tilAngle); - ^FoaTumble.ar(in, tumAngle, mul, add); - } -} - -FoaMirror { - *ar { arg in, theta = 0, phi = 0, mul = 1, add = 0; - in = FoaRotate.ar(in, theta.neg); - in = FoaTumble.ar(in, phi.neg); - in = FoaXform.ar(in, FoaXformerMatrix.newMirrorX); - in = FoaTumble.ar(in, phi); - ^FoaRotate.ar(in, theta, mul, add); - } -} - -FoaDirect { - *ar { arg in, angle = 0, theta = 0, phi = 0, mul = 1, add = 0; - - in = FoaRotate.ar(in, theta.neg); - in = FoaTumble.ar(in, phi.neg); - in = FoaDirectX.ar(in, angle); - in = FoaTumble.ar(in, phi); - ^FoaRotate.ar(in, theta, mul, add); - } -} - -FoaDominate { - *ar { arg in, gain = 0, theta = 0, phi = 0, mul = 1, add = 0; - - in = FoaRotate.ar(in, theta.neg); - in = FoaTumble.ar(in, phi.neg); - in = FoaDominateX.ar(in, gain); - in = FoaTumble.ar(in, phi); - ^FoaRotate.ar(in, theta, mul, add); - } -} - -FoaZoom { - *ar { arg in, angle = 0, theta = 0, phi = 0, mul = 1, add = 0; - - in = FoaRotate.ar(in, theta.neg); - in = FoaTumble.ar(in, phi.neg); - in = FoaZoomX.ar(in, angle); - in = FoaTumble.ar(in, phi); - ^FoaRotate.ar(in, theta, mul, add); - } -} - -FoaFocus { - *ar { arg in, angle = 0, theta = 0, phi = 0, mul = 1, add = 0; - - in = FoaRotate.ar(in, theta.neg); - in = FoaTumble.ar(in, phi.neg); - in = FoaFocusX.ar(in, angle); - in = FoaTumble.ar(in, phi); - ^FoaRotate.ar(in, theta, mul, add); - } -} - -FoaPush { - *ar { arg in, angle = 0, theta = 0, phi = 0, mul = 1, add = 0; - - in = FoaRotate.ar(in, theta.neg); - in = FoaTumble.ar(in, phi.neg); - in = FoaPushX.ar(in, angle); - in = FoaTumble.ar(in, phi); - ^FoaRotate.ar(in, theta, mul, add); - } -} - -FoaPress { - *ar { arg in, angle = 0, theta = 0, phi = 0, mul = 1, add = 0; - - in = FoaRotate.ar(in, theta.neg); - in = FoaTumble.ar(in, phi.neg); - in = FoaPressX.ar(in, angle); - in = FoaTumble.ar(in, phi); - ^FoaRotate.ar(in, theta, mul, add); - } -} - - -//------------------------------------------------------------------------ -// Filters - -FoaProximity : Foa { - *ar { arg in, distance = 1, mul = 1, add = 0; - var w, x, y, z; - in = this.checkChans(in); - #w, x, y, z = in; - ^this.multiNew('audio', w, x, y, z, distance).madd(mul, add); - } - -} - -FoaNFC : Foa { - *ar { arg in, distance = 1, mul = 1, add = 0; - var w, x, y, z; - in = this.checkChans(in); - #w, x, y, z = in; - ^this.multiNew('audio', w, x, y, z, distance).madd(mul, add); - } - -} - -FoaPsychoShelf : Foa { - *ar { arg in, freq = 400, k0 = (3/2).sqrt, k1 = 3.sqrt/2, mul = 1, add = 0; - var w, x, y, z; - in = this.checkChans(in); - #w, x, y, z = in; - ^this.multiNew('audio', w, x, y, z, freq, k0, k1).madd(mul, add); - } - -} - - -//------------------------------------------------------------------------ -// AtkMatrixMix & AtkKernelConv - -AtkMatrixMix { - *ar { arg in, matrix, mul = 1, add = 0; - - var out; - - // wrap input as array if needed, for mono inputs - in.isArray.not.if({ in = [in] }); - - out = Mix.fill( matrix.cols, { arg i; // fill input - UGen.replaceZeroesWithSilence( - matrix.flop.asArray.at(i) * in.at(i) - ) - }); - - ^out.madd(mul, add) - } -} - -AtkKernelConv { - *ar { arg in, kernel, mul = 1, add = 0; - - var out; - - // wrap input as array if needed, for mono inputs - in.isArray.not.if({ in = [in] }); - - out = Mix.new( - kernel.shape.at(0).collect({ arg i; - kernel.shape.at(1).collect({ arg j; - Convolution2.ar( - in.at(i), - kernel.at(i).at(j), - framesize: kernel.at(i).at(j).numFrames - ) - }) - }) - ); - - ^out.madd(mul, add) - } -} - - -//------------------------------------------------------------------------ -// Decoder built using AtkMatrixMix & AtkKernelConv - -FoaUGen { - *checkChans {arg in; - (in.size < 4).if({ - ^([in] ++ (4 - in.size).collect({Silent.ar})).flat; - }, { - ^in - }); - } - - *argDict { arg ugen, args, argDefaults; - var index, userDict; - var ugenKeys; - var ugenDict; - // find index dividing ordered and named args - index = args.detectIndex({arg item; item.isKindOf(Symbol)}); - - // find ugen args, drop [ 'this', sig] - ugenKeys = ugen.class.findRespondingMethodFor(\ar).argNames.drop(2); - ugenDict = Dictionary.new; - ugenKeys.do({arg key, i; ugenDict.put(key, argDefaults.at(i))}); - - // build user dictionary - userDict = Dictionary.new(ugenKeys.size); - (index == nil).not.if({ - userDict = userDict.putAll(Dictionary.newFrom(args[index..])); - }, { - index = args.size; - }); - userDict = userDict.putAll(Dictionary.newFrom((index).collect({arg i; - [ugenKeys.at(i), args.at(i)]}).flat)); - - // merge - ^ugenDict.merge(userDict, { - arg ugenArg, userArg; (userArg != nil).if({userArg}) - }) - } -} - -FoaDecode : FoaUGen { - *ar { arg in, decoder, mul = 1, add = 0; - in = this.checkChans(in); - - case - { decoder.isKindOf(FoaDecoderMatrix) } { - - if ( decoder.shelfFreq.isNumber, { // shelf filter? - in = FoaPsychoShelf.ar(in, - decoder.shelfFreq, decoder.shelfK.at(0), decoder.shelfK.at(1)) - }); - - ^AtkMatrixMix.ar(in, decoder.matrix, mul, add) - } - { decoder.isKindOf(FoaDecoderKernel) } { - ^AtkKernelConv.ar(in, decoder.kernel, mul, add) - }; - } -} - - -//------------------------------------------------------------------------ -// Encoder built using AtkMatrixMix & AtkKernelConv - -FoaEncode : FoaUGen { - *ar { arg in, encoder, mul = 1, add = 0; - var out; - - case - { encoder.isKindOf(FoaEncoderMatrix) } { - out = AtkMatrixMix.ar(in, encoder.matrix, mul, add) - } - { encoder.isKindOf(FoaEncoderKernel) } { - out = AtkKernelConv.ar(in, encoder.kernel, mul, add) - }; - -// if ( out.size < 4, { // 1st order, fill missing harms with zeros -// out = out ++ Silent.ar(4 - out.size) -// }); - out = this.checkChans(out); - ^out - } -} - - -//------------------------------------------------------------------------ -// Transformer built using AtkMatrixMix & AtkKernelConv - -FoaXform : FoaUGen { - *ar { arg in, xformer, mul = 1, add = 0; - - var out; - in = this.checkChans(in); - -// switch ( xformer.class, -// -// FoaXformerMatrix, { -// out = AtkMatrixMix.ar(in, xformer.matrix, mul, add) -// }, -// -// FoaXformerKernel, { -// out = AtkKernelConv.ar(in, xformer.kernel, mul, add) -// } -// ); -// -// ^out - - // for now... - ^AtkMatrixMix.ar(in, xformer.matrix, mul, add) - } -} - - -//------------------------------------------------------------------------ -// Transformer: UGen wrapper -/* -argument key - see helpfile for reasonable values -'rtt' - angle - -*/ - -FoaTransform : FoaUGen { - *ar { arg in, kind ... args; - - var argDict, argDefaults; - var ugen; - in = this.checkChans(in); - -// argDict = { arg ugen, args, argDefaults; -// var index, userDict; -// var ugenKeys; -// var ugenDict; -// [ugen, args, argDefaults].postln; -// // find index dividing ordered and named args -// index = args.detectIndex({arg item; item.isKindOf(Symbol)}); -// -// // find ugen args, drop [ 'this', w, x, y, z ] -// ugenKeys = ugen.class.findRespondingMethodFor(\ar).argNames.drop(2); -// ugenDict = Dictionary.new; -// ugenKeys.do({arg key, i; ugenDict.put(key, argDefaults.at(i))}); -// -// // build user dictionary -// userDict = Dictionary.new(ugenKeys.size); -// (index == nil).not.if({ -// userDict = userDict.putAll(Dictionary.newFrom(args[index..])); -// }, { -// index = args.size; -// }); -// userDict = userDict.putAll(Dictionary.newFrom((index).collect({arg i; -// [ugenKeys.at(i), args.at(i)]}).flat)); -// -// // merge -// ugenDict.merge(userDict, { -// arg ugenArg, userArg; (userArg != nil).if({userArg}) -// }) -// }; -// - - switch ( kind, - - 'rotate', { - - ugen = FoaRotate; - argDefaults = [0, 1, 0]; - - argDict = this.argDict(ugen, args, argDefaults); - - ^ugen.ar( - in, - argDict.at(\angle), argDict.at(\mul), argDict.at(\add) - ) - }, - - 'tilt', { - - ugen = FoaTilt; - argDefaults = [0, 1, 0]; - - argDict = this.argDict(ugen, args, argDefaults); - - ^ugen.ar( - in, - argDict.at(\angle), argDict.at(\mul), argDict.at(\add) - ) - }, - - 'tumble', { - - ugen = FoaTumble; - argDefaults = [0, 1, 0]; - - argDict = this.argDict(ugen, args, argDefaults); - - ^ugen.ar( - in, - argDict.at(\angle), argDict.at(\mul), argDict.at(\add) - ) - }, - - 'directO', { - - ugen = FoaDirectO; - argDefaults = [0, 1, 0]; - - argDict = this.argDict(ugen, args, argDefaults); - - ^ugen.ar( - in, - argDict.at(\angle), argDict.at(\mul), argDict.at(\add) - ) - }, - - 'directX', { - - ugen = FoaDirectX; - argDefaults = [0, 1, 0]; - - argDict = this.argDict(ugen, args, argDefaults); - - ^ugen.ar( - in, - argDict.at(\angle), argDict.at(\mul), argDict.at(\add) - ) - }, - - 'directY', { - - ugen = FoaDirectY; - argDefaults = [0, 1, 0]; - - argDict = this.argDict(ugen, args, argDefaults); - - ^ugen.ar( - in, - argDict.at(\angle), argDict.at(\mul), argDict.at(\add) - ) - }, - - 'directZ', { - - ugen = FoaDirectZ; - argDefaults = [0, 1, 0]; - - argDict = this.argDict(ugen, args, argDefaults); - - ^ugen.ar( - in, - argDict.at(\angle), argDict.at(\mul), argDict.at(\add) - ) - }, - - 'dominateX', { - - ugen = FoaDominateX; - argDefaults = [0, 1, 0]; - - argDict = this.argDict(ugen, args, argDefaults); - - ^ugen.ar( - in, - argDict.at(\gain), argDict.at(\mul), argDict.at(\add) - ) - }, - - 'dominateY', { - - ugen = FoaDominateY; - argDefaults = [0, 1, 0]; - - argDict = this.argDict(ugen, args, argDefaults); - - ^ugen.ar( - in, - argDict.at(\gain), argDict.at(\mul), argDict.at(\add) - ) - }, - - 'dominateZ', { - - ugen = FoaDominateZ; - argDefaults = [0, 1, 0]; - - argDict = this.argDict(ugen, args, argDefaults); - - ^ugen.ar( - in, - argDict.at(\gain), argDict.at(\mul), argDict.at(\add) - ) - }, - - 'zoomX', { - - ugen = FoaZoomX; - argDefaults = [0, 1, 0]; - - argDict = this.argDict(ugen, args, argDefaults); - - ^ugen.ar( - in, - argDict.at(\angle), argDict.at(\mul), argDict.at(\add) - ) - }, - - 'zoomY', { - - ugen = FoaZoomY; - argDefaults = [0, 1, 0]; - - argDict = this.argDict(ugen, args, argDefaults); - - ^ugen.ar( - in, - argDict.at(\angle), argDict.at(\mul), argDict.at(\add) - ) - }, - - 'zoomZ', { - - ugen = FoaZoomZ; - argDefaults = [0, 1, 0]; - - argDict = this.argDict(ugen, args, argDefaults); - - ^ugen.ar( - in, - argDict.at(\angle), argDict.at(\mul), argDict.at(\add) - ) - }, - - 'focusX', { - - ugen = FoaFocusX; - argDefaults = [0, 1, 0]; - - argDict = this.argDict(ugen, args, argDefaults); - - ^ugen.ar( - in, - argDict.at(\angle), argDict.at(\mul), argDict.at(\add) - ) - }, - - 'focusY', { - - ugen = FoaFocusY; - argDefaults = [0, 1, 0]; - - argDict = this.argDict(ugen, args, argDefaults); - - ^ugen.ar( - in, - argDict.at(\angle), argDict.at(\mul), argDict.at(\add) - ) - }, - - 'focusZ', { - - ugen = FoaFocusZ; - argDefaults = [0, 1, 0]; - - argDict = this.argDict(ugen, args, argDefaults); - - ^ugen.ar( - in, - argDict.at(\angle), argDict.at(\mul), argDict.at(\add) - ) - }, - - 'pushX', { - - ugen = FoaPushX; - argDefaults = [0, 1, 0]; - - argDict = this.argDict(ugen, args, argDefaults); - - ^ugen.ar( - in, - argDict.at(\angle), argDict.at(\mul), argDict.at(\add) - ) - }, - - 'pushY', { - - ugen = FoaPushY; - argDefaults = [0, 1, 0]; - - argDict = this.argDict(ugen, args, argDefaults); - - ^ugen.ar( - in, - argDict.at(\angle), argDict.at(\mul), argDict.at(\add) - ) - }, - - 'pushZ', { - - ugen = FoaPushZ; - argDefaults = [0, 1, 0]; - - argDict = this.argDict(ugen, args, argDefaults); - - ^ugen.ar( - in, - argDict.at(\angle), argDict.at(\mul), argDict.at(\add) - ) - }, - - 'pressX', { - - ugen = FoaPressX; - argDefaults = [0, 1, 0]; - - argDict = this.argDict(ugen, args, argDefaults); - - ^ugen.ar( - in, - argDict.at(\angle), argDict.at(\mul), argDict.at(\add) - ) - }, - - 'pressY', { - - ugen = FoaPressY; - argDefaults = [0, 1, 0]; - - argDict = this.argDict(ugen, args, argDefaults); - - ^ugen.ar( - in, - argDict.at(\angle), argDict.at(\mul), argDict.at(\add) - ) - }, - - 'pressZ', { - - ugen = FoaPressZ; - argDefaults = [0, 1, 0]; - - argDict = this.argDict(ugen, args, argDefaults); - - ^ugen.ar( - in, - argDict.at(\angle), argDict.at(\mul), argDict.at(\add) - ) - }, - - 'asymmetry', { - - ugen = FoaAsymmetry; - argDefaults = [0, 1, 0]; - - argDict = this.argDict(ugen, args, argDefaults); - - ^ugen.ar( - in, - argDict.at(\angle), argDict.at(\mul), argDict.at(\add) - ) - }, - - 'balance', { - - ugen = FoaZoomY; - argDefaults = [0, 1, 0]; - - argDict = this.argDict(ugen, args, argDefaults); - - ^ugen.ar( - in, - argDict.at(\angle), argDict.at(\mul), argDict.at(\add) - ) - }, - - 'rtt', { - - ugen = FoaRTT; - argDefaults = [0, 0, 0, 1, 0]; - - argDict = this.argDict(ugen, args, argDefaults); - - ^ugen.ar( - in, - argDict.at(\rotAngle), argDict.at(\tilAngle), argDict.at(\tumAngle), - argDict.at(\mul), argDict.at(\add) - ) - }, - - 'mirror', { - - ugen = FoaMirror; - argDefaults = [0, 0, 1, 0]; - - argDict = this.argDict(ugen, args, argDefaults); - - ^ugen.ar( - in, - argDict.at(\theta), argDict.at(\phi), - argDict.at(\mul), argDict.at(\add) - ) - }, - - 'direct', { - - ugen = FoaDirect; - argDefaults = [0, 0, 0, 1, 0]; - - argDict = this.argDict(ugen, args, argDefaults); - - ^ugen.ar( - in, - argDict.at(\angle), argDict.at(\theta), argDict.at(\phi), - argDict.at(\mul), argDict.at(\add) - ) - }, - - 'dominate', { - - ugen = FoaDominate; - argDefaults = [0, 0, 0, 1, 0]; - - argDict = this.argDict(ugen, args, argDefaults); - - ^ugen.ar( - in, - argDict.at(\gain), argDict.at(\theta), argDict.at(\phi), - argDict.at(\mul), argDict.at(\add) - ) - }, - - 'zoom', { - - ugen = FoaZoom; - argDefaults = [0, 0, 0, 1, 0]; - - argDict = this.argDict(ugen, args, argDefaults); - - ^ugen.ar( - in, - argDict.at(\angle), argDict.at(\theta), argDict.at(\phi), - argDict.at(\mul), argDict.at(\add) - ) - }, - - 'focus', { - - ugen = FoaFocus; - argDefaults = [0, 0, 0, 1, 0]; - - argDict = this.argDict(ugen, args, argDefaults); - - ^ugen.ar( - in, - argDict.at(\angle), argDict.at(\theta), argDict.at(\phi), - argDict.at(\mul), argDict.at(\add) - ) - }, - - 'push', { - - ugen = FoaPush; - argDefaults = [0, 0, 0, 1, 0]; - - argDict = this.argDict(ugen, args, argDefaults); - - ^ugen.ar( - in, - argDict.at(\angle), argDict.at(\theta), argDict.at(\phi), - argDict.at(\mul), argDict.at(\add) - ) - }, - - 'press', { - - ugen = FoaPress; - argDefaults = [0, 0, 0, 1, 0]; - - argDict = this.argDict(ugen, args, argDefaults); - - ^ugen.ar( - in, - argDict.at(\angle), argDict.at(\theta), argDict.at(\phi), - argDict.at(\mul), argDict.at(\add) - ) - }, - - 'nfc', { - - ugen = FoaNFC; - argDefaults = [1, 1, 0]; - - argDict = this.argDict(ugen, args, argDefaults); - - ^ugen.ar( - in, - argDict.at(\distance), - argDict.at(\mul), argDict.at(\add) - ) - }, - - 'proximity', { - - ugen = FoaProximity; - argDefaults = [1, 1, 0]; - - argDict = this.argDict(ugen, args, argDefaults); - - ^ugen.ar( - in, - argDict.at(\distance), - argDict.at(\mul), argDict.at(\add) - ) - } - ) - } -} diff --git a/source/ATK/sc/Classes/ATKMatrix.sc b/source/ATK/sc/Classes/ATKMatrix.sc deleted file mode 100644 index c77188c8df..0000000000 --- a/source/ATK/sc/Classes/ATKMatrix.sc +++ /dev/null @@ -1,2767 +0,0 @@ -/* - Copyright the ATK Community and Joseph Anderson, 2011-2016 - J Anderson j.anderson[at]ambisonictoolkit.net - - - This file is part of SuperCollider3 version of the Ambisonic Toolkit (ATK). - - The SuperCollider3 version of the Ambisonic Toolkit (ATK) is free software: - you can redistribute it and/or modify it under the terms of the GNU General - Public License as published by the Free Software Foundation, either version 3 - of the License, or (at your option) any later version. - - The SuperCollider3 version of the Ambisonic Toolkit (ATK) is distributed in - the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See - the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with the - SuperCollider3 version of the Ambisonic Toolkit (ATK). If not, see - . -*/ - - -//--------------------------------------------------------------------- -// The Ambisonic Toolkit (ATK) is a soundfield kernel support library. -// -// Class: FoaSpeakerMatrix -// Class: FoaDecoderMatrix -// Class: FoaEncoderMatrix -// Class: FoaDecoderKernel -// Class: FoaEncoderKernel -// -// The Ambisonic Toolkit (ATK) is intended to bring together a number of tools and -// methods for working with Ambisonic surround sound. The intention is for the toolset -// to be both ergonomic and comprehensive, providing both classic and novel algorithms -// to creatively manipulate and synthesise complex Ambisonic soundfields. -// -// The tools are framed for the user to think in terms of the soundfield kernel. By -// this, it is meant the ATK addresses the holistic problem of creatively controlling a -// complete soundfield, allowing and encouraging the composer to think beyond the placement -// of sounds in a sound-space and instead attend to the impression and image of a soundfield. -// This approach takes advantage of the model the Ambisonic technology presents, and is -// viewed to be the idiomatic mode for working with the Ambisonic technique. -// -// -// We hope you enjoy the ATK! -// -// For more information visit http://ambisonictoolkit.net/ or -// email info[at]ambisonictoolkit.net -// -//--------------------------------------------------------------------- - - -//------------------------------------------------------------------------ -// Third Party Notices -//------------------------------------------------------------------------ -// -//----------------------------------------------------------------------- -// Support for Gerzon's Diametric Decoder Theorem (DDT) decoding algorithm is derived -// from Aaron Heller's Octave code available at: http://www.ai.sri.com/ajh/ambisonics/ -// -// Benjamin, et al., "Localization in Horizontal-Only Ambisonic Systems" -// Preprint from AES-121, 10/2006, San Francisco -// -// Implementation in the SuperCollider3 version of the ATK is by -// Joseph Anderson -//----------------------------------------------------------------------- -// -//----------------------------------------------------------------------- -// Irregular array decoding coefficients (5.0, 7.0) are kindly provided by -// Bruce Wiggins: http://www.brucewiggins.co.uk/ -// -// B. Wiggins, "An Investigation into the Real-time Manipulation and Control of -// Three-dimensional Sound Fields," PhD Thesis, University of Derby, Derby, 2004. -//----------------------------------------------------------------------- - - -//----------------------------------------------------------------------- -// matrix decoders - -// Heller's DDT (helper function) -FoaSpeakerMatrix { - var 1) { - postf("\n% : [\n", attribute); - value.do{ |elem| postf("\t%\n", elem) }; - " ]".postln; - } { - postf("\n% : \n\t%\n", attribute, value); - } - } { - postf("\n% : %\n", attribute, value); - }; - }; - } - - // For subclasses of AtkMatrix - writeToFile { arg fileNameOrPath, note, attributeDictionary, overwrite=false; - this.prWriteToFile(fileNameOrPath, this.set, this.type, note, attributeDictionary, overwrite); - } - - // argSet: FOA, HOA1, HOA2, etc - // argType: \encoder, \decoder, \xformer - prWriteToFile { arg fileNameOrPath, argSet, argType, note, attributeDictionary, overwrite=false; - var pn, writer, ext; - var mtxPath, relPath; - - pn = PathName(fileNameOrPath); - - if (PathName(pn.parentPath).isFolder.not) { // check for an enclosing folder - // ... no enclosing folder found so assumed - // to be relative to extensions/matrices/'type' directory - - Atk.checkSet(argSet); - - // This is only needed for relative file paths in user-matrices directory - ['encoder', 'decoder', 'xformer'].includes(argType).not.if{ - Error("'type' argument must be 'encoder', 'decoder', or 'xformer'").throw; ^this - }; - - case - { pn.colonIndices.size == 0} { - // only filename provided, write to dir matching 'type' - pn = Atk.getMatrixExtensionSubPath(argSet, argType) +/+ pn; - - } { pn.colonIndices.size > 0} { - // relative path given, look for it - mtxPath = Atk.getMatrixExtensionSubPath(argSet, argType); - relPath = (mtxPath +/+ PathName(pn.parentPath)); - if (relPath.isFolder) { - // valid relative path confirmed - pn = mtxPath +/+ pn; - } { - Error( - format( - "Specified relative folder path was not found in %\n", - relPath.fullPath - ) - ).throw; - ^this - } - }; - }; // otherwise, provided path is absolute - - ext = pn.extension; - if (ext == "") {pn = pn +/+ PathName(".yml")}; - - overwrite.not.if{ - pn.isFile.if{ - Error(format( - "File already exists:\n\t%\nChoose another name or location, or set overwrite:true", - pn.fullPath - )).throw; ^this} - }; - - case - {ext == "txt"} { - if (pn.fileName.contains(".mosl")) { - this.prWriteMatrixToMOSL(pn) - } { - this.prWriteMatrixToTXT(pn) - } - } - {ext == "yml"} {this.prWriteMatrixToYML(pn, argSet, argType, note, attributeDictionary)} - { // catch all - Error( format( "%%", - "Invalid file extension: provide '.txt' for writing matrix only, ", - "or '.yml' or no extension to write matrix with metadata (as YAML)") - ).throw; - }; - } - - - prWriteMatrixToTXT { arg pn; // a PathName - var writer; - writer = FileWriter( pn.fullPath ); - // write the matrix into it by row, and close - matrix.rows.do{ |i| writer.writeLine( matrix.getRow(i) ) }; - writer.close - } - - prWriteMatrixToMOSL { arg pn; // a PathName - var writer; - writer = FileWriter( pn.fullPath ); - - // write num rows and cols to first 2 lines - writer.writeLine(["// Dimensions: rows, columns"]); - writer.writeLine(matrix.rows.asArray); - writer.writeLine(matrix.cols.asArray); - // write the matrix into it by row, and close - matrix.rows.do{ |i| - var row; - writer.writeLine([""]); // blank line - writer.writeLine([format("// Row %", i)]); - - row = matrix.getRow(i); - row.do{ |j| writer.writeLine( j.asArray ) }; - }; - writer.close; - } - - prWriteMatrixToYML { arg pn, set, type, note, attributeDictionary; - var writer, defAttributes; - - writer = FileWriter( pn.fullPath ); - - // writer.writeLine(["matrix :"] ++ m.asArray.asString.split($ )); // all one line - - // overkill on formatting, but more readable... - writer.writeLine(["matrix : ["]); - matrix.rows.do{ |i| - var line, row; - row = matrix.getRow(i); - line = row.asString.split($ ); - if ((i+1) != matrix.rows) {line[line.size-1] = line.last ++ ","}; - writer.writeLine(line); - }; - writer.writeLine(["]"]); - - type !? { - writer.writeLine([]); - writer.writeLine( ["type", ":", type] ) - }; - - // write default attributes - defAttributes = [\kind, \dirOutputs, \dirInputs]; - if (type=='decoder') { - defAttributes = defAttributes ++ [\shelfK,\shelfFreq] - }; - - if (attributeDictionary.notNil) { - // make sure attribute dict doesn't explicitly set the attribute first - defAttributes.do{ |attribute| - attributeDictionary[attribute] ?? { - writer.writeLine([]); //newline for readability - writer.writeLine( [attribute, ":", this.tryPerform(attribute)] ) - } - }; - } { - defAttributes.do{ |attribute| - writer.writeLine([]); //newline for readability - writer.writeLine( [attribute, ":", this.tryPerform(attribute)] ) - }; - }; - - note !? { - writer.writeLine([]); - writer.writeLine( ["note", ":", note] ) - }; - - attributeDictionary !? { - attributeDictionary.keysValuesDo{ |k,v| - writer.writeLine([]); - writer.writeLine( [k.asString, ":", v] ) - } - }; - - writer.close; - } - - prParseMOSL { |pn| - var file, numRows, numCols, mtx, row; - file = FileReader.read(pn.fullPath); - numRows = nil; - numCols = nil; - mtx = []; - row = []; - file.do{ |line| - var val = line[0]; - switch( val, - "//", {}, // ignore comments - "", {}, // ignore blank line - { // found valid line - case - {numRows.isNil} { numRows = val.asInt } - {numCols.isNil} { numCols = val.asInt } - { - row = row.add(val.asFloat); - if (row.size==numCols) { - mtx = mtx.add(row); - row = []; - } - } - } - ) - }; - // test matrix dimensions - (mtx.size==numRows).not.if{ - Error( - format( - "Mismatch in matrix dimensions: rows specified [%], rows parsed from file [%]", - numRows, mtx.size - ) - ).throw - }; - mtx.do{ |row, i| - if (row.size!=numCols) { - Error( - format( - "Mismatch in matrix dimensions: rows % has % columns, but file species %", - i, row.size, numCols - ) - ).throw - } - }; - - ^mtx - } - - fileName { ^try {PathName(filePath).fileName} } - - loadFromLib { |...args| - var pathStr; - pathStr = this.kind.asString ++ "/"; - - args.do{ |argParam, i| - pathStr = if (i>0) { - format("%-%", pathStr, argParam.asString) - } { - format("%%", pathStr, argParam.asString) - }; - }; - - this.initFromFile( - // format("%/%-%.yml", this.kind, *args), - pathStr++".yml", - this.type - ); - - switch( this.type, - '\encoder', {this.initEncoderVarsForFiles}, // properly set dirInputs - '\decoder', {this.initDecoderVarsForFiles}, // properly set dirOutputs - '\xformer', {} - ) - } - -} - -FoaDecoderMatrix : AtkMatrix { - var shelfFreq, missing kernel database - { databasePath.isFolder.not } - { - errorMsg = "ATK kernel database missing!" + - "Please install % database.".format(kind) - } - - // --> unsupported SR - { PathName.new(subjectPath.parentLevelPath(2)).isFolder.not } - { - "Supported samplerates:".warn; - PathName.new(subjectPath.parentLevelPath(3)).folders.do({ - arg folder; - ("\t" + folder.folderName).postln; - }); - - errorMsg = "Samplerate = % is not available for".format(sampleRate) - + - "% kernel decoder.".format(kind) - } - - // --> unsupported kernelSize - { PathName.new(subjectPath.parentLevelPath(1)).isFolder.not } - { - "Supported kernel sizes:".warn; - PathName.new(subjectPath.parentLevelPath(2)).folders.do({ - arg folder; - ("\t" + folder.folderName).postln; - }); - - errorMsg = "Kernel size = % is not available for".format(kernelSize) - + - "% kernel decoder.".format(kind) - } - - // --> unsupported subject - { subjectPath.isFolder.not } - { - "Supported subjects:".warn; - PathName.new(subjectPath.parentLevelPath(1)).folders.do({ - arg folder; - ("\t" + folder.folderName).postln; - }); - - errorMsg = "Subject % is not available for".format(subjectID) - + - "% kernel decoder.".format(kind) - }; - - // throw error! - "\n".post; - Error(errorMsg).throw - }, { - score.isNil.if({ - if ( server.serverRunning.not, { // is server running? - - // throw server error! - Error( - "Please boot server: %. Encoder kernel failed to load.".format( - server.name.asString - ) - ).throw - }, { - // Else... everything is fine! Load kernel. - kernel = subjectPath.files.collect({ arg kernelPath; - chans.collect({ arg chan; - Buffer.readChannel(server, kernelPath.fullPath, channels: [chan], - action: { arg buf; - ( - kernelBundle = kernelBundle.add( - ["/b_allocReadChannel", buf.bufnum, kernelPath.fullPath, 0, kernelSize, chan] - ); - kernelInfo = kernelInfo.add([kernelPath.fullPath, buf.bufnum, [chan]]); - "Kernel %, channel % loaded.".format( - kernelPath.fileName, chan - ) - ).postln - } - ) - }) - }) - }) - }); - - score.isKindOf(CtkScore).if({ - kernel = subjectPath.files.collect({ arg kernelPath; - chans.collect({ arg chan; - var buf = CtkBuffer(kernelPath.fullPath, channels: [chan]); - kernelInfo = kernelInfo.add([kernelPath.fullPath, buf.bufnum, [chan]]); - score.add(buf); - buf; - }) - }) - }); - - score.isKindOf(Score).if({ - kernel = subjectPath.files.collect({ arg kernelPath; - chans.collect({ arg chan; - var buf; - buf = Buffer(server, kernelSize); - kernelBundle = kernelBundle.add( - ["/b_allocReadChannel", buf.bufnum, kernelPath.fullPath, 0, kernelSize, chan] - ); - kernelInfo = kernelInfo.add([kernelPath.fullPath, buf.bufnum, [chan]]); - buf; - }) - }); - score.add(kernelBundle) - }); - - (score.isKindOf(CtkScore).not && score.isKindOf(Score).not && score.notNil).if( { - Error( - "Score is not a Score or a CtkScore. Score is a %.".format( - score.class.asString - ) - ).throw - - }) - - - }) - } - - free { - var path; - kernel.shape.at(0).do({ arg i; - kernel.shape.at(1).do({ arg j; - path = kernel.at(i).at(j).path; - kernel.at(i).at(j).free; - ( - "Kernel %, channel % freed.".format( - PathName.new(path).fileName, j - ) - ).postln - }) - }) - } - - buffers { ^kernel.flat } - - kernelInfo { ^kernelInfo } - - kernelBundle { ^kernelBundle } - - dim { ^kernel.shape.at(0) - 1} - - numChannels { ^kernel.shape.at(1) } - - kernelSize { ^kernel.at(0).at(0).numFrames } - - numOutputs { ^kernel.shape.at(1) } - - dirOutputs { ^dirChannels } - - numInputs { ^kernel.shape.at(0) } - - dirInputs { ^this.numInputs.collect({ inf }) } - - type { ^'decoder' } - - printOn { arg stream; - stream << this.class.name << "(" <<* - [kind, this.dim, this.numChannels, subjectID, this.kernelSize] <<")"; - } -} - - -//------------------------------------------------------------------------ -// kernel encoders - -FoaEncoderKernel { - var missing kernel database - { databasePath.isFolder.not } - { - errorMsg = "ATK kernel database missing!" + - "Please install % database.".format(kind) - } - - // --> unsupported SR - { PathName.new(subjectPath.parentLevelPath(2)).isFolder.not } - { - "Supported samplerates:".warn; - PathName.new(subjectPath.parentLevelPath(3)).folders.do({ - arg folder; - ("\t" + folder.folderName).postln; - }); - - errorMsg = "Samplerate = % is not available for".format(sampleRate) - + - "% kernel encoder.".format(kind) - } - - // --> unsupported kernelSize - { PathName.new(subjectPath.parentLevelPath(1)).isFolder.not } - { - "Supported kernel sizes:".warn; - PathName.new(subjectPath.parentLevelPath(2)).folders.do({ - arg folder; - ("\t" + folder.folderName).postln; - }); - - errorMsg = "Kernel size = % is not available for".format(kernelSize) - + - "% kernel encoder.".format(kind) - } - - // --> unsupported subject - { subjectPath.isFolder.not } - { - "Supported subjects:".warn; - PathName.new(subjectPath.parentLevelPath(1)).folders.do({ - arg folder; - ("\t" + folder.folderName).postln; - }); - - errorMsg = "Subject % is not available for".format(subjectID) - + - "% kernel encoder.".format(kind) - }; - - // throw error! - "\n".post; - Error(errorMsg).throw - }, { - score.isNil.if( { - if ( server.serverRunning.not, { // is server running? - - // throw server error! - Error( - "Please boot server: %. Encoder kernel failed to load.".format( - server.name.asString - ) - ).throw - }, { - // Else... everything is fine! Load kernel. - kernel = subjectPath.files.collect({ arg kernelPath; - chans.collect({ arg chan; - Buffer.readChannel(server, kernelPath.fullPath, channels: [chan], - action: { arg buf; - ( - kernelBundle = kernelBundle.add( - ["/b_allocReadChannel", buf.bufnum, kernelPath.fullPath, 0, kernelSize, chan] - ); - kernelInfo = kernelInfo.add([kernelPath.fullPath, buf.bufnum, [chan]]); - "Kernel %, channel % loaded.".format( - kernelPath.fileName, chan - ) - ).postln - } - ) - }) - }) - }) - }); - score.isKindOf(CtkScore).if({ - kernel = subjectPath.files.collect({ arg kernelPath; - chans.collect({ arg chan; - var buf = CtkBuffer(kernelPath.fullPath, channels: [chan]); - kernelInfo = kernelInfo.add([kernelPath.fullPath, buf.bufnum, [chan]]); - score.add(buf); - buf; - }) - }) - }); - - score.isKindOf(Score).if({ - kernel = subjectPath.files.collect({ arg kernelPath; - chans.collect({ arg chan; - var buf; - buf = Buffer(server, kernelSize); - kernelBundle = kernelBundle.add( - ["/b_allocReadChannel", buf.bufnum, kernelPath.fullPath, 0, kernelSize, chan] - ); - kernelInfo = kernelInfo.add([kernelPath.fullPath, buf.bufnum, [chan]]); - buf; - }) - }); - score.add(kernelBundle) - }); - - (score.isKindOf(CtkScore).not && score.isKindOf(Score).not && score.notNil).if({ - Error( - "Score is not a Score or a CtkScore. Score is a %.".format( - score.class.asString - ) - ).throw - - }); - - - }) - } - - free { - var path; - kernel.shape.at(0).do({ arg i; - kernel.shape.at(1).do({ arg j; - path = kernel.at(i).at(j).path; - kernel.at(i).at(j).free; - ( - "Kernel %, channel % freed.".format( - PathName.new(path).fileName, j - ) - ).postln - }) - }) - } - - buffers { ^kernel.flat } - - kernelInfo { ^kernelInfo } - - kernelBundle { ^kernelBundle } - - dim { ^kernel.shape.at(1) - 1} - - numChannels { ^kernel.shape.at(0) } - - kernelSize { ^kernel.at(0).at(0).numFrames } - - numOutputs { ^kernel.shape.at(1) } - - dirInputs { ^dirChannels } - - numInputs { ^kernel.shape.at(0) } - - dirOutputs { ^this.numOutputs.collect({ inf }) } - - type { ^'encoder' } - - printOn { arg stream; - stream << this.class.name << "(" <<* - [kind, this.dim, this.numChannels, subjectID, this.kernelSize] <<")"; - } -} diff --git a/source/ATK/sc/Classes/extArray.sc b/source/ATK/sc/Classes/extArray.sc deleted file mode 100644 index 5b68834693..0000000000 --- a/source/ATK/sc/Classes/extArray.sc +++ /dev/null @@ -1,13 +0,0 @@ -+ Array { - - // set: FOA, HOA1, HOA2, etc. - // type: \encoder, \decoder, \xformer - // NOTE: set and type aren't currently enforced, but it's a - // good idea to provide it for writing to file - asAtkMatrix { arg set, type; - var mtx; - mtx = Matrix.with(this.asArray); - ^AtkMatrix.newFromMatrix(mtx, set, type); - } - -} diff --git a/source/ATK/sc/Classes/extPathName.sc b/source/ATK/sc/Classes/extPathName.sc deleted file mode 100644 index 028b01e3a9..0000000000 --- a/source/ATK/sc/Classes/extPathName.sc +++ /dev/null @@ -1,64 +0,0 @@ -/* - Copyright the ATK Community and Joseph Anderson, 2011 - J Anderson j.anderson[at]ambisonictoolkit.net - - - This file is part of SuperCollider3 version of the Ambisonic Toolkit (ATK). - - The SuperCollider3 version of the Ambisonic Toolkit (ATK) is free software: - you can redistribute it and/or modify it under the terms of the GNU General - Public License as published by the Free Software Foundation, either version 3 - of the License, or (at your option) any later version. - - The SuperCollider3 version of the Ambisonic Toolkit (ATK) is distributed in - the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See - the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with the - SuperCollider3 version of the Ambisonic Toolkit (ATK). If not, see - . -*/ - - -//--------------------------------------------------------------------- -// The Ambisonic Toolkit (ATK) is a soundfield kernel support library. -// -// Extension: PathName -// -// The Ambisonic Toolkit (ATK) is intended to bring together a number of tools and -// methods for working with Ambisonic surround sound. The intention is for the toolset -// to be both ergonomic and comprehensive, providing both classic and novel algorithms -// to creatively manipulate and synthesise complex Ambisonic soundfields. // -// The tools are framed for the user to think in terms of the soundfield kernel. By -// this, it is meant the ATK addresses the holistic problem of creatively controlling a -// complete soundfield, allowing and encouraging the composer to think beyond the placement -// of sounds in a sound-space and instead attend to the impression and image of a soundfield. -// This approach takes advantage of the model the Ambisonic technology presents, and is -// viewed to be the idiomatic mode for working with the Ambisonic technique. -// -// -// We hope you enjoy the ATK! -// -// For more information visit http://ambisonictoolkit.net/ or -// email info[at]ambisonictoolkit.net -// -//--------------------------------------------------------------------- - -+ PathName { - - parentLevelPath { arg index; - - var ci = this.colonIndices; - - ^if( index == 0, { - fullPath - }, { - if((fullPath.last.isPathSeparator) && (ci.size > 1), { - fullPath.copyRange(0, ci[ci.size - (1 + index)]) - }, { - fullPath.copyRange(0, ci[ci.size - index]) - }) - }) - } -} \ No newline at end of file diff --git a/source/ATK/sc/HelpSource/Classes/Atk.schelp b/source/ATK/sc/HelpSource/Classes/Atk.schelp deleted file mode 100644 index a00c73b283..0000000000 --- a/source/ATK/sc/HelpSource/Classes/Atk.schelp +++ /dev/null @@ -1,172 +0,0 @@ -CLASS:: Atk -summary:: a class that stores some global variables for the Ambisonic Toolkit -categories:: Libraries>Ambisonic Toolkit>Internals -related:: Guides/Intro-to-the-ATK - -DESCRIPTION:: -The Atk class defines variables that may be used by the rest of the ATK library, including resources for kernel encoding and decoding and sample soundfile paths. - - -CLASSMETHODS:: - -METHOD:: sets - -returns:: an Array listing valid ATK sets. (Currently only code::'FOA':: is -supported, code::'HOAn':: is in development!) - -SUBSECTION:: ATK's default asset directories - -NOTE:: The following methods have both strong::user:: and -strong::system:: versions. Which version you should use will depend on whether -you have the ATK assets installed at the user level: -code:: -Platform.userAppSupportDir -:: -or the system level: -code:: -Platform.systemAppSupportDir -:: -:: - -METHOD:: userSupportDir -set the user support dir where ATK resources are located - -argument:: userSupportDirIn -the path to the ATK folder containing your ATK support files - -METHOD:: userSupportDir - -returns::the path to the ATK support dir. Defaults to: -code::Platform.userAppSupportDir.dirname ++ "/ATK";:: - -METHOD:: userSoundsDir - -returns:: a path to the 'sounds' dir inside the ATK support dir - -METHOD:: userMatrixDir - -returns:: a path to the 'matrices' dir inside the ATK support dir - -METHOD:: userKernelDir - -returns:: a path to the 'kernel' dir inside the ATK support dir - -METHOD:: openUserSupportDir -runs a link::Classes/String#-unixCmd:: to open the userAppSupport dir. Uses -'open' (OS X only) - -METHOD:: createUserSupportDir -runs a unix command to create the user support dir for ATK - -METHOD:: systemSupportDir - -returns::the path to the ATK support dir. Defaults to: -code::Platform.systemAppSupportDir.dirname ++ "/ATK";:: - -METHOD:: systemSoundsDir - -returns:: a path to the 'sounds' dir inside the ATK system support dir - -METHOD:: systemMatrixDir - -returns:: a path to the 'matrices' dir inside the ATK system support dir - -METHOD:: systemKernelDir - -returns:: a path to the 'kernel' dir inside the ATK system support dir - -METHOD:: openSystemSupportDir -runs a link::Classes/String#-unixCmd:: to open the systemAppSupport dir. Uses -'open' (OS X only) - -METHOD:: createSystemSupportDir -runs a unix command to create the system support dir for ATK - - -SUBSECTION:: User asset /extensions directory - -The code::extensions:: directory is where the ATK looks for assets generated or -added by you, such as your own matrices or kernels. It is located in -code:: -Atk.userExtensionsDir -:: -or if the ATK assets are installed system-wide, in: -code:: -Atk.systemExtensionsDir -:: -It is strong::not installed by default::. It can be -created by running -code:: -Atk.createExtensionsDir -:: -You can find out more about the directory structure in the -link::Guides/Guide-to-ATK-Matrix-Files::. - -METHOD:: userExtensionsDir - -returns:: a path to the 'extensions' dir inside the ATK support dir. This is where -user-generated matrices and kernels are stored to and rerieved from by default. - -METHOD:: systemExtensionsDir - -returns:: a path to the 'extensions' dir inside the ATK support dir. This is where -user-generated matrices and kernels are stored to and rerieved from by default. - -METHOD:: postMyMatrices -Displays a formatted list the matrices stored in your -code::ATK/extensions/matrices:: directory. The strong::set:: and -strong::type:: arguments are optional filters to display only matrices of a the -specified strong::set:: and strong::type::. -NOTE:: This method first searches the code::Atk.userExtensionsDir:: and if no -directory is found, it proceeds to check for a system-wide installation in -code::Atk.systemExtensionsDir::. -:: - -METHOD:: createExtensionsDir -Creates the code::extensions:: folder, along with numerous subdirectories in a -pre-defined structure, in your ATK assets folder. This is where the ATK looks -for assets generated or added by you, such as your own matrices or kernels. -You can find out more about the directory structure and its use in the -link::Guides/Guide-to-ATK-Matrix-Files::. - - -SUBSECTION:: Convenience methods for accessing subdirectories - -The following methods are used by ATK internally but listed here in the case -you find them useful. - -METHOD:: getAtkOpPath -Get the Link::Classes/PathName:: of the strong::op:: directory (code::'kernels':: or -code::'matrices'::), in either the "built-in" ATK support directory or -the user code::extension:: subdirectory (strong::isExtension:: = true). - -METHOD:: getAtkOpSubPath - -Get the Link::Classes/PathName:: of the subdirectory within the -code::ATK/'op'/'set'/'type':: folder. -NOTE:: This method first searches the code::Atk.userExtensionsDir:: and if no -directory is found, it proceeds to check the code::Atk.systemExtensionsDir::. -:: - -METHOD:: getAtkMatrixSubPath -A shortcut for code::Atk.getAtkOpSubPath(set, op, 'matrices'):: - -METHOD:: getAtkKernelSubPath -A shortcut for code::Atk.getAtkOpSubPath(set, op, 'kernels'):: - -METHOD:: getExtensionSubPath -Get the Link::Classes/PathName:: of the subdirectory within the -code::ATK/extensions/'op'/'set'/'type':: folder. -NOTE:: This method first searches the code::Atk.userExtensionsDir:: and if no -directory is found, it proceeds to check the code::Atk.systemExtensionsDir::. -:: - -METHOD:: getMatrixExtensionSubPath -A shortcut for code::Atk.getExtensionSubPath(set, op, 'matrices'):: - -METHOD:: getKernelExtensionSubPath -A shortcut for code::Atk.getExtensionSubPath(set, op, 'kernels'):: - - - -PRIVATE:: checkSet, sets, getAtkLibSubPath, getKernelExtensionPath, getBuiltInPath, getMatrixBuiltInPath, resolveMtxPath, folderExists diff --git a/source/ATK/sc/HelpSource/Classes/AtkKernelConv.schelp b/source/ATK/sc/HelpSource/Classes/AtkKernelConv.schelp deleted file mode 100644 index 3baf4da869..0000000000 --- a/source/ATK/sc/HelpSource/Classes/AtkKernelConv.schelp +++ /dev/null @@ -1,78 +0,0 @@ -CLASS:: AtkKernelConv -summary:: Kernel convolution from the Ambisonic Toolkit (ATK) -categories:: Libraries>Ambisonic Toolkit>Internals, UGens>Multichannel>Ambisonics -related:: Classes/Convolution2, Classes/AtkMatrixMix - -DESCRIPTION:: -Convolve an link::Classes/Array:: of channels to an link::Classes/Array:: of channels. - -note:: -link::Classes/AtkKernelConv:: is usually called internally by the Ambisonic Toolkit's encoders, transformers and decoders. -:: - - - -CLASSMETHODS:: - -METHOD:: ar - -argument:: in -The input signal, an array. - -argument:: kernel -The convolution kernel. - -argument:: mul -Output will be multiplied by this value. - -argument:: add -This value will be added to the output. - -returns:: -An array of channels. - - -discussion:: - -note:: In normal circumstances, the user will not call link::Classes/AtkKernelConv:: directly.:: - - -EXAMPLES:: - -subsection:: Monophonic to decorrelated FOA -code:: -// hand code a mono signal to a decorrelated soundfield in B-format -// NOTE: the demonstrated kernel is not ideal for this task - -// define encoding kernel -( -var kernelSize; -var scale; - -kernelSize = 256; -scale = 24.neg.dbamp; - -~kernel = [[ - Buffer.loadCollection(s, FloatArray.fill(kernelSize, {(3/2).sqrt * scale.rand2})), - Buffer.loadCollection(s, FloatArray.fill(kernelSize, {scale.rand2})), - Buffer.loadCollection(s, FloatArray.fill(kernelSize, {scale.rand2})), - Buffer.loadCollection(s, FloatArray.fill(kernelSize, {scale.rand2})) -]] -) - -// convolve -( -{ - var sig; - - // pink noise - sig = PinkNoise.ar; - - // encode - AtkKernelConv.ar(sig, ~kernel); -}.scope -) - -// free kernel when finished -~kernel.at(0).do({arg kern; kern.free}) -:: diff --git a/source/ATK/sc/HelpSource/Classes/AtkMatrix.schelp b/source/ATK/sc/HelpSource/Classes/AtkMatrix.schelp deleted file mode 100644 index 1b598628e4..0000000000 --- a/source/ATK/sc/HelpSource/Classes/AtkMatrix.schelp +++ /dev/null @@ -1,117 +0,0 @@ -TITLE:: AtkMatrix -summary:: A superclass to the Atk's various matrix classes. -categories:: Libraries>Ambisonic Toolkit>Internals -related:: Classes/FoaEncoderMatrix, Classes/FoaDecoderMatrix, Classes/FoaXformerMatrix, Classes/Matrix, Guides/Guide-to-ATK-Matrix-Files - -DESCRIPTION:: -An AtkMatrix is not typically instantiated directly, but rather through one of its subclasses: -link::Classes/FoaEncoderMatrix::, link::Classes/FoaDecoderMatrix::, and link::Classes/FoaXformerMatrix::. - - -CLASSMETHODS:: - -METHOD:: new -code::*new:: should not be called directly from AtkMatrix but rather is called from the various creation methods of its subclasses: -link::Classes/FoaEncoderMatrix::, link::Classes/FoaDecoderMatrix::, or link::Classes/FoaXformerMatrix::. - - -METHOD:: newFromMatrix -Create an instance from a raw 2D link::Classes/Matrix::. - -ARGUMENT:: aMatrix -A link::Classes/Matrix:: in the form of -code:: -Matrix.with([[row1],[row2],...[rowN]]) -:: - -ARGUMENT:: set -code::'FOA', 'HOA1', 'HOA2', ... etc::. -Set describes both the signal set and the tool set, encompassing the Ambisonic order, as well as channel ordering and normalisation. - -ARGUMENT:: type -code::'decoder', 'encoder', or 'xformer'::. - -NOTE:: -strong::set:: and strong::type:: will be required if the code::AtkMatrix:: will subsequently be written to a file. -:: - - -INSTANCEMETHODS:: - -PRIVATE:: set, kind - -METHOD:: op -Answers code::'matrix'::, i.e. the type of operation used to compute the resulting signals. - -METHOD:: matrix -Returns the raw coefficient Matrix. - -METHOD:: info -A convenience method to post the properties of the matrix, including metadata -if the matrix was loaded from a code::.yml:: file. - -METHOD:: fileParse -If the instance was created by loading a code::.yml:: file, this method returns -the link::Classes/IdentityDictionary:: containing the parsed metadata. This can -be useful if anything was stored in the metadata that can be subsequently used -once reloaded, such as encoding directions, rotations, etc. -Note:: For simply a quick glance at the metadata, it's recommended to use link::#-info::.:: - -METHOD:: filePath -Answers the path of the file used to create the instance, or code::nil:: if not created by loading a matrix from a file. - -METHOD:: fileName -Answers the name of the file used to create the instance, or code::nil:: if not created by loading a matrix from a file. - -METHOD:: writeToFile -Write the matrix to a file - -ARGUMENT:: fileNameOrPath -A String of the file name. The file extension determines the format: -list:: -## code::.yml:: allows for additional user-specified metadata (recommended). -## code::.txt:: writes the matrix coefficients only, in rows. -## code::.mosl.txt:: creates basic matrix files compatible with the link::http://www.ambisonictoolkit.net/download/reaper/##ATK for Reaper::, a set of link::http://www.reaper.fm/sdk/js/js.php##JSFX plugins:: for the link::http://www.reaper.fm/##Reaper:: DAW. -:: -You may provide a full path if you would like to save the file somewhere other -than the default location in the Atk code::extensions:: folder. See the -Discussion below for more information. - -ARGUMENT:: note -A String that is a short description or bit of info about the matrix to store for future reference. - -ARGUMENT:: attributeDictionary -A Dictionary containing any information that's useful to store in key:value pairs. Keys that match getters in the AtkMatrix will take precedence over the defaults. See the Discussion for more details. - -ARGUMENT:: overwrite -A boolean specifying whether you'd like to force overwriting an existing file of the same name and extension. - -DISCUSSION:: - -The link::Guides/Guide-to-ATK-Matrix-Files:: offers examples and more discussion regarding -writing and reading matrices and metadata, including how to generate -matrices for use in Reaper. - - -METHOD:: info -A convenience method to post the properties of the matrix, including metadata -if the matrix was loaded from a code::.yml:: file. - - -METHOD:: fileParse -If the instance was created by loading a code::.yml:: file, this method returns -the link::Classes/IdentityDictionary:: containing the parsed metadata. This can -be useful if anything was stored in the metadata that can be subsequently used -once reloaded, such as encoding directions, rotations, etc. -Note:: For simply a quick glance at the metadata, it's recommended to use link::#-info::.:: - - -METHOD:: filePath -Answers the path of the file used to create the instance, or code::nil:: if not created by loading a matrix from a file. - - -METHOD:: fileName -Answers the name of the file used to create the instance, or code::nil:: if not created by loading a matrix from a file. - - -PRIVATE:: prWriteMatrixToMOSL, prWriteMatrixToYML, prWriteMatrixToTXT, prParseMOSL, initFromMatrix, initFromFile, loadFromLib, prWriteToFile diff --git a/source/ATK/sc/HelpSource/Classes/AtkMatrixMix.schelp b/source/ATK/sc/HelpSource/Classes/AtkMatrixMix.schelp deleted file mode 100644 index 8b9ebab7c4..0000000000 --- a/source/ATK/sc/HelpSource/Classes/AtkMatrixMix.schelp +++ /dev/null @@ -1,92 +0,0 @@ -CLASS:: AtkMatrixMix -summary:: Matrix mixer from the Ambisonic Toolkit (ATK) -categories:: Libraries>Ambisonic Toolkit>Internals, UGens>Multichannel>Ambisonics -related:: Classes/Mix, Classes/AtkKernelConv - - -DESCRIPTION:: -Mix an link::Classes/Array:: of channels to an link::Classes/Array:: of channels. - -note:: -link::Classes/AtkMatrixMix:: is usually called internally by the Ambisonic Toolkit's encoders, transformers and decoders. -:: - - - -CLASSMETHODS:: - -METHOD:: ar - -argument:: in -The input signal, an array. - -argument:: matrix -The mixing matrix. - -argument:: mul -Output will be multiplied by this value. - -argument:: add -This value will be added to the output. - -returns:: -An array of channels. - - -discussion:: - -note:: In normal circumstances, the user will not call link::Classes/AtkMatrixMix:: directly.:: - - - -EXAMPLES:: - -subsection:: Monophonic to FOA -code:: -// hand code a mono signal to a planewave in B-format -( -{ - var matrix; - var sig; - - // define encoding matrix - matrix = Matrix.with([ - [ 2.sqrt.reciprocal ], - [ 1 ], - [ 0 ], - [ 0 ] - ]); - - // pink noise - sig = PinkNoise.ar; - - // encode - AtkMatrixMix.ar(sig, matrix); -}.scope -) -:: - -subsection:: Stereophonic to FOA -code:: -// hand code a stereo signal to a +/-45deg in B-format -( -{ - var matrix; - var sig; - - // define encoding matrix - matrix = Matrix.with([ - [ 2.sqrt.reciprocal, 2.sqrt.reciprocal ], - [ 2.sqrt.reciprocal, 2.sqrt.reciprocal ], - [ 2.sqrt.reciprocal, 2.sqrt.reciprocal.neg ], - [ 0, 0 ] - ]); - - // pink noise - sig = PinkNoise.ar([1, 1]); - - // encode - AtkMatrixMix.ar(sig, matrix); -}.scope -) -:: \ No newline at end of file diff --git a/source/ATK/sc/HelpSource/Classes/Foa.schelp b/source/ATK/sc/HelpSource/Classes/Foa.schelp deleted file mode 100644 index 0544413ee0..0000000000 --- a/source/ATK/sc/HelpSource/Classes/Foa.schelp +++ /dev/null @@ -1,12 +0,0 @@ -CLASS:: Foa -summary:: First Order Ambisonic (FOA) UGen superclass -categories:: Libraries>Ambisonic Toolkit>Internals - - -DESCRIPTION:: -UGen superclass from the Ambisonic Toolkit (ATK) - -note:: -In normal circumstances, the user will not call link::Classes/Foa:: directly. -:: - diff --git a/source/ATK/sc/HelpSource/Classes/FoaAsymmetry.schelp b/source/ATK/sc/HelpSource/Classes/FoaAsymmetry.schelp deleted file mode 100644 index 28345b12eb..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaAsymmetry.schelp +++ /dev/null @@ -1,46 +0,0 @@ -CLASS:: FoaAsymmetry -summary:: First Order Ambisonic (FOA) asymmetry transformer -categories:: Libraries>Ambisonic Toolkit>FOA>Transforming>UGens, UGens>Multichannel>Ambisonics, UGens>Multichannel>Panners -related:: Classes/FoaTransform, Classes/FoaXform - -DESCRIPTION:: -Apply asymmetry to a first order ambisonic signal (B-format). - - -NOTE:: -link::Classes/FoaAsymmetry:: is usually called via the convenience wrapper link::Classes/FoaTransform::. -:: - - - -CLASSMETHODS:: - -METHOD:: ar - -argument:: in -The B-format signal, an array: [w, x, y, z] - -argument:: angle -The distortion angle, in radians. -pi/2 to pi/2 - -argument:: mul -Output will be multiplied by this value. - -argument:: add -This value will be added to the output. - -discussion:: Positive values of strong::angle:: rotate code:: [0, -pi/2] :: towards code:: [0, 0] ::, and at pi/2 collapse the soundfield to a planewave. Negative values rotate code:: [0, pi/2] :: towards code:: [0, 0] ::. The default, 0, results in no change. - - - -anchor::figure:: - -image::asymmetry_fig.png#Asymmetry imaging:: - - -note:: Corresponding matrix transformer: link::Classes/FoaXformerMatrix#*newAsymmetry:: :: - - -EXAMPLES:: - -Please see various examples link::Classes/FoaTransform#examples#here::. \ No newline at end of file diff --git a/source/ATK/sc/HelpSource/Classes/FoaBalance.schelp b/source/ATK/sc/HelpSource/Classes/FoaBalance.schelp deleted file mode 100644 index 4a93c720e0..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaBalance.schelp +++ /dev/null @@ -1,48 +0,0 @@ -CLASS:: FoaBalance -summary:: First Order Ambisonic (FOA) balance transformer -categories:: Libraries>Ambisonic Toolkit>FOA>Transforming>UGens, UGens>Multichannel>Ambisonics, UGens>Multichannel>Panners -related:: Classes/FoaZoomX, Classes/FoaZoomY, Classes/FoaZoomZ, Classes/FoaZoom, Classes/FoaTransform, Classes/FoaXform - -DESCRIPTION:: -Soundfield balance. A synonym for link::Classes/FoaZoomY:: - -Apply zoom to a first order ambisonic signal (B-format) along the y-axis. - - -NOTE:: -link::Classes/FoaZoomY:: is usually called via the convenience wrapper link::Classes/FoaTransform::. -:: - - - -CLASSMETHODS:: - -METHOD:: ar - -argument:: in -The B-format signal, an array: [w, x, y, z] - -argument:: angle -The distortion angle, in radians. -pi/2 to pi/2 - -argument:: mul -Output will be multiplied by this value. - -argument:: add -This value will be added to the output. - - - -discussion:: Zoom is a normailised dominance variant, specified in terms of a distortion angle. Positive values of strong::angle:: increase gain at code:: [0, pi/2] ::, while reducing at code:: [0, -pi/2] ::. Negative values do the inverse. The default, 0, results in no change. - -anchor::figure:: - -image::balance_fig.png#Balance imaging:: - - -note:: Corresponding matrix transformer: link::Classes/FoaXformerMatrix#*newZoomY:: :: - - -EXAMPLES:: - -Please see various examples link::Classes/FoaTransform#examples#here::. diff --git a/source/ATK/sc/HelpSource/Classes/FoaDecode.schelp b/source/ATK/sc/HelpSource/Classes/FoaDecode.schelp deleted file mode 100644 index 84c28e35ce..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaDecode.schelp +++ /dev/null @@ -1,871 +0,0 @@ -CLASS:: FoaDecode -summary:: First Order Ambisonic (FOA) decoder -categories:: Libraries>Ambisonic Toolkit>FOA>Decoding, UGens>Multichannel>Ambisonics -related:: Classes/FoaDecoderMatrix, Classes/FoaDecoderKernel - -DESCRIPTION:: -Renders (decodes) a first order ambisonic signal (B-format) to speaker feeds in a variety of configurations. link::Classes/DecodeB2:: is the SuperCollider inbuilt equivalent. - - -CLASSMETHODS:: - -METHOD:: ar - -argument:: in -The B-format signal, an array: [w, x, y, z] - -argument:: decoder -link::Classes/FoaDecoderMatrix:: or link::Classes/FoaDecoderKernel:: instance. - -argument:: mul -Output will be multiplied by this value. - -argument:: add -This value will be added to the output. - -returns:: -An array of channels, one for each speaker. - - -EXAMPLES:: - -The examples below are intended to briefly illustrate some of the first order decoding options made available in the Ambisonic Toolkit. The user is encouraged to carefully review the features of link::Classes/FoaDecoderMatrix:: and link::Classes/FoaDecoderKernel:: to gain a deeper understanding of the flexibility of these tools. - -As the Ambisonic technique is a hierarchal system, numerous options for playback are possible. These include two channel stereo, two channel binaural, 2D horizontal only surround (pantophonic) and full 3D with height surround (periphonic). A brief introduction is explored below. - - -Encoded as an omnidirectional soundfield, link::Classes/PinkNoise:: is used as the example sound source. In a well aligned, dampend studio environment, this usually sounds "in the head". link::Classes/FoaPush:: is used to "push" the omnidirectional soundfield so that it becomes a planewave (infinite distance, in an anechoic environment) arriving from some direction. - -The soundfield is controlled by link::Classes/MouseX:: and link::Classes/MouseY::, where link::Classes/MouseX:: specifies the incident azimuth angle (pi to -pi; left to right of display) and link::Classes/MouseY:: the link::Classes/FoaPush:: angle (0 to pi/2; bottom to top of display). With the mouse at the bottom of the display, the soundfield remains omnidirectional. Placed at the top of the display, the soundfield becomes directional, and varying left/right position will vary the incident azimuth of the resulting planewave. - -Before exploring the examples below, it is suggested you confirm your -link::Classes/Server:: has enough output channels to support your chosen -decoder. You can query the server: - -code:: -myServer.options.numOutputBusChannels -:: - -An example link::Classes/Function::, code:: ~checkMyServerOutputs::, can -be found link::Guides/Intro-to-the-ATK#Choose a decoder#here::. -code:: ~checkMyServerOutputs:: throws a warning if -code::myServer.options.numOutputBusChannels < myDecoder.numOutputs::. If you -need to update your link::Classes/Server::'s number of output bus channels, -review the example found link::Classes/ServerOptions#examples#here::. - - -subsection:: Virtual microphone stereo decoder - -The soundfield may be decoded to stereo using a pair of virtual microphones. - -note:: A matrix type decoder, see link::Classes/FoaDecoderMatrix#*newStereo:: for further details.:: - -code:: -// ------------------------------------------------------------ -// virtual microphone stereo decoder -// -// mono pink noise source -// omni encoder - - -// define encoder / decoder matrices -~encoder = FoaEncoderMatrix.newOmni -~decoder = FoaDecoderMatrix.newStereo - - -// inspect -~encoder.kind -~encoder.numChannels -~encoder.dirChannels - -~decoder.kind -~decoder.numChannels -~decoder.dirChannels.raddeg - -( -{ - var sig;// audio signal - var angle, azim; // angle and azimuth control - - - // display encoder and decoder - "Ambisonic encoding via % encoder".format(~encoder.kind).postln; - "Ambisonic decoding via % decoder".format(~decoder.kind).postln; - - // angle ---> top = push to plane wave - // bottom = omni-directional - angle = MouseY.kr(pi/2, 0); - - // azimuth -> hard left = back - // centre = centre - // hard right = back - azim = MouseX.kr(pi, -pi); - - - // ------------------------------------------------------------ - // test sig - sig = PinkNoise.ar; // mono pink noise - - - // ------------------------------------------------------------ - // encode - sig = FoaEncode.ar(sig, ~encoder); - - // ------------------------------------------------------------ - // transform - sig = FoaTransform.ar(sig, 'push', angle, azim); - - - // ------------------------------------------------------------ - // decode (to stereo) - FoaDecode.ar(sig, ~decoder); - -}.scope; -) - -// free kernel -~decoder.free - -// ------------------------------------------------------------ -:: - - -subsection:: Ambisonic UHJ stereo decoder - -Ambisonic UHJ stereo footnote::See: link::http://en.wikipedia.org/wiki/Ambisonic_UHJ_format:::: is the 'native' stereo format for Ambisonics. A B-format signal (2D, with some losses) can be recovered from a UHJ decoded signal through the use of link::Classes/FoaEncoderKernel#*newUHJ::. - - - -note:: A kernel type decoder, see link::Classes/FoaDecoderKernel#*newUHJ:: for further details.:: - -warning:: Kernel decoders require special care. Allow the kernel time to load before attempting to use. Additionally, the kernel buffer should be freed through the use of link::Classes/FoaDecoderKernel#-free:: after use.:: - - - -code:: -// ------------------------------------------------------------ -// UHJ (stereo) decoder -// -// mono pink noise source -// omni encoder - - -// define encoder / decoder matrices -~encoder = FoaEncoderMatrix.newOmni -~decoder = FoaDecoderKernel.newUHJ // kernel decoders should be freed after use!! - // free below... - -// inspect -~encoder.kind -~encoder.numChannels -~encoder.dirChannels - -~decoder.kind -~decoder.numChannels -~decoder.dirChannels.raddeg - -( -{ - var sig;// audio signal - var angle, azim; // angle and azimuth control - - - // display encoder and decoder - "Ambisonic encoding via % encoder".format(~encoder.kind).postln; - "Ambisonic decoding via % decoder".format(~decoder.kind).postln; - - // angle ---> top = push to plane wave - // bottom = omni-directional - angle = MouseY.kr(pi/2, 0); - - // azimuth -> hard left = back - // centre = centre - // hard right = back - azim = MouseX.kr(pi, -pi); - - - // ------------------------------------------------------------ - // test sig - sig = PinkNoise.ar; // mono pink noise - - - // ------------------------------------------------------------ - // encode - sig = FoaEncode.ar(sig, ~encoder); - - // ------------------------------------------------------------ - // transform - sig = FoaTransform.ar(sig, 'push', angle, azim); - - - // ------------------------------------------------------------ - // decode (to stereo) - FoaDecode.ar(sig, ~decoder); - -}.scope; -) - -// free kernel -~decoder.free - -// ------------------------------------------------------------ -:: - -subsection:: Synthetic binaural decoder - - -The Ambisonic Tookit provides a synthetic spherical head model HRTF decoder. footnote::See: R. O. Duda, "Modeling head related transfer functions," in Proceedings of the Twenty-Seventh Annual Asilomar Conference on Signals, Systems and Computers, Asilomar, CA, 1993.:: Ten subjects with varying head sizes are available. Audition to find one that works best for you. - -Additionally, HRTF decoders computed from measured HRIRs are also available: link::Classes/FoaDecoderKernel#*newListen:: & link::Classes/FoaDecoderKernel#*newCIPIC::. - - -note:: A kernel type decoder, see link::Classes/FoaDecoderKernel#*newSpherical:: for further details.:: - -warning:: Kernel decoders require special care. Allow the kernel time to load before attempting to use. Additionally, the kernel buffer should be freed through the use of link::Classes/FoaDecoderKernel#-free:: after use.:: - - -code:: -// ------------------------------------------------------------ -// Binaural (synthetic) decoder -// -// mono pink noise source -// omni encoder - - -// define encoder / decoder matrices -~encoder = FoaEncoderMatrix.newOmni -~decoder = FoaDecoderKernel.newSpherical // kernel decoders should be freed after use!! - // free below... - -// inspect -~encoder.kind -~encoder.numChannels -~encoder.dirChannels - -~decoder.kind -~decoder.numChannels -~decoder.dirChannels.raddeg - -( -{ - var sig;// audio signal - var angle, azim; // angle and azimuth control - - - // display encoder and decoder - "Ambisonic encoding via % encoder".format(~encoder.kind).postln; - "Ambisonic decoding via % decoder".format(~decoder.kind).postln; - - // angle ---> top = push to plane wave - // bottom = omni-directional - angle = MouseY.kr(pi/2, 0); - - // azimuth -> hard left = back - // centre = centre - // hard right = back - azim = MouseX.kr(pi, -pi); - - - // ------------------------------------------------------------ - // test sig - sig = PinkNoise.ar; // mono pink noise - - - // ------------------------------------------------------------ - // encode - sig = FoaEncode.ar(sig, ~encoder); - - // ------------------------------------------------------------ - // transform - sig = FoaTransform.ar(sig, 'push', angle, azim); - - - // ------------------------------------------------------------ - // decode (to binaural) - FoaDecode.ar(sig, ~decoder); - -}.scope; -) - -// free kernel -~decoder.free - -// ------------------------------------------------------------ -:: - - -subsection:: CIPIC binaural decoder - -Measured HRTF decoder, with measurements from the University of California Davis' link::http://interface.cipic.ucdavis.edu/sound/hrtf.html##CIPIC HRTF database::. footnote::See: link::http://interface.cipic.ucdavis.edu/sound/hrtf.html:::: Forty-five subjects with varying head sizes are available. Audition to find one that works best for you. - - -note:: A kernel type decoder, see link::Classes/FoaDecoderKernel#*newCIPIC:: for further details.:: - -warning:: Kernel decoders require special care. Allow the kernel time to load before attempting to use. Additionally, the kernel buffer should be freed through the use of link::Classes/FoaDecoderKernel#-free:: after use.:: - -code:: -// ------------------------------------------------------------ -// Binaural (CIPIC) decoder -// -// mono pink noise source -// omni encoder - - -// define encoder / decoder matrices -~encoder = FoaEncoderMatrix.newOmni -~decoder = FoaDecoderKernel.newCIPIC // kernel decoders should be freed after use!! - // free below... - -// inspect -~encoder.kind -~encoder.numChannels -~encoder.dirChannels - -~decoder.kind -~decoder.numChannels -~decoder.dirChannels.raddeg - -( -{ - var sig;// audio signal - var angle, azim; // angle and azimuth control - - - // display encoder and decoder - "Ambisonic encoding via % encoder".format(~encoder.kind).postln; - "Ambisonic decoding via % decoder".format(~decoder.kind).postln; - - // angle ---> top = push to plane wave - // bottom = omni-directional - angle = MouseY.kr(pi/2, 0); - - // azimuth -> hard left = back - // centre = centre - // hard right = back - azim = MouseX.kr(pi, -pi); - - - // ------------------------------------------------------------ - // test sig - sig = PinkNoise.ar; // mono pink noise - - - // ------------------------------------------------------------ - // encode - sig = FoaEncode.ar(sig, ~encoder); - - // ------------------------------------------------------------ - // transform - sig = FoaTransform.ar(sig, 'push', angle, azim); - - - // ------------------------------------------------------------ - // decode (to binaural) - FoaDecode.ar(sig, ~decoder); - -}.scope; -) - -// free kernel -~decoder.free - -// ------------------------------------------------------------ -:: - - -subsection:: Quadraphonic decoder - -The Ambisonic Toolkit provides an optimised quadraphonic decoder with variable loudspeaker angle. The below example uses the default settings, which results in a square layout, code::'single':: band type ( code::'energy':: ) decoder. This sort of decoder is suitable for mid-scale playback, though, for best results for an audience, the use of a larger array (5+ loudspeakers) is advised. link::Classes/FoaDecoderMatrix#*newPanto:: or link::Classes/FoaDecoderMatrix#*newDiametric:: would be appropriate. - -A psychoacoustically optimised (dual-band) near-field compensated decoder, suitable for studio monitoring, is demonstrated link::#psychoacoustically_optimised_quadraphonic_decoder#below::. - -note:: A matrix type decoder, see link::Classes/FoaDecoderMatrix#*newQuad:: for further details.:: - -code:: -// ------------------------------------------------------------ -// quad decoder -// -// mono pink noise source -// omni encoder - - -// define encoder / decoder matrices -~encoder = FoaEncoderMatrix.newOmni -~decoder = FoaDecoderMatrix.newQuad - -// inspect -~encoder.kind -~encoder.numChannels -~encoder.dirChannels - -~decoder.kind -~decoder.numChannels -~decoder.dirChannels.raddeg - -( -{ - var sig; // audio signal - var angle, azim; // angle and azimuth control - var fl, bl, br, fr; // quad output channels - - - // display encoder and decoder - "Ambisonic encoding via % encoder".format(~encoder.kind).postln; - "Ambisonic decoding via % decoder".format(~decoder.kind).postln; - - // angle ---> top = push to plane wave - // bottom = omni-directional - angle = MouseY.kr(pi/2, 0); - - // azimuth -> hard left = back - // centre = centre - // hard right = back - azim = MouseX.kr(pi, -pi); - - // ------------------------------------------------------------ - // test sig - sig = PinkNoise.ar; // mono pink noise - - - // ------------------------------------------------------------ - // encode - sig = FoaEncode.ar(sig, ~encoder); - - // ------------------------------------------------------------ - // transform - sig = FoaTransform.ar(sig, 'push', angle, azim); - - - - // ------------------------------------------------------------ - // decode (to quad) - #fl, bl, br, fr = FoaDecode.ar(sig, ~decoder); - [fl, fr, bl, br] // reorder output to match speaker arrangement - -}.scope; -) -// ------------------------------------------------------------ -:: - -subsection:: SuperCollider's inbuilt decoder - -By default, SuperCollider includes a pantophonic (2D) decoder, link::Classes/DecodeB2::. This inbuilt decoder provides functionality similar to the Ambisonic Toolkit's link::Classes/FoaDecoderMatrix#*newPanto::, with the exceptions of a variable strong::k:: argument and the documentation features of link::Classes/FoaDecoderMatrix::, e.g. link::Classes/FoaDecoderMatrix#-dirChannels::. - -The inbuilt decoder is a code::'controlled':: strong::k:: decoder. (See link::Classes/FoaDecoderMatrix#decoder k#this discussion:: on strong::k::.) The below code includes a function, code::funK::, to add variable strong::k:: functionality to link::Classes/DecodeB2::. So, this example is realised as a code::'single':: band type ( code::'energy':: ) decoder, matching the link::Classes/FoaDecoderMatrix#*newQuad:: example link::#quadraphonic_decoder#above::. - -note:: See link::Classes/DecodeB2#*ar:: for further details.:: - - -code:: -// ------------------------------------------------------------ -// compare to SuperCollider's inbuilt DecodeB2 (as quad decoder) -// -// mono pink noise source -// omni encoder - - -// define encoder matrix and decoder channels -~encoder = FoaEncoderMatrix.newOmni -~numChans = 4 - -// inspect -~encoder.kind -~encoder.numChannels -~encoder.dirChannels - -~numChans - -// function to adjust k of DecodeB2.ar -( -var funK; - -funK = { arg k; - if ( k.isNumber, { - k - }, { - switch ( k, - 'velocity', { [1, 2, 2, 2] }, - 'energy', { [1, 2.sqrt, 2.sqrt, 2.sqrt] }, - 'controlled', { [1, 1, 1, 1] }, - 'single', { [1, 2.sqrt, 2.sqrt, 2.sqrt] } - ) - } - ) -}; - -~kScale = funK.value('single'); // specify ATK's default, -) // a single band ('energy') decoder - -( -{ - var sig; // audio signal - var angle, azim; // angle and azimuth control - var fl, bl, br, fr; // quad output channels - var w, x, y, z; // b-format channels (split) - - - // display encoder and decoder - "Ambisonic encoding via % encoder".format(~encoder.kind).postln; - "Ambisonic decoding via % decoder".format("inbuilt").postln; - - // angle ---> top = push to plane wave - // bottom = omni-directional - angle = MouseY.kr(pi/2, 0); - - // azimuth -> hard left = back - // centre = centre - // hard right = back - azim = MouseX.kr(pi, -pi); - - // ------------------------------------------------------------ - // test sig - sig = PinkNoise.ar; // mono pink noise - - - // ------------------------------------------------------------ - // encode - sig = FoaEncode.ar(sig, ~encoder); - - // ------------------------------------------------------------ - // transform - sig = FoaTransform.ar(sig, 'push', angle, azim); - - // ------------------------------------------------------------ - // split to w, x, y, z, and scale k - #w, x, y, z = sig * ~kScale; - - // ------------------------------------------------------------ - // decode (to quad), and match gain to ATK decoders - #fl, fr, br, bl = DecodeB2.ar(~numChans, w, x, y) * 6.neg.dbamp; - [fl, fr, bl, br] // reorder output to match speaker arrangement - -}.scope; -) -// ------------------------------------------------------------ -:: - - -subsection:: Psychoacoustically optimised quadraphonic decoder - -The decoder presented here is an example of a dual-band ( code::'dual':: ) psychoacoustically optmisied, near-field compensated decoder described by Gerzon. footnote::M. A. Gerzon, "Multi-system ambisonic decoder," Wireless World, pp. 43-47, 69-73, July/Aug. 1977.:: This sort of decoder is considered the ideal for first order Ambisonics, meeting all the criteria outlined by Gerzon to qualify as Ambisonic, footnote::E. Benjamin, R. Lee, and A. Heller, "Is My Decoder Ambisonic?," in Proceedings of the 125th Audio Engineering Society Convention, San Francisco, 2008.:: and is the choice for critical studio listening. - -Additionally, this decode is rendered as a 'narrow quadraphonic' layout, with loudspeaker angles at code:: [ 30.0, 150.0, -150.0, -30.0 ] ::. For studio based work, this can be convenient, as the front pair is at the correct angle for two channel stereo monitoring. The narrow layout gives increased localisation and stabilised images at front and back, at the expense of reduced stability at the sides. - -Near-field compensation, filtering for the near-field effects of loudspeaker placement, is made through the use of link::Classes/FoaNFC::. - - -note:: A matrix type decoder, see link::Classes/FoaDecoderMatrix#*newQuad:: and link::Classes/FoaNFC:: for further details.:: - -code:: -// ------------------------------------------------------------ -// narrow quad decoder, psychocacousticly optimised, & with NFC -// -// mono pink noise source -// omni encoder - - -// define encoder / decoder matrices -~encoder = FoaEncoderMatrix.newOmni -~decoder = FoaDecoderMatrix.newQuad(pi/6, 'dual') -~distance = 1.2 // louspeaker distance, for NFC, in meters - - -// inspect -~encoder.kind -~encoder.numChannels -~encoder.dirChannels - -~decoder.kind -~decoder.numChannels -~decoder.dirChannels.raddeg -~distance - -( -{ - var sig; // audio signal - var angle, azim; // angle and azimuth control - var fl, bl, br, fr; // quad output channels - - - // display encoder and decoder - "Ambisonic encoding via % encoder".format(~encoder.kind).postln; - "Ambisonic decoding via % decoder".format(~decoder.kind).postln; - - - // angle ---> top = push to plane wave - // bottom = omni-directional - angle = MouseY.kr(pi/2, 0); - - // azimuth -> hard left = back - // centre = centre - // hard right = back - azim = MouseX.kr(pi, -pi); - - // ------------------------------------------------------------ - // test sig - sig = PinkNoise.ar; // mono pink noise - - - // ------------------------------------------------------------ - // encode - sig = FoaEncode.ar(sig, ~encoder); - - // ------------------------------------------------------------ - // transform - sig = FoaTransform.ar(sig, 'push', angle, azim); - - - - // ------------------------------------------------------------ - // nfc & decode (to quad) - sig = FoaTransform.ar(sig, 'nfc', ~distance); - #fl, bl, br, fr = FoaDecode.ar(sig, ~decoder); - [fl, fr, bl, br] // reorder output to match speaker arrangement - -}.scope; -) -// ------------------------------------------------------------ -:: - - - -subsection:: ITU 5.0 decoder - -The Ambisonic Toolkit includes link::http://www.brucewiggins.co.uk/?page_id=78##Bruce Wiggins':: optimised ITU 5.0 decoders. footnote::Irregular decoders in the Ambisonic Toolkit are kindly provided by Bruce Wiggins: link::http://www.brucewiggins.co.uk/::. See also: B. Wiggins, I. Paterson-Stephens, V. Lowndes, and S. Berry, "The design and optimisation of surround sound decoders using heuristic methods," in Proceedings of UKSIM 2003: Conference on Computer Simulation, Cambridge, England, 2003.:: - -note:: A matrix type decoder, see link::Classes/FoaDecoderMatrix#*new5_0:: for further details.:: - - -code:: -// ------------------------------------------------------------ -// 5.0 decoder -// -// mono pink noise source -// omni encoder - - -// define encoder / decoder matrices -~encoder = FoaEncoderMatrix.newOmni -~decoder = FoaDecoderMatrix.new5_0 - -// inspect -~encoder.kind -~encoder.numChannels -~encoder.dirChannels - -~decoder.kind -~decoder.numChannels -~decoder.dirChannels.raddeg - -( -{ - var sig;// audio signal - var angle, azim; // angle and azimuth control - var fc, fl, bl, br, fr; // 5.0 output channels - var lo; // low freq channel place holder - - - // display encoder and decoder - "Ambisonic encoding via % encoder".format(~encoder.kind).postln; - "Ambisonic decoding via % decoder".format(~decoder.kind).postln; - - // angle ---> top = push to plane wave - // bottom = omni-directional - angle = MouseY.kr(pi/2, 0); - - // azimuth -> hard left = back - // centre = centre - // hard right = back - azim = MouseX.kr(pi, -pi); - - - // ------------------------------------------------------------ - // test sig - sig = PinkNoise.ar; // mono pink noise - - - // ------------------------------------------------------------ - // encode - sig = FoaEncode.ar(sig, ~encoder); - - // ------------------------------------------------------------ - // transform - sig = FoaTransform.ar(sig, 'push', angle, azim); - - - // ------------------------------------------------------------ - // decode (to 5.0) - #fc, fl, bl, br, fr = FoaDecode.ar(sig, ~decoder); - lo = Silent.ar; - - [fl, fr, fc, lo, bl, br] // reorder output to match speaker arrangement - -}.scope; -) -// ------------------------------------------------------------ -:: - - -subsection:: Periphonic (cube) decoder - -A full 3D decoder, with eight loudspeakers arranged in upper and lower rings of four. This small eight channel array is not optimal for large scale playback. For public performance, a 10 or 12 channel arrangement (two rings of 5 or 6) is more suitable. - -The loudspeaker layout specified by this decoder is more suited to a small-scale situation. See link::#Diametric_(bi-rectangle)_decoder#below:: for a minimal arrangement appropriate for full 3D studio monitoring. - -note:: A matrix type decoder, see link::Classes/FoaDecoderMatrix#*newPeri:: for further details.:: - - -code:: -// ------------------------------------------------------------ -// periphonic (3D) decoder (8-channels arranged as a cube) -// -// mono pink noise source -// omni encoder - - -// define encoder / decoder matrices -~encoder = FoaEncoderMatrix.newOmni -~decoder = FoaDecoderMatrix.newPeri - -// inspect -~encoder.kind -~encoder.numChannels -~encoder.dirChannels - -~decoder.kind -~decoder.numChannels -~decoder.dirChannels.raddeg - -( -{ - var sig; // audio signal - var angle, azim; // angle and azimuth control - var flu, blu, bru, fru; // cube output channels - var fld, bld, brd, frd; - - - // display encoder and decoder - "Ambisonic encoding via % encoder".format(~encoder.kind).postln; - "Ambisonic decoding via % decoder".format(~decoder.kind).postln; - - // angle ---> top = push to plane wave - // bottom = omni-directional - angle = MouseY.kr(pi/2, 0); - - // azimuth -> hard left = back - // centre = centre - // hard right = back - azim = MouseX.kr(pi, -pi); - - // ------------------------------------------------------------ - // test sig - sig = PinkNoise.ar; // mono pink noise - - - // ------------------------------------------------------------ - // encode - sig = FoaEncode.ar(sig, ~encoder); - - // ------------------------------------------------------------ - // transform - sig = FoaTransform.ar(sig, 'push', angle, azim); - - - - // ------------------------------------------------------------ - // decode (to cube) - #flu, blu, bru, fru, fld, bld, brd, frd = FoaDecode.ar(sig, ~decoder); - [flu, fru, blu, bru, fld, frd, bld, brd] // reorder output to match speaker arrangement - -}.scope; -) -// ------------------------------------------------------------ -:: - -subsection:: Psychoacoustically optimised diametric (bi-rectangle) decoder - -This bi-rectangular decoder has been described by Gerzon as optimal for small-scale, full 3D listening. The decoder presented is an example of a dual-band ( code::'dual':: ) psychoacoustically optmisied, near-field compensated decoder. Meeting all the criteria outlined by Gerzon to qualify as Ambisonic, this decoder is a good choice for full 3D critical studio listening. - -The frontal loudspeaker pair is arranged at code:: [ 30.0, -30.0 ] :: degrees. For studio based work, this can be convenient, as the front pair is at the correct angle for two channel stereo monitoring. - -Near-field compensation, filtering for the near-field effects of loudspeaker placement, is made through the use of link::Classes/FoaNFC::. - - - - - -note:: A matrix type decoder, see link::Classes/FoaDecoderMatrix#*newDiametric:: and link::Classes/FoaNFC:: for further details.:: - -code:: -// ------------------------------------------------------------ -// diametric 3d decoder (8-channels in a bi-rectangle) -// psychocacousticly optimised, & with NFC -// -// mono pink noise source -// omni encoder - - -// define encoder / decoder matrices -~encoder = FoaEncoderMatrix.newOmni -~decoder = FoaDecoderMatrix.newDiametric( - [[30, 0], [-30, 0], [90, 35.3], [-90, 35.3]].degrad, - 'dual' -) -~distance = 1.2 // louspeaker distance, for NFC, in meters - -// inspect -~encoder.kind -~encoder.numChannels -~encoder.dirChannels - -~decoder.kind -~decoder.numChannels -~decoder.dirChannels.raddeg -~distance - -( -{ - var sig; // audio signal - var angle, azim; // angle and azimuth control - var fl, fr, bl, br; // bi-rectangle output channels - var slu, sru, sld, srd; - - - // display encoder and decoder - "Ambisonic encoding via % encoder".format(~encoder.kind).postln; - "Ambisonic decoding via % decoder".format(~decoder.kind).postln; - - // angle ---> top = push to plane wave - // bottom = omni-directional - angle = MouseY.kr(pi/2, 0); - - // azimuth -> hard left = back - // centre = centre - // hard right = back - azim = MouseX.kr(pi, -pi); - - // ------------------------------------------------------------ - // test sig - sig = PinkNoise.ar; // mono pink noise - - - // ------------------------------------------------------------ - // encode - sig = FoaEncode.ar(sig, ~encoder); - - // ------------------------------------------------------------ - // transform - sig = FoaTransform.ar(sig, 'push', angle, azim); - - - - // ------------------------------------------------------------ - // nfc & decode (to bi-rectangle) - sig = FoaTransform.ar(sig, 'nfc', ~distance); - #fl, fr, slu, sru, br, bl, srd, sld = FoaDecode.ar(sig, ~decoder); - [fl, fr, bl, br, slu, sru, sld, srd] // reorder output to match speaker arrangement - -}.scope; -) -// ------------------------------------------------------------ -:: diff --git a/source/ATK/sc/HelpSource/Classes/FoaDecoderKernel.schelp b/source/ATK/sc/HelpSource/Classes/FoaDecoderKernel.schelp deleted file mode 100644 index 0d8d25f4a7..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaDecoderKernel.schelp +++ /dev/null @@ -1,386 +0,0 @@ -CLASS:: FoaDecoderKernel -summary:: First Order Ambisonic (FOA) decoder kernels -categories:: Libraries>Ambisonic Toolkit>FOA>Decoding -related:: Classes/FoaDecoderMatrix, Classes/FoaDecode - -DESCRIPTION:: -Generates decoding kernels required by the Ambisonic Toolkit's first order decoder, link::Classes/FoaDecode::. - -note:: The ATK kernels are required for kernel decoding. Please see the instructions link::http://www.ambisonictoolkit.net/download/kernels/#ATK_Kernels#here:: for installation. :: - - -CLASSMETHODS:: - -METHOD:: newUHJ -Ambisonic UHJ stereo decoder. footnote::See: link::http://en.wikipedia.org/wiki/Ambisonic_UHJ_format:::: - -argument:: kernelSize -256, 512, 1024, 2048, 4096, 8192 - -argument:: server -link::Classes/Server:: on which to load kernel. - -argument:: sampleRate -The sample rate defaults to code::nil:: and is usually supplied by the running server. In NRT, you can specify a sampleRate to avoid booting a server. - -argument:: score -Default is code::nil:: for most real time usages. When using NRT, you can supply a score (a link::Classes/Score:: or a link::Classes/CtkScore::) onto which the kernels will be added, which lets you bypass booting a server. - -discussion:: For production work targeting stereo output, the authors advise using UHJ, as Ambisonic UHJ stereo is the native Ambisonic stereo format. - - - -METHOD:: newSpherical -Synthetic spherical head model HRTF footnote::See: R. O. Duda, "Modeling head related transfer functions," in Proceedings of the Twenty-Seventh Annual Asilomar Conference on Signals, Systems and Computers, Asilomar, CA, 1993.:: decoder, equalised for the diffuse field. - -argument:: subjectID -0 to 9 - -argument:: server -link::Classes/Server:: on which to load kernel. - -argument:: sampleRate -The sample rate defaults to code::nil:: and is usually supplied by the running server. In NRT, you can specify a sampleRate to avoid booting a server. - -argument:: score -Default is code::nil:: for most real time usages. When using NRT, you can supply a score (a link::Classes/Score:: or a link::Classes/CtkScore::) onto which the kernels will be added, which lets you bypass booting a server. - -discussion:: -link::#-newSpherical:: models a sphere only, and is equivalent to placing a pair of spaced, sphere baffled microphones in the soundfield. With no pinnae and no body, elevation cues are not present. - -The strong::subjectID:: argument varies to suit listener head width, with 0 the smallest and 9 the largest head. The user is advised to audition to find a suitable choice. - - - -METHOD:: newListen -Measured HRTF decoder, with measurements from IRCAM's link::http://recherche.ircam.fr/equipes/salles/listen/##Listen HRTF database:: footnote::See: link::http://recherche.ircam.fr/equipes/salles/listen/:::: equalised for the diffuse field. - -argument:: subjectID -1002 to 1059 (51 in total) warning:: strong::subjectID::s are not entirely contiguous.:: - -argument:: server -link::Classes/Server:: on which to load kernel. - -argument:: sampleRate -The sample rate defaults to code::nil:: and is usually supplied by the running server. In NRT, you can specify a sampleRate to avoid booting a server. - -argument:: score -Default is code::nil:: for most real time usages. When using NRT, you can supply a score (a link::Classes/Score:: or a link::Classes/CtkScore::) onto which the kernels will be added, which lets you bypass booting a server. - -discussion:: -The user is advised to audition strong::subjectID::s to find a suitable choice. If an invalid strong::subjectID:: is chosen, valid choices are returned. - - -code:: -// Boot desired server first... -// ... choose an invalid subject -~encoder = FoaDecoderKernel.newListen(0) - -// make sure you scroll up to see the resulting valid subjects! -:: - - - -METHOD:: newCIPIC -Measured HRTF decoder, with measurements from the University of California Davis' link::http://interface.cipic.ucdavis.edu/sound/hrtf.html##CIPIC HRTF database:: footnote::See: link::http://interface.cipic.ucdavis.edu/sound/hrtf.html:::: equalised for the diffuse field. - -argument:: subjectID -3 to 165 (45 in total) warning:: strong::subjectID::s are not entirely contiguous.:: - -argument:: server -link::Classes/Server:: on which to load kernel. - -argument:: sampleRate -The sample rate defaults to code::nil:: and is usually supplied by the running server. In NRT, you can specify a sampleRate to avoid booting a server. - -argument:: score -Default is code::nil:: for most real time usages. When using NRT, you can supply a score (a link::Classes/Score:: or a link::Classes/CtkScore::) onto which the kernels will be added, which lets you bypass booting a server. - - -discussion:: -The link::http://interface.cipic.ucdavis.edu/sound/hrtf.html##CIPIC HRTF database:: provides two link::http://www.gras.dk/00012/00330/##KEMAR dummy:: measurements. strong::subjectID:: = 21 is the large pinnae dummy and strong::subjectID:: = 165 is the small pinnae dummy. - -The user is advised to audition strong::subjectID::s to find a suitable choice. If an invalid strong::subjectID:: is chosen, valid choices are returned. - -code:: -// Boot desired server first... -// ... choose an invalid subject -~encoder = FoaDecoderKernel.newCIPIC(0) - -// make sure you scroll up to see the resulting valid subjects! -:: - - - -INSTANCEMETHODS:: -private:: initPath, initKernel, printOn - - -METHOD:: set - -Describes both the emphasis::signal set:: and the emphasis::tool set::, encompassing the Ambisonic order, as well as channel ordering and normalisation. - -Answers code::'FOA'::, aka traditional B-format: - -table:: -## strong::Ambisonic Order:: || strong::Channel Ordering:: || strong::Channel Normalisation:: -## 1st || Gerzon (aka Furse-Malham) || MaxN -:: - -METHOD:: type -returns:: code::'decoder':: - -METHOD:: op -Answers code::'kernel'::, i.e. the type of operation used to compute the resulting signals. - -METHOD:: kind -Answers the kind of decoder - -discussion:: - -code:: -// decoder - make sure you boot the server first!! -~decoder = FoaDecoderKernel.newUHJ - -// inspect -~decoder.kind - -// don't forget to free!! -~decoder.free -:: - -code:: -// decoder - make sure you boot the server first!! -~decoder = FoaDecoderKernel.newCIPIC - -// inspect -~decoder.kind - -// don't forget to free!! -~decoder.free -:: - - - -METHOD:: subjectID -Answers the strong::subjectID:: of the decoder - -discussion:: - -code:: -// decoder - make sure you boot the server first!! -~decoder = FoaDecoderKernel.newUHJ - -// inspect -~decoder.subjectID - -// don't forget to free!! -~decoder.free -:: - -code:: -// decoder - make sure you boot the server first!! -~decoder = FoaDecoderKernel.newCIPIC - -// inspect -~decoder.subjectID - -// don't forget to free!! -~decoder.free -:: - - - -METHOD:: dim -Answers the number of decoder dimensions: 2D or 3D. - -discussion:: - -code:: -// decoder - make sure you boot the server first!! -~decoder = FoaDecoderKernel.newSpherical - -// inspect -~decoder.dim - -// don't forget to free!! -~decoder.free -:: - -code:: -// decoder - make sure you boot the server first!! -~decoder = FoaDecoderKernel.newCIPIC - -// inspect -~decoder.dim - -// don't forget to free!! -~decoder.free -:: - - -METHOD:: numChannels -Answers the number of loudspeaker (or headphone) feeds (output channels). - -discussion:: - -code:: -// decoder - make sure you boot the server first!! -~decoder = FoaDecoderKernel.newUHJ - -// inspect -~decoder.numChannels - -// don't forget to free!! -~decoder.free -:: - - - - -METHOD:: dirChannels -Answers the direction of loudspeaker (or headphone) feeds, with angles in radians. - - -discussion:: - -code:: -// decoder - make sure you boot the server first!! -~decoder = FoaDecoderKernel.newUHJ - -// inspect -~decoder.dirChannels.raddeg - -// don't forget to free!! -~decoder.free -:: - -code:: -// decoder - make sure you boot the server first!! -~decoder = FoaDecoderKernel.newCIPIC - -// inspect -~decoder.dirChannels.raddeg - -// don't forget to free!! -~decoder.free -:: - - - -METHOD:: kernel -Answers the decoder kernel. - -discussion:: - -code:: -// decoder - make sure you boot the server first!! -~decoder = FoaDecoderKernel.newUHJ - -// inspect -~decoder.kernel - -// don't forget to free!! -~decoder.free -:: - -code:: -// decoder - make sure you boot the server first!! -~decoder = FoaDecoderKernel.newCIPIC - -// inspect -~decoder.kernel - -// don't forget to free!! -~decoder.free -:: - - -METHOD:: kernelSize -Answers the strong::kernelSize::. - -discussion:: - -Use of link::Classes/FoaDecoderKernel:: introduces a delay to the decoded -B-format signal. - -The total delay, in samples, can be calculated as -code::(kernelSize-1)/2 + kernelSize - blockSize::, where -link::Classes/ServerOptions#-blockSize#blockSize:: is the number of -samples in one control period of the link::Classes/Server:: in use. - -code:: -// decoder - make sure you boot the server first!! -~decoder = FoaDecoderKernel.newUHJ - -// inspect -~decoder.kernelSize - -// calculate delay in samples -(~decoder.kernelSize-1)/2 + ~decoder.kernelSize - s.options.blockSize - -// calculate delay in seconds -((~decoder.kernelSize-1)/2 + ~decoder.kernelSize - s.options.blockSize) / s.sampleRate - -// don't forget to free!! -~decoder.free -:: - -code:: -// decoder - make sure you boot the server first!! -~decoder = FoaDecoderKernel.newCIPIC - -// inspect -~decoder.kernelSize - -// calculate delay in samples -(~decoder.kernelSize-1)/2 + ~decoder.kernelSize - s.options.blockSize - -// calculate delay in seconds -((~decoder.kernelSize-1)/2 + ~decoder.kernelSize - s.options.blockSize) / s.sampleRate - -// don't forget to free!! -~decoder.free -:: - - - - -METHOD:: free -Free the kernel. - -discussion:: Release the kernel buffer's memory on the server and return the bufferID back to the server's buffer number allocator for future reuse. - -warning:: Only free the kernel when the link::Classes/FoaDecode#*ar:: is no longer in use!:: - - - -METHOD:: numOutputs -A synonym for link::#-numChannels:: - - -METHOD:: dirOutputs -A synonym for link::#-dirChannels:: - - -METHOD:: numInputs -Answers the number of inputs for the decoder. 3 for 2D and 4 for 3D. - - - -METHOD:: dirInputs -A convenience method providing polymorphism with link::Classes/FoaEncoderKernel#-dirInputs::. - -returns:: - -list:: -## for 2D: code:: [ inf, inf, inf ] :: -## for 3D: code:: [ inf, inf, inf , inf ] :: -:: - -PRIVATE:: buffers, kernelBundle, kernelInfo - - -EXAMPLES:: - -Please see link::Classes/FoaDecode#Examples::. diff --git a/source/ATK/sc/HelpSource/Classes/FoaDecoderMatrix.schelp b/source/ATK/sc/HelpSource/Classes/FoaDecoderMatrix.schelp deleted file mode 100644 index 1126654ff5..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaDecoderMatrix.schelp +++ /dev/null @@ -1,625 +0,0 @@ -CLASS:: FoaDecoderMatrix -summary:: First Order Ambisonic (FOA) decoder matrices -categories:: Libraries>Ambisonic Toolkit>FOA>Decoding -related:: Classes/FoaDecoderKernel, Classes/FoaDecode - -DESCRIPTION:: -Generates decoding matrices required by the Ambisonic Toolkit's first order decoder, link::Classes/FoaDecode::. - - - -CLASSMETHODS:: - - -METHOD:: newMono -Virtual microphone monophonic decoder. - -argument:: theta -Azimuth angle, in radians: pi to pi.neg. - -argument:: phi -Elevation angle, in radians: pi/2 to pi.neg/2. - -argument:: pattern -Virtual microphone pattern, 0 to 1: - -table:: -## strong::pattern:: || strong::virtual microphone:: -## 0.0 || Omni -## 0.5 || Cardioid -## (3-sqrt(3))/2 || Super-cardioid -## 0.75 || Hyper-cardioid -## 1.0 || Bi-directional -:: - -For equivalences to decoder strong::k::, please see link::#decoder k::. - -discussion:: The virtual microphone decoder returns a single monophonic channel, and can be used to "listen in" to the soundfield at the specified azimuth and elevation. - - -METHOD:: newStereo -Virtual microphone stereophonic decoder. - -argument:: angle -The half angle of the stereo pair, in radians: 0 to pi., Default: pi/2 - -argument:: pattern -Virtual microphone pattern, 0 to 1: - -table:: -## strong::pattern:: || strong::virtual microphone:: -## 0.0 || Omni -## 0.5 || Cardioid -## (3-sqrt(3))/2 || Super-cardioid -## 0.75 || Hyper-cardioid -## 1.0 || Bi-directional -:: - -For equivalences to decoder strong::k::, please see link::#decoder k::. - -discussion:: Standard coincident stereo microphone configurations footnote::Sengpiel Audio provides a useful tool to visualise resulting imaging: link::http://www.sengpielaudio.com/Visualization-Blumlein-E.htm::::: - -code:: -// Default: Cardioids at 180 deg -~decoder = FoaDecoderMatrix.newStereo - -// Cardioids at 131 deg -~angle = (131/2).degrad -~pattern = 0.5 -~decoder = FoaDecoderMatrix.newStereo(~angle, ~pattern) - -// Super-cardioids at 115 deg -~angle = (115/2).degrad -~pattern = (3-sqrt(3))/2 -~decoder = FoaDecoderMatrix.newStereo(~angle, ~pattern) - -// Hyper-cardioids at 105 deg -~angle = (105/2).degrad -~pattern = 0.75 -~decoder = FoaDecoderMatrix.newStereo(~angle, ~pattern) - -// Blumlein -~angle = (90/2).degrad -~pattern = 1.0 -~decoder = FoaDecoderMatrix.newStereo(~angle, ~pattern) - -:: - -note::While the virtual microphone stereophonic decoder is very easy and convenient, for production work the authors advise using the UHJ ( link::Classes/FoaDecoderKernel#*newUHJ:: ) decoder. footnote::See link::http://en.wikipedia.org/wiki/Ambisonic_UHJ_format:: for further information.:::: - - -METHOD:: newQuad -Optimised quadraphonic decoder with variable loudspeaker angle. - -argument:: angle -The half angle of the front (and rear) loudspeaker pair. Defaults to pi/4, a square. In radians. - -argument:: k -The k factor of the decoder. May be specified as a float: 0.5 to 1.0. Or more conviently by name: - -list:: -## code::'single':: -## code::'dual':: -## code::'velocity':: -## code::'energy':: -## code::'controlled':: -:: - -discussion:: The outputs are in anti-clockwise order. The position of the first speaker is left of centre. link::#-dirChannels:: may be used to query resulting loudspeaker directions. - -Varying strong::angle:: allows a number of flexible quadraphonic decoders to be generated. E.g, strong::angle:: = pi/6 returns a decoder with loudspeakers at [ 30, 150, -150, 30 ] degrees. - -Please see link::#decoder k:: for further discussion on strong::k::. - - - -METHOD:: new5_0 -link::http://www.brucewiggins.co.uk/?page_id=78##Bruce Wiggins':: optimised ITU 5.0 decoders. footnote::Irregular decoders in the Ambisonic Toolkit are kindly provided by Bruce Wiggins: link::http://www.brucewiggins.co.uk/::. See also: B. Wiggins, I. Paterson-Stephens, V. Lowndes, and S. Berry, "The design and optimisation of surround sound decoders using heuristic methods," in Proceedings of UKSIM 2003: Conference on Computer Simulation, Cambridge, England, 2003.:: - -argument:: irregKind -Three kinds are available: - -list:: -## code::'focused':: -## code::'equal':: -## code::'four':: -:: - -discussion:: -The outputs are in anti-clockwise order. The position of the first speaker is centre. link::#-dirChannels:: may be used to query resulting loudspeaker directions. - -strong::irregKind:: code:: = 'focused':: returns a focused, but front weighted image. code::'equal':: equalises the angles across the image. code::'four':: is similar to code::'equal'::, but doesn't use the centre speaker. - - - - -METHOD:: newPanto -Pantophonic (2D) regular polygon decoder. - -argument:: numChans -number of loudspeaker feeds - -argument:: orientation -code::'flat':: or code::'point':: - -argument:: k -The k factor of the decoder. May be specified as a float: 0.5 to 1.0. Or more conviently by name: - -list:: -## code::'single':: -## code::'dual':: -## code::'velocity':: -## code::'energy':: -## code::'controlled':: -:: - -discussion:: The outputs are in anti-clockwise order. The position of the first speaker is either centre or left of centre. link::#-dirChannels:: may be used to query resulting loudspeaker directions. - -Used in conjunction with link::Classes/FoaDecode#*ar:: the resulting decoder is equivalent to link::Classes/DecodeB2#*ar:: (SuperCollider's inbuilt decoder), albeit with the addition of variable strong::k:: and dual-band optimised psychoacoustic decoding. link::Classes/DecodeB2#*ar:: is a "controlled opposites" decoder ( strong::k:: = code::'controlled':: ) with a gain of 6dB greater than link::#*newPanto::. - -Please see link::#decoder k:: for further discussion on strong::k::. - - -METHOD:: newPeri -Periphonic (3D) dual ring, regular cylindrical decoder. - -argument:: numChanPairs -Number of channel pairs. (Half the total number of loudspeaker feeds.) - -argument:: elevation -Elevation of the upper ring, measured from the origin. In radians. - -argument:: orientation -code::'flat':: or code::'point':: - -argument:: k -The k factor of the decoder. May be specified as a float: 0.5 to 1.0. Or more conviently by name: - -list:: -## code::'single':: -## code::'dual':: -## code::'velocity':: -## code::'energy':: -## code::'controlled':: -:: - -discussion:: The outputs are in anti-clockwise order, beginning with the top ring. The position of the first speaker is either centre or left of centre. link::#-dirChannels:: may be used to query resulting loudspeaker directions. - -Please see link::#decoder k:: for further discussion on strong::k::. - - -METHOD:: newDiametric -Gerzon's classic diametric decoder, suitable for varied periphonic and pantophonic loudspeaker arrays. footnote::See: M. A. Gerzon, "Practical Periphony: The Reproduction of Full-Sphere Sound," in Proceedings of the 65th Audio Engineering Engineering Society Convention, London, 1980, p. 10.:: - -argument:: directions -An array of directions for half of the loudspeaker feeds for the desired decoder. Specify in radians. - -Rank 1 arrays return pantophonic, while rank 2 arrays return periphonic. E.g., -code:: -// 2D: -~directions = [ theta0, theta1, ... thetaN ]; -:: -code:: -// 3D: -~directions = [ [ theta0, phi0 ], [ theta1, phi1 ], ... [ thetaN, phiN ] ]; -:: - -argument:: k -The k factor of the decoder. May be specified as a float: 0.5 to 1.0. Or more conviently by name: - -list:: -## code::'single':: -## code::'dual':: -## code::'velocity':: -## code::'energy':: -## code::'controlled':: -:: - -discussion:: -strong::directions:: specifies only half of the loudspeakers for the resulting array, the remaining loudspeakers are diametrically opposite (through the origin). link::#-dirChannels:: may be used to query resulting loudspeaker directions. - -code:: -// Pantophonic (2D) decoder with four channels arranged in a rectangle: -// [ 30, -30, -150, 150 ] - -// specify 1/2 the desired directions -~directions = [ 30, -30 ].degrad; -~decoder = FoaDecoderMatrix.newDiametric(~directions); - -// inspect -~decoder.dirChannels.raddeg -:: -code:: -// Periphonic (3D) decoder with eight channels arranged in a bi-rectangle: -// [ [ 30, 0 ], [ -30, 0 ], [ 90, 35.3 ], [ -90, 35.3 ], -// [ -150, -0 ], [ 150, -0 ], [ -90, -35.3 ], [ 90, -35.3 ] ] - -// specify 1/2 the desired directions -~directions = [[ 30, 0 ], [ -30, 0 ], [ 90, 35.3 ], [ -90, 35.3]].degrad; -~decoder = FoaDecoderMatrix.newDiametric(~directions); - -// inspect -~decoder.dirChannels.raddeg -:: - -Please see link::#decoder k:: for further discussion on strong::k::. - - -METHOD:: newBtoA -B-format to A-format decoder. Decodes to a variety of tetrahedral orientations and W channel weights. - -argument:: orientation -Orientation of the A-format tetrahedron. - -table:: -## strong::orientation:: || strong::angles:: ([theta, phi] in degrees) -## code::'flu':: || code:: [[45.0, 35.3], [-45.0, -35.3], [135.0, -35.3], [-135.0, 35.3]] :: -## code::'fld':: || code:: [[45.0, -35.3], [-45.0 , 35.3], [135.0, 35.3], [-135.0, -35.3]] :: -## code::'flr':: || code:: [[54.7, 0.0], [-54.7, 0.0], [180.0, 54.7], [ 180.0, -54.7]] :: -## code::'fud':: || code:: [[ 0.0, 54.7], [ 0.0, -54.7], [125.7, 0.0], [-125.7, 0.0]] :: -## code::'fbd':: || code:: [[ 0.0, 0.0], [180.0, -70.5], [112.2, 28.1], [-112.2, 28.1]] :: -## code::'fbu':: || code:: [[ 0.0, 0.0], [180.0, 70.5], [112.2, -28.1], [-112.2, -28.1]] :: -## code::'flru':: || code:: [[67.8, 28.1], [-67.8, 28.1], [ 0.0, -70.5], [ 180.0, 0.0]] :: -## code::'flrd':: || code:: [[67.8, -28.1], [-67.8, -28.1], [ 0.0, 70.5], [ 180.0, 0.0]] :: -:: - -argument:: weight -The W weight factor. - -For convenience, equivalent virtual microphone strong::pattern:: and decoding strong::k:: are also listed. - -table:: -## strong::weight:: || strong::kind:: || strong::W scale:: || strong::virtual microphone:: || strong::pattern:: || strong::decoding:: || strong::k:: -## code::'dec':: || Decorrelated (on the sphere) || 1/sqrt(3) || Hyper-cardioid || 0.75 || strict soundfield || code::'velocity':: -## code::'can':: || Canonical (B-format) || 1/sqrt(2) || || sqrt(6)/(1+sqrt(6)) || || sqrt(2/3) -## code::'uns':: || Unscaled || 1 || Super-cardioid || (3-sqrt(3))/2 || energy optimised || code::'energy':: -## code::'car':: || Cardioid || sqrt(3) || Cardioid || 0.5 || controlled opposites || code::'controlled':: -:: - -discussion:: -anchor::btoadiscuss:: -The B-format to A-format decoder is primarily intended to be used in conjuction with the A-format to B-format encoder, link::Classes/FoaEncoderMatrix#*newAtoB::. Though the use of BtoA/AtoB decoder/encoder pairs, signal processing networks can be constructed which preserve the spatial encoding found in the original input B-format signal. - -In order to reconstruct the original B-format signal, matching strong::orientation:: and strong::weight:: for both decoding and encoding should be chosen. For most applications the default strong::weight:: (code::'dec'::) is a good choice. This strong::weight:: decodes to four planewaves. Setting strong::weight:: to code::'uns':: returns an energy optimised decoding. For link::Browse#UGens>Dynamics#Dynamic Range Control:: processing, code::'uns':: is often a good choice. - -code:: -// ------------------------------------------------------------ -// Single stage allpass ambience in A-format -// -// mono pink noise source -// FoaPanB encoder -// -// quad decoder - - -// decoder matrix -~decoder = FoaDecoderMatrix.newQuad - -// b-to-a, a-to-b matrices -~b2a = FoaDecoderMatrix.newBtoA -~a2b = FoaEncoderMatrix.newAtoB - -// inspect -~decoder.kind -~decoder.numChannels -~decoder.dirChannels.raddeg - -( -{ - var sig; // audio signal - var azim; // azimuth control - var fl, bl, br, fr; // quad output channels - var delaytime, decaytime; // allpass parameters - - - // display decoder - "Ambisonic decoding via % decoder".format(~decoder.kind).postln; - - // ------------------------------------------------------------ - // parameters - delaytime = 0.1; - decaytime = 0.2; - - // azimuth -> hard left = back - // centre = centre - // hard right = back - azim = MouseX.kr(pi, -pi); - - // ------------------------------------------------------------ - // test sig - sig = PinkNoise.ar * LFPulse.ar(2.0); // enveloped mono pink noise - - - // ------------------------------------------------------------ - // encode to b-format - sig = FoaPanB.ar(sig, azim); - - // ------------------------------------------------------------ - // b-to-a --> allpass --> a-to-b - sig = FoaDecode.ar(sig, ~b2a); - sig = AllpassN.ar(sig, delaytime, Array.fill(4, {delaytime}).rand, decaytime); - sig = FoaEncode.ar(sig, ~a2b); - - - // ------------------------------------------------------------ - // decode (to quad) - #fl, bl, br, fr = FoaDecode.ar(sig, ~decoder); - [fl, fr, bl, br] // reorder output to match speaker arrangement - -}.scope; -) -// ------------------------------------------------------------ -:: - -METHOD:: newHoa1 -A first order link::https://en.wikipedia.org/wiki/Ambisonic_data_exchange_formats##Ambisonic format exchange:: decoder. Decodes traditional B-format to a variety of formats. - -argument:: ordering -Input Ambisonic channel component ordering. - -table:: -## strong::ordering:: || strong::kind:: -## code::'acn':: || Ambisonic Channel Number (ACN) -## code::'sid':: || Single Index Designation (SID) -:: - -argument:: normalisation -Spherical harmonic normalisation method. - -table:: -## strong::normalisation:: || strong::kind:: -## code::'n3d':: || Orthonormal basis for 3D decomposition (N3D) -## code::'sn3d':: || Semi-normalised basis for 3D decomposition (SN3D) -:: - - -discussion:: -Decoding means decoding from traditional B-format to another Ambisonic channel componenent orderding and normalisation. In other words, from strong::Gerzon:: (aka strong::Furse-Malham::) ordering with strong::MaxN:: normalisation to some other standard scheme. - -note::code::Hoa1:: in the method name link::#*newHoa1:: refers to Higher Order Ambisonic (HOA) encoding format, Ambisonic order = 1.:: - - -METHOD:: newAmbix1 -A first order link::https://en.wikipedia.org/wiki/Ambisonic_data_exchange_formats##Ambisonic format exchange:: decoder. Decodes traditional B-format to AmbiX. A convenience alias to link::#*newHoa1::. - - -discussion:: -Decoding means decoding from traditional B-format to another Ambisonic channel componenent orderding and normalisation. In this case, from strong::Gerzon:: (aka strong::Furse-Malham::) ordering, strong::MaxN:: normalisation to the AmbiX encoding scheme (strong::ACN:: ordering, strong::SN3D:: normalisation). - - -METHOD:: newFromFile -Create an FoaEncoderMatrix by loading a matrix from a file. - -argument:: filePathOrName -Can be a path relative to your code::/extensions/matrices/decoders:: folder: -code:: -Atk.getMatrixExtensionPath('decoders').fullPath -:: -Otherwise a full path to your matrix file. - -discussion:: -See the link::Guides/Guide-to-ATK-Matrix-Files:: for more information. - - -COPYMETHOD:: AtkMatrix, *newFromMatrix - - - -SUBSECTION:: Decoder k -The default strong::k:: ( code::'single':: ), for decoders accepting strong::k:: as an argument, returns an code::'energy':: optimised (aka "maximum energy" or "max rE") decoder. code::'dual':: returns a dual-band psychoacoustically optimised decoder. footnote::See: E. Benjamin, R. Lee, and A. Heller, "Is My Decoder Ambisonic?," in Proceedings of the 125th Audio Engineering Society Convention, San Francisco, 2008.:: The code::'dual':: decoder is the optimum choice for small scale studio or domestic settings. code::'single':: is suitable for larger, mid-scale environments. code::'velocity':: returns "strict soundfield" (aka "planewave" or "basic") decoding. footnote::While "strict soundfield" decoding is usually not preferred for first order Ambisonics audition, it is usually a good choice for use in signal processing networks.:: code::'controlled':: returns "controlled opposites" decoding (aka "minimum energy" or "in phase"), which is often preferred in large-scale, concert environments. footnote::See: D. G. Malham, "Experience with Large Area 3-D Ambisonic Sound Systems," Proceedings of the Institute of Acoustics, vol. 14, no. 5, pp. 209–215, Nov. 1992.:: (SuperCollider's inbuilt decoder, link::Classes/DecodeB2#*ar::, is a "controlled opposites" decoder. See link::Classes/FoaDecode#supercollider#this discussion::.) - -Given a uniform periphonic (3D) distribution of loudspeakers, e.g. a link::https://en.wikipedia.org/wiki/Platonic_solid##Platonic solid::, some useful strong::virtual microphone:: equivalences: - -table:: -## strong::keyword:: || strong::decoding:: || strong::virtual microphone:: || strong::pattern:: -## code::'velocity':: || strict soundfield || Hyper-cardioid || 0.75 -## code::'energy':: || energy optimised || Super-cardioid || (3-sqrt(3))/2 -## code::'controlled':: || controlled opposites || Cardioid || 0.5 -:: - -The strong::k:: keywords translate to numerical values as follows: - -table:: -## strong::keyword:: || strong::k:: for pantophonic (2D) || strong::k:: for periphonic (3D) -## code::'velocity':: || 1 || 1 -## code::'energy':: || 1/sqrt(2) || 1/sqrt(3) -## code::'controlled':: || 1/2 || 1/3 -:: - -note:: For large-scale concert presentation, the authors advise auditioning values of strong::k:: between those noted for code::'energy':: and code::'controlled'::.:: - - - - -INSTANCEMETHODS:: -private:: initPeri, initK2D, initStereo, initBtoA, initPanto, initK3D, initQuad, printOn, initMono, init5_0, initDiametric, initHoa1, initAmbix1 - -METHOD:: set - -Describes both the emphasis::signal set:: and the emphasis::tool set::, encompassing the Ambisonic order, as well as channel ordering and normalisation. - -Answers code::'FOA'::, aka traditional B-format: - -table:: -## strong::Ambisonic Order:: || strong::Channel Ordering:: || strong::Channel Normalisation:: -## 1st || Gerzon (aka Furse-Malham) || MaxN -:: - -METHOD:: type -returns:: code::'decoder':: - -COPYMETHOD:: AtkMatrix, -op - -METHOD:: kind -Answers the kind of decoder - -discussion:: - -code:: -// decoder -~decoder = FoaDecoderMatrix.newQuad - -// inspect -~decoder.kind -:: - -code:: -// decoder -~decoder = FoaDecoderMatrix.newPeri - -// inspect -~decoder.kind -:: - - - -METHOD:: dim -Answers the number of decoder dimensions: 2D or 3D. - -discussion:: - -code:: -// decoder -~decoder = FoaDecoderMatrix.newQuad - -// inspect -~decoder.dim -:: - -code:: -// decoder -~decoder = FoaDecoderMatrix.newPeri - -// inspect -~decoder.dim -:: - -METHOD:: numChannels -Answers the number of loudspeaker feeds (output channels). - -discussion:: - -code:: -// decoder (narrow quad) -~decoder = FoaDecoderMatrix.newQuad(pi/6) - -// inspect -~decoder.numChannels -:: - -code:: -// decoder (two rings of 6) -~decoder = FoaDecoderMatrix.newPeri(6) - -// inspect -~decoder.numChannels -:: - - -METHOD:: dirChannels -Answers the direction of loudspeaker feeds, with angles in radians. - -returns:: A rank 1 array for pantophonic, and rank 2 array for periphonic. E.g., -code:: -// 2D: -[ theta0, theta1, ... thetaN ] -:: -code:: -// 3D -[ [ theta0, phi0 ], [ theta1, phi1 ], ... [ thetaN, phiN ] ] -:: - -discussion:: Loudspeakers should be place at the angles returned (with equal radii). - -code:: -// decoder (narrow quad) -~decoder = FoaDecoderMatrix.newQuad(pi/6) - -// inspect -~decoder.dirChannels.raddeg -:: - -code:: -// decoder (two rings of 6) -~decoder = FoaDecoderMatrix.newPeri(6) - -// inspect -~decoder.dirChannels.raddeg -:: - -code:: -// Pantophonic (2D) decoder with four channels arranged in a rectangle: -~directions = [ 30, -30 ].degrad -~decoder = FoaDecoderMatrix.newDiametric(~directions) - -// inspect -~decoder.dirChannels.raddeg -:: - -code:: -// Periphonic (3D) decoder with eight channels arranged in a bi-rectangle: -~directions = [[ 30, 0 ], [ -30, 0 ], [ 90, 35.3 ], [ -90, 35.3]].degrad -~decoder = FoaDecoderMatrix.newDiametric(~directions) - -// inspect -~decoder.dirChannels.raddeg -:: - - -METHOD:: matrix -Answers the decoding matrix - - - -METHOD:: shelfFreq -If the decoder is dual-band psychoacoustically optimised, get or set the shelf filter frequency, in Hz. - -discussion:: strong::shelfFreq:: defaults to 400Hz, which is suitable for a well aligned domestic or studio space. strong::shelfFreq:: may be set up to 700Hz, for a tight sweet-spot, and very focused single user listening. - - -METHOD:: shelfK -If the decoder is dual-band psychoacoustically optimised, get or set the shelf k. - -discussion:: If set, strong::shelfK:: is optimised for the chosen decoder, and should be left at the assigned value unless one is an expert user. - - - -METHOD:: numOutputs -A synonym for link::#-numChannels:: - - -METHOD:: dirOutputs -A synonym for link::#-dirChannels:: - - - -METHOD:: numInputs -Answers the number of inputs for the decoder. 3 for 2D and 4 for 3D. - - -METHOD:: dirInputs -A convenience method providing polymorphism with link::Classes/FoaEncoderMatrix#-dirInputs::. - -returns:: - -list:: -## for 2D: code:: [ inf, inf, inf ] :: -## for 3D: code:: [ inf, inf, inf, inf ] :: -:: - - -COPYMETHOD:: AtkMatrix, -info - -COPYMETHOD:: AtkMatrix, -fileParse - -COPYMETHOD:: AtkMatrix, -filePath - -COPYMETHOD:: AtkMatrix, -fileName - -COPYMETHOD:: AtkMatrix, -writeToFile - -private:: initDecoderVarsForFiles - -EXAMPLES:: - -Please see link::Classes/FoaDecode#Examples::. diff --git a/source/ATK/sc/HelpSource/Classes/FoaDirect.schelp b/source/ATK/sc/HelpSource/Classes/FoaDirect.schelp deleted file mode 100644 index 6db70b2fa8..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaDirect.schelp +++ /dev/null @@ -1,48 +0,0 @@ -CLASS:: FoaDirect -summary:: First Order Ambisonic (FOA) directivity transformer -categories:: Libraries>Ambisonic Toolkit>FOA>Transforming>UGens, UGens>Multichannel>Ambisonics, UGens>Multichannel>Panners -related:: Classes/FoaDirectO, Classes/FoaDirectX, Classes/FoaDirectY, Classes/FoaDirectZ, Classes/FoaTransform, Classes/FoaXform - -DESCRIPTION:: -Adjust the soundfield directivity of a first order ambisonic signal (B-format) across an arbitrary plane. - - -NOTE:: -link::Classes/FoaDirect:: is usually called via the convenience wrapper link::Classes/FoaTransform::. -:: - - - -CLASSMETHODS:: - -METHOD:: ar - -argument:: in -The B-format signal, an array: [w, x, y, z] - -argument:: angle -The distortion angle, in radians. 0 to pi/2 - -argument:: theta -Azimuth for the normal to the plane, in radians. - -argument:: phi -Elevation for the normal to the plane, in radians. - -argument:: mul -Output will be multiplied by this value. - -argument:: add -This value will be added to the output. - - -discussion:: - -strong::Angle:: = 0 retains the current directivity of the soundfield. Increasing strong::angle:: towards pi/2 decreases the directivity along the normal defined by strong::theta:: and strong::phi::, reducing the gain on this normal to zero, and is equivalent to a spatial low-pass filter. The resulting image becomes directionless on the normal. - -note:: Corresponding matrix transformer: link::Classes/FoaXformerMatrix#*newDirect:: :: - - -EXAMPLES:: - -Please see various examples link::Classes/FoaTransform#examples#here::. \ No newline at end of file diff --git a/source/ATK/sc/HelpSource/Classes/FoaDirectO.schelp b/source/ATK/sc/HelpSource/Classes/FoaDirectO.schelp deleted file mode 100644 index 101cab4498..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaDirectO.schelp +++ /dev/null @@ -1,47 +0,0 @@ -CLASS:: FoaDirectO -summary:: First Order Ambisonic (FOA) directivity transformer -categories:: Libraries>Ambisonic Toolkit>FOA>Transforming>UGens, UGens>Multichannel>Ambisonics, UGens>Multichannel>Panners -related:: Classes/FoaDirectX, Classes/FoaDirectY, Classes/FoaDirectZ, Classes/FoaDirect, Classes/FoaTransform, Classes/FoaXform - -DESCRIPTION:: -Adjust the soundfield directivity of a first order ambisonic signal (B-format) across the origin. - - -NOTE:: -link::Classes/FoaDirectO:: is usually called via the convenience wrapper link::Classes/FoaTransform::. -:: - - -CLASSMETHODS:: - -METHOD:: ar - -argument:: in -The B-format signal, an array: [w, x, y, z] - -argument:: angle -The distortion angle, in radians. 0 to pi/2 - -argument:: mul -Output will be multiplied by this value. - -argument:: add -This value will be added to the output. - -discussion:: - -strong::Angle:: = 0 retains the current directivity of the soundfield. Increasing strong::angle:: towards pi/2 decreases the directivity, reducing the gains on the directional compenents to zero, and is equivalent to a spatial low-pass filter. The resulting image becomes omnidirectional or directionless. - -anchor::figure:: - -image::direct_fig.png#DirectO imaging:: - - -note:: Corresponding matrix transformer: link::Classes/FoaXformerMatrix#*newDirectO:: :: - - - - -EXAMPLES:: - -Please see various examples link::Classes/FoaTransform#examples#here::. \ No newline at end of file diff --git a/source/ATK/sc/HelpSource/Classes/FoaDirectX.schelp b/source/ATK/sc/HelpSource/Classes/FoaDirectX.schelp deleted file mode 100644 index 855bbe20f9..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaDirectX.schelp +++ /dev/null @@ -1,48 +0,0 @@ -CLASS:: FoaDirectX -summary:: First Order Ambisonic (FOA) directivity transformer -categories:: Libraries>Ambisonic Toolkit>FOA>Transforming>UGens, UGens>Multichannel>Ambisonics, UGens>Multichannel>Panners -related:: Classes/FoaDirectO, Classes/FoaDirectY, Classes/FoaDirectZ, Classes/FoaDirect, Classes/FoaTransform, Classes/FoaXform - -DESCRIPTION:: -Adjust the soundfield directivity of a first order ambisonic signal (B-format) along the x-axis. - - -NOTE:: -link::Classes/FoaDirectX:: is usually called via the convenience wrapper link::Classes/FoaTransform::. -:: - - - -CLASSMETHODS:: - -METHOD:: ar - -argument:: in -The B-format signal, an array: [w, x, y, z] - -argument:: angle -The distortion angle, in radians. 0 to pi/2 - -argument:: mul -Output will be multiplied by this value. - -argument:: add -This value will be added to the output. - - -discussion:: - -strong::Angle:: = 0 retains the current directivity of the soundfield. Increasing strong::angle:: towards pi/2 decreases the directivity along the x-axis, reducing the gain on this axis to zero, and is equivalent to a spatial low-pass filter. The resulting image becomes directionless on the x-axis. - -anchor::figure:: - - -image::direct_x_fig.png#DirectX imaging:: - - -note:: Corresponding matrix transformer: link::Classes/FoaXformerMatrix#*newDirectX:: :: - - -EXAMPLES:: - -Please see various examples link::Classes/FoaTransform#examples#here::. \ No newline at end of file diff --git a/source/ATK/sc/HelpSource/Classes/FoaDirectY.schelp b/source/ATK/sc/HelpSource/Classes/FoaDirectY.schelp deleted file mode 100644 index 4a86a64241..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaDirectY.schelp +++ /dev/null @@ -1,48 +0,0 @@ -CLASS:: FoaDirectY -summary:: First Order Ambisonic (FOA) directivity transformer -categories:: Libraries>Ambisonic Toolkit>FOA>Transforming>UGens, UGens>Multichannel>Ambisonics, UGens>Multichannel>Panners -related:: Classes/FoaDirectO, Classes/FoaDirectX, Classes/FoaDirectZ, Classes/FoaDirect, Classes/FoaTransform, Classes/FoaXform - -DESCRIPTION:: -Adjust the soundfield directivity of a first order ambisonic signal (B-format) along the y-axis. - - -NOTE:: -link::Classes/FoaDirectY:: is usually called via the convenience wrapper link::Classes/FoaTransform::. -:: - - - -CLASSMETHODS:: - -METHOD:: ar - -argument:: in -The B-format signal, an array: [w, x, y, z] - -argument:: angle -The distortion angle, in radians. 0 to pi/2 - -argument:: mul -Output will be multiplied by this value. - -argument:: add -This value will be added to the output. - - -discussion:: - -strong::Angle:: = 0 retains the current directivity of the soundfield. Increasing strong::angle:: towards pi/2 decreases the directivity along the y-axis, reducing the gain on this axis to zero, and is equivalent to a spatial low-pass filter. The resulting image becomes directionless on the y-axis. - - -anchor::figure:: - -image::direct_y_fig.png#DirectY imaging:: - - -note:: Corresponding matrix transformer: link::Classes/FoaXformerMatrix#*newDirectY:: :: - - -EXAMPLES:: - -Please see various examples link::Classes/FoaTransform#examples#here::. \ No newline at end of file diff --git a/source/ATK/sc/HelpSource/Classes/FoaDirectZ.schelp b/source/ATK/sc/HelpSource/Classes/FoaDirectZ.schelp deleted file mode 100644 index ed3dbcb967..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaDirectZ.schelp +++ /dev/null @@ -1,42 +0,0 @@ -CLASS:: FoaDirectZ -summary:: First Order Ambisonic (FOA) directivity transformer -categories:: Libraries>Ambisonic Toolkit>FOA>Transforming>UGens, UGens>Multichannel>Ambisonics, UGens>Multichannel>Panners -related:: Classes/FoaDirectO, Classes/FoaDirectX, Classes/FoaDirectY, Classes/FoaDirect, Classes/FoaTransform, Classes/FoaXform - -DESCRIPTION:: -Adjust the soundfield directivity of a first order ambisonic signal (B-format) along the z-axis. - - -NOTE:: -link::Classes/FoaDirectZ:: is usually called via the convenience wrapper link::Classes/FoaTransform::. -:: - - - -CLASSMETHODS:: - -METHOD:: ar - -argument:: in -The B-format signal, an array: [w, x, y, z] - -argument:: angle -The distortion angle, in radians. 0 to pi/2 - -argument:: mul -Output will be multiplied by this value. - -argument:: add -This value will be added to the output. - - -discussion:: - -strong::Angle:: = 0 retains the current directivity of the soundfield. Increasing strong::angle:: towards pi/2 decreases the directivity along the z-axis, reducing the gain on this axis to zero, and is equivalent to a spatial low-pass filter. The resulting image becomes directionless on the z-axis. - -note:: Corresponding matrix transformer: link::Classes/FoaXformerMatrix#*newDirectZ:: :: - - -EXAMPLES:: - -Please see various examples link::Classes/FoaTransform#examples#here::. \ No newline at end of file diff --git a/source/ATK/sc/HelpSource/Classes/FoaDominate.schelp b/source/ATK/sc/HelpSource/Classes/FoaDominate.schelp deleted file mode 100644 index e43022742d..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaDominate.schelp +++ /dev/null @@ -1,47 +0,0 @@ -CLASS:: FoaDominate -summary:: First Order Ambisonic (FOA) dominance transformer -categories:: Libraries>Ambisonic Toolkit>FOA>Transforming>UGens, UGens>Multichannel>Ambisonics, UGens>Multichannel>Panners -related:: Classes/FoaDominateX, Classes/FoaDominateY, Classes/FoaDominateZ, Classes/FoaTransform, Classes/FoaXform - -DESCRIPTION:: -Apply dominance to a first order ambisonic signal (B-format) along an arbitrary axis. - - -NOTE:: -link::Classes/FoaDominate:: is usually called via the convenience wrapper link::Classes/FoaTransform::. -:: - - - -CLASSMETHODS:: - -METHOD:: ar - -argument:: in -The B-format signal, an array: [w, x, y, z] - -argument:: gain -Dominance gain, in dB. - -argument:: theta -Azimuth, in radians. - -argument:: phi -Elevation, in radians. - -argument:: mul -Output will be multiplied by this value. - -argument:: add -This value will be added to the output. - - -discussion:: Applies dominance along the axis defined by strong::theta:: and strong::phi::. See link::Classes/FoaDominateX::. - - -note:: Corresponding matrix transformer: link::Classes/FoaXformerMatrix#*newDominate:: :: - - -EXAMPLES:: - -Please see various examples link::Classes/FoaTransform#examples#here::. \ No newline at end of file diff --git a/source/ATK/sc/HelpSource/Classes/FoaDominateX.schelp b/source/ATK/sc/HelpSource/Classes/FoaDominateX.schelp deleted file mode 100644 index 695f0e4c0a..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaDominateX.schelp +++ /dev/null @@ -1,45 +0,0 @@ -CLASS:: FoaDominateX -summary:: First Order Ambisonic (FOA) dominance transformer -categories:: Libraries>Ambisonic Toolkit>FOA>Transforming>UGens, UGens>Multichannel>Ambisonics, UGens>Multichannel>Panners -related:: Classes/FoaDominateY, Classes/FoaDominateZ, Classes/FoaDominate, Classes/FoaTransform, Classes/FoaXform - -DESCRIPTION:: -Apply dominance to a first order ambisonic signal (B-format) along the x-axis. - - -NOTE:: -link::Classes/FoaDominateX:: is usually called via the convenience wrapper link::Classes/FoaTransform::. -:: - - - -CLASSMETHODS:: - -METHOD:: ar - -argument:: in -The B-format signal, an array: [w, x, y, z] - -argument:: gain -Dominance gain, in dB. - -argument:: mul -Output will be multiplied by this value. - -argument:: add -This value will be added to the output. - -discussion:: Positive values of strong::gain:: increase the gain at code:: [0, 0] :: to strong::+gain:: dB, while decreasing the gain at code:: [pi, 0] :: to strong::-gain::. This simultaneously results in a distortion of the image towards code:: [0, 0] ::. Negative values of gain invert this distortion, distorting towards code:: [pi, 0] :: . The default, 0, results in no change. - - -anchor::figure:: - -image::dominance_fig.png#Dominance imaging:: - - -note:: Corresponding matrix transformer: link::Classes/FoaXformerMatrix#*newDominateX:: :: - - -EXAMPLES:: - -Please see various examples link::Classes/FoaTransform#examples#here::. \ No newline at end of file diff --git a/source/ATK/sc/HelpSource/Classes/FoaDominateY.schelp b/source/ATK/sc/HelpSource/Classes/FoaDominateY.schelp deleted file mode 100644 index 1d4c435577..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaDominateY.schelp +++ /dev/null @@ -1,41 +0,0 @@ -CLASS:: FoaDominateY -summary:: First Order Ambisonic (FOA) dominance transformer -categories:: Libraries>Ambisonic Toolkit>FOA>Transforming>UGens, UGens>Multichannel>Ambisonics, UGens>Multichannel>Panners -related:: Classes/FoaDominateX, Classes/FoaDominateZ, Classes/FoaDominate, Classes/FoaTransform, Classes/FoaXform - -DESCRIPTION:: -Apply dominance to a first order ambisonic signal (B-format) along the y-axis. - - -NOTE:: -link::Classes/FoaDominateY:: is usually called via the convenience wrapper link::Classes/FoaTransform::. -:: - - - -CLASSMETHODS:: - -METHOD:: ar - -argument:: in -The B-format signal, an array: [w, x, y, z] - -argument:: gain -Dominance gain, in dB. - -argument:: mul -Output will be multiplied by this value. - -argument:: add -This value will be added to the output. - - -discussion:: Positive values of strong::gain:: increase the gain at code:: [pi/2, 0] :: to strong::+gain:: dB, while decreasing the gain at code:: [-pi/2, 0] :: to strong::-gain::. This simultaneously results in a distortion of the image towards code:: [pi/2, 0] ::. Negative values of gain invert this distortion, distorting towards code:: [-pi/2, 0] :: . The default, 0, results in no change. - - -note:: Corresponding matrix transformer: link::Classes/FoaXformerMatrix#*newDominateY:: :: - - -EXAMPLES:: - -Please see various examples link::Classes/FoaTransform#examples#here::. \ No newline at end of file diff --git a/source/ATK/sc/HelpSource/Classes/FoaDominateZ.schelp b/source/ATK/sc/HelpSource/Classes/FoaDominateZ.schelp deleted file mode 100644 index 4b27e23b00..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaDominateZ.schelp +++ /dev/null @@ -1,41 +0,0 @@ -CLASS:: FoaDominateZ -summary:: First Order Ambisonic (FOA) dominance transformer -categories:: Libraries>Ambisonic Toolkit>FOA>Transforming>UGens, UGens>Multichannel>Ambisonics, UGens>Multichannel>Panners -related:: Classes/FoaDominateX, Classes/FoaDominateY, Classes/FoaDominate, Classes/FoaTransform, Classes/FoaXform - -DESCRIPTION:: -Apply dominance to a first order ambisonic signal (B-format) along the z-axis. - - -NOTE:: -link::Classes/FoaDominateZ:: is usually called via the convenience wrapper link::Classes/FoaTransform::. -:: - - - -CLASSMETHODS:: - -METHOD:: ar - -argument:: in -The B-format signal, an array: [w, x, y, z] - -argument:: gain -Dominance gain, in dB. - -argument:: mul -Output will be multiplied by this value. - -argument:: add -This value will be added to the output. - - -discussion:: Positive values of strong::gain:: increase the gain at code:: [0, pi/2] :: to strong::+gain:: dB, while decreasing the gain at code:: [0, -pi/2] :: to strong::-gain::. This simultaneously results in a distortion of the image towards code:: [0, pi/2] ::. Negative values of gain invert this distortion, distorting towards code:: [0, -pi/2] :: . The default, 0, results in no change. - - -note:: Corresponding matrix transformer: link::Classes/FoaXformerMatrix#*newDominateZ:: :: - - -EXAMPLES:: - -Please see various examples link::Classes/FoaTransform#examples#here::. \ No newline at end of file diff --git a/source/ATK/sc/HelpSource/Classes/FoaEncode.schelp b/source/ATK/sc/HelpSource/Classes/FoaEncode.schelp deleted file mode 100644 index 9f6ecee611..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaEncode.schelp +++ /dev/null @@ -1,1020 +0,0 @@ -CLASS:: FoaEncode -summary:: First Order Ambisonic (FOA) encoder -categories:: Libraries>Ambisonic Toolkit>FOA>Encoding, UGens>Multichannel>Ambisonics -related:: Classes/FoaEncoderMatrix, Classes/FoaEncoderKernel - - -DESCRIPTION:: -Encodes signals in a variety of configurations to a first order ambisonic signal (B-format). link::Classes/PanB:: is a SuperCollider inbuilt equivalent. - - - - -CLASSMETHODS:: - -METHOD:: ar - -argument:: in -The input signal, an array: [in0, in1, ... inN] - -argument:: encoder -link::Classes/FoaEncoderMatrix:: or link::Classes/FoaEncoderKernel:: instance. - -argument:: mul -Output will be multiplied by this value. - -argument:: add -This value will be added to the output. - -returns:: - -A B-format signal as an array of channels: [w, x, y, z] - - - -EXAMPLES:: - -The examples below are intended to briefly illustrate some of the first order encoding options made available in the Ambisonic Toolkit. The user is encouraged to carefully review the features of link::Classes/FoaEncoderMatrix:: and link::Classes/FoaEncoderKernel:: to gain a deeper understanding of the flexibility of these tools. - -Available encoders include monophonic (as an omnidirectional soundfield, planewave or frequency spreading), stereophonic and varieties of pantophonic (2D surround) and periphonic (3D surround). Additionally, microphone array encoding is also supported. - -As the Ambisonic technique is a hierarchal system, numerous options for playback are possible. These include two channel stereo, two channel binaural, pantophonic and full 3D periphonic. With the examples below, we'll take advantage of this by first choosing a suitable decoder with with to audition. - -subsection:: Choose a decoder - -Choose a decoder suitable for your system, as illustrated link::Guides/Intro-to-the-ATK#Choose a decoder#here::. You'll end up definining code:: ~decoder :: and code:: ~renderDecode :: . - -note:: If you choose a kernel decoder, link::Classes/FoaDecoderKernel::, be sure to free the kernel after use. :: - - -subsection:: Omnidirectional encoder - - -Encoded as an omnidirectional soundfield, link::Classes/PinkNoise:: is used as the example sound source. In a well aligned, dampend studio environment, this usually sounds "in the head". link::Classes/FoaPush:: is used to "push" the omnidirectional soundfield so that it becomes a planewave (infinite distance, in an anechoic environment) arriving from some direction. - -The soundfield is controlled by link::Classes/MouseX:: and link::Classes/MouseY::, where link::Classes/MouseX:: specifies the incident azimuth angle (pi to -pi; left to right of display) and link::Classes/MouseY:: the link::Classes/FoaPush:: angle (0 to pi/2; bottom to top of display). With the mouse at the bottom of the display, the soundfield remains omnidirectional. Placed at the top of the display, the soundfield becomes directional, and varying left/right position will vary the incident azimuth of the resulting planewave. - -If you haven't already choosen a code:: ~decoder:: and defined code:: ~renderDecode ::, do so link::#Choose a decoder#now::. - -note:: A matrix type encoder, see link::Classes/FoaEncoderMatrix#*newOmni:: for further details.:: - -code:: -// ------------------------------------------------------------ -// omni encoder -// mono pink noise source - - -// define encoder matrix -~encoder = FoaEncoderMatrix.newOmni - -// inspect -~encoder.kind -~encoder.numChannels -~encoder.dirChannels - -( -{ - var sig; // audio signal - var angle, azim; // angle and azimuth control - - - // display encoder and decoder - "Ambisonic encoding via % encoder".format(~encoder.kind).postln; - "Ambisonic decoding via % decoder".format(~decoder.kind).postln; - - // angle ---> top = push to plane wave - // bottom = omni-directional - angle = MouseY.kr(pi/2, 0); - - // azimuth -> hard left = back - // centre = centre - // hard right = back - azim = MouseX.kr(pi, -pi); - - // ------------------------------------------------------------ - // test sig - sig = PinkNoise.ar; // mono pink noise - - - // ------------------------------------------------------------ - // encode - sig = FoaEncode.ar(sig, ~encoder); - - // ------------------------------------------------------------ - // transform - sig = FoaTransform.ar(sig, 'push', angle, azim); - - - - // ------------------------------------------------------------ - // decode (via ~renderDecode) - ~renderDecode.value(sig, ~decoder) - -}.scope; -) -// ------------------------------------------------------------ -:: - - - -subsection:: Frequency spreading encoder - - -Encoded as a frequency spread soundfield, link::Classes/PinkNoise:: is used as the example sound source. This sounds as spread across the soundfield, with the various frequency components appearing in various places. link::Classes/FoaPush:: is used to "push" the omnidirectional soundfield so that it becomes a planewave (infinite distance, in an anechoic environment) arriving from some direction. - -The soundfield is controlled by link::Classes/MouseX:: and link::Classes/MouseY::, where link::Classes/MouseX:: specifies the incident azimuth angle (pi to -pi; left to right of display) and link::Classes/MouseY:: the link::Classes/FoaPush:: angle (0 to pi/2; bottom to top of display). With the mouse at the bottom of the display, the soundfield remains spread. Placed at the top of the display, the soundfield becomes directional, and varying left/right position will vary the incident azimuth of the resulting planewave. - -If you haven't already choosen a code:: ~decoder:: and defined code:: ~renderDecode ::, do so link::#Choose a decoder#now::. - -note:: A kernel type encoder, see link::Classes/FoaEncoderKernel#*newSpread:: for further details.:: - -warning:: Kernel encoders require special care. Allow the kernel time to load before attempting to use. Additionally, the kernel buffer should be freed through the use of link::Classes/FoaEncoderKernel#-free:: after use.:: - -code:: -// ------------------------------------------------------------ -// frequency spreading encoder -// mono pink noise source - - -// define encoder kernel -~encoder = FoaEncoderKernel.newSpread - -// inspect -~encoder.kind -~encoder.numChannels -~encoder.dirChannels - -( -{ - var sig; // audio signal - var angle, azim; // angle and azimuth control - - - // display encoder and decoder - "Ambisonic encoding via % encoder".format(~encoder.kind).postln; - "Ambisonic decoding via % decoder".format(~decoder.kind).postln; - - // angle ---> top = push to plane wave - // bottom = omni-directional - angle = MouseY.kr(pi/2, 0); - - // azimuth -> hard left = back - // centre = centre - // hard right = back - azim = MouseX.kr(pi, -pi); - - // ------------------------------------------------------------ - // test sig - sig = PinkNoise.ar; // mono pink noise - - - // ------------------------------------------------------------ - // encode - sig = FoaEncode.ar(sig, ~encoder); - - // ------------------------------------------------------------ - // transform - sig = FoaTransform.ar(sig, 'push', angle, azim); - - - - // ------------------------------------------------------------ - // decode (via ~renderDecode) - ~renderDecode.value(sig, ~decoder) - -}.scope; -) -// ------------------------------------------------------------ - -// free kernel -~encoder.free -:: - - -subsection:: Frequency diffusion encoder - - -Encoded as a frequency diffused soundfield, link::Classes/PinkNoise:: is used as the example sound source. This sounds as diffused across the soundfield, with the various frequency components appearing in various places, with various phases. link::Classes/FoaPush:: is used to "push" the omnidirectional soundfield so that it becomes a planewave (infinite distance, in an anechoic environment) arriving from some direction. - -The soundfield is controlled by link::Classes/MouseX:: and link::Classes/MouseY::, where link::Classes/MouseX:: specifies the incident azimuth angle (pi to -pi; left to right of display) and link::Classes/MouseY:: the link::Classes/FoaPush:: angle (0 to pi/2; bottom to top of display). With the mouse at the bottom of the display, the soundfield remains spread. Placed at the top of the display, the soundfield becomes directional, and varying left/right position will vary the incident azimuth of the resulting planewave. - -If you haven't already choosen a code:: ~decoder:: and defined code:: ~renderDecode ::, do so link::#Choose a decoder#now::. - -note:: A kernel type encoder, see link::Classes/FoaEncoderKernel#*newDiffuse:: for further details.:: - -warning:: Kernel encoders require special care. Allow the kernel time to load before attempting to use. Additionally, the kernel buffer should be freed through the use of link::Classes/FoaEncoderKernel#-free:: after use.:: - -code:: -// ------------------------------------------------------------ -// frequency diffusion encoder -// mono pink noise source - - -// define encoder kernel -~encoder = FoaEncoderKernel.newDiffuse - -// inspect -~encoder.kind -~encoder.numChannels -~encoder.dirChannels - -( -{ - var sig; // audio signal - var angle, azim; // angle and azimuth control - - - // display encoder and decoder - "Ambisonic encoding via % encoder".format(~encoder.kind).postln; - "Ambisonic decoding via % decoder".format(~decoder.kind).postln; - - // angle ---> top = push to plane wave - // bottom = omni-directional - angle = MouseY.kr(pi/2, 0); - - // azimuth -> hard left = back - // centre = centre - // hard right = back - azim = MouseX.kr(pi, -pi); - - // ------------------------------------------------------------ - // test sig - sig = PinkNoise.ar; // mono pink noise - - - // ------------------------------------------------------------ - // encode - sig = FoaEncode.ar(sig, ~encoder); - - // ------------------------------------------------------------ - // transform - sig = FoaTransform.ar(sig, 'push', angle, azim); - - - - // ------------------------------------------------------------ - // decode (via ~renderDecode) - ~renderDecode.value(sig, ~decoder) - -}.scope; -) -// ------------------------------------------------------------ - -// free kernel -~encoder.free -:: - - -subsection:: A to B encoder - - -Here we encode four channels of decorrelated link::Classes/PinkNoise:: as a decorrelated soundfield, resulting in a maximally diffuse soundfield. link::Classes/FoaPush:: is used to "push" the soundfield so that it becomes a planewave (infinite distance, in an anechoic environment) arriving from some direction. This technique gives the opportunity to continuously modulate between a directional and a diffuse soundfield. - -The soundfield is controlled by link::Classes/MouseX:: and link::Classes/MouseY::, where link::Classes/MouseX:: specifies the incident azimuth angle (pi to -pi; left to right of display) and link::Classes/MouseY:: the link::Classes/FoaPush:: angle (0 to pi/2; bottom to top of display). With the mouse at the bottom of the display, the soundfield remains omnidirectional. Placed at the top of the display, the soundfield becomes directional, and varying left/right position will vary the incident azimuth of the resulting planewave. - -If you haven't already choosen a code:: ~decoder:: and defined code:: ~renderDecode ::, do so link::#Choose a decoder#now::. - -note:: A matrix type encoder, see link::Classes/FoaEncoderMatrix#*newAtoB:: for further details.:: - - -code:: -// ------------------------------------------------------------ -// A to B encoder -// decorrelated pink noise source - - -// define encoder matrix -~encoder = FoaEncoderMatrix.newAtoB - -// inspect -~encoder.kind -~encoder.numChannels -~encoder.dirChannels - -( -{ - var sig; // audio signal - var angle, azim; // angle and azimuth control - - - // display encoder and decoder - "Ambisonic encoding via % encoder".format(~encoder.kind).postln; - "Ambisonic decoding via % decoder".format(~decoder.kind).postln; - - // angle ---> top = push to plane wave - // bottom = omni-directional - angle = MouseY.kr(pi/2, 0); - - // azimuth -> hard left = back - // centre = centre - // hard right = back - azim = MouseX.kr(pi, -pi); - - // ------------------------------------------------------------ - // test sig - sig = -3.dbamp * PinkNoise.ar([1, 1, 1, 1]); // 4 channels decorrelated pink noise - - - // ------------------------------------------------------------ - // encode - sig = FoaEncode.ar(sig, ~encoder); - - // ------------------------------------------------------------ - // transform - sig = FoaTransform.ar(sig, 'push', angle, azim); - - - - // ------------------------------------------------------------ - // decode (via ~renderDecode) - ~renderDecode.value(sig, ~decoder) - -}.scope; -) -// ------------------------------------------------------------ -:: - -subsection:: A to B encoder (soundfile) - -This example is somewhat unconvential as regards the literature. Four microphones (omnis) are place around the performer in a tetrahedron. This is then matrixed into B-format. - -As the performer rotates and moves about, the image shifts through the sound-scene. In a compositional context, link::Classes/FoaPush:: could be used to control the soundfield. - -If you haven't already choosen a code:: ~decoder:: and defined code:: ~renderDecode ::, do so link::#Choose a decoder#now::. - -note:: A matrix type encoder, see link::Classes/FoaEncoderMatrix#*newAtoB:: for further details.:: - - -code:: -// ------------------------------------------------------------ -// A to B encoder -// A-format soundfile read from disk - -// define encoder matrix -~encoder = FoaEncoderMatrix.newAtoB('flrd') // for Thomas -~encoder = FoaEncoderMatrix.newAtoB('flr') // for Cross - - -// inspect -~encoder.kind -~encoder.numChannels -~encoder.dirChannels.raddeg - - -// read a whole sound into memory -// remember to free the buffer later! -// (boot the server, if you haven't!) -~sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/a-format/Thomas_Mackay.wav") -~sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/a-format/Cross_Tenor_Sax.wav") - - -( -{ - var sig; // audio signal - - - // display encoder and decoder - "Ambisonic encoding via % encoder".format(~encoder.kind).postln; - "Ambisonic decoding via % decoder".format(~decoder.kind).postln; - - // ------------------------------------------------------------ - // test sig - sig = PlayBuf.ar(~sndbuf.numChannels, ~sndbuf, BufRateScale.kr(~sndbuf), doneAction:2); // soundfile - - // ------------------------------------------------------------ - // encode - sig = FoaEncode.ar(sig, ~encoder); - - - // ------------------------------------------------------------ - // decode (via ~renderDecode) - ~renderDecode.value(sig, ~decoder) - -}.scope; -) - -// free buffer -~sndbuf.free -// ------------------------------------------------------------ -:: - -note:: strong::Soundfile Credits:: - -list:: -## Niall Thomas, "Rob Mackay: flute improvisations," [unpublished recording] -## David Cross, "Tenor saxophone improvisations," [unpublished recording] -:: - -:: - - -subsection:: Stereophonic encoder - -In this example we first encode a single channel of link::Classes/PinkNoise:: into a stereophonic signal with link::Classes/Pan2::. link::Classes/FoaZoom:: is then used to balance the soundfield across the x-axis (front/back). - -The soundfield is controlled by link::Classes/MouseX:: and link::Classes/MouseY::, where link::Classes/MouseX:: specifies the left to right position of the stereo panned source and link::Classes/MouseY:: the link::Classes/FoaZoom:: front to back position (distortion angle). Moving the mouse in a circular motion results in a circular motion of the sound. footnote:: We don't advise using this approach for encoding monophonic sources. The technique illustrated link::#omnidirectional_encoder#here:: is the idiomatic method. If one desires a similar use of the mouse, link::Classes/MouseX:: and link::Classes/MouseY:: can be mapped appropriately to link::Classes/FoaPush::'s strong::angle::, strong::theta::, and strong::phi:: parameters. :: - -If you haven't already choosen a code:: ~decoder:: and defined code:: ~renderDecode ::, do so link::#Choose a decoder#now::. - - -note:: A matrix type encoder, see link::Classes/FoaEncoderMatrix#*newStereo:: for further details.:: - - -code:: -// ------------------------------------------------------------ -// stereo encoder -// stereo panned mono pink noise source - - -// define encoder matrix -~encoder = FoaEncoderMatrix.newStereo - - -// inspect -~encoder.kind -~encoder.numChannels -~encoder.dirChannels.raddeg - -( -{ - var sig; // audio signal - var angle, azim; // angle and azimuth control - - - // display encoder and decoder - "Ambisonic encoding via % encoder".format(~encoder.kind).postln; - "Ambisonic decoding via % decoder".format(~decoder.kind).postln; - - // angle ---> top = zoom to plane wave at front - // bottom = zoom to plane wave at back - angle = MouseY.kr(pi/2, pi.neg/2); - - // azimuth -> hard left = back - // centre = centre - // hard right = back - azim = MouseX.kr(pi, -pi); - - // ------------------------------------------------------------ - // test sig - sig = PinkNoise.ar; // mono pink noise - - // ------------------------------------------------------------ - // pan (encode) to stereo - sig = Pan2.ar(sig, azim.neg/pi); - - // ------------------------------------------------------------ - // encode - sig = FoaEncode.ar(sig, ~encoder); - - // ------------------------------------------------------------ - // transform - sig = FoaTransform.ar(sig, 'zoom', angle); - - - // ------------------------------------------------------------ - // decode (via ~renderDecode) - ~renderDecode.value(sig, ~decoder) - -}.scope; -) - -// free kernel -~encoder.free - -// ------------------------------------------------------------ -:: - -subsection:: Stereophonic encoder (soundfile) - -For this example we'll look at encoding stereo soundfiles. - -The stereo encoder places the left channel at +pi/4 and the right at -pi/4. Compare to the link::Classes/FoaEncoderKernel#*newSuper#Super Stereo:: encoder link::#super_stereo_encoder_(soundfile)#below::. - -If you haven't already choosen a code:: ~decoder:: and defined code:: ~renderDecode ::, do so link::#Choose a decoder#now::. - - -note:: A matrix type encoder, see link::Classes/FoaEncoderMatrix#*newStereo:: for further details.:: - - -code:: -// ------------------------------------------------------------ -// stereo encoder -// stereo soundfile read from disk - - -// define encoder matrix -~encoder = FoaEncoderMatrix.newStereo(pi/4) - - -// inspect -~encoder.kind -~encoder.numChannels -~encoder.dirChannels.raddeg - - -// read a whole sound into memory -// remember to free the buffer later! -// (boot the server, if you haven't!) -~sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/stereo/The_City_Waites-The_Downfall.wav") -~sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/stereo/The_City_Waites-An_Old.wav") -~sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/stereo/Aurora_Surgit-Lux_Aeterna.wav") -~sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/stereo/Aurora_Surgit-Dies_Irae.wav") - - -( -{ - var sig; // audio signal - - - // display encoder and decoder - "Ambisonic encoding via % encoder".format(~encoder.kind).postln; - "Ambisonic decoding via % decoder".format(~decoder.kind).postln; - - // ------------------------------------------------------------ - // test sig - sig = PlayBuf.ar(~sndbuf.numChannels, ~sndbuf, BufRateScale.kr(~sndbuf), doneAction:2); // soundfile - - // ------------------------------------------------------------ - // encode - sig = FoaEncode.ar(sig, ~encoder); - - - // ------------------------------------------------------------ - // decode (via ~renderDecode) - ~renderDecode.value(sig, ~decoder) - -}.scope; -) - -// free buffer -~sndbuf.free -// ------------------------------------------------------------ -:: - -note:: strong::Soundfile Credits:: - -list:: -## The City Waites, "The Downfall of Dancing," Penny Merriments, NAXOS 8.557672 -## The City Waites, "An Old Song on the Spanish Armada," Penny Merriments, NAXOS 8.557672 -## Aurora Surgit, "Lux aeterna," Ego sum Resurrectio, NAXOS 8.557672 -## Aurora Surgit, "Dies irae," Ego sum Resurrectio, NAXOS 8.557672 -:: - -:: - - -subsection:: Super Stereo encoder (soundfile) - -Super Stereo footnote:: See: http://en.wikipedia.org/wiki/Ambisonics#Super_stereo :: is the classic Ambisonic method to encode stereophonic files, and is considered to be optimal for frontal stereo encoding. - -If you haven't already choosen a code:: ~decoder:: and defined code:: ~renderDecode ::, do so link::#Choose a decoder#now::. - -note:: A kernel type encoder, see link::Classes/FoaEncoderKernel#*newSuper:: for further details.:: - -warning:: Kernel encoders require special care. Allow the kernel time to load before attempting to use. Additionally, the kernel buffer should be freed through the use of link::Classes/FoaEncoderKernel#-free:: after use.:: - - -code:: -// ------------------------------------------------------------ -// super stereo encoder -// stereo soundfile read from disk - - -// define encoder matrix -~encoder = FoaEncoderKernel.newSuper - - -// inspect -~encoder.kind -~encoder.numChannels -~encoder.dirChannels.raddeg - - -// read a whole sound into memory -// remember to free the buffer later! -// (boot the server, if you haven't!) -~sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/stereo/The_City_Waites-The_Downfall.wav") -~sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/stereo/The_City_Waites-An_Old.wav") -~sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/stereo/Aurora_Surgit-Lux_Aeterna.wav") -~sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/stereo/Aurora_Surgit-Dies_Irae.wav") - - -( -{ - var sig; // audio signal - - - // display encoder and decoder - "Ambisonic encoding via % encoder".format(~encoder.kind).postln; - "Ambisonic decoding via % decoder".format(~decoder.kind).postln; - - // ------------------------------------------------------------ - // test sig - sig = PlayBuf.ar(~sndbuf.numChannels, ~sndbuf, BufRateScale.kr(~sndbuf), doneAction:2); // soundfile - - // ------------------------------------------------------------ - // encode - sig = FoaEncode.ar(sig, ~encoder); - - - // ------------------------------------------------------------ - // decode (via ~renderDecode) - ~renderDecode.value(sig, ~decoder) - -}.scope; -) - -// free kernel & buffer -~encoder.free -~sndbuf.free -// ------------------------------------------------------------ -:: - - -note:: strong::Soundfile Credits:: - -list:: -## The City Waites, "The Downfall of Dancing," Penny Merriments, NAXOS 8.557672 -## The City Waites, "An Old Song on the Spanish Armada," Penny Merriments, NAXOS 8.557672 -## Aurora Surgit, "Lux aeterna," Ego sum Resurrectio, NAXOS 8.557672 -## Aurora Surgit, "Dies irae," Ego sum Resurrectio, NAXOS 8.557672 -:: - -:: - - -subsection:: Ambisonic UHJ stereo encoder (soundfile) - -link::http://en.wikipedia.org/wiki/Ambisonic_UHJ_format##Ambisonic UHJ:: is the stereo format for Ambisonics. - -If you haven't already choosen a code:: ~decoder:: and defined code:: ~renderDecode ::, do so link::#Choose a decoder#now::. - -note:: A kernel type encoder, see link::Classes/FoaEncoderKernel#*newUHJ:: for further details.:: - -warning:: Kernel encoders require special care. Allow the kernel time to load before attempting to use. Additionally, the kernel buffer should be freed through the use of link::Classes/FoaEncoderKernel#-free:: after use.:: - - -code:: -// ------------------------------------------------------------ -// ambisonic uhj stereo encoder -// stereo soundfile read from disk - - -// define encoder matrix -~encoder = FoaEncoderKernel.newUHJ - - -// inspect -~encoder.kind -~encoder.numChannels -~encoder.dirChannels.raddeg - - -// read a whole sound into memory -// remember to free the buffer later! -// (boot the server, if you haven't!) -~sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/uhj/Palestrina-O_Bone.wav") -~sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/uhj/Gabrieli-Canzon_Duodecimi.wav") -~sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/uhj/Cante_Flamenco-Alegrias.wav") -~sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/uhj/Waldteufel-The_Skaters.wav") - - -( -{ - var sig; // audio signal - - - // display encoder and decoder - "Ambisonic encoding via % encoder".format(~encoder.kind).postln; - "Ambisonic decoding via % decoder".format(~decoder.kind).postln; - - // ------------------------------------------------------------ - // test sig - sig = PlayBuf.ar(~sndbuf.numChannels, ~sndbuf, BufRateScale.kr(~sndbuf), doneAction:2); // soundfile - - // ------------------------------------------------------------ - // encode - sig = FoaEncode.ar(sig, ~encoder); - - - // ------------------------------------------------------------ - // decode (via ~renderDecode) - ~renderDecode.value(sig, ~decoder) - -}.scope; -) - -// free kernel & buffer -~encoder.free -~sndbuf.free -// ------------------------------------------------------------ -:: - - -note:: strong::Soundfile Credits:: - -list:: -## Christ Church Cathedral Choir, "Palestrina: O Bone Jesu, exaudi me," Ambisonic Sampler, NI 1417 -## The Wallace Collection, "Gabrieli: Canzon Duodecimi Toni a 10 (No 2)," Ambisonic Sampler, NI 1417 -## C. Lobato, J. del Gastor, & P. del Gastor, "Alegrias," Ambisonic Sampler, NI 1417 -## The Gulbenkian Orchestra, "Waldteufel: The Skaters' Waltz," Ambisonic Sampler, NI 1417 -:: - -:: - - -subsection:: ZoomH2 encoder (soundfile) - -The link::http://www.zoom.co.jp/english/products/h2/##ZoomH2:: is a convenient, portable handheld recorder. The device only records horizontal surround (pantophonic), so we don't get height. - -As a relatively inexpensive piece of equipment, the imaging of the link::http://www.zoom.co.jp/english/products/h2/##ZoomH2:: isn't always as consistent as we'd prefer. To remedy, the Y gain is tweaked to widen the image, and link::Classes/FoaXformerMatrix#*newDominateX#dominance:: is applied to stabilise the front. - -If you haven't already choosen a code:: ~decoder:: and defined code:: ~renderDecode ::, do so link::#Choose a decoder#now::. - -note:: A matrix type encoder, see link::Classes/FoaEncoderMatrix#*newZoomH2:: and link::Classes/FoaXformerMatrix#*newDominateX:: for further details.:: - - -code:: -// ------------------------------------------------------------ -// zoomH2 encoder -// zoomH2 soundfile read from disk - - -// define encoder and xform matricies -~encoder = FoaEncoderMatrix.newZoomH2(k: 1.7378) -~xformer = FoaXformerMatrix.newDominateX(3.0) - -// inspect -~encoder.kind -~encoder.numChannels -~encoder.dirChannels.raddeg - - -// read a whole sound into memory -// remember to free the buffer later! -// (boot the server, if you haven't!) -~sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/zoomh2/Anderson-Waltz.wav") -~sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/zoomh2/Anderson-Steam.wav") -~sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/zoomh2/Anderson-Stape_Silver.wav") -~sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/zoomh2/Anderson-St_Peter_&_St_Paul.wav") - - -( -{ - var sig; // audio signal - - - // display encoder and decoder - "Ambisonic encoding via % encoder".format(~encoder.kind).postln; - "Ambisonic decoding via % decoder".format(~decoder.kind).postln; - - // ------------------------------------------------------------ - // test sig - sig = PlayBuf.ar(~sndbuf.numChannels, ~sndbuf, BufRateScale.kr(~sndbuf), doneAction:2); // soundfile - - // ------------------------------------------------------------ - // encode - sig = FoaEncode.ar(sig, ~encoder); - - - // ------------------------------------------------------------ - // xform - sig = FoaXform.ar(sig, ~xformer); - - - // ------------------------------------------------------------ - // decode (via ~renderDecode) - ~renderDecode.value(sig, ~decoder) - -}.scope; -) - -// free buffer -~sndbuf.free -// ------------------------------------------------------------ -:: - -note:: strong::Soundfile Credits:: - -list:: -## Joseph Anderson, "Pickering Steam Fair: Waltz," [unpublished recording] -## Joseph Anderson, "Pickering Steam Fair: Engine," [unpublished recording] -## Joseph Anderson, "Stape Silver Band: March," [unpublished recording] -## Joseph Anderson, "St Peter & St Paul," [unpublished recording] -:: - -:: - - - -subsection:: ZoomH2 encoder, reversed (soundfile) - -As described link::Classes/FoaEncoderMatrix#*newZoomH2#here::, the link::http://www.zoom.co.jp/english/products/h2/##ZoomH2:: encoder reverses the labels for front and back of the link::http://www.zoom.co.jp/english/products/h2/##ZoomH2::. This is done to favour the use of the decoder as a roving, hand-held device, with the display facing the operator. - -If one wishes to respect the labelled orientation of the device as does link::http://www.radio.uqam.ca/ambisonic/comparative_recording.html##Courville:: in the example below, we'll need to either adjust the strong::angles:: argument or apply link::Classes/FoaXform#*newMirrorX::. For this example, we'll set strong::angles:: = code:: [3/4*pi, pi/3] ::, which are those specified in the link::http://www.zoom.co.jp/downloads/h2/manual/##ZoomH2 documentation::. - -As a relatively inexpensive piece of equipment, the imaging of the link::http://www.zoom.co.jp/english/products/h2/##ZoomH2:: isn't always as consistent as we'd prefer. To remedy, the Y gain is tweaked to widen the image. - -If you haven't already choosen a code:: ~decoder:: and defined code:: ~renderDecode ::, do so link::#Choose a decoder#now::. - -note:: A matrix type encoder, see link::Classes/FoaEncoderMatrix#*newZoomH2:: for further details.:: - - -code:: -// ------------------------------------------------------------ -// zoomH2 encoder -// zoomH2 soundfile read from disk - - -// define encoder matrix -~encoder = FoaEncoderMatrix.newZoomH2([3/4*pi, pi/3], 1.7378) - -// inspect -~encoder.kind -~encoder.numChannels -~encoder.dirChannels.raddeg - - -// read a whole sound into memory -// remember to free the buffer later! -// (boot the server, if you haven't!) -~sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/zoomh2/Courville-Dialogue.wav") - - -( -{ - var sig; // audio signal - - - // display encoder and decoder - "Ambisonic encoding via % encoder".format(~encoder.kind).postln; - "Ambisonic decoding via % decoder".format(~decoder.kind).postln; - - // ------------------------------------------------------------ - // test sig - sig = PlayBuf.ar(~sndbuf.numChannels, ~sndbuf, BufRateScale.kr(~sndbuf), doneAction:2); // soundfile - - // ------------------------------------------------------------ - // encode - sig = FoaEncode.ar(sig, ~encoder); - - - // ------------------------------------------------------------ - // decode (via ~renderDecode) - ~renderDecode.value(sig, ~decoder) - -}.scope; -) - -// free buffer -~sndbuf.free -// ------------------------------------------------------------ -:: - -note:: strong::Soundfile Credits:: - -list:: -## D. Courville, "Comparative Surround Recording," Ambisonic Studio | Comparative Surround Recording, 2007. [Online]. Available: http://www.radio.uqam.ca/ambisonic/comparative_recording.html [Accessed: 26-Jul-2011]. -:: - -:: - - - -subsection:: Pantophonic encoder (soundfile) - -The pantophonic encoder may be used to transcode from one format to another. This example transcodes an octophonic recording to the decoder you've chosen. - -If you haven't already choosen a code:: ~decoder:: and defined code:: ~renderDecode ::, do so link::#Choose a decoder#now::. - -note:: A matrix type encoder, see link::Classes/FoaEncoderMatrix#*newPanto:: for further details.:: - - -code:: -// ------------------------------------------------------------ -// pantophonic (8-channel) encoder -// pantophonic (8-channel) soundfile read from disk - - -// define encoder matrix -~encoder = FoaEncoderMatrix.newPanto(8, 'flat') // choose for Mackay -~encoder = FoaEncoderMatrix.newPanto(8, 'point') // choose for Young - - -// inspect -~encoder.kind -~encoder.numChannels -~encoder.dirChannels.raddeg - - -// read a whole sound into memory -// remember to free the buffer later! -// (boot the server, if you haven't!) -~sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/multichannel/Mackay-Augustines_Message.wav") -~sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/multichannel/Young-Allting_Runt.wav") - - -( -{ - var sig; // audio signal - - - // display encoder and decoder - "Ambisonic encoding via % encoder".format(~encoder.kind).postln; - "Ambisonic decoding via % decoder".format(~decoder.kind).postln; - - // ------------------------------------------------------------ - // test sig - sig = PlayBuf.ar(~sndbuf.numChannels, ~sndbuf, BufRateScale.kr(~sndbuf), doneAction:2); // soundfile - - // ------------------------------------------------------------ - // encode - sig = FoaEncode.ar(sig, ~encoder); - - - // ------------------------------------------------------------ - // decode (via ~renderDecode) - ~renderDecode.value(sig, ~decoder) - -}.scope; -) - -// free buffer -~sndbuf.free -// ------------------------------------------------------------ -:: - -note:: -strong::Soundfile Credits:: -list:: -## Robert Mackay, "Augustine's Message," [unpublished recording] -## John Young, "Allting Runt Omkring," [unpublished recording] -:: -:: - -subsection:: Directions encoder (soundfile) - -The directions encoder may be used to transcode from one format to another. This example transcodes a periphonic 12-channel recording to the decoder you've chosen. - -If you haven't already choosen a code:: ~decoder:: and defined code:: ~renderDecode ::, do so link::#Choose a decoder#now::. - -note:: A matrix type encoder, see link::Classes/FoaEncoderMatrix#*newPanto:: for further details.:: - - -code:: -// ------------------------------------------------------------ -// periphonic (12-channel) encoder - - -// define encoder matrix -~directions = [ [ 22.5, 0 ], [ -22.5, 0 ], [ 67.5, 0 ], [ -67.5, 0 ], [ 112.5, 0 ], [ -112.5, 0 ], [ 157.5, 0 ], [ -157.5, 0 ], [ 45, 45 ], [ -45, 45 ], [ -135, 45 ], [ 135, 45 ] ].degrad -~encoder = FoaEncoderMatrix.newDirections(~directions) - - -// inspect -~encoder.kind -~encoder.numChannels -~encoder.dirChannels.raddeg - - -// read a whole sound into memory -// remember to free the buffer later! -// (boot the server, if you haven't!) -~sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/multichannel/Wilson-Bose.wav") - - -( -{ - var sig; // audio signal - - - // display encoder and decoder - "Ambisonic encoding via % encoder".format(~encoder.kind).postln; - "Ambisonic decoding via % decoder".format(~decoder.kind).postln; - - // ------------------------------------------------------------ - // test sig - sig = PlayBuf.ar(~sndbuf.numChannels, ~sndbuf, BufRateScale.kr(~sndbuf) doneAction:2); // soundfile - - // ------------------------------------------------------------ - // encode - sig = FoaEncode.ar(sig, ~encoder); - - - // ------------------------------------------------------------ - // decode (via ~renderDecode) - ~renderDecode.value(sig, ~decoder) - -}.scope; -) - -// free buffer -~sndbuf.free -// ------------------------------------------------------------ -:: - -note:: strong::Soundfile Credits:: -list:: -## Scott Wilson, "Böse," [unpublished recording] -:: -:: diff --git a/source/ATK/sc/HelpSource/Classes/FoaEncoderKernel.schelp b/source/ATK/sc/HelpSource/Classes/FoaEncoderKernel.schelp deleted file mode 100644 index 63037a7235..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaEncoderKernel.schelp +++ /dev/null @@ -1,307 +0,0 @@ -CLASS:: FoaEncoderKernel -summary:: First Order Ambisonic (FOA) encoder kernels -categories:: Libraries>Ambisonic Toolkit>FOA>Encoding -related:: Classes/FoaEncoderMatrix, Classes/FoaEncode - -DESCRIPTION:: -Generates encoding kernels required by the Ambisonic Toolkit's first order encoder, link::Classes/FoaEncode::. - -note:: The ATK kernels are required for kernel encoding. Please see the instructions link::http://www.ambisonictoolkit.net/download/kernels/#ATK_Kernels#here:: for installation. :: - - -CLASSMETHODS:: - -METHOD:: newSuper -Ambisonic Super Stereo encoder. footnote::See: link::https://en.wikipedia.org/wiki/Ambisonic_UHJ_format#Super_stereo:::: - -argument:: kernelSize -256, 512, 1024, 2048, 4096, 8192 - -argument:: server -link::Classes/Server:: on which to load kernel. - -argument:: sampleRate -The sample rate defaults to code::nil:: and is usually supplied by the running server. In NRT, you can specify a sampleRate to avoid booting a server. - -argument:: score -Default is code::nil:: for most real time usages. When using NRT, you can supply a score (a link::Classes/Score:: or a link::Classes/CtkScore::) onto which the kernels will be added, which lets you bypass booting a server. - -discussion:: The Super Stereo encoding technique is the classic method for encoding stereophonic signals into B-format. - - -METHOD:: newUHJ -Ambisonic UHJ stereo encoder. footnote::See: link::http://en.wikipedia.org/wiki/Ambisonic_UHJ_format:::: - -argument:: kernelSize -256, 512, 1024, 2048, 4096, 8192 - -argument:: server -link::Classes/Server:: on which to load kernel. - -argument:: sampleRate -The sample rate defaults to code::nil:: and is usually supplied by the running server. In NRT, you can specify a sampleRate to avoid booting a server. - -argument:: score -Default is code::nil:: for most real time usages. When using NRT, you can supply a score (a link::Classes/Score:: or a link::Classes/CtkScore::) onto which the kernels will be added, which lets you bypass booting a server. - -discussion:: The UHJ encoder offers access to numerous published recordings footnote:: Nimbus Records' primary output is in Ambisonic UHJ. See: http://en.wikipedia.org/wiki/Nimbus_Records And: http://www.wyastone.co.uk/index.php :: for periphonic (2D) audition. - -note:: For optimal performance, use a dual-band decoder ( code::'dual':: ) for monitoring. See discussion link::Classes/FoaDecoderMatrix#decoder_k#here::. :: - - -METHOD:: newSpread -Frequency spreading mono encoder. - -argument:: subjectID -0 to 12. Specifies the number of bands per octave of the frequency spreader. 0 returns 1 band per octave, etc. - -argument:: kernelSize -512, 1024, 2048, 4096, 8192, 16384 - -argument:: server -link::Classes/Server:: on which to load kernel. - -argument:: sampleRate -The sample rate defaults to code::nil:: and is usually supplied by the running server. In NRT, you can specify a sampleRate to avoid booting a server. - -argument:: score -Default is code::nil:: for most real time usages. When using NRT, you can supply a score (a link::Classes/Score:: or a link::Classes/CtkScore::) onto which the kernels will be added, which lets you bypass booting a server. - -discussion:: The frequency spreading technique encodes a monophonic signal into B-format by smoothly rotating the signal across the soundfield sphere, by frequency. - -note:: As the number of bands per octaves increases, more time domain artefacts are introduced. This is usually heard as smearing in time.:: - - -METHOD:: newDiffuse -Frequency diffusion mono encoder. - -argument:: subjectID -0 to 5. Specifies the amount of phase dispersion of the frequency diffuser. 0 is low, 5 is high. - -argument:: kernelSize -512, 1024, 2048, 4096, 8192, 16384 - -argument:: server -link::Classes/Server:: on which to load kernel. - -argument:: sampleRate -The sample rate defaults to code::nil:: and is usually supplied by the running server. In NRT, you can specify a sampleRate to avoid booting a server. - -argument:: score -Default is code::nil:: for most real time usages. When using NRT, you can supply a score (a link::Classes/Score:: or a link::Classes/CtkScore::) onto which the kernels will be added, which lets you bypass booting a server. - -discussion:: The frequency diffusion technique encodes a monophonic signal into B-format by randomising the phase of the signal across the soundfield sphere, by frequency. - -note:: As the diffusion increases, more time domain artefacts are introduced. This is usually heard as smearing in time.:: - - -INSTANCEMETHODS:: -private:: initPath, initKernel, printOn - - -METHOD:: set - -Describes both the emphasis::signal set:: and the emphasis::tool set::, encompassing the Ambisonic order, as well as channel ordering and normalisation. - -Answers code::'FOA'::, aka traditional B-format: - -table:: -## strong::Ambisonic Order:: || strong::Channel Ordering:: || strong::Channel Normalisation:: -## 1st || Gerzon (aka Furse-Malham) || MaxN -:: - -METHOD:: type -returns:: code::'encoder':: - -METHOD:: op -Answers code::'kernel'::, i.e. the type of operation used to compute the resulting signals. - -METHOD:: kind -Answers the kind of encoder - -discussion:: - -code:: -// encoder - make sure you boot the server first!! -~encoder = FoaEncoderKernel.newUHJ - -// inspect -~encoder.kind - -// don't forget to free!! -~encoder.free -:: - - -METHOD:: subjectID -Answers the strong::subjectID:: of the decoder - -discussion:: - -code:: -// encoder - make sure you boot the server first!! -~encoder = FoaEncoderKernel.newUHJ - -// inspect -~encoder.subjectID - -// don't forget to free!! -~encoder.free -:: - - - -METHOD:: dim -Answers the number of decoder dimensions: 2D or 3D. - -discussion:: - -code:: -// encoder - make sure you boot the server first!! -~encoder = FoaEncoderKernel.newUHJ - -// inspect -~encoder.dim - -// don't forget to free!! -~encoder.free -:: - - - -METHOD:: numChannels -Answers the number of input channels. - -discussion:: - -code:: -// encoder - make sure you boot the server first!! -~encoder = FoaEncoderKernel.newUHJ - -// inspect -~encoder.numChannels - -// don't forget to free!! -~encoder.free -:: - - - - -METHOD:: dirChannels -Answers the direction of input channels, with angles in radians. - -discussion:: - -code:: -// encoder - make sure you boot the server first!! -~encoder = FoaEncoderKernel.newSuper - -// inspect -~encoder.dirChannels.raddeg - -// don't forget to free!! -~encoder.free -:: - -code:: -// encoder - make sure you boot the server first!! -~encoder = FoaEncoderKernel.newUHJ - -// inspect -~encoder.dirChannels.raddeg - -// don't forget to free!! -~encoder.free -:: - - -METHOD:: kernel -Answers the encoder kernel. - -discussion:: - -code:: -// encoder - make sure you boot the server first!! -~encoder = FoaEncoderKernel.newUHJ - -// inspect -~encoder.kernel - -// don't forget to free!! -~encoder.free -:: - - - - -METHOD:: kernelSize -Answers the strong::kernelSize::. - - -discussion:: - -Use of link::Classes/FoaEncoderKernel:: introduces a delay to the encoded -B-format signal. - -The total delay, in samples, can be calculated as -code::(kernelSize-1)/2 + kernelSize - blockSize::, where -link::Classes/ServerOptions#-blockSize#blockSize:: is the number of -samples in one control period of the link::Classes/Server:: in use. - -code:: -// encoder - make sure you boot the server first!! -~encoder = FoaEncoderKernel.newUHJ - -// inspect -~encoder.kernelSize - -// calculate delay in samples -(~encoder.kernelSize-1)/2 + ~encoder.kernelSize - s.options.blockSize - -// calculate delay in seconds -((~encoder.kernelSize-1)/2 + ~encoder.kernelSize - s.options.blockSize) / s.sampleRate - -// don't forget to free!! -~encoder.free -:: - - -METHOD:: free -Free the kernel. - -discussion:: Release the kernel buffer's memory on the server and return the bufferID back to the server's buffer number allocator for future reuse. - -warning:: Only free the kernel when the link::Classes/FoaEncode#*ar:: is no longer in use!:: - - - -METHOD:: numInputs -A synonym for link::#-numChannels:: - - -METHOD:: dirInputs -A synonym for link::#-dirChannels:: - - -METHOD:: numOutputs -Answers the number of outputs for the decoder. 3 for 2D and 4 for 3D. - - -METHOD:: dirOutputs -A convenience method providing polymorphism with link::Classes/FoaDecoderKernel#-dirOutputs::. - -returns:: - -list:: -## for 2D: code:: [ inf, inf, inf ] :: -## for 3D: code:: [ inf, inf, inf , inf ] :: -:: - - -PRIVATE:: buffers, kernelBundle, kernelInfo - - -EXAMPLES:: - -Please see link::Classes/FoaEncode#Examples::. diff --git a/source/ATK/sc/HelpSource/Classes/FoaEncoderMatrix.schelp b/source/ATK/sc/HelpSource/Classes/FoaEncoderMatrix.schelp deleted file mode 100644 index 34eade3fc9..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaEncoderMatrix.schelp +++ /dev/null @@ -1,486 +0,0 @@ -CLASS:: FoaEncoderMatrix -summary:: First Order Ambisonic (FOA) encoder matrices -categories:: Libraries>Ambisonic Toolkit>FOA>Encoding -related:: Classes/FoaEncoderKernel, Classes/FoaEncode - -DESCRIPTION:: -Generates encoding matrices required by the Ambisonic Toolkit's first order encoder, link::Classes/FoaEncode::. - - - -CLASSMETHODS:: - -METHOD:: newOmni -Omnidirectional encoder (monophonic). - -discussion:: An omnidirectional soundfield can be regarded in two ways: a soundfield with an infinite number of planewaves arriving in all directions, or a soundfield with no directions. In a well aligned, dampend studio environment, this usually sounds "in the head", while in concert hall listening usually appears as omnipresent. - -To control the soundfield, link::Classes/FoaPush:: and link::Classes/FoaFocus:: can be applied to either "push" or "focus" an omnidirectional soundfield into a planewave, giving the soundfield an angle of arrival. footnote:: In combination with distance scaling, link::#*newOmni:: and link::Classes/FoaPush:: can be used to implement Menzies' "W-panning" technique. See: D. Menzies, "W-panning and O-format, tools for object spatialization," in Proceedings of the Audio Engineering Society 22nd International Conference on Virtual, Synthetic and Entertainment Audio, Espoo, Finland, 2002.:: - - - -METHOD:: newDirection -Planewave encoder (monophonic). - -argument:: theta -Azimuth angle, in radians: pi to -pi - -argument:: phi -Elevation anglein radians: pi/2 to -pi/2 - -discussion:: This is the classic Ambisonic encoding (panning) function. SuperCollider's inbuilt link::Classes/PanB:: and the Ambisonic Toolkit's link::Classes/FoaPanB:: implement this encoder as a UGen, and allow dynamically changing strong::theta:: and strong::phi::. - - - -METHOD:: newStereo -Stereophonic encoder. - -argument:: angle -Soundfield distortion angle, in radians: pi/2 to -pi/2 - -discussion:: The stereophonic signal is encoded as two planewaves. When strong::angle:: = 0, the left and right channels of the input signal arrive at code:: [90, -90] :: degrees. strong::angle:: = pi/4 distorts the arrivals to code:: [45, -45] :: degrees. strong::angle:: = pi/2, places both the left and right inputs at front centre, code:: [0, 0] :: degrees. This behaviour matches that of the Ambisonic Toolkit's first order image warping UGens: link::Classes/FoaFocus::, link::Classes/FoaZoom::, link::Classes/FoaPush::, and link::Classes/FoaPress::. -note::The authors also suggest reviewing the Super Stereo footnote::See link::https://en.wikipedia.org/wiki/Ambisonic_UHJ_format#Super_stereo:: for further information.:: encoding technique, the classic method for encoding stereophonic signals into B-format: link::Classes/FoaEncoderKernel#*newSuper:: :: - -METHOD:: newQuad -Quadraphonic encoder. - -discussion:: The quadraphonic signal is encoded as four planewaves arriving at code:: [ 45, 135, -135, -45 ] :: degrees. This encoding is equivalent to placing infinitely distant loudspeakers around a soundfield microphone in an anechoic chamber. - - - -METHOD:: new5_0 -5.0 encoder. - -discussion:: The 5.0 signal is encoded as five planewaves arriving at code:: [ 0, 30, 110, -110, -30 ] :: degrees. This encoding is equivalent to placing infinitely distant loudspeakers around a soundfield microphone in an anechoic chamber. - - - -METHOD:: new7_0 -7.0 encoder. - -discussion:: The 7.0 signal is encoded as seven planewaves arriving at code:: [ 0, 30, 90, 135, -135, -90, -30 ] :: degrees. This encoding is equivalent to placing infinitely distant loudspeakers around a soundfield microphone in an anechoic chamber. - - - -METHOD:: newPanto -Pantophonic (2D) regular polygon encoder. - -argument:: numChans -number of input channel feeds - -argument:: orientation -code::'flat':: or code::'point':: - -discussion:: Inputs are in anti-clockwise order. The position of the first input channel is either centre or left of centre. link::#-dirChannels:: may be used to query resulting input channel directions. This encoding is equivalent to placing infinitely distant loudspeakers around a soundfield microphone in an anechoic chamber. - - - -METHOD:: newPeri -Periphonic (3D) dual ring, regular cylindrical encoder. - -argument:: numChanPairs -Number of channel pairs. (Half the total number of input channel feeds.) - -argument:: elevation -Elevation of the upper ring, measured from the origin. In radians. - -argument:: orientation -code::'flat':: or code::'point':: - - -discussion:: Inputs are in anti-clockwise order, beginning with the top ring. The position of the first speaker is either centre or left of centre. link::#-dirChannels:: may be used to query resulting loudspeaker directions. This encoding is equivalent to placing infinitely distant loudspeakers around a soundfield microphone in an anechoic chamber. - - - -METHOD:: newDirections -Virtual loudspeaker or microphone encoder, suitable for varied periphonic and pantophonic arrays. - -argument:: directions -An array of directions of the virtual loudspeakers or microphones. Specify in radians. - -Rank 1 arrays return pantophonic, while rank 2 arrays return periphonic. E.g., -code:: -// 2D: -~directions = [ theta0, theta1, ... thetaN ]; -:: -code:: -// 3D: -~directions = [ [ theta0, phi0 ], [ theta1, phi1 ], ... [ thetaN, phiN ] ]; -:: - -argument:: pattern -Virtual microphone pattern, code::nil::, or 0 to 1. - -definitionList:: -## code::nil:: || strong::directions:: specifies virtual loudspeaker positions -## 0 to 1 || strong::directions:: specifies a microphone array with patterns: - table:: - ## strong::pattern:: || strong::microphone:: - ## 0.0 || Omni - ## 0.5 || Cardioid - ## (3-sqrt(3))/2 || Super-cardioid - ## 0.75 || Hyper-cardioid - ## 1.0 || Bi-directional - :: - If strong::pattern:: is an link::Classes/Array::, individual microphone patterns are specified. - - For equivalences to decoder strong::k::, please see link::Classes/FoaDecoderMatrix#decoder k::. -:: - - -discussion:: link::#-newDirections:: is the Ambisonic Toolkit's most versatile first order encoder. Arbitrary input loudspeaker and/or microphone arrays may be specified. - -code:: -// Periphonic (3D) encoder, a 1/2 dome of 13 loudspeakers -// [[0, 0], [45, 0], [90, 0], [135, 0], [-180, 0], [-135, 0], [-90, 0], [-45, 0], -// [45, 35.3], [135, 35.3], [-135, 35.3], [-45, 35.3], [0, 90]] - -~directions = [[0, 0], [45, 0], [90, 0], [135, 0], [-180, 0], [-135, 0], [-90, 0], - [-45, 0], [45, 35.3], [135, 35.3], [-135, 35.3], [-45, 35.3], [0, 90]].degrad; -~encoder = FoaEncoderMatrix.newDirections(~directions); - -// inspect -~encoder.dirChannels.raddeg; -:: - -code:: -// Periphonic (2D) encoder, 3 cardioid microphones -// See: http://www.michaelgerzonphotos.org.uk/microphones-calrecs.html -// [60, -180, -60] - -~directions = [60, -180, -60].degrad; -~pattern = 0.5; -~encoder = FoaEncoderMatrix.newDirections(~directions, ~pattern); - -// inspect -~encoder.dirChannels.raddeg; -:: - -code:: -// Periphonic (2D) encoder, 1 omni and 2 cardioid microphones -// [0, 45, -45] - -~directions = [0, 45, -45].degrad; -~pattern = [0, 0.5, 0.5]; -~encoder = FoaEncoderMatrix.newDirections(~directions, ~pattern); - -// inspect -~encoder.dirChannels.raddeg; -:: - - -METHOD:: newZoomH2 -link::http://www.zoom.co.jp/english/products/h2/##ZoomH2:: (pantophonic) encoder. - -argument:: angles -Angles for front left and back left microphones, in radians. (The corresponding right microphones are mirrored across the y-axis.) Defaults to code:: [pi/3, 3/4*pi] :: . - -note:: anchor::newzoomh2note:: The encoder reverses the labels for front and back of the link::http://www.zoom.co.jp/english/products/h2/##ZoomH2::. This is done so that directions are are preserved from the point of view of a field recording operator. With the link::http://www.zoom.co.jp/english/products/h2/##ZoomH2::'s display facing the operator (for ease of monitoring), sounds arriving in front of the operator will be encoded in the front of the soundfield. See also link::#newzoomdiscussion#Discussion:: below.:: - -argument:: pattern -Microphone pattern footnote::The default value, 0.5857, is derived from measurements made by Farina, and is a hyper-cardioid response with a zero at 135 degrees. See: link::http://pcfarina.eng.unipr.it/Public/Brahma/Zoom-H2/Polar-ZoomH2.xls:: ::, 0 to 1: - -table:: -## strong::pattern:: || strong::virtual microphone:: -## 0.0 || Omni -## 0.5 || Cardioid -## (3-sqrt(3))/2 || Super-cardioid -## 0.75 || Hyper-cardioid -## 1.0 || Bi-directional -:: - -argument:: k -Post-encoding Y scalar. -note::Please see further discussion of strong::k:: link::#newzoomh2k#here:::: - -discussion:: -anchor::newzoomdiscussion:: -A four channel recording made by the link::http://www.zoom.co.jp/english/products/h2/##ZoomH2:: will be returned as two stereo .wav files named: - -list:: -## SRxxxF.wav -## SRxxxR.wav -:: - -Presuming the link::http://www.zoom.co.jp/english/products/h2/##ZoomH2:: is oriented as described link::#newzoomh2note#here::, the following illustrates correct input for the encoder: -code:: -// ZoomH2 records two stereo .wav files: -// SRxxxF.wav -// SRxxxR.wav -// correct input for FoaEncoderMatrix.newZoomH2 is: - -~in = [ SRxxxR.at(0), SRxxxR.at(1), SRxxxF.at(0), SRxxxF.at(1) ] -:: - -anchor::newzoomh2k:: -The encoder includes a Y scalar, strong::k::, and an auditioned adjustment is usually necessary to improve the resulting image. As the link::http://www.zoom.co.jp/english/products/h2/##ZoomH2::'s polar patterns are not consistent across frequency, and the capsules are not coincident, imaging is not always consistent. Touching strong::k:: can go some way towards remedy-ing this. - -note:: -strong::k:: = 1.7378 is a value that has been found suitable for matching link::http://www.radio.uqam.ca/ambisonic/comparative_recording.html##Courville::'s link::http://www.zoom.co.jp/english/products/h2/##ZoomH2:: footnote:: Courville orients his ZoomH2 so that the labelled front of the device faces the front of the sound scene. This is front/back reversed as regards -newZoomH2. If you choose to encode Courville's example files, you'll need to follow with FoaMirrorX.:: and Soundfield recordings. footnote:: See: http://www.radio.uqam.ca/ambisonic/comparative_recording.html :: -:: - -METHOD:: newZoomH2n -A first order link::https://en.wikipedia.org/wiki/Ambisonic_data_exchange_formats##Ambisonic format exchange:: encoder, for use with the link::https://www.zoom-na.com/products/field-video-recording/field-recording/zoom-h2n-handy-recorder##ZoomH2n::. Encodes from AmbiX to traditional B-format. A convenience alias to link::#*newHoa1::. - - -discussion:: -Encoding means encoding from one Ambisonic channel componenent orderding and normalisation to that of traditional B-format. In this case, from AmbiX encoding scheme (strong::ACN:: ordering, strong::SN3D:: normalisation) to strong::Gerzon:: (aka strong::Furse-Malham::) ordering, strong::MaxN:: normalisation. - - -note:: -Requires a device firmware update to link::https://www.zoom-na.com/sites/default/files/products/downloads/software/H2n_v2.00E.zip##H2n System Version 2.00:: or higher. Set the link::https://www.zoom-na.com/products/field-video-recording/field-recording/zoom-h2n-handy-recorder##ZoomH2n:: to record in the code::SPATIAL AUDIO:: mode. Further details may be reviewed in the manual addendum link::https://www.zoom.co.jp/sites/default/files/products/downloads/pdfs/H2n_Ver2_OPmanual_E.pdf##found here::. -:: - - - -METHOD:: newAtoB -A-format to B-format encoder. Encodes to a variety of tetrahedral orientations and W channel weights. - - -argument:: orientation -Orientation of the A-format tetrahedron. - -table:: -## strong::orientation:: || strong::angles:: ([theta, phi] in degrees) -## code::'flu':: || code:: [[45.0, 35.3], [-45.0, -35.3], [135.0, -35.3], [-135.0, 35.3]] :: -## code::'fld':: || code:: [[45.0, -35.3], [-45.0 , 35.3], [135.0, 35.3], [-135.0, -35.3]] :: -## code::'flr':: || code:: [[54.7, 0.0], [-54.7, 0.0], [180.0, 54.7], [ 180.0, -54.7]] :: -## code::'fud':: || code:: [[ 0.0, 54.7], [ 0.0, -54.7], [125.7, 0.0], [-125.7, 0.0]] :: -## code::'fbd':: || code:: [[ 0.0, 0.0], [180.0, -70.5], [112.2, 28.1], [-112.2, 28.1]] :: -## code::'fbu':: || code:: [[ 0.0, 0.0], [180.0, 70.5], [112.2, -28.1], [-112.2, -28.1]] :: -## code::'flru':: || code:: [[67.8, 28.1], [-67.8, 28.1], [ 0.0, -70.5], [ 180.0, 0.0]] :: -## code::'flrd':: || code:: [[67.8, -28.1], [-67.8, -28.1], [ 0.0, 70.5], [ 180.0, 0.0]] :: -:: - -argument:: weight -The W weight factor. - -For convenience, equivalent virtual microphone strong::pattern:: and decoding strong::k:: are also listed. - -table:: -## strong::weight:: || strong::kind:: || strong::W scale:: || strong::virtual microphone:: || strong::pattern:: || strong::decoding:: || strong::k:: -## code::'dec':: || Decorrelated (on the sphere) || 1/sqrt(3) || Hyper-cardioid || 0.75 || strict soundfield || code::'velocity':: -## code::'can':: || Canonical (B-format) || 1/sqrt(2) || ||sqrt(6)/(1+sqrt(6)) || || sqrt(2/3) -## code::'uns':: || Unscaled || 1 || Super-cardioid || (3-sqrt(3))/2 || energy optimised || code::'energy':: -## code::'car':: || Cardioid || sqrt(3) || Cardioid || 0.5 || controlled opposites || code::'controlled':: -:: - - -discussion:: -The A-format encoder is often used in conjunction with the link::Classes/FoaDecoderMatrix#*newBtoA:: B-format decoder to form signal processing networks which preserve the spatial encoding as is described link::Classes/FoaDecoderMatrix#btoadiscuss#here::. - -On its own, link::#*newAtoB:: is often used to author immersive, periphonic (3D) decorrelated soundfields. - - -METHOD:: newHoa1 -A first order link::https://en.wikipedia.org/wiki/Ambisonic_data_exchange_formats##Ambisonic format exchange:: encoder. Encodes a variety of formats to traditional B-format. - -argument:: ordering -Input Ambisonic channel component ordering. - -table:: -## strong::ordering:: || strong::kind:: -## code::'acn':: || Ambisonic Channel Number (ACN) -## code::'sid':: || Single Index Designation (SID) -:: - -argument:: normalisation -Spherical harmonic normalisation method. - -table:: -## strong::normalisation:: || strong::kind:: -## code::'n3d':: || Orthonormal basis for 3D decomposition (N3D) -## code::'sn3d':: || Semi-normalised basis for 3D decomposition (SN3D) -:: - - -discussion:: -Encoding means encoding from one Ambisonic channel componenent orderding and normalisation to that of traditional B-format. In other words, from some standard scheme to strong::Gerzon:: (aka strong::Furse-Malham::) ordering with strong::MaxN:: normalisation. - -note::code::Hoa1:: in the method name link::#*newHoa1:: refers to Higher Order Ambisonic (HOA) encoding format, Ambisonic order = 1. The input signal should have four channels, with the given encoding format as specified in the arguments.:: - - -METHOD:: newAmbix1 -A first order link::https://en.wikipedia.org/wiki/Ambisonic_data_exchange_formats##Ambisonic format exchange:: encoder. Encodes from AmbiX to traditional B-format. A convenience alias to link::#*newHoa1::. - -discussion:: -Encoding means encoding from one Ambisonic channel componenent orderding and normalisation to that of traditional B-format. In this case, from AmbiX encoding scheme (strong::ACN:: ordering, strong::SN3D:: normalisation) to strong::Gerzon:: (aka strong::Furse-Malham::) ordering, strong::MaxN:: normalisation. - - -METHOD:: newFromFile -Create an FoaEncoderMatrix by loading a matrix from a file. - -argument:: filePathOrName -Can be a path relative to your code::/extensions/matrices/encoders:: folder: -code:: -Atk.getMatrixExtensionPath('encoders').fullPath -:: -Otherwise a full path to your matrix file. - -discussion:: -See the link::Guides/Guide-to-ATK-Matrix-Files:: for more information. - - -COPYMETHOD:: AtkMatrix, *newFromMatrix - - -INSTANCEMETHODS:: -private:: init2D, init3D, initInv2D, initInv3D, initAtoB, initOmni, initDirection, initStereo, initQuad, init5_0, init7_0, initDirections, initPanto, initPeri, initZoomH2, initHoa1, initAmbix1, initZoomH2n, printOn, initEncoderVarsForFiles - - -METHOD:: set - -Describes both the emphasis::signal set:: and the emphasis::tool set::, encompassing the Ambisonic order, as well as channel ordering and normalisation. - -Answers code::'FOA'::, aka traditional B-format: - -table:: -## strong::Ambisonic Order:: || strong::Channel Ordering:: || strong::Channel Normalisation:: -## 1st || Gerzon (aka Furse-Malham) || MaxN -:: - -METHOD:: type -returns:: code::'encoder':: - -COPYMETHOD:: AtkMatrix, -op - -METHOD:: kind -Answers the kind of encoder. - -discussion:: - -code:: -// encoder -~encoder = FoaEncoderMatrix.newQuad - -// inspect -~encoder.kind -:: - -code:: -// encoder -~encoder = FoaEncoderMatrix.newPeri - -// inspect -~encoder.kind -:: - - -METHOD:: dim -Answers the number of encoder dimensions: 2D or 3D. - -discussion:: - -code:: -// encoder -~encoder = FoaEncoderMatrix.newQuad - -// inspect -~encoder.dim -:: - -code:: -// encoder -~encoder = FoaEncoderMatrix.newPeri - -// inspect -~encoder.dim -:: - - - -METHOD:: numChannels -Answers the number of input channels (virtual loudspeakers or microphones). - -discussion:: - -code:: -// encoder -~encoder = FoaEncoderMatrix.newQuad - -// inspect -~encoder.numChannels -:: - -code:: -// encoder (two rings of 6) -~encoder = FoaEncoderMatrix.newPeri(6) - -// inspect -~encoder.numChannels -:: - - - -METHOD:: dirChannels -Answers the direction of virtual loudspeaker or microphone feeds, with angles in radians. - -returns:: A rank 1 array for pantophonic, and rank 2 array for periphonic. E.g., -code:: -// 2D: -[ theta0, theta1, ... thetaN ] -:: -code:: -// 3D -[ [ theta0, phi0 ], [ theta1, phi1 ], ... [ thetaN, phiN ] ] -:: - -code:: -// encoder -~encoder = FoaEncoderMatrix.newQuad - -// inspect -~encoder.dirChannels.raddeg -:: - -code:: -// encoder (two rings of 6) -~encoder = FoaEncoderMatrix.newPeri(6) - -// inspect -~encoder.dirChannels.raddeg -:: - - - -METHOD:: matrix -Answers the encoding matrix - - - - -METHOD:: numOutputs -Answers the number of outputs for the encoder. 3 for 2D and 4 for 3D. - - -METHOD:: dirOutputs -A convenience method providing polymorphism with link::Classes/FoaEncoderMatrix#-dirOutputs::. - -returns:: - -list:: -## for 2D: code:: [ inf, inf, inf ] :: -## for 3D: code:: [ inf, inf, inf , inf ] :: -:: - - -METHOD:: numInputs -A synonym for link::#-numChannels:: - - -METHOD:: dirInputs -A synonym for link::#-dirChannels:: - -COPYMETHOD:: AtkMatrix, -info - -COPYMETHOD:: AtkMatrix, -fileParse - -COPYMETHOD:: AtkMatrix, -filePath - -COPYMETHOD:: AtkMatrix, -fileName - -COPYMETHOD:: AtkMatrix, -writeToFile - -EXAMPLES:: - -Please see link::Classes/FoaEncode#Examples::. diff --git a/source/ATK/sc/HelpSource/Classes/FoaFocus.schelp b/source/ATK/sc/HelpSource/Classes/FoaFocus.schelp deleted file mode 100644 index f11d64ba5c..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaFocus.schelp +++ /dev/null @@ -1,47 +0,0 @@ -CLASS:: FoaFocus -summary:: First Order Ambisonic (FOA) focus transformer -categories:: Libraries>Ambisonic Toolkit>FOA>Transforming>UGens, UGens>Multichannel>Ambisonics, UGens>Multichannel>Panners -related:: Classes/FoaFocusX, Classes/FoaFocusY, Classes/FoaFocusZ, Classes/FoaTransform, Classes/FoaXform - -DESCRIPTION:: -Apply focus to a first order ambisonic signal (B-format) along an arbitrary axis. - - -NOTE:: -link::Classes/FoaFocus:: is usually called via the convenience wrapper link::Classes/FoaTransform::. -:: - - - -CLASSMETHODS:: - -METHOD:: ar - -argument:: in -The B-format signal, an array: [w, x, y, z] - -argument:: angle -The distortion angle, in radians. -pi/2 to pi/2 - -argument:: theta -Azimuth, in radians. - -argument:: phi -Elevation, in radians. - -argument:: mul -Output will be multiplied by this value. - -argument:: add -This value will be added to the output. - - -discussion:: Applies focus along the axis defined by strong::theta:: and strong::phi::. See link::Classes/FoaFocusX::. - - -note:: Corresponding matrix transformer: link::Classes/FoaXformerMatrix#*newFocus:: :: - - -EXAMPLES:: - -Please see various examples link::Classes/FoaTransform#examples#here::. \ No newline at end of file diff --git a/source/ATK/sc/HelpSource/Classes/FoaFocusX.schelp b/source/ATK/sc/HelpSource/Classes/FoaFocusX.schelp deleted file mode 100644 index 5324f17a50..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaFocusX.schelp +++ /dev/null @@ -1,46 +0,0 @@ -CLASS:: FoaFocusX -summary:: First Order Ambisonic (FOA) focus transformer -categories:: Libraries>Ambisonic Toolkit>FOA>Transforming>UGens, UGens>Multichannel>Ambisonics, UGens>Multichannel>Panners -related:: Classes/FoaFocusY, Classes/FoaFocusZ, Classes/FoaFocus, Classes/FoaTransform, Classes/FoaXform - -DESCRIPTION:: -Apply focus to a first order ambisonic signal (B-format) along the x-axis. - - -NOTE:: -link::Classes/FoaFocusX:: is usually called via the convenience wrapper link::Classes/FoaTransform::. -:: - - - -CLASSMETHODS:: - -METHOD:: ar - -argument:: in -The B-format signal, an array: [w, x, y, z] - -argument:: angle -The distortion angle, in radians. -pi/2 to pi/2 - -argument:: mul -Output will be multiplied by this value. - -argument:: add -This value will be added to the output. - -discussion:: Focus is a normalised dominance variant, specified in terms of a distortion angle. Positive values of strong::angle:: maintain gain at code:: [0, 0] ::, while reducing at code:: [pi, 0] ::. Negative values do the inverse. The default, 0, results in no change. - -In contrast with zoom, gain is maintained at 0dB in the direction of distortion. - -anchor::figure:: - -image::focus_fig.png#Focus imaging:: - - -note:: Corresponding matrix transformer: link::Classes/FoaXformerMatrix#*newFocusX:: :: - - -EXAMPLES:: - -Please see various examples link::Classes/FoaTransform#examples#here::. \ No newline at end of file diff --git a/source/ATK/sc/HelpSource/Classes/FoaFocusY.schelp b/source/ATK/sc/HelpSource/Classes/FoaFocusY.schelp deleted file mode 100644 index 04cffe1d37..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaFocusY.schelp +++ /dev/null @@ -1,42 +0,0 @@ -CLASS:: FoaFocusY -summary:: First Order Ambisonic (FOA) focus transformer -categories:: Libraries>Ambisonic Toolkit>FOA>Transforming>UGens, UGens>Multichannel>Ambisonics, UGens>Multichannel>Panners -related:: Classes/FoaFocusX, Classes/FoaFocusZ, Classes/FoaFocus, Classes/FoaTransform, Classes/FoaXform - -DESCRIPTION:: -Apply focus to a first order ambisonic signal (B-format) along the y-axis. - - -NOTE:: -link::Classes/FoaFocusY:: is usually called via the convenience wrapper link::Classes/FoaTransform::. -:: - - - -CLASSMETHODS:: - -METHOD:: ar - -argument:: in -The B-format signal, an array: [w, x, y, z] - -argument:: angle -The distortion angle, in radians. -pi/2 to pi/2 - -argument:: mul -Output will be multiplied by this value. - -argument:: add -This value will be added to the output. - -discussion:: Focus is a normalised dominance variant, specified in terms of a distortion angle. Positive values of strong::angle:: maintain gain at code:: [pi/2, 0] ::, while reducing at code:: [-pi/2, 0] ::. Negative values do the inverse. The default, 0, results in no change. - -In contrast with zoom, gain is maintained at 0dB in the direction of distortion. - - -note:: Corresponding matrix transformer: link::Classes/FoaXformerMatrix#*newFocusY:: :: - - -EXAMPLES:: - -Please see various examples link::Classes/FoaTransform#examples#here::. \ No newline at end of file diff --git a/source/ATK/sc/HelpSource/Classes/FoaFocusZ.schelp b/source/ATK/sc/HelpSource/Classes/FoaFocusZ.schelp deleted file mode 100644 index b7fafe6ef2..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaFocusZ.schelp +++ /dev/null @@ -1,42 +0,0 @@ -CLASS:: FoaFocusZ -summary:: First Order Ambisonic (FOA) focus transformer -categories:: Libraries>Ambisonic Toolkit>FOA>Transforming>UGens, UGens>Multichannel>Ambisonics, UGens>Multichannel>Panners -related:: Classes/FoaFocusX, Classes/FoaFocusY, Classes/FoaFocus, Classes/FoaTransform, Classes/FoaXform - -DESCRIPTION:: -Apply focus to a first order ambisonic signal (B-format) along the z-axis. - - -NOTE:: -link::Classes/FoaFocusZ:: is usually called via the convenience wrapper link::Classes/FoaTransform::. -:: - - - -CLASSMETHODS:: - -METHOD:: ar - -argument:: in -The B-format signal, an array: [w, x, y, z] - -argument:: angle -The distortion angle, in radians. -pi/2 to pi/2 - -argument:: mul -Output will be multiplied by this value. - -argument:: add -This value will be added to the output. - -discussion:: Focus is a normalised dominance variant, specified in terms of a distortion angle. Positive values of strong::angle:: maintain gain at code:: [0, pi/2] ::, while reducing at code:: [0, -pi/2] ::. Negative values do the inverse. The default, 0, results in no change. - -In contrast with zoom, gain is maintained at 0dB in the direction of distortion. - - -note:: Corresponding matrix transformer: link::Classes/FoaXformerMatrix#*newFocusZ:: :: - - -EXAMPLES:: - -Please see various examples link::Classes/FoaTransform#examples#here::. \ No newline at end of file diff --git a/source/ATK/sc/HelpSource/Classes/FoaMirror.schelp b/source/ATK/sc/HelpSource/Classes/FoaMirror.schelp deleted file mode 100644 index be8061289a..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaMirror.schelp +++ /dev/null @@ -1,47 +0,0 @@ -CLASS:: FoaMirror -summary:: First Order Ambisonic (FOA) mirror transformer -categories:: Libraries>Ambisonic Toolkit>FOA>Transforming>UGens, UGens>Multichannel>Ambisonics, UGens>Multichannel>Panners -related:: Classes/FoaTransform, Classes/FoaXform - -DESCRIPTION:: -Mirror a first order ambisonic signal (B-format) across an arbitrary plane. - - -NOTE:: -link::Classes/FoaMirror:: is usually called via the convenience wrapper link::Classes/FoaTransform::. -:: - - - -CLASSMETHODS:: - -METHOD:: ar - -argument:: in -The B-format signal, an array: [w, x, y, z] - -argument:: theta -Azimuth for the normal to the plane, in radians. - -argument:: phi -Elevation for the normal to the plane, in radians. - -argument:: mul -Output will be multiplied by this value. - -argument:: add -This value will be added to the output. - - - -discussion:: - -Mirroring across the origin and individual axes is implemented via link::Classes/FoaXformerMatrix#*newMirrorO:: and link::Classes/FoaXformerMatrix#*newMirrorX::, link::Classes/FoaXformerMatrix#*newMirrorY::, link::Classes/FoaXformerMatrix#*newMirrorZ::. - -note:: Corresponding matrix transformer: link::Classes/FoaXformerMatrix#*newMirror:: :: - - - -EXAMPLES:: - -Please see various examples link::Classes/FoaTransform#examples#here::. \ No newline at end of file diff --git a/source/ATK/sc/HelpSource/Classes/FoaNFC.schelp b/source/ATK/sc/HelpSource/Classes/FoaNFC.schelp deleted file mode 100644 index d1ce9b4b58..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaNFC.schelp +++ /dev/null @@ -1,48 +0,0 @@ -CLASS:: FoaNFC -summary:: First Order Ambisonic (FOA) nearfield compensation filter -categories:: Libraries>Ambisonic Toolkit>FOA>Decoding>UGens, Libraries>Ambisonic Toolkit>FOA>Transforming>UGens, UGens>Multichannel>Ambisonics, UGens>Multichannel>Panners -related:: Classes/FoaProximity, Classes/FoaTransform, Classes/FoaDecode - -DESCRIPTION:: -Apply nearfield compensation filtering to a first order ambisonic signal (B-format). - -note:: -link::Classes/FoaNFC:: is usually called via the convenience wrapper link::Classes/FoaTransform::. -:: - - - -CLASSMETHODS:: - -METHOD:: ar - -argument:: in -The B-format signal, an array: [w, x, y, z] - -argument:: distance -The distance, in meters. - -warning:: strong::Distance:: = 0 is an invalid value! :: - -argument:: mul -Output will be multiplied by this value. - -argument:: add -This value will be added to the output. - - -discussion:: - -link::Classes/FoaNFC:: facilitates the reduction or removal of the link::http://en.wikipedia.org/wiki/Proximity_effect_(audio)##proximity effect:: from encoded signals. The link::http://en.wikipedia.org/wiki/Proximity_effect_(audio)##proximity effect:: can be an important contributor to perceptions of nearness. - -Nearfield compensation footnote::Usually called distance compensation in the classic Ambisonics literature.:: is usually used in conjunction with link::Classes/FoaDecode:: to compensate for the distance of loudspeakers on playback. Additionally, link::Classes/FoaNFC:: can also be used to reduce the link::http://en.wikipedia.org/wiki/Proximity_effect_(audio)##proximity effect:: found in nearfield recordings. - - -The Ambisonic Toolkit's proximity filter, link::Classes/FoaProximity::, undoes link::Classes/FoaNFC:: given the same strong::distance:: argument. - - - - -EXAMPLES:: - -Please see link::Classes/FoaDecode#psychoacoustically_optimised_quadraphonic_decoder#this:: and link::Classes/FoaTransform#nfc_(soundfile)#this::. diff --git a/source/ATK/sc/HelpSource/Classes/FoaPanB.schelp b/source/ATK/sc/HelpSource/Classes/FoaPanB.schelp deleted file mode 100644 index a2ce5c1e9a..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaPanB.schelp +++ /dev/null @@ -1,37 +0,0 @@ -CLASS:: FoaPanB -summary:: First Order Ambisonic (FOA) panner -categories:: Libraries>Ambisonic Toolkit>FOA>Encoding>UGens, UGens>Multichannel>Ambisonics, UGens>Multichannel>Panners -related:: Classes/FoaEncode - -DESCRIPTION:: -Encode a monophonic input to a first order ambisonic signal (B-format), as a planewave. link::Classes/PanB:: is the SuperCollider inbuilt equivalent. - - - -CLASSMETHODS:: - -METHOD:: ar - - -argument:: in -The input signal. - -argument:: azimuth -Azimuth, in radians. - -argument:: elevation -Elevation, in radians. - -argument:: mul -Output will be multiplied by this value. - -argument:: add -This value will be added to the output. - - - -discussion:: - -link::Classes/FoaPanB:: is provided primarily as a convenience. Encoding monophonic signals via link::Classes/FoaEncoderMatrix#*newOmni:: and transformation via link::Classes/FoaPush:: is often regarded as a more idiomatic option. See link::Classes/FoaEncode#omnidirectional_encoder#this example::. - -Additionally, use of link::Classes/FoaProximity:: to generate proximity cues is also encouraged. \ No newline at end of file diff --git a/source/ATK/sc/HelpSource/Classes/FoaPress.schelp b/source/ATK/sc/HelpSource/Classes/FoaPress.schelp deleted file mode 100644 index bdfe980a28..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaPress.schelp +++ /dev/null @@ -1,47 +0,0 @@ -CLASS:: FoaPress -summary:: First Order Ambisonic (FOA) press transformer -categories:: Libraries>Ambisonic Toolkit>FOA>Transforming>UGens, UGens>Multichannel>Ambisonics, UGens>Multichannel>Panners -related:: Classes/FoaPressX, Classes/FoaPressY, Classes/FoaPressZ, Classes/FoaTransform, Classes/FoaXform - -DESCRIPTION:: -Apply press to a first order ambisonic signal (B-format) along an arbitrary axis. - - -NOTE:: -link::Classes/FoaPress:: is usually called via the convenience wrapper link::Classes/FoaTransform::. -:: - - - -CLASSMETHODS:: - -METHOD:: ar - -argument:: in -The B-format signal, an array: [w, x, y, z] - -argument:: angle -The distortion angle, in radians. -pi/2 to pi/2 - -argument:: theta -Azimuth, in radians. - -argument:: phi -Elevation, in radians. - -argument:: mul -Output will be multiplied by this value. - -argument:: add -This value will be added to the output. - - -discussion:: Applies press along the axis defined by strong::theta:: and strong::phi::. See link::Classes/FoaPressX::. - - -note:: Corresponding matrix transformer: link::Classes/FoaXformerMatrix#*newPress:: :: - - -EXAMPLES:: - -Please see various examples link::Classes/FoaTransform#examples#here::. \ No newline at end of file diff --git a/source/ATK/sc/HelpSource/Classes/FoaPressX.schelp b/source/ATK/sc/HelpSource/Classes/FoaPressX.schelp deleted file mode 100644 index ac869e658c..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaPressX.schelp +++ /dev/null @@ -1,45 +0,0 @@ -CLASS:: FoaPressX -summary:: First Order Ambisonic (FOA) press transformer -categories:: Libraries>Ambisonic Toolkit>FOA>Transforming>UGens, UGens>Multichannel>Ambisonics, UGens>Multichannel>Panners -related:: Classes/FoaPressY, Classes/FoaPressZ, Classes/FoaPress, Classes/FoaTransform, Classes/FoaXform - -DESCRIPTION:: -Apply press to a first order ambisonic signal (B-format) along the x-axis. - - -NOTE:: -link::Classes/FoaPressX:: is usually called via the convenience wrapper link::Classes/FoaTransform::. -:: - - - -CLASSMETHODS:: - -METHOD:: ar - -argument:: in -The B-format signal, an array: [w, x, y, z] - -argument:: angle -The distortion angle, in radians. -pi/2 to pi/2 - -argument:: mul -Output will be multiplied by this value. - -argument:: add -This value will be added to the output. - -discussion:: Press is a dominance related transform, specified in terms of a distortion angle. Positive values of strong::angle:: press the image towards code:: [0, 0] ::. Negative values press towards code:: [pi, 0] ::. The default, 0, results in no change. - - -anchor::figure:: - -image::press_fig.png#Press imaging:: - - -note:: Corresponding matrix transformer: link::Classes/FoaXformerMatrix#*newPressX:: :: - - -EXAMPLES:: - -Please see various examples link::Classes/FoaTransform#examples#here::. \ No newline at end of file diff --git a/source/ATK/sc/HelpSource/Classes/FoaPressY.schelp b/source/ATK/sc/HelpSource/Classes/FoaPressY.schelp deleted file mode 100644 index 6e1418c0e3..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaPressY.schelp +++ /dev/null @@ -1,40 +0,0 @@ -CLASS:: FoaPressY -summary:: First Order Ambisonic (FOA) press transformer -categories:: Libraries>Ambisonic Toolkit>FOA>Transforming>UGens, UGens>Multichannel>Ambisonics, UGens>Multichannel>Panners -related:: Classes/FoaPressX, Classes/FoaPressZ, Classes/FoaPress, Classes/FoaTransform, Classes/FoaXform - -DESCRIPTION:: -Apply press to a first order ambisonic signal (B-format) along the y-axis. - - -NOTE:: -link::Classes/FoaPressY:: is usually called via the convenience wrapper link::Classes/FoaTransform::. -:: - - - -CLASSMETHODS:: - -METHOD:: ar - -argument:: in -The B-format signal, an array: [w, x, y, z] - -argument:: angle -The distortion angle, in radians. -pi/2 to pi/2 - -argument:: mul -Output will be multiplied by this value. - -argument:: add -This value will be added to the output. - -discussion:: Press is a dominance related transform, specified in terms of a distortion angle. Positive values of strong::angle:: press the image towards code:: [pi/2, 0] ::. Negative values press towards code:: [-pi/2, 0] ::. The default, 0, results in no change. - - -note:: Corresponding matrix transformer: link::Classes/FoaXformerMatrix#*newPressY:: :: - - -EXAMPLES:: - -Please see various examples link::Classes/FoaTransform#examples#here::. \ No newline at end of file diff --git a/source/ATK/sc/HelpSource/Classes/FoaPressZ.schelp b/source/ATK/sc/HelpSource/Classes/FoaPressZ.schelp deleted file mode 100644 index 56e93304bf..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaPressZ.schelp +++ /dev/null @@ -1,40 +0,0 @@ -CLASS:: FoaPressZ -summary:: First Order Ambisonic (FOA) press transformer -categories:: Libraries>Ambisonic Toolkit>FOA>Transforming>UGens, UGens>Multichannel>Ambisonics, UGens>Multichannel>Panners -related:: Classes/FoaPressX, Classes/FoaPressY, Classes/FoaPress, Classes/FoaTransform, Classes/FoaXform - -DESCRIPTION:: -Apply press to a first order ambisonic signal (B-format) along the z-axis. - - -NOTE:: -link::Classes/FoaPressZ:: is usually called via the convenience wrapper link::Classes/FoaTransform::. -:: - - - -CLASSMETHODS:: - -METHOD:: ar - -argument:: in -The B-format signal, an array: [w, x, y, z] - -argument:: angle -The distortion angle, in radians. -pi/2 to pi/2 - -argument:: mul -Output will be multiplied by this value. - -argument:: add -This value will be added to the output. - -discussion:: Press is a dominance related transform, specified in terms of a distortion angle. Positive values of strong::angle:: press the image towards code:: [0, pi/2] ::. Negative values press towards code:: [0, -pi/2] ::. The default, 0, results in no change. - - -note:: Corresponding matrix transformer: link::Classes/FoaXformerMatrix#*newPressZ:: :: - - -EXAMPLES:: - -Please see various examples link::Classes/FoaTransform#examples#here::. \ No newline at end of file diff --git a/source/ATK/sc/HelpSource/Classes/FoaProximity.schelp b/source/ATK/sc/HelpSource/Classes/FoaProximity.schelp deleted file mode 100644 index 383c50789b..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaProximity.schelp +++ /dev/null @@ -1,46 +0,0 @@ -CLASS:: FoaProximity -summary:: First Order Ambisonic (FOA) proximity effect filter -categories:: Libraries>Ambisonic Toolkit>FOA>Transforming>UGens, UGens>Multichannel>Ambisonics, UGens>Multichannel>Panners -related:: Classes/FoaNFC, Classes/FoaTransform - -DESCRIPTION:: -Apply proximity filtering to a first order ambisonic signal (B-format). - -NOTE:: -link::Classes/FoaProximity:: is usually called via the convenience wrapper link::Classes/FoaTransform::. -:: - - -CLASSMETHODS:: - -METHOD:: ar - -argument:: in -The B-format signal, an array: [w, x, y, z] - -argument:: distance -The distance, in meters. - -warning:: strong::Distance:: = 0 is an invalid value! :: - -argument:: mul -Output will be multiplied by this value. - -argument:: add -This value will be added to the output. - - -discussion:: - -link::Classes/FoaProximity:: facilitates the introduction of the link::http://en.wikipedia.org/wiki/Proximity_effect_(audio)##proximity effect:: to encoded signals. At extremes, the proximity effect introduces a strong bass boost, as well as phase differences. The link::http://en.wikipedia.org/wiki/Proximity_effect_(audio)##proximity effect:: can be an important contributor to perceptions of nearness. - -The Ambisonic Toolkit's nearfield compensation filter, link::Classes/FoaNFC::, undoes link::Classes/FoaProximity:: given the same strong::distance:: argument. - - -warning:: As link::Classes/FoaProximity:: includes a 1st-order integration, signals must be highpass filtered before application. link::Classes/HPF:: is usually a suitable choice to control low frequency boost.:: - - - -EXAMPLES:: - -Please see link::Classes/FoaTransform#proximity#this::. diff --git a/source/ATK/sc/HelpSource/Classes/FoaPsychoShelf.schelp b/source/ATK/sc/HelpSource/Classes/FoaPsychoShelf.schelp deleted file mode 100644 index 569c5a1803..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaPsychoShelf.schelp +++ /dev/null @@ -1,47 +0,0 @@ -CLASS:: FoaPsychoShelf -summary:: First Order Ambisonic (FOA) psychoacoustic shelf filter -categories:: Libraries>Ambisonic Toolkit>FOA>Decoding>UGens, UGens>Multichannel>Ambisonics -related:: Classes/FoaNFC, Classes/FoaDecode - -DESCRIPTION:: -Apply psychoacoustic shelf filtering to a first order ambisonic signal (B-format). - -note:: -link::Classes/FoaPsychoShelf:: is usually called internally by link::Classes/FoaDecode::. -:: - - -CLASSMETHODS:: - -METHOD:: ar - -argument:: in -The B-format signal, an array: [w, x, y, z] - -argument:: freq -Shelf filter corner frequency, in Hz. - -argument:: k0 -High frequency scale for 0-order harmonic: W. - -argument:: k1 -High frequency scale for 1st-order harmonics: X, Y, Z. - -argument:: mul -Output will be multiplied by this value. - -argument:: add -This value will be added to the output. - - -discussion:: - -link::Classes/FoaPsychoShelf:: is invoked by link::Classes/FoaDecode:: when a dual-band psychoacoustically optimised decoder footnote::See: E. Benjamin, R. Lee, and A. Heller, "Is My Decoder Ambisonic?," in Proceedings of the 125th Audio Engineering Society Convention, San Francisco, 2008.:: is called by setting strong::k:: to code:: 'dual' ::. This kind of decoder is the optimum choice for small scale studio or domestic settings. - -note:: In normal circumstances, the user will not call link::Classes/FoaPsychoShelf:: directly.:: - - -EXAMPLES:: - -Please see link::Classes/FoaDecode#psychoacoustically_optimised_quadraphonic_decoder#this::. - diff --git a/source/ATK/sc/HelpSource/Classes/FoaPush.schelp b/source/ATK/sc/HelpSource/Classes/FoaPush.schelp deleted file mode 100644 index e1b0954b7b..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaPush.schelp +++ /dev/null @@ -1,47 +0,0 @@ -CLASS:: FoaPush -summary:: First Order Ambisonic (FOA) push transformer -categories:: Libraries>Ambisonic Toolkit>FOA>Transforming>UGens, UGens>Multichannel>Ambisonics, UGens>Multichannel>Panners -related:: Classes/FoaPushX, Classes/FoaPushY, Classes/FoaPushZ, Classes/FoaTransform, Classes/FoaXform - -DESCRIPTION:: -Apply push to a first order ambisonic signal (B-format) along an arbitrary axis. - - -NOTE:: -link::Classes/FoaPush:: is usually called via the convenience wrapper link::Classes/FoaTransform::. -:: - - - -CLASSMETHODS:: - -METHOD:: ar - -argument:: in -The B-format signal, an array: [w, x, y, z] - -argument:: angle -The distortion angle, in radians. -pi/2 to pi/2 - -argument:: theta -Azimuth, in radians. - -argument:: phi -Elevation, in radians. - -argument:: mul -Output will be multiplied by this value. - -argument:: add -This value will be added to the output. - - -discussion:: Applies push along the axis defined by strong::theta:: and strong::phi::. See link::Classes/FoaPushX::. - - -note:: Corresponding matrix transformer: link::Classes/FoaXformerMatrix#*newPush:: :: - - -EXAMPLES:: - -Please see various examples link::Classes/FoaTransform#examples#here::. \ No newline at end of file diff --git a/source/ATK/sc/HelpSource/Classes/FoaPushX.schelp b/source/ATK/sc/HelpSource/Classes/FoaPushX.schelp deleted file mode 100644 index 9af96cfe42..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaPushX.schelp +++ /dev/null @@ -1,45 +0,0 @@ -CLASS:: FoaPushX -summary:: First Order Ambisonic (FOA) push transformer -categories:: Libraries>Ambisonic Toolkit>FOA>Transforming>UGens, UGens>Multichannel>Ambisonics, UGens>Multichannel>Panners -related:: Classes/FoaPushY, Classes/FoaPushZ, Classes/FoaPush, Classes/FoaTransform, Classes/FoaXform - -DESCRIPTION:: -Apply push to a first order ambisonic signal (B-format) along the x-axis. - - -NOTE:: -link::Classes/FoaPushX:: is usually called via the convenience wrapper link::Classes/FoaTransform::. -:: - - - -CLASSMETHODS:: - -METHOD:: ar - -argument:: in -The B-format signal, an array: [w, x, y, z] - -argument:: angle -The distortion angle, in radians. -pi/2 to pi/2 - -argument:: mul -Output will be multiplied by this value. - -argument:: add -This value will be added to the output. - -discussion:: Push is a dominance related transform, specified in terms of a distortion angle. Positive values of strong::angle:: push the image towards code:: [0, 0] ::. Negative values push towards code:: [pi, 0] ::. The default, 0, results in no change. - - -anchor::figure:: - -image::push_fig.png#Push imaging:: - - -note:: Corresponding matrix transformer: link::Classes/FoaXformerMatrix#*newPushX:: :: - - -EXAMPLES:: - -Please see various examples link::Classes/FoaTransform#examples#here::. \ No newline at end of file diff --git a/source/ATK/sc/HelpSource/Classes/FoaPushY.schelp b/source/ATK/sc/HelpSource/Classes/FoaPushY.schelp deleted file mode 100644 index 25ca8a7ec2..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaPushY.schelp +++ /dev/null @@ -1,40 +0,0 @@ -CLASS:: FoaPushY -summary:: First Order Ambisonic (FOA) push transformer -categories:: Libraries>Ambisonic Toolkit>FOA>Transforming>UGens, UGens>Multichannel>Ambisonics, UGens>Multichannel>Panners -related:: Classes/FoaPushX, Classes/FoaPushZ, Classes/FoaPush, Classes/FoaTransform, Classes/FoaXform - -DESCRIPTION:: -Apply push to a first order ambisonic signal (B-format) along the y-axis. - - -NOTE:: -link::Classes/FoaPushY:: is usually called via the convenience wrapper link::Classes/FoaTransform::. -:: - - - -CLASSMETHODS:: - -METHOD:: ar - -argument:: in -The B-format signal, an array: [w, x, y, z] - -argument:: angle -The distortion angle, in radians. -pi/2 to pi/2 - -argument:: mul -Output will be multiplied by this value. - -argument:: add -This value will be added to the output. - -discussion:: Push is a dominance related transform, specified in terms of a distortion angle. Positive values of strong::angle:: push the image towards code:: [pi/2, 0] ::. Negative values push towards code:: [-pi/2, 0] ::. The default, 0, results in no change. - - -note:: Corresponding matrix transformer: link::Classes/FoaXformerMatrix#*newPushY:: :: - - -EXAMPLES:: - -Please see various examples link::Classes/FoaTransform#examples#here::. \ No newline at end of file diff --git a/source/ATK/sc/HelpSource/Classes/FoaPushZ.schelp b/source/ATK/sc/HelpSource/Classes/FoaPushZ.schelp deleted file mode 100644 index c9c7de2c1a..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaPushZ.schelp +++ /dev/null @@ -1,40 +0,0 @@ -CLASS:: FoaPushZ -summary:: First Order Ambisonic (FOA) push transformer -categories:: Libraries>Ambisonic Toolkit>FOA>Transforming>UGens, UGens>Multichannel>Ambisonics, UGens>Multichannel>Panners -related:: Classes/FoaPushX, Classes/FoaPushY, Classes/FoaPush, Classes/FoaTransform, Classes/FoaXform - -DESCRIPTION:: -Apply push to a first order ambisonic signal (B-format) along the z-axis. - - -NOTE:: -link::Classes/FoaPushZ:: is usually called via the convenience wrapper link::Classes/FoaTransform::. -:: - - - -CLASSMETHODS:: - -METHOD:: ar - -argument:: in -The B-format signal, an array: [w, x, y, z] - -argument:: angle -The distortion angle, in radians. -pi/2 to pi/2 - -argument:: mul -Output will be multiplied by this value. - -argument:: add -This value will be added to the output. - -discussion:: Push is a dominance related transform, specified in terms of a distortion angle. Positive values of strong::angle:: push the image towards code:: [0, pi/2] ::. Negative values push towards code:: [0, -pi/2] ::. The default, 0, results in no change. - - -note:: Corresponding matrix transformer: link::Classes/FoaXformerMatrix#*newPushZ:: :: - - -EXAMPLES:: - -Please see various examples link::Classes/FoaTransform#examples#here::. \ No newline at end of file diff --git a/source/ATK/sc/HelpSource/Classes/FoaRTT.schelp b/source/ATK/sc/HelpSource/Classes/FoaRTT.schelp deleted file mode 100644 index 0ee74bfba0..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaRTT.schelp +++ /dev/null @@ -1,51 +0,0 @@ -CLASS:: FoaRTT -summary:: First Order Ambisonic (FOA) multi-axes rotation transformer -categories:: Libraries>Ambisonic Toolkit>FOA>Transforming>UGens, UGens>Multichannel>Ambisonics, UGens>Multichannel>Panners -related:: Classes/FoaRotate, Classes/FoaTilt, Classes/FoaTumble, Classes/FoaTransform, Classes/FoaXform, Classes/Rotate2 - -DESCRIPTION:: -Rotate a first order ambisonic signal (B-format) around the z, x and y axes. - - -The inbuilt equivalent is link::Classes/Rotate2::. - - - -NOTE:: -link::Classes/FoaRTT:: is usually called via the convenience wrapper link::Classes/FoaTransform::. -:: - - -CLASSMETHODS:: - -METHOD:: ar - -argument:: in -The B-format signal, an array: [w, x, y, z] - -argument:: rotAngle -Rotation angle around z-axis, in radians. - -argument:: tilAngle -Rotation angle around x-axis, in radians. - -argument:: tumAngle -Rotation angle around y-axis, in radians. - - -argument:: mul -Output will be multiplied by this value. - -argument:: add -This value will be added to the output. - - -discussion:: - -link::Classes/FoaRotate##Rotate:: is followed by link::Classes/FoaTilt##tilt:: and then link::Classes/FoaTumble##tumble::. - -note:: Corresponding matrix transformer: link::Classes/FoaXformerMatrix#*newRTT:: :: - -EXAMPLES:: - -Please see various examples link::Classes/FoaTransform#examples#here::. \ No newline at end of file diff --git a/source/ATK/sc/HelpSource/Classes/FoaRotate.schelp b/source/ATK/sc/HelpSource/Classes/FoaRotate.schelp deleted file mode 100644 index 2120a94a71..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaRotate.schelp +++ /dev/null @@ -1,43 +0,0 @@ -CLASS:: FoaRotate -summary:: First Order Ambisonic (FOA) rotation transformer -categories:: Libraries>Ambisonic Toolkit>FOA>Transforming>UGens, UGens>Multichannel>Ambisonics, UGens>Multichannel>Panners -related:: Classes/FoaTilt, Classes/FoaTumble, Classes/FoaRTT, Classes/FoaTransform, Classes/FoaXform, Classes/Rotate2 - -DESCRIPTION:: -Rotate a first order ambisonic signal (B-format) around the z-axis. - - -The inbuilt equivalent is link::Classes/Rotate2::. - - -NOTE:: -link::Classes/FoaRotate:: is usually called via the convenience wrapper link::Classes/FoaTransform::. -:: - - -CLASSMETHODS:: - -METHOD:: ar - -argument:: in -The B-format signal, an array: [w, x, y, z] - -argument:: angle -Rotation angle, in radians. - -argument:: mul -Output will be multiplied by this value. - -argument:: add -This value will be added to the output. - -discussion:: -A rotation of pi/2 will rotate a source at code:: [0, 0] :: to code:: [pi/2, 0] ::. - -note:: Corresponding matrix transformer: link::Classes/FoaXformerMatrix#*newRotate:: :: - - - -EXAMPLES:: - -Please see various examples link::Classes/FoaTransform#examples#here::. \ No newline at end of file diff --git a/source/ATK/sc/HelpSource/Classes/FoaSpeakerMatrix.schelp b/source/ATK/sc/HelpSource/Classes/FoaSpeakerMatrix.schelp deleted file mode 100644 index 0f5bfff907..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaSpeakerMatrix.schelp +++ /dev/null @@ -1,84 +0,0 @@ -CLASS:: FoaSpeakerMatrix -summary:: First Order Ambisonic (FOA) diametric decoder speaker matrices -categories:: Libraries>Ambisonic Toolkit>Internals -related:: Classes/FoaDecoderMatrix - -DESCRIPTION:: -Generates speaker matrices required by the Ambisonic Toolkit's first order diametric decoder, link::Classes/FoaDecoderMatrix#*newDiametric::. footnote:: link::Classes/FoaSpeakerMatrix:: is Heller's speaker matrix helper used to generate matricies for diamatric decoding. See: See: E. Benjamin, R. Lee, and A. Heller, "Is My Decoder Ambisonic?," in Proceedings of the 125th Audio Engineering Society Convention, San Francisco, 2008. :: - - -NOTE:: -In normal circumstances, the user will not call link::Classes/FoaSpeakerMatrix:: directly. -:: - - -CLASSMETHODS:: - -METHOD:: new - -argument:: directions - -An array of directions for half of the loudspeaker feeds for the desired decoder. Specify in radians. - -Rank 1 arrays return pantophonic, while rank 2 arrays return periphonic. E.g., -code:: -// 2D: -~directions = [ theta0, theta1, ... thetaN ]; -:: -code:: -// 3D: -~directions = [ [ theta0, phi0 ], [ theta1, phi1 ], ... [ thetaN, phiN ] ]; -:: - -argument:: k -The k factor of the decoder. May be specified as a float: 0.5 to 1.0. - - -METHOD:: newPositions - -argument:: positions -An array of positions for half of the loudspeaker feeds for the desired decoder. Specify in cartesian coordinates. - -code:: -// 2D: -~positions = [ [ x0, y0 ], [ x1, y1 ], ... [ xN, yN ] ]; -:: -code:: -// 3D: -~positions = [ [ x0, y0, z0 ], [ x1, y1, z1 ], ... [ xN, yN, zN ] ]; -:: - - -argument:: k -The k factor of the decoder. May be specified as a float: 0.5 to 1.0. - - - - - - -INSTANCEMETHODS:: - -private:: initDiametric, printOn - - -METHOD:: dim -Answers the number of decoder dimensions: 2D or 3D. - - -METHOD:: numChannels -Answers the number of loudspeaker feeds (output channels). - - -METHOD:: positions -Answers the position of loudspeaker feeds, in cartesian coordinates. - - - -METHOD:: matrix -Answers the speaker matrix - - -METHOD:: k -Answer strong::k:: - diff --git a/source/ATK/sc/HelpSource/Classes/FoaTilt.schelp b/source/ATK/sc/HelpSource/Classes/FoaTilt.schelp deleted file mode 100644 index d2abffb402..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaTilt.schelp +++ /dev/null @@ -1,44 +0,0 @@ -CLASS:: FoaTilt -summary:: First Order Ambisonic (FOA) rotation transformer -categories:: Libraries>Ambisonic Toolkit>FOA>Transforming>UGens, UGens>Multichannel>Ambisonics, UGens>Multichannel>Panners -related:: Classes/FoaRotate, Classes/FoaTumble, Classes/FoaRTT, Classes/FoaTransform, Classes/FoaXform, Classes/Rotate2 - -DESCRIPTION:: -Rotate a first order ambisonic signal (B-format) around the x-axis. - - -The inbuilt equivalent is link::Classes/Rotate2::. - - - -NOTE:: -link::Classes/FoaTilt:: is usually called via the convenience wrapper link::Classes/FoaTransform::. -:: - - -CLASSMETHODS:: - -METHOD:: ar - -argument:: in -The B-format signal, an array: [w, x, y, z] - -argument:: angle -Rotation angle, in radians. - -argument:: mul -Output will be multiplied by this value. - -argument:: add -This value will be added to the output. - -discussion:: -A rotation of pi/2 will rotate a source at code:: [pi/2, 0] :: to code:: [0, pi/2] ::. - -note:: Corresponding matrix transformer: link::Classes/FoaXformerMatrix#*newTilt:: :: - - - -EXAMPLES:: - -Please see various examples link::Classes/FoaTransform#examples#here::. \ No newline at end of file diff --git a/source/ATK/sc/HelpSource/Classes/FoaTransform.schelp b/source/ATK/sc/HelpSource/Classes/FoaTransform.schelp deleted file mode 100644 index e5439f10a1..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaTransform.schelp +++ /dev/null @@ -1,884 +0,0 @@ -CLASS:: FoaTransform -summary:: First Order Ambisonic (FOA) transformer -categories:: Libraries>Ambisonic Toolkit>FOA>Transforming, UGens>Multichannel>Ambisonics -related:: Classes/FoaXform - -DESCRIPTION:: -Transforms (spatial domain filter) a first order ambisonic signal (B-format). link::Classes/FoaTransform:: applies dynamic transforms, for static transforms see link::Classes/FoaXform::. - - - -NOTE:: -link::Classes/FoaTransform:: is a convenience wrapper around the various transformer UGens. -:: - - -CLASSMETHODS:: - -METHOD:: ar - -argument:: in -The input signal, an array: [in0, in1, ... inN] - -argument:: kind -The kind of transform to apply. -anchor::transforms:: - - -definitionList:: -## code:: 'rtt' rotAngle = 0, tilAngle = 0, tumAngle = 0, mul = 1, add = 0 :: || link::Classes/FoaRTT:: -## code:: 'mirror' theta = 0, phi = 0, mul = 1, add = 0 :: || link::Classes/FoaMirror:: -## code:: 'directO' angle = 0, mul = 1, add = 0 :: || link::Classes/FoaDirectO:: -## code:: 'direct' angle = 0, theta = 0, phi = 0, mul = 1, add = 0 :: || link::Classes/FoaDirect:: -## code:: 'dominate' gain = 0, theta = 0, phi = 0, mul = 1, add = 0 :: || link::Classes/FoaDominate:: -## code:: 'zoom' angle = 0, theta = 0, phi = 0, mul = 1, add = 0 :: || link::Classes/FoaZoom:: -## code:: 'focus' angle = 0, theta = 0, phi = 0, mul = 1, add = 0 :: || link::Classes/FoaFocus:: -## code:: 'push' angle = 0, theta = 0, phi = 0, mul = 1, add = 0 :: || link::Classes/FoaPush:: -## code:: 'press' angle = 0, theta = 0, phi = 0, mul = 1, add = 0 :: || link::Classes/FoaPress:: -## code:: 'asymmetry' angle = 0, mul = 1, add = 0 :: || link::Classes/FoaAsymmetry:: -## code:: 'balance' angle = 0, mul = 1, add = 0 :: || link::Classes/FoaBalance:: -## code:: 'nfc' distance = 1, mul = 1, add = 0 :: || link::Classes/FoaNFC:: -## code:: 'proximity' distance = 1, mul = 1, add = 0 :: || link::Classes/FoaProximity:: -:: - - -note:: strong:: Axial transforms - except as noted, all take args of angle = 0, mul = 1, add = 0 as defaults:: - -definitionList:: -## code:: 'rotate' :: || link::Classes/FoaRotate:: -## code:: 'tilt' :: || link::Classes/FoaTilt:: -## code:: 'tumble' :: || link::Classes/FoaTumble:: -## code:: 'directX' :: || link::Classes/FoaDirectX:: -## code:: 'directY' :: || link::Classes/FoaDirectY:: -## code:: 'directZ' :: || link::Classes/FoaDirectZ:: -## code:: 'dominateX' gain = 0, mul = 1, add = 0 :: || link::Classes/FoaDominateX:: -## code:: 'dominateY' gain = 0, mul = 1, add = 0 :: || link::Classes/FoaDominateY:: -## code:: 'dominateZ' gain = 0, mul = 1, add = 0 :: || link::Classes/FoaDominateZ:: -## code:: 'zoomX' :: || link::Classes/FoaZoomX:: -## code:: 'zoomY' :: || link::Classes/FoaZoomY:: -## code:: 'zoomZ' :: || link::Classes/FoaZoomZ:: -## code:: 'focusX' :: || link::Classes/FoaFocusX:: -## code:: 'focusY' :: || link::Classes/FoaFocusY:: -## code:: 'focusZ' :: || link::Classes/FoaFocusZ:: -## code:: 'pushX' :: || link::Classes/FoaPushX:: -## code:: 'pushY' :: || link::Classes/FoaPushY:: -## code:: 'pushZ' :: || link::Classes/FoaPushZ:: -## code:: 'pressX' :: || link::Classes/FoaPressX:: -## code:: 'pressY' :: || link::Classes/FoaPressY:: -## code:: 'pressZ' :: || link::Classes/FoaPressZ:: -:: - -:: - - -argument:: ... args -Arguments (listed above with each 'kind') for the wrapped transformer UGens. Arguments can NOT be passed in through keyword through the FoaTransform wrapper. You can pass values in by keyword if you use the transform UGens directly. - - - -EXAMPLES:: - -The examples below are intended to briefly illustrate some of the first order tranform options made available in the Ambisonic Toolkit. The user is encouraged to carefully review the features of the individual link::#transforms:: to gain a deeper understanding of the flexibility of these tools. - -Available transformers include rotations, mirroring, directivity (spatial low pass fitering), dominance (image warping), and a variety of dominance related transforms. - -As the Ambisonic technique is a hierarchal system, numerous options for playback are possible. These include two channel stereo, two channel binaural, pantophonic and full 3D periphonic. With the examples below, we'll take advantage of this by first choosing a suitable decoder with with to audition. - -subsection:: Choose a decoder - -Choose a decoder suitable for your system, as illustrated link::Guides/Intro-to-the-ATK#Choose a decoder#here::. You'll end up definining code:: ~decoder :: and code:: ~renderDecode :: . - -note:: If you choose a kernel decoder, link::Classes/FoaDecoderKernel::, be sure to free the kernel after use. :: - - -subsection:: Rotate (soundfile) - -Rotation is one of the most used soundfield transforms. In this case we'll it to centre the subject of a field recording. - -The soundfield is controlled by link::Classes/MouseX::, which specifies the rotation angle (pi to -pi; left to right of display). - -If you haven't already choosen a code:: ~decoder:: and defined code:: ~renderDecode ::, do so link::#Choose a decoder#now::. - -note:: A UGen type transformer, see link::Classes/FoaRotate:: for further details.:: - -code:: -// ------------------------------------------------------------ -// rotate transformer -// b-format soundfile read from disk - -// choose transformer -~transformer = 'rotate' - - - -// read a whole sound into memory -// remember to free the buffer later! -// (boot the server, if you haven't!) -~sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/b-format/Courville-Dialogue.wav") -~sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/b-format/Hodges-Purcell.wav") -~sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/b-format/Leonard-Orfeo_Trio.wav") - - -( -{ - var sig; // audio signal - var azim; // azimuth control - - - // display transformer & decoder - "Ambisonic transforming via % transformer".format(~transformer).postln; - "Ambisonic decoding via % decoder".format(~decoder.kind).postln; - - // azimuth -> hard left = back - // centre = centre - // hard right = back - azim = MouseX.kr(pi, -pi); - - - // ------------------------------------------------------------ - // test sig - sig = PlayBuf.ar(~sndbuf.numChannels, ~sndbuf, BufRateScale.kr(~sndbuf), doneAction:2); // soundfile - - // ------------------------------------------------------------ - // transform - sig = FoaTransform.ar(sig, ~transformer, azim); - - - // ------------------------------------------------------------ - // decode (via ~renderDecode) - ~renderDecode.value(sig, ~decoder) - -}.scope; -) - -// free buffer -~sndbuf.free -// ------------------------------------------------------------ -:: - -note:: strong::Soundfile Credits:: - -list:: -## D. Courville, "Comparative Surround Recording," Ambisonic Studio | Comparative Surround Recording, 2007. [Online]. Available: http://www.radio.uqam.ca/ambisonic/comparative_recording.html [Accessed: 26-Jul-2011]. -## P. Hodges, "Purcell - Passacaglia (King Arthur)," Sound of Space: ambisonic surround sound. [Online]. Available: http://soundofspace.com/ambisonic_files/52 [Accessed: 03-Nov-2011]. -## J. Leonard, "The Orfeo Trio & TetraMic," Sound of Space: ambisonic surround sound. [Online]. Available: http://soundofspace.com/ambisonic_files/41 [Accessed: 03-Nov-2011]. - -:: - -:: - - - -subsection:: DominateX (soundfile) - -Dominance specified in gain is a classic Ambisonic production technique. Here we apply gain across the X axis. With these example recordings, we adjust both the stage width and the subject to reverb balance. - -The soundfield is controlled by link::Classes/MouseY::, which specifies the dominance gain (4.5 dB to -4.5 dB; top to bottom of display). - -If you haven't already choosen a code:: ~decoder:: and defined code:: ~renderDecode ::, do so link::#Choose a decoder#now::. - -note:: A UGen type transformer, see link::Classes/FoaDominateX:: for further details.:: - -code:: -// ------------------------------------------------------------ -// dominateX transformer -// b-format soundfile read from disk - -// choose transformer -~transformer = 'dominateX' - - - -// read a whole sound into memory -// remember to free the buffer later! -// (boot the server, if you haven't!) -~sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/b-format/Courville-Dialogue.wav") -~sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/b-format/Hodges-Purcell.wav") -~sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/b-format/Leonard-Orfeo_Trio.wav") - - -( -{ - var sig; // audio signal - var gain; // gain control - - - // display transformer & decoder - "Ambisonic transforming via % transformer".format(~transformer).postln; - "Ambisonic decoding via % decoder".format(~decoder.kind).postln; - - // gain ---> top = +4.5db for front - // bottom = -4.5db for front - gain = MouseY.kr(4.5, 4.5.neg); - - - // ------------------------------------------------------------ - // test sig - sig = PlayBuf.ar(~sndbuf.numChannels, ~sndbuf, BufRateScale.kr(~sndbuf), doneAction:2); // soundfile - - // ------------------------------------------------------------ - // transform - sig = FoaTransform.ar(sig, ~transformer, gain); - - - // ------------------------------------------------------------ - // decode (via ~renderDecode) - ~renderDecode.value(sig, ~decoder) - -}.scope; -) - -// free buffer -~sndbuf.free -// ------------------------------------------------------------ -:: - -note:: strong::Soundfile Credits:: - -list:: -## D. Courville, "Comparative Surround Recording," Ambisonic Studio | Comparative Surround Recording, 2007. [Online]. Available: http://www.radio.uqam.ca/ambisonic/comparative_recording.html [Accessed: 26-Jul-2011]. -## P. Hodges, "Purcell - Passacaglia (King Arthur)," Sound of Space: ambisonic surround sound. [Online]. Available: http://soundofspace.com/ambisonic_files/52 [Accessed: 03-Nov-2011]. -## J. Leonard, "The Orfeo Trio & TetraMic," Sound of Space: ambisonic surround sound. [Online]. Available: http://soundofspace.com/ambisonic_files/41 [Accessed: 03-Nov-2011]. - -:: - -:: - - - - -subsection:: Focus - - -Here we encode four channels of decorrelated and comb filtered link::Classes/PinkNoise:: as a decorrelated soundfield, resulting in a maximally diffuse soundfield. link::Classes/FoaFocus:: is used to "focus" on various parts of the soundfield. At extremes, it becomes a planewave (infinite distance, in an anechoic environment) arriving from some direction. This technique gives the opportunity to continuously modulate between a directional and a diffuse soundfield. - -The soundfield is controlled by link::Classes/MouseX:: and link::Classes/MouseY::, where link::Classes/MouseX:: specifies the incident azimuth angle (pi to -pi; left to right of display) and link::Classes/MouseY:: the link::Classes/FoaFocus:: angle (0 to pi/2; bottom to top of display). With the mouse at the bottom of the display, the soundfield remains decorrelated. Placed at the top of the display, the soundfield becomes directional, and varying left/right position will vary the incident azimuth of the resulting planewave. - -If you haven't already choosen a code:: ~decoder:: and defined code:: ~renderDecode ::, do so link::#Choose a decoder#now::. - -note:: A UGen type transformer, see link::Classes/FoaFocus:: for further details.:: - - -code:: -// ------------------------------------------------------------ -// focus transformer -// decorrelated, comb filtered pink noise source - - -// define encoder matrix -~encoder = FoaEncoderMatrix.newAtoB - -// choose transformer -~transformer = 'focus' - -( -{ - var sig; // audio signal - var angle, azim; // angle and azimuth control - var freq; - - - // display encoder and decoder - "Ambisonic encoding via % encoder".format(~encoder.kind).postln; - "Ambisonic transforming via % transformer".format(~transformer).postln; - "Ambisonic decoding via % decoder".format(~decoder.kind).postln; - - // frequencies - freq = 220; - - // angle ---> top = push to plane wave - // bottom = omni-directional - angle = MouseY.kr(pi/2, 0); - - // azimuth -> hard left = back - // centre = centre - // hard right = back - azim = MouseX.kr(pi, -pi); - - - // ------------------------------------------------------------ - // test sig - sig = PinkNoise.ar([1, 1, 1, 1]); // 4 channels decorrelated pink noise - - // ------------------------------------------------------------ - // comb filter - sig = HPF.ar(sig, freq); - sig = CombL.ar(sig, freq.reciprocal, freq.reciprocal, mul: 9.neg.dbamp); - - - // ------------------------------------------------------------ - // encode - sig = FoaEncode.ar(sig, ~encoder); - - // ------------------------------------------------------------ - // transform - sig = FoaTransform.ar(sig, ~transformer, angle, azim); - - - - // ------------------------------------------------------------ - // decode (via ~renderDecode) - ~renderDecode.value(sig, ~decoder) - -}.scope; -) -// ------------------------------------------------------------ -:: - - -subsection:: Push and RTT - - - -Here we encode four channels of link::Classes/Klank:: resonated link::Classes/Dust:: from A-format. link::Classes/FoaPush:: is used to "push" the soundfield so that it becomes a planewave (infinite distance, in an anechoic environment) arriving from some direction. This technique gives the opportunity to continuously modulate between a directional and a spatially active soundfield. Additionally, link::Classes/FoaRTT:: is used to continuously reorient the granular stream so that individual A-format directions don't predominate, and the complete soundfield is filled with activity. - -The soundfield is controlled by link::Classes/MouseX:: and link::Classes/MouseY::, where link::Classes/MouseX:: specifies the incident azimuth angle (pi to -pi; left to right of display) and link::Classes/MouseY:: the link::Classes/FoaPush:: angle (0 to pi/2; bottom to top of display). With the mouse at the bottom of the display, the soundfield remains decorrelated. Placed at the top of the display, the soundfield becomes directional, and varying left/right position will vary the incident azimuth of the resulting planewave. - -If you haven't already choosen a code:: ~decoder:: and defined code:: ~renderDecode ::, do so link::#Choose a decoder#now::. - -note:: UGen type transformers, see link::Classes/FoaPush:: and link::Classes/FoaRTT:: for further details.:: - - -code:: -// ------------------------------------------------------------ -// push and rtt transformer -// granular klank stream source - - -// define encoder matrix -~encoder = FoaEncoderMatrix.newAtoB - -// choose transformer -~transformer1 = 'rtt' -~transformer2 = 'push' - -( -{ - var sig; // audio signal - var angle, azim; // angle and azimuth control - var freq; - - // ir... - var gain = -18; - - var freqs = [50.0, 7000.0], gains = [-24, 0], rtimes = [0.1, 2.0]; - var frequencies, amplitudes, ringTimes; - var numModes = 20; - - var density = 20; // grain/klank density - - var rttFreq = 10 * density; - - - // display encoder and decoder - "Ambisonic encoding via % encoder".format(~encoder.kind).postln; - "Ambisonic transforming via % transformer".format(~transformer1).postln; - "Ambisonic transforming via % transformer".format(~transformer2).postln; - "Ambisonic decoding via % decoder".format(~decoder.kind).postln; - - - // calculate klank args - frequencies = Array.rand(numModes, freqs.at(0), freqs.at(1)).sort; - amplitudes = Array.rand(numModes, gains.at(0), gains.at(1)).sort.reverse.dbamp; - ringTimes = Array.rand(numModes, rtimes.at(0), rtimes.at(1)).sort.reverse; - - - // angle ---> top = push to plane wave - // bottom = omni-directional - angle = MouseY.kr(pi/2, 0); - - // azimuth -> hard left = back - // centre = centre - // hard right = back - azim = MouseX.kr(pi, -pi); - - - // ------------------------------------------------------------ - // test sig - sig = Dust.ar(Array.fill(4, density / 4)); - - // ------------------------------------------------------------ - // encode - sig = FoaEncode.ar(sig, ~encoder); - - // ------------------------------------------------------------ - // transform 1 (rtt) - sig = FoaTransform.ar( - sig, - ~transformer1, - LFSaw.ar(rttFreq, pi, add: pi), - LFSaw.ar(rttFreq**(1/3), pi, add: pi), - LFSaw.ar(rttFreq**(2/3), pi, add: pi) - ); - - - // ------------------------------------------------------------ - // Klank - sig = gain.dbamp * Klank.ar( - `[ frequencies, amplitudes, ringTimes ], - sig - ); - - - // ------------------------------------------------------------ - // transform 2 (push) - sig = FoaTransform.ar(sig, ~transformer2, angle, azim); - - - - // ------------------------------------------------------------ - // decode (via ~renderDecode) - ~renderDecode.value(sig, ~decoder) - -}.scope; -) -// ------------------------------------------------------------ -:: - - - -subsection:: Push and RTT with Spread Encoder (soundfile) - - -Here we encode the mono component of a stereo soundfile via the link::Classes/FoaEncoderKernel#*newSpread:: encoder. link::Classes/FoaPush:: is used to "push" the soundfield so that it becomes a planewave (infinite distance, in an anechoic environment) arriving from some direction. This technique gives the opportunity to continuously modulate between a directional and a spatially spread soundfield. Additionally, link::Classes/FoaRTT:: is used to continuously reorient the frequency spread soundfield so that individual frequencies are moved throughout the space, and the complete soundfield is constantly in motion. - -The soundfield is controlled by link::Classes/MouseX:: and link::Classes/MouseY::, where link::Classes/MouseX:: specifies the incident azimuth angle (pi to -pi; left to right of display) and link::Classes/MouseY:: the link::Classes/FoaPush:: angle (0 to pi/2; bottom to top of display). With the mouse at the bottom of the display, the soundfield remains decorrelated. Placed at the top of the display, the soundfield becomes directional, and varying left/right position will vary the incident azimuth of the resulting planewave. - -If you haven't already choosen a code:: ~decoder:: and defined code:: ~renderDecode ::, do so link::#Choose a decoder#now::. - -note:: UGen type transformers, see link::Classes/FoaPush::, link::Classes/FoaRTT:: and link::Classes/FoaEncoderKernel#*newSpread:: for further details.:: - - -code:: -// ------------------------------------------------------------ -// push and rtt transformer -// spreader encoder -// stereo soundfile read from disk - - -// define encoder matrix -~encoder = FoaEncoderKernel.newSpread(0000) -~encoder = FoaEncoderKernel.newSpread(0001) -~encoder = FoaEncoderKernel.newSpread(0006) -~encoder = FoaEncoderKernel.newSpread(0008) -~encoder = FoaEncoderKernel.newSpread(0010) -~encoder = FoaEncoderKernel.newSpread(0012) - -// free kernel (when you swap encoders!) -~encoder.free - -// inspect -~encoder -~encoder.kind -~encoder.numChannels -~encoder.dirChannels.raddeg - - -// read a whole sound into memory -// remember to free the buffer later! -// (boot the server, if you haven't!) -~sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/stereo/The_City_Waites-The_Downfall.wav") -~sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/stereo/The_City_Waites-An_Old.wav") -~sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/stereo/Aurora_Surgit-Lux_Aeterna.wav") -~sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/stereo/Aurora_Surgit-Dies_Irae.wav") - -// free buffer (when you swap buffers!) -~sndbuf.free - - -( -{ - var sig; // audio signal - var angle, azim; // angle and azimuth control - - - // display encoder and decoder - "Ambisonic encoding via % encoder".format(~encoder.kind).postln; - "Ambisonic decoding via % decoder".format(~decoder.kind).postln; - - // angle ---> top = push to plane wave - // bottom = omni-directional - angle = MouseY.kr(pi/2, 0); - - // azimuth -> hard left = back - // centre = centre - // hard right = back - azim = MouseX.kr(pi, -pi); - - // ------------------------------------------------------------ - // test sig - sig = PlayBuf.ar(~sndbuf.numChannels, ~sndbuf, BufRateScale.kr(~sndbuf), doneAction:2); // soundfile - sig = 0.5 * sig.sum; // to mono - - - // ------------------------------------------------------------ - // encode - sig = FoaEncode.ar(sig, ~encoder); - - // ------------------------------------------------------------ - // transform - sig = FoaRTT.ar(sig, - LFNoise2.kr(1.0/5.0, pi), - LFNoise2.kr(1.0/5.0, pi), - LFNoise2.kr(1.0/5.0, pi) - ); - sig = FoaTransform.ar(sig, 'push', angle, azim); - - - - // ------------------------------------------------------------ - // decode (via ~renderDecode) - ~renderDecode.value(sig, ~decoder) - -}.scope; -) - -// free buffer -~sndbuf.free -// free kernel -~encoder.free -// ------------------------------------------------------------ -:: - - - - -subsection:: X-axis: FocusX, ZoomX & PushX - - -With this example we encode four channels of comb filtered link::Classes/Dust:: as planewaves arriving from the cardinal directions. link::Classes/FoaFocusX::, link::Classes/FoaZoomX:: and link::Classes/FoaPushX:: are used to distort the soundfield. At extremes, encoded planewaves are distorted to arrive from the same direction. This example allows one to get compare these transforms on the x-axis. - -The soundfield is controlled by link::Classes/MouseY::, with strong::angle:: varying between -pi/2 and pi/2. With the mouse in the centre of the display, the soundfield remains unchanged. Placed at the top or bottom of the display, the soundfield is distorted. - -If you haven't already choosen a code:: ~decoder:: and defined code:: ~renderDecode ::, do so link::#Choose a decoder#now::. - -note:: UGen type transformers, see link::Classes/FoaFocusX::, link::Classes/FoaZoomX:: & link::Classes/FoaPushX:: for further details.:: - - -code:: -// ------------------------------------------------------------ -// x-axis transformers -// comb filtered dust noise source, at cardinal points - - -// define encoder matricies, for each cardinal point -( -~encoder = [ - FoaEncoderMatrix.newDirection, - FoaEncoderMatrix.newDirection(pi/2), - FoaEncoderMatrix.newDirection(pi), - FoaEncoderMatrix.newDirection(pi.neg/2) -] -) - -// choose transformer -~transformer = 'focusX' -~transformer = 'zoomX' -~transformer = 'pushX' - -( -{ - var sig; // audio signal - var angle; // angle control - var freq; - var density = 10; // grain density - - - // display encoder and decoder - "Ambisonic encoding via % encoder".format(~encoder.at(0).kind).postln; - "Ambisonic transforming via % transformer".format(~transformer).postln; - "Ambisonic decoding via % decoder".format(~decoder.kind).postln; - - // frequencies - freq = 220 * [ 4, 5, 7, 6 ] / 4; - - // angle ---> top = pi/2 - // bottom = -pi/2 - angle = MouseY.kr(pi/2, pi.neg/2); - - - // ------------------------------------------------------------ - // test sig - sig = Dust.ar(Array.fill(4, density / 4)); - - - // ------------------------------------------------------------ - // comb filter - sig = BPF.ar(sig, freq, mul: 18.dbamp); - sig = CombL.ar(sig, freq.reciprocal, freq.reciprocal, mul: 9.neg.dbamp); - - - // ------------------------------------------------------------ - // encode - sig = Mix.fill(sig.numChannels, { arg i; FoaEncode.ar(sig.at(i), ~encoder.at(i)) }); - - - // ------------------------------------------------------------ - // transform - sig = FoaTransform.ar(sig, ~transformer, angle); - - - - // ------------------------------------------------------------ - // decode (via ~renderDecode) - ~renderDecode.value(sig, ~decoder) - -}.scope; -) -// ------------------------------------------------------------ -:: - - -subsection:: Y-axis: Balance and Asymmetry - - -With with the link::#x-axis:_focusx,_zoomx_&_pushx#above example:: we encode four channels of comb filtered link::Classes/Dust:: as planewaves arriving from the cardinal directions. link::Classes/FoaZoomY:: and link::Classes/FoaAsymmetry:: are used to distort the soundfield. At extremes, encoded planewaves are distorted to arrive from the same direction. This example allows one to get compare these transforms on the x-axis. - -The soundfield is controlled by link::Classes/MouseX::, with strong::angle:: varying between -pi/2 and pi/2. With the mouse in the centre of the display, the soundfield remains unchanged. Placed at the left or right of the display, the soundfield is distorted. - - -If you haven't already choosen a code:: ~decoder:: and defined code:: ~renderDecode ::, do so link::#Choose a decoder#now::. - -note:: UGen type transformers, see link::Classes/FoaZoomY:: and link::Classes/FoaAsymmetry:: for further details.:: - - -code:: -// ------------------------------------------------------------ -// y-axis transformers -// comb filtered dust noise source, at cardinal points - - -// define encoder matricies, for each cardinal point -( -~encoder = [ - FoaEncoderMatrix.newDirection, - FoaEncoderMatrix.newDirection(pi/2), - FoaEncoderMatrix.newDirection(pi), - FoaEncoderMatrix.newDirection(pi.neg/2) -] -) - -// choose transformer -~transformer = 'balance' -~transformer = 'asymmetry' - -( -{ - var sig; // audio signal - var angle; // angle control - var freq; - var density = 10; // grain density - - - // display encoder and decoder - "Ambisonic encoding via % encoder".format(~encoder.at(0).kind).postln; - "Ambisonic transforming via % transformer".format(~transformer).postln; - "Ambisonic decoding via % decoder".format(~decoder.kind).postln; - - // frequencies - freq = 220 * [ 4, 5, 7, 6 ] / 4; - - // angle ---> left = pi/2 - // right = -pi/2 - angle = MouseX.kr(pi/2, pi.neg/2); - - - // ------------------------------------------------------------ - // test sig - sig = Dust.ar(Array.fill(4, density / 4)); - - - // ------------------------------------------------------------ - // comb filter - sig = BPF.ar(sig, freq, mul: 18.dbamp); - sig = CombL.ar(sig, freq.reciprocal, freq.reciprocal, mul: 9.neg.dbamp); - - - // ------------------------------------------------------------ - // encode - sig = Mix.fill(sig.numChannels, { arg i; FoaEncode.ar(sig.at(i), ~encoder.at(i)) }); - - - // ------------------------------------------------------------ - // transform - sig = FoaTransform.ar(sig, ~transformer, angle); - - - - // ------------------------------------------------------------ - // decode (via ~renderDecode) - ~renderDecode.value(sig, ~decoder) - -}.scope; -) -// ------------------------------------------------------------ -:: - - - -subsection:: Proximity - -link::Classes/FoaProximity:: facilitates the introduction of the link::http://en.wikipedia.org/wiki/Proximity_effect_(audio)##proximity effect:: to encoded signals. At extremes, the proximity effect introduces a strong bass boost, as well as phase differences. The link::http://en.wikipedia.org/wiki/Proximity_effect_(audio)##proximity effect:: can be an important contributor to perceptions of nearness. - - -The soundfield is controlled by link::Classes/MouseY::, with strong::distance:: varying between 0.05 and 0.5 meter. With the mouse at the bottom of the display, the soundfield receives the strongest effect, contributing to as sense of nearness. - - -warning:: As link::Classes/FoaProximity:: includes a 1st-order integration, signals must be highpass filtered before application. link::Classes/HPF:: is usually a suitable choice to control low frequency boost.:: - -If you haven't already choosen a code:: ~decoder:: and defined code:: ~renderDecode ::, do so link::#Choose a decoder#now::. - -note:: UGen type transformer, see link::Classes/FoaProximity:: for further details.:: - - -code:: -// ------------------------------------------------------------ -// proximity transform -// comb filtered dust noise source, panned across the front - - -// define encoder matricies -( -~encoder = [ - FoaEncoderMatrix.newDirection(pi/6), - FoaEncoderMatrix.newDirection(pi/12), - FoaEncoderMatrix.newDirection(pi.neg/12), - FoaEncoderMatrix.newDirection(pi.neg/6) -] -) - -// choose transformer -~transformer = 'proximity' - -( -{ - var sig; // audio signal - var dist; // distance control - var freq; - var density = 10; // grain density - - - // display encoder and decoder - "Ambisonic encoding via % encoder".format(~encoder.at(0).kind).postln; - "Ambisonic transforming via % transformer".format(~transformer).postln; - "Ambisonic decoding via % decoder".format(~decoder.kind).postln; - - // frequencies - freq = 220 * [ 4, 5, 7, 6 ] / 4; - - // dist ---> top = 0.5 - // bottom = 0.05 - dist = MouseY.kr(0.5, 0.05); - - - // ------------------------------------------------------------ - // test sig - sig = Dust.ar(Array.fill(4, density / 4)); - - - // ------------------------------------------------------------ - // comb filter - sig = BPF.ar(sig, freq, mul: 18.dbamp); - sig = CombL.ar(sig, freq.reciprocal, freq.reciprocal, mul: 9.neg.dbamp); - - - // ------------------------------------------------------------ - // encode - sig = Mix.fill(sig.numChannels, { arg i; FoaEncode.ar(sig.at(i), ~encoder.at(i)) }); - - - // ------------------------------------------------------------ - // transform - sig = FoaTransform.ar(sig, ~transformer, dist); - - - - // ------------------------------------------------------------ - // decode (via ~renderDecode) - ~renderDecode.value(sig, ~decoder) - -}.scope; -) -// ------------------------------------------------------------ -:: - - - -subsection:: NFC (soundfile) - -link::Classes/FoaNFC:: facilitates the reduction or removal of the link::http://en.wikipedia.org/wiki/Proximity_effect_(audio)##proximity effect:: from encoded signals. The link::http://en.wikipedia.org/wiki/Proximity_effect_(audio)##proximity effect:: can be an important contributor to perceptions of nearness. - - -The soundfield is controlled by link::Classes/MouseY::, with strong::distance:: varying between 0.5 and 0.05 meter. With the mouse at the top of the display, the soundfield receives the strongest effect (removal), contributing to as sense of distance. - - -If you haven't already choosen a code:: ~decoder:: and defined code:: ~renderDecode ::, do so link::#Choose a decoder#now::. - -note:: UGen type transformer, see link::Classes/FoaNFC:: for further details.:: - - -code:: -// ------------------------------------------------------------ -// NFC transform -// b-format soundfile read from disk - - - - -// read a whole sound into memory -// remember to free the buffer later! -// (boot the server, if you haven't!) -~sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/b-format/Anderson-Nearfield.wav") - - -// choose transformer -~transformer = 'nfc' - - -( -{ - var sig; // audio signal - var dist; // distance control - - - - // display encoder and decoder - "Ambisonic transforming via % transformer".format(~transformer).postln; - "Ambisonic decoding via % decoder".format(~decoder.kind).postln; - - // dist ---> top = 0.05 - // bottom = 1.0 - dist = MouseY.kr(0.05, 1.0); - - - // ------------------------------------------------------------ - // test sig - sig = PlayBuf.ar(~sndbuf.numChannels, ~sndbuf, BufRateScale.kr(~sndbuf), doneAction:2); // soundfile - - - // ------------------------------------------------------------ - // transform - sig = FoaTransform.ar(sig, ~transformer, dist); - - - // ------------------------------------------------------------ - // decode (via ~renderDecode) - ~renderDecode.value(sig, ~decoder) - -}.scope; -) - -// free buffer -~sndbuf.free -// ------------------------------------------------------------ -:: - - - -note:: strong::Soundfile Credits:: - -list:: -## Joseph Anderson, "Nearfield source," [unpublished recording] -:: - -:: diff --git a/source/ATK/sc/HelpSource/Classes/FoaTumble.schelp b/source/ATK/sc/HelpSource/Classes/FoaTumble.schelp deleted file mode 100644 index e38f1915c9..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaTumble.schelp +++ /dev/null @@ -1,44 +0,0 @@ -CLASS:: FoaTumble -summary:: First Order Ambisonic (FOA) rotation transformer -categories:: Libraries>Ambisonic Toolkit>FOA>Transforming>UGens, UGens>Multichannel>Ambisonics, UGens>Multichannel>Panners -related:: Classes/FoaRotate, Classes/FoaTilt, Classes/FoaRTT, Classes/FoaTransform, Classes/FoaXform, Classes/Rotate2 - -DESCRIPTION:: -Rotate a first order ambisonic signal (B-format) around the y-axis. - - -The inbuilt equivalent is link::Classes/Rotate2::. - - - -NOTE:: -link::Classes/FoaTumble:: is usually called via the convenience wrapper link::Classes/FoaTransform::. -:: - - -CLASSMETHODS:: - -METHOD:: ar - -argument:: in -The B-format signal, an array: [w, x, y, z] - -argument:: angle -Rotation angle, in radians. - -argument:: mul -Output will be multiplied by this value. - -argument:: add -This value will be added to the output. - - -discussion:: -A rotation of pi/2 will rotate a source at code:: [0, 0] :: to code:: [0, pi/2] ::. - -note:: Corresponding matrix transformer: link::Classes/FoaXformerMatrix#*newTumble:: :: - - -EXAMPLES:: - -Please see various examples link::Classes/FoaTransform#examples#here::. \ No newline at end of file diff --git a/source/ATK/sc/HelpSource/Classes/FoaXform.schelp b/source/ATK/sc/HelpSource/Classes/FoaXform.schelp deleted file mode 100644 index 2059c81b11..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaXform.schelp +++ /dev/null @@ -1,274 +0,0 @@ -CLASS:: FoaXform -summary:: First Order Ambisonic (FOA) matrix transformer -categories:: Libraries>Ambisonic Toolkit>FOA>Transforming, UGens>Multichannel>Ambisonics -related:: Classes/FoaXformerMatrix, Classes/FoaTransform - -DESCRIPTION:: -Transforms (spatial domain filter) a first order ambisonic signal (B-format). link::Classes/FoaXform:: applies static transforms, for dynamic transforms see link::Classes/FoaTransform::. - - - -CLASSMETHODS:: - -METHOD:: ar - -argument:: in -The B-format signal, an array: [w, x, y, z] - -argument:: xformer -link::Classes/FoaXformerMatrix:: instance. - -argument:: mul -Output will be multiplied by this value. - -argument:: add -This value will be added to the output. - -returns:: -An array of channels, the transformed B-format signal. - - - -EXAMPLES:: - -The examples below are intended to briefly illustrate some of the first order tranform options made available in the Ambisonic Toolkit. The user is encouraged to carefully review the features of link::Classes/FoaXformerMatrix:: to gain a deeper understanding of the flexibility of these tools. - -Available transformers include rotations, mirroring, directivity (spatial low pass fitering), dominance (image warping), and a variety of dominance related transforms. - -As the Ambisonic technique is a hierarchal system, numerous options for playback are possible. These include two channel stereo, two channel binaural, pantophonic and full 3D periphonic. With the examples below, we'll take advantage of this by first choosing a suitable decoder with with to audition. - -subsection:: Choose a decoder - -Choose a decoder suitable for your system, as illustrated link::Guides/Intro-to-the-ATK#Choose a decoder#here::. You'll end up definining code:: ~decoder :: and code:: ~renderDecode :: . - -note:: If you choose a kernel decoder, link::Classes/FoaDecoderKernel::, be sure to free the kernel after use. :: - - -subsection:: Rotate - -Rotation is one of the most used soundfield transforms. In this case we'll it to centre the subject of a field recording. - -If you haven't already choose a code:: ~decoder:: and defined code:: ~renderDecode ::, do so link::#Choose a decoder#now::. - -note:: A matrix type transformer, see link::Classes/FoaXformerMatrix#*newRotate:: for further details.:: - -code:: -// ------------------------------------------------------------ -// rotate xformer -// b-format soundfile read from disk - - -// define xformer matrix -~xformer = FoaXformerMatrix.newRotate // no rotation --> try this 1st -~xformer = FoaXformerMatrix.newRotate(-110.degrad) // by -110deg --> try this 2nd - - -// inspect -~encoder.kind -~encoder.numChannels -~encoder.dirChannels.raddeg - - -// read a whole sound into memory -// remember to free the buffer later! -// (boot the server, if you haven't!) -~sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/b-format/Leonard-Chinook.wav") - - -( -{ - var sig; // audio signal - - - // display xformer & decoder - "Ambisonic transforming via % xformer".format(~xformer.kind).postln; - "Ambisonic decoding via % decoder".format(~decoder.kind).postln; - - // ------------------------------------------------------------ - // test sig - sig = PlayBuf.ar(~sndbuf.numChannels, ~sndbuf, BufRateScale.kr(~sndbuf), doneAction:2); // soundfile - - // ------------------------------------------------------------ - // transform - sig = FoaXform.ar(sig, ~xformer); - - - // ------------------------------------------------------------ - // decode (via ~renderDecode) - ~renderDecode.value(sig, ~decoder) - -}.scope; -) - -// free buffer -~sndbuf.free -// ------------------------------------------------------------ -:: - -note:: strong::Soundfile Credits:: - -list:: -## J. Leonard, "A couple of Chinook helicopters," Sound of Space: ambisonic surround sound, 20-Mar-2008. [Online]. Available: http://soundofspace.com/ambisonic_files/47 [Accessed: 03-Nov-2011]. - -:: - -:: - - -subsection:: MirrorO - -In mirroring through the origin and delaying the soundfield, we can generate a new set of echos in this fireworks field recording. - -If you haven't already choose a code:: ~decoder:: and defined code:: ~renderDecode ::, do so link::#Choose a decoder#now::. - -note:: A matrix type transformer, see link::Classes/FoaXformerMatrix#*newMirrorO:: for further details.:: - - -code:: -// ------------------------------------------------------------ -// mirrorO xformer -// b-format soundfile read from disk - - -// define xformer matrix -~xformer = FoaXformerMatrix.newMirrorO - - -// inspect -~encoder.kind -~encoder.numChannels -~encoder.dirChannels.raddeg - - -// read a whole sound into memory -// remember to free the buffer later! -// (boot the server, if you haven't!) -~sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/b-format/Leonard-Fireworks.wav") - - -( -{ - var sig; // audio signal - var delSig; // delayed signal - var freq; // lp frequency - var delay; // delay time - var scale; // delay gain (as scale) - - // display xformer & decoder - "Ambisonic transforming via % xformer".format(~xformer.kind).postln; - "Ambisonic decoding via % decoder".format(~decoder.kind).postln; - - // ------------------------------------------------------------ - // parameters - freq = 1200; // in Hz - delay = 0.5; // in seconds - scale = 9.neg.dbamp; - - // ------------------------------------------------------------ - // test sig - sig = PlayBuf.ar(~sndbuf.numChannels, ~sndbuf, BufRateScale.kr(~sndbuf), doneAction:2); // soundfile - - // ------------------------------------------------------------ - // delay, lp and gain - delSig = LPF.ar(DelayN.ar(sig, delay, delay), freq, scale); - - // ------------------------------------------------------------ - // transform - delSig = FoaXform.ar(delSig, ~xformer); - - // ------------------------------------------------------------ - // sum (comment this out to hear original signal) - sig = sig + delSig; -// sig = delSig; // or listen to the mirrored sig - - // ------------------------------------------------------------ - // decode (via ~renderDecode) - ~renderDecode.value(sig, ~decoder) - -}.scope; -) - -// free buffer -~sndbuf.free -// ------------------------------------------------------------ -:: - -note:: strong::Soundfile Credits:: - -list:: -## J. Leonard, "Fireworks," Sound of Space: ambisonic surround sound, 25-Aug-2009. [Online]. Available: http://soundofspace.com/ambisonic_files/37 [Accessed: 03-Nov-2011]. - -:: - -:: - - -subsection:: DominateX - -Dominance adjusts the gain of a soundfield in a particular direction. Here we'll increase the amount of reverberation in this natural soundfield recording. As the image is warped at the same time, we'll also hear the frontal stage widen. - -If you haven't already choose a code:: ~decoder:: and defined code:: ~renderDecode ::, do so link::#Choose a decoder#now::. - -note:: A matrix type transformer, see link::Classes/FoaXformerMatrix#*newDominateX:: for further details.:: - - -code:: -// ------------------------------------------------------------ -// dominateX xformer -// b-format soundfile read from disk - - -// define xformer matrix -~xformer = FoaXformerMatrix.newDominateX // no dominance --> try this 1st -~xformer = FoaXformerMatrix.newDominateX(-3.0) // increase gain at rear - - -// inspect -~encoder.kind -~encoder.numChannels -~encoder.dirChannels.raddeg - - -// read a whole sound into memory -// remember to free the buffer later! -// (boot the server, if you haven't!) -~sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/b-format/Leonard-Orfeo_Trio.wav") - - -( -{ - var sig; // audio signal - - // display xformer & decoder - "Ambisonic transforming via % xformer".format(~xformer.kind).postln; - "Ambisonic decoding via % decoder".format(~decoder.kind).postln; - - // ------------------------------------------------------------ - // test sig - sig = PlayBuf.ar(~sndbuf.numChannels, ~sndbuf, BufRateScale.kr(~sndbuf), doneAction:2); // soundfile - - // ------------------------------------------------------------ - // transform - sig = FoaXform.ar(sig, ~xformer); - - - // ------------------------------------------------------------ - // decode (via ~renderDecode) - ~renderDecode.value(sig, ~decoder) - -}.scope; -) - -// free buffer -~sndbuf.free -// ------------------------------------------------------------ -:: - -note:: strong::Soundfile Credits:: - -list:: -## J. Leonard, "The Orfeo Trio & TetraMic," Sound of Space: ambisonic surround sound. [Online]. Available: http://soundofspace.com/ambisonic_files/41 [Accessed: 03-Nov-2011]. - -:: - -:: diff --git a/source/ATK/sc/HelpSource/Classes/FoaXformerMatrix.schelp b/source/ATK/sc/HelpSource/Classes/FoaXformerMatrix.schelp deleted file mode 100644 index 1ef335d827..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaXformerMatrix.schelp +++ /dev/null @@ -1,610 +0,0 @@ -CLASS:: FoaXformerMatrix -summary:: First Order Ambisonic (FOA) transformer matrices -categories:: Libraries>Ambisonic Toolkit>FOA>Transforming -related:: Classes/FoaXform - -DESCRIPTION:: -Generates transform matrices required by the Ambisonic Toolkit's first order (matrix) transformer, link::Classes/FoaXform::. - - - -CLASSMETHODS:: - -METHOD:: newRotate -Rotate around the z-axis. - -argument:: angle -Rotation angle, in radians. - -discussion:: -A rotation of pi/2 will rotate a source at code:: [0, 0] :: to code:: [pi/2, 0] ::. - -note:: Corresponding UGen: link::Classes/FoaRotate:: :: - - -METHOD:: newTilt -Rotate around the x-axis. - -argument:: angle -Rotation angle, in radians. - -discussion:: -A rotation of pi/2 will rotate a source at code:: [pi/2, 0] :: to code:: [0, pi/2] ::. - -note:: Corresponding UGen: link::Classes/FoaTilt:: :: - - -METHOD:: newTumble -Rotate around the y-axis. - -argument:: angle -Rotation angle, in radians. - -discussion:: -A rotation of pi/2 will rotate a source at code:: [0, 0] :: to code:: [0, pi/2] ::. - -note:: Corresponding UGen: link::Classes/FoaTumble:: :: - - -METHOD:: newRTT -Rotate around the z, x and y axes. - -argument:: rotAngle -Rotation angle around z-axis, in radians. - -argument:: tilAngle -Rotation angle around x-axis, in radians. - -argument:: tumAngle -Rotation angle around y-axis, in radians. - -discussion:: -link::#*newRotate#Rotate:: is followed by link::#*newTilt#Tilt:: and then link::#*newTumble#Tumble::. - -note:: Corresponding UGen: link::Classes/FoaRTT:: :: - - - -METHOD:: newMirrorO -Mirror across the origin. - -discussion:: -A source at code:: [pi/4, pi/6] :: will be mirrored to code:: [-3/4*pi, -pi/6] ::. - - -METHOD:: newMirrorX -Mirror in the x-axis (across the y-z plane). - -discussion:: -A source at code:: [pi/4, pi/6] :: will be mirrored to code:: [3/4*pi, pi/6] ::. - - -METHOD:: newMirrorY -Mirror in the y-axis (across the x-z plane). - -discussion:: -A source at code:: [pi/4, pi/6] :: will be mirrored to code:: [-pi/4, pi/6] ::. - - -METHOD:: newMirrorZ -Mirror in the y-axis (across the x-z plane). - -discussion:: -A source at code:: [pi/4, pi/6] :: will be mirrored to code:: [pi/4, -pi/6] ::. - - -METHOD:: newMirror -Mirror across an arbitrary plane. - -argument:: theta -Azimuth for the normal to the plane, in radians. - -argument:: phi -Elevation for the normal to the plane, in radians. - -discussion:: -note:: Corresponding UGen: link::Classes/FoaMirror:: :: - - - -METHOD:: newDirectO -Adjust the soundfield directivity (across the origin). - -argument:: angle -The distortion angle, in radians. 0 to pi/2 - -discussion:: - -strong::Angle:: = 0 retains the current directivity of the soundfield. Increasing strong::angle:: towards pi/2 decreases the directivity, reducing the gains on the directional compenents to zero, and is equivalent to a spatial low-pass filter. The resulting image becomes omnidirectional or directionless. - - -Imaging is illustrated link::Classes/FoaDirectO#figure#here::. - -note:: Corresponding UGen: link::Classes/FoaDirectO:: :: - - -METHOD:: newDirectX -Adjust the soundfield directivity along the x-axis. - -argument:: angle -The distortion angle, in radians. 0 to pi/2 - -discussion:: - -strong::Angle:: = 0 retains the current directivity of the soundfield. Increasing strong::angle:: towards pi/2 decreases the directivity along the x-axis, reducing the gain on this axis to zero, and is equivalent to a spatial low-pass filter. The resulting image becomes directionless on the x-axis. - -Imaging is illustrated link::Classes/FoaDirectX#figure#here::. - -note:: Corresponding UGen: link::Classes/FoaDirectX:: :: - - -METHOD:: newDirectY -Adjust the soundfield directivity along the y-axis. - -argument:: angle -The distortion angle, in radians. 0 to pi/2 - -discussion:: - -strong::Angle:: = 0 retains the current directivity of the soundfield. Increasing strong::angle:: towards pi/2 decreases the directivity along the y-axis, reducing the gain on this axis to zero, and is equivalent to a spatial low-pass filter. The resulting image becomes directionless on the y-axis. - -Imaging is illustrated link::Classes/FoaDirectY#figure#here::. - -note:: Corresponding UGen: link::Classes/FoaDirectY:: :: - - -METHOD:: newDirectZ -Adjust the soundfield directivity along the z-axis. - -argument:: angle -The distortion angle, in radians. 0 to pi/2 - -discussion:: - -strong::Angle:: = 0 retains the current directivity of the soundfield. Increasing strong::angle:: towards pi/2 decreases the directivity along the z-axis, reducing the gain on this axis to zero, and is equivalent to a spatial low-pass filter. The resulting image becomes directionless on the z-axis. - -note:: Corresponding UGen: link::Classes/FoaDirectZ:: :: - - -METHOD:: newDirect -Adjust the soundfield directivity across an arbitrary plane. - -argument:: angle -The distortion angle, in radians. 0 to pi/2 - -argument:: theta -Azimuth for the normal to the plane, in radians. - -argument:: phi -Elevation for the normal to the plane, in radians. - - -discussion:: - -strong::Angle:: = 0 retains the current directivity of the soundfield. Increasing strong::angle:: towards pi/2 decreases the directivity along the normal defined by strong::theta:: and strong::phi::, reducing the gain on this normal to zero, and is equivalent to a spatial low-pass filter. The resulting image becomes directionless on the normal. - -note:: Corresponding UGen: link::Classes/FoaDirect:: :: - - - - -METHOD:: newDominateX -Apply dominance along the x-axis. - -argument:: gain -Dominance gain, in dB. - -discussion:: Positive values of strong::gain:: increase the gain at code:: [0, 0] :: to strong::+gain:: dB, while decreasing the gain at code:: [pi, 0] :: to strong::-gain::. This simultaneously results in a distortion of the image towards code:: [0, 0] ::. Negative values of gain invert this distortion, distorting towards code:: [pi, 0] :: . The default, 0, results in no change. - -Imaging is illustrated link::Classes/FoaDominateX#figure#here::. - - -note:: Corresponding UGen: link::Classes/FoaDominateX:: :: - - -METHOD:: newDominateY -Apply dominance along the y-axis. - -argument:: gain -Dominance gain, in dB. - -discussion:: Positive values of strong::gain:: increase the gain at code:: [pi/2, 0] :: to strong::+gain:: dB, while decreasing the gain at code:: [-pi/2, 0] :: to strong::-gain::. This simultaneously results in a distortion of the image towards code:: [pi/2, 0] ::. Negative values of gain invert this distortion, distorting towards code:: [-pi/2, 0] :: . The default, 0, results in no change. - - -note:: Corresponding UGen: link::Classes/FoaDominateY:: :: - - - -METHOD:: newDominateZ -Apply dominance along the z-axis. - -argument:: gain -Dominance gain, in dB. - -discussion:: Positive values of strong::gain:: increase the gain at code:: [0, pi/2] :: to strong::+gain:: dB, while decreasing the gain at code:: [0, -pi/2] :: to strong::-gain::. This simultaneously results in a distortion of the image towards code:: [0, pi/2] ::. Negative values of gain invert this distortion, distorting towards code:: [0, -pi/2] :: . The default, 0, results in no change. - - -note:: Corresponding UGen: link::Classes/FoaDominateZ:: :: - - -METHOD:: newDominate -Apply dominance along an arbitrary axis. - -argument:: gain -Dominance gain, in dB. - -argument:: theta -Azimuth, in radians. - -argument:: phi -Elevation, in radians. - -discussion:: Applies dominance along the axis defined by strong::theta:: and strong::phi::. See link::#*newDominateX::. - -note:: Corresponding UGen: link::Classes/FoaDominate:: :: - - - - -METHOD:: newZoomX -Apply zoom along the x-axis. - -argument:: angle -The distortion angle, in radians. -pi/2 to pi/2 - -discussion:: Zoom is a normailised dominance variant, specified in terms of a distortion angle. Positive values of strong::angle:: increase gain at code:: [0, 0] ::, while reducing at code:: [pi, 0] ::. Negative values do the inverse. The default, 0, results in no change. - -Imaging is illustrated link::Classes/FoaZoomX#figure#here::. - -note:: Corresponding UGen: link::Classes/FoaZoomX:: :: - - - -METHOD:: newZoomY -Apply zoom along the y-axis. - -argument:: angle -The distortion angle, in radians. -pi/2 to pi/2 - -discussion:: Zoom is a normailised dominance variant, specified in terms of a distortion angle. Positive values of strong::angle:: increase gain at code:: [pi/2, 0] ::, while reducing at code:: [-pi/2, 0] ::. Negative values do the inverse. The default, 0, results in no change. - -Imaging is illustrated link::Classes/FoaZoomY#figure#here::. - -note:: Corresponding UGen: link::Classes/FoaZoomY:: :: - - -METHOD:: newZoomZ -Apply zoom along the z-axis. - -argument:: angle -The distortion angle, in radians. -pi/2 to pi/2 - -discussion:: Zoom is a normailised dominance variant, specified in terms of a distortion angle. Positive values of strong::angle:: increase gain at code:: [0, pi/2] ::, while reducing at code:: [0, -pi/2] ::. Negative values do the inverse. The default, 0, results in no change. - -note:: Corresponding UGen: link::Classes/FoaZoomZ:: :: - - - -METHOD:: newZoom -Apply zoom along an arbitrary axis. - -argument:: angle -The distortion angle, in radians. -pi/2 to pi/2 - -argument:: theta -Azimuth, in radians. - -argument:: phi -Elevation, in radians. - - -discussion:: Applies zoom along the axis defined by strong::theta:: and strong::phi::. See link::#*newZoomX::. - -note:: Corresponding UGen: link::Classes/FoaZoom:: :: - - - - - - -METHOD:: newFocusX -Apply focus along the x-axis. - -argument:: angle -The distortion angle, in radians. -pi/2 to pi/2 - -discussion:: Focus is a normalised dominance variant, specified in terms of a distortion angle. Positive values of strong::angle:: maintain gain at code:: [0, 0] ::, while reducing at code:: [pi, 0] ::. Negative values do the inverse. The default, 0, results in no change. - -In contrast with zoom, gain is maintained at 0dB in the direction of distortion. - -Imaging is illustrated link::Classes/FoaFocusX#figure#here::. - -note:: Corresponding UGen: link::Classes/FoaFocusX:: :: - - -METHOD:: newFocusY -Apply focus along the y-axis. - -argument:: angle -The distortion angle, in radians. -pi/2 to pi/2 - -discussion:: Focus is a normalised dominance variant, specified in terms of a distortion angle. Positive values of strong::angle:: maintain gain at code:: [pi/2, 0] ::, while reducing at code:: [-pi/2, 0] ::. Negative values do the inverse. The default, 0, results in no change. - -In contrast with zoom, gain is maintained at 0dB in the direction of distortion. - -note:: Corresponding UGen: link::Classes/FoaFocusY:: :: - - - -METHOD:: newFocusZ -Apply focus along the x-axis. - -argument:: angle -The distortion angle, in radians. -pi/2 to pi/2 - -discussion:: Focus is a normalised dominance variant, specified in terms of a distortion angle. Positive values of strong::angle:: maintain gain at code:: [0, pi/2] ::, while reducing at code:: [0, -pi/2] ::. Negative values do the inverse. The default, 0, results in no change. - -In contrast with zoom, gain is maintained at 0dB in the direction of distortion. - -note:: Corresponding UGen: link::Classes/FoaFocusZ:: :: - - - -METHOD:: newFocus -Apply focus along an arbitrary axis. - -argument:: angle -The distortion angle, in radians. -pi/2 to pi/2 - -argument:: theta -Azimuth, in radians. - -argument:: phi -Elevation, in radians. - -discussion:: Applies focus along the axis defined by strong::theta:: and strong::phi::. See link::#*newFocusX::. - -note:: Corresponding UGen: link::Classes/FoaFocus:: :: - - - -METHOD:: newPushX -Apply push along the x-axis. - -argument:: angle -The distortion angle, in radians. -pi/2 to pi/2 - -discussion:: Push is a dominance related transform, specified in terms of a distortion angle. Positive values of strong::angle:: push the image towards code:: [0, 0] ::. Negative values push towards code:: [pi, 0] ::. The default, 0, results in no change. - -Imaging is illustrated link::Classes/FoaPushX#figure#here::. - -note:: Corresponding UGen: link::Classes/FoaPushX:: :: - - -METHOD:: newPushY -Apply push along the y-axis. - -argument:: angle -The distortion angle, in radians. -pi/2 to pi/2 - -discussion:: Push is a dominance related transform, specified in terms of a distortion angle. Positive values of strong::angle:: push the image towards code:: [pi/2, 0] ::. Negative values push towards code:: [-pi/2, 0] ::. The default, 0, results in no change. - -note:: Corresponding UGen: link::Classes/FoaPushY:: :: - - - -METHOD:: newPushZ -Apply push along the x-axis. - -argument:: angle -The distortion angle, in radians. -pi/2 to pi/2 - -discussion:: Push is a dominance related transform, specified in terms of a distortion angle. Positive values of strong::angle:: push the image towards code:: [0, pi/2] ::. Negative values push towards code:: [0, -pi/2] ::. The default, 0, results in no change. - -note:: Corresponding UGen: link::Classes/FoaPushZ:: :: - - -METHOD:: newPush -Apply push along an arbitrary axis. - -argument:: angle -The distortion angle, in radians. -pi/2 to pi/2 - -argument:: theta -Azimuth, in radians. - -argument:: phi -Elevation, in radians. - -discussion:: Applies push along the axis defined by strong::theta:: and strong::phi::. See link::#*PushX::. - -note:: Corresponding UGen: link::Classes/FoaPush:: :: - - - - - - -METHOD:: newPressX -Apply press along the x-axis. - -argument:: angle -The distortion angle, in radians. -pi/2 to pi/2 - -discussion:: Press is a dominance related transform, specified in terms of a distortion angle. Positive values of strong::angle:: press the image towards code:: [0, 0] ::. Negative values press towards code:: [pi, 0] ::. The default, 0, results in no change. - -Imaging is illustrated link::Classes/FoaPressX#figure#here::. - -note:: Corresponding UGen: link::Classes/FoaPressX:: :: - - -METHOD:: newPressY -Apply press along the x-axis. - -argument:: angle -The distortion angle, in radians. -pi/2 to pi/2 - -discussion:: Press is a dominance related transform, specified in terms of a distortion angle. Positive values of strong::angle:: press the image towards code:: [pi/2, 0] ::. Negative values press towards code:: [-pi/2, 0] ::. The default, 0, results in no change. - -note:: Corresponding UGen: link::Classes/FoaPressY:: :: - - -METHOD:: newPressZ -Apply press along the z-axis. - -argument:: angle -The distortion angle, in radians. -pi/2 to pi/2 - -discussion:: Press is a dominance related transform, specified in terms of a distortion angle. Positive values of strong::angle:: press the image towards code:: [0, pi/2] ::. Negative values press towards code:: [0, -pi/2] ::. The default, 0, results in no change. - -Imaging is illustrated link::Classes/FoaPressZ##here::. - -note:: Corresponding UGen: link::Classes/FoaPressZ:: :: - - -METHOD:: newPress -Apply press along an arbitrary axis. - -argument:: angle -The distortion angle, in radians. -pi/2 to pi/2 - -argument:: theta -Azimuth, in radians. - -argument:: phi -Elevation, in radians. - -discussion:: Applies press along the axis defined by strong::theta:: and strong::phi::. See link::#*PressX::. - -note:: Corresponding UGen: link::Classes/FoaPress:: :: - - -METHOD:: newAsymmetry -Apply soundfield asymmetry - -argument:: angle -The distortion angle, in radians. -pi/2 to pi/2 - -discussion:: Positive values of strong::angle:: rotate code:: [0, -pi/2] :: towards code:: [0, 0] ::, and at pi/2 collapse the soundfield to a planewave. Negative values rotate code:: [0, pi/2] :: toowards code:: [0, 0] ::. The default, 0, results in no change. - -Imaging is illustrated link::Classes/FoaAsymmetry#figure#here::. - -note:: Corresponding UGen: link::Classes/FoaAsymmetry:: :: - - - -METHOD:: newBalance -Soundfield balance. A synonym for link::#*newZoomY#ZoomY:: - -argument:: angle -The distortion angle, in radians. -pi/2 to pi/2 - -discussion:: See link::#*newZoomY#ZoomY::. - -Imaging is illustrated link::Classes/FoaBalance#figure#here::. - -note:: Corresponding UGen: link::Classes/FoaBalance:: :: - - -METHOD:: newFromFile -Create an FoaEncoderMatrix by loading a matrix from a file. - -argument:: filePathOrName -Can be a path relative to your code::/extensions/matrices/xformers:: folder: -code:: -Atk.getMatrixExtensionPath('xformers').fullPath -:: -Otherwise a full path to your matrix file. - -discussion:: -See the link::Guides/Guide-to-ATK-Matrix-Files:: for more information. - - -COPYMETHOD:: AtkMatrix, *newFromMatrix - - - -INSTANCEMETHODS:: - -private:: initMirrorChan, initMirrorX, initMirrorY, initMirrorZ, initMirrorO, initRotate, initTilt, initTumble, initDirectO, initDirectX, initDirectY, initDirectZ, initDominateX, initDominateY, initDominateZ, initZoomX, initZoomY, initZoomZ, initFocusX, initFocusY, initFocusZ, initPushX, initPushY, initPushZ, initPressX, initPressY, initPressZ, initAsymmetry, initRTT, initMirror, initDirect, initDominate, initZoom, initFocus, initPush, initPress, printOn - - -METHOD:: set - -Describes both the emphasis::signal set:: and the emphasis::tool set::, encompassing the Ambisonic order, as well as channel ordering and normalisation. - -Answers code::'FOA'::, aka traditional B-format: - -table:: -## strong::Ambisonic Order:: || strong::Channel Ordering:: || strong::Channel Normalisation:: -## 1st || Gerzon (aka Furse-Malham) || MaxN -:: - -METHOD:: type -returns:: code::'xformer':: - -COPYMETHOD:: AtkMatrix, -op - -METHOD:: kind -Answers the kind of encoder - -discussion:: - -code:: -// encoder -~xformer = FoaXformerMatrix.newZoomX - -// inspect -~encoder.kind -:: - - -METHOD:: dim -Answers the number of transformer dimensions: 3D. - - -METHOD:: numChannels -Answers the number of channels. - -discussion:: All Transformer matricies are square: 4. - - -METHOD:: dirChannels -A convenience method providing polymorphism with link::Classes/FoaEncoderMatrix#-dirChannels:: and link::Classes/FoaDecoderMatrix#-dirChannels::. - -returns:: code:: [ inf, inf, inf , inf ] :: - - -METHOD:: matrix -Answers the transform matrix - - -METHOD:: numOutputs -A convenience method providing polymorphism with link::Classes/FoaEncoderMatrix#-numOutputs:: and link::Classes/FoaDecoderMatrix#-numOutputs::. - - -METHOD:: dirOutputs -A convenience method providing polymorphism with link::Classes/FoaEncoderMatrix#-dirOutputs:: and link::Classes/FoaDecoderMatrix#-dirOutputs::. - - -METHOD:: numInputs -A convenience method providing polymorphism with link::Classes/FoaEncoderMatrix#-numInputs:: and link::Classes/FoaDecoderMatrix#-numInputs::. - - -METHOD:: dirInputs -A convenience method providing polymorphism with link::Classes/FoaEncoderMatrix#-dirInputs:: and link::Classes/FoaDecoderMatrix#-dirInputs::. - - -COPYMETHOD:: AtkMatrix, -info - -COPYMETHOD:: AtkMatrix, -fileParse - -COPYMETHOD:: AtkMatrix, -filePath - -COPYMETHOD:: AtkMatrix, -fileName - -COPYMETHOD:: AtkMatrix, -writeToFile - -EXAMPLES:: - -Please see link::Classes/FoaXform#Examples::. diff --git a/source/ATK/sc/HelpSource/Classes/FoaZoom.schelp b/source/ATK/sc/HelpSource/Classes/FoaZoom.schelp deleted file mode 100644 index f9009a4550..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaZoom.schelp +++ /dev/null @@ -1,48 +0,0 @@ -CLASS:: FoaZoom -summary:: First Order Ambisonic (FOA) zoom transformer -categories:: Libraries>Ambisonic Toolkit>FOA>Transforming>UGens, UGens>Multichannel>Ambisonics, UGens>Multichannel>Panners -related:: Classes/FoaZoomX, Classes/FoaZoomY, Classes/FoaZoomZ, Classes/FoaTransform, Classes/FoaXform - -DESCRIPTION:: -Apply zoom to a first order ambisonic signal (B-format) along an arbitrary axis. - - -NOTE:: -link::Classes/FoaZoom:: is usually called via the convenience wrapper link::Classes/FoaTransform::. -:: - - - -CLASSMETHODS:: - -METHOD:: ar - -argument:: in -The B-format signal, an array: [w, x, y, z] - -argument:: angle -The distortion angle, in radians. -pi/2 to pi/2 - -argument:: theta -Azimuth, in radians. - -argument:: phi -Elevation, in radians. - -argument:: mul -Output will be multiplied by this value. - -argument:: add -This value will be added to the output. - - - -discussion:: Applies zoom along the axis defined by strong::theta:: and strong::phi::. See link::Classes/FoaZoomX::. - - -note:: Corresponding matrix transformer: link::Classes/FoaXformerMatrix#*newZoom:: :: - - -EXAMPLES:: - -Please see various examples link::Classes/FoaTransform#examples#here::. \ No newline at end of file diff --git a/source/ATK/sc/HelpSource/Classes/FoaZoomX.schelp b/source/ATK/sc/HelpSource/Classes/FoaZoomX.schelp deleted file mode 100644 index 0369513e42..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaZoomX.schelp +++ /dev/null @@ -1,46 +0,0 @@ -CLASS:: FoaZoomX -summary:: First Order Ambisonic (FOA) zoom transformer -categories:: Libraries>Ambisonic Toolkit>FOA>Transforming>UGens, UGens>Multichannel>Ambisonics, UGens>Multichannel>Panners -related:: Classes/FoaZoomY, Classes/FoaZoomZ, Classes/FoaZoom, Classes/FoaTransform, Classes/FoaXform - -DESCRIPTION:: -Apply zoom to a first order ambisonic signal (B-format) along the x-axis. - - -NOTE:: -link::Classes/FoaZoomX:: is usually called via the convenience wrapper link::Classes/FoaTransform::. -:: - - - -CLASSMETHODS:: - -METHOD:: ar - -argument:: in -The B-format signal, an array: [w, x, y, z] - -argument:: angle -The distortion angle, in radians. -pi/2 to pi/2 - -argument:: mul -Output will be multiplied by this value. - -argument:: add -This value will be added to the output. - - - -discussion:: Zoom is a normailised dominance variant, specified in terms of a distortion angle. Positive values of strong::angle:: increase gain at code:: [0, 0] ::, while reducing at code:: [pi, 0] ::. Negative values do the inverse. The default, 0, results in no change. - - -anchor::figure:: - -image::zoom_fig.png#Zoom imaging:: - -note:: Corresponding matrix transformer: link::Classes/FoaXformerMatrix#*newZoomX:: :: - - -EXAMPLES:: - -Please see various examples link::Classes/FoaTransform#examples#here::. \ No newline at end of file diff --git a/source/ATK/sc/HelpSource/Classes/FoaZoomY.schelp b/source/ATK/sc/HelpSource/Classes/FoaZoomY.schelp deleted file mode 100644 index 8108d0bfc1..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaZoomY.schelp +++ /dev/null @@ -1,47 +0,0 @@ -CLASS:: FoaZoomY -summary:: First Order Ambisonic (FOA) zoom transformer -categories:: Libraries>Ambisonic Toolkit>FOA>Transforming>UGens, UGens>Multichannel>Ambisonics, UGens>Multichannel>Panners -related:: Classes/FoaZoomX, Classes/FoaZoomZ, Classes/FoaZoom, Classes/FoaTransform, Classes/FoaXform - -DESCRIPTION:: -Apply zoom to a first order ambisonic signal (B-format) along the y-axis. - - -NOTE:: -link::Classes/FoaZoomY:: is usually called via the convenience wrapper link::Classes/FoaTransform::. -:: - - - -CLASSMETHODS:: - -METHOD:: ar - -argument:: in -The B-format signal, an array: [w, x, y, z] - -argument:: angle -The distortion angle, in radians. -pi/2 to pi/2 - -argument:: mul -Output will be multiplied by this value. - -argument:: add -This value will be added to the output. - - - -discussion:: Zoom is a normailised dominance variant, specified in terms of a distortion angle. Positive values of strong::angle:: increase gain at code:: [0, pi/2] ::, while reducing at code:: [0, -pi/2] ::. Negative values do the inverse. The default, 0, results in no change. - - -anchor::figure:: - -image::balance_fig.png#ZoomY imaging:: - - -note:: Corresponding matrix transformer: link::Classes/FoaXformerMatrix#*newZoomY:: :: - - -EXAMPLES:: - -Please see various examples link::Classes/FoaTransform#examples#here::. diff --git a/source/ATK/sc/HelpSource/Classes/FoaZoomZ.schelp b/source/ATK/sc/HelpSource/Classes/FoaZoomZ.schelp deleted file mode 100644 index 5f015f9f36..0000000000 --- a/source/ATK/sc/HelpSource/Classes/FoaZoomZ.schelp +++ /dev/null @@ -1,42 +0,0 @@ -CLASS:: FoaZoomZ -summary:: First Order Ambisonic (FOA) zoom transformer -categories:: Libraries>Ambisonic Toolkit>FOA>Transforming>UGens, UGens>Multichannel>Ambisonics, UGens>Multichannel>Panners -related:: Classes/FoaZoomX, Classes/FoaZoomY, Classes/FoaZoom, Classes/FoaTransform, Classes/FoaXform - -DESCRIPTION:: -Apply zoom to a first order ambisonic signal (B-format) along the z-axis. - - -NOTE:: -link::Classes/FoaZoomZ:: is usually called via the convenience wrapper link::Classes/FoaTransform::. -:: - - - -CLASSMETHODS:: - -METHOD:: ar - -argument:: in -The B-format signal, an array: [w, x, y, z] - -argument:: angle -The distortion angle, in radians. -pi/2 to pi/2 - -argument:: mul -Output will be multiplied by this value. - -argument:: add -This value will be added to the output. - - - -discussion:: Zoom is a normailised dominance variant, specified in terms of a distortion angle. Positive values of strong::angle:: increase gain at code:: [0, pi/2] ::, while reducing at code:: [0, -pi/2] ::. Negative values do the inverse. The default, 0, results in no change. - - -note:: Corresponding matrix transformer: link::Classes/FoaXformerMatrix#*newZoomZ:: :: - - -EXAMPLES:: - -Please see various examples link::Classes/FoaTransform#examples#here::. \ No newline at end of file diff --git a/source/ATK/sc/HelpSource/Classes/asymmetry_fig.png b/source/ATK/sc/HelpSource/Classes/asymmetry_fig.png deleted file mode 100644 index 59ba43b7ea..0000000000 Binary files a/source/ATK/sc/HelpSource/Classes/asymmetry_fig.png and /dev/null differ diff --git a/source/ATK/sc/HelpSource/Classes/balance_fig.png b/source/ATK/sc/HelpSource/Classes/balance_fig.png deleted file mode 100644 index 3b669001bf..0000000000 Binary files a/source/ATK/sc/HelpSource/Classes/balance_fig.png and /dev/null differ diff --git a/source/ATK/sc/HelpSource/Classes/direct_fig.png b/source/ATK/sc/HelpSource/Classes/direct_fig.png deleted file mode 100644 index 05c038c291..0000000000 Binary files a/source/ATK/sc/HelpSource/Classes/direct_fig.png and /dev/null differ diff --git a/source/ATK/sc/HelpSource/Classes/direct_x_fig.png b/source/ATK/sc/HelpSource/Classes/direct_x_fig.png deleted file mode 100644 index 8258a449cb..0000000000 Binary files a/source/ATK/sc/HelpSource/Classes/direct_x_fig.png and /dev/null differ diff --git a/source/ATK/sc/HelpSource/Classes/direct_y_fig.png b/source/ATK/sc/HelpSource/Classes/direct_y_fig.png deleted file mode 100644 index cc9649caf7..0000000000 Binary files a/source/ATK/sc/HelpSource/Classes/direct_y_fig.png and /dev/null differ diff --git a/source/ATK/sc/HelpSource/Classes/dominance_fig.png b/source/ATK/sc/HelpSource/Classes/dominance_fig.png deleted file mode 100644 index 8e4bdd7205..0000000000 Binary files a/source/ATK/sc/HelpSource/Classes/dominance_fig.png and /dev/null differ diff --git a/source/ATK/sc/HelpSource/Classes/focus_fig.png b/source/ATK/sc/HelpSource/Classes/focus_fig.png deleted file mode 100644 index dc38265f66..0000000000 Binary files a/source/ATK/sc/HelpSource/Classes/focus_fig.png and /dev/null differ diff --git a/source/ATK/sc/HelpSource/Classes/press_fig.png b/source/ATK/sc/HelpSource/Classes/press_fig.png deleted file mode 100644 index 10fdaab384..0000000000 Binary files a/source/ATK/sc/HelpSource/Classes/press_fig.png and /dev/null differ diff --git a/source/ATK/sc/HelpSource/Classes/push_fig.png b/source/ATK/sc/HelpSource/Classes/push_fig.png deleted file mode 100644 index 5fd63cea64..0000000000 Binary files a/source/ATK/sc/HelpSource/Classes/push_fig.png and /dev/null differ diff --git a/source/ATK/sc/HelpSource/Classes/zoom_fig.png b/source/ATK/sc/HelpSource/Classes/zoom_fig.png deleted file mode 100644 index 7679a8595a..0000000000 Binary files a/source/ATK/sc/HelpSource/Classes/zoom_fig.png and /dev/null differ diff --git a/source/ATK/sc/HelpSource/Guides/ATK-SynthDef-Examples.schelp b/source/ATK/sc/HelpSource/Guides/ATK-SynthDef-Examples.schelp deleted file mode 100644 index 8e069e916b..0000000000 --- a/source/ATK/sc/HelpSource/Guides/ATK-SynthDef-Examples.schelp +++ /dev/null @@ -1,582 +0,0 @@ -title:: SynthDef and NRT examples for ATK -summary:: SynthDef and NRT examples for ATK -categories:: Libraries>Ambisonic Toolkit -keyword::Atk - -section:: ATK with SynthDef and Synth - -For a more in-depth overview of the paradigm of ATK and a complete presentation -of its capabilities, see link::Guides/Intro-to-the-ATK::. These examples show a -limited set of the ATK's functionality, but illustrate how to work with the -library when using link::Classes/SynthDef##SynthDefs:: and -link::Classes/Synth##Synths::, and a single decoder that reads the Ambisonic -signal through audio bus routing. Additionally, examples for -link::Guides/Non-Realtime-Synthesis##Non-Realtime (NRT):: processing are found -in this guide. - -subsection:: Mono Encoder using FoaPanB - -link::Classes/FoaPanB:: encodes a monophonic input to a first order ambisonic -signal (B-format), as a planewave. link::Classes/PanB:: is the SuperCollider -inbuilt equivalent. - -This first example encodes a link::Classes/PinkNoise:: source as a planewave and -decodes to stereo. - - -code:: - -Server.default = s = Server.local.boot; - -( -var decoder; - -// First we will define our decoder -// stereo decoder -decoder = FoaDecoderMatrix.newStereo((131/2).degrad, 0.5); - -// next we define a synth using FoaPanB, and decoder using FoaDecode -SynthDef(\foaEncode1, { - var src, theta, phi, foa, out; - - // our source: pink noise - src = PinkNoise.ar(-6.dbamp); - - // theta is our angle on the X-Y plane and phi is our elevation - // use a MouseX to control theta in real time, from pi to -pi - theta = MouseX.kr(pi, -pi); - phi = 0; - - // Encode into our foa signal - foa = FoaPanB.ar(src, theta, phi); - - // decode our signal using our decoder defined above - out = FoaDecode.ar(foa, decoder); - - Out.ar(0, out); -}).add; -) - -// play the synth -a = Synth(\foaEncode1); - -//free the synth -a.free; -:: - -subsection:: Omni Encoder using FoaEncoderMatrix, Transforms using FoaTransform - -Encodes a monophonic input as an -link::Classes/FoaEncoderMatrix#*newOmni#omnidirectional:: soundfield, then -re-image via two transforms using the link::Classes/FoaTransform:: UGen wrapper. - -code:: - -( -var decoder, encoder; -// First we will define our decoder and encoder -// stereo decoder -decoder = FoaDecoderMatrix.newStereo((131/2).degrad, 0.5); - -// a matrix for an omni image -encoder = FoaEncoderMatrix.newOmni; - -// define a synth using FoaEncode and FoaDecode -SynthDef(\foaEncode2, { - var src, angle, azim, foa, out; - - // our source: Pink Noise (could be any mono signal) - src = PinkNoise.ar(-6.dbamp); - - - // for the 'push' transform later - // see FoaPush help for details - // angle ---> top = push to plane wave - // bottom = omni-directional - angle = MouseY.kr(pi/2, 0); - - - // for 'rotate' transform - // azimuth -> hard left = back - // centre = centre - // hard right = back - azim = MouseX.kr(pi, -pi); - - - // Encode into our foa signal - foa = FoaEncode.ar(src, encoder); - - - // push transform using angle - foa = FoaTransform.ar(foa, 'pushX', angle); - - // rotate transform using azim - foa = FoaTransform.ar(foa, 'rotate', azim); - - - // decode our signal - out = FoaDecode.ar(foa, decoder); - - - Out.ar(0, out); -}).add; - -) - -// play the synth -a = Synth(\foaEncode2); - -// free the synth -a.free; - -:: - - -subsection:: Route Encoding Synth to a separate Decoding Synth - -Encode a planewave, and route to a single decoder: - -code:: - -( -var decoder; - -// define our deocder -decoder = FoaDecoderMatrix.newStereo((131/2).degrad, 0.5); - -// allocate four channels for routing -a = Bus.audio(s, 4); - -// Encoding Synth -SynthDef(\foaEncode3, {arg outBus, duration = 0.05, theta, phi; - var src, foa, env; - - // our mono source - src = PinkNoise.ar(-6.dbamp); - - // amplitude scaling envelope - env = EnvGen.kr( - Env([0, 1, 0], [0.5, 0.5], \sin), - timeScale: duration, - doneAction: 2); - - // Encode into our foa signal - foa = FoaPanB.ar(src, theta, phi, env); - - Out.ar(outBus, foa); -}).add; - -// Decoding Synth -SynthDef(\foaDecode, {arg inBus; - var foa, out; - - // read in 4 channels (B-format) from inBus - foa = In.ar(inBus, 4); - - // decode to stereo - out = FoaDecode.ar(foa, decoder); - - Out.ar(0, out); -}).add; - -) - - -// start the decoder, reading bus 'a' at the \tail -b = Synth(\foaDecode, [\inBus, a], 1, \addToTail); - -// use a Routine to start many encoded signals at random angles -Routine.run({ - 20.do({ - Synth(\foaEncode3, [\outBus, a, \theta, pi.rand2, \phi, 0]); - 0.1.wait; - }) -}); - - -b.free; // free the decoder -a.free; // free the audio bus - -:: - -section:: Kernel Decoders and Encoders - -subsection:: B-format Sound File and Binaural Decoder - -In this example we're working with a B-format sound file. As the source is -already encoded, an encoding stage is not needed. For audition, a -link::Classes/FoaDecoderKernel#*newListen#binaural (HRTF) decoder:: is used. -This decoder takes a subjectID as an argument. It would be wise to experiment -with various subjectIDs to discover which suits your own head. - -code:: - - -( -var cond, decoder, sndbuf, synth; - -// boot the server -s.boot; - -// wait for the server to boot -cond = Condition.new; -s.waitForBoot({ - - - Routine.run({ - - // define a binaural decoder - decoder = FoaDecoderKernel.newListen(1013); - - // load sound file into a buffer - sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/b-format/Pampin-On_Space.wav"); - - s.sync(cond); - - // synth to decode our B-format sound file - SynthDef(\kernelDecode, {arg buffer; - var out, src; - - // play B-format sound file - src = PlayBuf.ar(sndbuf.numChannels, buffer, BufRateScale.kr(buffer), loop: 1); - - // decode using decoder - out = FoaDecode.ar(src, decoder); - - - Out.ar(0, out); - }).add; - - s.sync(cond); - - synth = Synth(\kernelDecode, [\buffer, sndbuf]); - - // press command period when done - CmdPeriod.doOnce({ - synth.free; - decoder.free; - sndbuf.free - }); - }) -}) -) - -:: - -subsection:: Encode an Ambisonic UHJ Stereo File, Decode to HRTF - -link::https://en.wikipedia.org/wiki/Ambisonic_UHJ_format##Ambisonic UHJ:: is -the stereo compatible Ambisonic format, and a suitable Ambisonic B-format -signal can be retrieved from UHJ encoded signals. footnote:: -See further discussion -link::https://en.wikipedia.org/wiki/Ambisonic_UHJ_format##here::. -:: - -Here we will encode (emphasis::transcode::, actually!) a UHJ Stereo file to -B-format. For audition, a -link::Classes/FoaDecoderKernel#*newListen#binaural (HRTF) decoder:: is used. -This decoder takes a subjectID as an argument. It would be wise to experiment -with various subjectIDs to discover which suits your own head. suits your own -head. - -code:: -( -var cond, encoder, decoder, sndbuf, synth; - -// boot the server -s.boot; - -// wait for the server to boot -cond = Condition.new; -s.waitForBoot({ - - Routine.run({ - - // define an UHJ encoder - encoder = FoaEncoderKernel.newUHJ; - - // define an HRTF decoder - decoder = FoaDecoderKernel.newListen(1013); - - // load a UHJ sound file into a buffer - sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/uhj/Palestrina-O_Bone.wav"); - - s.sync(cond); - - // synth to encode a UHJ file and decode using an HRTF - SynthDef(\kernelEncodeDecode, {arg buffer; - var out, src, encode; - - // our stereo source signal - src = PlayBuf.ar(sndbuf.numChannels, buffer, BufRateScale.kr(buffer)); - - // encode using a UHJ encoder - encode = FoaEncode.ar(src, encoder); - - // decode using an HRTF decoder - out = FoaDecode.ar(encode, decoder); - - Out.ar(0, out); - }).add; - - s.sync(cond); - - // play the synth - synth = Synth(\kernelEncodeDecode, [\buffer, sndbuf]); - - // press command period when done - CmdPeriod.doOnce({ - synth.free; - encoder.free; - decoder.free; - sndbuf.free}); - }) -}) -) -:: - -section:: ATK in Non-Realtime - -subsection:: ATK and Score - -In many cases, examples using link::Classes/Score:: are often trickier due to -the need for the use of link::Guides/Bundled-Messages##bundles::. Since the -Kernels footnote:: -link::Classes/FoaEncoderKernel:: and link::Classes/FoaDecoderKernel:: -:: also pass in hardcoded buffer IDs, we need to make sure those are referenced, -as well. - -The example below decodes a B-format input file to Stereo Ambisonic UHJ using -the ATK's link::Classes/FoaDecoderKernel#*newUHJ:: decoder. - -code:: -( -var score, bufnum, sndPath, duration, decoder, sampleRate, headerFormat, sampleFormat, numChannels; -var offset = 0.1; - -// deinfe our score -score = Score.new; - -// get a buffer number from the server -bufnum = Server.default.bufferAllocator.alloc(1); - -// the path to our B-Format sound file -sndPath = Atk.userSoundsDir ++ "/b-format/Pampin-On_Space.wav"; - -// get some info about the soundfile we are decoding for the Score requirements -SoundFile.use( - sndPath, - {arg soundFile; - headerFormat = soundFile.headerFormat; - sampleFormat = soundFile.sampleFormat; - sampleRate = soundFile.sampleRate; - numChannels = soundFile.numChannels; - duration = soundFile.duration; - } -); - -// define a decoder of your choosing -// the decoder takes a score argument so that it will add the kernels to the score for you -decoder = FoaDecoderKernel.newUHJ( - sampleRate: sampleRate, - score: score -); - -// define an encoding and decoding synth -SynthDef(\kernelDecode, {arg buffer; - var out, src; - - // play B-format sound file from a buffer - src = PlayBuf.ar(numChannels, buffer, BufRateScale.kr(buffer)); - - // decode our B-format signal - out = FoaDecode.ar(src, decoder); - - Out.ar(0, out); -}).load; - -score.add( - [ 0.0, - [ 'b_allocRead', bufnum, sndPath, 0, 0 ], - [ 's_new', 'kernelDecode', 1001, 0, 1, 'buffer', bufnum ] - ], -); - -// add commands to free the synth and buffer -score.add([ duration, [ 'n_free', 1001 ] ],); -score.add([ duration + 0.1, [ 'b_free', bufnum ] ],); - -// free the kernel buffers -decoder.kernel.do({arg bufs; - bufs.do({arg buf; - offset = offset + 0.1; - score.add([ duration + offset, [ 'b_free', buf.bufnum ]]) - }); -}); - -// add the needed dummy command to stop NRT -score.add([offset + duration + 0.2, [0]] ); - -// render our score to a sound file -score.recordNRT( - "/tmp/trashme", - "~/Desktop/myDecode.wav".standardizePath, - sampleRate: sampleRate, - headerFormat: headerFormat, - sampleFormat: sampleFormat, - options: ServerOptions.new.numOutputBusChannels_(decoder.numChannels) -); - -) -:: - - -subsection:: ATK and the Composer's Toolkit (Ctk) - -The -link::https://github.com/supercollider-quarks/Ctk##Composer's Toolkit:: (Ctk) -link::Guides/UsingQuarks##quark:: offers a convenient model for working in a -score based paradigm in both Realtime and Non-Realtime. - -The example here, link::#ATK and Score#as above::, decodes a B-format input -file to Stereo Ambisonic UHJ using the ATK's -link::Classes/FoaDecoderKernel#*newUHJ:: decoder. - - -code:: -( -var score, sndbuf, sndPath, decoder, synth, duration, sampleRate, headerFormat, sampleFormat, numChannels; - -// define our CtkScore -score = CtkScore.new; - -// the path to our B-Format sound file -sndPath = Atk.userSoundsDir ++ "/b-format/Pampin-On_Space.wav"; - -// get some info about the soundfile we are decoding for the Score requirements -SoundFile.use( - sndPath, - {arg soundFile; - headerFormat = soundFile.headerFormat; - sampleFormat = soundFile.sampleFormat; - sampleRate = soundFile.sampleRate; - numChannels = soundFile.numChannels; - duration = soundFile.duration; - } -); - -// define a CtkBuffer and add it to our score -sndbuf = CtkBuffer.playbuf(sndPath).addTo(score); - -// define a decoder of your choosing -// the decoder takes a score argument so that it will add the kernels to the score for you -decoder = FoaDecoderKernel.newUHJ( - sampleRate: sampleRate, - score: score -); - -// define a CtkSynthDef -synth = CtkSynthDef(\kernelDecode, {arg buffer; - var out, src; - - // play a sound file from a buffer - src = PlayBuf.ar(numChannels, buffer, BufRateScale.kr(buffer)); - - // decode our B-format sound file - out = FoaDecode.ar(src, decoder); - - Out.ar(0, out); -}); - -// create a synth note and add it to the score -score.add( - synth.note(0.0, duration).buffer_(sndbuf) -); - -// write our score to disk -score.write("~/Desktop/myDecode.wav".standardizePath, - sampleRate: sampleRate, - headerFormat: headerFormat, - sampleFormat: sampleFormat, - options: ServerOptions.new.numOutputBusChannels_(decoder.numChannels) -); -) -:: - -And, this example uses both a Kernel -link::Classes/FoaEncoderKernel##Encoder:: and -link::Classes/FoaDecoderKernel##Decoder::. First an -link::https://en.wikipedia.org/wiki/Ambisonic_UHJ_format##Ambisonic UHJ:: soundfile -is encode to B-format. Then, it is decoded using the ATK's -link::Classes/FoaDecoderKernel#*newListen#binaural (HRTF) decoder:: decoder. - -code:: -( -var score, sndbuf, sndPath, encoder, decoder, synth, duration, sampleRate, headerFormat, sampleFormat, numChannels; - -// define our CtkScore -score = CtkScore.new; - -// the path to our B-Format sound file -sndPath = Atk.userSoundsDir ++ "/uhj/Palestrina-O_Bone.wav"; - -// get some info about the soundfile we are decoding for the Score requirements -SoundFile.use( - sndPath, - {arg soundFile; - headerFormat = soundFile.headerFormat; - sampleFormat = soundFile.sampleFormat; - sampleRate = soundFile.sampleRate; - numChannels = soundFile.numChannels; - duration = soundFile.duration; - } -); - -// define a CtkBuffer and add it to our score -sndbuf = CtkBuffer.playbuf(sndPath).addTo(score); - -// define the UHJ encoder -// the decoder takes a score argument so that it will add the kernels to the score for you -encoder = FoaEncoderKernel.newUHJ( - sampleRate: sampleRate, - score: score -); - -// define a decoder of your choosing -// the decoder takes a score argument so that it will add the kernels to the score for you -decoder = FoaDecoderKernel.newListen( - subjectID: 1013, - sampleRate: sampleRate, - score: score -); - -// define a CtkSynthDef -synth = CtkSynthDef(\kernelEncodeDecode, {arg buffer; - var out, encoded, src; - - // play a sound file from a buffer - src = PlayBuf.ar(numChannels, buffer, BufRateScale.kr(buffer)); - - // encode our UHJ sound file - encoded = FoaEncode.ar(src, encoder); - - // decode our B-format sound file - out = FoaDecode.ar(encoded, decoder); - - Out.ar(0, out); -}); - -// create a synth note and add it to the score -score.add( - synth.note(0.0, duration).buffer_(sndbuf) -); - -// write our score to disk -score.write("~/Desktop/myDecode.wav".standardizePath, - sampleRate: sampleRate, - headerFormat: headerFormat, - sampleFormat: sampleFormat, - options: ServerOptions.new.numOutputBusChannels_(decoder.numChannels) -); -) -:: diff --git a/source/ATK/sc/HelpSource/Guides/Guide-to-ATK-Matrix-Files.schelp b/source/ATK/sc/HelpSource/Guides/Guide-to-ATK-Matrix-Files.schelp deleted file mode 100644 index 4137102abb..0000000000 --- a/source/ATK/sc/HelpSource/Guides/Guide-to-ATK-Matrix-Files.schelp +++ /dev/null @@ -1,500 +0,0 @@ -title:: Guide to ATK Matrix Files -summary:: A guide to reading, writing, and storing ATK matrices. -categories:: Libraries>Ambisonic Toolkit - - -SECTION:: Directory Structure - -The ATK store assets in its Application Support directory: -code:: -Atk.userSupportDir -:: -This includes three default directories: -list:: -##strong::kernels:: (FIR filters for kernel en/decoders), -##strong::sounds:: (example sound files in A-format, B-format, &c.), -##strong::matrices:: (for encoding, decoding, xforming). -:: -These folders store the files shipped with the ATK. -You can also optionally add your own code::extensions:: folder, -in which you can store kernels and matrices of your own design. -Note this is different from SuperCollider's code::Extensions:: folder. -If you haven't yet added an code::extensions:: directory, you can see where -to put it by executing the following method: -code:: -Atk.userExtensionsDir // view it -Atk.userExtensionsDir.openOS // open it... if it exists! -:: - -There's a handy method that will build it for you in the expected structure: -code:: -Atk.createExtensionsDir -:: - -This will create a directory structure that lives in your next to your default -ATK assets. Note this creates both a strong::matrices:: folder structure, -and an identical strong::kernels:: folder structure for storing your custom kernels. -The full structure will look like this: -tree:: - ## teletype::Application Support:: - tree:: - ## teletype::ATK:: - tree:: - ## teletype::kernels:: (ATK default) - ## teletype::matrices:: (ATK default) - ## teletype::sounds:: (ATK default) - ## teletype::extensions:: (your custom additions) - tree:: - ## teletype::kernels:: - ## teletype::matrices:: - tree:: - ##teletype::FOA:: - tree:: - ##teletype::decoders:: - tree:: - ##myDecoderMatrix.txt - ##myDecoderMatrixForReaper.mosl.txt - ##myDecoderMatrixWithMetadata.yml - :: - ##teletype::encoders:: - ##teletype::xformers:: - :: - ##teletype::HOA1:: - ##teletype::HOA2:: - ##teletype::...:: - ##teletype::HOAN:: - :: - :: - :: - :: -:: -Each of the folders (code::FOA>encoders::, code::HOA5>decoders::, etc.) are -empty and ready to store matrices (and kernels) for use with the ATK-SC3 (this package) -and link::http://www.ambisonictoolkit.net/download/reaper/##ATK-Reaper:: (more -on that later). When you write a matrix using the ATK, it -will store it in this directory structure by default, and will look here by -default when asked to read in a matrix from file. - -You can view this structure and any files you've stored there using the following method: -code:: -Atk.postMyMatrices(); // All sets, all matrices types -Atk.postMyMatrices('FOA'); // FOA matrices hierarchy -Atk.postMyMatrices('FOA', 'encoders'); // FOA encoders only -Atk.postMyMatrices('FOA', 'decoders'); // FOA decoders only -Atk.postMyMatrices('FOA', 'xformers'); // FOA xformers only -:: - -Each of these matrix subdirectories can have further subdirectories at your -discretion, e.g. for particular projects or categories of matrices. - -SECTION::Writing Matrices - -We'll start by writing a matrix file. - -Let's create a first order A-format encoding matrix from a nine-point -link::https://en.wikipedia.org/wiki/Spherical_design##spherical t-design::. For -our purposes, we'll use a spherical designs with emphasis::d:: = 2, giving a -collection of uniformly distributed points on a sphere. -The t-design we're using below can be found in Hardin and Sloan's -link::http://neilsloane.com/sphdesigns/dim3##Library of 3-D Designs::. -footnote::Hardin, R. H. and Sloane, N. J. A., "Sperical Designs", http://neilsloane.com/sphdesigns/, accessed on July 29, 2016.:: - -code:: -( -// Spherical coordinates of the nine-point t-design. -~directions = [ - [ 0, 45 ], [ 120, 45 ], [ -120, 45 ], - [ 0, 0 ], [ 120, 0 ], [ -120, 0 ], - [ 0, -45 ], [ 120, -45 ], [ -120, -45 ] -].degrad; - -// Here's our 9-point A-format to B-format (planewave, aka velocity) encoder: -~encoder = FoaEncoderMatrix.newDirections(~directions); -) -:: - -This link::Classes/FoaEncoderMatrix:: is now ready to be used for encoding -planewaves arriving from those nine uniformly distributed incidences. Within -the ATK's classification hierarchy, code::~encoder:: looks like this: - -table:: - ## strong::set:: || strong::type:: || strong::op:: || strong::kind:: - ## code::'FOA':: || code::'encoder':: || code::'matrix':: || code::'dirs':: -:: - -For fun, let's inspect: - -code:: -( -var methodsToInspect = ['class', 'set', 'type', 'op', 'kind' ]; - -methodsToInspect.do({arg item; (item.asString ++ " : " ++ ~encoder.perform(item)).postln;}) -) -:: - - -After all that hard work (thanks ATK!), we want to store the result to a file for -use in the future, and to use in -link::http://www.ambisonictoolkit.net/download/reaper/##ATK-Reaper:: plugins! -footnote::ATK-Reaper will support matrix loading in an upcoming release.:: - -There are three available file formats, each with a special purpose: - -list:: -##code::.txt:: : the most basic text file, writing the raw matrix only. -##code::.yml:: : store the matrix along with metadata in a human readable format. -##code::.mosl.txt:: : a text file formatted for use with ATK-Reaper JSFX-plugins. -:: - -Let's write this encoder matrix out in all three formats: - -code:: -// .txt extension writes the matrix only -~encoder.writeToFile("my9PointEncoder.txt"); - -// .yml writes metadata as well -~encoder.writeToFile("my9PointEncoder.yml"); - -// .mosl.txt writes matrix only, single lines for Reaper to read -~encoder.writeToFile("my9PointEncoder.mosl.txt"); -:: - -Because we only specified a file name, not a full path, -the ATK will store the matrix in the default location. -As we're writing an link::Classes/FoaEncoderMatrix::, ATK can infer that -it's an strong::encoder:: in the strong::FOA:: set. (We also know, we're dealing -with a strong::matrix:: operation.) -Therefore, the ATK knows to put it in: code::../extensions/matrices/FOA/encoders::. - -Had we specified a full path instead, it would have saved to that location. - -code:: -// Here are our encoders (defaults to showing the FOA set) -Atk.postMyMatrices('FOA', 'encoders'); -:: - - -SUBSECTION::Writing Metadata - -Because this matrix encoder is somewhat unique, it would be helpful to provide a bit more information -about it for future reference. This is where the code::.yml:: file format comes in. - -Note that the link::Classes/AtkMatrix#-writeToFile:: method has some optional -arguments: code::note:: and code::attributeDictionary::. A code::note:: can be a -brief description, while an code::attributeDictionary:: is a Dictionary for storing any -info you'd like in the form of key:value pairs. - -code:: -( -// A 'note': a description or note about the matrix. -~note = "This is a nine-point t-design encoder made for a matrix file writing demo."; - -// A Dictionary of more metadata to add. -~properties = ( - author: "Me, the Reader", - dateCreated: Date.getDate.stamp, - ordering: 'FuMa', - normalisation: 'MaxN', - dirInputs: ~directions -); -) -:: - -NOTE:: -If keys in the strong::attributeDictionary:: match instance variables of FoaEncoderMatrix, -they can be retrieved with getters once loaded from the file. This is the case for -strong::dirInputs:: specified in the code::~properties:: dictionary above. -We'll see the effect this has below. -:: - -Now write this matrix and metadata to file... -Be sure to specify the code::.yml:: extension in order to write the metadata. -Set strong::overwrite:: code::= true:: to force overwrite the file we wrote before with -the same name and extension. - -code:: -( -~encoder.writeToFile( "my9PointEncoder.yml", - note: ~note, - attributeDictionary: ~properties, - overwrite: true -) -) -:: - -SUBSECTION:: Writing Raw Matrices -In the above examples, we've been reading/writing matrices encapsulated in -the link::Classes/AtkMatrix:: subclasses. When writing from these objects, some the information -can be inferred from them, such as the strong::set:: (Ambisonic order, -channel ordering, channel normalisation, e.g. code::'FOA'::, code::'HOA3'::, -etc.) and strong::type:: of matrix (e.g. code::'encoder', 'decoder', 'xformer'::). -In the case of a raw matrix, you must cast it to an code::AtkMatrix::, specifying the -strong::set:: and strong::type:: explicitly, before writing it to a file. - -code:: -( // Here's a raw A-to-B encoder matrix: -~matrix = Matrix.with([ - [ 0.61237243569579, 0.61237243569579, 0.61237243569579, 0.61237243569579 ], - [ 0.5, 0.5, -0.5, -0.5 ], - [ 0.5, -0.5, 0.5, -0.5 ], - [ 0.5, -0.5, -0.5, 0.5 ] -]) -) -:: - -Metadata is useful to record more information about the matrix: - -code:: -( -~note = "A 4-channel A-to-B encoder matrix, in Front-Left-Up orientation."; - -// A Dictionary of more metadata to add. -~properties = ( - author: "Me, the Reader", - dateCreated: Date.getDate.stamp, - ordering: 'FuMa', - normalisation: 'MaxN', - dirInputs: [ [ 0.78539816339745, 0.61547970867039 ], [ -0.78539816339745, -0.61547970867039 ], [ 2.3561944901923, -0.61547970867039 ], [ -2.3561944901923, 0.61547970867039 ] ] -); -) -:: - -Be sure to specify the strong::set:: and strong::type:: when creating an -code::AtkMatrix:: from your code::Matrix::. This is how the ATK will know where -to store the file by default (unless a full path is provided to the file name -argument). - -code:: -( -~atkMatrix = ~matrix.asAtkMatrix('FOA', 'encoder'); // set, type -// be sure to use .yml extension for metadata -~atkMatrix.writeToFile("myA2B_flu_Matrix.yml", ~note, ~properties); -) -:: - -NOTE:: If providing a file path relative to your code::/ATK/extension/matrices/...:: -directory, strong::set:: and strong::type:: arguments are necessary when creating the -code::AtkMatrix:: from your code::Matrix:: in order to locate the -proper directory to store your file. If providing an absolute file path, -strong::set:: and strong::type:: are recommended but not strictly enforced. This -allows storing matrices outside the ATK paradigm, e.g. VBAP matrices, etc. -:: - -There it is: -code:: -Atk.postMyMatrices('FOA', 'encoders'); -:: - -SUBSECTION:: Subfolders: Organizing your matrices - -If you'll be generating many matrices, it's advisable to organize your matrices into -subfolders. For example, if you're algorithmically generating hundreds of matrices -for a particular project or process, it makes sense to store them in a subfolder. - -To do this, you can create subfolders inside your code::/encoders::, code::/decoders::, -and code::/xformers:: folders. - -code:: -// Store your encoder matrix with the other encoders, which live here: -Atk.getMatrixExtensionSubPath('FOA', 'encoders'); - -// You can make subfolder for a group of matrices, say, for a particular project: -( -~projSubFolderName = "myProject"; - -File.mkdir( Atk.getMatrixExtensionSubPath('FOA', 'encoders').fullPath +/+ ~projSubFolderName ) -) - -// For convenience, we'll write the 9-point ~encoder matrix, -// which we created above, to a new file in your new project folder. -// (We'll need to reset ~note and ~properties, as we clobbered them above!) -( - -// A 'note': a description or note about the matrix. -~note = "This is a nine-point t-design encoder made for a matrix file writing demo."; - -// A Dictionary of more metadata to add. -~properties =  ( -    author: "Me, the Reader", -    dateCreated: Date.getDate.stamp, -    ordering: 'FuMa', -    normalisation: 'MaxN', -    dirInputs: ~directions -); - -~encoder.writeToFile(~projSubFolderName +/+ "projectEncoder1.yml", - note: ~note, - attributeDictionary: ~properties -) -) -:: - -NOTE:: Remember that because code::~encoder:: is an link::Classes/FoaEncoderMatrix::, -the strong::set:: (code::'FOA'::) and strong::type:: (code::'encoder'::) -arguments are inferred. -:: - -code:: -// There it is, in the 'myProject' subdirectory. -Atk.postMyMatrices('FOA', 'encoders') -:: - -Later you'll use link::Classes/FoaEncoderMatrix:: to read the file back in. -ATK will know where to look ( code::extensions/matrices/enocoders/FOA:: ) -so you can simply specify the emphasis::relative:: path of your code::subfolder/file.yml::: - -code:: -~projectEncoder1 = FoaEncoderMatrix.newFromFile(~projSubFolderName +/+ "projectEncoder1.yml"); - -~projectEncoder1.info; -:: - -SECTION:: Reading Matrices - -We wrote three encoder matrix files earlier. Let's now read them in. As when writing, -the ATK looks in the strong::extensions/matrices:: directory by default. Unless -the matrix file is somewhere outside the default location, a filename -will suffice to read it in. The strong::type:: (code::'encoder'::, code::'decoder'::, -code::'xformer'::) is inferred from the object being instantiated. - -We can even omit the file extension if we don't expect multiple file -emphasis::formats:: (code::.txt, .yml, .mosl.txt::) stored under the same emphasis::name::: - -code:: -~encoder = FoaEncoderMatrix.newFromFile("my9PointEncoder") -// >> ERROR: It sees we have more than one file with that name. -:: - -So, we'll need to specify the extension. As mentioned before, each file format -determines what kind of information is stored in the file. - -Lets have a look at what each file format gives us back: - -code::.txt:: format: -code:: -// Reading the .txt file, we just get a matrix and basic info. -~encoder = FoaEncoderMatrix.newFromFile("my9PointEncoder.txt"); - -// All the standard instance vars are preserved. -~encoder.matrix; -~encoder.kind; // Defaults to filename -~encoder.dirOutputs; // Outputs are inf, becuase the output is b-format, i.e "all directions". -~encoder.dirInputs; // With no metadata, we can't know input directions, so 'unspecified' -~encoder.dirInputs.size;// ...but knowing how large the array is tells us how many inputs the matrix expects -~encoder.dim; // We see it's a 3-D matrix -:: - -code::.mosl.txt:: format: -code:: -// reading the mosl.txt file, we just get a matrix and basic info -~encoder = FoaEncoderMatrix.newFromFile("my9PointEncoder.mosl.txt"); - -// all the standard instance vars are preserved -~encoder.matrix; -~encoder.kind; // Defaults to filename -~encoder.dirOutputs; // inf, by nature of encoding to b-format -~encoder.dirInputs; // With no metadata, we can't know input directions -~encoder.dim; -:: - -code::.yml:: format: -code:: -// reading the .yml file, we get the matrix plus metadata -~encoder = FoaEncoderMatrix.newFromFile("my9PointEncoder.yml"); - -// all the standard instance vars are preserved -~encoder.matrix; -~encoder.kind; -~encoder.dirOutputs; -~encoder.dim; - -// NOTE: because we provided the 'dirInputs' to the attributeDictionary -// when we wrote it to file, we now have that info for reference. Useful! -~encoder.dirInputs; - - -// Plus the other data written to it: -~encoder.info; // Formatted post - -// Metadata is loaded as an IndentityDictionary, so values -// from the attributeDictionary can be accessed by their -// keys as pseudo-methods. -~encoder.fileParse; // For direct access to the dictionary of values -~encoder.fileParse.note; // What was this matrix again?? Oh yea... -~encoder.fileParse.ordering; -~encoder.fileParse.keysValuesDo{|k,v| postf("% : %\n", k, v)}; -:: - - -SUBSECTION:: Test case: Creating a decoder from an FoaEncoderMatrix - -We've now instantiated a new code::~encoder:: by reading in the file that stored -the matrix that we originally built using the planewave encoder: -link::Classes/FoaEncoderMatrix#*newDirections:: (using the points of a nine-point t-design). -As it turns out, a matrix emphasis::encoder:: created by -link::Classes/FoaEncoderMatrix#*newDirections:: can be used to build -a emphasis::decoder:: of the same geometry. footnote::Recall -the ATK's matching A-format link::Classes/FoaEncoderMatrix#*newAtoB#encoders:: and -link::Classes/FoaDecoderMatrix#*newBtoA#decoders::!:: -Doing so just involves performing the link::Classes/Matrix#-pseudoInverse:: on the -encoder's Matrix. footnote::This decoder design method is often described -as emphasis::pseudo-inverse:: or emphasis::mode-matching::.:: - -code:: -// Retrieve the Matrix object stored in the FoaEncoderMatrix -// (Should be the 9-point t-design from above!) -~encoderMatrix = ~encoder.matrix; - -// Perform the pseudoinverse on that matrix to find decoding coefficients -~decoderMatrix = ~encoderMatrix.pseudoInverse; -:: - -Using these coefficients will return a code::'velocity':: decode (aka "strict -soundfield" or "basic"). Loudspeakers should be positioned in the following -directions (and in this order): -code:: -~encoder.dirInputs.do{|azElPairs, i| postf("chan %: %\n", i, azElPairs.raddeg) } -:: - - -NOTE:: -Because we're inverting an encoder to produce a decoder, the original -emphasis::input directions:: of the strong::encoder:: will now be the -emphasis::output directions:: of the strong::decoder::. -The channel ordering will be in the same order the input directions were -specified in the encoder. Therefore, in the above code we query the -emphasis::encoder:: for its code::-dirInputs:: to know where our output channel -signals are expected to be sent (in space!). -:: - -It's important to note here that the code::~decoderMatrix:: matrix is a link::Classes/Matrix:: object, -not an link::Classes/FoaDecoderMatrix:: object. As such, we'll need to use care when building -the decoding SynthDef. Instead of using the link::Classes/FoaDecode:: UGen -(which expects an FoaDecoderMatrix or FoaDecoderKernel decoder), -we'll use the link::Classes/AtkMatrixMix:: UGen, which will decode our B-format -signal by using our newly authored decoding Matrix, code::~decoderMatrix::. - -code:: -( -~decoderDef = SynthDef(\pinv_decoder, { arg outbus=0, amp=1; - var foa, out; - - // Test signal: panning noise - foa = FoaPanB.ar( PinkNoise.ar, LFSaw.kr( 12.reciprocal, 1 ), 0 ); - - // ~decoderMatrix is just a Matrix of decoding coefficients, so we use AtkMatrixMix - out = AtkMatrixMix.ar(foa, ~decoderMatrix, amp); - - Out.ar(outbus, out); - -}).load(Server.default); -) - -~decoderSynth = Synth(\pinv_decoder, [\outbus, 0, \amp, -8.dbamp]); - -// Scope the 9 channels of the decoded output -s.scope(9, 0); - -// Clean up -~decoderSynth.free; -:: diff --git a/source/ATK/sc/HelpSource/Guides/Intro-to-the-ATK.schelp b/source/ATK/sc/HelpSource/Guides/Intro-to-the-ATK.schelp deleted file mode 100644 index 54b9cd68ad..0000000000 --- a/source/ATK/sc/HelpSource/Guides/Intro-to-the-ATK.schelp +++ /dev/null @@ -1,467 +0,0 @@ -title:: Introducing the Ambisonic Toolkit -summary:: Introduction to the Ambisonic Toolkit -categories:: Libraries>Ambisonic Toolkit -keyword::Atk - -section:: The paradigm - -The Ambisonic Toolkit (ATK) brings together a number of classic and novel tools and transforms for the artist working with Ambisonic surround sound and makes these available to the SuperCollider3 user. The toolset in intended to be both ergonomic and comprehensive, and is framed so that the user is encouraged to ‘think Ambisonically’. By this, it is meant the ATK addresses the holistic problem of creatively controlling a complete soundfield, allowing and encouraging the artist to think beyond the placement of sounds in a sound-space (sound-scene paradigm). Instead the artist is encouraged to attend to the impression and imaging of a soundfield, therefore taking advantage of the native soundfield-kernel paradigm the Ambisonic technique presents. - -The ATK's production model is illustrated below: - -image::atknetwork.png#ATK paradigm:: - -Here you'll see that the ATK breaks down the task of working with Ambisonics into three separate elements: - -definitionlist:: -## Author || Capture or synthesise an Ambisonic soundfield. -## Image || Spatially filter an Ambisonic soundfield. -## Monitor || Playback or render an Ambisonic soundfield. -:: - -The below sections go into more detail as to the specifics of each task. For examples that show more concise examples for usage in SynthDef and NRT, see link::Guides/ATK-SynthDef-Examples:: - - -section:: Authoring - -Most users approaching Ambisonics are usually presented with two avenues to author an Ambisonic soundfield: capture a natural soundfield directly with a Soundfield microphone, footnote::J.-M. Batke, "The B-Format Microphone Revised," presented at the Ambisonics Symposium 2009, Graz, 2009. -:: or author a planewave from a monophonic signal. footnote::D. G. Malham and A. Myatt, "3-D Sound Spatialization using Ambisonic Techniques," Computer Music Journal, vol. 19, no. 4, pp. 58-70, 1995.:: SuperCollider's inbuilt link::Classes/PanB:: provides the latter solution. - -The ATK provides a much wider palate of authoring tools via link::Classes/FoaEncode::. These include: - -list:: -## emphasis::planewave: :: classic directional encoding -## emphasis::omnidirectional: :: a soundfield from everywhere -## emphasis::virtual loudspeaker array: :: transcoding standard formats -## emphasis::pseudoinverse microphone array: :: encoding from discrete microphones or signals -:: - -The emphasis::pseudoinverse:: encoding technique provides the greatest flexibility, and can be used with both microphone arrays and synthetic signals. In the absence of a Soundfield microphone, this feature gives the opportunity to deploy real-world microphone arrays (omni, cardioid, etc.) to capture natural soundfields. With synthetic signals, emphasis::pseudoinverse:: encoding is usually regarded as the method of choice to generate spatially complex synthetic Ambisonic images. In combination with the ATK's link::#Imaging#imaging:: tools these can then be compositionally controlled as required. - -See link::Classes/FoaEncode::, link::Classes/FoaEncoderMatrix:: and link::Classes/FoaEncoderKernel:: for more details about encoding. - - - -section:: Imaging - -For the artist, the real power of the ATK is found in the imaging transforms. These are spatial domain filters which reorient, reshape or otherwise spatially filter an input soundfield. Many users will be familiar with the soundfield rotation transform, as SuperCollider provides the inbuilt link::Classes/Rotate2::. - -The ATK provides a much wider and comprehensive toolset, including: - -list:: -## emphasis::rotation: :: soundfield rotation about an axis -## emphasis::mirror: :: soundfield reflection across an axis -## emphasis::directivity: :: soundfield directivity -## emphasis::dominance: :: adjust directional gain of soundfield -## emphasis::focus: :: focus on a region of a soundfield -## emphasis::push: :: push a soundfield in a direction -:: - -The imaging tools are provided in two forms: link::Classes/FoaXform##static:: and link::Classes/FoaTransform##dynamic:: implementations. While most transforms are provided in both categories, a number are found in only one guise. footnote::It is also useful to note that the link::Classes/FoaTransform##dynamic:: transforms are also available as individual UGens. However, users are advised to use link::Classes/FoaTransform:: for convenience.:: - -See link::Classes/FoaTransform::, link::Classes/FoaXform:: and link::Classes/FoaXformerMatrix:: for more details about imaging. - - -subsection:: Reading imaging illustrations - -As artists working with sound, we should expect most users to be very capable expert listeners, and able to audition the results of spatial filtering of an input soundfield. However, it is often very convenient to view a visual representation of the effect of a soundfield transform. The ATK illustrates a number of its included transforms in the form shown below. - -The emphasis::X-Y:: axis is shown, as viewed from above with the top of the plot corresponding to the front of the soundfield, emphasis::+X::. On the left hand side of the figures, an unchanged soundfield composed of eight planewave is shown. These are indicated as coloured circles, and arrive from cardinal directions: - -list:: -## Front -## Front-Left -## Left -## Back-Left -## Back -## Back-Right -## Right -## Front-Right -:: - -Three useful features are displayed in these plots, providing inportant insight as to how an input soundfield will be modified by a transform: - -list:: -## emphasis::incidence:: footnote::emphasis::Incidence:: is measured in terms of the emphasis::(Active) Intensity:: vector.:: : illustrated as emphasis::polar angle:: -## emphasis::quality:: footnote::emphasis::Quality:: is measured as the magnitude of the emphasis::Energy Normalised (Active) Intensity:: vector, aka emphasis::rE::.:: : illustrated as emphasis::radius:: -## emphasis::gain:: footnote::emphasis::Gain:: reported is the emphasis::Potential-Kinetic Energy Mean::, aka emphasis::Soundfield Energy::.:: : illustrated via emphasis::colour:: -:: - - -Individual planewaves are coloured with respect to the gain scale at the far left of the figures. Additionally, emphasis::Front::, emphasis::Left::, emphasis::Back-Left:: and emphasis::Back:: are annotated with a numerical figure for emphasis::gain::, in dB. - - -subsection:: Soundfield quality - -The meaning of transformation to soundfield emphasis::incidence:: and emphasis::gain:: should be clear. Understading the meaning of soundfield emphasis::quality:: takes a little more effort. This feature describes how emphasis::apparently localised:: an element in some direction will appear. - -A planewave has a emphasis::quality:: measure of code::1.0::, and is heard as localised. At the opposite end of the scale, with a emphasis::quality:: measure of code::0.0::, is an omnidirectional soundfield. This is heard to be emphasis::without direction:: or emphasis::"in the head"::. As you'd expect, intermediate measures are heard as scaled between these two extremes. - - -subsection:: Reading ZoomX - -anchor::zoom:: -image::../Classes/zoom_fig.png#ZoomX imaging:: - -With changing link::Classes/FoaZoomX##ZoomX::'s strong::angle::, we see the eight cardinal planewaves both move towards the front of the image and change gain. When strong::angle:: is 90 degrees, the gain of the planewave at emphasis::Front:: has been increased by 6dB, while emphasis::Back:: has disappeared. footnote::Decreased to -inf dB:: We also see the soundfield appears to have collapsed to a single planewave, incident at 0 degrees. footnote::Or, we might describe this as applying directionally dependent gains across the whole soundfield, mixing, and then re-incoding to a single planewave.:: - -subsection:: Reading PushX - -anchor::push:: -image::../Classes/push_fig.png#PushX imaging:: - -link::Classes/FoaPushX##PushX:: also distorts the incident angles of the cardinal planewaves. However, here we see two differences with link::#zoom#ZoomX::. The gains of the individual elements don't vary as considerably. More intriguingly, a number of the encoded planewaves are illustrated as moving off the perimeter of the plot, indicating a change in soundfield link::#Soundfield quality#quality::. - -Moving from the edge of the plot towards the centre emphasis::does not imply:: the sound moves from the edge of the loudspeakers towards the centre, as one might expect. Instead, what we are seeing is the loss of directivity. Moving towards the centre means a planewave moves toward becoming omnidirectional, or without direction. (This becomes clearer when we look at link::#Reading DirectO#DirectO::.) A reducing radius indicates a reducing soundfield emphasis::quality::. - -When link::Classes/FoaPushX##PushX::'s strong::angle:: is 90 degrees, all encoded planewaves have been emphasis::pushed:: to the front of the image. Unlike link::#Reading ZoomX#ZoomX::, gain is retained at 0 dB for all elements. footnote::Equivalent to mixing all elements (scaled by 0dB), and then re-incoding to a single planewave.:: - -subsection:: Reading DirectO - -anchor::direct:: -image::../Classes/direct_fig.png#DirectO imaging:: - -link::#direct#DirectO:: adjusts the directivity of the soundfield across the origin. Here we see the cardinal planewaves collapsing towards the centre of the plot. At this point the soundfield is omnidirectional, or directionless. See further discussion of soundfield link::#Soundfield quality#quality:: above. - -See link::Classes/FoaZoomX::, link::Classes/FoaPushX:: and link::Classes/FoaDirectO:: for more details regarding use of these associated UGens. - - -subsection:: Illustrated transforms - -Additionally, the following UGens include figures illustration imaging transformation: - -list:: -## link::Classes/FoaAsymmetry:: -## link::Classes/FoaBalance:: -## link::Classes/FoaDirectO:: -## link::Classes/FoaDirectX:: -## link::Classes/FoaDirectY:: -## link::Classes/FoaDominateX:: -## link::Classes/FoaFocusX:: -## link::Classes/FoaPressX:: -## link::Classes/FoaPushX:: -## link::Classes/FoaZoomX:: -:: - -Explore these to get a sense of the wide variety of image transformation tools available in the ATK. - -section:: Monitoring - -Perhaps one of the most celebrated aspects of the Ambisonic sound technique has been its design as a hierarchal reproduction system, able to target a number of varying loudspeaker arrays. Users may be familiar with SuperCollider's inbuilt regular polygon decoder, link::Classes/DecodeB2::. - -The ATK provides a much wider palate of optimised monitoring tools via link::Classes/FoaDecode::. These include: - -list:: -## emphasis::stereo UHJ: :: classic Ambisonic stereo decoding -## emphasis::binaural: :: measured and synthetic HRTFs -## emphasis::regular 2D & 3D: :: single and dual polygons -## emphasis::diametric 2D & 3D: :: flexible semi-regular arrays -## emphasis::5.0: :: link::http://www.brucewiggins.co.uk/##Wiggins:: optimised decoders -:: - -While the emphasis::regular:: decoders will be suitable for many users, emphasis::diametric:: decoding enables the greatest flexibility, and allows the user to design substantially varying semi-regular arrays suitable for a wide variety of playback situations. - -note:: All decoders presume loudspeakers are placed at equal radii from the origin of the array, and gain is normalised. Loudspeaker arrays with unequal radii may be realised if the resulting wavefront arrival times are compensated through the use of delay lines.:: - - -See link::Classes/FoaDecode::, link::Classes/FoaDecoderMatrix:: and link::Classes/FoaDecoderKernel:: for more details about decoding. - - -section:: Installation - -The ATK library for SuperCollider3 is distributed via the link::https://github.com/supercollider/sc3-plugins/##sc3-plugins:: project. If you're reading this document, these extensions have most likely been corectly installed. - -Additionally, the ATK has a number of dependencies. Please install the following: - -list:: -##link::https://github.com/supercollider-quarks/MathLib/##MathLib:: Quark. - -##link::https://github.com/supercollider-quarks/FileLog##FileLog:: Quark. - -##link::http://www.ambisonictoolkit.net/download/kernels/##ATK Kernels:: - -##link::http://www.ambisonictoolkit.net/download/recordings/##ATK Example Soundfiles:: -:: - -For link::Classes/Quark:: installation, see: link::Guides/UsingQuarks:: and the link::https://github.com/supercollider-quarks/quarks/##Quarks for SuperCollider:: project. - -section:: Examples - -The examples below are intended to briefly illustrate playback and imaging of soundfields with the ATK. The user is encouraged to explore the ATK's documentation to gain a deeper understanding of the flexibility of these tools. - -As the Ambisonic technique is a hierarchal system, numerous options for playback are possible. These include two channel stereo, two channel binaural, pantophonic and full 3D periphonic. With the examples below, we'll take advantage of this by first choosing a suitable decoder with with to audition. - -subsection:: Choose a decoder - -A number of decoders are defined below. Please choose one suitable for your system. Also, don't forget to define code:: ~renderDecode :: ! - -note:: If you choose a kernel decoder, link::Classes/FoaDecoderKernel::, be sure to free the kernel after use. :: - -code:: -// ------------------------------------------------------------ -// boot server -( - s = Server.default; - s.boot; -) - - -// ------------------------------------------------------------ -// define convenience function to verify number of server outputs -( -~checkMyServerOutputs = { arg server, decoder; - server.serverRunning.if({ - (decoder.numOutputs > server.options.numOutputBusChannels).if({ - "Number of Server output bus channels is less than number required by Decoder!".warn; - "Server Outputs: %\n".postf(server.options.numOutputBusChannels); - "Decoder Outputs: %\n\n".postf(decoder.numOutputs); - "Update number of Server outputs as illustrated here: ".post; - "http://doc.sccode.org/Classes/ServerOptions.html#examples".postln; - }, { - "Server has an adequate number of output bus channels for use with this Decoder!".postln; - }) - }) -} -) - - -// ------------------------------------------------------------ -// choose a decoder - -// stereophonic / binaural -~decoder = FoaDecoderMatrix.newStereo((131/2).degrad, 0.5) // Cardioids at 131 deg -~decoder = FoaDecoderKernel.newUHJ // UHJ (kernel) -~decoder = FoaDecoderKernel.newSpherical // synthetic binaural (kernel) -~decoder = FoaDecoderKernel.newCIPIC // KEMAR binaural (kernel) - - -// pantophonic (2D) -~decoder = FoaDecoderMatrix.newQuad(k: 'dual') // psycho optimised quad -~decoder = FoaDecoderMatrix.newQuad(pi/6, 'dual') // psycho optimised narrow quad -~decoder = FoaDecoderMatrix.new5_0 // 5.0 -~decoder = FoaDecoderMatrix.newPanto(6, k: 'dual') // psycho optimised hex - - -// periphonic (3D) -~decoder = FoaDecoderMatrix.newPeri(k: 'dual') // psycho optimised cube -~decoder = FoaDecoderMatrix.newDiametric( // psycho optimised bi-rectangle - [[30, 0], [-30, 0], [90, 35.3], [-90, 35.3]].degrad, - 'dual' -) - - -// inspect -~decoder.kind -~checkMyServerOutputs.value(s, ~decoder) - - -// ------------------------------------------------------------ -// define ~renderDecode -( -~renderDecode = { arg in, decoder; - var kind; - var fl, bl, br, fr; - var fc, lo; - var sl, sr; - var flu, blu, bru, fru; - var fld, bld, brd, frd; - var slu, sru, sld, srd; - - - kind = decoder.kind; - - case - { decoder.numChannels == 2 } - { - // decode to stereo (or binaural) - FoaDecode.ar(in, decoder) - } - { kind == 'quad' } - { - // decode (to quad) - #fl, bl, br, fr = FoaDecode.ar(in, decoder); - - // reorder output to match speaker arrangement - [fl, fr, bl, br] - } - { kind == '5.0' } - { - // decode (to 5.0) - #fc, fl, bl, br, fr = FoaDecode.ar(in, decoder); - lo = Silent.ar; - - // reorder output to match speaker arrangement - [fl, fr, fc, lo, bl, br] - } - { kind == 'panto' } - { - // decode (to hex) - #fl, sl, bl, br, sr, fr = FoaDecode.ar(in, decoder); - - // reorder output to match speaker arrangement - [fl, fr, sl, sr, bl, br] - } - { kind == 'peri' } - { - // decode (to cube) - #flu, blu, bru, fru, fld, bld, brd, frd = FoaDecode.ar(in, decoder); - - // reorder output to match speaker arrangement - [flu, fru, blu, bru, fld, frd, bld, brd] - } - { kind == 'diametric' } - { - // decode (to bi-rectangle) - #fl, fr, slu, sru, br, bl, srd, sld = FoaDecode.ar(in, decoder); - - // reorder output to match speaker arrangement - [fl, fr, bl, br, slu, sru, sld, srd] - }; -} -) - -// ------------------------------------------------------------ -// now we're ready to try the examples below! -// ------------------------------------------------------------ -:: - - -subsection:: Produced via the Ambisonic Toolkit - -The following three sound examples are excerpts from recordings produced via the ATK. - -If you haven't already choosen a code:: ~decoder:: and defined code:: ~renderDecode ::, do so link::#Choose a decoder#now::. - - -code:: -// ------------------------------------------------------------ -// B-format examples, produced via the ATK -// B-format soundfile read from disk - - -// read a whole sound into memory -// remember to free the buffer later! -// (boot the server, if you haven't!) -~sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/b-format/Anderson-Pacific_Slope.wav") -~sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/b-format/Howle-Calling_Tunes.wav") -~sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/b-format/Pampin-On_Space.wav") - - - -( -{ - var sig; // audio signal - - - // display encoder and decoder - "Ambisonic decoding via % decoder".format(~decoder.kind).postln; - - // ------------------------------------------------------------ - // test sig - sig = PlayBuf.ar(~sndbuf.numChannels, ~sndbuf, BufRateScale.kr(~sndbuf), doneAction:2); // soundfile - - - // ------------------------------------------------------------ - // decode (via ~renderDecode) - ~renderDecode.value(sig, ~decoder) - -}.scope; -) - -// free buffer -~sndbuf.free -// ------------------------------------------------------------ -:: - -note:: strong::Soundfile Credits:: - -list:: -## Joseph Anderson, "Pacific Slope," Epiphanie Sequence, Sargasso SCD28056 -## Tim Howle, "Calling Tunes," 20 Odd Years, FMR FMRCD316-0711 -## Juan Pampin, "On Space," Les Percussions de Strasbourg 50th Anniversary Edition, Classics Jazz France 480 6512 -:: - -:: - - -subsection:: Natural soundfields, with imaging transforms - -This example illustrates the application of various spatial filtering transforms to natural soundfields, recorded via the Soundfield microphone. - -The soundfield is controlled by link::Classes/MouseY::, which specifies the transform strong::angle:: argument (90 deg to 0 deg; top to bottom of display). With the mouse at the bottom of the display, the recorded soundfield is unchanged. At the top, the transform is at its most extreme. - -If you haven't already choosen a code:: ~decoder:: and defined code:: ~renderDecode ::, do so link::#Choose a decoder#now::. - -note:: See link::Classes/FoaTransform:: for further details.:: - -code:: -// ------------------------------------------------------------ -// B-format examples, natural soundfield with imaging transform -// B-format soundfile read from disk - -// choose transformer -~transformer = 'zoomX' -~transformer = 'pushX' -~transformer = 'directO' - - - -// read a whole sound into memory -// remember to free the buffer later! -// (boot the server, if you haven't!) -~sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/b-format/Hodges-Purcell.wav") -~sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/b-format/Leonard-Orfeo_Trio.wav") -~sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/b-format/Courville-Dialogue.wav") -~sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/b-format/Leonard-Chinook.wav") -~sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/b-format/Leonard-Fireworks.wav") -~sndbuf = Buffer.read(s, Atk.userSoundsDir ++ "/b-format/Anderson-Nearfield.wav") - - -( -{ - var sig; // audio signal - var angle; // angle control - - - // display transformer & decoder - "Ambisonic transforming via % transformer".format(~transformer).postln; - "Ambisonic decoding via % decoder".format(~decoder.kind).postln; - - // gain ---> top = 90 deg - // bottom = 0 deg - angle = MouseY.kr(pi/2, 0); - - - // ------------------------------------------------------------ - // test sig - sig = PlayBuf.ar(~sndbuf.numChannels, ~sndbuf, BufRateScale.kr(~sndbuf), doneAction:2); // soundfile - - // ------------------------------------------------------------ - // transform - sig = FoaTransform.ar(sig, ~transformer, angle); - - - // ------------------------------------------------------------ - // decode (via ~renderDecode) - ~renderDecode.value(sig, ~decoder) - -}.scope; -) - -// free buffer -~sndbuf.free -// ------------------------------------------------------------ -:: - -note:: strong::Soundfile Credits:: - -list:: -## P. Hodges, "Purcell - Passacaglia (King Arthur)," Sound of Space: ambisonic surround sound. [Online]. Available: http://soundofspace.com/ambisonic_files/52 [Accessed: 03-Nov-2011]. -## J. Leonard, "The Orfeo Trio & TetraMic," Sound of Space: ambisonic surround sound. [Online]. Available: http://soundofspace.com/ambisonic_files/41 [Accessed: 03-Nov-2011]. -## D. Courville, "Comparative Surround Recording," Ambisonic Studio | Comparative Surround Recording, 2007. [Online]. Available: http://www.radio.uqam.ca/ambisonic/comparative_recording.html [Accessed: 26-Jul-2011]. -## J. Leonard, ""A couple of Chinook helicopters," Sound of Space: ambisonic surround sound, 20-Mar-2008. [Online]. Available: http://soundofspace.com/ambisonic_files/47. [Accessed: 03-Nov-2011]. -## J. Leonard, “Fireworks,” Sound of Space: ambisonic surround sound, 25-Aug-2009. [Online]. Available: http://soundofspace.com/ambisonic_files/37. [Accessed: 03-Nov-2011]. -## Joseph Anderson, "Nearfield source," [unpublished recording] -:: - -:: diff --git a/source/ATK/sc/HelpSource/Guides/atk-network.pdf b/source/ATK/sc/HelpSource/Guides/atk-network.pdf deleted file mode 100644 index 3a79a9f8b2..0000000000 Binary files a/source/ATK/sc/HelpSource/Guides/atk-network.pdf and /dev/null differ diff --git a/source/ATK/sc/HelpSource/Guides/atknetwork.png b/source/ATK/sc/HelpSource/Guides/atknetwork.png deleted file mode 100644 index bcafaef996..0000000000 Binary files a/source/ATK/sc/HelpSource/Guides/atknetwork.png and /dev/null differ diff --git a/source/ATK/sc/HelpSource/Other/ATKDocsLicensing.schelp b/source/ATK/sc/HelpSource/Other/ATKDocsLicensing.schelp deleted file mode 100644 index 9a7c94c3a0..0000000000 --- a/source/ATK/sc/HelpSource/Other/ATKDocsLicensing.schelp +++ /dev/null @@ -1,14 +0,0 @@ -title:: ATK Documentation License -summary:: Ambisonic Toolkit Documentation License -categories:: Libraries>Ambisonic Toolkit>Licensing -related:: Other/ATKLicensing - - -image::ccbysa3_88x31.png:: - -link::Guides/Intro-to-the-ATK##Ambisonic Toolkit help documentation:: for SuperCollider is licensed under a link::http://creativecommons.org/licenses/by-sa/3.0/##Creative Commons Attribution-Share Alike 3.0 Unported License::. - -Executable Ambisonic Toolkit code for SuperCollider remains under the GPL as stated in the Ambisonic Toolkit's and SuperCollider's main link::Other/ATKLicensing##license conditions::. - -To supply attribution for a help document (which may have multiple contributors), unless otherwise indicated you may credit "Ambisonic Toolkit for SuperCollider 3 documentation contributors". - diff --git a/source/ATK/sc/HelpSource/Other/ATKLicensing.schelp b/source/ATK/sc/HelpSource/Other/ATKLicensing.schelp deleted file mode 100644 index f8e6743d6d..0000000000 --- a/source/ATK/sc/HelpSource/Other/ATKLicensing.schelp +++ /dev/null @@ -1,133 +0,0 @@ -title:: ATK Licensing and Notices -summary:: Ambisonic Toolkit Licensing and Notices -categories:: Libraries>Ambisonic Toolkit>Licensing -related:: Other/ATKDocsLicensing - -section:: Ambisonic Toolkit for SuperCollider License - -image::gplv3-88x31.png:: - -The SuperCollider3 version of the Ambisonic Toolkit is copyright the Ambisonic Toolkit Community, Joseph Anderson, and Josh Parmenter, 2011. - -The SuperCollider3 version of the Ambisonic Toolkit is free software: you can redistribute it and/or modify it under the terms of the strong::GNU General Public License:: as published by the link::http://www.fsf.org/##Free Software Foundation::, either version 3 of the License, or (at your option) any later version. - -The SuperCollider3 version of the Ambisonic Toolkit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the link::http://www.gnu.org/licenses/gpl.html##GNU General Public License:: for more details. - -You should have received a copy of the GNU General Public License along with the SuperCollider3 version of the Ambisonic Toolkit. If not, see . - -subsection:: Ambisonic Toolkit Filter Kernels - -The filter kernels distributed with the Ambisonic Toolkit are licensed under a link::http://creativecommons.org/licenses/by-sa/3.0/##Creative Commons Attribution-Share Alike 3.0 Unported License:: and are copyright the Ambisonic Toolkit Community and Joseph Anderson, 2011. - - -section:: Third Party Notices - -subsection:: CIPIC HRTF Database (University of California) - -The Ambisonic Toolkit includes binaural decoders derived from HRIRs found in the link::http://interface.cipic.ucdavis.edu/sound/hrtf.html##CIPIC HRTF Database::. footnote::See: V. R. Algazi, R. O. Duda, D. M. Thompson, and C. Avendano, "The CIPIC HRTF Database," in Proceedings of the 2001 IEEE ASSP Workshop on Applications of Signal Processing to Audio and Acoustics, New Paltz, NY, 2001.:: - - -Copyright (c) 2001 The Regents of the University of California. All Rights Reserved - -Disclaimer - -THE REGENTS OF THE UNIVERSITY OF CALIFORNIA MAKE NO REPRESENTATION OR WARRANTIES WITH RESPECT TO THE CONTENTS HEREOF AND SPECIFICALLY DISCLAIM ANY IMPLIED WARRANTIES OR MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. - -Further, the Regents of the University of California reserve the right to revise this software and/or documentation and to make changes from time to time in the content hereof without obligation of the Regents of the University of California to notify any person of such revision or change. - -Use of Materials - -The Regents of the University of California hereby grant users permission to reproduce and/or use materials available therein for any purpose-educational, research or commercial. However, each reproduction of any part of the materials must include the copyright notice, if it is present. In addition, as a courtesy, if these materials are used in published research, this use should be acknowledged in the publication. If these materials are used in the development of commercial products, the Regents of the University of California request that written acknowledgment of such use be sent to: - -CIPIC- Center for Image Processing and Integrated Computing University of California, -1 Shields Avenue, -Davis, CA 95616-8553 - - -subsection:: Listen HRTF Database (IRCAM) - -The Ambisonic Toolkit includes binaural decoders derived from HRIRs found in the link::http://recherche.ircam.fr/equipes/salles/listen/##Listen HRTF Database::. - - -Copyright (c) 2002 IRCAM (Institut de Recherche et Coordination Acoustique/Musique). All Rights Reserved - - -Use of Materials - -The Listen database is public and available for any use. We would however appreciate an acknowledgment of the database somewhere in the description of your work (e.g. paper) or in your development. - - -Contacts: - -Olivier Warusfel, -Room Acoustics Team, IRCAM -1, place Igor Stravinsky -75004 PARIS, France - - -subsection:: Aaron Heller diametric decoder - -Support for Gerzon's Diametric Decoder Theorem (DDT) footnote::See: E. Benjamin, R. Lee, and A. Heller, "Is My Decoder Ambisonic?," in Proceedings of the 125th Audio Engineering Society Convention, San Francisco, 2008.:: decoding algorithm is derived from Aaron Heller's Octave code available link::http://www.ai.sri.com/ajh/ambisonics/##here::. - -Implementation in the SuperCollider3 version of the ATK is by Joseph Anderson. - - -subsection:: Bruce Wiggins irregular decoders - -Irregular array decoding coefficients footnote::See: B. Wiggins, "An Investigation into the Real-time Manipulation and Control of Three-dimensional Sound Fields," PhD Thesis, University of Derby, Derby, 2004. -:: (5.0) are kindly provided by link::http://www.brucewiggins.co.uk/##Bruce Wiggins::. - - - - -section:: Included musical/sound examples - -The SuperCollider3 version of the Ambisonic Toolkit optionally includes a number of 30 second extracts from published and unpublished recordings. - -Copyright remains with the cited authors and owners. - -definitionList:: -## Ambisonic A-format recordings || - list:: - ## David Cross, "Tenor saxophone improvisations," [unpublished recording] - ## Niall Thomas, "Rob Mackay: flute improvisations," [unpublished recording] - :: -## Ambisonic B-format recordings || - list:: - ## Joseph Anderson, "Nearfield source," [unpublished recording] - ## Joseph Anderson, "Pacific Slope," Epiphanie Sequence, Sargasso SCD28056 - ## D. Courville, "Comparative Surround Recording," Ambisonic Studio | Comparative Surround Recording, 2007. [Online]. Available: http://www.radio.uqam.ca/ambisonic/comparative_recording.html [Accessed: 26-Jul-2011]. - ## P. Hodges, "Purcell - Passacaglia (King Arthur)," Sound of Space: ambisonic surround sound. [Online]. Available: http://soundofspace.com/ambisonic_files/52 [Accessed: 03-Nov-2011]. - ## Tim Howle, "Calling Tunes," 20 Odd Years, FMR FMRCD316-0711 - ## J. Leonard, ""A couple of Chinook helicopters," Sound of Space: ambisonic surround sound, 20-Mar-2008. [Online]. Available: http://soundofspace.com/ambisonic_files/47. [Accessed: 03-Nov-2011]. - ## J. Leonard, “Fireworks,” Sound of Space: ambisonic surround sound, 25-Aug-2009. [Online]. Available: http://soundofspace.com/ambisonic_files/37. [Accessed: 03-Nov-2011]. - ## J. Leonard, "The Orfeo Trio & TetraMic," Sound of Space: ambisonic surround sound. [Online]. Available: http://soundofspace.com/ambisonic_files/41 [Accessed: 03-Nov-2011]. - ## Juan Pampin, "On Space," Les Percussions de Strasbourg 50th Anniversary Edition, Classics Jazz France 480 6512 :: -## Multichannel recordings || - list:: - ## Robert Mackay, "Augustine's Message," [unpublished recording] - ## John Young, "Allting Runt Omkring," [unpublished recording] - :: -## Stereophonic recordings || - list:: - ## Aurora Surgit, "Lux aeterna," Ego sum Resurrectio, NAXOS 8.557672 - ## Aurora Surgit, "Dies irae," Ego sum Resurrectio, NAXOS 8.557672 - ## The City Waites, "The Downfall of Dancing," Penny Merriments, NAXOS 8.557672 - ## The City Waites, "An Old Song on the Spanish Armada," Penny Merriments, NAXOS 8.557672 - :: -## Ambisonic UHJ stereophonic recordings || - list:: - ## Christ Church Cathedral Choir, "Palestrina: O Bone Jesu, exaudi me," Ambisonic Sampler, NI 1417 - ## The Gulbenkian Orchestra, "Waldteufel: The Skaters' Waltz," Ambisonic Sampler, NI 1417 - ## C. Lobato, J. del Gastor, & P. del Gastor, "Alegrias," Ambisonic Sampler, NI 1417 - ## The Wallace Collection, "Gabrieli: Canzon Duodecimi Toni a 10 (No 2)," Ambisonic Sampler, NI 1417 - :: -## link::http://www.zoom.co.jp/english/products/h2/##ZoomH2:: quadraphonic recordings || - list:: - ## Joseph Anderson, "Pickering Steam Fair: Engine," [unpublished recording] - ## Joseph Anderson, "Pickering Steam Fair: Waltz," [unpublished recording] - ## Joseph Anderson, "St Peter & St Paul," [unpublished recording] - ## Joseph Anderson, "Stape Silver Band: March," [unpublished recording] - ## D. Courville, "Comparative Surround Recording," Ambisonic Studio | Comparative Surround Recording, 2007. [Online]. Available: http://www.radio.uqam.ca/ambisonic/comparative_recording.html [Accessed: 26-Jul-2011]. - :: -:: diff --git a/source/ATK/sc/HelpSource/Other/ccbysa3_88x31.png b/source/ATK/sc/HelpSource/Other/ccbysa3_88x31.png deleted file mode 100644 index f0a944e0b8..0000000000 Binary files a/source/ATK/sc/HelpSource/Other/ccbysa3_88x31.png and /dev/null differ diff --git a/source/ATK/sc/HelpSource/Other/gplv3-88x31.png b/source/ATK/sc/HelpSource/Other/gplv3-88x31.png deleted file mode 100644 index ba78d4c494..0000000000 Binary files a/source/ATK/sc/HelpSource/Other/gplv3-88x31.png and /dev/null differ diff --git a/source/ATK/sc/README.md b/source/ATK/sc/README.md index 03f6072d43..0cd7910b04 100644 --- a/source/ATK/sc/README.md +++ b/source/ATK/sc/README.md @@ -1,10 +1,11 @@ -ATK for SuperCollider3 : Read Me +ATK UGens for SuperCollider3 : Read Me ======================== -This is the SuperCollider3 version of the Ambisonic Toolkit (ATK). -It can be used with [SuperCollider3](http://supercollider.github.io/) on OSX, -Linux and Windows, and is distributed via the -[sc3-plugins](https://github.com/supercollider/sc3-plugins) project. +This is the unit generator plugin (UGen) component of the SuperCollider3 version +of the Ambisonic Toolkit (ATK), which is distributed via the +[sc3-plugins](https://github.com/supercollider/sc3-plugins) project. It can be +used with [SuperCollider3](http://supercollider.github.io/) on OSX, Linux and +Windows. The Ambisonic Toolkit (ATK) is intended to bring together a number of tools and methods for working with Ambisonic surround sound. The intention @@ -23,8 +24,8 @@ technique. We hope you enjoy the ATK! -For more information please visit the [Ambisonic Toolkit -website](http:www.ambisonictoolkit.net/) or send us an +For more information please visit the +[Ambisonic Toolkit website](http:www.ambisonictoolkit.net) or send us an [e-mail](mailto:info[at]ambisonictoolkit.net). See also [Introducing the Ambisonic Toolkit](http://doc.sccode.org/Guides/Intro-to-the-ATK.html) for an overview on working with the ATK for SuperCollider3. @@ -50,22 +51,41 @@ or later. Download the latest version   +atk-sc3 Quark +----------- + +The ATK for [SuperCollider3](http://supercollider.github.io)'s classes, +extension methods and documentation are distributed via the +[atk-sc3 Quark](https://github.com/ambisonictoolkit/atk-sc3). Start by reviewing +the Quark installation instructions +[found here](https://github.com/supercollider-quarks/quarks#installing). See +also [Using Quarks](http://doc.sccode.org/Guides/UsingQuarks.html). + +With [git](https://git-scm.com/) installed, you can easily install the +[atk-sc3 Quark](https://github.com/ambisonictoolkit/atk-sc3) directly by +running the following line of code in SuperCollider: + + Quarks.install("https://github.com/ambisonictoolkit/atk-sc3.git"); + + sc3-plugins ----------- -Compiled releases are available from the +The ATK's compiled UGen component releases are available from the [sc3-plugins](https://github.com/supercollider/sc3-plugins/releases) releases page. -Place the downloaded `SC3plugins` folder in your `Extensions` folder. On Mac OS X, this resolves to: +Place the downloaded `SC3plugins` folder in your `Extensions` folder. On Mac +OS X, this resolves to: ~/Library/Application Support/SuperCollider/Extensions You may need to create the `Extensions` folder if it does not already exist. -On other platforms, you can find where this is by running the following line of code in SuperCollider: +On other platforms, you can find where this is by running the following line of +code in SuperCollider: - ( + ( // post the directory in which to move the SC3Plugins folder Platform.userExtensionDir.postln; ) @@ -75,26 +95,21 @@ On other platforms, you can find where this is by running the following line of Platform.userExtensionDir.openOS; ) -Additionally, the SuperCollider3 version of the ATK has a number of -dependencies. Please install the following: -* Install the [MathLib Quark](https://github.com/supercollider-quarks/MathLib) -most simply by running `Quarks.gui` in the SuperCollider IDE. Further install -options and information on Quarks can be found in SuperCollider's Help system. -See [Using Quarks](http://doc.sccode.org/Guides/UsingQuarks.html) and also the -[supercollider-quarks](https://github.com/supercollider-quarks/quarks) GitHub page. -* Install the [FileLog Quark](https://github.com/supercollider-quarks/FileLog) +Kernels & Recordings +-------------------- + +Additionally, the SuperCollider3 version of the ATK has further dependencies: + * Download and install [ATK Kernels](http://www.ambisonictoolkit.net/download/kernels/). * Download and install [ATK Sound File Example Recordings](http://www.ambisonictoolkit.net/download/recordings/). -__NOTE:__ The ATK requires SuperCollider3 version 3.5 or later. Download the latest version [here](http://supercollider.github.io/download), or fork the source code at [GitHub](http://supercollider.github.io/). -   ### Source code -You can build ATK for SuperCollider from the [sc3-plugins](https://github.com/supercollider/sc3-plugins) source-code. +You can build the ATK for SuperCollider UGen components from the [sc3-plugins](https://github.com/supercollider/sc3-plugins) source-code.   @@ -158,7 +173,12 @@ Ambisonic Toolkit. List of Changes --------------- -Unreleased +Unreleased 3.9.0 + +* Refactoring: + * Quark-ify: classes, extension methods & documentation moved to + [atk-sc3 Quark](https://github.com/ambisonictoolkit/atk-sc3). UGens remain + in [sc3-plugins](https://github.com/supercollider/sc3-plugins). * Issue fixes: * Class library: fix inline warnings @@ -249,14 +269,16 @@ Version 3.5 __A note on the ATK's version numbers__: As part of the [sc3-plugins](https://github.com/supercollider/sc3-plugins) project, the -SuperCollider3 ATK's versioning is synced to the release numbers assigned to -[sc3-plugins releases](https://github.com/supercollider/sc3-plugins/releases). -As a result, at this time the versioning for -[atk-sc3](https://github.com/ambisonictoolkit/atk-sc3) does not adhere to the +SuperCollider3 ATK's versioning for UGen components is synced to the release +numbers assigned to +[sc3-plugins releases](https://github.com/supercollider/sc3-plugins/releases). A +separate versioning trajectory for +[atk-sc3](https://github.com/ambisonictoolkit/atk-sc3) adheres to the familiar system known as [Semantic Versioning](http://semver.org/). As SuperCollider3's plugin system continues to develop, we expect to adopt -[Semantic Versioning](http://semver.org/) when it is possible to do so. +[Semantic Versioning](http://semver.org/) for all components when it is possible +to do so.   @@ -268,7 +290,8 @@ Credits   -Copyright the ATK Community, Joseph Anderson, and Joshua Parmenter, 2011, 2016. +Copyright the ATK Community, Joseph Anderson, and Joshua Parmenter, 2011, +2016-17. * J Anderson : [[e-mail]](mailto:j.anderson[at]ambisonictoolkit.net) * J Parmenter : [[e-mail]](mailto:j.parmenter[at]ambisonictoolkit.net) @@ -286,8 +309,10 @@ are copyright the Ambisonic Toolkit Community and Joseph Anderson, Contributors ------------ -Unreleased +Unreleased 3.9.0 +* Joseph Anderson (@joslloand) * Julian Rohrhuber (@telephon) +* Michael McCrea (@mtmccrea) Version 3.8.0 * Daniel Peterson (@dmartinp)