Home : Pieces-O-MIDI : Source Code 
 
# Pieces-O-MIDI
#
# Read a MIDI File, split it up into n pieces, and sequence the pieces
# by using the pitch values of the notes in the original music to
# select which pieces to use.  The "offset" value is something you can
# use to adjust the pitch values, causing it to select different sections
# of the piece (ie. if you split it into 1000 pieces, you don't want to
# be limited to picking only pieces 0-127)

function pieces(fname,n,offset,mult) {
	if ( offset == "" )
		offset = 0
	f = readmf(fname)
	f.length = latest(f)
	arr = cutitup(f,n)
	p = seqpieces(arr,f,offset,mult)
	writemf(p,"www.mid")
	writelines(p,"www.lines")
}

# Sequence from the pieces in the arr array

function seqpieces(arr,p,offset,mult) {
	npieces = sizeof(arr)
	r = ''
	for ( n in onlynotes(p) ) {
		i = ((n.pitch*mult) + offset) % npieces
		r += arr[i]
		if ( r.length >= p.length )
			break;
	} 
	return(r)
}

# Cut a phrase up into "np" pieces

function cutitup(p,np) {

	arr = []

	# Here we try to figure out a reasonable size for the pieces
	s1 = p.length / np
	qnt = 2b
	sectsize = numquant( s1 , qnt )
	while ( sectsize <= 0 ) {
		qnt /= 2
		if ( qnt == 0 ) {
			print("Bad news in resection!?")
			break
		}
		sectsize = numquant( s1 , qnt )
	}
	# Now split it up
	nsect = p.length / sectsize
	for ( n=0; n < nsect; n++ ) {
		p2 = cut(p,CUT_TIME,n*sectsize,(n+1)*sectsize)
		p2 -= nonnotes(p2)
		p2.time -= numquant(p2%1.time,sectsize)
		if ( p2%1.time < 0 )
			p2.time += sectsize
		p2.length = sectsize
		arr[n] = p2
	}
	return(arr)
}