
#import <musickit/musickit.h>
#import <objc/List.h>
#import "EchoFilter.h"

#define NUMCHANS 8  
  
@implementation EchoFilter : NoteFilter
  /* A simple note filter that does MIDI echo */
{
    double delay;		    
}

-init
  /* Called automatically when an instance is created. */
{    int i;
     
     [super init]; 
     delay = .1;
     for (i=0;i<=NUMCHANS;i++)  
     	 [self addNoteSender:[[NoteSender alloc] init]];
     [self addNoteReceiver:[[NoteReceiver alloc] init]];
     return self;
 }

-setDelay:(double)delayArg
  /* change the amount of delay (in seconds) between echoes */
{
    delay = delayArg;
    return self;
}

-connectAcross:anInstOrNoteFilter    
  /* Just connects successive NoteSenders of the receivers to successive
     NoteReceivers of anInstOrNoteFilter. */
{
    id pList = [self noteSenders];
    id iList = [anInstOrNoteFilter noteReceivers];
    int i,siz;
    int pSiz = [pList count];
    int iSiz = [iList count];
    siz = (pSiz > iSiz) ? iSiz : pSiz; 
    for (i = 0; i<siz; i++)            
          [[pList objectAt:i] connect:[iList objectAt:i]];
    [pList free]; 
    [iList free];
    return self;
}

#define NOTESENDER(_i) NX_ADDRESS(noteSenders)[_i] 

-realizeNote:aNote fromNoteReceiver:aNoteReceiver
  /* Here's where the work is done. */
{
    int i;
    double curDly;
    int velocity,noteType;
    id newNote;
    noteType = [aNote noteType];
    if (noteType == MK_mute) {
	[NOTESENDER(0) sendNote:aNote];         					
	return self;
    }
    curDly = 0;
    [NOTESENDER(1) sendNote:aNote];              
    if (delay == 0)
    	return self;
    velocity = [aNote parAsInt:MK_velocity];     
    for (i=2;i<=NUMCHANS;i++) {                  
	curDly += delay;                         
	newNote = [aNote copy];                  
	if (noteType == MK_noteOn)               
	  [newNote setPar:MK_velocity toInt:
	  velocity -= 15];                                         			
	[NOTESENDER(i) sendAndFreeNote:newNote 
	 withDelay:curDly];
    }
    return self;
}

@end

