def loop(self): ansi.info("Starting process run loop...") try: while True: self.eachLoop() # Process any queued callbacks. while self.queuedCallbacks: callback = self.queuedCallbacks.popleft() callback() self.afterEachCallback() except QuitApplication: print() print("Exiting application.") except KeyboardInterrupt: print() print("User interrupted; exiting.") except Exception: print("Got Exception while looping:", traceback.format_exc()) finally: ansi.info("Process shutting down...") self.onShutdown() ansi.done()
def fftFrequencies(self, sampleRate): frequencies = fftfreq(self.framesPerSlice) * sampleRate startFreq = 0 if self.keepZeroBand else 1 ansi.info("Total generated frequency bands: {} {!r}", len(frequencies), frequencies) ansi.info("Trimmed frequency bands: {} {!r}", len(frequencies[startFreq:self.frequencyBands + 1]), abs(frequencies[startFreq:self.frequencyBands + 1]) ) # From http://docs.scipy.org/doc/numpy/reference/routines.fft.html#implementation-details: # > For an even number of input points, A[n/2] represents both positive and negative Nyquist frequency, and is # > also purely real for real input. # # Since numpy gives us -0.5 as the frequency of A[n/2], we need to call abs() on the frequencies for it to make # sense. return abs(frequencies[startFreq:self.frequencyBands + 1])
def __init__(self, analyzer, config): self.analyzer = ref(analyzer) self.songConfig = SongConfig(config) ansi.info('Serial connecting to {} at {} bps', serialDevice, serialSpeed) self.serial = serial.Serial(serialDevice, serialSpeed, timeout=1) # Assume we're already started unless we're using the USB interface to the Arduino. self.ready = 'ttyACM' not in serialDevice while not self.ready: if self.readFromSerial().startswith('LSDG Holiday Light controller ver '): self.ready = True self.lastLightUpdate = datetime.datetime.now() self.previousLightStates = [False] * analyzer.frequencyBands self.lightUpdateTimes = [time.time() for x in range(int(config.get('spectrum', 'frequencyBands')))]
def loadNextFile(self): self.currentFilename = next(self.filenameIter).encode("utf-8") if self.currentFilename is None: mainLoop.currentProcess.queuedCallbacks.append(self.nextChunk) return print("Loading file {!r}.".format(self.currentFilename)) tags = hsaudiotag.auto.File(self.currentFilename) if not tags.valid: print("Couldn't read tags!") else: print( json.dumps({"artist": tags.artist, "album": tags.album, "title": tags.title, "duration": tags.duration}) ) self.tags = tags self.file = audioread.audio_open(self.currentFilename) songInfo = {"channels": self.channels, "samplerate": self.samplerate, "duration": self.duration} ansi.info( "Loaded song {!r}; channels: {}; samplerate: {}; duration: {} (duration from tags: {})", self.currentFilename, self.channels, self.samplerate, self.duration, tags.duration, ) mainLoop.currentProcess.queueCall(self.onSongChanged, tags, songInfo) blockSize = self.framesPerChunk * self.file.channels * self.bytes_per_frame_per_channel try: # MAD (pymad) self.sampleIter = self.file.read_blocks(blockSize) except AttributeError: try: # FFMpeg (command line) self.sampleIter = self.file.read_data(blockSize) except AttributeError: # gstreamer (pygst) self.sampleIter = iter(self.file)
handler(event) # Wait for stream to finish. try: while True: processEvent(pygame.event.wait()) # Process any queued callbacks. while queuedCallbacks: callback = queuedCallbacks.popleft() callback() # Process waiting events before moving on to the next callback. for event in pygame.event.get(): processEvent(event) except QuitApplication: print() print("Exiting application.") except KeyboardInterrupt: print() print("User interrupted; exiting.") ansi.info("Shutting down...") pygame.quit() ansi.done()