
/********************** FUNKY.MM ****************************************/
/* Functions for processing MIDI musical interface data */
			
/**** functions to copy data between tracks in RAM ***/
record(knobs)	/* copies all data from mpu in buffer, expects it to refill */
struct knob_space *knobs;
{uchar *innie, *outie;	/* ptr to input, output byte locations */
			/* don't change input, output ptrs - pt to byte 0 */
 
 /* if this is the first call, set F8 key to start recording */
 if(!knobs->value[0])	 /* value[0] used internally as flag */
   {if(board[knobs->slot].in == MPU_IN)  /* only if input is MPU-401 */
     {strcpy(root[8].descrip,"Start recording    "); /* set F8 in root menu */
      root[8].doit = start_rec; 		/* to function in MPU401.MM */
      }   
    knobs->value[0] = 1;      /* show set-up done, don't repeat */
    return(0);		       /* wait for F8 to start actual recording */
    }

 /* record only when data is available in input track */
 if(!*knobs->inctr)  return(0);

 innie = knobs->input; /* input starts at byte 0 */
 outie = knobs->output + *knobs->outctr;  /* output after last byte filled */
	   /* recalc each call because others may be affecting track count */
 while(*knobs->inctr)	 /* active data in input track */
      {if(outie > knobs->endout)
	 {fprintf(stdout,"Track %d (%s) is filled.  Recording paused.\n",
	    board[knobs->slot].out,tracks[board[knobs->slot].out].tlabel);
	  board[knobs->slot].active = 0;  /* deactivate unit */
	  movmem(innie,knobs->input,*knobs->inctr);  /* slide remaining data
						   to start of input track */
	  return(0);
	  }
       else /* record byte, input->output tracks */
	 {*outie = *innie;	      /* copy value of ptr locations */
	  outie++; innie++;	      /* move pointers */
	  (*knobs->outctr)++;	      /* increment output counter */
	  (*knobs->inctr)--;	      /* decrement input counter */
	  }
       }  /* end of recording loop */

 return(0);
 }  /* End of record() */

play(knobs)	 /* copies track data to mpu out, expects it to be emptied */
struct knob_space *knobs;
{uchar *outie;	/* ptr to output byte location */
 
 /* if this is the first call, set F9 key to start playing */
 if(!knobs->value[0])	 /* value[0] used internally as flag */
   {if((board[knobs->slot].out >= MPU_OUT_0) && 
     (board[knobs->slot].out <= MPU_OUT_7))  /* only for feeding MPU tracks */
     {strcpy(root[9].descrip,"Start playing track"); /* set F9 in root menu */
      root[9].doit = start_play;		/* to function in MPU401.MM */
      root[9].doarg |= (1 << (board[knobs->slot].out - 1));   /* set track */
      } 
    knobs->value[0] = 1;       /* show set-up done, don't repeat */
    return(0);			/* wait for F9 to start actual play */
    }

 outie = knobs->output + *knobs->outctr;  /* output after last byte filled */
 
 while(outie <= knobs->endout)	 /* still room in output track */
      {if(knobs->value[1] > *knobs->inctr)
	 {fprintf(stdout,"Track %d (%s) is played out.  Play paused.\n",
	    board[knobs->slot].in,tracks[board[knobs->slot].in].tlabel);
	  board[knobs->slot].active = 0;  /* deactivate unit */
	  return(0);
	  }
       else /* record byte, input->output tracks */
	 {*outie = *knobs->input;     /* copy value of ptr locations */
	  outie++; knobs->input++;    /* move pointers */
	  (*knobs->outctr)++;	      /* increment output counter */
	  knobs->value[1]++;	      /* incr byte counter in knobs */
	  }
       }  /* end of play loop */

 return(0);
 }  /* End of play */

/*** functions to copy between disk and RAM tracks ***/
rec_to_disk(knobs)   /* copies all data from input buffer to disk */
struct knob_space *knobs;
{uchar *innie; 
 
 if(!*knobs->inctr)  return(0);
 innie = knobs->input; /* input starts at byte 0 */

 while(*knobs->inctr)	 /* active data in input track */
      {if(fputc(*innie,knobs->output) == EOF)
	 {fprintf(stdout,"Track %d (%s) is filled.  Recording paused.\n",
	    board[knobs->slot].out,tracks[board[knobs->slot].out].tlabel);
	  board[knobs->slot].active = 0;  /* deactivate unit */
	  movmem(innie,knobs->input,*knobs->inctr);  /* slide remaining data
						   to start of input track */
	  return(0);
	  }
       else /* byte copied to disk, update ptrs */
	 {innie++;	      /* move pointers */
	  (*knobs->outctr)++;	      /* increment output counter */
	  (*knobs->inctr)--;	      /* decrement input counter */
	  }
       }  /* end of recording loop */

 return(0);
 }  /* End of rec_to_disk */

play_from_disk(knobs)	 /* copies disk file to RAM track as it empties */
struct knob_space *knobs;
{uchar *outie, data; 
 outie = knobs->output + *knobs->outctr;  /* output after last byte filled */
 
 while(outie <= knobs->endout)	 /* still room in output track */
      {data = fgetc(knobs->input);  /* get byte from disk file */
       if(data == -1)  /* EOF or error */
	 {fprintf(stdout,"Track %d (%s) is played out.  Play paused.\n",
	    board[knobs->slot].in,tracks[board[knobs->slot].in].tlabel);
	  board[knobs->slot].active = 0;  /* deactivate unit */
	  return(0);
	  }
       else /* record byte, disk->output tracks */
	 {*outie = data;     /* put data byte in output track */
	  outie++;    /* move pointers */
	  (*knobs->outctr)++;	      /* increment output counter */
	  }
       }  /* end of play loop */

 return(0);
 }  /* End of play_from_disk */
