| 1 | (***************************************************************************** |
|---|
| 2 | |
|---|
| 3 | Liquidsoap, a programmable audio stream generator. |
|---|
| 4 | Copyright 2003-2009 Savonet team |
|---|
| 5 | |
|---|
| 6 | This program is free software; you can redistribute it and/or modify |
|---|
| 7 | it under the terms of the GNU General Public License as published by |
|---|
| 8 | the Free Software Foundation; either version 2 of the License, or |
|---|
| 9 | (at your option) any later version. |
|---|
| 10 | |
|---|
| 11 | This program is distributed in the hope that it will be useful, |
|---|
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 14 | GNU General Public License for more details, fully stated in the COPYING |
|---|
| 15 | file at the root of the liquidsoap distribution. |
|---|
| 16 | |
|---|
| 17 | You should have received a copy of the GNU General Public License |
|---|
| 18 | along with this program; if not, write to the Free Software |
|---|
| 19 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|---|
| 20 | |
|---|
| 21 | *****************************************************************************) |
|---|
| 22 | |
|---|
| 23 | let knotes = [|'a'; '?'; 'z'; '"'; 'e'; 'r'; '('; 't'; '-'; 'y'; '?'; 'u'; 'i'; '?'; 'o'; '?'; 'p'|] |
|---|
| 24 | |
|---|
| 25 | let array_index a x = |
|---|
| 26 | let ans = ref None in |
|---|
| 27 | for i = 0 to Array.length knotes - 1 do |
|---|
| 28 | if knotes.(i) = x then ans := Some i |
|---|
| 29 | done; |
|---|
| 30 | match !ans with |
|---|
| 31 | | Some i -> i |
|---|
| 32 | | None -> raise Not_found |
|---|
| 33 | |
|---|
| 34 | let note_of_char c = |
|---|
| 35 | array_index knotes c + 72 |
|---|
| 36 | |
|---|
| 37 | class keyboard = |
|---|
| 38 | object (self) |
|---|
| 39 | inherit Source.active_source |
|---|
| 40 | |
|---|
| 41 | method stype = Source.Infallible |
|---|
| 42 | method is_ready = true |
|---|
| 43 | method remaining = -1 |
|---|
| 44 | method abort_track = () |
|---|
| 45 | method output = if AFrame.is_partial memo then self#get_frame memo |
|---|
| 46 | |
|---|
| 47 | val mutable ev = [] |
|---|
| 48 | val ev_m = Mutex.create () |
|---|
| 49 | |
|---|
| 50 | method add_event (t:int) (e:Midi.event) = |
|---|
| 51 | Mutex.lock ev_m; |
|---|
| 52 | ev <- (t,e)::ev; |
|---|
| 53 | Mutex.unlock ev_m |
|---|
| 54 | |
|---|
| 55 | method get_events = |
|---|
| 56 | Mutex.lock ev_m; |
|---|
| 57 | let e = List.rev ev in |
|---|
| 58 | ev <- []; |
|---|
| 59 | Mutex.unlock ev_m; |
|---|
| 60 | e |
|---|
| 61 | |
|---|
| 62 | val mutable reader = None |
|---|
| 63 | |
|---|
| 64 | method output_get_ready = |
|---|
| 65 | if reader = None then |
|---|
| 66 | reader <- |
|---|
| 67 | Some |
|---|
| 68 | (Tutils.create |
|---|
| 69 | (fun () -> |
|---|
| 70 | while true do |
|---|
| 71 | let c = |
|---|
| 72 | let c = String.create 1 in |
|---|
| 73 | ignore (Unix.read Unix.stdin c 0 1); |
|---|
| 74 | c.[0] |
|---|
| 75 | in |
|---|
| 76 | try |
|---|
| 77 | Printf.printf "\nPlaying note %d.\n%!" (note_of_char c); |
|---|
| 78 | self#add_event 0 (Midi.Note_on (note_of_char c, 0.8)) |
|---|
| 79 | with |
|---|
| 80 | | Not_found -> () |
|---|
| 81 | done |
|---|
| 82 | ) () "Virtual keyboard") |
|---|
| 83 | |
|---|
| 84 | method output_reset = () |
|---|
| 85 | method is_active = true |
|---|
| 86 | |
|---|
| 87 | method get_frame frame = |
|---|
| 88 | assert (0 = MFrame.position frame); |
|---|
| 89 | let m = MFrame.tracks frame in |
|---|
| 90 | let t = self#get_events in |
|---|
| 91 | for c = 0 to Array.length m - 1 do |
|---|
| 92 | m.(c) := t |
|---|
| 93 | done; |
|---|
| 94 | MFrame.add_break frame (MFrame.size frame) |
|---|
| 95 | end |
|---|
| 96 | |
|---|
| 97 | let () = |
|---|
| 98 | Lang.add_operator "input.keyboard" |
|---|
| 99 | [ |
|---|
| 100 | ] |
|---|
| 101 | ~category:Lang.Input |
|---|
| 102 | ~flags:[Lang.Hidden; Lang.Experimental] |
|---|
| 103 | ~descr:"Play notes from the keyboard." |
|---|
| 104 | (fun p _ -> |
|---|
| 105 | (* let e f v = f (List.assoc v p) in *) |
|---|
| 106 | ((new keyboard):>Source.source) |
|---|
| 107 | ) |
|---|