root/trunk/liquidsoap/src/synth/keyboard.ml @ 6695

Revision 6695, 3.1 KB (checked in by smimram, 15 months ago)

Virtual keyboard and sine synth are now working. Just try

out(synth.sine(input.keyboard.sdl()))

and press azerty.

Line 
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
23let knotes = [|'a'; '?'; 'z'; '"'; 'e'; 'r'; '('; 't'; '-'; 'y'; '?'; 'u'; 'i'; '?'; 'o'; '?'; 'p'|]
24
25let 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
34let note_of_char c =
35  array_index knotes c + 72
36
37class keyboard =
38object (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)
95end
96
97let () =
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    )
Note: See TracBrowser for help on using the browser.