| @@ -381,7 +381,7 @@ double RtApi :: getStreamTime( void ) | |||
| then = stream_.lastTickTimestamp; | |||
| return stream_.streamTime + | |||
| ((now.tv_sec + 0.000001 * now.tv_usec) - | |||
| (then.tv_sec + 0.000001 * then.tv_usec)); | |||
| (then.tv_sec + 0.000001 * then.tv_usec)); | |||
| #else | |||
| return stream_.streamTime; | |||
| #endif | |||
| @@ -1728,7 +1728,7 @@ bool RtApiCore :: callbackEvent( AudioDeviceID deviceId, | |||
| channelsLeft -= streamChannels; | |||
| } | |||
| } | |||
| if ( stream_.doConvertBuffer[1] ) { // convert from our internal "device" buffer | |||
| convertBuffer( stream_.userBuffer[1], | |||
| stream_.deviceBuffer, | |||
| @@ -2623,7 +2623,7 @@ RtApiAsio :: RtApiAsio() | |||
| // CoInitialize beforehand, but it must be for appartment threading | |||
| // (in which case, CoInitilialize will return S_FALSE here). | |||
| coInitialized_ = false; | |||
| HRESULT hr = CoInitialize( NULL ); | |||
| HRESULT hr = CoInitialize( NULL ); | |||
| if ( FAILED(hr) ) { | |||
| errorText_ = "RtApiAsio::ASIO requires a single-threaded appartment. Call CoInitializeEx(0,COINIT_APARTMENTTHREADED)"; | |||
| error( RtError::WARNING ); | |||
| @@ -2982,7 +2982,7 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne | |||
| handle = new AsioHandle; | |||
| } | |||
| catch ( std::bad_alloc& ) { | |||
| //if ( handle == NULL ) { | |||
| //if ( handle == NULL ) { | |||
| drivers.removeCurrentDriver(); | |||
| errorText_ = "RtApiAsio::probeDeviceOpen: error allocating AsioHandle memory."; | |||
| return FAILURE; | |||
| @@ -3518,13 +3518,13 @@ static long asioMessages( long selector, long value, void* message, double* opt | |||
| static const char* getAsioErrorString( ASIOError result ) | |||
| { | |||
| struct Messages | |||
| struct Messages | |||
| { | |||
| ASIOError value; | |||
| const char*message; | |||
| }; | |||
| static const Messages m[] = | |||
| static const Messages m[] = | |||
| { | |||
| { ASE_NotPresent, "Hardware input or output is not present or available." }, | |||
| { ASE_HWMalfunction, "Hardware is malfunctioning." }, | |||
| @@ -3547,7 +3547,7 @@ static const char* getAsioErrorString( ASIOError result ) | |||
| #if defined(__WINDOWS_DS__) // Windows DirectSound API | |||
| // Modified by Robin Davies, October 2005 | |||
| // - Improvements to DirectX pointer chasing. | |||
| // - Improvements to DirectX pointer chasing. | |||
| // - Bug fix for non-power-of-two Asio granularity used by Edirol PCR-A30. | |||
| // - Auto-call CoInitialize for DSOUND and ASIO platforms. | |||
| // Various revisions for RtAudio 4.0 by Gary Scavone, April 2007 | |||
| @@ -3587,7 +3587,7 @@ struct DsHandle { | |||
| void *id[2]; | |||
| void *buffer[2]; | |||
| bool xrun[2]; | |||
| UINT bufferPointer[2]; | |||
| UINT bufferPointer[2]; | |||
| DWORD dsBufferSize[2]; | |||
| DWORD dsPointerLeadTime[2]; // the number of bytes ahead of the safe pointer to lead by. | |||
| HANDLE condition; | |||
| @@ -4433,7 +4433,7 @@ void RtApiDs :: startStream() | |||
| // Increase scheduler frequency on lesser windows (a side-effect of | |||
| // increasing timer accuracy). On greater windows (Win2K or later), | |||
| // this is already in effect. | |||
| timeBeginPeriod( 1 ); | |||
| timeBeginPeriod( 1 ); | |||
| buffersRolling = false; | |||
| duplexPrerollBytes = 0; | |||
| @@ -4736,7 +4736,7 @@ void RtApiDs :: callbackEvent() | |||
| } | |||
| if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) { | |||
| LPDIRECTSOUNDBUFFER dsBuffer = (LPDIRECTSOUNDBUFFER) handle->buffer[0]; | |||
| if ( handle->drainCounter > 1 ) { // write zeros to the output stream | |||
| @@ -4802,7 +4802,7 @@ void RtApiDs :: callbackEvent() | |||
| } | |||
| if ( dsPointerBetween( nextWritePointer, safeWritePointer, currentWritePointer, dsBufferSize ) | |||
| || dsPointerBetween( endWrite, safeWritePointer, currentWritePointer, dsBufferSize ) ) { | |||
| || dsPointerBetween( endWrite, safeWritePointer, currentWritePointer, dsBufferSize ) ) { | |||
| // We've strayed into the forbidden zone ... resync the read pointer. | |||
| handle->xrun[0] = true; | |||
| nextWritePointer = safeWritePointer + handle->dsPointerLeadTime[0] - bufferBytes; | |||
| @@ -4872,14 +4872,14 @@ void RtApiDs :: callbackEvent() | |||
| if ( safeReadPointer < (DWORD)nextReadPointer ) safeReadPointer += dsBufferSize; // unwrap offset | |||
| DWORD endRead = nextReadPointer + bufferBytes; | |||
| // Handling depends on whether we are INPUT or DUPLEX. | |||
| // Handling depends on whether we are INPUT or DUPLEX. | |||
| // If we're in INPUT mode then waiting is a good thing. If we're in DUPLEX mode, | |||
| // then a wait here will drag the write pointers into the forbidden zone. | |||
| // | |||
| // In DUPLEX mode, rather than wait, we will back off the read pointer until | |||
| // it's in a safe position. This causes dropouts, but it seems to be the only | |||
| // practical way to sync up the read and write pointers reliably, given the | |||
| // the very complex relationship between phase and increment of the read and write | |||
| // | |||
| // In DUPLEX mode, rather than wait, we will back off the read pointer until | |||
| // it's in a safe position. This causes dropouts, but it seems to be the only | |||
| // practical way to sync up the read and write pointers reliably, given the | |||
| // the very complex relationship between phase and increment of the read and write | |||
| // pointers. | |||
| // | |||
| // In order to minimize audible dropouts in DUPLEX mode, we will | |||
| @@ -4929,7 +4929,7 @@ void RtApiDs :: callbackEvent() | |||
| error( RtError::SYSTEM_ERROR ); | |||
| return; | |||
| } | |||
| if ( safeReadPointer < (DWORD)nextReadPointer ) safeReadPointer += dsBufferSize; // unwrap offset | |||
| } | |||
| } | |||
| @@ -6140,7 +6140,7 @@ void RtApiAlsa :: stopStream() | |||
| AlsaHandle *apiInfo = (AlsaHandle *) stream_.apiHandle; | |||
| snd_pcm_t **handle = (snd_pcm_t **) apiInfo->handles; | |||
| if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) { | |||
| if ( apiInfo->synchronized ) | |||
| if ( apiInfo->synchronized ) | |||
| result = snd_pcm_drop( handle[0] ); | |||
| else | |||
| result = snd_pcm_drain( handle[0] ); | |||
| @@ -6603,7 +6603,7 @@ void RtApiPulse::callbackEvent( void ) | |||
| else | |||
| bytes = stream_.nUserChannels[INPUT] * stream_.bufferSize * | |||
| formatBytes( stream_.userFormat ); | |||
| if ( pa_simple_read( pah->s_rec, pulse_in, bytes, &pa_error ) < 0 ) { | |||
| errorStream_ << "RtApiPulse::callbackEvent: audio read error, " << | |||
| pa_strerror( pa_error ) << "."; | |||
| @@ -6866,7 +6866,7 @@ bool RtApiPulse::probeDeviceOpen( unsigned int device, StreamMode mode, | |||
| stream_.state = STREAM_STOPPED; | |||
| return true; | |||
| error: | |||
| if ( pah && stream_.callbackInfo.isRunning ) { | |||
| pthread_cond_destroy( &pah->runnable_cv ); | |||
| @@ -430,8 +430,6 @@ void carla_engine_idle() | |||
| bool carla_is_engine_running() | |||
| { | |||
| carla_debug("carla_is_engine_running()"); | |||
| return (gStandalone.engine != nullptr && gStandalone.engine->isRunning()); | |||
| } | |||
| @@ -40,50 +40,73 @@ class CarlaMiniW(HostWindow): | |||
| def __init__(self, parent=None): | |||
| HostWindow.__init__(self, parent) | |||
| #self.fContainer = CarlaRackW(self) | |||
| self.fContainer = CarlaPatchbayW(self) | |||
| self.fContainer = CarlaRackW(self) | |||
| #self.fContainer = CarlaPatchbayW(self) | |||
| self.setCentralWidget(self.fContainer) | |||
| Carla.host.engine_init("JACK", "Carla") | |||
| self.init() | |||
| Carla.host.patchbay_refresh() | |||
| def closeEvent(self, event): | |||
| Carla.host.engine_close() | |||
| HostWindow.closeEvent(self, event) | |||
| # ------------------------------------------------------------------------------------------------------------ | |||
| # Main | |||
| if __name__ == '__main__': | |||
| # ------------------------------------------------------------- | |||
| # App initialization | |||
| app = QApplication(sys.argv) | |||
| app.setApplicationName("Carla") | |||
| app.setApplicationVersion(VERSION) | |||
| app.setOrganizationName("falkTX") | |||
| app.setWindowIcon(QIcon(":/scalable/carla.svg")) | |||
| initHost() | |||
| # ------------------------------------------------------------- | |||
| # Set-up custom signal handling | |||
| setUpSignals() | |||
| # ------------------------------------------------------------- | |||
| # Read CLI args | |||
| appName = os.path.basename(__file__) if ("__file__" in dir() and os.path.dirname(__file__) in PATH) else sys.argv[0] | |||
| libPrefix = None | |||
| projectFilename = None | |||
| argv = app.arguments() | |||
| argc = len(argv) | |||
| Carla.host.set_engine_option(OPTION_PROCESS_NAME, 0, "carla") | |||
| for i in range(argc): | |||
| if i == 0: continue | |||
| argument = argv[i] | |||
| if argument.startswith("--with-appname="): | |||
| appName = os.path.basename(argument.replace("--with-appname=", "")) | |||
| elif argument.startswith("--with-libprefix="): | |||
| libPrefix = argument.replace("--with-libprefix=", "") | |||
| elif os.path.exists(argument): | |||
| projectFilename = argument | |||
| # ------------------------------------------------------------- | |||
| # Init host backend | |||
| initHost(appName, libPrefix) | |||
| # ------------------------------------------------------------- | |||
| # Create GUI | |||
| # Create GUI and start engine | |||
| Carla.gui = CarlaMiniW() | |||
| Carla.host.patchbay_refresh() | |||
| # ------------------------------------------------------------- | |||
| # Load project file if set | |||
| if projectFilename is not None: | |||
| Carla.gui.loadProjectLater(projectFilename) | |||
| # ------------------------------------------------------------- | |||
| # Show GUI | |||
| Carla.gui.show() | |||
| # ------------------------------------------------------------- | |||
| # App-Loop | |||
| ret = app.exec_() | |||
| # Destroy GUI | |||
| tmp = Carla.gui | |||
| Carla.gui = None | |||
| del tmp | |||
| # Exit properly | |||
| sys.exit(ret) | |||
| sys.exit(app.exec_()) | |||
| @@ -33,6 +33,12 @@ from carla_database import * | |||
| from carla_settings import * | |||
| from carla_widgets import * | |||
| # ------------------------------------------------------------------------------------------------------------ | |||
| # Session Management support | |||
| LADISH_APP_NAME = os.getenv("LADISH_APP_NAME") | |||
| NSM_URL = os.getenv("NSM_URL") | |||
| # ------------------------------------------------------------------------------------------------------------ | |||
| # Dummy widget | |||
| @@ -45,9 +51,6 @@ class CarlaDummyW(object): | |||
| def getPluginCount(self): | |||
| return 0 | |||
| def getPlugin(self, pluginId): | |||
| return None | |||
| # ----------------------------------------------------------------- | |||
| def addPlugin(self, pluginId, isProjectLoading): | |||
| @@ -64,83 +67,10 @@ class CarlaDummyW(object): | |||
| # ----------------------------------------------------------------- | |||
| def setParameterValue(self, pluginId, index, value): | |||
| pass | |||
| def setParameterDefault(self, pluginId, index, value): | |||
| pass | |||
| def setParameterMidiChannel(self, pluginId, index, channel): | |||
| pass | |||
| def setParameterMidiCC(self, pluginId, index, cc): | |||
| pass | |||
| # ----------------------------------------------------------------- | |||
| def setProgram(self, pluginId, index): | |||
| pass | |||
| def setMidiProgram(self, pluginId, index): | |||
| pass | |||
| # ----------------------------------------------------------------- | |||
| def noteOn(self, pluginId, channel, note, velocity): | |||
| pass | |||
| def noteOff(self, pluginId, channel, note): | |||
| pass | |||
| # ----------------------------------------------------------------- | |||
| def setGuiState(self, pluginId, state): | |||
| pass | |||
| # ----------------------------------------------------------------- | |||
| def updateInfo(self, pluginId): | |||
| pass | |||
| def reloadInfo(self, pluginId): | |||
| pass | |||
| def reloadParameters(self, pluginId): | |||
| pass | |||
| def reloadPrograms(self, pluginId): | |||
| pass | |||
| def reloadAll(self, pluginId): | |||
| pass | |||
| # ----------------------------------------------------------------- | |||
| def patchbayClientAdded(self, clientId, clientIcon, clientName): | |||
| pass | |||
| def patchbayClientRemoved(self, clientId, clientName): | |||
| pass | |||
| def patchbayClientRenamed(self, clientId, newClientName): | |||
| pass | |||
| def patchbayPortAdded(self, clientId, portId, portFlags, portName): | |||
| def engineStarted(self): | |||
| pass | |||
| def patchbayPortRemoved(self, groupId, portId, fullPortName): | |||
| pass | |||
| def patchbayPortRenamed(self, groupId, portId, newPortName): | |||
| pass | |||
| def patchbayConnectionAdded(self, connectionId, portOutId, portInId): | |||
| pass | |||
| def patchbayConnectionRemoved(self, connectionId): | |||
| pass | |||
| def patchbayIconChanged(self, clientId, clientIcon): | |||
| def engineStopped(self): | |||
| pass | |||
| # ----------------------------------------------------------------- | |||
| @@ -210,6 +140,9 @@ class HostWindow(QMainWindow): | |||
| # ------------------------------------------------------------- | |||
| # Internal stuff | |||
| self.fBufferSize = 0 | |||
| self.fSampleRate = 0.0 | |||
| self.fIdleTimerFast = 0 | |||
| self.fIdleTimerSlow = 0 | |||
| self.fIsProjectLoading = False | |||
| @@ -217,6 +150,32 @@ class HostWindow(QMainWindow): | |||
| self.fLadspaRdfNeedsUpdate = True | |||
| self.fLadspaRdfList = [] | |||
| self.fLastTransportFrame = 0 | |||
| self.fLastTransportState = False | |||
| if LADISH_APP_NAME: | |||
| self.fClientName = LADISH_APP_NAME | |||
| self.fSessionManagerName = "LADISH" | |||
| elif NSM_URL: | |||
| self.fClientName = "Carla.tmp" | |||
| self.fSessionManagerName = "Non Session Manager" | |||
| else: | |||
| self.fClientName = "Carla" | |||
| self.fSessionManagerName = "" | |||
| # ------------------------------------------------------------- | |||
| # Set up GUI (engine stopped) | |||
| self.ui.act_file_save.setEnabled(False) | |||
| self.ui.act_file_save_as.setEnabled(False) | |||
| self.ui.act_engine_start.setEnabled(True) | |||
| self.ui.act_engine_stop.setEnabled(False) | |||
| self.ui.act_plugin_remove_all.setEnabled(False) | |||
| #self.ui.menu_Plugins.setEnabled(False) | |||
| self.ui.menu_Canvas.setEnabled(False) | |||
| self.setTransportMenuEnabled(False) | |||
| # ------------------------------------------------------------- | |||
| # Connect actions to functions | |||
| @@ -225,100 +184,153 @@ class HostWindow(QMainWindow): | |||
| #self.ui.act_file_save.triggered.connect(self.slot_fileSave) | |||
| #self.ui.act_file_save_as.triggered.connect(self.slot_fileSaveAs) | |||
| #self.ui.act_engine_start.triggered.connect(self.slot_engineStart) | |||
| #self.ui.act_engine_stop.triggered.connect(self.slot_engineStop) | |||
| self.ui.act_engine_start.triggered.connect(self.slot_engineStart) | |||
| self.ui.act_engine_stop.triggered.connect(self.slot_engineStop) | |||
| self.ui.act_plugin_add.triggered.connect(self.slot_pluginAdd) | |||
| self.ui.act_plugin_add2.triggered.connect(self.slot_pluginAdd) | |||
| self.ui.act_plugin_remove_all.triggered.connect(self.slot_pluginRemoveAll) | |||
| #self.ui.act_plugins_enable.triggered.connect(self.slot_pluginsEnable) | |||
| #self.ui.act_plugins_disable.triggered.connect(self.slot_pluginsDisable) | |||
| #self.ui.act_plugins_panic.triggered.connect(self.slot_pluginsDisable) | |||
| #self.ui.act_plugins_volume100.triggered.connect(self.slot_pluginsVolume100) | |||
| #self.ui.act_plugins_mute.triggered.connect(self.slot_pluginsMute) | |||
| #self.ui.act_plugins_wet100.triggered.connect(self.slot_pluginsWet100) | |||
| #self.ui.act_plugins_bypass.triggered.connect(self.slot_pluginsBypass) | |||
| #self.ui.act_plugins_center.triggered.connect(self.slot_pluginsCenter) | |||
| #self.ui.act_transport_play-triggered(bool)"), SLOT("slot_transportPlayPause(bool)")) | |||
| #self.ui.act_transport_stop.triggered.connect(self.slot_transportStop) | |||
| #self.ui.act_transport_backwards.triggered.connect(self.slot_transportBackwards) | |||
| #self.ui.act_transport_forwards.triggered.connect(self.slot_transportForwards) | |||
| #self.ui.act_canvas_arrange.setEnabled(False) # TODO, later | |||
| #self.ui.act_canvas_arrange.triggered.connect(self.slot_canvasArrange) | |||
| #self.ui.act_canvas_refresh.triggered.connect(self.slot_canvasRefresh) | |||
| #self.ui.act_canvas_zoom_fit.triggered.connect(self.slot_canvasZoomFit) | |||
| #self.ui.act_canvas_zoom_in.triggered.connect(self.slot_canvasZoomIn) | |||
| #self.ui.act_canvas_zoom_out.triggered.connect(self.slot_canvasZoomOut) | |||
| #self.ui.act_canvas_zoom_100.triggered.connect(self.slot_canvasZoomReset) | |||
| #self.ui.act_canvas_print.triggered.connect(self.slot_canvasPrint) | |||
| #self.ui.act_canvas_save_image.triggered.connect(self.slot_canvasSaveImage) | |||
| self.ui.act_settings_configure.triggered.connect(self.slot_configureCarla) | |||
| self.ui.act_transport_play.triggered.connect(self.slot_transportPlayPause) | |||
| self.ui.act_transport_stop.triggered.connect(self.slot_transportStop) | |||
| self.ui.act_transport_backwards.triggered.connect(self.slot_transportBackwards) | |||
| self.ui.act_transport_forwards.triggered.connect(self.slot_transportForwards) | |||
| self.ui.act_help_about.triggered.connect(self.slot_aboutCarla) | |||
| self.ui.act_help_about_qt.triggered.connect(self.slot_aboutQt) | |||
| #self.ui.splitter-splitterMoved.connect(self.slot_splitterMoved) | |||
| #self.ui.cb_disk-currentIndexChanged.connect(self.slot_diskFolderChanged) | |||
| #self.ui.b_disk_add-clicked.connect(self.slot_diskFolderAdd) | |||
| #self.ui.b_disk_remove-clicked.connect(self.slot_diskFolderRemove) | |||
| #self.ui.fileTreeView-doubleClicked(QModelIndex)"), SLOT("slot_fileTreeDoubleClicked(QModelIndex)")) | |||
| #self.ui.miniCanvasPreview-miniCanvasMoved(double, double)"), SLOT("slot_miniCanvasMoved(double, double)")) | |||
| #self.ui.graphicsView.horizontalScrollBar()-valueChanged.connect(self.slot_horizontalScrollBarChanged) | |||
| #self.ui.graphicsView.verticalScrollBar()-valueChanged.connect(self.slot_verticalScrollBarChanged) | |||
| #self.ui.splitter.splitterMoved.connect(self.slot_splitterMoved) | |||
| #self.scene-sceneGroupMoved(int, int, QPointF)"), SLOT("slot_canvasItemMoved(int, int, QPointF)")) | |||
| #self.scene-scaleChanged(double)"), SLOT("slot_canvasScaleChanged(double)")) | |||
| #self.ui.cb_disk.currentIndexChanged.connect(self.slot_diskFolderChanged) | |||
| #self.ui.b_disk_add.clicked.connect(self.slot_diskFolderAdd) | |||
| #self.ui.b_disk_remove.clicked.connect(self.slot_diskFolderRemove) | |||
| #self.ui.fileTreeView.doubleClicked.connect(self.slot_fileTreeDoubleClicked) | |||
| self.DebugCallback.connect(self.slot_handleDebugCallback) | |||
| self.PluginAddedCallback.connect(self.slot_handlePluginAddedCallback) | |||
| self.PluginRemovedCallback.connect(self.slot_handlePluginRemovedCallback) | |||
| self.PluginRenamedCallback.connect(self.slot_handlePluginRenamedCallback) | |||
| self.ParameterValueChangedCallback.connect(self.slot_handleParameterValueChangedCallback) | |||
| self.ParameterDefaultChangedCallback.connect(self.slot_handleParameterDefaultChangedCallback) | |||
| self.ParameterMidiChannelChangedCallback.connect(self.slot_handleParameterMidiChannelChangedCallback) | |||
| self.ParameterMidiCcChangedCallback.connect(self.slot_handleParameterMidiCcChangedCallback) | |||
| self.ProgramChangedCallback.connect(self.slot_handleProgramChangedCallback) | |||
| self.MidiProgramChangedCallback.connect(self.slot_handleMidiProgramChangedCallback) | |||
| self.NoteOnCallback.connect(self.slot_handleNoteOnCallback) | |||
| self.NoteOffCallback.connect(self.slot_handleNoteOffCallback) | |||
| self.ShowGuiCallback.connect(self.slot_handleShowGuiCallback) | |||
| self.UpdateCallback.connect(self.slot_handleUpdateCallback) | |||
| self.ReloadInfoCallback.connect(self.slot_handleReloadInfoCallback) | |||
| self.ReloadParametersCallback.connect(self.slot_handleReloadParametersCallback) | |||
| self.ReloadProgramsCallback.connect(self.slot_handleReloadProgramsCallback) | |||
| self.ReloadAllCallback.connect(self.slot_handleReloadAllCallback) | |||
| self.PatchbayClientAddedCallback.connect(self.slot_handlePatchbayClientAddedCallback) | |||
| self.PatchbayClientRemovedCallback.connect(self.slot_handlePatchbayClientRemovedCallback) | |||
| self.PatchbayClientRenamedCallback.connect(self.slot_handlePatchbayClientRenamedCallback) | |||
| self.PatchbayPortAddedCallback.connect(self.slot_handlePatchbayPortAddedCallback) | |||
| self.PatchbayPortRemovedCallback.connect(self.slot_handlePatchbayPortRemovedCallback) | |||
| self.PatchbayPortRenamedCallback.connect(self.slot_handlePatchbayPortRenamedCallback) | |||
| self.PatchbayConnectionAddedCallback.connect(self.slot_handlePatchbayConnectionAddedCallback) | |||
| self.PatchbayConnectionRemovedCallback.connect(self.slot_handlePatchbayConnectionRemovedCallback) | |||
| self.PatchbayIconChangedCallback.connect(self.slot_handlePatchbayIconChangedCallback) | |||
| #self.BufferSizeChangedCallback.connect(self.slot_handleBufferSizeChangedCallback) | |||
| #self.SampleRateChangedCallback(double)"), SLOT("slot_handleSampleRateChangedCallback(double)")) | |||
| #self.NSM_AnnounceCallback(QString)"), SLOT("slot_handleNSM_AnnounceCallback(QString)")) | |||
| #self.NSM_OpenCallback(QString)"), SLOT("slot_handleNSM_OpenCallback(QString)")) | |||
| self.BufferSizeChangedCallback.connect(self.slot_handleBufferSizeChangedCallback) | |||
| self.SampleRateChangedCallback.connect(self.slot_handleSampleRateChangedCallback) | |||
| #self.NSM_AnnounceCallback.connect(self.slot_handleNSM_AnnounceCallback) | |||
| #self.NSM_OpenCallback.connect(self.slot_handleNSM_OpenCallback) | |||
| #self.NSM_SaveCallback.connect(self.slot_handleNSM_SaveCallback) | |||
| #self.ErrorCallback(QString)"), SLOT("slot_handleErrorCallback(QString)")) | |||
| #self.ErrorCallback.connect(self.slot_handleErrorCallback) | |||
| #self.QuitCallback.connect(self.slot_handleQuitCallback) | |||
| self.SIGUSR1.connect(self.slot_handleSIGUSR1) | |||
| self.SIGTERM.connect(self.slot_handleSIGTERM) | |||
| # ----------------------------------------------------------------- | |||
| # Called by containers | |||
| def init(self): | |||
| def openSettings(self, hasCanvas, hasCanvasGL): | |||
| dialog = CarlaSettingsW(self, hasCanvas, hasCanvasGL) | |||
| return dialog.exec_() | |||
| # ----------------------------------------------------------------- | |||
| # Internal stuff | |||
| def startEngine(self): | |||
| # --------------------------------------------- | |||
| # Engine settings | |||
| settings = QSettings() | |||
| forceStereo = settings.value("Engine/ForceStereo", CARLA_DEFAULT_FORCE_STEREO, type=bool) | |||
| preferPluginBridges = settings.value("Engine/PreferPluginBridges", CARLA_DEFAULT_PREFER_PLUGIN_BRIDGES, type=bool) | |||
| preferUiBridges = settings.value("Engine/PreferUiBridges", CARLA_DEFAULT_PREFER_UI_BRIDGES, type=bool) | |||
| uisAlwaysOnTop = settings.value("Engine/OscUiTimeout", CARLA_DEFAULT_UIS_ALWAYS_ON_TOP, type=bool) | |||
| uiBridgesTimeout = settings.value("Engine/OscUiTimeout", CARLA_DEFAULT_UI_BRIDGES_TIMEOUT, type=int) | |||
| Carla.processMode = settings.value("Engine/ProcessMode", CARLA_DEFAULT_PROCESS_MODE, type=int) | |||
| Carla.maxParameters = settings.value("Engine/MaxParameters", CARLA_DEFAULT_MAX_PARAMETERS, type=int) | |||
| audioDriver = settings.value("Engine/AudioDriver", CARLA_DEFAULT_AUDIO_DRIVER, type=str) | |||
| if audioDriver == "JACK": | |||
| #transportMode = settings.value("Engine/TransportMode", TRANSPORT_MODE_JACK, type=int) | |||
| transportMode = TRANSPORT_MODE_JACK | |||
| else: | |||
| transportMode = TRANSPORT_MODE_INTERNAL | |||
| audioNumPeriods = settings.value("Engine/AudioBufferSize", CARLA_DEFAULT_AUDIO_NUM_PERIODS, type=int) | |||
| audioBufferSize = settings.value("Engine/AudioBufferSize", CARLA_DEFAULT_AUDIO_BUFFER_SIZE, type=int) | |||
| audioSampleRate = settings.value("Engine/AudioSampleRate", CARLA_DEFAULT_AUDIO_SAMPLE_RATE, type=int) | |||
| audioDevice = settings.value("Engine/AudioDevice", "", type=str) | |||
| Carla.host.set_engine_option(OPTION_AUDIO_NUM_PERIODS, audioNumPeriods, "") | |||
| Carla.host.set_engine_option(OPTION_AUDIO_BUFFER_SIZE, audioBufferSize, "") | |||
| Carla.host.set_engine_option(OPTION_AUDIO_SAMPLE_RATE, audioSampleRate, "") | |||
| Carla.host.set_engine_option(OPTION_AUDIO_DEVICE, 0, audioDevice) | |||
| if Carla.processMode == PROCESS_MODE_CONTINUOUS_RACK: | |||
| forceStereo = True | |||
| elif Carla.processMode == PROCESS_MODE_MULTIPLE_CLIENTS: # and LADISH_APP_NAME: | |||
| print("LADISH detected but using multiple clients (not allowed), forcing single client now") | |||
| Carla.processMode = PROCESS_MODE_SINGLE_CLIENT | |||
| Carla.host.set_engine_option(OPTION_FORCE_STEREO, forceStereo, "") | |||
| Carla.host.set_engine_option(OPTION_PREFER_PLUGIN_BRIDGES, preferPluginBridges, "") | |||
| Carla.host.set_engine_option(OPTION_PREFER_UI_BRIDGES, preferUiBridges, "") | |||
| Carla.host.set_engine_option(OPTION_UIS_ALWAYS_ON_TOP, uisAlwaysOnTop, "") | |||
| Carla.host.set_engine_option(OPTION_UI_BRIDGES_TIMEOUT, uiBridgesTimeout, "") | |||
| Carla.host.set_engine_option(OPTION_PROCESS_MODE, Carla.processMode, "") | |||
| Carla.host.set_engine_option(OPTION_MAX_PARAMETERS, Carla.maxParameters, "") | |||
| Carla.host.set_engine_option(OPTION_TRANSPORT_MODE, transportMode, "") | |||
| # --------------------------------------------- | |||
| # Start | |||
| if not Carla.host.engine_init(audioDriver, self.fClientName): | |||
| #if self.fFirstEngineInit: | |||
| #self.fFirstEngineInit = False | |||
| #return | |||
| audioError = cString(Carla.host.get_last_error()) | |||
| if audioError: | |||
| QMessageBox.critical(self, self.tr("Error"), self.tr("Could not connect to Audio backend '%s', possible reasons:\n%s" % (audioDriver, audioError))) | |||
| else: | |||
| QMessageBox.critical(self, self.tr("Error"), self.tr("Could not connect to Audio backend '%s'" % audioDriver)) | |||
| return | |||
| self.fBufferSize = Carla.host.get_buffer_size() | |||
| self.fSampleRate = Carla.host.get_sample_rate() | |||
| #self.fFirstEngineInit = False | |||
| # Peaks and TimeInfo | |||
| #self.fIdleTimerFast = self.startTimer(self.fSavedSettings["Main/RefreshInterval"]) | |||
| # LEDs and edit dialog parameters | |||
| #self.fIdleTimerSlow = self.startTimer(self.fSavedSettings["Main/RefreshInterval"]*2) | |||
| self.fIdleTimerFast = self.startTimer(50) | |||
| self.fIdleTimerSlow = self.startTimer(50*2) | |||
| def stopEngine(self): | |||
| if self.fContainer.getPluginCount() > 0: | |||
| ask = QMessageBox.question(self, self.tr("Warning"), self.tr("There are still some plugins loaded, you need to remove them to stop the engine.\n" | |||
| "Do you want to do this now?"), | |||
| QMessageBox.Yes | QMessageBox.No, QMessageBox.No) | |||
| if ask != QMessageBox.Yes: | |||
| return | |||
| self.ui.act_plugin_remove_all.setEnabled(False) | |||
| self.fContainer.removeAllPlugins() | |||
| if Carla.host.is_engine_running() and not Carla.host.engine_close(): | |||
| print(cString(Carla.host.get_last_error())) | |||
| self.fBufferSize = 0 | |||
| self.fSampleRate = 0.0 | |||
| if self.fIdleTimerFast != 0: | |||
| self.killTimer(self.fIdleTimerFast) | |||
| self.fIdleTimerFast = 0 | |||
| if self.fIdleTimerSlow != 0: | |||
| self.killTimer(self.fIdleTimerSlow) | |||
| self.fIdleTimerSlow = 0 | |||
| def getExtraStuff(self, plugin): | |||
| ptype = plugin['type'] | |||
| @@ -367,6 +379,90 @@ class HostWindow(QMainWindow): | |||
| def setLoadRDFsNeeded(self): | |||
| self.fLadspaRdfNeedsUpdate = True | |||
| def refreshTransport(self, forced = False): | |||
| if not Carla.host.is_engine_running(): | |||
| return | |||
| if self.fSampleRate == 0.0: | |||
| return | |||
| timeInfo = Carla.host.get_transport_info() | |||
| playing = bool(timeInfo['playing']) | |||
| frame = int(timeInfo['frame']) | |||
| if playing != self.fLastTransportState or forced: | |||
| if playing: | |||
| icon = getIcon("media-playback-pause") | |||
| self.ui.act_transport_play.setChecked(True) | |||
| self.ui.act_transport_play.setIcon(icon) | |||
| self.ui.act_transport_play.setText(self.tr("&Pause")) | |||
| else: | |||
| icon = getIcon("media-playback-start") | |||
| self.ui.act_transport_play.setChecked(False) | |||
| self.ui.act_transport_play.setIcon(icon) | |||
| self.ui.act_transport_play.setText(self.tr("&Play")) | |||
| self.fLastTransportState = playing | |||
| if frame != self.fLastTransportFrame or forced: | |||
| time = frame / self.fSampleRate | |||
| secs = time % 60 | |||
| mins = (time / 60) % 60 | |||
| hrs = (time / 3600) % 60 | |||
| #textTransport = "Transport %s, at %02i:%02i:%02i" % ("playing" if playing else "stopped", hrs, mins, secs) | |||
| #self.fInfoLabel.setText("%s | %s" % (self.fInfoText, textTransport)) | |||
| self.fLastTransportFrame = frame | |||
| def setTransportMenuEnabled(self, enabled): | |||
| self.ui.act_transport_play.setEnabled(enabled) | |||
| self.ui.act_transport_stop.setEnabled(enabled) | |||
| self.ui.act_transport_backwards.setEnabled(enabled) | |||
| self.ui.act_transport_forwards.setEnabled(enabled) | |||
| self.ui.menu_Transport.setEnabled(enabled) | |||
| # ----------------------------------------------------------------- | |||
| @pyqtSlot() | |||
| def slot_engineStart(self): | |||
| self.startEngine() | |||
| check = Carla.host.is_engine_running() | |||
| self.ui.act_file_save.setEnabled(check) | |||
| self.ui.act_engine_start.setEnabled(not check) | |||
| self.ui.act_engine_stop.setEnabled(check) | |||
| self.ui.menu_Canvas.setEnabled(check) | |||
| if self.fSessionManagerName != "Non Session Manager": | |||
| self.ui.act_file_open.setEnabled(check) | |||
| self.ui.act_file_save_as.setEnabled(check) | |||
| if check: | |||
| #self.fInfoText = "Engine running | SampleRate: %g | BufferSize: %i" % (self.fSampleRate, self.fBufferSize) | |||
| self.refreshTransport(True) | |||
| self.fContainer.engineStarted() | |||
| self.setTransportMenuEnabled(check) | |||
| @pyqtSlot() | |||
| def slot_engineStop(self): | |||
| self.stopEngine() | |||
| check = Carla.host.is_engine_running() | |||
| self.ui.act_file_save.setEnabled(check) | |||
| self.ui.act_engine_start.setEnabled(not check) | |||
| self.ui.act_engine_stop.setEnabled(check) | |||
| self.ui.menu_Canvas.setEnabled(check) | |||
| if self.fSessionManagerName != "Non Session Manager": | |||
| self.ui.act_file_open.setEnabled(check) | |||
| self.ui.act_file_save_as.setEnabled(check) | |||
| if not check: | |||
| self.fContainer.engineStopped() | |||
| #self.fInfoText = "" | |||
| #self.fInfoLabel.setText("Engine stopped") | |||
| self.setTransportMenuEnabled(check) | |||
| # ----------------------------------------------------------------- | |||
| @pyqtSlot() | |||
| @@ -392,40 +488,55 @@ class HostWindow(QMainWindow): | |||
| @pyqtSlot() | |||
| def slot_pluginRemoveAll(self): | |||
| self.ui.act_plugin_remove_all.setEnabled(False) | |||
| self.fContainer.removeAllPlugins() | |||
| Carla.host.remove_all_plugins() | |||
| # ----------------------------------------------------------------- | |||
| @pyqtSlot(bool) | |||
| def slot_transportPlayPause(self, toggled): | |||
| if not Carla.host.is_engine_running(): | |||
| return | |||
| if toggled: | |||
| Carla.host.transport_play() | |||
| else: | |||
| Carla.host.transport_pause() | |||
| self.refreshTransport() | |||
| @pyqtSlot() | |||
| def slot_configureCarla(self): | |||
| dialog = CarlaSettingsW(self, False) # TODO - hasGL | |||
| def slot_transportStop(self): | |||
| if not Carla.host.is_engine_running(): | |||
| return | |||
| if not dialog.exec_(): | |||
| Carla.host.transport_pause() | |||
| Carla.host.transport_relocate(0) | |||
| self.refreshTransport() | |||
| @pyqtSlot() | |||
| def slot_transportBackwards(self): | |||
| if not Carla.host.is_engine_running(): | |||
| return | |||
| #self.loadSettings(False) | |||
| #patchcanvas.clear() | |||
| newFrame = Carla.host.get_current_transport_frame() - 100000 | |||
| if newFrame < 0: | |||
| newFrame = 0 | |||
| #pOptions = patchcanvas.options_t() | |||
| #pOptions.theme_name = self.fSavedSettings["Canvas/Theme"] | |||
| #pOptions.auto_hide_groups = self.fSavedSettings["Canvas/AutoHideGroups"] | |||
| #pOptions.use_bezier_lines = self.fSavedSettings["Canvas/UseBezierLines"] | |||
| #pOptions.antialiasing = self.fSavedSettings["Canvas/Antialiasing"] | |||
| #pOptions.eyecandy = self.fSavedSettings["Canvas/EyeCandy"] | |||
| Carla.host.transport_relocate(newFrame) | |||
| #pFeatures = patchcanvas.features_t() | |||
| #pFeatures.group_info = False | |||
| #pFeatures.group_rename = False | |||
| #pFeatures.port_info = False | |||
| #pFeatures.port_rename = False | |||
| #pFeatures.handle_group_pos = True | |||
| @pyqtSlot() | |||
| def slot_transportForwards(self): | |||
| if not Carla.host.is_engine_running(): | |||
| return | |||
| #patchcanvas.setOptions(pOptions) | |||
| #patchcanvas.setFeatures(pFeatures) | |||
| #patchcanvas.init("Carla", self.scene, canvasCallback, False) | |||
| newFrame = Carla.host.get_current_transport_frame() + 100000 | |||
| Carla.host.transport_relocate(newFrame) | |||
| #if self.fEngineStarted: | |||
| #Carla.host.patchbay_refresh() | |||
| # ----------------------------------------------------------------- | |||
| @pyqtSlot() | |||
| def slot_aboutCarla(self): | |||
| @@ -460,97 +571,15 @@ class HostWindow(QMainWindow): | |||
| def slot_handlePluginRenamedCallback(self, pluginId, newName): | |||
| self.fContainer.renamePlugin(pluginId, newName) | |||
| @pyqtSlot(int, int, float) | |||
| def slot_handleParameterValueChangedCallback(self, pluginId, parameterId, value): | |||
| self.fContainer.setParameterValue(parameterId, value) | |||
| @pyqtSlot(int, int, float) | |||
| def slot_handleParameterDefaultChangedCallback(self, pluginId, parameterId, value): | |||
| self.fContainer.setParameterDefault(parameterId, value) | |||
| @pyqtSlot(int, int, int) | |||
| def slot_handleParameterMidiChannelChangedCallback(self, pluginId, parameterId, channel): | |||
| self.fContainer.setParameterMidiChannel(parameterId, channel) | |||
| @pyqtSlot(int, int, int) | |||
| def slot_handleParameterMidiCcChangedCallback(self, pluginId, parameterId, cc): | |||
| self.fContainer.setParameterMidiCC(parameterId, cc) | |||
| @pyqtSlot(int, int) | |||
| def slot_handleProgramChangedCallback(self, pluginId, programId): | |||
| self.fContainer.setProgram(programId) | |||
| @pyqtSlot(int, int) | |||
| def slot_handleMidiProgramChangedCallback(self, pluginId, midiProgramId): | |||
| self.fContainer.setMidiProgram(midiProgramId) | |||
| @pyqtSlot(int, int, int, int) | |||
| def slot_handleNoteOnCallback(self, pluginId, channel, note, velo): | |||
| self.fContainer.noteOn(channel, note) | |||
| @pyqtSlot(int, int, int) | |||
| def slot_handleNoteOffCallback(self, pluginId, channel, note): | |||
| self.fContainer.noteOff(channel, note) | |||
| @pyqtSlot(int, int) | |||
| def slot_handleShowGuiCallback(self, pluginId, state): | |||
| self.fContainer.setGuiState(pluginId, state) | |||
| @pyqtSlot(int) | |||
| def slot_handleUpdateCallback(self, pluginId): | |||
| self.fContainer.updateInfo(pluginId) | |||
| @pyqtSlot(int) | |||
| def slot_handleReloadInfoCallback(self, pluginId): | |||
| self.fContainer.reloadInfo(pluginId) | |||
| @pyqtSlot(int) | |||
| def slot_handleReloadParametersCallback(self, pluginId): | |||
| self.fContainer.reloadParameters(pluginId) | |||
| @pyqtSlot(int) | |||
| def slot_handleReloadProgramsCallback(self, pluginId): | |||
| self.fContainer.reloadPrograms(pluginId) | |||
| @pyqtSlot(int) | |||
| def slot_handleReloadAllCallback(self, pluginId): | |||
| self.fContainer.reloadAll(pluginId) | |||
| @pyqtSlot(int, int, str) | |||
| def slot_handlePatchbayClientAddedCallback(self, clientId, clientIcon, clientName): | |||
| self.fContainer.patchbayClientAdded(clientId, clientIcon, clientName) | |||
| @pyqtSlot(int, str) | |||
| def slot_handlePatchbayClientRemovedCallback(self, clientId, clientName): | |||
| self.fContainer.patchbayClientRemoved(clientId, clientName) | |||
| @pyqtSlot(int, str) | |||
| def slot_handlePatchbayClientRenamedCallback(self, clientId, newClientName): | |||
| self.fContainer.patchbayClientRenamed(clientId, newClientName) | |||
| def slot_handleBufferSizeChangedCallback(self, newBufferSize): | |||
| self.fBufferSize = newBufferSize | |||
| #self.fInfoText = "Engine running | SampleRate: %g | BufferSize: %i" % (self.fSampleRate, self.fBufferSize) | |||
| @pyqtSlot(int, int, int, str) | |||
| def slot_handlePatchbayPortAddedCallback(self, clientId, portId, portFlags, portName): | |||
| self.fContainer.patchbayPortAdded(clientId, portId, portFlags, portName) | |||
| @pyqtSlot(int, int, str) | |||
| def slot_handlePatchbayPortRemovedCallback(self, groupId, portId, fullPortName): | |||
| self.fContainer.patchbayPortRemoved(groupId, portId, fullPortName) | |||
| @pyqtSlot(int, int, str) | |||
| def slot_handlePatchbayPortRenamedCallback(self, groupId, portId, newPortName): | |||
| self.fContainer.patchbayPortRenamed(groupId, portId, newPortName) | |||
| @pyqtSlot(int, int, int) | |||
| def slot_handlePatchbayConnectionAddedCallback(self, connectionId, portOutId, portInId): | |||
| self.fContainer.patchbayConnectionAdded(connectionId, portOutId, portInId) | |||
| @pyqtSlot(int) | |||
| def slot_handlePatchbayConnectionRemovedCallback(self, connectionId): | |||
| self.fContainer.patchbayConnectionRemoved(connectionId) | |||
| @pyqtSlot(int, int) | |||
| def slot_handlePatchbayIconChangedCallback(self, clientId, clientIcon): | |||
| self.fContainer.patchbayIconChanged(clientId, clientIcon) | |||
| @pyqtSlot(float) | |||
| def slot_handleSampleRateChangedCallback(self, newSampleRate): | |||
| self.fSampleRate = newSampleRate | |||
| #self.fInfoText = "Engine running | SampleRate: %g | BufferSize: %i" % (self.fSampleRate, self.fBufferSize) | |||
| # ----------------------------------------------------------------- | |||
| @@ -570,6 +599,7 @@ class HostWindow(QMainWindow): | |||
| if event.timerId() == self.fIdleTimerFast: | |||
| Carla.host.engine_idle() | |||
| self.fContainer.idleFast() | |||
| self.refreshTransport() | |||
| elif event.timerId() == self.fIdleTimerSlow: | |||
| self.fContainer.idleSlow() | |||
| @@ -585,6 +615,14 @@ class HostWindow(QMainWindow): | |||
| self.killTimer(self.fIdleTimerSlow) | |||
| self.fIdleTimerSlow = 0 | |||
| #self.saveSettings() | |||
| if Carla.host.is_engine_running(): | |||
| Carla.host.set_engine_about_to_close() | |||
| self.ui.act_plugin_remove_all.setEnabled(False) | |||
| self.fContainer.removeAllPlugins() | |||
| self.stopEngine() | |||
| QMainWindow.closeEvent(self, event) | |||
| # ------------------------------------------------------------------------------------------------------------ | |||
| @@ -24,6 +24,9 @@ try: | |||
| except: | |||
| from PyQt4.QtGui import QGraphicsView | |||
| #QPrinter, QPrintDialog | |||
| #QImage | |||
| # ------------------------------------------------------------------------------------------------------------ | |||
| # Imports (Custom Stuff) | |||
| @@ -53,6 +56,7 @@ class CarlaPatchbayW(QGraphicsView): | |||
| # ------------------------------------------------------------- | |||
| # Internal stuff | |||
| self.fParent = parent | |||
| self.fPluginCount = 0 | |||
| self.fPluginList = [] | |||
| @@ -88,26 +92,69 @@ class CarlaPatchbayW(QGraphicsView): | |||
| #patchcanvas.setInitialPos(DEFAULT_CANVAS_WIDTH / 2, DEFAULT_CANVAS_HEIGHT / 2) | |||
| #self.setSceneRect(0, 0, DEFAULT_CANVAS_WIDTH, DEFAULT_CANVAS_HEIGHT) | |||
| # ----------------------------------------------------------------- | |||
| # ------------------------------------------------------------- | |||
| # Connect actions to functions | |||
| def recheckPluginHints(self, hints): | |||
| pass | |||
| if parent is None: | |||
| return | |||
| parent.ui.act_plugins_enable.triggered.connect(self.slot_pluginsEnable) | |||
| parent.ui.act_plugins_disable.triggered.connect(self.slot_pluginsDisable) | |||
| parent.ui.act_plugins_volume100.triggered.connect(self.slot_pluginsVolume100) | |||
| parent.ui.act_plugins_mute.triggered.connect(self.slot_pluginsMute) | |||
| parent.ui.act_plugins_wet100.triggered.connect(self.slot_pluginsWet100) | |||
| parent.ui.act_plugins_bypass.triggered.connect(self.slot_pluginsBypass) | |||
| parent.ui.act_plugins_center.triggered.connect(self.slot_pluginsCenter) | |||
| parent.ui.act_plugins_panic.triggered.connect(self.slot_pluginsDisable) | |||
| parent.ui.act_canvas_arrange.setEnabled(False) # TODO, later | |||
| parent.ui.act_canvas_arrange.triggered.connect(self.slot_canvasArrange) | |||
| parent.ui.act_canvas_refresh.triggered.connect(self.slot_canvasRefresh) | |||
| parent.ui.act_canvas_zoom_fit.triggered.connect(self.slot_canvasZoomFit) | |||
| parent.ui.act_canvas_zoom_in.triggered.connect(self.slot_canvasZoomIn) | |||
| parent.ui.act_canvas_zoom_out.triggered.connect(self.slot_canvasZoomOut) | |||
| parent.ui.act_canvas_zoom_100.triggered.connect(self.slot_canvasZoomReset) | |||
| parent.ui.act_canvas_print.triggered.connect(self.slot_canvasPrint) | |||
| parent.ui.act_canvas_save_image.triggered.connect(self.slot_canvasSaveImage) | |||
| parent.ui.act_settings_configure.triggered.connect(self.slot_configureCarla) | |||
| parent.ParameterValueChangedCallback.connect(self.slot_handleParameterValueChangedCallback) | |||
| parent.ParameterDefaultChangedCallback.connect(self.slot_handleParameterDefaultChangedCallback) | |||
| parent.ParameterMidiChannelChangedCallback.connect(self.slot_handleParameterMidiChannelChangedCallback) | |||
| parent.ParameterMidiCcChangedCallback.connect(self.slot_handleParameterMidiCcChangedCallback) | |||
| parent.ProgramChangedCallback.connect(self.slot_handleProgramChangedCallback) | |||
| parent.MidiProgramChangedCallback.connect(self.slot_handleMidiProgramChangedCallback) | |||
| parent.NoteOnCallback.connect(self.slot_handleNoteOnCallback) | |||
| parent.NoteOffCallback.connect(self.slot_handleNoteOffCallback) | |||
| parent.ShowGuiCallback.connect(self.slot_handleShowGuiCallback) | |||
| parent.UpdateCallback.connect(self.slot_handleUpdateCallback) | |||
| parent.ReloadInfoCallback.connect(self.slot_handleReloadInfoCallback) | |||
| parent.ReloadParametersCallback.connect(self.slot_handleReloadParametersCallback) | |||
| parent.ReloadProgramsCallback.connect(self.slot_handleReloadProgramsCallback) | |||
| parent.ReloadAllCallback.connect(self.slot_handleReloadAllCallback) | |||
| parent.PatchbayClientAddedCallback.connect(self.slot_handlePatchbayClientAddedCallback) | |||
| parent.PatchbayClientRemovedCallback.connect(self.slot_handlePatchbayClientRemovedCallback) | |||
| parent.PatchbayClientRenamedCallback.connect(self.slot_handlePatchbayClientRenamedCallback) | |||
| parent.PatchbayPortAddedCallback.connect(self.slot_handlePatchbayPortAddedCallback) | |||
| parent.PatchbayPortRemovedCallback.connect(self.slot_handlePatchbayPortRemovedCallback) | |||
| parent.PatchbayPortRenamedCallback.connect(self.slot_handlePatchbayPortRenamedCallback) | |||
| parent.PatchbayConnectionAddedCallback.connect(self.slot_handlePatchbayConnectionAddedCallback) | |||
| parent.PatchbayConnectionRemovedCallback.connect(self.slot_handlePatchbayConnectionRemovedCallback) | |||
| parent.PatchbayIconChangedCallback.connect(self.slot_handlePatchbayIconChangedCallback) | |||
| #self.ui.miniCanvasPreview-miniCanvasMoved(double, double)"), SLOT("slot_miniCanvasMoved(double, double)")) | |||
| #self.ui.graphicsView.horizontalScrollBar()-valueChanged.connect(self.slot_horizontalScrollBarChanged) | |||
| #self.ui.graphicsView.verticalScrollBar()-valueChanged.connect(self.slot_verticalScrollBarChanged) | |||
| #self.scene-sceneGroupMoved(int, int, QPointF)"), SLOT("slot_canvasItemMoved(int, int, QPointF)")) | |||
| #self.scene-scaleChanged(double)"), SLOT("slot_canvasScaleChanged(double)")) | |||
| # ----------------------------------------------------------------- | |||
| def getPluginCount(self): | |||
| return self.fPluginCount | |||
| def getPlugin(self, pluginId): | |||
| if pluginId >= self.fPluginCount: | |||
| return None | |||
| pitem = self.fPluginList[pluginId] | |||
| if pitem is None: | |||
| return None | |||
| return pitem | |||
| # ----------------------------------------------------------------- | |||
| def addPlugin(self, pluginId, isProjectLoading): | |||
| @@ -142,7 +189,7 @@ class CarlaPatchbayW(QGraphicsView): | |||
| if pitem is None: | |||
| return | |||
| pitem.setName(name) | |||
| pitem.setName(newName) | |||
| def removeAllPlugins(self): | |||
| for i in range(self.fPluginCount): | |||
| @@ -159,7 +206,160 @@ class CarlaPatchbayW(QGraphicsView): | |||
| # ----------------------------------------------------------------- | |||
| def setParameterValue(self, pluginId, index, value): | |||
| def engineStarted(self): | |||
| pass | |||
| def engineStopped(self): | |||
| patchcanvas.clear() | |||
| # ----------------------------------------------------------------- | |||
| def idleFast(self): | |||
| pass | |||
| def idleSlow(self): | |||
| for i in range(self.fPluginCount): | |||
| pitem = self.fPluginList[i] | |||
| if pitem is None: | |||
| break | |||
| pitem.idleSlow() | |||
| # ----------------------------------------------------------------- | |||
| def recheckPluginHints(self, hints): | |||
| pass | |||
| # ----------------------------------------------------------------- | |||
| @pyqtSlot() | |||
| def slot_pluginsEnable(self): | |||
| if not Carla.host.is_engine_running(): | |||
| return | |||
| for i in range(self.fPluginCount): | |||
| Carla.host.set_active(i, True) | |||
| @pyqtSlot() | |||
| def slot_pluginsDisable(self): | |||
| if not Carla.host.is_engine_running(): | |||
| return | |||
| for i in range(self.fPluginCount): | |||
| Carla.host.set_active(i, False) | |||
| @pyqtSlot() | |||
| def slot_pluginsVolume100(self): | |||
| if not Carla.host.is_engine_running(): | |||
| return | |||
| for i in range(self.fPluginCount): | |||
| pitem = self.fPluginList[i] | |||
| if pitem is None: | |||
| break | |||
| if pitem.fPluginInfo['hints'] & PLUGIN_CAN_VOLUME: | |||
| pitem.setParameterValue(PARAMETER_VOLUME, 1.0) | |||
| Carla.host.set_volume(i, 1.0) | |||
| @pyqtSlot() | |||
| def slot_pluginsMute(self): | |||
| if not Carla.host.is_engine_running(): | |||
| return | |||
| for i in range(self.fPluginCount): | |||
| pitem = self.fPluginList[i] | |||
| if pitem is None: | |||
| break | |||
| if pitem.fPluginInfo['hints'] & PLUGIN_CAN_VOLUME: | |||
| pitem.setParameterValue(PARAMETER_VOLUME, 0.0) | |||
| Carla.host.set_volume(i, 0.0) | |||
| @pyqtSlot() | |||
| def slot_pluginsWet100(self): | |||
| if not Carla.host.is_engine_running(): | |||
| return | |||
| for i in range(self.fPluginCount): | |||
| pitem = self.fPluginList[i] | |||
| if pitem is None: | |||
| break | |||
| if pitem.fPluginInfo['hints'] & PLUGIN_CAN_DRYWET: | |||
| pitem.setParameterValue(PARAMETER_DRYWET, 1.0) | |||
| Carla.host.set_drywet(i, 1.0) | |||
| @pyqtSlot() | |||
| def slot_pluginsBypass(self): | |||
| if not Carla.host.is_engine_running(): | |||
| return | |||
| for i in range(self.fPluginCount): | |||
| pitem = self.fPluginList[i] | |||
| if pitem is None: | |||
| break | |||
| if pitem.fPluginInfo['hints'] & PLUGIN_CAN_DRYWET: | |||
| pitem.setParameterValue(PARAMETER_DRYWET, 0.0) | |||
| Carla.host.set_drywet(i, 0.0) | |||
| @pyqtSlot() | |||
| def slot_pluginsCenter(self): | |||
| if not Carla.host.is_engine_running(): | |||
| return | |||
| for i in range(self.fPluginCount): | |||
| pitem = self.fPluginList[i] | |||
| if pitem is None: | |||
| break | |||
| if pitem.fPluginInfo['hints'] & PLUGIN_CAN_BALANCE: | |||
| pitem.setParameterValue(PARAMETER_BALANCE_LEFT, -1.0) | |||
| pitem.setParameterValue(PARAMETER_BALANCE_RIGHT, 1.0) | |||
| Carla.host.set_balance_left(i, -1.0) | |||
| Carla.host.set_balance_right(i, 1.0) | |||
| if pitem.fPluginInfo['hints'] & PLUGIN_CAN_PANNING: | |||
| pitem.setParameterValue(PARAMETER_PANNING, 1.0) | |||
| Carla.host.set_panning(i, 1.0) | |||
| # ----------------------------------------------------------------- | |||
| @pyqtSlot() | |||
| def slot_configureCarla(self): | |||
| if self.fParent is None or not self.fParent.openSettings(False, False): | |||
| return | |||
| #self.loadSettings(False) | |||
| patchcanvas.clear() | |||
| #pOptions = patchcanvas.options_t() | |||
| #pOptions.theme_name = self.fSavedSettings["Canvas/Theme"] | |||
| #pOptions.auto_hide_groups = self.fSavedSettings["Canvas/AutoHideGroups"] | |||
| #pOptions.use_bezier_lines = self.fSavedSettings["Canvas/UseBezierLines"] | |||
| #pOptions.antialiasing = self.fSavedSettings["Canvas/Antialiasing"] | |||
| #pOptions.eyecandy = self.fSavedSettings["Canvas/EyeCandy"] | |||
| pFeatures = patchcanvas.features_t() | |||
| pFeatures.group_info = False | |||
| pFeatures.group_rename = False | |||
| pFeatures.port_info = False | |||
| pFeatures.port_rename = False | |||
| pFeatures.handle_group_pos = True | |||
| #patchcanvas.setOptions(pOptions) | |||
| patchcanvas.setFeatures(pFeatures) | |||
| patchcanvas.init("Carla", self.scene, CanvasCallback, False) | |||
| if Carla.host.is_engine_running(): | |||
| Carla.host.patchbay_refresh() | |||
| # ----------------------------------------------------------------- | |||
| @pyqtSlot(int, int, float) | |||
| def slot_handleParameterValueChangedCallback(self, pluginId, index, value): | |||
| if pluginId >= self.fPluginCount: | |||
| return | |||
| @@ -169,7 +369,8 @@ class CarlaPatchbayW(QGraphicsView): | |||
| pitem.setParameterValue(index, value) | |||
| def setParameterDefault(self, pluginId, index, value): | |||
| @pyqtSlot(int, int, float) | |||
| def slot_handleParameterDefaultChangedCallback(self, pluginId, index, value): | |||
| if pluginId >= self.fPluginCount: | |||
| return | |||
| @@ -179,7 +380,8 @@ class CarlaPatchbayW(QGraphicsView): | |||
| pitem.setParameterDefault(index, value) | |||
| def setParameterMidiChannel(self, pluginId, index, channel): | |||
| @pyqtSlot(int, int, int) | |||
| def slot_handleParameterMidiChannelChangedCallback(self, pluginId, index, channel): | |||
| if pluginId >= self.fPluginCount: | |||
| return | |||
| @@ -189,7 +391,8 @@ class CarlaPatchbayW(QGraphicsView): | |||
| pitem.setParameterMidiChannel(index, channel) | |||
| def setParameterMidiCC(self, pluginId, index, cc): | |||
| @pyqtSlot(int, int, int) | |||
| def slot_handleParameterMidiCcChangedCallback(self, pluginId, index, cc): | |||
| if pluginId >= self.fPluginCount: | |||
| return | |||
| @@ -201,7 +404,8 @@ class CarlaPatchbayW(QGraphicsView): | |||
| # ----------------------------------------------------------------- | |||
| def setProgram(self, pluginId, index): | |||
| @pyqtSlot(int, int) | |||
| def slot_handleProgramChangedCallback(self, pluginId, index): | |||
| if pluginId >= self.fPluginCount: | |||
| return | |||
| @@ -211,7 +415,8 @@ class CarlaPatchbayW(QGraphicsView): | |||
| pitem.setProgram(index) | |||
| def setMidiProgram(self, pluginId, index): | |||
| @pyqtSlot(int, int) | |||
| def slot_handleMidiProgramChangedCallback(self, pluginId, index): | |||
| if pluginId >= self.fPluginCount: | |||
| return | |||
| @@ -223,7 +428,8 @@ class CarlaPatchbayW(QGraphicsView): | |||
| # ----------------------------------------------------------------- | |||
| def noteOn(self, pluginId, channel, note, velocity): | |||
| @pyqtSlot(int, int, int, int) | |||
| def slot_handleNoteOnCallback(self, pluginId, channel, note, velo): | |||
| if pluginId >= self.fPluginCount: | |||
| return | |||
| @@ -233,7 +439,8 @@ class CarlaPatchbayW(QGraphicsView): | |||
| pitem.sendNoteOn(channel, note) | |||
| def noteOff(self, pluginId, channel, note): | |||
| @pyqtSlot(int, int, int) | |||
| def slot_handleNoteOffCallback(self, pluginId, channel, note): | |||
| if pluginId >= self.fPluginCount: | |||
| return | |||
| @@ -245,12 +452,14 @@ class CarlaPatchbayW(QGraphicsView): | |||
| # ----------------------------------------------------------------- | |||
| def setGuiState(self, pluginId, state): | |||
| @pyqtSlot(int, int) | |||
| def slot_handleShowGuiCallback(self, pluginId, state): | |||
| pass | |||
| # ----------------------------------------------------------------- | |||
| def updateInfo(self, pluginId): | |||
| @pyqtSlot(int) | |||
| def slot_handleUpdateCallback(self, pluginId): | |||
| if pluginId >= self.fPluginCount: | |||
| return | |||
| @@ -260,7 +469,8 @@ class CarlaPatchbayW(QGraphicsView): | |||
| pitem.updateInfo() | |||
| def reloadInfo(self, pluginId): | |||
| @pyqtSlot(int) | |||
| def slot_handleReloadInfoCallback(self, pluginId): | |||
| if pluginId >= self.fPluginCount: | |||
| return | |||
| @@ -270,7 +480,8 @@ class CarlaPatchbayW(QGraphicsView): | |||
| pitem.reloadInfo() | |||
| def reloadParameters(self, pluginId): | |||
| @pyqtSlot(int) | |||
| def slot_handleReloadParametersCallback(self, pluginId): | |||
| if pluginId >= self.fPluginCount: | |||
| return | |||
| @@ -280,7 +491,8 @@ class CarlaPatchbayW(QGraphicsView): | |||
| pitem.reloadParameters() | |||
| def reloadPrograms(self, pluginId): | |||
| @pyqtSlot(int) | |||
| def slot_handleReloadProgramsCallback(self, pluginId): | |||
| if pluginId >= self.fPluginCount: | |||
| return | |||
| @@ -290,7 +502,8 @@ class CarlaPatchbayW(QGraphicsView): | |||
| pitem.reloadPrograms() | |||
| def reloadAll(self, pluginId): | |||
| @pyqtSlot(int) | |||
| def slot_handleReloadAllCallback(self, pluginId): | |||
| if pluginId >= self.fPluginCount: | |||
| return | |||
| @@ -302,7 +515,8 @@ class CarlaPatchbayW(QGraphicsView): | |||
| # ----------------------------------------------------------------- | |||
| def patchbayClientAdded(self, clientId, clientIcon, clientName): | |||
| @pyqtSlot(int, int, str) | |||
| def slot_handlePatchbayClientAddedCallback(self, clientId, clientIcon, clientName): | |||
| pcSplit = patchcanvas.SPLIT_UNDEF | |||
| pcIcon = patchcanvas.ICON_APPLICATION | |||
| @@ -319,16 +533,19 @@ class CarlaPatchbayW(QGraphicsView): | |||
| patchcanvas.addGroup(clientId, clientName, pcSplit, pcIcon) | |||
| #QTimer.singleShot(0, self.ui.miniCanvasPreview, SLOT("update()")) | |||
| def patchbayClientRemoved(self, clientId, clientName): | |||
| @pyqtSlot(int, str) | |||
| def slot_handlePatchbayClientRemovedCallback(self, clientId, clientName): | |||
| #if not self.fEngineStarted: return | |||
| patchcanvas.removeGroup(clientId) | |||
| #QTimer.singleShot(0, self.ui.miniCanvasPreview, SLOT("update()")) | |||
| def patchbayClientRenamed(self, clientId, newClientName): | |||
| @pyqtSlot(int, str) | |||
| def slot_handlePatchbayClientRenamedCallback(self, clientId, newClientName): | |||
| patchcanvas.renameGroup(clientId, newClientName) | |||
| #QTimer.singleShot(0, self.ui.miniCanvasPreview, SLOT("update()")) | |||
| def patchbayPortAdded(self, clientId, portId, portFlags, portName): | |||
| @pyqtSlot(int, int, int, str) | |||
| def slot_handlePatchbayPortAddedCallback(self, clientId, portId, portFlags, portName): | |||
| if (portFlags & PATCHBAY_PORT_IS_INPUT): | |||
| portMode = patchcanvas.PORT_MODE_INPUT | |||
| elif (portFlags & PATCHBAY_PORT_IS_OUTPUT): | |||
| @@ -346,25 +563,30 @@ class CarlaPatchbayW(QGraphicsView): | |||
| patchcanvas.addPort(clientId, portId, portName, portMode, portType) | |||
| #QTimer.singleShot(0, self.ui.miniCanvasPreview, SLOT("update()")) | |||
| def patchbayPortRemoved(self, groupId, portId, fullPortName): | |||
| @pyqtSlot(int, int, str) | |||
| def slot_handlePatchbayPortRemovedCallback(self, groupId, portId, fullPortName): | |||
| #if not self.fEngineStarted: return | |||
| patchcanvas.removePort(portId) | |||
| #QTimer.singleShot(0, self.ui.miniCanvasPreview, SLOT("update()")) | |||
| def patchbayPortRenamed(self, groupId, portId, newPortName): | |||
| @pyqtSlot(int, int, str) | |||
| def slot_handlePatchbayPortRenamedCallback(self, groupId, portId, newPortName): | |||
| patchcanvas.renamePort(portId, newPortName) | |||
| #QTimer.singleShot(0, self.ui.miniCanvasPreview, SLOT("update()")) | |||
| def patchbayConnectionAdded(self, connectionId, portOutId, portInId): | |||
| @pyqtSlot(int, int, int) | |||
| def slot_handlePatchbayConnectionAddedCallback(self, connectionId, portOutId, portInId): | |||
| patchcanvas.connectPorts(connectionId, portOutId, portInId) | |||
| #QTimer.singleShot(0, self.ui.miniCanvasPreview, SLOT("update()")) | |||
| def patchbayConnectionRemoved(self, connectionId): | |||
| @pyqtSlot(int) | |||
| def slot_handlePatchbayConnectionRemovedCallback(self, connectionId): | |||
| #if not self.fEngineStarted: return | |||
| patchcanvas.disconnectPorts(connectionId) | |||
| #QTimer.singleShot(0, self.ui.miniCanvasPreview, SLOT("update()")) | |||
| def patchbayIconChanged(self, clientId, clientIcon): | |||
| @pyqtSlot(int, int) | |||
| def slot_handlePatchbayIconChangedCallback(self, clientId, clientIcon): | |||
| pcIcon = patchcanvas.ICON_APPLICATION | |||
| if clientIcon == PATCHBAY_ICON_HARDWARE: | |||
| @@ -380,20 +602,6 @@ class CarlaPatchbayW(QGraphicsView): | |||
| # ----------------------------------------------------------------- | |||
| def idleFast(self): | |||
| pass | |||
| def idleSlow(self): | |||
| for i in range(self.fPluginCount): | |||
| pitem = self.fPluginList[i] | |||
| if pitem is None: | |||
| break | |||
| pitem.idleSlow() | |||
| # ----------------------------------------------------------------- | |||
| @pyqtSlot() | |||
| def slot_canvasArrange(self): | |||
| patchcanvas.arrange() | |||
| @@ -403,7 +611,7 @@ class CarlaPatchbayW(QGraphicsView): | |||
| patchcanvas.clear() | |||
| if Carla.host.is_engine_running(): | |||
| Carla.host.patchbay_refresh() | |||
| QTimer.singleShot(1000 if self.fSavedSettings['Canvas/EyeCandy'] else 0, self.ui.miniCanvasPreview, SLOT("update()")) | |||
| #QTimer.singleShot(1000 if self.fSavedSettings['Canvas/EyeCandy'] else 0, self.ui.miniCanvasPreview, SLOT("update()")) | |||
| @pyqtSlot() | |||
| def slot_canvasZoomFit(self): | |||
| @@ -66,6 +66,7 @@ class CarlaRackW(QListWidget): | |||
| # ------------------------------------------------------------- | |||
| # Internal stuff | |||
| self.fParent = parent | |||
| self.fPluginCount = 0 | |||
| self.fPluginList = [] | |||
| @@ -92,21 +93,45 @@ class CarlaRackW(QListWidget): | |||
| } | |||
| """ % (col1, col2)) | |||
| # ------------------------------------------------------------- | |||
| # Connect actions to functions | |||
| if parent is None: | |||
| return | |||
| parent.ui.menu_Canvas.hide() | |||
| parent.ui.act_plugins_enable.triggered.connect(self.slot_pluginsEnable) | |||
| parent.ui.act_plugins_disable.triggered.connect(self.slot_pluginsDisable) | |||
| parent.ui.act_plugins_volume100.triggered.connect(self.slot_pluginsVolume100) | |||
| parent.ui.act_plugins_mute.triggered.connect(self.slot_pluginsMute) | |||
| parent.ui.act_plugins_wet100.triggered.connect(self.slot_pluginsWet100) | |||
| parent.ui.act_plugins_bypass.triggered.connect(self.slot_pluginsBypass) | |||
| parent.ui.act_plugins_center.triggered.connect(self.slot_pluginsCenter) | |||
| parent.ui.act_plugins_panic.triggered.connect(self.slot_pluginsDisable) | |||
| parent.ui.act_settings_configure.triggered.connect(self.slot_configureCarla) | |||
| parent.ParameterValueChangedCallback.connect(self.slot_handleParameterValueChangedCallback) | |||
| parent.ParameterDefaultChangedCallback.connect(self.slot_handleParameterDefaultChangedCallback) | |||
| parent.ParameterMidiChannelChangedCallback.connect(self.slot_handleParameterMidiChannelChangedCallback) | |||
| parent.ParameterMidiCcChangedCallback.connect(self.slot_handleParameterMidiCcChangedCallback) | |||
| parent.ProgramChangedCallback.connect(self.slot_handleProgramChangedCallback) | |||
| parent.MidiProgramChangedCallback.connect(self.slot_handleMidiProgramChangedCallback) | |||
| parent.NoteOnCallback.connect(self.slot_handleNoteOnCallback) | |||
| parent.NoteOffCallback.connect(self.slot_handleNoteOffCallback) | |||
| parent.ShowGuiCallback.connect(self.slot_handleShowGuiCallback) | |||
| parent.UpdateCallback.connect(self.slot_handleUpdateCallback) | |||
| parent.ReloadInfoCallback.connect(self.slot_handleReloadInfoCallback) | |||
| parent.ReloadParametersCallback.connect(self.slot_handleReloadParametersCallback) | |||
| parent.ReloadProgramsCallback.connect(self.slot_handleReloadProgramsCallback) | |||
| parent.ReloadAllCallback.connect(self.slot_handleReloadAllCallback) | |||
| # ----------------------------------------------------------------- | |||
| def getPluginCount(self): | |||
| return self.fPluginCount | |||
| def getPlugin(self, pluginId): | |||
| if pluginId >= self.fPluginCount: | |||
| return None | |||
| pitem = self.fPluginList[pluginId] | |||
| if pitem is None: | |||
| return None | |||
| return pitem | |||
| # ----------------------------------------------------------------- | |||
| def addPlugin(self, pluginId, isProjectLoading): | |||
| @@ -146,8 +171,8 @@ class CarlaRackW(QListWidget): | |||
| if pitem is None: | |||
| return | |||
| pitem.fWidget.ui.label_name.setText(name) | |||
| pitem.fWidget.ui.edit_dialog.setName(name) | |||
| pitem.fWidget.ui.label_name.setText(newName) | |||
| pitem.fWidget.ui.edit_dialog.setName(newName) | |||
| def removeAllPlugins(self): | |||
| while (self.takeItem(0)): | |||
| @@ -167,7 +192,147 @@ class CarlaRackW(QListWidget): | |||
| # ----------------------------------------------------------------- | |||
| def setParameterValue(self, pluginId, index, value): | |||
| def engineStarted(self): | |||
| pass | |||
| def engineStopped(self): | |||
| pass | |||
| # ----------------------------------------------------------------- | |||
| def idleFast(self): | |||
| for i in range(self.fPluginCount): | |||
| pitem = self.fPluginList[i] | |||
| if pitem is None: | |||
| break | |||
| pitem.fWidget.idleFast() | |||
| def idleSlow(self): | |||
| for i in range(self.fPluginCount): | |||
| pitem = self.fPluginList[i] | |||
| if pitem is None: | |||
| break | |||
| pitem.fWidget.idleSlow() | |||
| # ----------------------------------------------------------------- | |||
| @pyqtSlot() | |||
| def slot_pluginsEnable(self): | |||
| if not Carla.host.is_engine_running(): | |||
| return | |||
| for i in range(self.fPluginCount): | |||
| pitem = self.fPluginList[i] | |||
| if pitem is None: | |||
| break | |||
| pitem.fWidget.setActive(True, True, True) | |||
| @pyqtSlot() | |||
| def slot_pluginsDisable(self): | |||
| if not Carla.host.is_engine_running(): | |||
| return | |||
| for i in range(self.fPluginCount): | |||
| pitem = self.fPluginList[i] | |||
| if pitem is None: | |||
| break | |||
| pitem.fWidget.setActive(False, True, True) | |||
| @pyqtSlot() | |||
| def slot_pluginsVolume100(self): | |||
| if not Carla.host.is_engine_running(): | |||
| return | |||
| for i in range(self.fPluginCount): | |||
| pitem = self.fPluginList[i] | |||
| if pitem is None: | |||
| break | |||
| if pitem.fWidget.fPluginInfo['hints'] & PLUGIN_CAN_VOLUME: | |||
| pitem.fWidget.ui.edit_dialog.setParameterValue(PARAMETER_VOLUME, 1.0) | |||
| Carla.host.set_volume(i, 1.0) | |||
| @pyqtSlot() | |||
| def slot_pluginsMute(self): | |||
| if not Carla.host.is_engine_running(): | |||
| return | |||
| for i in range(self.fPluginCount): | |||
| pitem = self.fPluginList[i] | |||
| if pitem is None: | |||
| break | |||
| if pitem.fWidget.fPluginInfo['hints'] & PLUGIN_CAN_VOLUME: | |||
| pitem.fWidget.ui.edit_dialog.setParameterValue(PARAMETER_VOLUME, 0.0) | |||
| Carla.host.set_volume(i, 0.0) | |||
| @pyqtSlot() | |||
| def slot_pluginsWet100(self): | |||
| if not Carla.host.is_engine_running(): | |||
| return | |||
| for i in range(self.fPluginCount): | |||
| pitem = self.fPluginList[i] | |||
| if pitem is None: | |||
| break | |||
| if pitem.fWidget.fPluginInfo['hints'] & PLUGIN_CAN_DRYWET: | |||
| pitem.fWidget.ui.edit_dialog.setParameterValue(PARAMETER_DRYWET, 1.0) | |||
| Carla.host.set_drywet(i, 1.0) | |||
| @pyqtSlot() | |||
| def slot_pluginsBypass(self): | |||
| if not Carla.host.is_engine_running(): | |||
| return | |||
| for i in range(self.fPluginCount): | |||
| pitem = self.fPluginList[i] | |||
| if pitem is None: | |||
| break | |||
| if pitem.fWidget.fPluginInfo['hints'] & PLUGIN_CAN_DRYWET: | |||
| pitem.fWidget.ui.edit_dialog.setParameterValue(PARAMETER_DRYWET, 0.0) | |||
| Carla.host.set_drywet(i, 0.0) | |||
| @pyqtSlot() | |||
| def slot_pluginsCenter(self): | |||
| if not Carla.host.is_engine_running(): | |||
| return | |||
| for i in range(self.fPluginCount): | |||
| pitem = self.fPluginList[i] | |||
| if pitem is None: | |||
| break | |||
| if pitem.fWidget.fPluginInfo['hints'] & PLUGIN_CAN_BALANCE: | |||
| pitem.fWidget.ui.edit_dialog.setParameterValue(PARAMETER_BALANCE_LEFT, -1.0) | |||
| pitem.fWidget.ui.edit_dialog.setParameterValue(PARAMETER_BALANCE_RIGHT, 1.0) | |||
| Carla.host.set_balance_left(i, -1.0) | |||
| Carla.host.set_balance_right(i, 1.0) | |||
| if pitem.fWidget.fPluginInfo['hints'] & PLUGIN_CAN_PANNING: | |||
| pitem.fWidget.ui.edit_dialog.setParameterValue(PARAMETER_PANNING, 1.0) | |||
| Carla.host.set_panning(i, 1.0) | |||
| # ----------------------------------------------------------------- | |||
| @pyqtSlot() | |||
| def slot_configureCarla(self): | |||
| if self.fParent is None or not self.fParent.openSettings(False, False): | |||
| return | |||
| #self.loadSettings(False) | |||
| # ----------------------------------------------------------------- | |||
| @pyqtSlot(int, int, float) | |||
| def slot_handleParameterValueChangedCallback(self, pluginId, index, value): | |||
| if pluginId >= self.fPluginCount: | |||
| return | |||
| @@ -177,7 +342,8 @@ class CarlaRackW(QListWidget): | |||
| pitem.fWidget.setParameterValue(index, value) | |||
| def setParameterDefault(self, pluginId, index, value): | |||
| @pyqtSlot(int, int, float) | |||
| def slot_handleParameterDefaultChangedCallback(self, pluginId, index, value): | |||
| if pluginId >= self.fPluginCount: | |||
| return | |||
| @@ -187,7 +353,8 @@ class CarlaRackW(QListWidget): | |||
| pitem.fWidget.setParameterDefault(index, value) | |||
| def setParameterMidiChannel(self, pluginId, index, channel): | |||
| @pyqtSlot(int, int, int) | |||
| def slot_handleParameterMidiChannelChangedCallback(self, pluginId, index, channel): | |||
| if pluginId >= self.fPluginCount: | |||
| return | |||
| @@ -197,7 +364,8 @@ class CarlaRackW(QListWidget): | |||
| pitem.fWidget.setParameterMidiChannel(index, channel) | |||
| def setParameterMidiCC(self, pluginId, index, cc): | |||
| @pyqtSlot(int, int, int) | |||
| def slot_handleParameterMidiCcChangedCallback(self, pluginId, index, cc): | |||
| if pluginId >= self.fPluginCount: | |||
| return | |||
| @@ -209,7 +377,8 @@ class CarlaRackW(QListWidget): | |||
| # ----------------------------------------------------------------- | |||
| def setProgram(self, pluginId, index): | |||
| @pyqtSlot(int, int) | |||
| def slot_handleProgramChangedCallback(self, pluginId, index): | |||
| if pluginId >= self.fPluginCount: | |||
| return | |||
| @@ -219,7 +388,8 @@ class CarlaRackW(QListWidget): | |||
| pitem.fWidget.setProgram(index) | |||
| def setMidiProgram(self, pluginId, index): | |||
| @pyqtSlot(int, int) | |||
| def slot_handleMidiProgramChangedCallback(self, pluginId, index): | |||
| if pluginId >= self.fPluginCount: | |||
| return | |||
| @@ -231,7 +401,8 @@ class CarlaRackW(QListWidget): | |||
| # ----------------------------------------------------------------- | |||
| def noteOn(self, pluginId, channel, note, velocity): | |||
| @pyqtSlot(int, int, int, int) | |||
| def slot_handleNoteOnCallback(self, pluginId, channel, note, velo): | |||
| if pluginId >= self.fPluginCount: | |||
| return | |||
| @@ -241,7 +412,8 @@ class CarlaRackW(QListWidget): | |||
| pitem.fWidget.sendNoteOn(channel, note) | |||
| def noteOff(self, pluginId, channel, note): | |||
| @pyqtSlot(int, int, int) | |||
| def slot_handleNoteOffCallback(self, pluginId, channel, note): | |||
| if pluginId >= self.fPluginCount: | |||
| return | |||
| @@ -253,7 +425,8 @@ class CarlaRackW(QListWidget): | |||
| # ----------------------------------------------------------------- | |||
| def setGuiState(self, pluginId, state): | |||
| @pyqtSlot(int, int) | |||
| def slot_handleShowGuiCallback(self, pluginId, state): | |||
| if pluginId >= self.fPluginCount: | |||
| return | |||
| @@ -273,7 +446,8 @@ class CarlaRackW(QListWidget): | |||
| # ----------------------------------------------------------------- | |||
| def updateInfo(self, pluginId): | |||
| @pyqtSlot(int) | |||
| def slot_handleUpdateCallback(self, pluginId): | |||
| if pluginId >= self.fPluginCount: | |||
| return | |||
| @@ -283,7 +457,8 @@ class CarlaRackW(QListWidget): | |||
| pitem.ui.edit_dialog.updateInfo() | |||
| def reloadInfo(self, pluginId): | |||
| @pyqtSlot(int) | |||
| def slot_handleReloadInfoCallback(self, pluginId): | |||
| if pluginId >= self.fPluginCount: | |||
| return | |||
| @@ -293,7 +468,8 @@ class CarlaRackW(QListWidget): | |||
| pitem.ui.edit_dialog.reloadInfo() | |||
| def reloadParameters(self, pluginId): | |||
| @pyqtSlot(int) | |||
| def slot_handleReloadParametersCallback(self, pluginId): | |||
| if pluginId >= self.fPluginCount: | |||
| return | |||
| @@ -303,7 +479,8 @@ class CarlaRackW(QListWidget): | |||
| pitem.ui.edit_dialog.reloadParameters() | |||
| def reloadPrograms(self, pluginId): | |||
| @pyqtSlot(int) | |||
| def slot_handleReloadProgramsCallback(self, pluginId): | |||
| if pluginId >= self.fPluginCount: | |||
| return | |||
| @@ -313,7 +490,8 @@ class CarlaRackW(QListWidget): | |||
| pitem.ui.edit_dialog.reloadPrograms() | |||
| def reloadAll(self, pluginId): | |||
| @pyqtSlot(int) | |||
| def slot_handleReloadAllCallback(self, pluginId): | |||
| if pluginId >= self.fPluginCount: | |||
| return | |||
| @@ -323,55 +501,6 @@ class CarlaRackW(QListWidget): | |||
| pitem.ui.edit_dialog.reloadAll() | |||
| # ----------------------------------------------------------------- | |||
| def patchbayClientAdded(self, clientId, clientIcon, clientName): | |||
| pass | |||
| def patchbayClientRemoved(self, clientId, clientName): | |||
| pass | |||
| def patchbayClientRenamed(self, clientId, newClientName): | |||
| pass | |||
| def patchbayPortAdded(self, clientId, portId, portFlags, portName): | |||
| pass | |||
| def patchbayPortRemoved(self, groupId, portId, fullPortName): | |||
| pass | |||
| def patchbayPortRenamed(self, groupId, portId, newPortName): | |||
| pass | |||
| def patchbayConnectionAdded(self, connectionId, portOutId, portInId): | |||
| pass | |||
| def patchbayConnectionRemoved(self, connectionId): | |||
| pass | |||
| def patchbayIconChanged(self, clientId, clientIcon): | |||
| pass | |||
| # ----------------------------------------------------------------- | |||
| def idleFast(self): | |||
| for i in range(self.fPluginCount): | |||
| pitem = self.fPluginList[i] | |||
| if pitem is None: | |||
| break | |||
| pitem.fWidget.idleFast() | |||
| def idleSlow(self): | |||
| for i in range(self.fPluginCount): | |||
| pitem = self.fPluginList[i] | |||
| if pitem is None: | |||
| break | |||
| pitem.fWidget.idleSlow() | |||
| # ------------------------------------------------------------------------------------------------------------ | |||
| # TESTING | |||
| @@ -183,7 +183,7 @@ class CarlaSettingsW(QDialog): | |||
| # so add +2 pos padding if driverName != "JACK". | |||
| PROCESS_MODE_NON_JACK_PADDING = 2 | |||
| def __init__(self, parent, hasCanvas, hasGL): | |||
| def __init__(self, parent, hasCanvas, hasCanvasGL): | |||
| QDialog.__init__(self, parent) | |||
| self.ui = ui_carla_settings.Ui_CarlaSettingsW() | |||
| self.ui.setupUi(self) | |||
| @@ -205,7 +205,7 @@ class CarlaSettingsW(QDialog): | |||
| if not hasCanvas: | |||
| # TODO - hide canvas section | |||
| if not hasGL: | |||
| if not hasCanvasGL: | |||
| self.ui.cb_canvas_use_opengl.setChecked(False) | |||
| self.ui.cb_canvas_use_opengl.setEnabled(False) | |||
| @@ -416,7 +416,7 @@ def findTool(toolDir, toolName): | |||
| # ------------------------------------------------------------------------------------------------------------ | |||
| # Init host | |||
| def initHost(failError = True): | |||
| def initHost(appName, libPrefix = None, failError = True): | |||
| # ------------------------------------------------------------- | |||
| # Search for Carla library | |||
| @@ -434,26 +434,28 @@ def initHost(failError = True): | |||
| else: | |||
| libname += ".so" | |||
| libfilename = "" | |||
| if libPrefix is not None: | |||
| libfilename = os.path.join(libPrefix, "lib", "carla", libname) | |||
| if os.path.exists(os.path.join(CWD, "backend", libname)): | |||
| libfilename = os.path.join(CWD, "backend", libname) | |||
| #else: | |||
| #CARLA_LIB_PATH = os.getenv("CARLA_LIB_PATH") | |||
| #if CARLA_LIB_PATH and os.path.exists(CARLA_LIB_PATH): | |||
| #CARLA_LIB_PATH = os.path.join(CARLA_LIB_PATH, "..") | |||
| #elif WINDOWS: | |||
| #CARLA_LIB_PATH = (os.path.join(PROGRAMFILES, "Carla"),) | |||
| #elif MACOS: | |||
| #CARLA_LIB_PATH = ("/opt/local/lib", "/usr/local/lib/", "/usr/lib") | |||
| else: | |||
| if os.path.exists(os.path.join(CWD, "backend", libname)): | |||
| libfilename = os.path.join(CWD, "backend", libname) | |||
| #else: | |||
| #CARLA_LIB_PATH = ("/usr/local/lib/", "/usr/lib") | |||
| #for path in CARLA_LIB_PATH: | |||
| #if os.path.exists(os.path.join(path, "carla", libname)): | |||
| #libfilename = os.path.join(path, "carla", libname) | |||
| #break | |||
| #CARLA_LIB_PATH = os.getenv("CARLA_LIB_PATH") | |||
| #if CARLA_LIB_PATH and os.path.exists(CARLA_LIB_PATH): | |||
| #CARLA_LIB_PATH = os.path.join(CARLA_LIB_PATH, "..") | |||
| #elif WINDOWS: | |||
| #CARLA_LIB_PATH = (os.path.join(PROGRAMFILES, "Carla"),) | |||
| #elif MACOS: | |||
| #CARLA_LIB_PATH = ("/opt/local/lib", "/usr/local/lib/", "/usr/lib") | |||
| #else: | |||
| #CARLA_LIB_PATH = ("/usr/local/lib/", "/usr/lib") | |||
| #for path in CARLA_LIB_PATH: | |||
| #if os.path.exists(os.path.join(path, "carla", libname)): | |||
| #libfilename = os.path.join(path, "carla", libname) | |||
| #break | |||
| # ------------------------------------------------------------- | |||
| # Search for Carla tools | |||
| @@ -537,6 +539,16 @@ def initHost(failError = True): | |||
| Carla.host = Host(libfilename) | |||
| # ------------------------------------------------------------- | |||
| # Set internal stuff | |||
| Carla.host.set_engine_option(OPTION_PROCESS_NAME, 0, os.path.basename(appName)) | |||
| NSM_URL = os.getenv("NSM_URL") | |||
| if NSM_URL: | |||
| Carla.host.nsm_announce(NSM_URL, appName, os.getpid()) | |||
| # ------------------------------------------------------------- | |||
| # Set resource path | |||