|
||||||
# GIF Jam # Take an image (in pnm format), scan the pixels in a variety of # ways, and use the RGB values to produce music. function gifjam(fname,xval,yval,scantype,redrange,greenrange,bluerange) { inc = 1b/4 Note1 = 'a' Note1.dur = inc Note1.length = inc Rest1 = 'r' Rest1.length = inc Maxval = 0 if ( readpnm(fname) != 0 ) { print("Unrecognized file format"); return() } Nrows = sizeof(CellR); Ncols = sizeof(CellR[0]); # print("ranges=",redrange,greenrange,bluerange); RedRange = getrange(redrange); GreenRange = getrange(greenrange); BlueRange = getrange(bluerange); # print("Nrows=",Nrows," Ncols=",Ncols); # print("xval=",xval," yval=",yval); y = integer(yval) * Nrows / 150 x = integer(xval) * Ncols / 300 NotesR = '' NotesG = '' NotesB = '' if ( scantype ~~ "Scan 3.*" ) { scanline(y) ; scanline(y+3) ; scanline(y+6) } else if ( scantype ~~ "Scan 1.*" ) { scanline(y) } else if ( scantype ~~ "Scan 6.*" ) { scanline(y) ; scanline(y+2) ; scanline(y+4) scanline(y+6) ; scanline(y+8) ; scanline(y+10) } else if ( scantype ~~ "Spiral.*" ) { spiralout(128,x,y) } else if ( scantype ~~ "Four.*" ) { spiralout(128,x,y) } else { print("Unrecognized scan type: ",scantype) } if ( typeof(RedRange) == "array" ) { NotesR.chan = 1; NotesR = scadjust(NotesR,transpose(scale_dorian(),'a')); } NotesR = NotesR{ rand(2)==0 }; if ( typeof(GreenRange) == "array" ) { NotesG.chan = 2; NotesG = scadjust(NotesG,transpose(scale_dorian(),'a')); } NotesG = NotesG{ rand(2)==0 } if ( typeof(BlueRange) == "array" ) { NotesB.chan = 3; NotesB = scadjust(NotesB,transpose(scale_dorian(),'a')); } NotesB = NotesB{ rand(2)==0 } p = (NotesR | NotesG | NotesB) p = p | makerootevery(p{??.chan!=10},2b) writemf(p,"www.mid") writelines(p,"www.lines") } function getrange(range) { r = [] if ( range ~~ "High .*" ) { r["high"] = 110 r["low"] = 70 } else if ( range ~~ "Medium-High .*" ) { r["high"] = 100 r["low"] = 60 } else if ( range ~~ "Medium .*" ) { r["high"] = 90 r["low"] = 50 } else if ( range ~~ "Medium-Low .*" ) { r["high"] = 80 r["low"] = 40 } else if ( range ~~ "Low .*" ) { r["high"] = 70 r["low"] = 30 } else if ( range ~~ "None.*" ) { return(-1) } else if ( range ~~ "Drums.*" ) { return(-2) } else if ( range ~~ "Chords.*" ) { return(-3) } r["span"] = r["high"] - r["low"] return(r) } function spiralout(nnts,x,y) { p = '' oy = y; dx = 1 dxdir = -1 dy = 0 dydir = 1 ndx = 0 ndy = 0 ndxsofar = 0 ndysofar = 0 for ( n=0; n<nnts; n++) { if ( x<0 || y<0 || x>=Ncols || y>=Nrows ) break; usecell(y,x) x += dx y += dy if ( ++ndxsofar > ndx ) { ndxsofar = 0; if ( dx == 0 ) { dx = 1 * dxdir dy = 0 dxdir = -dxdir ndx++ } else { dx = 0 dy = 1 * -dxdir } } } return(p) } function scanline(y) { for ( x=0; x<Ncols; x++ ) { usecell(y,x) } } Drums = [0=35,1=36,2=37,3=38,4=39,5=41,6=42,7=46,8=47, 9=48,10=50,11=53,12=54,13=56,14=60,15=61,16=62,17=63] Chords = [0='c e g',1='f a c',2='d f+ a',3='g b d',4='a c+ e'] function usecell(y,x) { v = (CellR[y][x]) if ( v != 0 && v != Maxval ) { if ( typeof(RedRange) == "array" ) { v2 = v * RedRange["span"] / (Maxval) Note1.pitch = v2 + RedRange["low"] NotesR += Note1 } else if ( RedRange == -2 ) { Note1.pitch = Drums[v%sizeof(Drums)] Note1.chan = 10 NotesR += Note1 } else if ( RedRange == -3 ) { ch = Chords[v%sizeof(Chords)] ch.dur = Note1.dur ch.length = Note1.length NotesR += ch } } else { NotesR += Rest1 } v = (CellG[y][x]) if ( v != 0 && v != Maxval ) { if ( typeof(GreenRange) == "array" ) { v2 = v * GreenRange["span"] / (Maxval) Note1.pitch = v2 + GreenRange["low"] NotesG += Note1 } else if ( GreenRange == -2 ) { Note1.pitch = Drums[v%sizeof(Drums)] Note1.chan = 10 NotesG += Note1 } } else { NotesG += Rest1 } v = (CellB[y][x]) if ( v != 0 && v != Maxval ) { if ( typeof(BlueRange) == "array" ) { v2 = v * BlueRange["span"] / (Maxval) Note1.pitch = v2 + BlueRange["low"] NotesB += Note1 } else if ( BlueRange == -2 ) { Note1.pitch = Drums[v%sizeof(Drums)] Note1.chan = 10 NotesB += Note1 } } else { NotesG += Rest1 } } function readpnm(fname) { f = open(fname) Words = [] Used = 0 Type = getword(f) cols = getword(f) rows = getword(f) Maxval = getword(f) CellR = [] CellG = [] CellB = [] if ( Type == "P2" ) { # greyscale for ( r=0; r<rows; r++ ) { CellR[r] = [] CellG[r] = [] CellB[r] = [] for ( c=0; c<cols; c++ ) { i = integer(getword(f)) if ( i == Eof ) { print("Premature EOF!?"); break; } CellR[r][c] = i CellG[r][c] = i CellB[r][c] = i } } return(0) } else if ( Type == "P3" ) { # color for ( r=0; r<rows; r++ ) { CellR[r] = [] CellG[r] = [] CellB[r] = [] for ( c=0; c<cols; c++ ) { ir = integer(getword(f)) if ( ir == Eof ) { print("Premature EOF!?"); break; } ig = integer(getword(f)) if ( ig == Eof ) { print("Premature EOF!?"); break; } ib = integer(getword(f)) if ( ib == Eof ) { print("Premature EOF!?"); break; } CellR[r][c] = ir CellG[r][c] = ig CellB[r][c] = ib } } return(0) } else { print("Unrecognized image type: ",Type); return(1) } } function getword(f) { if ( Used < sizeof(Words) ) { return(Words[Used++]) } while (1) { ln = get(f) if ( ln == Eof ) return(Eof) Words = split(ln) if ( sizeof(Words) > 0 ) break; } Used = 0 return (Words[Used++]) } |