commit e88a3f74cf27a981c0127d422e1e9fef492f5e27
parent af0cd14c6307eb570e215173e9bda71ecf0d0204
Author: paulnasca <paulnasca>
Date: Sat, 27 Mar 2004 18:08:59 +0000
*** empty log message ***
Diffstat:
9 files changed, 242 insertions(+), 112 deletions(-)
diff --git a/src/Makefile b/src/Makefile
@@ -52,6 +52,7 @@ subdirs=DSP Effects Input Misc Output Params Synth Seq
all:
$(MAKE) -C UI $@
rm -f Make.deps
+ yes " " | head
@for name in $(subdirs); do sh -c "cd $$name ; $(CXX) -MM -MG -w *.C >> ../Make.deps ; cd .."; done
@for name in $(subdirs); do sh -c "make -C $$name $@"; done
$(MAKE) objs
diff --git a/src/Misc/Master.C b/src/Misc/Master.C
@@ -220,10 +220,10 @@ void Master::AudioOut(REALTYPE *outl,REALTYPE *outr){
//test!!!!!!!!!!!!! se poate bloca aici (mutex)
while (1){
- int type,par1,par2,again;
- char chan=0;//deocamdata
- again=seq.getevent(chan,&type,&par1,&par2);
-// if (type!=0) printf("%d %d %d %d\n",type,chan,par1,par2);
+ int type,par1,par2,again,midichan;
+ char chan=1;//deocamdata
+ again=seq.getevent(chan,&midichan,&type,&par1,&par2);
+ if (type!=0) printf("%d %d %d %d %d\n",type,midichan,chan,par1,par2);
if (again<=0) break;
};
diff --git a/src/Seq/MIDIEvents.C b/src/Seq/MIDIEvents.C
@@ -0,0 +1,73 @@
+/*
+ ZynAddSubFX - a software synthesizer
+
+ MIDIEvents.C - It stores the midi events from midi file or sequencer
+ Copyright (C) 2003-2004 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>
+
+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;
+ 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;
+};
+
+
+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/src/Seq/MIDIEvents.h b/src/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-2004 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
+ } 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/src/Seq/MIDIFile.C b/src/Seq/MIDIFile.C
@@ -30,6 +30,7 @@ MIDIFile::MIDIFile(){
midifilesize=0;
midifilek=0;
midieof=false;
+ me=NULL;
};
MIDIFile::~MIDIFile(){
@@ -69,7 +70,8 @@ int MIDIFile::loadfile(char *filename){
return(0);
};
-int MIDIFile::parsemidifile(){
+int MIDIFile::parsemidifile(MIDIEvents *me_){
+ this->me=me_;
//read the header
int chunk=getint32();//MThd
@@ -77,10 +79,11 @@ int MIDIFile::parsemidifile(){
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 if the format is "0"
+ int ntracks=getint16();//this is always 1 if the format is "0"
printf("ntracks %d\n",ntracks);
int division=getint16();
@@ -91,6 +94,8 @@ int MIDIFile::parsemidifile(){
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();
@@ -102,6 +107,7 @@ int MIDIFile::parsemidifile(){
printf("\nMIDI file succesfully parsed.\n");
// printf("\n0x%x\n",getbyte());
+ this->me=NULL;
return(0);
};
@@ -141,18 +147,18 @@ int MIDIFile::parsetrack(int ntrack){
switch(msg){
case 0x80 ... 0x8f://note on off
- parsenoteon(msg & 0x0f,dt);
+ parsenoteon(ntrack,msg & 0x0f,dt);
dt=0;
break;
case 0x90 ... 0x9f://note on (or note off)
- parsenoteon(msg & 0x0f,dt);
+ parsenoteon(ntrack,msg & 0x0f,dt);
dt=0;
break;
case 0xa0 ... 0xaf://aftertouch - ignored
skipnbytes(2);
break;
case 0xb0 ... 0xbf://control change
- parsecontrolchange(msg & 0x0f,dt);
+ parsecontrolchange(ntrack,msg & 0x0f,dt);
dt=0;
break;
case 0xc0 ... 0xcf://program change - ignored
@@ -201,26 +207,43 @@ int MIDIFile::parsetrack(int ntrack){
};
-void MIDIFile::parsenoteoff(char chan,unsigned int dt){
+void MIDIFile::parsenoteoff(char ntrack,char chan,unsigned int dt){
unsigned char note,vel;
note=getbyte();
if (chan>=NUM_MIDI_CHANNELS) return;
+ me->tmpevent.deltatime=convertdt(dt);
+ me->tmpevent.type=1;
+ me->tmpevent.par1=note;
+ me->tmpevent.par2=0;
+
+
+ ///test
+ ntrack=0;
+
+ me->writeevent(&me->miditrack[ntrack].record,&me->tmpevent);
+
printf("Note off:%d ",note);
};
-void MIDIFile::parsenoteon(char chan,unsigned int dt){
+void MIDIFile::parsenoteon(char ntrack,char chan,unsigned int dt){
unsigned char note,vel;
note=getbyte();
vel=getbyte();
if (chan>=NUM_MIDI_CHANNELS) return;
+ me->tmpevent.deltatime=convertdt(dt);
+ me->tmpevent.type=1;
+ me->tmpevent.par1=note;
+ me->tmpevent.par2=vel;
+ me->writeevent(&me->miditrack[ntrack].record,&me->tmpevent);
+
printf("[dt %d ] Note on:%d %d\n",dt,note,vel);
};
-void MIDIFile::parsecontrolchange(char chan,unsigned int dt){
+void MIDIFile::parsecontrolchange(char ntrack,char chan,unsigned int dt){
unsigned char control,value;
control=getbyte();
value=getbyte();
@@ -229,9 +252,15 @@ void MIDIFile::parsecontrolchange(char chan,unsigned int dt){
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->writeevent(&me->miditrack[ntrack].record,&me->tmpevent);
+
};
-void MIDIFile::parsepitchwheel(char chan, unsigned int dt){
+void MIDIFile::parsepitchwheel(char ntrack,char chan, unsigned int dt){
unsigned char valhi,vallo;
vallo=getbyte();
valhi=getbyte();
@@ -254,6 +283,12 @@ void MIDIFile::parsemetaevent(unsigned char mtype,unsigned char mlength){
};
+unsigned int MIDIFile::convertdt(unsigned int dt){
+ double result=dt;
+
+ return((int) (result*3.0));
+};
+
void MIDIFile::clearmidifile(){
if (midifile!=NULL) delete(midifile);
diff --git a/src/Seq/MIDIFile.h b/src/Seq/MIDIFile.h
@@ -24,6 +24,7 @@
#define MIDIFILE_H
#include "../globals.h"
+#include "MIDIEvents.h"
class MIDIFile{
public:
@@ -34,9 +35,11 @@ class MIDIFile{
int loadfile(char *filename);
//returns -1 if there is an error, otherwise 0
- int parsemidifile();
+ int parsemidifile(MIDIEvents *me_);
private:
+ MIDIEvents *me;
+
unsigned char *midifile;
int midifilesize,midifilek;
bool midieof;
@@ -44,13 +47,16 @@ class MIDIFile{
//returns -1 if there is an error, otherwise 0
int parsetrack(int ntrack);
- void parsenoteoff(char chan,unsigned int dt);
- void parsenoteon(char chan,unsigned int dt);
- void parsecontrolchange(char chan,unsigned int dt);
- void parsepitchwheel(char chan, unsigned int dt);
+ 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 clearmidifile();
+
+ //convert the delta-time to internal format
+ unsigned int convertdt(unsigned int dt);
/* Low Level MIDIfile functions */
@@ -74,6 +80,7 @@ class MIDIFile{
struct {
double tick;//how many seconds one tick has
+
}data;
};
diff --git a/src/Seq/Makefile b/src/Seq/Makefile
@@ -1,6 +1,6 @@
include ../Makefile.inc
-objects=MIDIFile.o Sequencer.o
+objects=MIDIEvents.o MIDIFile.o Sequencer.o
all: $(objects)
diff --git a/src/Seq/Sequencer.C b/src/Seq/Sequencer.C
@@ -33,33 +33,44 @@
Sequencer::Sequencer(){
play=0;
- for (int i=0;i<NUM_MIDI_CHANNELS;i++){
- midichan[i].track.first=NULL;
- midichan[i].track.current=NULL;
- midichan[i].track.size=0;
- midichan[i].track.length=0.0;
- midichan[i].record.first=NULL;
- midichan[i].record.current=NULL;
- midichan[i].record.size=0;
- midichan[i].record.length=0.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;
};
resettime(&rectime);
resettime(&playtime);
- nextevent.time=-1.0;//must be less than 0
+ nextevent.time=0.0;//must be less than 0
};
Sequencer::~Sequencer(){
- for (int i=0;i<NUM_MIDI_CHANNELS;i++){
- deletelist(&midichan[i].track);
- deletelist(&midichan[i].record);
+ 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);
- if (midifile.parsemidifile()<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);
};
@@ -71,7 +82,9 @@ void Sequencer::startplay(){
resettime(&playtime);
//test - canalul 1, deocamdata
- rewindlist(&midichan[0].track);
+ for (int i=0;i<NUM_MIDI_TRACKS;i++){
+ rewindlist(&miditrack[i].track);
+ };
};
void Sequencer::stopplay(){
@@ -79,75 +92,35 @@ void Sequencer::stopplay(){
play=0;
};
+// ************ Player stuff ***************
-/************** Player stuff ***************/
-
-int Sequencer::getevent(char chan,int *type,int *par1, int *par2){
+int Sequencer::getevent(char chan,int *midich, int *type,int *par1, int *par2){
*type=0;
if (play==0) return(-1);
updatecounter(&playtime);
- if (nextevent.time>=playtime.abs) readevent(&midichan[chan].track,&nextevent.ev);
+// printf("%g %g\n",nextevent.time,playtime.abs);
+
+ if (nextevent.time<playtime.abs) readevent(&miditrack[chan].track,&nextevent.ev);
else return(-1);
if (nextevent.ev.type==-1) return(-1);
+// printf("********************************\n");
+
+
*type=nextevent.ev.type;
*par1=nextevent.ev.par1;
*par2=nextevent.ev.par2;
+ *midich=nextevent.ev.channel;
double dt=nextevent.ev.deltatime*0.001;
nextevent.time+=dt;
- printf("%f - %d %d \n",nextevent.time,par1,par2);
+// printf("%f - %d %d \n",nextevent.time,par1,par2);
return(0);//?? sau 1
};
-
-/************** Track stuff ***************/
-
-
-void Sequencer::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;
- l->size++;
-};
-
-void Sequencer::readevent(list *l,event *ev){
- if (l->current==NULL) {
- ev->type=-1;
- return;
- };
- *ev=l->current->ev;
- l->current=l->current->next;
-};
-
-
-void Sequencer::rewindlist(list *l){
- l->current=l->first;
-};
-
-void Sequencer::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 Sequencer::deletelistreference(list *l){
- l->current=l->first=NULL;
- l->size=0;
- l->length=0.0;
-};
-
/************** Timer stuff ***************/
void Sequencer::resettime(timestruct *t){
diff --git a/src/Seq/Sequencer.h b/src/Seq/Sequencer.h
@@ -23,9 +23,10 @@
#define SEQUENCER_H
#include "../globals.h"
+#include "MIDIEvents.h"
#include "MIDIFile.h"
-class Sequencer{
+class Sequencer:public MIDIEvents{
public:
Sequencer();
~Sequencer();
@@ -38,7 +39,7 @@ class Sequencer{
//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 chan, int *type,int *par1, int *par2);
+ int getevent(char chan, 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);
@@ -53,32 +54,6 @@ class Sequencer{
MIDIFile midifile;
- /* Events */
- struct event{
- int deltatime;
- int type,par1,par2;//type=1 for note, type=2 for controller
- } 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
- ,record;//the track being recorded
- } midichan[NUM_MIDI_CHANNELS];
-
- void writeevent(list *l,event *ev);
- void readevent(list *l,event *ev);
-
- void rewindlist(list *l);
- void deletelist(list *l);
- void deletelistreference(list *l);
-
/* Timer */
struct timestruct{
double abs;//the time from the begining of the track