def __init__(self, context, name, parent, numberOfObjects, lspConfig): """ Constructor, instantiates the component, all contained sub-components, and their connections. Parameters ---------- self: VbapRenderer self argument, mandatory for Python methods. context: visr.SignalFlowContext A context object containing the sampling frequency and the block size. That is a mandatory parameter for VISR components. name: string Name of the component to be identified within a containing component. parent: visr.Compositcomponent A containing component, or None if this is the top-level component. numberOfObjects: int The maximum number of objects to be rendered. lspConfig: panning.LoudspeakerArray Object containing the loudspeaker positions. """ numLsp = lspConfig.numberOfRegularLoudspeakers super().__init__(context, name, parent) self.audioIn = visr.AudioInputFloat("in", self, numberOfObjects) self.audioOut = visr.AudioOutputFloat("out", self, numLsp) self.objectIn = visr.ParameterInput( "objects", self, pml.ObjectVector.staticType, pml.DoubleBufferingProtocol.staticType, pml.EmptyParameterConfig()) self.calculator = rcl.PanningCalculator(context, "VbapGainCalculator", self, numberOfObjects, lspConfig) self.matrix = rcl.GainMatrix(context, "GainMatrix", self, numberOfObjects, numLsp, interpolationSteps=context.period, initialGains=0.0) # Uncomment this and comment the lines above to use the simple, Python-based # GainMatrix class instead. # self.matrix = GainMatrix( context, "GainMatrix", self, numberOfObjects, # numLsp ) self.audioConnection(self.audioIn, self.matrix.audioPort("in")) self.audioConnection(self.matrix.audioPort("out"), self.audioOut) self.parameterConnection( self.objectIn, self.calculator.parameterPort("objectVectorInput")) self.parameterConnection(self.calculator.parameterPort("vbapGains"), self.matrix.parameterPort("gainInput"))
def __init__(self, context, name, parent, numberOfInputs, numberOfOutputs, arrayConfig, interpolationSteps): super(StandardVbap, self).__init__(context, name, parent) self.input = visr.AudioInputFloat("in", self, numberOfInputs) self.output = visr.AudioOutputFloat("out", self, numberOfOutputs) self.objectInput = visr.ParameterInput( "objectVectorInput", self, parameterType=pml.ObjectVector.staticType, protocolType=pml.DoubleBufferingProtocol.staticType, parameterConfig=pml.EmptyParameterConfig()) self.panningCalculator = rcl.PanningCalculator( context, "GainCalculator", self, arrayConfig=arrayConfig, numberOfObjects=numberOfInputs, separateLowpassPanning=False) self.panningMatrix = rcl.GainMatrix( context, "PanningMatrix", self, numberOfInputs=numberOfInputs, numberOfOutputs=numberOfOutputs, interpolationSteps=interpolationSteps, initialGains=0.0, controlInput=True) self.audioConnection(self.input, self.panningMatrix.audioPort("in")) self.audioConnection(self.panningMatrix.audioPort("out"), self.output) self.parameterConnection( self.objectInput, self.panningCalculator.parameterPort("objectVectorInput")) self.parameterConnection( self.panningCalculator.parameterPort("gainOutput"), self.panningMatrix.parameterPort("gainInput"))
def __init__(self, context, name, parent, numberOfObjects, lspArray): numLsp = lspArray.numberOfRegularLoudspeakers super().__init__(context, name, parent) self.audioIn = visr.AudioInputFloat("in", self, numberOfObjects) self.audioOut = visr.AudioOutputFloat("out", self, numLsp) self.objectIn = visr.ParameterInput( "objects", self, pml.ObjectVector.staticType, pml.DoubleBufferingProtocol.staticType, pml.EmptyParameterConfig()) self.calculator = VbapL2Panner(context, "VbapGainCalculator", self, numberOfObjects, lspArray) self.matrix = rcl.GainMatrix(context, "GainMatrix", self, numberOfObjects, numLsp, interpolationSteps=context.period, initialGains=0.0) self.audioConnection(self.audioIn, self.matrix.audioPort("in")) self.audioConnection(self.matrix.audioPort("out"), self.audioOut) self.parameterConnection(self.objectIn, self.calculator.parameterPort("objects")) self.parameterConnection(self.calculator.parameterPort("gains"), self.matrix.parameterPort("gainInput"))
# -*- coding: utf-8 -*- """ Created on Sat Feb 24 07:25:02 2018 @author: andi """ import visr import rcl import numpy as np ctxt = visr.SignalFlowContext( 64, 48000 ) numInputs = 3 numOutputs = 7 gains = np.array( np.random.rand( numOutputs, numInputs ), dtype=np.float32 ) mtx = rcl.GainMatrix( ctxt, "Matrix", None, numberOfInputs=numInputs, numberOfOutputs=numOutputs, interpolationSteps=0, initialGains=gains ) dv = rcl.DelayVector( ctxt, "DL", None, numberOfChannels=2, maxDelay=1.0, initialDelay = [0.0, 0.1], initialGain=[1.0,0.5]) iDelay = np.asarray([0.0, 0.1], dtype=np.float64) iGain=np.asarray([1.0,0.5]) dv = rcl.DelayVector( ctxt, "DL", None, numberOfChannels=2, maxDelay=1.0, initialDelay = iDelay, initialGain=iGain )
def __init__(self, context, name, parent, numberOfInputs, numberOfOutputs, arrayConfig, interpolationSteps, lfFilter=rbbl.BiquadCoefficientFloat(0.001921697757295, 0.003843395514590, 0.001921697757295, -1.824651307057289, 0.832338098086468), hfFilter=rbbl.BiquadCoefficientFloat(0.914247351285939, 1.828494702571878, -0.914247351285939, -1.824651307057289, 0.832338098086468)): super(LfHfVbap, self).__init__(context, name, parent) self.input = visr.AudioInputFloat("in", self, numberOfInputs) self.output = visr.AudioOutputFloat("out", self, numberOfOutputs) self.objectInput = visr.ParameterInput( "objectVectorInput", self, parameterType=pml.ObjectVector.staticType, protocolType=pml.DoubleBufferingProtocol.staticType, parameterConfig=pml.EmptyParameterConfig()) self.panningCalculator = rcl.PanningCalculator( context, "GainCalculator", self, arrayConfig=arrayConfig, numberOfObjects=numberOfInputs, separateLowpassPanning=True) filterMtx = rbbl.BiquadCoefficientMatrixFloat(2 * numberOfInputs, 1) for idx in range(0, numberOfInputs): filterMtx[idx, 0] = lfFilter filterMtx[idx + numberOfInputs, 0] = hfFilter self.filterBank = rcl.BiquadIirFilter( context, "filterBank", self, numberOfChannels=2 * numberOfInputs, numberOfBiquads=1, # TODO: allow variable number of sections. initialBiquads=filterMtx, controlInput=False) self.audioConnection( self.input, [i % numberOfInputs for i in range(0, 2 * numberOfInputs)], self.filterBank.audioPort("in"), range(0, 2 * numberOfInputs)) self.lfMatrix = rcl.GainMatrix(context, "LfPanningMatrix", self, numberOfInputs=numberOfInputs, numberOfOutputs=numberOfOutputs, interpolationSteps=interpolationSteps, initialGains=0.0, controlInput=True) self.audioConnection(self.filterBank.audioPort("out"), range(0, numberOfInputs), self.lfMatrix.audioPort("in"), range(0, numberOfInputs)) self.hfMatrix = rcl.GainMatrix(context, "HfPanningMatrix", self, numberOfInputs=numberOfInputs, numberOfOutputs=numberOfOutputs, interpolationSteps=interpolationSteps, initialGains=0.0, controlInput=True) self.audioConnection(self.filterBank.audioPort("out"), range(numberOfInputs, 2 * numberOfInputs), self.hfMatrix.audioPort("in"), range(0, numberOfInputs)) self.signalMix = rcl.Add(context, "SignalMix", self, numInputs=2, width=numberOfOutputs) self.audioConnection(self.signalMix.audioPort("out"), self.output) self.audioConnection(self.lfMatrix.audioPort("out"), self.signalMix.audioPort("in0")) self.audioConnection(self.hfMatrix.audioPort("out"), self.signalMix.audioPort("in1")) self.parameterConnection( self.objectInput, self.panningCalculator.parameterPort("objectVectorInput")) self.parameterConnection( self.panningCalculator.parameterPort("lowFrequencyGainOutput"), self.lfMatrix.parameterPort("gainInput")) self.parameterConnection( self.panningCalculator.parameterPort("gainOutput"), self.hfMatrix.parameterPort("gainInput"))
def __init__(self, context, name, parent, numberOfObjects, maxHoaOrder=None, sofaFile=None, decodingFilters=None, interpolationSteps=None, headOrientation=None, headTracking=True, objectChannelAllocation=False, fftImplementation='default'): """ Constructor. Parameters ---------- context : visr.SignalFlowContext Standard visr.Component construction argument, holds the block size and the sampling frequency name : string Name of the component, Standard visr.Component construction argument parent : visr.CompositeComponent Containing component if there is one, None if this is a top-level component of the signal flow. numberOfObjects : int The number of audio objects to be rendered. maxHoaOrder: int or None The maximum HOA order that can be reproduced. If None, the HOA order is deduced from the first dimension of the HOA filters (possibly contained in a SOFA file). sofaFile: string or NoneType decodingFilters : numpy.ndarray or NoneType Alternative way to provide the HOA decoding filters. interpolationSteps: int headOrientation : array-like Head orientation in spherical coordinates (2- or 3-element vector or list). Either a static orientation (when no tracking is used), or the initial view direction headTracking: bool Whether dynamic head tracking is active. objectChannelAllocation: bool Whether the processing resources are allocated from a pool of resources (True), or whether fixed processing resources statically tied to the audio signal channels are used. Not implemented at the moment, so leave the default value (False). fftImplementation: string, optional The FFT library to be used in the filtering. THe default uses VISR's default implementation for the present platform. """ if (decodingFilters is None) == (sofaFile is None): raise ValueError( "HoaObjectToBinauralRenderer: Either 'decodingFilters' or 'sofaFile' must be provided." ) if sofaFile is None: filters = decodingFilters else: # pos and delays are not used here. [pos, filters, delays] = readSofaFile(sofaFile) if maxHoaOrder is None: numHoaCoeffs = filters.shape[0] orderP1 = int(np.floor(np.sqrt(numHoaCoeffs))) if orderP1**2 != numHoaCoeffs: raise ValueError( "If maxHoaOrder is not given, the number of HOA filters must be a square number" ) maxHoaOrder = orderP1 - 1 else: numHoaCoeffs = (maxHoaOrder + 1)**2 if filters.ndim != 3 or filters.shape[1] != 2 or filters.shape[ 0] < numHoaCoeffs: raise ValueError( "HoaObjectToBinauralRenderer: the filter data must be a 3D matrix where the second dimension is 2 and the first dimension is equal or larger than (maxHoaOrder+1)^2." ) super(HoaObjectToBinauralRenderer, self).__init__(context, name, parent) self.objectSignalInput = visr.AudioInputFloat("audioIn", self, numberOfObjects) self.binauralOutput = visr.AudioOutputFloat("audioOut", self, 2) self.objectVectorInput = visr.ParameterInput( "objectVector", self, pml.ObjectVector.staticType, pml.DoubleBufferingProtocol.staticType, pml.EmptyParameterConfig()) if interpolationSteps is None: interpolationSteps = context.period self.objectEncoder = HoaObjectEncoder( context, 'HoaEncoder', self, numberOfObjects=numberOfObjects, hoaOrder=maxHoaOrder, channelAllocation=objectChannelAllocation) self.parameterConnection( self.objectVectorInput, self.objectEncoder.parameterPort("objectVector")) self.encoderMatrix = rcl.GainMatrix( context, "encoderMatrix", self, numberOfInputs=numberOfObjects, numberOfOutputs=(maxHoaOrder + 1)**2, interpolationSteps=interpolationSteps, initialGains=0.0, controlInput=True) self.audioConnection(self.objectSignalInput, self.encoderMatrix.audioPort("in")) filterMtx = np.concatenate( (filters[0:numHoaCoeffs, 0, :], filters[0:numHoaCoeffs, 1, :])) routings = rbbl.FilterRoutingList() for idx in range(0, numHoaCoeffs): routings.addRouting(idx, 0, idx, 1.0) routings.addRouting(idx, 1, idx + numHoaCoeffs, 1.0) self.binauralFilterBank = rcl.FirFilterMatrix( context, 'binauralFilterBank', self, numberOfInputs=numHoaCoeffs, numberOfOutputs=2, filterLength=filters.shape[-1], maxFilters=2 * numHoaCoeffs, maxRoutings=2 * numHoaCoeffs, filters=filterMtx, routings=routings, controlInputs=rcl.FirFilterMatrix.ControlPortConfig.NoInputs, fftImplementation=fftImplementation) self.audioConnection(self.encoderMatrix.audioPort("out"), self.binauralFilterBank.audioPort("in")) self.audioConnection(self.binauralFilterBank.audioPort("out"), self.binauralOutput) if headTracking: self.trackingInput = visr.ParameterInput( "tracking", self, pml.ListenerPosition.staticType, pml.DoubleBufferingProtocol.staticType, pml.EmptyParameterConfig()) self.coefficientRotator = HoaCoefficientRotation( context, 'coefficientRotator', self, numberOfObjects=numberOfObjects, hoaOrder=maxHoaOrder) self.parameterConnection( self.trackingInput, self.coefficientRotator.parameterPort("tracking")) self.parameterConnection( self.objectEncoder.parameterPort("coefficientOutput"), self.coefficientRotator.parameterPort("coefficientInput")) self.parameterConnection( self.coefficientRotator.parameterPort("coefficientOutput"), self.encoderMatrix.parameterPort("gainInput")) else: self.parameterConnection( self.objectEncoder.parameterPort("coefficientOutput"), self.encoderMatrix.parameterPort("gainInput"))