From b703eab295330e6f81564fbb39a10a1a2fdd2f54 Mon Sep 17 00:00:00 2001
From: Robert Jonsson <spamatica@gmail.com>
Date: Sun, 27 Dec 2009 11:30:35 +0000
Subject: moved old qt4 branch

---
 .../synti/zynaddsubfx/Seq/MIDIEvents.C             |  85 +++++
 .../synti/zynaddsubfx/Seq/MIDIEvents.h             |  66 ++++
 .../synti/zynaddsubfx/Seq/MIDIFile.C               | 389 +++++++++++++++++++++
 .../synti/zynaddsubfx/Seq/MIDIFile.h               |  90 +++++
 .../synti/zynaddsubfx/Seq/Sequencer.C              | 165 +++++++++
 .../synti/zynaddsubfx/Seq/Sequencer.h              |  84 +++++
 6 files changed, 879 insertions(+)
 create mode 100644 muse_qt4_evolution/synti/zynaddsubfx/Seq/MIDIEvents.C
 create mode 100644 muse_qt4_evolution/synti/zynaddsubfx/Seq/MIDIEvents.h
 create mode 100644 muse_qt4_evolution/synti/zynaddsubfx/Seq/MIDIFile.C
 create mode 100644 muse_qt4_evolution/synti/zynaddsubfx/Seq/MIDIFile.h
 create mode 100644 muse_qt4_evolution/synti/zynaddsubfx/Seq/Sequencer.C
 create mode 100644 muse_qt4_evolution/synti/zynaddsubfx/Seq/Sequencer.h

(limited to 'muse_qt4_evolution/synti/zynaddsubfx/Seq')

diff --git a/muse_qt4_evolution/synti/zynaddsubfx/Seq/MIDIEvents.C b/muse_qt4_evolution/synti/zynaddsubfx/Seq/MIDIEvents.C
new file mode 100644
index 00000000..729089c6
--- /dev/null
+++ b/muse_qt4_evolution/synti/zynaddsubfx/Seq/MIDIEvents.C
@@ -0,0 +1,85 @@
+/*
+  ZynAddSubFX - a software synthesizer
+ 
+  MIDIEvents.C - It stores the midi events from midi file or sequencer
+  Copyright (C) 2003-2005 Nasca Octavian Paul
+  Author: Nasca Octavian Paul
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of version 2 of the GNU General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License (version 2) for more details.
+
+  You should have received a copy of the GNU General Public License (version 2)
+  along with this program; if not, write to the Free Software Foundation,
+  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+*/
+
+#include "MIDIEvents.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+MIDIEvents::MIDIEvents(){
+};
+
+MIDIEvents::~MIDIEvents(){
+};
+
+
+/************** Track stuff ***************/
+void MIDIEvents::writeevent(list *l,event *ev){
+    listpos *tmp=new listpos;
+    tmp->next=NULL;
+    tmp->ev=*ev;
+    if (l->current!=NULL) l->current->next=tmp;
+	else l->first=tmp;
+    l->current=tmp;
+//    printf("Wx%x ",(int) l->current);
+//    printf("-> %d  \n",l->current->ev.deltatime);
+    l->size++;
+};
+
+void MIDIEvents::readevent(list *l,event *ev){
+    if (l->current==NULL) {
+	ev->type=-1;
+	return;
+    };
+    *ev=l->current->ev;
+    l->current=l->current->next;
+
+    //test
+    if (l->current!=NULL) {
+//	ev->deltatime=10000;
+//	printf("Rx%d\n",l->current->ev.deltatime);
+//	printf("Rx%x  ",(int) l->current);
+//	printf("-> %d  (next=%x) \n",(int)l->current->ev.deltatime,(int)l->current->next);
+    };
+
+};
+
+
+void MIDIEvents::rewindlist(list *l){
+    l->current=l->first;
+};
+
+void MIDIEvents::deletelist(list *l){
+    l->current=l->first;
+    if (l->current==NULL) return;
+    while (l->current->next!=NULL){
+	listpos *tmp=l->current;
+	l->current=l->current->next;
+	delete(tmp);
+    };
+    deletelistreference(l);
+};
+
+void MIDIEvents::deletelistreference(list *l){
+    l->current=l->first=NULL;
+    l->size=0;
+    l->length=0.0;
+};
diff --git a/muse_qt4_evolution/synti/zynaddsubfx/Seq/MIDIEvents.h b/muse_qt4_evolution/synti/zynaddsubfx/Seq/MIDIEvents.h
new file mode 100644
index 00000000..1bf9befc
--- /dev/null
+++ b/muse_qt4_evolution/synti/zynaddsubfx/Seq/MIDIEvents.h
@@ -0,0 +1,66 @@
+/*
+  ZynAddSubFX - a software synthesizer
+ 
+  MIDIEvents.h - It stores the midi events from midi file or sequencer
+  Copyright (C) 2003-2005 Nasca Octavian Paul
+  Author: Nasca Octavian Paul
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of version 2 of the GNU General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License (version 2) for more details.
+
+  You should have received a copy of the GNU General Public License (version 2)
+  along with this program; if not, write to the Free Software Foundation,
+  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+*/
+#ifndef MIDI_EVENTS_H
+#define MIDI_EVENTS_H
+
+#include "../globals.h"
+#define NUM_MIDI_TRACKS NUM_MIDI_CHANNELS
+
+class MIDIEvents{
+    friend class MIDIFile;
+    public:
+	MIDIEvents();
+	~MIDIEvents();
+
+    protected:
+
+    /* Events */
+    struct event{
+        int deltatime;
+	int channel;//on what midi channel is
+	int type,par1,par2;//type=1 for note, type=2 for controller, type=255 for time messages
+    } tmpevent;
+    struct listpos{
+	event ev;
+        struct listpos *next;
+    };
+    struct list{
+	listpos *first,*current;
+	int size;//how many events are
+	double length;//in seconds
+    };
+    struct {
+	list track;//the stored track
+	list record;//the track being "recorded" from midi
+    } miditrack[NUM_MIDI_TRACKS];
+    
+    void writeevent(list *l,event *ev);
+    void readevent(list *l,event *ev);
+    
+    void rewindlist(list *l);
+    void deletelist(list *l);
+    void deletelistreference(list *l);
+
+};
+
+
+#endif
diff --git a/muse_qt4_evolution/synti/zynaddsubfx/Seq/MIDIFile.C b/muse_qt4_evolution/synti/zynaddsubfx/Seq/MIDIFile.C
new file mode 100644
index 00000000..a5fdaa1c
--- /dev/null
+++ b/muse_qt4_evolution/synti/zynaddsubfx/Seq/MIDIFile.C
@@ -0,0 +1,389 @@
+/*
+  ZynAddSubFX - a software synthesizer
+ 
+  MIDIFile.C - MIDI file loader
+  Copyright (C) 2003-2005 Nasca Octavian Paul
+  Author: Nasca Octavian Paul
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of version 2 of the GNU General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License (version 2) for more details.
+
+  You should have received a copy of the GNU General Public License (version 2)
+  along with this program; if not, write to the Free Software Foundation,
+  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include "MIDIFile.h"
+
+
+MIDIFile::MIDIFile(){
+    midifile=NULL;
+    midifilesize=0;
+    midifilek=0;
+    midieof=false;
+    me=NULL;
+};
+
+MIDIFile::~MIDIFile(){
+    clearmidifile();
+};
+
+int MIDIFile::loadfile(char *filename){
+    clearmidifile();
+    
+    FILE *file=fopen(filename,"r");
+    if (file==NULL) return(-1);
+    
+    char header[4];
+    ZERO(header,4);
+    fread(header,4,1,file);
+
+    //test to see if this a midi file
+    if ((header[0]!='M')||(header[1]!='T')||(header[2]!='h')||(header[3]!='d')){
+	fclose(file);
+	return(-1);
+    };
+    
+    //get the filesize
+    fseek(file,0,SEEK_END);
+    midifilesize=ftell(file);
+    rewind(file);
+    
+    midifile=new unsigned char[midifilesize];
+    ZERO(midifile,midifilesize);
+    fread(midifile,midifilesize,1,file);
+    fclose(file);
+
+//    for (int i=0;i<midifilesize;i++) printf("%2x ",midifile[i]);
+//    printf("\n");
+    
+    
+    return(0);
+};
+
+int MIDIFile::parsemidifile(MIDIEvents *me_){
+    this->me=me_;
+
+    //read the header
+    int chunk=getint32();//MThd
+    if (chunk!=0x4d546864) return(-1);
+    int size=getint32();
+    if (size!=6) return(-1);//header is always 6 bytes long
+
+
+    int format=getint16();
+    printf("format %d\n",format);
+
+    int ntracks=getint16();//this is always 1 if the format is "0"
+    printf("ntracks %d\n",ntracks);
+
+    int division=getint16();
+    printf("division %d\n",division);
+    if (division>=0){//delta time units in each a quater note
+//	tick=???;
+    } else {//SMPTE (frames/second and ticks/frame)
+	printf("ERROR:in MIDIFile.C::parsemidifile() - SMPTE not implemented yet.");
+    };    
+    
+    if (ntracks>=NUM_MIDI_TRACKS) ntracks=NUM_MIDI_TRACKS-1;
+    
+    for (int n=0;n<ntracks;n++){
+	if (parsetrack(n)<0) {
+	    clearmidifile();
+	    return(-1);
+	};
+    };
+
+    printf("\n\nCURRENT File position is = 0x%x\n",midifilek);
+    printf("\nMIDI file succesfully parsed.\n");
+//    printf("\n0x%x\n",getbyte());
+
+    this->me=NULL;
+    return(0);
+};
+
+//private members
+
+
+int MIDIFile::parsetrack(int ntrack){
+    printf("\n--==*Reading track %d **==--\n",ntrack);
+
+    int chunk=getint32();//MTrk
+    if (chunk!=0x4d54726b) return(-1);
+
+    int size=getint32();
+    printf("size = %d\n",size);
+
+    int oldmidifilek=midifilek;
+
+    unsigned char lastmsg=0;
+    unsigned int dt=0;
+    
+    while(!midieof){
+	unsigned int msgdeltatime=getvarint32();
+	
+///	printf("MSGDELTATIME = %d\n",msgdeltatime);
+	
+//	dt+=msgdeltatime;
+
+	int msg=peekbyte();
+///	printf("raw msg=0x%x     ",msg);
+	if (msg<0x80) {
+	    msg=lastmsg;
+	} else {
+	    lastmsg=msg;
+	    getbyte();
+	};  
+///	printf("msg=0x%x\n",msg);
+
+//	dt+=msgdeltatime;
+	add_dt(ntrack, msgdeltatime);
+	
+	unsigned int mtype,mlength;
+	
+	switch(msg){
+	    case 0x80 ... 0x8f://note on off
+		    parsenoteoff(ntrack,msg & 0x0f,dt);
+		    dt=0;
+		break;
+	    case 0x90 ... 0x9f://note on (or note off)
+		    parsenoteon(ntrack,msg & 0x0f,dt);
+		    dt=0;
+		break;
+	    case 0xa0 ... 0xaf://aftertouch - ignored
+		    skipnbytes(2);
+		break;
+	    case 0xb0 ... 0xbf://control change
+		    parsecontrolchange(ntrack,msg & 0x0f,dt);
+		    dt=0;
+		break;
+	    case 0xc0 ... 0xcf://program change - ignored
+		    skipnbytes(1);
+		break;
+	    case 0xd0 ... 0xdf://channel pressure - ignored
+		    skipnbytes(1);
+		break;
+	    case 0xe0 ... 0xef://channel mode messages
+		    skipnbytes(2);
+		break;
+	    case 0xf0://sysex - ignored
+		while (getbyte()!=0xf7){
+		    if (midieof) break;
+		};
+	      break;
+	    case 0xf7://sysex (another type) - ignored
+		skipnbytes(getvarint32());
+	      break;
+
+	    case 0xff://meta-event
+		mtype=getbyte();
+		mlength=getbyte();
+		parsemetaevent(mtype,mlength);
+  	      break;
+
+	    default:
+		getbyte();
+		printf("UNKNOWN message! 0x%x\n",msg);
+		return(-1);
+  	     break;
+	};
+
+
+	
+	if (midieof) return(-1);
+
+	if ((midifilek-oldmidifilek)==size) break;
+	    else if((midifilek-oldmidifilek)>size) return(-1);
+//    if (size!=6) return(-1);//header is always 6 bytes long
+    };
+
+    printf("End Track\n\n");
+
+    return(0);
+};
+
+
+void MIDIFile::parsenoteoff(char ntrack,char chan,unsigned int dt){
+    unsigned char note;
+    note=getbyte();
+    
+    unsigned char noteoff_velocity=getbyte();//unused by zynaddsubfx
+    noteoff_velocity=0;
+    if (chan>=NUM_MIDI_CHANNELS) return;
+    
+    me->tmpevent.deltatime=convertdt(dt);
+    me->tmpevent.type=1;
+    me->tmpevent.par1=note;
+    me->tmpevent.par2=0;
+    me->tmpevent.channel=chan;
+    
+    printf("Note off:%d \n",note);
+    
+    ///test 
+//    ntrack=0;
+    
+    me->writeevent(&me->miditrack[(int)ntrack].record,&me->tmpevent);
+    
+};
+
+
+void MIDIFile::parsenoteon(char ntrack,char chan,unsigned int dt){
+    unsigned char note,vel;
+    note=getbyte();
+    vel=getbyte();
+    
+//    printf("ntrack=%d\n",ntrack);
+    printf("[dt %d ]  Note on:%d %d\n",dt,note,vel);
+    
+    if (chan>=NUM_MIDI_CHANNELS) return;
+    
+    me->tmpevent.deltatime=convertdt(dt);
+    me->tmpevent.type=1;
+    me->tmpevent.par1=note;
+    me->tmpevent.par2=vel;
+    me->tmpevent.channel=chan;
+    me->writeevent(&me->miditrack[(int)ntrack].record,&me->tmpevent);
+
+    
+    
+};
+
+void MIDIFile::parsecontrolchange(char ntrack,char chan,unsigned int dt){
+    unsigned char control,value;
+    control=getbyte();
+    value=getbyte();
+    
+    if (chan>=NUM_MIDI_CHANNELS) return;
+    
+    printf("[dt %d] Control change:%d %d\n",dt,control,value);
+    
+    me->tmpevent.deltatime=convertdt(dt);
+    me->tmpevent.type=2;
+    me->tmpevent.par1=control;//???????????? ma uit la Sequencer::recordnote() din varianele vechi de zyn
+    me->tmpevent.par2=value;
+    me->tmpevent.channel=chan;
+    me->writeevent(&me->miditrack[(int)ntrack].record,&me->tmpevent);
+    
+};
+
+void MIDIFile::parsepitchwheel(char ntrack,char chan, unsigned int dt){
+    unsigned char valhi,vallo;
+    vallo=getbyte();
+    valhi=getbyte();
+    
+    if (chan>=NUM_MIDI_CHANNELS) return;
+    
+    int value=(int)valhi*128+vallo;
+    
+    printf("[dt %d] Pitch wheel:%d\n",dt,value);
+    
+};
+
+void MIDIFile::parsemetaevent(unsigned char mtype,unsigned char mlength){
+    int oldmidifilek=midifilek;
+    printf("meta-event type=0x%x  length=%d\n",mtype,mlength);
+    
+
+
+    midifilek=oldmidifilek+mlength;
+        
+};
+
+void MIDIFile::add_dt(char ntrack, unsigned int dt){
+    me->tmpevent.deltatime=convertdt(dt);
+    me->tmpevent.type=255;
+    me->tmpevent.par1=0;
+    me->tmpevent.par2=0;
+    me->tmpevent.channel=0;
+    me->writeevent(&me->miditrack[(int)ntrack].record,&me->tmpevent);
+};
+
+
+unsigned int MIDIFile::convertdt(unsigned int dt){
+    double result=dt;
+    printf("DT=%d\n",dt);
+
+    return((int) (result*15.0));
+};
+
+
+void MIDIFile::clearmidifile(){
+    if (midifile!=NULL) delete(midifile);
+    midifile=NULL;
+    midifilesize=0;
+    midifilek=0;
+    midieof=false;
+    data.tick=0.05;
+};
+
+unsigned char MIDIFile::getbyte(){
+    if (midifilek>=midifilesize) {
+	midieof=true;
+	return(0);
+    };
+
+///    printf("(%d) ",midifile[midifilek]);
+    return(midifile[midifilek++]);
+};
+
+unsigned char MIDIFile::peekbyte(){
+    if (midifilek>=midifilesize) {
+	midieof=true;
+	return(0);
+    };
+    return(midifile[midifilek]);
+};
+
+unsigned int MIDIFile::getint32(){
+    unsigned int result=0;
+    for (int i=0;i<4;i++) {
+	result=result*256+getbyte();
+    };
+    if (midieof) result=0;
+    return(result);
+};
+
+unsigned short int MIDIFile::getint16(){
+    unsigned short int result=0;
+    for (int i=0;i<2;i++) {
+	result=result*256+getbyte();
+    };
+    if (midieof) result=0;
+    return(result);
+};
+
+unsigned int MIDIFile::getvarint32(){
+    unsigned long result=0;
+    unsigned char b;
+
+///    printf("\n[start]");
+
+    if ((result = getbyte()) & 0x80) {
+        result &= 0x7f;
+        do  {
+	    b=getbyte();
+            result = (result << 7) + (b & 0x7f);
+        }while (b & 0x80);
+    }
+///    printf("[end - result= %d]\n",result);
+    return result;
+};
+
+
+void MIDIFile::skipnbytes(int n){
+    midifilek+=n;
+    if (midifilek>=midifilesize){
+	midifilek=midifilesize-1;
+	midieof=true;
+    };
+};
+
diff --git a/muse_qt4_evolution/synti/zynaddsubfx/Seq/MIDIFile.h b/muse_qt4_evolution/synti/zynaddsubfx/Seq/MIDIFile.h
new file mode 100644
index 00000000..c88f679c
--- /dev/null
+++ b/muse_qt4_evolution/synti/zynaddsubfx/Seq/MIDIFile.h
@@ -0,0 +1,90 @@
+/*
+  ZynAddSubFX - a software synthesizer
+ 
+  MIDIFile.h - MIDI file loader
+  Copyright (C) 2003-2005 Nasca Octavian Paul
+  Author: Nasca Octavian Paul
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of version 2 of the GNU General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License (version 2) for more details.
+
+  You should have received a copy of the GNU General Public License (version 2)
+  along with this program; if not, write to the Free Software Foundation,
+  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+*/
+
+#ifndef MIDIFILE_H
+#define MIDIFILE_H
+
+#include "../globals.h"
+#include "MIDIEvents.h"
+
+class MIDIFile{
+    public:
+	MIDIFile();
+	~MIDIFile();
+	
+	//returns -1 if there is an error, otherwise 0
+	int loadfile(char *filename);
+	
+	//returns -1 if there is an error, otherwise 0
+	int parsemidifile(MIDIEvents *me_);
+	
+    private:
+	MIDIEvents *me;	
+    
+	unsigned char *midifile;
+	int midifilesize,midifilek;
+	bool midieof;
+
+	//returns -1 if there is an error, otherwise 0
+	int parsetrack(int ntrack);
+    
+	void parsenoteoff(char ntrack,char chan,unsigned int dt);
+	void parsenoteon(char ntrack,char chan,unsigned int dt);
+	void parsecontrolchange(char ntrack,char chan,unsigned int dt);
+	void parsepitchwheel(char ntrack,char chan, unsigned int dt);
+	void parsemetaevent(unsigned char mtype,unsigned char mlength);
+
+	void add_dt(char ntrack, unsigned int dt);
+	
+	void clearmidifile();
+
+	//convert the delta-time to internal format 
+	unsigned int convertdt(unsigned int dt);	
+	
+	/* Low Level MIDIfile functions */
+	
+	//get a byte from the midifile
+	unsigned char getbyte();
+
+	//peek the current byte from the midifile
+	unsigned char peekbyte();
+	
+	//get a set of 4 bytes from the midifile
+	unsigned int getint32();
+	
+	//get a word of 2 bytes from the midifile
+	unsigned short int getint16();
+
+	//read a variable length quantity
+	unsigned int getvarint32();	
+
+	//skip some bytes
+	void skipnbytes(int n);
+
+	struct {
+	    double tick;//how many seconds one tick has
+	    
+	}data;
+	
+};
+
+#endif
diff --git a/muse_qt4_evolution/synti/zynaddsubfx/Seq/Sequencer.C b/muse_qt4_evolution/synti/zynaddsubfx/Seq/Sequencer.C
new file mode 100644
index 00000000..d81ee611
--- /dev/null
+++ b/muse_qt4_evolution/synti/zynaddsubfx/Seq/Sequencer.C
@@ -0,0 +1,165 @@
+/*
+  ZynAddSubFX - a software synthesizer
+ 
+  Sequencer.C - The Sequencer
+  Copyright (C) 2003-2005 Nasca Octavian Paul
+  Author: Nasca Octavian Paul
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of version 2 of the GNU General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License (version 2) for more details.
+
+  You should have received a copy of the GNU General Public License (version 2)
+  along with this program; if not, write to the Free Software Foundation,
+  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+*/
+
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <sys/time.h>
+#include <time.h>
+
+#include "Sequencer.h"
+
+
+
+Sequencer::Sequencer(){
+    play=0;
+    for (int i=0;i<NUM_MIDI_TRACKS;i++){
+	miditrack[i].track.first=NULL;
+	miditrack[i].track.current=NULL;
+	miditrack[i].track.size=0;
+	miditrack[i].track.length=0.0;
+	miditrack[i].record.first=NULL;
+	miditrack[i].record.current=NULL;
+	miditrack[i].record.size=0;
+	miditrack[i].record.length=0.0;
+
+	nextevent[i].time=0.0;
+	resettime(&playtime[i]);
+    };
+    
+    setplayspeed(0);
+};
+
+Sequencer::~Sequencer(){
+    for (int i=0;i<NUM_MIDI_TRACKS;i++){
+	deletelist(&miditrack[i].track);
+	deletelist(&miditrack[i].record);
+    };
+};
+
+
+int Sequencer::importmidifile(char *filename){
+    if (midifile.loadfile(filename)<0) return(-1);
+
+    for (int i=0;i<NUM_MIDI_TRACKS;i++){
+	deletelist(&miditrack[i].record);
+    };
+    if (midifile.parsemidifile(this)<0) return(-1);
+    
+    //copy the "record" track to the main track
+    for (int i=0;i<NUM_MIDI_TRACKS;i++){
+	deletelist(&miditrack[i].track);
+	miditrack[i].track=miditrack[i].record;
+	deletelistreference(&miditrack[i].record);
+    };
+    return(0);
+};
+
+
+
+void Sequencer::startplay(){
+    if (play!=0) return;
+    for (int i=0;i<NUM_MIDI_TRACKS;i++) resettime(&playtime[i]);
+    
+    for (int i=0;i<NUM_MIDI_TRACKS;i++){
+	rewindlist(&miditrack[i].track);
+    };
+    play=1;
+    
+};
+void Sequencer::stopplay(){
+    if (play==0) return;
+    play=0;
+};
+
+// ************ Player stuff ***************
+
+int Sequencer::getevent(char ntrack,int *midich, int *type,int *par1, int *par2){
+    *type=0;
+    if (play==0) return(-1);
+
+    //test
+//    if (ntrack!=0) return(-1);
+
+    updatecounter(&playtime[(int)ntrack]);
+
+//    printf("%g %g\n",nextevent[ntrack].time,playtime[ntrack].abs);
+
+    if (nextevent[(int)ntrack].time<playtime[(int)ntrack].abs) readevent(&miditrack[(int)ntrack].track,&nextevent[(int)ntrack].ev);
+	else return(-1);
+    if (nextevent[(int)ntrack].ev.type==-1) return(-1);
+//    printf("********************************\n");    
+
+    //sa pun aici o protectie. a.i. daca distanta dintre timpul curent si eveliment e prea mare (>1sec) sa elimin nota
+
+    if (ntrack==1) printf("_ %f %.2f  (%d)\n",nextevent[(int)ntrack].time,playtime[(int)ntrack].abs,nextevent[(int)ntrack].ev.par2);
+
+    *type=nextevent[(int)ntrack].ev.type;
+    *par1=nextevent[(int)ntrack].ev.par1;
+    *par2=nextevent[(int)ntrack].ev.par2;
+    *midich=nextevent[(int)ntrack].ev.channel;
+
+    
+    double dt=nextevent[(int)ntrack].ev.deltatime*0.0001*realplayspeed;
+    printf("zzzzzzzzzzzzzz[%d] %d\n",ntrack,nextevent[(int)ntrack].ev.deltatime);
+    nextevent[(int)ntrack].time+=dt;
+
+//    printf("%f   -  %d %d \n",nextevent[ntrack].time,par1,par2);
+    return(0);//?? sau 1
+};
+
+/************** Timer stuff ***************/
+
+void Sequencer::resettime(timestruct *t){
+    t->abs=0.0;
+    t->rel=0.0;
+    
+    timeval tval;
+    
+    t->last=0.0;
+    #ifndef OS_WINDOWS
+    if (gettimeofday(&tval,NULL)==0)  
+	t->last=tval.tv_sec+tval.tv_usec*0.000001;
+    #endif
+    
+};
+
+void Sequencer::updatecounter(timestruct *t){
+    timeval tval;
+    double current=0.0;
+    #ifndef OS_WINDOWS
+    if (gettimeofday(&tval,NULL)==0)  
+	current=tval.tv_sec+tval.tv_usec*0.000001;
+    #endif
+    
+    t->rel=current - t->last;
+    t->abs+=t->rel;
+    t->last=current;
+    
+//    printf("%f %f %f\n",t->last,t->abs,t->rel);
+};
+
+void Sequencer::setplayspeed(int speed){
+    playspeed=speed;
+    realplayspeed=pow(10.0,speed/128.0);
+};
diff --git a/muse_qt4_evolution/synti/zynaddsubfx/Seq/Sequencer.h b/muse_qt4_evolution/synti/zynaddsubfx/Seq/Sequencer.h
new file mode 100644
index 00000000..82ebe495
--- /dev/null
+++ b/muse_qt4_evolution/synti/zynaddsubfx/Seq/Sequencer.h
@@ -0,0 +1,84 @@
+/*
+  ZynAddSubFX - a software synthesizer
+ 
+  Sequencer.h - The Sequencer
+  Copyright (C) 2003-2005 Nasca Octavian Paul
+  Author: Nasca Octavian Paul
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of version 2 of the GNU General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License (version 2) for more details.
+
+  You should have received a copy of the GNU General Public License (version 2)
+  along with this program; if not, write to the Free Software Foundation,
+  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+*/
+
+#ifndef SEQUENCER_H
+#define SEQUENCER_H
+
+#include "../globals.h"
+#include "MIDIEvents.h"
+#include "MIDIFile.h"
+
+class Sequencer:public MIDIEvents{
+    public:
+	Sequencer();
+	~Sequencer();
+	
+	//theese functions are called by the master and are ignored if the recorder/player are stopped
+	void recordnote(char chan, char note, char vel);
+	void recordcontroller(char chan,unsigned int type,int par);
+	
+	//this is only for player
+	//it returns 1 if this must be called at least once more
+	//it returns 0 if there are no more notes for the current time
+	//or -1 if there is no note
+	int getevent(char ntrack, int *midich,int *type,int *par1, int *par2);
+
+	//returns 0 if ok or -1 if there is a error loading file
+	int importmidifile(char *filename);	
+	
+	void startplay();
+	void stopplay();
+	
+
+	int play;	
+	int playspeed;//viteza de rulare (0.1x-10x), 0=1.0x, 128=10x
+	void setplayspeed(int speed);
+	
+    private:
+    
+	MIDIFile midifile;
+
+    /* Timer */
+    struct timestruct{
+	double abs;//the time from the begining of the track
+	double rel;//the time difference between the last and the current event
+	double last;//the time of the last event (absolute, since 1 Jan 1970)
+	//theese must be double, because the float's precision is too low
+	//and all theese represents the time in seconds
+    } playtime[NUM_MIDI_TRACKS];
+    
+    void resettime(timestruct *t);
+    void updatecounter(timestruct *t);//this updates the timer values
+
+    /* Player only*/
+
+    struct {
+	event ev;
+	double time;
+    } nextevent[NUM_MIDI_TRACKS];    
+    
+    double realplayspeed;
+    
+};
+
+
+#endif
+
-- 
cgit v1.2.3