spectralRange = samplingRate/2. c = 344. sphericalHarmonics = bmaudio.sphericalHarmonics2D spectrumBins = nBins/2+1 shFilters = dict( [ (shName, numpy.zeros(spectrumBins, numpy.complex)) for shOrder, shName, _, shFunction, shWeight in sphericalHarmonics ]) w = 2*math.pi*spectralRange/spectrumBins * numpy.arange(spectrumBins) print "Computing the filter for each spherical harmonic..." for i in xrange(N) : # i = random.random() * N # Montecarlo sampling (instead of equidistant) e = 0. a = i * numpy.pi / N t = (bmaudio.sphericalHeadDelay(a+math.pi/2, R, r) - (r-R)) / c sinusoid = numpy.exp( 1j * t * w ) for shOrder, shName, _, shFunction, shWeight in sphericalHarmonics : shFilters[shName] += shFunction(a,e) * sinusoid print "Obtaining the resulting filter for different orientations..." steps = 72 orderFilters = {} for azimuthDegrees in 360./steps*numpy.arange(steps) : orderFilters[azimuthDegrees] = {} for shOrder, shName, _, shFunction, shWeight in sphericalHarmonics : orderFilters[azimuthDegrees][shOrder] = numpy.zeros(spectrumBins, numpy.complex) for order in orderFilters[azimuthDegrees].keys() : for shOrder, shName, _, shFunction, shWeight in sphericalHarmonics : if shOrder>order : continue orderFilters[azimuthDegrees][order] += shWeight * shFunction(math.radians(azimuthDegrees),0) * shFilters[shName]
print "max", max(patternValues) pylab.polar(angles, patternValues, label="%s"%l) pylab.title("InPhase",horizontalalignment='center', verticalalignment='baseline', position=(.5,-.1)) pylab.rgrids(numpy.arange(.4,1,.2),angle=220) pylab.legend(loc=2) pylab.savefig(figurePath(__file__,"pdf")) pylab.show() if False: print "Filtering at 90 degrees" plot = bmaudio.SpectrumDisplay() plot.inDb() #plot.showPhase() plot.ylim(-40,5) delays = [ (bmaudio.sphericalHeadDelay(azimuth, R, r)-(r-R))/c for azimuth in angles ] for no in ordersToShow[:-1] : print no decoding = headDistortion.decoding3dMaxRe(no) / (no+1) decoding = headDistortion.decoding3dInPhase(no) amplitudes = [ sum( (decoding[l] * float(sh_normalization2(l,0)) * float(sympy.legendre(l,cosTheta)) * math.sin(azimuth) / nSamples for l in xrange(0,no+1) ) ) for azimuth, cosTheta in zip(angles, numpy.cos(numpy.pi/2-angles)) ] plot.addSpectrumData(headDistortion.delayAmplitudeToSpectrum(delays,amplitudes,w),spectralRange,"Order %i"%no) plot.show() def deviated3dAmbisonics(pattern, planeWaveAzimuth, ringAzimuth, slices=72) : """
pylab.ylim(-2,2) pylab.grid(1) pylab.legend() pylab.show() if False : """Comparing the simplified delay with the one not considering R<<r. The remainder is multiplied by 100. It is a regular amplitude oscilation so that's why it is more significant on higher frequencies where the filter is lower, not because the absolute error increases. """ azimuths = fullAzimuths delays1 = numpy.array([headDelaySimplified(a) for a in azimuths]) delays2 = numpy.array([bmaudio.sphericalHeadDelay(a,R,r)/c-r/c for a in azimuths]) ordersToShow = xrange(0,1,1) for order in ordersToShow: print order ocolor=colors[order%len(colors)] oddOrder = order&1 polarPattern = polarPatternY if oddOrder else polarPatternX pattern = [ polarPattern(azimuth, order) for azimuth in azimuths] spectrum1 = headDistortion.delayAmplitudeToSpectrum(delays1, pattern, w) spectrum2 = headDistortion.delayAmplitudeToSpectrum(delays2, pattern, w) remainder = spectrum1-spectrum2 pylab.plot(100*numpy.real(remainder), ocolor+'--', label="RR"+str(order)) pylab.plot(100*numpy.imag(remainder), ocolor+':', label="RI"+str(order))
if len(sys.argv)<2 or sys.argv[1] not in decodings.keys() : print "Please specify one decoding:", ", ".join(decodings.keys()) sys.exit() if len(sys.argv)<3 or not int(sys.argv[2]) : print "Please specify an order" sys.exit() maxOrder = int(sys.argv[2]) decodingName=sys.argv[1] decoding=decodings[decodingName](maxOrder) print "decoding", decoding, "order", maxOrder print "Computing delays..." distances = numpy.array([ bmaudio.sphericalHeadDelay(numpy.radians(a),R,r) for a in azimuths ]) relativeDistances = distances + R - r # force closer distance be 0 delays = relativeDistances / c # distance -> time print "Computing simplified delays..." distancesSimplified = numpy.array([ bmaudio.sphericalHeadDelaySimplified(numpy.radians(a),R,r) for a in azimuths ]) relativeDistancesSimplified = distancesSimplified + R - r # force closer distance be 0 delaysSimplified = relativeDistancesSimplified / c # distance -> time
import pylab from parameters import * def figurePath(file, extension) : return os.path.join('figures', os.path.splitext(os.path.basename(file))[0] + "." + extension) databaseFile = bmaudio.selectHrtfDatabase(sys.argv) print "Using", databaseFile, "database." print "Gathering files..." hrtfDatabase = bmaudio.HrtfDatabase(databaseFile) azimuths = numpy.arange(0,360,360/N) radiansAzimuths = [math.radians(degrees) for degrees in azimuths] sphericHeadDelays = dict([ (azimuthDegrees, ( bmaudio.sphericalHeadDelay(math.radians(azimuthDegrees), R, r) - (r-R) ) / c ) for azimuthDegrees in azimuths]) realHeadDelays = bmaudio.azimuthDelaysFromHorizontalHrtf(hrtfDatabase) pylab.rcParams["figure.figsize"] = (8,5) pylab.axes(polar=True).set_theta_zero_location("N") pylab.axes(polar=True).set_thetagrids( range(0,360,45), labels= [str(g) for g in range(0,180+1,45)+range(-135,0,45)] ) pylab.polar(radiansAzimuths, numpy.array([sphericHeadDelays[azimuth] for azimuth in azimuths])*1000, "k--", label='Spherical head' ) pylab.polar(radiansAzimuths, numpy.array([realHeadDelays[azimuth] for azimuth in azimuths])*1000, "k-", label="Real head" ) pylab.ylabel("ms") pylab.legend() pylab.savefig(figurePath(__file__,"pdf"))