head	1.4;
access;
symbols
	rel-0-2-1:1.3
	before_adj_struct:1.3
	jack:1.3.0.2
	rel-0-1-0:1.2
	rel-0-0-0:1.1;
locks; strict;
comment	@ * @;


1.4
date	2007.03.22.20.55.43;	author robertatwood;	state Exp;
branches;
next	1.3;

1.3
date	2005.08.20.18.26.42;	author robertatwood;	state Exp;
branches;
next	1.2;

1.2
date	2005.04.03.20.05.39;	author robertatwood;	state Exp;
branches;
next	1.1;

1.1
date	2004.04.16.11.36.56;	author robertatwood;	state Exp;
branches;
next	;


desc
@@


1.4
log
@Updated GPL text to reflect new address of Free Software foundation
Prepare to move repository to savannah.nongnu.org
@
text
@/**************************************************************
This file is part of the Variseq program.
Variseq -- a variable pitch and step sample sequencer
Copyright (C) 2004  Robert Atwood r.atwood (at) imperial (dot) ac (dot) uk

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

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 for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 
See the file COPYING for more information
**************************************************************/


#include <stdio.h>
#include "constants.h" /* #defined constants should be in here */
#include "mysound.h"
#include "pattern.h"

/* get a reference tothe global sound buffer */
/* TODO: get rid of this somehow*/
extern sbuf mysound;

/* initialize a pattern with defaults */
/* n=number of notes s=speed of pattern */
void pattern::init_pattern(int n,int s){
      int i;
      nnotes=n;
      /* create an array of notes */
      /* and set up the pointers and default values */
      notes = new note[n];
      for (i=0;i<nnotes;i++){
         notes[i].mynum(i);
         notes[i].setparent(this);
         notes[i].next = (notes + ((i+1)%nnotes));
         notes[i].prev = (notes + ((i-1)%nnotes));
         notes[i].setticks(D_NTICKS); 
      }
      vol=1;
      pan=0.5;
      smooth = 1.0;
      calcticks();
      setspeed(s);
};

/* figure out how many total ticks in the whole pattern */
/* note: a tick is the minimum allowed division of the beat*/
void pattern::calcticks(){
   int i;
   totalticks=0;
   for (i=0;i<nnotes;i++){
       notes[i].setstarttick(totalticks);
       totalticks += notes[i].ticks;
   }
}

/* calcframes figures how many frames in each note, and in the whole pattern */
/* then expands the array to the correct number of frames */
/* a frame is the minimum time unit in the digitized signal */
/* it better be somewhat smaller than a tick */

void pattern::calcframes(){
       int i;

       frames_per_tick=(int)floor((44100 * 60 /(D_NTICKS*4*speed)));
       if (frames_per_tick <= MINFRAMES){
           fprintf(stderr,"WARNING: frames_per_tick too small!");
           fprintf(stderr,"frames_per_tick %i",frames_per_tick);
           if (frames_per_tick <= 0){
              fprintf(stderr,"ERROR: frames_per_tick zero, set to 1");
              frames_per_tick = 1;
           }
       }
       frames_per_note=D_NTICKS*frames_per_tick;
       totalframes = frames_per_tick * totalticks;

		for (i=0;i<nnotes;i++){
			 notes[i].setframes(frames_per_tick);
			 /* notes::setsmooth calculates the absolute frames */
			 /* of smoothing , so it needs to be called when the speed */
			 /* is changed */
			 notes[i].setsmooth(smooth);
		}
   
   expand_sbuf(&mysound,totalframes);
   write(&mysound,0);
};

/* change the tailoff smoothing of the whole pattern */
/* that is applied at the end of each note */
void pattern::setsmooth(float s){
   int i;
   smooth=s;
   for (i=0;i<nnotes;i++){
       notes[i].setsmooth(smooth);
   }
   /* global change, so rewrite the buffer */
   write(&mysound,0);
}

/* change the speed, then recalculate the number of frames */
void pattern::setspeed(float s){
   speed=s;
   calcframes();
}

/* change the number of ticks in one specific note */
void pattern::change_note_length(int nn, int nl){
    #ifndef NOPRINT
    printf("Changing note %i ticks %i \n",nn,nl);
    #endif
    notes[nn].setticks(nl);
    calcticks();
    calcframes();
}
    

/* write the pattern into the sound buffer */
void pattern::write(sbuf * buffer,int start){
     int i;
     #ifdef DUMPSTATE
		  printf("Note states before\n");
		  for (i=0;i<nnotes;i++){
				printf("%i:%i ",i,notes[i].state);
		  }
		  printf("\n");
     #endif /* DUMPSTATE */
     for (i=0;i<nnotes;i++){
         notes[i].write(buffer);
     }
     #ifdef DUMPSTATE
		  printf("Note states middle\n");
		  for (i=0;i<nnotes;i++){
				printf("%i:%i ",i,notes[i].state);
		  }
		  printf("\n");
     #endif /* DUMPSTATE */
     for (i=0;i<nnotes;i++){
         notes[i].overwrite(buffer);
     }
     #ifdef DUMPSTATE
		  printf("Note states after\n");
		  for (i=0;i<nnotes;i++){
				printf("%i:%i ",i,notes[i].state);
		  }
		  printf("\n\n");
     #endif /* DUMPSTATE */

 }

/* write the specified note into the sound buffer */
void pattern::writenote(sbuf * buffer,int notenum){
     /*
     notes[notenum].write(buffer);
     */
     /* replace all write note operations with write pattern */
     write(buffer,0);
}

 /* save the pattern to a file */
 void pattern::savepat(FILE * fp){
     int i;      
      char hdr[32];
      char tlr[32];
      memset(hdr,0,32);
      memset(tlr,0,32);
      snprintf(hdr,32,"pattern of %i notes\n",nnotes);
      snprintf(tlr,32,"end of pattern\n");
      fwrite(hdr,sizeof(char),32,fp);
     fwrite (this,sizeof(patpub),1,fp);
     for (i=0;i<nnotes;i++){
        notes[i].savenote(fp);
     }
     fwrite(tlr,sizeof(char),32,fp);
  }
 /* load the pattern from a file */
 void pattern::loadpat(FILE * fp){
     int i;
     int n_load;
     patpub inpat;
      char hdr[32];
      char tlr[32];
      fread(hdr,sizeof(char),32,fp);
      printf("%s",hdr);

     fread (&inpat,sizeof(patpub),1,fp);
     n_load = (inpat.nnotes > this->nnotes)?this->nnotes:inpat.nnotes;

     setvol(inpat.vol);
     setpan(inpat.pan);
     for (i=0;i<n_load;i++){
        notes[i].loadnote(fp);
     }
     calcticks();
     setspeed(inpat.speed);
     fread(tlr,sizeof(char),32,fp);
     printf("%s",tlr);
  }

/* print a human-readable list of the pattern */
void pattern::dumppat(FILE *fp){
    int i;
    fprintf(fp,"nnotes %i\n",nnotes);

    fprintf(fp,"vol %f\n",vol);
    fprintf(fp,"pan %f\n",pan);
    fprintf(fp,"speed %f\n",speed);
    fprintf(fp,"smooth %f\n",smooth);

    fprintf(fp,"my_num %i\n",my_num);
    fprintf(fp,"frames_per_note %i\n",frames_per_note);
    fprintf(fp,"frames_per_tick %i\n",frames_per_tick);
    fprintf(fp,"totalframes %i\n",totalframes);
    fprintf(fp,"totalticks %i\n",totalticks);
    fprintf(fp,"***************************\n");
    for (i=0;i<nnotes;i++){
       fprintf(fp,"Note %i\n\n",i);
       notes[i].dumpnote(fp);
    }
}
/* $Id: pattern.C,v 1.3 2005/08/20 18:26:42 robertatwood Exp $ */
@


1.3
log
@Added a save/restore workspace function
Added window to display names of samples
@
text
@d18 1
a18 1
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
d22 1
d229 1
a229 1
/* $Id: pattern.C,v 1.3 2005/08/04 22:36:27 robert Exp $ */
@


1.2
log
@Changed the buffer writing so that samples extend into unused notes.
Altered file choose usage to correctly use the FLTK chooser
@
text
@d169 8
a176 1
     int i;
d181 1
d188 5
d203 2
d228 1
a228 1
/* $Id: pattern.C,v 1.2 2005/04/03 19:05:10 robert Exp $ */
@


1.1
log
@Initial version uploaded to Sourceforge
@
text
@d23 1
a23 1
#include "constants.h"
d27 2
d31 2
d36 2
d42 3
a44 1
         notes[i].setticks(8);
d53 2
d64 5
d72 10
a81 2
       frames_per_tick=(int)floor((44100 * 60 /(8*4*speed)));
       frames_per_note=8*frames_per_tick;
a85 3
			 /*
			 notes[i].rlen = frames_per_note;
			 */
d96 2
d108 1
d114 1
d125 1
d128 7
d138 18
d158 1
d160 1
d162 3
d192 1
d213 1
a213 1
/* $Id: pattern.C,v 1.9 2004/04/12 13:22:33 robert Exp $ */
@

