Script Library: 1238 scripts
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

Archive version of: minisynth.r ... version: 1 ... aunario 21-Sep-2005

Amendment note: new script || Publicly available? Yes

REBOL [
	Title: "Mini Synthesizer"
	Author: "Ayrris Aunario"
	Email: aaunario@yahoo.com
	Purpose: {A GUI synthesizer that allows user input through both keyboard and mouse}
	Date: 21-Sep-2005/1:30-7:00
	Version: 0.0.1
	File: %minisynth.r
	Library: [
		Level: 'intermediate
		Platform: 'win
		Type: [demo fun]
		Domain: [gui ui user-interface sound vid]
		Tested-under: none
		Support: none
		License: none
		See-also: none
	]
]

sound-port: open sound:// 

play?: false
afreq: 440
st-ratio: 2 ** (1 / 12)
tone-length: .5
inc: 10
keys: [C1 Cs1 D1 Eb1 E1 F1 Fs1 G1 Ab1 A1 Bb1 Bb C2 Cs2 D2 Eb2 E2 F2 Fs2 G2 Ab2 A2 Bb2 B2]  
keyboardkeys: "q2w3er5t6y7ucfvgbnjmk,l."
 
sample: make sound [ 
	rate: 44100 / 2
	channels: 1 
	bits: 8
	volume: 0.5 
	data: #{} 
]

make-pitch: func [pitchfreq time samprate /local numsamps numcycles pitchdata] [ 
	pitchdata: copy #{}
	numsamps: samprate / pitchfreq	
	repeat sampcount (round/floor samprate * time)[
			x: sampcount * 360 / numsamps
			append pitchdata to-char val: 128 + round 127 * sine x
	]

	pitchdata
] 


key: make face [
	size: 
	edge: make edge [
		color: 0.0.0
		size: 1x1
	]
	white?: 
	indplace: 
	offset: 
	color: 
	tone: 
	make-sound: func [p][
		sample/data: make-pitch p tone-length (sample/rate)
		insert sound-port sample
	]
		
	playnote: does [
		color: yellow
		show keyboard
		make-sound tone 
		wait sound-port
		reset
		show keyboard
 	]
	reset: does [color: white * white?]
	feel: make feel[
		engage: func [face action event][
			if action = 'down [
				face/playnote
			]
		]
	]	
]


initkeys: has [xpos ind w? temp black_keys][
	black_keys: copy []
	temp: copy []
	xpos: 0
	w?: 1

	foreach k keys [
		ind: index? find keys k
		either (length? to-string k) > 2 [w?: 0][w?: 1]
		set k make key [	
			size: 20x100 + (w? * 10x100)
			offset: as-pair (xpos) (1) 
			color: white * w?
			white?: w?
			indplace: ind
			tone: st-ratio ** (ind - 10) * afreq
		]
		
		
		either any [(mod ind 12) = 0  (mod ind 12) = 5][
			xpos: 5 * w? + inc * 2 + xpos 	
		][
			xpos: 5 * w? + inc + xpos  
		]
		either w? = 0 [append black_keys k][append temp k]
	]
	
	foreach b black_keys [append temp b]
temp
]

keyboard: make face [
	size: 500x200
	offset: 0x0
	edge: none
	pane: initkeys			
]

input-panel: make face [
	size: 500x100
	offset: 0x200
	edge: make edge [
		color: 0.0.0
		size: 1x1
	]
	pane: layout [
		across
		button "Play Sample" [play?: true play-song]
		button "Stop Sample" [play?: false]
	]
]

song: [	1 1 2	
		8 1 2
		10 1 2
		8 2 1
		6 1 2
		5 1 2
		3 1 2
		1 2 1
		8 1 2
		6 1 2
		5 1 2
		3 2 1
		8 1 2
		6 1 2
		5 1 2
		3 2 1
		1 1 2	
		8 1 2
		10 1 2
		8 2 1
		6 1 2
		5 1 2
		3 1 2
		1 2 1]	 
play-song: does [
	foreach [no le times] song [
		if not play? [break]
		tone-length: le * .5
		k: get pick keys no
		loop times [
			k/playnote
			wait 0.05
		]
	]
]		
		
		
	
view/new window: make face [
	size: 500x300
	offset: 100x100
	edge: none
	pane: [input-panel keyboard]
	feel: make feel [
		engage: func [face action event /local k][
			if action = 'key [
				if find keyboardkeys event/key[
					k: get pick keys (index? find keyboardkeys event/key)
					k/playnote
				]
			]
		]
	]
]

focus window	
do-events
	
close sound-port