def __init__(self): threading.Thread.__init__(self) logging.info("Audio thread created, initializing fictTuner..") self.lastStation = Station.StaticStation() self.lastPosition = 0 self.tuner = None self.booted = False
def buildPoints(self): # Generate an empty spectrum, 1024 in length to match the possibility of the tuner self.points = [freqPoint(Station.StaticStation(), 0)] * 1024 """ BuildPoints is done in this pattern/algorithm: - Seperate spectrum into the neccesary slices, place stations on the slice lines - Iterate through stations beginnings, inserting the rest of the points required for the station - loadBuffer -> dropoff -> saveZone -> dropoff -> loadBuffer """ # Cutting the spectrum numStations = len(self.stations) # The algorithm splits the total frequencies (0-1023) by the number of stations plus one. # The addition of one allows wiggle room at the top and bottom of the spectrum. frequencySplits = 1023 / (numStations + 1) # Using the pie slice number to find the start of each station. This is the far left, so it is where the safeRadius begins stationStarts = [0] * numStations stationTotalRadius = self.safeRadius + self.dropoffRange + self.loadBuffer for index in range(numStations): # Station start is the split according to the index (turned into 1-based instead of 0-based) multiplied by the # distance between stations (frequencySplits), minus the radius of the station (for proper centering) stationStarts[index] = (frequencySplits * (index + 1) - stationTotalRadius) # This is the core of the buildPoints function, and it's an ugly monster. I'm sorry. for index, stationStart in enumerate(stationStarts): # This guy follows us through the process, letting each loop know exactly where to put their data currentFreqPoint = stationStart currentStation = self.stations[index] logging.debug("Building frequency points from %d to %d for %s" % (stationStart, stationStart + stationTotalRadius, currentStation)) # Points for each station are built through arrays for the different sections of its tuning spectrum # these are later spliced in to prevent massive ugly for-loops. It still doesn't look great, but it's a little better. loadBufferPoints = [freqPoint(currentStation, 0.0)] * (self.loadBuffer) dropoffPoints = range(self.dropoffRange) for dropoffPoint in range(self.dropoffRange): # I use an approximation of logarithmic volume, as this makes it operate similar to human hearing, which operates # on a logarithmic scale. My implementation is (x/(dropoffRange))^3. This allows it to scale properly with changing ranges pointVolume = math.pow((float(dropoffPoint + 1) / float(self.dropoffRange)), 3) dropoffPoints[dropoffPoint] = freqPoint(currentStation, pointVolume) safePoints = [freqPoint(currentStation, 1.0)] * (self.safeRadius * 2) # Apply the slices to the freqPoints list # Left-side loadBuffer currentFreqPoint = stationStart nextFreqPoint = currentFreqPoint + self.loadBuffer self.points[currentFreqPoint:nextFreqPoint] = loadBufferPoints # Left-side dropoffRange currentFreqPoint = nextFreqPoint nextFreqPoint = currentFreqPoint + self.dropoffRange self.points[currentFreqPoint:nextFreqPoint] = dropoffPoints # Central safe zone currentFreqPoint = nextFreqPoint nextFreqPoint = currentFreqPoint + (self.safeRadius * 2) self.points[currentFreqPoint:nextFreqPoint] = safePoints # Right-side dropoffRange currentFreqPoint = nextFreqPoint nextFreqPoint = currentFreqPoint + self.dropoffRange self.points[currentFreqPoint:nextFreqPoint] = dropoffPoints[::-1] # Right-side loadBuffer currentFreqPoint = nextFreqPoint nextFreqPoint = currentFreqPoint + self.loadBuffer self.points[currentFreqPoint:nextFreqPoint] = loadBufferPoints[::-1] logging.debug("Frequency Points created for %s", currentStation) logging.info("All frequency points created. Total Length: %d", len(self.points))