diff options
author | Robert Jonsson <spamatica@gmail.com> | 2010-10-13 19:34:22 +0000 |
---|---|---|
committer | Robert Jonsson <spamatica@gmail.com> | 2010-10-13 19:34:22 +0000 |
commit | 8a2c2824a59d7644e13bc52c9a0ecbd641f21f95 (patch) | |
tree | 064ad3f2bf8daab0ad27b128abd86a9bbdb1e496 /muse2/muse/remote | |
parent | a27706d9629e8b592cca4659f865b70adef24e6d (diff) |
new branch muse2, first checkin
Diffstat (limited to 'muse2/muse/remote')
-rw-r--r-- | muse2/muse/remote/Makefile.am | 15 | ||||
-rw-r--r-- | muse2/muse/remote/Makefile.in | 590 | ||||
-rw-r--r-- | muse2/muse/remote/pyapi.cpp | 1142 | ||||
-rw-r--r-- | muse2/muse/remote/pyapi.h | 40 |
4 files changed, 1787 insertions, 0 deletions
diff --git a/muse2/muse/remote/Makefile.am b/muse2/muse/remote/Makefile.am new file mode 100644 index 00000000..a1335682 --- /dev/null +++ b/muse2/muse/remote/Makefile.am @@ -0,0 +1,15 @@ +include $(top_srcdir)/common.am + +noinst_LIBRARIES = libremote.a + +if PCH +AM_CXXFLAGS += -include $(top_srcdir)/all.h +else +AM_CXXFLAGS += -DINSTPREFIX=\"$(prefix)\" +endif + +AM_CPPFLAGS += -I$(PYTHON_INCLUDES) -DENABLE_PYTHON + +dist_libremote_a_SOURCES = \ + pyapi.cpp pyapi.h + diff --git a/muse2/muse/remote/Makefile.in b/muse2/muse/remote/Makefile.in new file mode 100644 index 00000000..ecae5271 --- /dev/null +++ b/muse2/muse/remote/Makefile.in @@ -0,0 +1,590 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(top_srcdir)/common.am +@PCH_TRUE@am__append_1 = -include $(top_srcdir)/all.h +@PCH_FALSE@am__append_2 = -DINSTPREFIX=\"$(prefix)\" +subdir = muse/remote +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/aclocal-include.m4 \ + $(top_srcdir)/m4/alsa.m4 $(top_srcdir)/m4/docbook.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LIBRARIES = $(noinst_LIBRARIES) +ARFLAGS = cru +libremote_a_AR = $(AR) $(ARFLAGS) +libremote_a_LIBADD = +dist_libremote_a_OBJECTS = pyapi.$(OBJEXT) +libremote_a_OBJECTS = $(dist_libremote_a_OBJECTS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(dist_libremote_a_SOURCES) +DIST_SOURCES = $(dist_libremote_a_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALSA_CFLAGS = @ALSA_CFLAGS@ +ALSA_LIBS = @ALSA_LIBS@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DOCBOOKSTYLE = @DOCBOOKSTYLE@ +DOCBOOKTARGETS = @DOCBOOKTARGETS@ +DOT = @DOT@ +DOTPATH = @DOTPATH@ +DOXYGEN = @DOXYGEN@ +DOXYGEN_TREEVIEW = @DOXYGEN_TREEVIEW@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +FLUIDSYNTHDIRS = @FLUIDSYNTHDIRS@ +FST_CFLAGS = @FST_CFLAGS@ +FST_LIBS = @FST_LIBS@ +Fluidsynth_CFLAGS = @Fluidsynth_CFLAGS@ +Fluidsynth_LIBS = @Fluidsynth_LIBS@ +GIVERTCAP = @GIVERTCAP@ +GREP = @GREP@ +HAVEDOT = @HAVEDOT@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JACK_CFLAGS = @JACK_CFLAGS@ +JACK_LIBS = @JACK_LIBS@ +JADE = @JADE@ +LASH_CFLAGS = @LASH_CFLAGS@ +LASH_LIBS = @LASH_LIBS@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LO_CFLAGS = @LO_CFLAGS@ +LO_LIBS = @LO_LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MUSECXXFLAGS = @MUSECXXFLAGS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NSGMLS = @NSGMLS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PCH = @PCH@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_INCLUDES = @PYTHON_INCLUDES@ +PYTHON_LIB = @PYTHON_LIB@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +QTDIR_BIN = @QTDIR_BIN@ +QTDIR_INC = @QTDIR_INC@ +QT_LIBS = @QT_LIBS@ +RANLIB = @RANLIB@ +SAMPLERATE_CFLAGS = @SAMPLERATE_CFLAGS@ +SAMPLERATE_LIBS = @SAMPLERATE_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SNDFILE_CFLAGS = @SNDFILE_CFLAGS@ +SNDFILE_LIBS = @SNDFILE_LIBS@ +STRIP = @STRIP@ +SUIDBUILD = @SUIDBUILD@ +SUIDINSTALL = @SUIDINSTALL@ +USE_SSE = @USE_SSE@ +UUID_CFLAGS = @UUID_CFLAGS@ +UUID_LIBS = @UUID_LIBS@ +VERSION = @VERSION@ +XMKMF = @XMKMF@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +have_docbook = @have_docbook@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +synth_fluid = @synth_fluid@ +synth_fluidsynth = @synth_fluidsynth@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AM_CXXFLAGS = $(MUSECXXFLAGS) -I.. -I$(top_srcdir)/synti \ + -I$(top_srcdir)/muse/widgets -DQT_SHARED -DQT_THREAD_SUPPORT \ + -DQT_PLUGIN $(QTDIR_INC) -DQT3_SUPPORT $(am__append_1) \ + $(am__append_2) +AM_CPPFLAGS = -I$(PYTHON_INCLUDES) -DENABLE_PYTHON +MOC = $(QTDIR_BIN)/moc +#UIC = $(QTDIR_BIN)/uic3 +UIC = /usr/bin/uic3 +UIFILES = $(wildcard *.ui) +MOCFILES = $(shell for h in $(filter %.h,$(SOURCES)); do \ + if grep -q Q_OBJECT $$h; then \ + echo $$h | sed "s/\(.*\)\.h/moc_\1.cpp/"; \ + fi; \ + done) + +BUILT_SOURCES = $(MOCFILES) $(UIFILES:%.ui=%.h) +MOSTLYCLEANFILES = $(MOCFILES) $(UIFILES:%.ui=%.h) +SUFFIXES = .ui .h.gch +noinst_LIBRARIES = libremote.a +dist_libremote_a_SOURCES = \ + pyapi.cpp pyapi.h + +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .ui .h.gch .cpp .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/common.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu muse/remote/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu muse/remote/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) +libremote.a: $(libremote_a_OBJECTS) $(libremote_a_DEPENDENCIES) + -rm -f libremote.a + $(libremote_a_AR) libremote.a $(libremote_a_OBJECTS) $(libremote_a_LIBADD) + $(RANLIB) libremote.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pyapi.Po@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-am +all-am: Makefile $(LIBRARIES) +installdirs: +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: all check install install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am + + +de: + @for base in $(MOCFILES); do echo -e "\t$${base}.cpp $${base}.h \\"; done + +nde: + @for base in $(MOCFILES); do echo -e "\tmoc_$${base}.cpp \\"; done + +.ui.o: %.h + $(UIC) -L $(top_srcdir)/muse/widgets -o $*.cpp -impl $*.h $*.ui + $(MOC) $*.h >> $*.cpp + $(CXXCOMPILE) -c $*.cpp -o $*.o + $(RM) $*.cpp moc_$*.cpp moc_$*.o + +.ui.lo: %.h + $(UIC) -L $(top_srcdir)/muse/widgets -o $*.cpp -impl $*.h $*.ui + $(MOC) $*.h >> $*.cpp + $(LTCXXCOMPILE) -c $*.cpp -o $*.lo + $(RM) $*.cpp moc_$*.cpp moc_$*.lo moc_$*.o + +moc_%.cpp: %.h + $(MOC) $< -o $@ + +%.h: %.ui + $(UIC) -o $@ $< +# $(UIC) -L $(top_srcdir)/muse/widgets -o $@ $< + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/muse2/muse/remote/pyapi.cpp b/muse2/muse/remote/pyapi.cpp new file mode 100644 index 00000000..e71b8a18 --- /dev/null +++ b/muse2/muse/remote/pyapi.cpp @@ -0,0 +1,1142 @@ +//========================================================= +// MusE +// Linux Music Editor +// (C) Copyright 2009 Mathias Gyllengahm (lunar_shuttle@users.sf.net) +//========================================================= +#include <Python.h> +#include <iostream> +#include <fstream> +#include <string> +#include <pthread.h> + +#include <qobject.h> +#include <qapplication.h> +#include <qevent.h> + +#include "pyapi.h" +#include "song.h" +#include "tempo.h" +#include "track.h" +#include "audio.h" +#include "gconfig.h" +#include "midictrl.h" +#include "midiport.h" +#include "plugin.h" +#include "midi.h" +#include "app.h" + +// Steals ref: PyList_SetItem, PyTuple_SetItem +using namespace std; + +static pthread_t pyapiThread; +//------------------------------------------------------------ +QPybridgeEvent::QPybridgeEvent(QPybridgeEvent::EventType _type, int _p1, int _p2) + :QEvent(QEvent::User), + type(_type), + p1(_p1), + p2(_p2) +{ +} +//------------------------------------------------------------ +// Get current position +//------------------------------------------------------------ +PyObject* getCPos(PyObject*, PyObject*) +{ + return Py_BuildValue("i", song->cpos()); +} +//------------------------------------------------------------ +// Get position of left locator +//------------------------------------------------------------ +PyObject* getLPos(PyObject*, PyObject*) +{ + return Py_BuildValue("i", song->lpos()); +} +//------------------------------------------------------------ +// Get position of right locator +//------------------------------------------------------------ +PyObject* getRPos(PyObject*, PyObject*) +{ + return Py_BuildValue("i", song->rpos()); +} +//------------------------------------------------------------ +// Start playing from current position +//------------------------------------------------------------ +PyObject* startPlay(PyObject*, PyObject*) +{ + //song->setPlay(true); + QPybridgeEvent* pyevent = new QPybridgeEvent(QPybridgeEvent::SONG_SETPLAY); + QApplication::postEvent(song, pyevent); + Py_INCREF(Py_None); + return Py_None; +} +//------------------------------------------------------------ +// Stop playing +//------------------------------------------------------------ +PyObject* stopPlay(PyObject*, PyObject*) +{ + //song->setStop(true); + QPybridgeEvent* pyevent = new QPybridgeEvent(QPybridgeEvent::SONG_SETSTOP); + QApplication::postEvent(song, pyevent); + Py_INCREF(Py_None); + return Py_None; +} +//------------------------------------------------------------ +// Rewind to start +//------------------------------------------------------------ +PyObject* rewindStart(PyObject*, PyObject*) +{ + //song->rewindStart(); + QPybridgeEvent* pyevent = new QPybridgeEvent(QPybridgeEvent::SONG_REWIND); + QApplication::postEvent(song, pyevent); + Py_INCREF(Py_None); + return Py_None; +} +//------------------------------------------------------------ +// Get tempo at specific position +//------------------------------------------------------------ +PyObject* getTempo(PyObject*, PyObject* args) +{ + int tick; + if (!PyArg_ParseTuple(args, "i", &tick)) { + return Py_BuildValue("i", 1000); + } + + int tempovalue = tempomap.tempo(tick); + return Py_BuildValue("i", tempovalue); +} +//------------------------------------------------------------ +// Get track names +//------------------------------------------------------------ +PyObject* getTrackNames(PyObject*, PyObject*) +{ + TrackList* tracks = song->tracks(); + PyObject* res = Py_BuildValue("[]"); + for (ciTrack t = tracks->begin(); t != tracks->end(); ++t) { + Track* track = *t; + PyObject* ptrackname = Py_BuildValue("s", track->name().latin1()); + PyList_Append(res, ptrackname); + Py_DECREF(ptrackname); + } + + return res; +} +//------------------------------------------------------------ +// Find part by serial nr +//------------------------------------------------------------ +Part* findPartBySerial(int sn) +{ + TrackList* tracks = song->tracks(); + for (ciTrack t = tracks->begin(); t != tracks->end(); ++t) { + Track* track = *t; + PartList* parts = track->parts(); + for (ciPart p = parts->begin(); p != parts->end(); p++) { + Part* part = p->second; + if (part->sn() == sn) + return part; + } + } + + return NULL; +} +//------------------------------------------------------------ +// Get parts from track +//------------------------------------------------------------ +PyObject* getParts(PyObject*, PyObject* args) +{ + TrackList* tracks = song->tracks(); + const char* trackname; + if (!PyArg_ParseTuple(args, "s", &trackname)) { + return NULL; + } + + PyObject* pyparts = Py_BuildValue("[]"); + for (ciTrack t = tracks->begin(); t != tracks->end(); ++t) { + Track* track = *t; + if (track->name() != trackname) + continue; + + PartList* parts = track->parts(); + for (ciPart p = parts->begin(); p != parts->end(); p++) { + Part* part = p->second; + + MidiPart* mpart = (MidiPart*) part; + PyObject* pypart = PyDict_New(); + int tick = mpart->tick(); + int lentick = mpart->lenTick(); + int serialnr = mpart->sn(); + PyObject* pstrtick = Py_BuildValue("s","tick"); + PyObject* pitick = Py_BuildValue("i", tick); + PyObject* pstrid = Py_BuildValue("s","id"); + PyObject* pstrserial = Py_BuildValue("i", serialnr); + PyObject* pstrlen = Py_BuildValue("s","len"); + PyObject* pstrtick2 = Py_BuildValue("i", lentick); + + PyDict_SetItem(pypart, pstrtick, pitick); + PyDict_SetItem(pypart, pstrid, pstrserial); + PyDict_SetItem(pypart, pstrlen, pstrtick2); + + Py_DECREF(pstrtick); + Py_DECREF(pitick); + Py_DECREF(pstrid); + Py_DECREF(pstrserial); + Py_DECREF(pstrlen); + Py_DECREF(pstrtick2); + + // Pack midi events into list before wrapping it all up + EventList* events = mpart->events(); + PyObject* pyevents = Py_BuildValue("[]"); + for (ciEvent e = events->begin(); e != events->end(); e++) { + PyObject* pyevent = PyDict_New(); // The event structure - a dictionary with keys 'type','tick','data' + + const Event& event = e->second; + unsigned tick = e->first; + PyObject* eventdata = Py_BuildValue("[i,i,i]", event.dataA(), event.dataB(), event.dataC()); + PyObject* pstrdata = Py_BuildValue("s", "data"); + pstrtick = Py_BuildValue("s", "tick"); + PyObject* pitickval = Py_BuildValue("i", tick); + PyDict_SetItem(pyevent, pstrdata, eventdata); + PyDict_SetItem(pyevent, pstrtick, pitickval); + Py_DECREF(eventdata); + Py_DECREF(pstrdata); + Py_DECREF(pstrtick); + Py_DECREF(pitickval); + + switch(event.type()) { + case Note: { + PyObject* pstrtype = Py_BuildValue("s", "type"); + PyObject* pstrnote = Py_BuildValue("s", "note"); + PyObject* pstrlen = Py_BuildValue("s", "len"); + PyObject* pilentick = Py_BuildValue("i", event.lenTick()); + PyDict_SetItem(pyevent, pstrtype, pstrnote); + PyDict_SetItem(pyevent, pstrlen, pilentick); + Py_DECREF(pstrtype); + Py_DECREF(pstrnote); + Py_DECREF(pstrlen); + Py_DECREF(pilentick); + break; + } + case Controller: { + PyObject* pstrtype = Py_BuildValue("s", "type"); + PyObject* pstrctrl = Py_BuildValue("s", "ctrl"); + PyDict_SetItem(pyevent, pstrtype, pstrctrl); + Py_DECREF(pstrtype); + Py_DECREF(pstrctrl); + break; + } + default: + printf("Event type not supported yet: %d\n", event.type()); + break; + } + PyList_Append(pyevents, pyevent); + Py_DECREF(pyevent); + } + Py_DECREF(pyevents); + // Add the event list to the pypart dictionary + PyObject* pystrevents = Py_BuildValue("s", "events"); + PyDict_SetItem(pypart, pystrevents, pyevents); + Py_DECREF(pystrevents); + PyList_Append(pyparts, pypart); + Py_DECREF(pypart); + } + + return pyparts; + } + + return NULL; +} + +//------------------------------------------------------------ +// parsePythonPart +// get part id/serialno from python part structure +//------------------------------------------------------------ +int getPythonPartId(PyObject* part) +{ + PyObject* pyid = PyDict_GetItemString(part, "id"); + int id = PyInt_AsLong(pyid); + return id; +} + +//------------------------------------------------------------ +// addPyPartEventsToMusePart +// parse events from python part structure into muse part +//------------------------------------------------------------ +bool addPyPartEventsToMusePart(MidiPart* npart, PyObject* part) +{ + PyObject* events; + + if (PyDict_Check(part) == false) { + printf("Not a dict!\n"); + return false; + } + PyObject* pstrevents = Py_BuildValue("s","events"); + if (PyDict_Contains(part, pstrevents) == false) { + Py_DECREF(pstrevents); + printf("No events in part data...\n"); + return false; + } + Py_DECREF(pstrevents); + + events = PyDict_GetItemString(part, "events"); + + if (PyList_Check(events) == false) { + printf("Events not a list!\n"); + return false; + } + + // + // Go through event list, create MusE events of them and add to new part + // + Py_ssize_t len = PyList_Size(events); + for (Py_ssize_t i=0; i<len; i++) { + PyObject* pevent = PyList_GetItem(events, i); + if (PyDict_Check(pevent) == false) { + printf("Event is not a dictionary!\n"); + return false; + } + PyObject* p_etick = PyDict_GetItemString(pevent, "tick"); + PyObject* p_type = PyDict_GetItemString(pevent, "type"); + PyObject* p_len = PyDict_GetItemString(pevent, "len"); + PyObject* p_data = PyDict_GetItemString(pevent, "data"); // list + + int etick = PyInt_AsLong(p_etick); + int elen = PyInt_AsLong(p_len); + string type = string(PyString_AsString(p_type)); + int data[3]; + + // Traverse data list: + for (int j=0; j<3; j++) { + PyObject* plItem = PyList_GetItem(p_data, j); + data[j] = PyInt_AsLong(plItem); + } + if (type == "note" || type == "ctrl") { + Event event(Note); + event.setA(data[0]); + event.setB(data[1]); + event.setC(data[2]); + event.setTick(etick); + event.setLenTick(elen); + npart->events()->add(event); + } + else + printf("Unhandled event type from python: %s\n", type.c_str()); + } + + return true; +} +//------------------------------------------------------------ +// Create a new part at a particular tick and track +//------------------------------------------------------------ +PyObject* createPart(PyObject*, PyObject* args) +{ + const char* trackname; + unsigned tick, tickLen; + PyObject* part; + + if (!PyArg_ParseTuple(args, "siiO", &trackname, &tick, &tickLen, &part)) { + return NULL; + } + + QString qtrackname(trackname); + MidiTrack* track = (MidiTrack*) song->findTrack(trackname); + if (track == NULL) + return NULL; + + MidiPart* npart = new MidiPart(track); + npart->setTick(tick); + npart->setLenTick(tickLen); + addPyPartEventsToMusePart(npart, part); + + song->addPart(npart); + QPybridgeEvent* pyevent = new QPybridgeEvent(QPybridgeEvent::SONG_UPDATE, SC_TRACK_MODIFIED); + QApplication::postEvent(song, pyevent); + + Py_INCREF(Py_None); + return Py_None; +} + +//------------------------------------------------------------ +// Modify a particular part: +// args: new part data, old part data is used from the part with the same id as the one sent here +// TODO: Lots and lots of refcount stuff +//------------------------------------------------------------ +PyObject* modifyPart(PyObject*, PyObject* part) +{ + int id = getPythonPartId(part); + + Part* opart = NULL; + // Verify a part with that id actually exists, then get it + TrackList* tracks = song->tracks(); + for (ciTrack t = tracks->begin(); t != tracks->end(); ++t) { + Track* track = *t; + for (ciPart p = track->parts()->begin(); p != track->parts()->end(); p++) { + if (p->second->sn() == id) { + opart = p->second; + break; + } + } + } + + if (opart == NULL) { + printf("Part doesn't exist!\n"); + return NULL; + } + + // Remove all note and controller events from current part eventlist + std::list< std::pair<const unsigned, Event> > elist; + MidiPart* npart = new MidiPart((MidiTrack*)opart->track()); + npart->setTick(opart->tick()); + npart->setLenTick(opart->lenTick()); + npart->setSn(opart->sn()); + + for (iEvent e = opart->events()->begin(); e != opart->events()->end(); e++) { + Event& event = e->second; + if (event.type() == Note || event.type() == Controller) + continue; + + npart->events()->add(event); + } + + addPyPartEventsToMusePart(npart, part); + + //song->startUndo(); + song->changePart(opart, npart); + //song->endUndo(SC_TRACK_MODIFIED | SC_PART_MODIFIED | SC_PART_INSERTED); // Crash! Probably since the call ends up in Qt GUI thread from this thread + + QPybridgeEvent* pyevent = new QPybridgeEvent(QPybridgeEvent::SONG_UPDATE, SC_TRACK_MODIFIED | SC_PART_MODIFIED | SC_PART_INSERTED); + QApplication::postEvent(song, pyevent); + + + Py_INCREF(Py_None); + return Py_None; +} +//------------------------------------------------------------ +// deletePart +// delete part by serial nr +//------------------------------------------------------------ +PyObject* deletePart(PyObject*, PyObject* args) +{ + int id; + if (!PyArg_ParseTuple(args, "i", &id)) { + return NULL; + } + + Part* part = findPartBySerial(id); + if (part == NULL) + return NULL; + + song->removePart(part); + QPybridgeEvent* pyevent = new QPybridgeEvent(QPybridgeEvent::SONG_UPDATE, SC_TRACK_MODIFIED | SC_PART_REMOVED); + QApplication::postEvent(song, pyevent); + Py_INCREF(Py_None); + return Py_None; +} + +//------------------------------------------------------------ +// setPos +//------------------------------------------------------------ +PyObject* setPos(PyObject*, PyObject* args) +{ + int index; + int ticks; + if (!PyArg_ParseTuple(args, "ii", &index, &ticks)) { + return NULL; + } + + //song->setPos(index, ticks); + QPybridgeEvent* pyevent = new QPybridgeEvent(QPybridgeEvent::SONG_POSCHANGE, index, ticks); + QApplication::postEvent(song, pyevent); + + Py_INCREF(Py_None); + return Py_None; +} + + +//------------------------------------------------------------ +// setLen +//------------------------------------------------------------ +PyObject* setSongLen(PyObject*, PyObject* args) +{ + unsigned len; + + if (!PyArg_ParseTuple(args, "i", &len)) { + return NULL; + } + //song->setLen(len);// Appears to not be ok to call from python thread, we do it with event instead + QPybridgeEvent* pyevent = new QPybridgeEvent(QPybridgeEvent::SONGLEN_CHANGE, len); + QApplication::postEvent(song, pyevent); + Py_INCREF(Py_None); + return Py_None; +} +//------------------------------------------------------------ +// getLen +//------------------------------------------------------------ +PyObject* getSongLen(PyObject*, PyObject*) +{ + PyObject* pylen = Py_BuildValue("i", song->len()); + + return pylen; +} +//------------------------------------------------------------ +// getDivision +//------------------------------------------------------------ +PyObject* getDivision(PyObject*, PyObject*) +{ + return Py_BuildValue("i", config.division); +} +//------------------------------------------------------------ +// setTrackParameter +//------------------------------------------------------------ +PyObject* setMidiTrackParameter(PyObject*, PyObject* args) +{ + const char* trackname; + const char* paramname; + int value; + if(!PyArg_ParseTuple(args, "ssi", &trackname, ¶mname, &value)) + return NULL; + + Track* track = song->findTrack(QString(trackname)); + if (track == NULL) + return NULL; + + MidiTrack* mt = (MidiTrack*) track; + + QString qparamname(paramname); + bool changed = false; + if (qparamname == "velocity") { + changed = true; + mt->velocity = value; + } + else if (qparamname == "compression") { + changed = true; + mt->compression = value; + } + else if (qparamname == "transposition") { + changed = true; + mt->transposition = value; + } + else if (qparamname == "delay") { + changed = true; + mt->delay = value; + } + + if (changed) { + QPybridgeEvent* pyevent = new QPybridgeEvent(QPybridgeEvent::SONG_UPDATE, SC_TRACK_MODIFIED); + QApplication::postEvent(song, pyevent); + } + + return Py_BuildValue("b", changed); // true/false depending on whether anythin was changed +} +//------------------------------------------------------------ +// Set loop +//------------------------------------------------------------ +PyObject* setLoop(PyObject*, PyObject* args) +{ + bool loopFlag; + if(!PyArg_ParseTuple(args, "b", &loopFlag)) + return NULL; + + song->setLoop(loopFlag); + Py_INCREF(Py_None); + return Py_None; +} +//------------------------------------------------------------ +// Get loop value +//------------------------------------------------------------ +PyObject* getLoop(PyObject*, PyObject*) +{ + return Py_BuildValue("b", song->getLoop()); +} +//------------------------------------------------------------ +// getMute trackname +//------------------------------------------------------------ +PyObject* getMute(PyObject*, PyObject* args) +{ + const char* trackname; + if (!PyArg_ParseTuple(args, "s", &trackname)) { + return NULL; + } + + Track* track = song->findTrack(QString(trackname)); + if (track == NULL) + return NULL; + + return Py_BuildValue("b", track->isMute()); +} +//------------------------------------------------------------ +// setMute (trackname, boolean) +//------------------------------------------------------------ +PyObject* setMute(PyObject*, PyObject* args) +{ + const char* trackname; + bool muted; + + if (!PyArg_ParseTuple(args, "sb", &trackname, &muted)) { + return NULL; + } + + Track* track = song->findTrack(QString(trackname)); + if (track == NULL) + return NULL; + + int mutedint = 1; + if (muted == false) + mutedint = 0; + + QPybridgeEvent* pyevent = new QPybridgeEvent(QPybridgeEvent::SONG_SETMUTE, mutedint); + pyevent->setS1(trackname); + QApplication::postEvent(song, pyevent); + Py_INCREF(Py_None); + return Py_None; +} +//------------------------------------------------------------ +// setController +//------------------------------------------------------------ +void setController(const char* trackname, int ctrltype, int ctrlval) +{ + QPybridgeEvent* pyevent = new QPybridgeEvent(QPybridgeEvent::SONG_SETCTRL, ctrltype, ctrlval); + pyevent->setS1(trackname); + QApplication::postEvent(song, pyevent); +} + +//------------------------------------------------------------ +// setMidiControllerValue +//------------------------------------------------------------ +PyObject* setMidiControllerValue(PyObject*, PyObject* args) +{ + const char* trackname; + int ctrltype; + int value; + + if (!PyArg_ParseTuple(args, "sii", &trackname, &ctrltype, &value)) { + return NULL; + } + + setController(trackname, ctrltype, value); + Py_INCREF(Py_None); + return Py_None; +} + +//------------------------------------------------------------ +// getMidiControllerValue +//------------------------------------------------------------ +PyObject* getMidiControllerValue(PyObject*, PyObject* args) +{ + const char* trackname; + int ctrltype; + + if (!PyArg_ParseTuple(args, "si", &trackname, &ctrltype)) { + return NULL; + } + + Track* t = song->findTrack(QString(trackname)); + if (t == NULL) + return NULL; + + if (t->isMidiTrack() == false) { + Py_INCREF(Py_None); + return Py_None; + } + + MidiTrack* track = (MidiTrack*) t; + int channel = track->outChannel(); + int outport = track->outPort(); + MidiPort* mp = &midiPorts[outport]; + if (mp == NULL) + return Py_BuildValue("i", -1); + + int value = mp->hwCtrlState(channel, ctrltype); + return Py_BuildValue("i", value); +} +//------------------------------------------------------------ +// setAudioTrackVolume +//------------------------------------------------------------ +PyObject* setAudioTrackVolume(PyObject*, PyObject* args) +{ + const char* trackname; + double volume = 0.0f; + + if (!PyArg_ParseTuple(args, "sd", &trackname, &volume)) { + return NULL; + } + + QPybridgeEvent* pyevent = new QPybridgeEvent(QPybridgeEvent::SONG_SETAUDIOVOL); + pyevent->setD1(volume); + pyevent->setS1(trackname); + QApplication::postEvent(song, pyevent); + Py_INCREF(Py_None); + return Py_None; +} +//------------------------------------------------------------ +// getAudioTrackVolume +//------------------------------------------------------------ +PyObject* getAudioTrackVolume(PyObject*, PyObject* args) +{ + const char* trackname; + + if (!PyArg_ParseTuple(args, "s", &trackname)) { + return NULL; + } + + Track* t = song->findTrack(QString(trackname)); + if (t == NULL) + return NULL; + + if (t->type() == Track::DRUM || t->type() == Track::MIDI) + return NULL; + + AudioTrack* track = (AudioTrack*) t; + return Py_BuildValue("d", track->volume()); +} + +//------------------------------------------------------------ +// getSelectedTrack +//------------------------------------------------------------ +PyObject* getSelectedTrack(PyObject*, PyObject*) +{ + TrackList* tracks = song->tracks(); + for (ciTrack t = tracks->begin(); t != tracks->end(); ++t) { + Track* track = *t; + if (track->selected()) + return Py_BuildValue("s", track->name().latin1()); + } + + Py_INCREF(Py_None); + return Py_None; +} + +//------------------------------------------------------------ +// importPart +//------------------------------------------------------------ +PyObject* importPart(PyObject*, PyObject* args) +{ + const char* trackname; + const char* filename; + int tick; + + if (!PyArg_ParseTuple(args, "ssi", &trackname, &filename, &tick)) { + return NULL; + } + + QPybridgeEvent* pyevent = new QPybridgeEvent(QPybridgeEvent::SONG_IMPORT_PART, tick); + pyevent->setS1(trackname); + pyevent->setS2(filename); + QApplication::postEvent(song, pyevent); + Py_INCREF(Py_None); + return Py_None; +} +//------------------------------------------------------------ +// getTrackEffects +//------------------------------------------------------------ +PyObject* getTrackEffects(PyObject*, PyObject* args) +{ + const char* trackname; + if (!PyArg_ParseTuple(args, "s", &trackname)) { + return NULL; + } + + Track* t = song->findTrack(QString(trackname)); + if (t == NULL) + return NULL; + + if (t->type() != Track::WAVE) + return NULL; + + AudioTrack* track = (AudioTrack*) t; + PyObject* pyfxnames = Py_BuildValue("[]"); + const Pipeline* pipeline = track->efxPipe(); + for (int i = 0; i < PipelineDepth; i++) { + QString name = pipeline->name(i); + printf("fx %d name: %s\n", i, name.latin1()); + PyObject* pyname = Py_BuildValue("s", name.latin1()); + PyList_Append(pyfxnames, pyname); + Py_DECREF(pyname); + } + + return pyfxnames; +} +//------------------------------------------------------------ +// toggleTrackEffect +//------------------------------------------------------------ +PyObject* toggleTrackEffect(PyObject*, PyObject* args) +{ + const char* trackname; + int fxid; + bool onoff; + + if (!PyArg_ParseTuple(args, "sib", &trackname, &fxid, &onoff)) + return NULL; + + Track* t = song->findTrack(QString(trackname)); + if (t == NULL) + return NULL; + + if (t->type() != Track::WAVE) + return NULL; + + QPybridgeEvent* pyevent = new QPybridgeEvent(QPybridgeEvent::SONG_TOGGLE_EFFECT, fxid, onoff); + pyevent->setS1(trackname); + + QApplication::postEvent(song, pyevent); + Py_INCREF(Py_None); + return Py_None; +} +//------------------------------------------------------------ +// changeTrackName +//------------------------------------------------------------ +PyObject* changeTrackName(PyObject*, PyObject* args) +{ + const char* trackname; + const char* newname; + + if (!PyArg_ParseTuple(args, "ss", &trackname, &newname)) + return NULL; + + Track* t = song->findTrack(QString(trackname)); + if (t == NULL) + return Py_BuildValue("b", false); + + QPybridgeEvent* pyevent = new QPybridgeEvent(QPybridgeEvent::SONG_CHANGE_TRACKNAME); + pyevent->setS1(trackname); + pyevent->setS2(newname); + QApplication::postEvent(song, pyevent); + QPybridgeEvent* pyevent2 = new QPybridgeEvent(QPybridgeEvent::SONG_UPDATE, SC_TRACK_MODIFIED); + QApplication::postEvent(song, pyevent2); + return Py_BuildValue("b", true); +} +//------------------------------------------------------------ +// addMidiTrack +//------------------------------------------------------------ +PyObject* addMidiTrack(PyObject*, PyObject*) +{ + QPybridgeEvent* pyevent = new QPybridgeEvent(QPybridgeEvent::SONG_ADD_TRACK, Track::MIDI); + QApplication::postEvent(song, pyevent); + Py_INCREF(Py_None); + return Py_None; +} +//------------------------------------------------------------ +// addWaveTrack +//------------------------------------------------------------ +PyObject* addWaveTrack(PyObject*, PyObject*) +{ + QPybridgeEvent* pyevent = new QPybridgeEvent(QPybridgeEvent::SONG_ADD_TRACK, Track::WAVE); + QApplication::postEvent(song, pyevent); + Py_INCREF(Py_None); + return Py_None; +} +//------------------------------------------------------------ +// addInput +//------------------------------------------------------------ +PyObject* addInput(PyObject*, PyObject*) +{ + QPybridgeEvent* pyevent = new QPybridgeEvent(QPybridgeEvent::SONG_ADD_TRACK, Track::AUDIO_INPUT); + QApplication::postEvent(song, pyevent); + Py_INCREF(Py_None); + return Py_None; +} +//------------------------------------------------------------ +// addOutput +//------------------------------------------------------------ +PyObject* addOutput(PyObject*, PyObject*) +{ + QPybridgeEvent* pyevent = new QPybridgeEvent(QPybridgeEvent::SONG_ADD_TRACK, Track::AUDIO_OUTPUT); + QApplication::postEvent(song, pyevent); + return Py_None; +} +//------------------------------------------------------------ +// addGroup +//------------------------------------------------------------ +PyObject* addGroup(PyObject*, PyObject*) +{ + QPybridgeEvent* pyevent = new QPybridgeEvent(QPybridgeEvent::SONG_ADD_TRACK, Track::AUDIO_GROUP); + QApplication::postEvent(song, pyevent); + return Py_None; +} +//------------------------------------------------------------ +// deleteTrack +//------------------------------------------------------------ +PyObject* deleteTrack(PyObject*, PyObject* args) +{ + const char* trackname; + + if (!PyArg_ParseTuple(args, "s", &trackname)) + return NULL; + + QPybridgeEvent* pyevent = new QPybridgeEvent(QPybridgeEvent::SONG_DELETE_TRACK); + pyevent->setS1(trackname); + QApplication::postEvent(song, pyevent); + return Py_None; +} +//------------------------------------------------------------ +// getOutputRoute +//------------------------------------------------------------ +/* +PyObject* getOutputRoute(PyObject*, PyObject* args) +{ + const char* trackname; + + if (!PyArg_ParseTuple(args, "s", &trackname)) + return NULL; + + Track* tt = song->findTrack(QString(trackname)); + if (tt == NULL) + return Py_BuildValue("b", false); + + PyObject* routes = Py_BuildValue("[]"); + if (tt->type() == Track::WAVE && tt->type() == Track::AUDIO_AUX) { + AudioTrack* t = (AudioTrack*)tt; + RouteList* r = t->outRoutes(); + + OutputList* al = song->outputs(); + for (iAudioOutput i = al->begin(); i != al->end(); ++i) { + Track* track = *i; + if (t == track) + continue; + + QString s(track->name()); + + // for (iRoute ir = r->begin(); ir != r->end(); ++ir) { + // if (ir->type == 0 && ir->track == track) { + // s += "*"; + // PyList_Append(routes, Py_BuildValue("s", s.latin1())); + // break; + // } + // } + // + } + } + else if (tt->type() == Track::AUDIO_OUTPUT) { + } + + + + return routes; +} +*/ +//------------------------------------------------------------ +// Global method definitions for MusE:s Python API +// +// This is where global functions in Python is linked to their equivalent C/C++ functions +//------------------------------------------------------------ +PyMethodDef g_methodDefinitions[] = +{ + { "startPlay", startPlay, METH_VARARGS, "Starts playing the song from current position" }, + { "stopPlay", stopPlay, METH_VARARGS, "Stops playback if currently playing" }, + { "rewindStart", rewindStart, METH_VARARGS, "Set current position to beginning of song" }, + { "getCPos", getCPos, METH_NOARGS, "Get current position (in ticks)" }, + { "getLPos", getLPos, METH_NOARGS, "Get position of left locator (in ticks)" }, + { "getRPos", getRPos, METH_NOARGS, "Get position of right locator (in ticks)" }, + { "setPos", setPos, METH_VARARGS, "Set position of locators or current position" }, + { "getTempo", getTempo, METH_VARARGS, "Get tempo of the song at a particular tick" }, + { "setLoop", setLoop, METH_VARARGS, "Set loop mode on/off" }, + { "getLoop", getLoop, METH_NOARGS, "Get loop value" }, + + { "getTrackNames", getTrackNames, METH_VARARGS, "Get track names (which are unique)" }, + { "getParts", getParts, METH_VARARGS, "Get part data from a track" }, + { "createPart", createPart, METH_VARARGS, "Create a part" }, + { "modifyPart", modifyPart, METH_O, "Modify a particular part" }, + { "deletePart", deletePart, METH_VARARGS, "Remove part with a particular serial nr" }, + { "getSelectedTrack", getSelectedTrack, METH_NOARGS, "Get first selected track" }, + { "importPart", importPart, METH_VARARGS, "Import part file to a track at a particular position" }, + { "changeTrackName", changeTrackName, METH_VARARGS, "Change track name" }, + { "addMidiTrack", addMidiTrack, METH_NOARGS, "Add a midi track" }, + { "addWaveTrack", addWaveTrack, METH_NOARGS, "Add a wave track" }, + { "addInput", addInput, METH_NOARGS, "Add audio input" }, + { "addOutput", addOutput, METH_NOARGS, "Add audio output" }, + { "addGroup", addGroup, METH_NOARGS, "Add audio group" }, + { "deleteTrack", deleteTrack, METH_VARARGS, "Delete a track" }, + + { "getTrackEffects", getTrackEffects, METH_VARARGS, "Get names of LADSPA effects on a track" }, + { "toggleTrackEffect", toggleTrackEffect, METH_VARARGS, "Toggle LADSPA effect on/off" }, + //{ "getOutputRoute", getOutputRoute, METH_VARARGS, "Get route for an audio output" }, + + { "setSongLen", setSongLen, METH_VARARGS, "Set length of song (in ticks)" }, + { "getSongLen", getSongLen, METH_VARARGS, "Get length of song (in ticks)" }, + + { "getMute", getMute, METH_VARARGS, "Get track mute property (if track is played or not)" }, + { "setMute", setMute, METH_VARARGS, "Set track mute property (if track should be played or not)" }, + { "setMidiControllerValue", setMidiControllerValue, METH_VARARGS, "Set midi controller value for a track" }, + { "getMidiControllerValue", getMidiControllerValue, METH_VARARGS, "Get midi controller value for a track" }, + { "setAudioTrackVolume", setAudioTrackVolume, METH_VARARGS, "Set volume on audio track/aux/output/input" }, + { "getAudioTrackVolume", getAudioTrackVolume, METH_VARARGS, "Get audio track/aux/output/input volume" }, + + { "setMidiTrackParameter", setMidiTrackParameter, METH_VARARGS, "Set transposition, velocity, compression or delay on track level" }, + + { "getDivision", getDivision, METH_VARARGS, "Number of ticks per 1/4 (?)" }, + + {NULL, NULL, NULL, NULL} +}; + +/** + * This function launches the Pyro name service, which blocks execution + * Thus it needs its own thread + **/ +static void* pyapithreadfunc(void*) +{ + Py_Initialize(); + PyImport_AddModule("muse"); + Py_InitModule( "muse", g_methodDefinitions ); + + // + // Access the "__main__" module and its name-space dictionary. + // + + PyObject *pMainModule = PyImport_AddModule( "__main__" ); + PyObject *pMainDictionary = PyModule_GetDict( pMainModule ); + string launcherfilename = string(INSTPREFIX) + string("/share/muse/pybridge/museplauncher.py"); + printf("Initiating MusE Pybridge launcher from %s\n", launcherfilename.c_str()); + FILE* fp = fopen(launcherfilename.c_str(),"r"); + PyRun_File(fp, launcherfilename.c_str(), Py_file_input, pMainDictionary, pMainDictionary); + fclose(fp); + + return NULL; +} + +/** + * This function currently only launches the thread. There should be some kind of check that + * things are up and running as they are supposed to + */ +bool initPythonBridge() +{ + if (pthread_create(&pyapiThread, NULL, ::pyapithreadfunc, 0)) { + return false; + } + return true; // TODO: Verify that things are up and running! +} + +//--------------------------------------------------------- +// event +// +// Function in Song class, run in the Qt event thread context. +// Handles events sent from the Python bridge subsystem +// +// This is part of Qt:s event handling and events are fed +// here via QApplication::postEvent since gui updates should +// be done by Qt:s GUI thread. QApplication::postEvent is +// a static method, which is threadsafe. Using the song object +// from the Python thread is dangerous when it comes to +// operations that manipulate the gui itself (read is ok) +//--------------------------------------------------------- +bool Song::event(QEvent* _e) +{ + if (_e->type() != QEvent::User) + return false; //ignore all events except user events, which are events from Python bridge subsystem + + QPybridgeEvent* e = (QPybridgeEvent*) _e; + switch (e->getType()) { + case QPybridgeEvent::SONG_UPDATE: + this->update(e->getP1()); + break; + case QPybridgeEvent::SONGLEN_CHANGE: + this->setLen(e->getP1()); + break; + case QPybridgeEvent::SONG_POSCHANGE: + this->setPos(e->getP1(), e->getP2()); + break; + case QPybridgeEvent::SONG_SETPLAY: + this->setPlay(true); + break; + case QPybridgeEvent::SONG_SETSTOP: + this->setStop(true); + break; + case QPybridgeEvent::SONG_REWIND: + this->rewindStart(); + break; + case QPybridgeEvent::SONG_SETMUTE: { + Track* track = this->findTrack(e->getS1()); + if (track == NULL) + return false; + + bool muted = e->getP1() == 1; + track->setMute(muted); + this->update(SC_MUTE | SC_TRACK_MODIFIED); + break; + } + case QPybridgeEvent::SONG_SETCTRL: { + Track* t = this->findTrack(e->getS1()); + if (t == NULL) + return false; + + if (t->isMidiTrack() == false) + return false; + + MidiTrack* track = (MidiTrack*) t; + int chan = track->outChannel(); + + int num = e->getP1(); + int val = e->getP2(); + int tick = song->cpos(); + MidiPlayEvent ev(tick, track->outPort(), chan, ME_CONTROLLER, num, val); + audio->msgPlayMidiEvent(&ev); + song->update(SC_MIDI_CONTROLLER); + break; + } + case QPybridgeEvent::SONG_SETAUDIOVOL: { + Track* t = this->findTrack(e->getS1()); + if (t == NULL) + return false; + + if (t->type() == Track::DRUM || t->type() == Track::MIDI) + return false; + + AudioTrack* track = (AudioTrack*) t; + track->setVolume(e->getD1()); + break; + } + case QPybridgeEvent::SONG_IMPORT_PART: { + Track* track = this->findTrack(e->getS1()); + QString filename = e->getS2(); + unsigned int tick = e->getP1(); + if (track == NULL) + return false; + + muse->importPartToTrack(filename, tick, track); + break; + } + case QPybridgeEvent::SONG_TOGGLE_EFFECT: { + Track* t = this->findTrack(e->getS1()); + if (t == NULL) + return false; + + if (t->type() != Track::WAVE) + return false; + + int fxid = e->getP1(); + + if (fxid > PipelineDepth) + return false; + + int onoff = (e->getP2() == 1); + + AudioTrack* track = (AudioTrack*) t; + Pipeline* pipeline = track->efxPipe(); + pipeline->setOn(fxid, onoff); + break; + } + case QPybridgeEvent::SONG_ADD_TRACK: + song->addTrack(e->getP1()); + break; + case QPybridgeEvent::SONG_CHANGE_TRACKNAME: { + Track* t = this->findTrack(e->getS1()); + if (t == NULL) + return false; + t->setName(e->getS2()); + break; + } + case QPybridgeEvent::SONG_DELETE_TRACK: { + Track* t = this->findTrack(e->getS1()); + if (t == NULL) + return false; + + audio->msgRemoveTrack(t); + break; + } + default: + printf("Unknown pythonthread event received: %d\n", e->getType()); + break; + } + + + return true; +} + + diff --git a/muse2/muse/remote/pyapi.h b/muse2/muse/remote/pyapi.h new file mode 100644 index 00000000..582f8b34 --- /dev/null +++ b/muse2/muse/remote/pyapi.h @@ -0,0 +1,40 @@ +//========================================================= +// MusE +// Linux Music Editor +// (C) Copyright 2009 Mathias Gyllengahm (lunar_shuttle@users.sf.net) +//========================================================= +#ifndef PYAPI_H +#define PYAPI_H + +#include <qevent.h> + +class QPybridgeEvent : public QEvent +{ +public: + enum EventType { SONG_UPDATE=0, SONGLEN_CHANGE, SONG_POSCHANGE, SONG_SETPLAY, SONG_SETSTOP, SONG_REWIND, SONG_SETMUTE, + SONG_SETCTRL, SONG_SETAUDIOVOL, SONG_IMPORT_PART, SONG_TOGGLE_EFFECT, SONG_ADD_TRACK, SONG_CHANGE_TRACKNAME, + SONG_DELETE_TRACK }; + QPybridgeEvent( QPybridgeEvent::EventType _type, int _p1=0, int _p2=0); + EventType getType() { return type; } + int getP1() { return p1; } + int getP2() { return p2; } + void setS1(QString in) { s1 = in; } + void setS2(QString in) { s2 = in; } + const QString& getS1() { return s1; } + const QString& getS2() { return s2; } + double getD1() { return d1; } + void setD1(double _d1) { d1 = _d1; } + +private: + EventType type; + int p1, p2; + double d1; + QString s1; + QString s2; + +}; + +bool initPythonBridge(); + +#endif + |