This is spliceplay.m in view mode; [Download] [Up]
/* compile with cmix.o -lNeXT_s -lsys_s */ /* bugs so far. Dont seem to be able to write 1k header, just writes NeXT header, have to write IRCAM header over it, destroying about 1000 samples mixsnd and deletesnd seem incompatible */ #import "/musr/H/ugens.h" #import <objc/objc.h> #import <soundkit/soundkit.h> #import "Transport.h" #include <sys/time.h> #include <signal.h> #include <stdio.h> #include <errno.h> int NBYTES = 16; #define MAXFILES 90 id inputSound[MAXFILES]; id pasteSound; id tempSound; id myTransport; int Srate,nchannels; SNDSoundStruct *Sndheader; #define ARRAYSIZE 1024 float array[ARRAYSIZE]; double opensnd(p,n_args) float *p; { /* opensnd("filename",num) where num >=0 <MAXFILES */ /* file number 0 is base file, it is opened first and must start at time 0 */ int i,filenum,error; char *filename; i = (int) p[0]; filename = (char *) i; filenum = p[1]; printf("Opening file %s as number %d\n",filename,filenum); inputSound[filenum] = [Sound new]; error = [inputSound[filenum] readSoundfile:filename]; if(error) die(error); if(!filenum) { error = [pasteSound setDataSize:[inputSound[filenum] dataSize] dataFormat:[inputSound[filenum] dataFormat] samplingRate:[inputSound[filenum] samplingRate] channelCount:[inputSound[filenum] channelCount] infoSize:1004]; if(error) die(error); Sndheader = [pasteSound soundStruct]; Sndheader->dataLocation = 1024; /* to make space for IRCAM header */ /* use file 0 as base, e.g. must start at time 0 */ if(!filenum) error = [pasteSound copySamples:inputSound[filenum] at:0 count:[inputSound[filenum] sampleCount]]; if(error) die(error); Srate = (int)[pasteSound samplingRate]; SR = Srate; /* to communicate with Cmix */ nchannels = [pasteSound channelCount]; } } double mixsnd(p,n_args) float *p; { /* mixsnd(filenum,inskip,outskip,endtime) if endtime <0 it is duration, if == 0 it means go to eof */ /* this doesnt seem to work if deletesnd is also used, dont know why */ int i,j,ichannels,filenum,inskip,outskip,endtime,error; filenum = p[0]; ichannels = [inputSound[filenum] channelCount]; inskip = Srate * p[1] * ichannels; outskip = Srate * p[2] * nchannels; p[3] = (p[3] > 0) ? p[3] : p[1]-p[3]; // if neg == endtime endtime = Srate * p[3] * ichannels; printf("file %d: inputskip=%f, outputskip=%f, inputend=%f\n",filenum,p[1],p[2],p[3]); if(mixSounds(inputSound[filenum],pasteSound,inskip,outskip,endtime) < 0) { printf("whoops\n"); exit(-1); } } double alter(p,n_args) float *p; { int filenum,i,j,jcount,kcount,inskip,dur; unsigned char *adata; short *ardata; float tabvals[4],mult; id tSound; filenum = p[0]; if(filenum) tSound = inputSound[filenum]; else tSound = pasteSound; inskip = p[1] * Srate; p[2] = (p[2] < 0) ? -p[2] : p[2]-p[1]; printf("file no. %d: start at %f, end at%f\n",filenum,p[1],p[2]+p[1]); dur = ( p[2] * Srate + inskip) * [tSound channelCount]; tableset(p[2],ARRAYSIZE,tabvals); jcount = Srate/(200/[tSound channelCount]); for(i=inskip; i<dur; i += jcount) { mult=tablei((i-inskip)/[tSound channelCount],array,tabvals); kcount = (jcount > (dur-i)) ? jcount : dur - i; alterSounds(tSound,mult,i,jcount); } } double ssetline(p,n_args) float *p; { int i; setline(p,n_args,ARRAYSIZE,array); } double compactsnd(p,n_args) float *p; { int i,error; i = p[0]; printf("compacting file %d\n",i); if(i) { // if([inputSound[i] needsCompacting]) error=[inputSound[i] compactSamples]; if(error) die(error); } else { // if([pasteSound needsCompacting]) error=[pasteSound compactSamples]; if(error) die(error); } } double splicesnd(p,n_args) float *p; { /* splicesnd(filenum,inskip,outskip,endtime) if endtime < 0 it is duration, if == 0 it means go to eof */ int filenum,inskip,outskip,duration,error; filenum = p[0]; inskip = Srate * p[1]; outskip = Srate * p[2]; p[3] = (p[3] >= 0) ? p[3] : p[1]-p[3]; // if neg == duration printf("file number %d, inskip=%f, outskip=%f, end inputtime=%f\n",filenum,p[1],p[2],p[3]); duration = Srate * p[3]; if(!duration) duration = [inputSound[filenum] sampleCount] - inskip; error = [tempSound copySamples:inputSound[filenum] at:inskip count:duration]; if(error) die(error); error = [pasteSound insertSamples:tempSound at:outskip]; if(error) die(error); } double copysnd(p,n_args) float *p; { int error,filein,fileout; /* simply replaces fileout with filein, thus destroying fileout */ filein = p[0]; fileout = p[1]; printf("copy from file %d to file %d\n",filein,fileout); if(!filein) { error = [inputSound[fileout] copySound:pasteSound]; if(error) die(error); } else if(!fileout) { error = [pasteSound copySound:inputSound[filein]]; if(error) die(error); } else { error = [inputSound[fileout] copySound:inputSound[filein]]; if(error) die(error); } } double playsnd(p,n_args) float *p; { /* playsnd(start,end) plays base file, if end < 0 it is duration, if 0 it means play to end of file. Note in this case that it will play whole thing including spliced ends of sections */ id newSound; int inskip,duration,error; inskip = p[0] * Srate; p[1] = (p[1] <= 0) ? -p[1] : p[1]-p[0]; duration = (p[1] * Srate) ? p[1] * Srate : [pasteSound sampleCount] - inskip; printf("play starting at time %f for %f seconds\n",p[0],(float)duration/Srate); if(!inskip && !duration) { [myTransport play:(id)pasteSound]; [myTransport wait]; } else { newSound = [Sound new]; error = [newSound copySamples:pasteSound at:inskip count:duration]; if(error) die(error); [myTransport play:(id)newSound]; [myTransport wait]; [newSound free]; } } double deletesnd(p,n_args) float *p; { /* deletesnd(filenum,inskip,end) if end < 0 it indicates duration */ int filenum,start,dur,error; filenum = p[0]; start = p[1] * Srate; p[2] = (p[2] < 0.) ? -p[2] : p[2] - p[1]; printf("file number %d, delete starting at time %f for %f seconds\n",filenum,p[1],p[2]); dur = p[2] * Srate; if(filenum) { if(!dur) dur = [inputSound[filenum] sampleCount] - start; error = [inputSound[filenum] deleteSamplesAt:start count:dur]; if(error) die(error); } else { if(!dur) dur = [pasteSound sampleCount] - start; error = [pasteSound deleteSamplesAt:start count:dur]; if(error) die(error); } } double writesnd(p,n_args) float *p; { int error,i,nbytes,inskip,duration,rest; id newSound; char *filename; i = (int) p[0]; filename = (char *) i; inskip = p[1] * Srate; p[2] = (p[2] < 0) ? -p[2] : p[2]-p[1]; duration = (p[2] * Srate) ? p[2] * Srate : [pasteSound sampleCount] - inskip; printf("create file %s, from scratch board at time %f for %f seconds\n" ,filename,p[1],(float)duration/Srate); if( inskip || duration) { error = [pasteSound deleteSamplesAt:0 count:inskip]; if(error) die(error); rest = [pasteSound sampleCount] - duration; error = [pasteSound deleteSamplesAt:duration count:rest]; if(error) die; } printf("duration and rest %d %d\n",duration,rest); error = [pasteSound writeSoundfile:filename]; if(error) die(error); printf("done\n"); } profile() { UG_INTRO("opensnd",opensnd); UG_INTRO("splicesnd",splicesnd); UG_INTRO("playsnd",playsnd); UG_INTRO("deletesnd",deletesnd); UG_INTRO("writesnd",writesnd); UG_INTRO("mixsnd",mixsnd); UG_INTRO("compactsnd",compactsnd); UG_INTRO("setline",ssetline); UG_INTRO("alter",alter); UG_INTRO("copysnd",copysnd); pasteSound = [Sound new]; tempSound = [Sound new]; myTransport = [Transport new]; } die(error) { printf("%s\n",SNDSoundError(error)); exit(-1); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.