This is EchoFilter.m in view mode; [Download] [Up]
#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
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.