summaryrefslogtreecommitdiff
path: root/attic/muse2-oom/muse2/muse/remote/pyapi.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'attic/muse2-oom/muse2/muse/remote/pyapi.cpp')
-rw-r--r--attic/muse2-oom/muse2/muse/remote/pyapi.cpp1140
1 files changed, 0 insertions, 1140 deletions
diff --git a/attic/muse2-oom/muse2/muse/remote/pyapi.cpp b/attic/muse2-oom/muse2/muse/remote/pyapi.cpp
deleted file mode 100644
index 84543b18..00000000
--- a/attic/muse2-oom/muse2/muse/remote/pyapi.cpp
+++ /dev/null
@@ -1,1140 +0,0 @@
-//=========================================================
-// 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 <QApplication>
-
-#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().toLatin1());
- 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, &paramname, &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().toLatin1());
- }
-
- 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.toLatin1());
- PyObject* pyname = Py_BuildValue("s", name.toLatin1());
- 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.toLatin1()));
- // 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(SHAREDIR) + string("/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;
-}
-
-