commit 4bd0ea6052648d1b133b2aad305f0df97c07d0bb
parent 69717ad21f66aec894a0eb588076efd0644aac36
Author: paulnasca <paulnasca>
Date: Mon, 8 Dec 2003 20:53:13 +0000
Started to make zynaddsubfx rt-safe (but not completed)
Diffstat:
11 files changed, 159 insertions(+), 33 deletions(-)
diff --git a/ChangeLog b/ChangeLog
@@ -497,5 +497,8 @@
26 Nov 2003 - Continuat de scris sequencerul - inceput sa scriu inregistrarea (fara timer)
27 Nov 2003 - Se poate inregistra (dar nu rula) - adaugat timerul de inregistrat
- Frecventa maxima al filtrelor este de Nyquist-500.0 pentru a evita instabilitatea filtrelor
-28 Nov 2003 - Adaugata favorizarea portamento-ului in sus sau un jos; ex. se poate face ca portamento-ul sa fie doar in sus, sa portamento-ul in jos sa fie mai scurt decat cel in jos
- - Inceput sa pun pe cvs la cvs.sourceforge.net
-\ No newline at end of file
+28 Nov 2003 - Adaugata favorizarea portamento-ului in sus sau un jos; ex. se poate face ca portamento-ul sa fie doar in sus, sau portamento-ul in jos sa fie mai scurt decat cel in jos
+ - Inceput sa pun pe cvs la cvs.sourceforge.net
+01 Dec 2003 - Am facut niste mici modificari ca urmare a unui bug-report
+05 Dec 2003 - Facute cateva modificari la jack
+08 Dec 2003 - Inceput sa incerc sa fac rt-safe sub jack, dar in stadiul actual suportul jack este nefunctional
+\ No newline at end of file
diff --git a/examples/14.71280603.mas_zyn b/examples/14.71280603.mas_zyn
Binary files differ.
diff --git a/src/Makefile b/src/Makefile
@@ -11,7 +11,7 @@ CXXFLAGS += -DOS_$(OS_PORT) -D$(MIDIIN)MIDIIN -D$(AUDIOOUT)AUDIOOUT -DFFTW_VERSI
export CXXFLAGS
LIBS= -lm `fltk-config --ldflags`
-ifeq ($(FFT_VERSION),2)
+ifeq ($(FFTW_VERSION),2)
LIBS += -lrfftw -lfftw
else
LIBS += -lfftw3
diff --git a/src/Misc/Dump.C b/src/Misc/Dump.C
@@ -48,20 +48,18 @@ void Dump::startnow(){
if (config.cfg.DumpNotesToFile!=0){
if (config.cfg.DumpAppend!=0) file=fopen(config.cfg.DumpFile,"a");
else file=fopen(config.cfg.DumpFile,"w");
-
- if (file==NULL) return;
- };
- if (config.cfg.DumpAppend!=0) fprintf(file,"#************************************\n");
+ if (file==NULL) return;
+ if (config.cfg.DumpAppend!=0) fprintf(file,"#************************************\n");
- time_t tm=time(NULL);
-
-
- fprintf(file,"#date/time = %s\n",ctime(&tm));
- fprintf(file,"#1 tick = %g milliseconds\n",SOUND_BUFFER_SIZE*1000.0/SAMPLE_RATE);
- fprintf(file,"SAMPLERATE = %d\n",SAMPLE_RATE);
- fprintf(file,"TICKSIZE = %d #samples\n",SOUND_BUFFER_SIZE);
- fprintf(file,"\n\nSTART\n");
+ time_t tm=time(NULL);
+
+ fprintf(file,"#date/time = %s\n",ctime(&tm));
+ fprintf(file,"#1 tick = %g milliseconds\n",SOUND_BUFFER_SIZE*1000.0/SAMPLE_RATE);
+ fprintf(file,"SAMPLERATE = %d\n",SAMPLE_RATE);
+ fprintf(file,"TICKSIZE = %d #samples\n",SOUND_BUFFER_SIZE);
+ fprintf(file,"\n\nSTART\n");
+ };
};
void Dump::inctick(){
diff --git a/src/Misc/Master.C b/src/Misc/Master.C
@@ -213,6 +213,18 @@ void Master::partonoff(int npart,int what){
*/
void Master::AudioOut(REALTYPE *outl,REALTYPE *outr){
int i,npart,nefx;
+
+ //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);
+
+ if (again<=0) break;
+ };
+ //test end
+
//Swaps the Left channel with Right Channel (if it is asked for)
if (swaplr!=0){
diff --git a/src/Output/JACKaudiooutput.C b/src/Output/JACKaudiooutput.C
@@ -20,21 +20,45 @@
*/
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+#include <unistd.h>
#include "JACKaudiooutput.h"
Master *jackmaster;
jack_client_t *jackclient;
jack_port_t *outport_left,*outport_right;
+jack_ringbuffer_t *rb=NULL;
+REALTYPE *jackoutl,*jackoutr;
+int jackfinish=0;
+
+void *thread_blocked(void *arg);
int jackprocess(jack_nframes_t nframes,void *arg);
int jacksrate(jack_nframes_t nframes,void *arg);
void jackshutdown(void *arg);
+pthread_cond_t more_data=PTHREAD_COND_INITIALIZER;
+pthread_mutex_t zyn_thread_lock=PTHREAD_MUTEX_INITIALIZER;
+
+pthread_t bthr;
+
+
void JACKaudiooutputinit(Master *master_){
jackmaster=master_;
jackclient=0;
char tmpstr[100];
+ jackoutl=new REALTYPE [SOUND_BUFFER_SIZE];
+ jackoutr=new REALTYPE [SOUND_BUFFER_SIZE];
+
+ int rbbufsize=SOUND_BUFFER_SIZE*sizeof (REALTYPE)*2*2;
+ printf("%d\n",rbbufsize);
+ rb=jack_ringbuffer_create(rbbufsize);
+ memset(rb->buf,rbbufsize,0);
+
+
for (int i=0;i<15;i++){
if (i!=0) snprintf(tmpstr,100,"ZynAddSubFX_%d",i);
else snprintf(tmpstr,100,"ZynAddSubFX");
@@ -64,6 +88,8 @@ void JACKaudiooutputinit(Master *master_){
fprintf(stderr,"Cannot activate jack client\n");
exit(1);
};
+
+ pthread_create(&bthr,NULL,thread_blocked,NULL);
/*
jack_connect(jackclient,jack_port_name(outport_left),"alsa_pcm:out_1");
@@ -71,19 +97,60 @@ void JACKaudiooutputinit(Master *master_){
*/
};
+void *thread_blocked(void *arg){
+ int datasize=SOUND_BUFFER_SIZE*sizeof (REALTYPE);
+
+ pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL);
+ pthread_mutex_lock(&zyn_thread_lock);
+
+ while (jackfinish==0){
+ while (jack_ringbuffer_write_space(rb)>=datasize){
+ pthread_mutex_lock(&jackmaster->mutex);
+ jackmaster->GetAudioOutSamples(SOUND_BUFFER_SIZE,jack_get_sample_rate(jackclient),jackoutl,jackoutr);
+ pthread_mutex_unlock(&jackmaster->mutex);
+
+ jack_ringbuffer_write(rb, (char *) jackoutl,datasize);
+ jack_ringbuffer_write(rb, (char *) jackoutr,datasize);
+ };
+ pthread_cond_wait(&more_data,&zyn_thread_lock);
+ };
+ pthread_mutex_unlock(&zyn_thread_lock);
+
+ return(0);
+};
+
+
int jackprocess(jack_nframes_t nframes,void *arg){
jack_default_audio_sample_t *outl=(jack_default_audio_sample_t *) jack_port_get_buffer (outport_left, nframes);
jack_default_audio_sample_t *outr=(jack_default_audio_sample_t *) jack_port_get_buffer (outport_right, nframes);
- pthread_mutex_lock(&jackmaster->mutex);
- jackmaster->GetAudioOutSamples(nframes,jack_get_sample_rate(jackclient),outl,outr);
- pthread_mutex_unlock(&jackmaster->mutex);
+ int datasize=nframes*sizeof (REALTYPE);
+// printf("%d\n",nframes);
+ if (jack_ringbuffer_read_space(rb)>=datasize){
+ jack_ringbuffer_read(rb, (char *) outl,datasize);
+ jack_ringbuffer_read(rb, (char *) outr,datasize);
+ } else {//the ringbuffer is empty or there are too small amount of samples in it
+ for (int i=0;i<nframes;i++){
+ outl[i]=0.0;outr[i]=0.0;
+ };
+ };
+
+ if (pthread_mutex_trylock(&zyn_thread_lock)==0){
+ pthread_cond_signal(&more_data);
+ pthread_mutex_unlock(&zyn_thread_lock);
+ };
return(0);
};
void JACKfinish(){
+ jackfinish=1;
+ jack_ringbuffer_free(rb);
jack_client_close(jackclient);
+
+ usleep(100000);
+ delete(jackoutl);
+ delete(jackoutr);
};
int jacksrate(jack_nframes_t nframes,void *arg){
diff --git a/src/Output/JACKaudiooutput.h b/src/Output/JACKaudiooutput.h
@@ -23,6 +23,9 @@
#define JACK_AUDIO_OUTPUT_H
#include <jack/jack.h>
+extern "C" {
+#include <jack/ringbuffer.h>
+};
#include "../globals.h"
#include "../Misc/Master.h"
diff --git a/src/Seq/Sequencer.C b/src/Seq/Sequencer.C
@@ -47,6 +47,7 @@ Sequencer::Sequencer(){
resettime(&rectime);
resettime(&playtime);
+ nextevent.time=-1.0;//must be less than 0
};
Sequencer::~Sequencer(){
@@ -118,11 +119,6 @@ void Sequencer::startplay(){
//test - canalul 1, deocamdata
rewindlist(&midichan[0].track);
- printf("\n\n===================================");
- do {
- readevent(&midichan[0].track,&tmpevent);
- printf("Play note %d %d \n",tmpevent.par1,tmpevent.par2);
- } while(tmpevent.type>=0);
};
void Sequencer::stopplay(){
@@ -130,6 +126,30 @@ void Sequencer::stopplay(){
play=0;
};
+/************** Player stuff ***************/
+
+int Sequencer::getevent(char chan,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);
+ else return(-1);
+ if (nextevent.ev.type==-1) return(-1);
+
+ *type=nextevent.ev.type;
+ *par1=nextevent.ev.par1;
+ *par2=nextevent.ev.par2;
+
+ double dt=nextevent.ev.deltatime*0.001;
+ nextevent.time+=dt;
+
+ printf("%f - %d %d \n",nextevent.time,par1,par2);
+ return(0);//?? sau 1
+};
+
+
/************** Track stuff ***************/
diff --git a/src/Seq/Sequencer.h b/src/Seq/Sequencer.h
@@ -33,8 +33,12 @@ class 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);
- //int playnote(char &chan, char ¬e, char &vel);//returns 1 if somehing must be played
- //(if returns 1) you need to call it until returns 0
+
+ //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 chan, int *type,int *par1, int *par2);
//UI controlling functions
@@ -48,11 +52,12 @@ class Sequencer{
private:
+
/* Events */
struct event{
int deltatime;
- int type,par1,par2;//type=1 for note,2 for controller
- }tmpevent;
+ int type,par1,par2;//type=1 for note, type=2 for controller
+ } tmpevent;
struct listpos{
event ev;
struct listpos *next;
@@ -85,7 +90,13 @@ class Sequencer{
void resettime(timestruct *t);
void updatecounter(timestruct *t);//this updates the timer values
-
+
+ /* Player only*/
+
+ struct {
+ event ev;
+ double time;
+ } nextevent;
};
#endif
diff --git a/src/UI/PartUI.fl b/src/UI/PartUI.fl
@@ -465,7 +465,7 @@ maxkcounter->do_callback();}
}
Fl_Window ctlwindow {
label Controllers
- private xywh {24 405 420 130} hide
+ private xywh {46 404 420 130} hide
} {
Fl_Check_Button {} {
label Expr
@@ -581,7 +581,7 @@ if (part->ctl.sustain.receive==0) {
xywh {310 50 55 15} labelsize 10 align 16
}
Fl_Dial {} {
- label {t.up/dn}
+ label {t.dn/up}
callback {int x=(int) o->value();
part->ctl.portamento.updowntimestretch=x;} selected
diff --git a/src/main.C b/src/main.C
@@ -60,7 +60,7 @@ extern Dump dump;
#include "UI/MasterUI.h"
MasterUI *ui;
-pthread_t thr1,thr2,thr3;
+pthread_t thr1,thr2,thr3,thr4;
Master *master;
int swaplr=0;//1 for left-right swapping
@@ -170,6 +170,18 @@ void *thread3(void *arg){
return(0);
};
+/*
+ * Sequencer thread (test)
+ */
+void *thread4(void *arg){
+ while (Pexitprogram==0){
+ pthread_mutex_lock(&master->mutex);
+//?????????????????????????????????????????????
+ pthread_mutex_unlock(&master->mutex);
+ };
+
+ return(0);
+};
/*
* Program initialisation
@@ -227,8 +239,8 @@ void exitprogram(){
PAfinish();
#endif
- delete(Midi);
delete(ui);
+ delete(Midi);
delete(denormalkillbuf);
// pthread_mutex_unlock(&master->mutex);