// This effect Copyright (C) 2004 and later Cockos Incorporated
// License: GPL - http://www.gnu.org/licenses/gpl.html
desc:sound effect player
slider1:/sound_fx:none:Sound Effect
slider2:0<-120,12,1>volume (dB)
slider3:1<-8,8,0.1>play speed (can be negative)
slider4:1<0,10,1>start/stop trigger
slider5:0<0,1,1{one-shot,loop}>playback mode
slider6:10<0,1000,10>loop edge overlap (ms)


@init
isplay=playpos=0;
mem_len=0;
mem_nch=1;
lslider1=-1;

@slider

lslider1 != slider1 ? 
(
  lslider1 = slider1;
  myfile=file_open(slider1);
  myfile > 0 ? 
  (
    file_riff(myfile,mem_nch,mem_srate);
    playpos=0;
    mem_nch>0?
    (
      act_len=file_avail(myfile);
      (act_len > 1048576 && mem_nch == 2) ? 
      (
        act_len *= 0.5;
        act_len = min(act_len|0,1048576);
        mem_nch=1;
        mem_len=act_len;
        i=0;
        loop(mem_len, 
          file_var(myfile,i[0]);
          file_var(myfile,tmp); // skip right channel
          i+=1;
        );
      )
      :
      (
        act_len = min(act_len,1048576);
        mem_len=act_len/mem_nch;  
        file_mem(myfile,0,act_len); 
      ); 
      skip_ol=1;
    ) : mem_len=0;

    file_close(myfile);
  );
);



playmix=2 ^ (slider2/6);
trigstart=2 ^ (slider4|0);
playspeed=slider3*mem_srate/srate;
doloop=slider5;
olsize=doloop?  srate*slider6/1000 : 0;

@block
  trigger&trigstart ? 
  ( 
    isplay ? (
      isplay=0;
    ) : (
      isplay=1;
      skip_ol=1;
      playpos=playspeed<0 ? mem_len+playspeed*2 : 0;
    );
  );

@sample

isplay ? (  
  ipp=playpos|0;
  pp=playpos-ipp;
  offs=ipp*mem_nch;

  s0 = (offs[0] * (1-pp) + offs[mem_nch]*pp);
  (mem_nch == 2) ? (s1 = (offs[1] * (1-pp) + offs[1+mem_nch]*pp)) : (s1=s0);

  playpos < olsize && !skip_ol ? 
  (
    sc=playpos/olsize;
    s0*=sc;
    s1*=sc;
    offs += (mem_len - (olsize|0))*mem_nch;
    
    t0 = (offs[0] * (1-pp) + offs[mem_nch]*pp) * (1-sc); 
    s0+=t0;
    (mem_nch == 2) ? 
       (s1 += (offs[1] * (1-pp) + offs[1+mem_nch]*pp)*(1-sc)) 
     : (s1+=t0);

  );

  spl0+=s0*playmix;
  spl1+=s1*playmix;

  playpos += playspeed;
  playpos >= mem_len-olsize ? 
  (
    doloop ? (skip_ol=0; playpos -= mem_len-olsize) : isplay=0;
  ) :
   playpos < 0 ? 
  (
    doloop ? (skip_ol=0; playpos += mem_len-olsize) : isplay=0;
  );
);
