
//
//    Min: sfront test program, exercises many parts of Structured Audio spec
//    Copyright (C) 2000 Regents of the University of California
//
//    This license also covers the SASL file in this directory.
//
//    This program is free software; you can redistribute it and/or modify
//    it under the terms of the GNU General Public License (Version 2) 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 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//    Maintainer: John Lazzaro, lazzaro@cs.berkeley.edu
//


// min.saol
// Test program 
// Written by John Lazzaro
// song length: 4 seconds
//
// Basic goal of this test program is to exercise large
// parts of the SA language without using any core opcodes
// or wavetable generators. 
//

global {

srate 44100;
krate 100;
route(trem_bus,square);
send (tremelo; 2000, 0.01 ; trem_bus);
sequence (sawtooth, square);

}

//
// Tremelo unit -- simplest effects unit
//

instr tremelo (starthalfperiod,startdepth) {
   asig count;
   ksig kinit;
   ksig halfperiod;
   ksig depth;

   if (!kinit) {
    kinit = 1;
    halfperiod = starthalfperiod;
    depth = startdepth;
   }

   count = count - 1;
   if (count > 0) {
    output((1+depth)*input[0]);}
   if (count <= 0) {
    output((1-depth)*input[0]);}
   if (count < -halfperiod) { 
    count = halfperiod;}
}

//
// instr square
//
// Square wave oscillator, launches sawtooth 
// dynamically

instr square (starthalfperiod) {
   asig count;
   ksig kinit;
   ksig delta;
   imports ksig halfperiod, stop;

   if (!kinit) {
    kinit = 1;
    halfperiod = starthalfperiod;
   }

   delta = delta + 1;
   
   if ((delta == 4) && (halfperiod > 40)) {
     instr sawtooth (0,dur, halfperiod-1);
    }

   if (stop) { 
    turnoff; 
   }
   count = count + 1;
   if (count > 0) {
     output(0.1);
   }
   if (count <= 0) {
     output(-0.1);
   }
   if (count > halfperiod) {
     count = - halfperiod + 1;
     }

}

//
// Sawtooth oscillator, inline
//

instr sawtooth (starthalfperiod) {
   asig count;
   ksig kinit;
   imports ksig halfperiod, stop;

   if (!kinit) {
    kinit = 1;
    halfperiod = starthalfperiod;
   }

   if (stop) { 
    turnoff; 
   }
   count = count + 1;
   if (count > halfperiod) {
     count = - halfperiod + 1;
   }
   output(0.1*(count/halfperiod));

}

//
// Sawtooth oscillator, uses a user-defined
// opcode.
//

instr sawtwo(starthalfperiod) {
   ksig kinit;
   imports ksig halfperiod, stop;

   if (!kinit) {
    kinit = 1;
    halfperiod = starthalfperiod;
   }

   if (stop) { 
    turnoff; 
   }
   output(count(halfperiod));

}

//
// Helper opcode for instr sawtwo
//

aopcode count(ksig halfperiod) {

asig idx;

idx = idx + 1;
if (idx > halfperiod) {
  idx = - halfperiod + 1;
}


return (0.1*(idx/halfperiod));

}
