def __init__(self): self.devices = None self._openedInputs = {} self._openedOutputs = {} logger.info("Initializing MIDI") pygame.midi.init() self.rescan()
def run(self): logger.debug("AudioOutputLoop started") self._isRunning = True while self._isRunning: startTime = clock() self._lock.acquire(True) # do cool stuff here if self.numFrames + self._bufferSize > self.totalFrames: self._isRunning = False else: startFrame = self.numFrames endFrame = startFrame + self._bufferSize * 2 bytesOut = bytes(self.allsamples[startFrame:endFrame]) sound = pygame.mixer.Sound(self.allsamples[startFrame:endFrame]) self._channel.play(sound) self.numFrames += self._bufferSize * 2 stopTime = clock() timeInBlockInSec = (stopTime - startTime) sleepTime = self._maxTimePerBlockInSec - timeInBlockInSec if sleepTime < 0: logger.warn("Audio dropout!") else: logger.info("CPU: %f", 100 * timeInBlockInSec / self._maxTimePerBlockInSec) sleep(sleepTime) self._lock.release()
def quit(self): self._lock.acquire(True) if self.devices is not None: self.devices.closeAll() self._isRunning = False self._lock.release() logger.info("Closed all MIDI devices")
def _processEvent(self, event): eventType = pygame.event.event_name(event.type) try: processFunction = getattr(self.mainDelegate, "on" + eventType) processFunction(event.dict) except AttributeError as exception: logger.info("Error handling event '" + eventType + "': " + str(exception)) except pygame.error as exception: logger.error("Error from pygame: " + str(exception))
def rescan(self): self.devices = {} logger.info("Audio device rescan started") devices = pygame.mixer.get_devices() logger.debug("Found %d devices", len(devices)) for device in devices: (name, numInputs, numOutputs) = device scannedDevice = AudioDevice(name, numInputs, numOutputs) self.devices[name] = scannedDevice logger.debug("%s", scannedDevice)
def __init__(self): logger.info("Lucidity initialized. Hello there!") self.mainDelegate = MainDelegate() self.mainDelegate.mainApp = self self.sequence = Sequence() self.settings = Settings(PathFinder.findUserFile('settings.db')) self.mediaRequestLoop = MediaRequestLoop(PathFinder.findUserFile('media.db')) self.midiEventLoop = MidiEventLoop(self.mainDelegate) self.statusLoop = StatusLoop() self.systemUsageLoop = SystemUsageLoop() self.mainWindow = None
def _processRequest(self, request:MediaRequest): if request.type == MediaRequest.Operations.SEARCH: results = self._search(request.query) if request.delegate is not None: request.delegate.onRequestComplete(request, results) elif request.type == MediaRequest.Operations.RESCAN: self._rescanLibrary() if request.delegate is not None: request.delegate.onRequestComplete(request, "Rescan finished") elif request.type == MediaRequest.Operations.QUIT: self._isRunning = False else: logger.info("Unknown media request type '" + request.type + "'")
def open(self): """ Open up the window for the application. This must, sadly, be done in the main thread, or else the window will not properly respond to events. """ windowFlags = self.getWindowFlags(self.settings) self.surface = pygame.display.set_mode(self._resolution, windowFlags) self._printVideoInfo(pygame.display.Info()) logger.info("Initialized display with driver: " + pygame.display.get_driver()) self.surface.fill(self._skin.guiColor("Background")) self._initializePanels(self._resolution, self._skin) pygame.display.flip() self._statusLoop.statusProvider = self.getStatusProvider(self.settings)
def quit(self): logger.info("Lucidity is quitting. Bye-bye!") self.mainWindow.setStatusText("Shutting Down...") if self.statusLoop.is_alive(): self.statusLoop.quit() self.statusLoop.join() if self.systemUsageLoop.is_alive(): self.systemUsageLoop.quit() self.systemUsageLoop.join() if self.mediaRequestLoop.is_alive(): self.mediaRequestLoop.quit() self.mediaRequestLoop.join() if self.midiEventLoop.is_alive(): self.midiEventLoop.quit() self.midiEventLoop.join() self.mainWindow.quit()
def _rescanLocation(self, location): logger.info("Scanning folder '%s'", location[1]) totalFilesFound = 0 newFilesFound = 0 missingFilesFound = 0 updatedFiles = 0 for filePath in self._scanDirectory(location[1], []): mediaFile = MediaFile(filePath) if mediaFile.exists: # See if the file is already in the database mediaFileId = None mediaFile.readMetadataFromFile(filePath) mediaFileRelativePath = mediaFile.relativePath(location[1]) searchResultIds = self.search(mediaFileRelativePath, ['relativePath'], matchExact = True) if isinstance(searchResultIds, list): for result in searchResultIds: if result.absolutePath == mediaFile.absolutePath: mediaFileId = result.id break if mediaFileId not in self.mediaFiles.keys(): newId = self._addFileToDatabase(mediaFile, location) mediaFile.id = newId newFilesFound += 1 else: # The ID is specific to the database, so this newly-created # object won't have one yet. That means that this equality # comparison would fail, so we copy the ID to this object. mediaFile.id = mediaFileId if mediaFile != self.mediaFiles[mediaFileId]: self._updateFileInDatabase(mediaFile) updatedFiles += 1 self.mediaFiles[mediaFile.id] = mediaFile # logger.debug(mediaFile) totalFilesFound += 1 else: if filePath in self.mediaFiles.keys(): del self.mediaFiles[filePath] missingFilesFound += 1 logger.info("Found %d files, %d new, %d updated, %d missing", totalFilesFound, newFilesFound, updatedFiles, missingFilesFound)
def __init__(self, audioDevice, sampleRate = 44100, bufferSize = 512): Thread.__init__(self, name = "AudioOutputLoop") self._lock = Lock() self._isRunning = False self._audioDevice = audioDevice self._bufferSize = bufferSize self._sampleRate = sampleRate self._maxTimePerBlockInSec = bufferSize / sampleRate pygame.mixer.init(deviceName = audioDevice.name, frequency = sampleRate, buffer = bufferSize) self._channel = pygame.mixer.find_channel() self.testWave = wave.open("./tests/resources/test.wav", "r") self.totalFrames = self.testWave.getnframes() self.allsamples = self.testWave.readframes(self.totalFrames) self._byteArray = bytearray(self._bufferSize * 2) self.numFrames = 0 logger.info("Mixer initialized")
def close(self): logger.info("Closing MIDI output '" + self.name + "'") if self.port is not None: self.port.close()
def open(self): logger.info("Opening MIDI output '" + self.name + "'") self.port = pygame.midi.Output(self._id)
def onActiveEvent(self, eventDict): """Called when the application window enters the foreground""" gain = eventDict['gain'] state = eventDict['state'] logger.info("Application activated, gain: " + str(gain) + ", state: " + str(state))
def onReset(self): """Remove all items from the arrangement""" logger.info("Reset called") self.mainGrid.reset()