User-Defined Opcode Database

circumspect

redistribute the spectral content of a monaural signal between 6 loudspeakers

Download UDO File

Description

redistribute the spectral content of a monaural signal between 6 loudspeakers

Syntax

circumspect iNumBins, iampin, iampoutlist, ipantab

Initialization

iNumBins - the number of indices in each table, which should match the number of bins in each analysis frame. This is calculated from the FFT size: FFT size/2+1.

iampin - the name of the table holding the amplitude values from the current frame.

iampoutlist - a table containing a list of 6 table ID numbers to which the calculated amplitude values are written.

ipantab - the ID number of the table that holds the user-defined amplitude panning values for each bin. There should be one 'panning' value for each FFT bin. The size of the table is defined by the FFT size (FFT_size/2+1). Integer values correspond with single channels (loudspeakers) while fractional values mix the bin between adjacent channels using square amplitude panning. The mapping is as follows:

The value 0 will mix the bin amplitude into iampout1.
The value 1 will mix the bin amplitude into iampout2.
The value 2 will mix the bin amplitude into iampout3.
The value 3 will mix the bin amplitude into iampout4.
The value 4 will mix the bin amplitude into iampout5.
The value 5 will mix the bin amplitude into iampout6.
The value 6 will mix the bin amplitude into iampout1. (This allows the bin to be mixed between iampout6 and iampout1.)

Note that inputing values by hand is unlikely to be of practical use. A higher-level table-filling instrument is needed for generating and scaling weighted random distributions.

Code

	opcode circumspect,0,iiii 
iNumBins, iampin, iampoutlist, ipantab  xin

;iNumBins: the number of indices in each table, which should match the number of bins  
;iampin: the name of the table holding the amplitude values from the current fsig frame
;iampoutlist: a table containing a list of 6 table numbers to which the calculated amplitude values are written
;ipantab: the name of the table that holds the user-defined amplitude-panning values for each bin

iampout1	tab_i 0, iampoutlist		;unpack list of ampout tables
iampout2	tab_i 1, iampoutlist
iampout3	tab_i 2, iampoutlist
iampout4	tab_i 3, iampoutlist
iampout5	tab_i 4, iampoutlist
iampout6	tab_i 5, iampoutlist

iclear 		ftgen 0, 0, iNumBins, -2, 0	;make an empty table

            tablecopy iampout1, iclear          ;copy the content of the above empty table into 
	    tablecopy iampout2, iclear          ;the iampout tables to zero them out before each frame is processed  
	    tablecopy iampout3, iclear
	    tablecopy iampout4, iclear
	    tablecopy iampout5, iclear
	    tablecopy iampout6, iclear

kcount = 0       ;set the initial pointer value for counting through the bins (table indices)

;start the loop block
loop:          

kamp		tab kcount, iampin       ;use kcount as read pointer into the table of input amplitude values 
kpan		tab kcount, ipantab      ;use kcount as read pointer into the table of panning values 

;do the magic per-bin panning
		if (kpan<=1) then
			kpan1 = sqrt(1-kpan)
			kpan2 = sqrt(kpan)
			tabw kamp*kpan1 , kcount, iampout1
			tabw kamp*kpan2 , kcount, iampout2
		elseif (kpan<=2) then
			kpan = kpan - 1
			kpan1 = sqrt(1-kpan)
			kpan2 = sqrt(kpan)		
			tabw kamp*kpan1 , kcount, iampout2
			tabw kamp*kpan2 , kcount, iampout4
		elseif (kpan<=3) then
			kpan = kpan - 2
			kpan1 = sqrt(1-kpan)
			kpan2 = sqrt(kpan)	
			tabw kamp*kpan1 , kcount, iampout4
			tabw kamp*kpan2 , kcount, iampout6
		elseif (kpan<=4) then
			kpan = kpan - 3
			kpan1 = sqrt(1-kpan)
			kpan2 = sqrt(kpan)			
			tabw kamp*kpan1 , kcount, iampout6
			tabw kamp*kpan2 , kcount, iampout5
		elseif (kpan<=5) then
			kpan = kpan - 4
			kpan1 = sqrt(1-kpan)
			kpan2 = sqrt(kpan)			
			tabw kamp*kpan1 , kcount, iampout5
			tabw kamp*kpan2 , kcount, iampout3
		elseif (kpan<=6) then
			kpan = kpan - 5
			kpan1 = sqrt(1-kpan)
			kpan2 = sqrt(kpan)			
			tabw kamp*kpan1 , kcount, iampout3
			tabw kamp*kpan2 , kcount, iampout1
		elseif	(kpan > 6) then			
			tabw kamp, kcount, iampout1
		endif		

;increment kcount by one value and go back to the top of the loop section, unless kcount has reached the final bin 
kcount = kcount + 1
if (kcount < (iNumBins-1)) kgoto loop

	endop

Examples

<CsoundSynthesizer>

<CsOptions>
-o circumspectralTest.aif -d
</CsOptions>

<CsInstruments>

sr     = 44100
ksmps  = 1
nchnls = 6
0dbfs  = 1 ;firstly the amplitude value must be scaled between 0 and 1 for the UDO to function correctly 

;paste UDO here

instr 1

ifftsize  = 2048                                  ;FFT_size
iol       = 2                                     ;overlap factor 
iwindmult = 2                                     ;window_size = 2*FFT_size
iwindtype = 0                                     ;hamming winodw
iwindow   = ifftsize*iwindmult			

ain inch 1                                                 ;get audio input
;ain  noise .2, 0                     ;for testing                             
fsin pvsanal ain,ifftsize,ifftsize/iol,iwindow,iwindtype   ;analyse the input  

fin1 pvsmix fsin,fsin ;make 6 copies of the fsig 
fin2 pvsmix fsin,fsin ;the amplitude data will be overwritten by the UDO 
fin3 pvsmix fsin,fsin
fin4 pvsmix fsin,fsin
fin5 pvsmix fsin,fsin
fin6 pvsmix fsin,fsin

iNumBins = ifftsize/2+1
;define all the ftables
;ipantab     ftgen 0,0,iNumBins,-7,0,iNumBins, 6 ;try this one out! 					
ipantab     ftgen 0,0,iNumBins,-2,0 					
ifreqin     ftgen 0,0,iNumBins,-2,0					
iampin	    ftgen 0,0,iNumBins,-2,0
iampout1    ftgen 0,0,iNumBins,-2,0
iampout2    ftgen 0,0,iNumBins,-2,0
iampout3    ftgen 0,0,iNumBins,-2,0
iampout4    ftgen 0,0,iNumBins,-2,0
iampout5    ftgen 0,0,iNumBins,-2,0
iampout6    ftgen 0,0,iNumBins,-2,0

;pack the 6iampout table IDs into a list stored in a table. This is passed to the UDO: cleaner than giving UDO 6 input variables. 
iampoutlist ftgen 0,0,8,-2,iampout1, iampout2, iampout3, iampout4, iampout5, iampout6, 0, 0 

kflag pvsftw fsin, iampin, ifreqin               ;write fsig data to tables
if (kflag > 0) then                              ;only proc when frame is ready

	circumspect iNumBins, iampin, iampoutlist, ipantab

	pvsftr fin1, iampout1, ifreqin               ;fin1-6 must be initiated prior to this
	pvsftr fin2, iampout2, ifreqin               ;the content of the pvs streams are then  
	pvsftr fin3, iampout3, ifreqin               ;read iteratively from the tables 
	pvsftr fin4, iampout4, ifreqin               ;note that ifreqin is common to all
	pvsftr fin5, iampout5, ifreqin   
	pvsftr fin6, iampout6, ifreqin
endif

;synthesise output
aout1 pvsynth fin1 ;corresponds with iampout1
aout2 pvsynth fin2 ;corresponds with iampout2
aout3 pvsynth fin3 ;corresponds with iampout3
aout4 pvsynth fin4 ;corresponds with iampout4
aout5 pvsynth fin5 ;corresponds with iampout5
aout6 pvsynth fin6 ;corresponds with iampout6

      outh aout1, aout2, aout3, aout4, aout5, aout6
endin

</CsInstruments>

<CsScore>
i1  0 3600

</CsScore>

</CsoundSynthesizer>
	
	

Credits

Peiman Khosravi


Previous Home Next
BufRec2   Counter