Changeset 6705

Show
Ignore:
Timestamp:
07/01/09 13:00:58 (14 months ago)
Author:
smimram
Message:

Complete midi files support.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/liquidsoap/src/formats/midiformat.ml

    r6703 r6705  
    197197                          let t3 = get_byte () in 
    198198                          let t = t1 lsl 16 + t2 lsl 8 + t3 in 
    199                             ignore t; 
    200199                            None, Midi.Tempo t 
    201200                      | 0x58 (* Time signature *) -> 
     
    205204                          let c = get_byte () in (* ticks in a metronome click *) 
    206205                          let b = get_byte () in (* 32nd notes to the quarter note *) 
    207                             ignore (n, d, c, b); 
    208206                            None, Midi.Time_signature (n, d, c, b) 
    209207                      | 0x59 (* Key signature *) -> 
     
    211209                          let sf = get_byte () in (* sharps / flats *) 
    212210                          let m = get_byte () in (* minor? *) 
    213                             ignore (sf, m); 
    214211                            None, Midi.Key_signature (sf, m <> 0) 
    215212                      | 0x54 (* SMPTE Offset *) 
     
    256253    (* We don't need to access the file anymore. *) 
    257254    close (); 
     255    (* Merge all tracks. *) 
     256    let track = 
     257      let find_min () = 
     258        let ans = ref None in 
     259          for c = 0 to Array.length tracks - 1 do 
     260            match tracks.(c) with 
     261              | [] -> () 
     262              | (d,_)::_ -> 
     263                  match !ans with 
     264                    | None -> 
     265                        ans := Some (d, c) 
     266                    | Some (d',_) -> 
     267                        if d < d' then ans := Some (d, c) 
     268          done; 
     269          match !ans with 
     270            | Some (d, c) -> d,c 
     271            | None -> raise Not_found 
     272      in 
     273      let ans = ref [] in 
     274        try 
     275          while true do 
     276            let d,c = find_min () in 
     277              ans := (List.hd tracks.(c)) :: !ans; 
     278              tracks.(c) <- List.tl tracks.(c); 
     279              Array.iteri 
     280                (fun n t -> 
     281                   if n <> c && t <> [] then 
     282                     let d',e = List.hd t in 
     283                       tracks.(n) <- (d'-d,e)::(List.tl t) 
     284                ) tracks 
     285          done; 
     286          assert false 
     287        with 
     288          | Not_found -> List.rev !ans 
     289    in 
    258290    (* Convert delta-times in delta-liquidsoap-ticks. *) 
    259     for n = 0 to ntracks - 1 do 
     291    let track = 
    260292      let tpq = 
    261293        match division with 
     
    264296      in 
    265297      let tempo = ref 125000 in 
    266         tracks.(n) <- 
    267           List.map 
    268             (fun (d,(c,e)) -> 
    269                let d = (d * !tempo / tpq) * Fmt.ticks_per_second () / 1000000 in 
    270                let d = d * 1 in (* TODO: remove this! *) 
    271                  ( 
    272                    match e with 
    273                      | Midi.Tempo t -> 
    274                          tempo := t 
    275                      | _ -> () 
    276                  ); 
    277                  (d,(c,e)) 
    278             ) tracks.(n) 
    279     done; 
    280     (* Merge all tracks. *) 
    281     let track = ref tracks.(0) in (* TODO! *) 
     298        List.map 
     299          (fun (d,(c,e)) -> 
     300             let d = (d * !tempo / tpq) * Fmt.ticks_per_second () / 1000000 in 
     301               ( 
     302                 match e with 
     303                   | Midi.Tempo t -> 
     304                       tempo := t 
     305                   | _ -> () 
     306               ); 
     307               (d,(c,e)) 
     308          ) track 
     309    in 
    282310    (* Filling function. *) 
     311    let track = ref track in 
    283312    let fill buf = 
    284313      let m = MFrame.tracks buf in 
     
    302331                          | Midi.Note_off _ -> 
    303332                              (* Printf.printf "EVENT (chan %d)!\n%!" c; *) 
    304                               let c = if c <> 10 then 0 else c in (* TODO: remove this *) 
    305333                              m.(c) := !(m.(c))@[!offset_in_buf, e] 
    306334                          | _ -> () (* TODO *) 
     
    311339              track := (!offset_in_buf - buflen,(c,e))::(List.tl !track) 
    312340        done; 
    313         MFrame.add_break buf (MFrame.size buf); 
     341        if !track = [] then 
     342          MFrame.add_break buf 0 
     343        else 
     344          MFrame.add_break buf (MFrame.size buf); 
    314345        0 
    315346    in