Changeset 6695

Show
Ignore:
Timestamp:
06/29/09 16:06:52 (14 months ago)
Author:
smimram
Message:

Virtual keyboard and sine synth are now working. Just try

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

and press azerty.

Location:
trunk/liquidsoap/src
Files:
1 added
5 modified
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/liquidsoap/src/Makefile

    r6694 r6695  
    146146        visualization/video_volume.ml 
    147147 
    148 synth = synth/synth.ml \ 
    149         synth/keyboard.ml 
     148synth = synth/synth.ml synth/synth_op.ml \ 
     149        synth/keyboard.ml \ 
     150        $(if $(W_SDL),synth/keyboard_sdl.ml) 
    150151 
    151152liquidsoap_sources= $(tools) SVN.ml audio_converter.ml $(stream) \ 
  • trunk/liquidsoap/src/lang/lang.ml

    r6527 r6695  
    8080  | Input | Output 
    8181  | TrackProcessing | SoundProcessing | VideoProcessing 
    82   | Visualization 
     82  | Visualization | SoundSynthesis 
    8383 
    8484let string_of_category x = "Source / " ^ match x with 
     
    8888  | SoundProcessing -> "Sound Processing" 
    8989  | VideoProcessing -> "Video Processing" 
     90  | SoundSynthesis -> "Sound Synthesis" 
    9091  | Visualization -> "Visualization" 
    9192 
  • trunk/liquidsoap/src/lang/lang.mli

    r6527 r6695  
    8787  | VideoProcessing (** Operations on video. *) 
    8888  | Visualization (** Visializations of the sound. *) 
     89  | SoundSynthesis (** Synthesis. *) 
    8990 
    9091(** Get a string representation of a [doc_flag]. *) 
  • trunk/liquidsoap/src/synth/keyboard.ml

    r6694 r6695  
    3333 
    3434let note_of_char c = 
    35   array_index knotes c + 94 
     35  array_index knotes c + 72 
    3636 
    3737class keyboard = 
     
    6060      e 
    6161 
     62  val mutable reader = None 
     63 
    6264  method output_get_ready = 
    63     let _ = 
    64       Tutils.create 
    65         (fun () -> 
    66            while true do 
    67              let c = input_char stdin in 
    68                try 
    69                  Printf.printf "\nPlaying note %d.\n%!" (note_of_char c); 
    70                  self#add_event 0 (Midi.Note_on (note_of_char c, 0.8)) 
    71                with 
    72                  | Not_found -> () 
    73            done 
    74         ) () "Virtual keyboard" 
    75     in 
    76       () 
     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") 
    7783 
    7884  method output_reset = () 
  • trunk/liquidsoap/src/synth/keyboard_sdl.ml

    r6694 r6695  
    2121 *****************************************************************************) 
    2222 
    23 let knotes = [|'a'; '?'; 'z'; '"'; 'e'; 'r'; '('; 't'; '-'; 'y'; '?'; 'u'; 'i'; '?'; 'o'; '?'; 'p'|] 
     23let knotes = [|'a'; '\233'; 'z'; '"'; 'e'; 'r'; '('; 't'; '-'; 'y'; '\232'; 'u'; 'i'; '\231'; 'o'; '\224'; 'p'|] 
    2424 
    2525let array_index a x = 
     
    3333 
    3434let note_of_char c = 
    35   array_index knotes c + 94 
     35  array_index knotes c + 72 
    3636 
    37 class keyboard = 
     37class keyboard velocity = 
    3838object (self) 
    3939  inherit Source.active_source 
     
    4545  method output = if AFrame.is_partial memo then self#get_frame memo 
    4646 
    47   val mutable ev = [] 
    48   val ev_m = Mutex.create () 
     47  initializer 
     48    Sdl.init [`EVENTTHREAD; `VIDEO]; 
     49    Sdlevent.disable_events (Sdlevent.all_events_mask); 
     50    Sdlevent.enable_events (Sdlevent.make_mask [Sdlevent.KEYDOWN_EVENT; Sdlevent.KEYUP_EVENT; Sdlevent.QUIT_EVENT]); 
     51    ignore (Sdlvideo.set_video_mode ~w:640 ~h:480 ~bpp:16 []) 
    4952 
    50   method add_event (t:int) (e:Midi.event) = 
    51     Mutex.lock ev_m; 
    52     ev <- (t,e)::ev; 
    53     Mutex.unlock ev_m 
     53  val mutable reader = None 
    5454 
    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   method output_get_ready = 
    63     let _ = 
    64       Tutils.create 
    65         (fun () -> 
    66            while true do 
    67              let c = input_char stdin in 
    68                try 
    69                  Printf.printf "\nPlaying note %d.\n%!" (note_of_char c); 
    70                  self#add_event 0 (Midi.Note_on (note_of_char c, 0.8)) 
    71                with 
    72                  | Not_found -> () 
    73            done 
    74         ) () "Virtual keyboard" 
    75     in 
    76       () 
     55  method output_get_ready = () 
    7756 
    7857  method output_reset = () 
     
    8261    assert (0 = MFrame.position frame); 
    8362    let m = MFrame.tracks frame in 
    84     let t = self#get_events in 
     63    let t = 
     64      let ans = ref [] in 
     65        Sdlevent.pump (); 
     66        while Sdlevent.has_event () do 
     67          try 
     68            match Sdlevent.poll () with 
     69              | Some (Sdlevent.KEYDOWN k) -> 
     70                  let c = Sdlkey.char_of_key k.Sdlevent.keysym in 
     71                  let n = note_of_char c in 
     72                    Printf.printf "Playing note %d.\n%!" n; 
     73                    ans := (0,Midi.Note_on (n, velocity))::!ans 
     74              | Some (Sdlevent.KEYUP k) -> 
     75                  let c = Sdlkey.char_of_key k.Sdlevent.keysym in 
     76                  let n = note_of_char c in 
     77                    Printf.printf "Stopping note %d.\n%!" n; 
     78                    ans := (0,Midi.Note_off (n, velocity))::!ans 
     79              | _ -> () 
     80          with 
     81            | Not_found 
     82            | Invalid_argument _ -> () 
     83        done; 
     84        !ans 
     85    in 
    8586      for c = 0 to Array.length m - 1 do 
    8687        m.(c) := t 
     
    9091 
    9192let () = 
    92   Lang.add_operator "input.keyboard" 
     93  Lang.add_operator "input.keyboard.sdl" 
    9394    [ 
     95      "velocity", Lang.float_t, Some (Lang.float 0.3), Some "Velocity of notes." 
    9496    ] 
    9597    ~category:Lang.Input 
    96     ~flags:[Lang.Hidden; Lang.Experimental] 
     98    ~flags:[Lang.Experimental] 
    9799    ~descr:"Play notes from the keyboard." 
    98100    (fun p _ -> 
    99        (* let e f v = f (List.assoc v p) in *) 
    100          ((new keyboard):>Source.source) 
     101       let f v = List.assoc v p in 
     102       let velocity = Lang.to_float (f "velocity") in 
     103         ((new keyboard velocity):>Source.source) 
    101104    ) 
  • trunk/liquidsoap/src/synth/synth.ml

    r6694 r6695  
    33let freq_of_note n = 440. *. (2. ** ((float n -. 69.) /. 12.)) 
    44 
     5class type synth = 
     6object 
     7  method note_on : int -> float -> unit 
     8 
     9  method note_off : int -> float -> unit 
     10 
     11  method synth : float -> float array array -> int -> int -> unit 
     12end 
     13 
    514(* Global state and note state. *) 
    6 class virtual ['gs,'ns] synth = 
     15class virtual ['gs,'ns] base = 
    716object (self) 
    817  val mutable state = None 
     
    2231    state <- Some (self#state_init) 
    2332 
     33  initializer 
     34    self#init 
     35 
    2436  method note_on n v = 
    2537    notes <- (n, ref (self#note_init n v))::notes 
    2638 
    2739  method note_off n (v:float) = 
     40    (* TODO: remove only one note *) 
    2841    notes <- List.filter (fun (m, _) -> m <> n) notes 
    2942 
     
    6174class sine = 
    6275object (self) 
    63   inherit [sine_gs, sine_ns] synth 
     76  inherit [sine_gs, sine_ns] base 
    6477 
    6578  method state_init = () 
    6679 
    67   method note_init n v = { sine_phase = 0.; sine_freq = freq_of_note n; sine_ampl = v } 
     80  method note_init n v = { sine_phase = (*Random.float (2. *. pi)*) 0.; sine_freq = freq_of_note n; sine_ampl = v } 
    6881 
    6982  method synth_note_mono gs ns freq buf ofs len = 
    7083    let phase i = ns.sine_phase +. float i /. freq *. ns.sine_freq *. 2. *. pi in 
    7184      for i = ofs to ofs + len - 1 do 
    72         buf.(i) <- ns.sine_ampl *. sin (phase i) 
     85        buf.(i) <- buf.(i) +. ns.sine_ampl *. sin (phase i) 
    7386      done; 
    74       gs, { ns with sine_phase = phase len} 
     87      gs, { ns with sine_phase = phase len } 
    7588end