[q-lang-cvs] qcalc/examples midiio.qcalc,1.1,1.2
Brought to you by:
agraef
From: Albert G. <ag...@us...> - 2007-11-25 15:06:21
|
Update of /cvsroot/q-lang/qcalc/examples In directory sc8-pr-cvs16.sourceforge.net:/tmp/cvs-serv9392/examples Modified Files: midiio.qcalc Log Message: code cleanup, added MIDI output Index: midiio.qcalc =================================================================== RCS file: /cvsroot/q-lang/qcalc/examples/midiio.qcalc,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** midiio.qcalc 22 Nov 2007 09:30:06 -0000 1.1 --- midiio.qcalc 25 Nov 2007 15:06:17 -0000 1.2 *************** *** 1,12 **** ! // qcalc 1.0, created Thu Nov 22 10:31:16 2007 -*-Q-*- -*- coding: UTF-8 -*- ! // [((0,1),"MidiShare Client"),((0,2),"Port"),((0,3),"Channel"),((1,0),"Input:"),((1,1),"= client_combobox"),((1,2),"= port_spinbox"),((1,3),"= chan_spinbox"),((3,0),"= midiin_taskbutton B2 C2 D2 F5:F11"),((3,1),"Time"),((3,2),"Channel"),((3,3),"Data #1"),((3,4),"Data #2"),((3,5),"= midiin_clearbutton"),((4,0),"Note On"),((4,2),"= spinbox (0,16,1,0,\" \")"),((4,3),"= spinbox (-1,127,1,-1,\" \")"),((4,4),"= spinbox (-1,127,1,-1,\" \")"),((4,5),"= togglebutton (\"Recv\",\"\",true)"),((4,6),"= note_name D5"),((5,0),"Note Off"),((5,2),"= spinbox (0,16,1,0,\" \")"),((5,3),"= spinbox (-1,127,1,-1,\" \")"),((5,4),"= spinbox (-1,127,1,-1,\" \")"),((5,5),"= togglebutton (\"Recv\",\"\",true)"),((6,0),"Pitch Wheel"),((6,2),"= spinbox (0,16,1,0,\" \")"),((6,3),"= spinbox (-1,127,1,-1,\" \")"),((6,4),"= spinbox (-1,127,1,-1,\" \")"),((6,5),"= togglebutton (\"Recv\",\"\",true)"),((7,0),"Controller"),((7,2),"= spinbox (0,16,1,0,\" \")"),((7,3),"= spinbox (-1,127,1,-1,\" \")"),((7,4),"= spinbox (-1,127,1,-1,\" \")"),((7,5),"= togglebutton (\"Recv\",\"\",true)"),((8,0),"Program"),((8,2),"= spinbox (0,16,1,0,\" \")"),((8,3),"= spinbox (-1,127,1,-1,\" \")"),((8,4),"= spinbox (-1,127,1,-1,\" \")"),((8,5),"= togglebutton (\"Recv\",\"\",true)"),((9,0),"Aftertouch"),((9,2),"= spinbox (0,16,1,0,\" \")"),((9,3),"= spinbox (-1,127,1,-1,\" \")"),((9,4),"= spinbox (-1,127,1,-1,\" \")"),((9,5),"= togglebutton (\"Recv\",\"\",true)"),((10,0),"Poly Aftertouch"),((10,2),"= spinbox (0,16,1,0,\" \")"),((10,3),"= spinbox (-1,127,1,-1,\" \")"),((10,4),"= spinbox (-1,127,1,-1,\" \")"),((10,5),"= togglebutton (\"Recv\",\"\",true)")] // [] // [(0,126),(1,146),(5,83)] // Start of script. Please do not remove this line. import calclib, midi; ! def MYNAME = "QCalc MIDI I/O", ! REF = midi_open MYNAME, _ = midi_connect REF REF; def NOTE_NAMES = ("C","C#","D","D#","E","F","F#","G","G#","A","Bb","B"); --- 1,20 ---- ! // qcalc 1.0, created Sun Nov 25 16:10:11 2007 -*-Q-*- -*- coding: UTF-8 -*- ! // [((0,1),"MidiShare Client"),((0,2),"Port"),((0,3),"Channel"),((1,0),">>> Input:"),((1,1),"= inclient_combobox"),((1,2),"= inport_spinbox"),((1,3),"= inchan_spinbox"),((3,0),"= intaskbutton B2 C2 D2 F5:F11"),((3,1),"Time"),((3,2),"Channel"),((3,3),"Data #1"),((3,4),"Data #2"),((3,5),"= clearbutton"),((4,0),"Note On"),((4,2),"= spinbox (0,16,1,0,\" \")"),((4,3),"= spinbox (-1,127,1,-1,\" \")"),((4,4),"= spinbox (-1,127,1,-1,\" \")"),((4,5),"= togglebutton (\"Recv\",\"\",true)"),((4,6),"= note_name D5"),((5,0),"Note Off"),((5,2),"= spinbox (0,16,1,0,\" \")"),((5,3),"= spinbox (-1,127,1,-1,\" \")"),((5,4),"= spinbox (-1,127,1,-1,\" \")"),((5,5),"= togglebutton (\"Recv\",\"\",true)"),((5,6),"= note_name D6"),((6,0),"Pitch Wheel"),((6,2),"= spinbox (0,16,1,0,\" \")"),((6,3),"= spinbox (-1,127,1,-1,\" \")"),((6,4),"= spinbox (-1,127,1,-1,\" \")"),((6,5),"= togglebutton (\"Recv\",\"\",true)"),((7,0),"Controller"),((7,2),"= spinbox (0,16,1,0,\" \")"),((7,3),"= spinbox (-1,127,1,-1,\" \")"),((7,4),"= spinbox (-1,127,1,-1,\" \")"),((7,5),"= togglebutton (\"Recv\",\"\",true)"),((8,0),"Program"),((8,2),"= spinbox (0,16,1,0,\" \")"),((8,3),"= spinbox (-1,127,1,-1,\" \")"),((8,4),"= spinbox (-1,127,1,-1,\" \")"),((8,5),"= togglebutton (\"Recv\",\"\",true)"),((9,0),"Aftertouch"),((9,2),"= spinbox (0,16,1,0,\" \")"),((9,3),"= spinbox (-1,127,1,-1,\" \")"),((9,4),"= spinbox (-1,127,1,-1,\" \")"),((9,5),"= togglebutton (\"Recv\",\"\",true)"),((10,0),"Poly Aftertouch"),((10,2),"= spinbox (0,16,1,0,\" \")"),((10,3),"= spinbox (-1,127,1,-1,\" \")"),((10,4),"= spinbox (-1,127,1,-1,\" \")"),((10,5),"= togglebutton (\"Recv\",\"\",true)"),((12,1),"MidiShare Client"),((12,2),"Port"),((12,3),"Channel"),((13,0),">>> Output:"),((13,1),"= outclient_combobox"),((13,2),"= outport_spinbox"),((13,3),"= outchan_spinbox"),((15,0),"= outtaskbutton B14"),((15,1),"Time"),((15,2),"Channel"),((15,3),"Data #1"),((15,4),"Data #2"),((15,5),"= resetbutton D14"),((16,0),"Note On"),((16,2),"= spinbox (0,16,1,D$14,\" \")"),((16,3),"= spinbox (-1,127,1,60,\" \")"),((16,4),"= spinbox (-1,127,1,64,\" \")"),((16,5),"= outsendbutton C$14 (note_on (C17-1) D17 E17)"),((16,6),"= note_name D17"),((17,0),"Note Off"),((17,2),"= spinbox (0,16,1,D$14,\" \")"),((17,3),"= spinbox (-1,127,1,60,\" \")"),((17,4),"= spinbox (-1,127,1,64,\" \")"),((17,5),"= outsendbutton C$14 (note_off (C18-1) D18 E18)"),((17,6),"= note_name D18"),((18,0),"Pitch Wheel"),((18,2),"= spinbox (0,16,1,D$14,\" \")"),((18,3),"= spinbox (-1,127,1,0,\" \")"),((18,4),"= spinbox (-1,127,1,64,\" \")"),((18,5),"= outsendbutton C$14 (pitch_wheel (C19-1) D19 E19)"),((19,0),"Controller"),((19,2),"= spinbox (0,16,1,D$14,\" \")"),((19,3),"= spinbox (-1,127,1,1,\" \")"),((19,4),"= spinbox (-1,127,1,0,\" \")"),((19,5),"= outsendbutton C$14 (ctrl_change (C20-1) D20 E20)"),((20,0),"Program"),((20,2),"= spinbox (0,16,1,D$14,\" \")"),((20,3),"= spinbox (-1,127,1,0,\" \")"),((20,4),"= spinbox (-1,127,1,-1,\" \")"),((20,5),"= outsendbutton C$14 (prog_change (C21-1) D21)"),((21,0),"Aftertouch"),((21,2),"= spinbox (0,16,1,D$14,\" \")"),((21,3),"= spinbox (-1,127,1,0,\" \")"),((21,4),"= spinbox (-1,127,1,-1,\" \")"),((21,5),"= outsendbutton C$14 (chan_press (C22-1) D22)"),((22,0),"Poly Aftertouch"),((22,2),"= spinbox (0,16,1,D$14,\" \")"),((22,3),"= spinbox (-1,127,1,60,\" \")"),((22,4),"= spinbox (-1,127,1,64,\" \")"),((22,5),"= outsendbutton C$14 (key_press (C23-1) D23 E23)")] // [] // [(0,126),(1,146),(5,83)] // Start of script. Please do not remove this line. + /* This is a little example which demonstrates realtime MIDI input and output + in qcalc. */ + import calclib, midi; ! /* Open MidiShare clients. */ ! ! def INNAME = "QCalc MIDI Input", OUTNAME = "QCalc MIDI Output", ! INREF = midi_open INNAME, OUTREF = midi_open OUTNAME, ! _ = midi_connect INREF INREF; ! ! /* Helper function to translate MIDI note numbers to note names. */ def NOTE_NAMES = ("C","C#","D","D#","E","F","F#","G","G#","A","Bb","B"); *************** *** 15,18 **** --- 23,28 ---- note_name _ = "N/A" otherwise; + /* Create and parse numbered client names, to resolve ambiguities. */ + make_client_name N = sprintf "%d %s" (N,midi_client_name N); *************** *** 20,29 **** client_name S = S where N:Int = sscanf S "%d", S:String = midi_client_name N; ! client_combobox = combobox $ filter ((<>MYNAME).client_name) $ map make_client_name midi_clients; ! port_spinbox = spinbox (-1,255,1,-1,"Any"); ! chan_spinbox = spinbox (0,16,1,0,"Any"); portno "Any" = -1; --- 30,52 ---- client_name S = S where N:Int = sscanf S "%d", S:String = midi_client_name N; ! /* Client selection comboboxes. */ ! ! inclient_combobox ! = combobox $ filter ((<>INNAME).client_name) $ map make_client_name midi_clients; ! outclient_combobox ! = combobox $ filter ((<>OUTNAME).client_name) $ ! map make_client_name midi_clients; ! /* Port and MIDI channel selection spinboxes. */ ! ! inport_spinbox = spinbox (-1,255,1,-1,"Any"); ! outport_spinbox = spinbox (0,255,1,0); ! ! inchan_spinbox = spinbox (0,16,1,0,"Any"); ! outchan_spinbox = spinbox (1,16,1,1); ! ! /* Translate symbolic port and channel names. */ portno "Any" = -1; *************** *** 33,50 **** channo N:Int = N; ! midiin_clearbutton ! = actionbutton "Clear" (matrix (row+1,1) [[""," "," "," "] : K in [1..7]] || ()); ! midiin_taskbutton NAME:String PORT CHAN F:List ! = taskbutton "Connect" $ midiin_task NAME (portno PORT) (channo CHAN) (tuple F); ! midiin_task NAME:String PORT:Int CHAN:Int F:Tuple ! = printf "opening client #%d %s (port %d, channel %d)\n" (IN,NAME,PORT,CHAN) || ! midi_connect IN REF || port_filter PORT || chan_filter CHAN || ! midiin_process F SEM (I,J) IN PORT ! (thread $ midiin_loop SEM (midi_get REF)) (get SEM) where IN:Int = client_ref NAME, --- 56,87 ---- channo N:Int = N; ! /* Clear the MIDI input area. */ ! ! clearbutton = actionbutton "Clear" (matrix (row+1,1) [[""," "," "," "] : K in [1..7]] || ()); ! /* Reset the MIDI output area to defaults. */ ! resetbutton CH = actionbutton "Reset" ! (matrix (row+1,1) [["",CH,60,64], ! ["",CH,60,64], ! ["",CH,0,64], ! ["",CH,1,0], ! ["",CH,0," "], ! ["",CH,0," "], ! ["",CH,60,64]] || ()); ! ! /* MIDI input task. This also starts a secondary thread handling the MIDI input. */ ! ! intaskbutton NAME:String PORT CHAN F:List ! = taskbutton "Connect" $ intask NAME (portno PORT) (channo CHAN) (tuple F); ! ! intask NAME:String PORT:Int CHAN:Int F:Tuple ! = printf "opening input client #%d %s (port %d, channel %d)\n" (IN,NAME,PORT,CHAN) || ! midi_connect IN INREF || port_filter PORT || chan_filter CHAN || ! inprocess F SEM (I,J) IN PORT ! (thread $ inloop SEM (midi_get INREF)) (get SEM) where IN:Int = client_ref NAME, *************** *** 54,116 **** port_filter PORT ! = do (flip (midi_accept_port REF) false) [0..255] || ! midi_accept_port REF PORT true if PORT >= 0; chan_filter CHAN ! = do (flip (midi_accept_chan REF) false) [0..15] || ! midi_accept_chan REF CHAN true if CHAN >= 0; ! midiin_process F SEM (I,J) IN PORT H:Thread B:Bool ! = puts "connecting\n" || ! midi_connect IN REF || ! midiin_process F SEM (I,J) IN PORT H (get SEM) if B; ! = puts "disconnecting\n" || ! midi_disconnect IN REF || ! midiin_process F SEM (I,J) IN PORT H (get SEM) otherwise; ! midiin_process F SEM (I,J) IN PORT H:Thread 'X ! = puts "closing\n" || ! midi_send REF PORT stop || cancel H || ! midi_accept_all REF || ! midi_disconnect IN REF || ! taskbutton ("Connect",CONN) $ midiin_task NAME (portno PORT) (channo CHAN) F where (_,_,NAME,PORT,CHAN,F) = task_params 'X, ! CONN = midi_connected IN REF; ! midiin_process F SEM (I,J) IN PORT H:Thread (TIME,note_on CH N V) = rowvect (I+1,J+1) [TIME,CH+1,N,V] || ! midiin_process F SEM (I,J) IN PORT H (get SEM) if F!0; ! midiin_process F SEM (I,J) IN PORT H:Thread (TIME,note_off CH N V) = rowvect (I+2,J+1) [TIME,CH+1,N,V] || ! midiin_process F SEM (I,J) IN PORT H (get SEM) if F!1; ! midiin_process F SEM (I,J) IN PORT H:Thread (TIME,pitch_wheel CH LSB MSB) = rowvect (I+3,J+1) [TIME,CH+1,LSB,MSB] || ! midiin_process F SEM (I,J) IN PORT H (get SEM) if F!2; ! midiin_process F SEM (I,J) IN PORT H:Thread (TIME,ctrl_change CH N V) = rowvect (I+4,J+1) [TIME,CH+1,N,V] || ! midiin_process F SEM (I,J) IN PORT H (get SEM) if F!3; ! midiin_process F SEM (I,J) IN PORT H:Thread (TIME,prog_change CH V) = rowvect (I+5,J+1) [TIME,CH+1,V] || ! midiin_process F SEM (I,J) IN PORT H (get SEM) if F!4; ! midiin_process F SEM (I,J) IN PORT H:Thread (TIME,key_press CH N V) ! = rowvect (I+6,J+1) [TIME,CH+1,N,V] || ! midiin_process F SEM (I,J) IN PORT H (get SEM) if F!5; ! midiin_process F SEM (I,J) IN PORT H:Thread (TIME,chan_press CH V) ! = rowvect (I+7,J+1) [TIME,CH+1,V] || ! midiin_process F SEM (I,J) IN PORT H (get SEM) if F!6; ! midiin_process F SEM (I,J) IN PORT H:Thread _ ! = midiin_process F SEM (I,J) IN PORT H (get SEM) otherwise; ! midiin_loop SEM (_,_,TIME,MSG) = post SEM (TIME,MSG) || //printf "%08d %s\n" (TIME,str MSG) || ! midiin_loop SEM (midi_get REF); --- 91,198 ---- port_filter PORT ! = do (flip (midi_accept_port INREF) false) [0..255] || ! midi_accept_port INREF PORT true if PORT >= 0; chan_filter CHAN ! = do (flip (midi_accept_chan INREF) false) [0..15] || ! midi_accept_chan INREF CHAN true if CHAN >= 0; ! inprocess F SEM (I,J) IN PORT H:Thread B:Bool ! = puts "connecting input\n" || ! midi_connect IN INREF || ! inprocess F SEM (I,J) IN PORT H (get SEM) if B; ! = puts "disconnecting input\n" || ! midi_disconnect IN INREF || ! inprocess F SEM (I,J) IN PORT H (get SEM) otherwise; ! inprocess F SEM (I,J) IN PORT H:Thread 'X ! = puts "closing input\n" || ! midi_send INREF (max 0 PORT) stop || cancel H || ! midi_accept_all INREF || ! midi_disconnect IN INREF || ! taskbutton ("Connect",CONN) $ intask NAME (portno PORT) (channo CHAN) F where (_,_,NAME,PORT,CHAN,F) = task_params 'X, ! CONN = midi_connected IN INREF; ! inprocess F SEM (I,J) IN PORT H:Thread (TIME,note_on CH N V) = rowvect (I+1,J+1) [TIME,CH+1,N,V] || ! inprocess F SEM (I,J) IN PORT H (get SEM) if F!0; ! inprocess F SEM (I,J) IN PORT H:Thread (TIME,note_off CH N V) = rowvect (I+2,J+1) [TIME,CH+1,N,V] || ! inprocess F SEM (I,J) IN PORT H (get SEM) if F!1; ! inprocess F SEM (I,J) IN PORT H:Thread (TIME,pitch_wheel CH LSB MSB) = rowvect (I+3,J+1) [TIME,CH+1,LSB,MSB] || ! inprocess F SEM (I,J) IN PORT H (get SEM) if F!2; ! inprocess F SEM (I,J) IN PORT H:Thread (TIME,ctrl_change CH N V) = rowvect (I+4,J+1) [TIME,CH+1,N,V] || ! inprocess F SEM (I,J) IN PORT H (get SEM) if F!3; ! inprocess F SEM (I,J) IN PORT H:Thread (TIME,prog_change CH V) = rowvect (I+5,J+1) [TIME,CH+1,V] || ! inprocess F SEM (I,J) IN PORT H (get SEM) if F!4; ! inprocess F SEM (I,J) IN PORT H:Thread (TIME,chan_press CH V) ! = rowvect (I+6,J+1) [TIME,CH+1,V] || ! inprocess F SEM (I,J) IN PORT H (get SEM) if F!5; ! inprocess F SEM (I,J) IN PORT H:Thread (TIME,key_press CH N V) ! = rowvect (I+7,J+1) [TIME,CH+1,N,V] || ! inprocess F SEM (I,J) IN PORT H (get SEM) if F!6; ! inprocess F SEM (I,J) IN PORT H:Thread _ ! = inprocess F SEM (I,J) IN PORT H (get SEM) otherwise; ! /* The MIDI input loop. Receives incoming MIDI events and queues them ! in the input task semaphore for processing. */ ! ! inloop SEM (_,_,TIME,MSG) = post SEM (TIME,MSG) || //printf "%08d %s\n" (TIME,str MSG) || ! inloop SEM (midi_get INREF); ! ! /* MIDI output task. This just manages the client connection. */ ! ! outtaskbutton NAME:String ! = taskbutton "Connect" $ outtask NAME; ! ! outtask NAME:String ! = printf "opening output client #%d %s\n" (OUT,NAME) || ! midi_connect OUTREF OUT || ! outprocess SEM (I,J) OUT (get SEM) ! where OUT:Int = client_ref NAME, ! NAME:String = midi_client_name OUT, ! SEM:Semaphore = task_input, (I,J) = index; ! ! outprocess SEM (I,J) OUT B:Bool ! = puts "connecting output\n" || ! midi_connect OUTREF OUT || ! outprocess SEM (I,J) OUT (get SEM) ! if B; ! = puts "disconnecting output\n" || ! midi_disconnect OUTREF OUT || ! outprocess SEM (I,J) OUT (get SEM) ! otherwise; ! outprocess SEM (I,J) OUT 'X ! = puts "closing output\n" || ! midi_disconnect OUTREF OUT || ! taskbutton ("Connect",CONN) $ outtask NAME ! where (_,_,NAME) = task_params 'X, ! CONN = midi_connected OUTREF OUT; ! outprocess SEM (I,J) OUT _ ! = outprocess SEM (I,J) OUT (get SEM) ! otherwise; ! ! /* MIDI output actionbuttons. */ ! ! outsendbutton PORT MSG ! = actionbutton "Send" (outsend PORT MSG); ! ! outsend PORT MSG ! = //printf "%08d %s\n" (TIME,str MSG) || ! setval (row,1) TIME || midi_send OUTREF PORT MSG ! where TIME = midi_time; |