File: shine_encoder.ml

package info (click to toggle)
liquidsoap 1.1.1-7.2
  • links: PTS, VCS
  • area: main
  • in suites: sid, stretch
  • size: 4,568 kB
  • ctags: 4,447
  • sloc: ml: 34,126; python: 956; makefile: 630; sh: 493; perl: 258; lisp: 62; ansic: 43; ruby: 8
file content (89 lines) | stat: -rw-r--r-- 2,982 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
(*****************************************************************************

  Liquidsoap, a programmable audio stream generator.
  Copyright 2003-2013 Savonet team

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details, fully stated in the COPYING
  file at the root of the liquidsoap distribution.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

 *****************************************************************************)

(** Fixed-point MP3 encoder *)

open Encoder.Shine
module G = Generator.Generator

let create_encoder ~samplerate ~bitrate ~channels =
  Shine.create
    { Shine.
       channels   = channels; 
       samplerate = samplerate;
       bitrate    = bitrate }

let encoder shine =
  let channels = shine.channels in
  let enc = create_encoder ~samplerate:shine.samplerate 
                           ~bitrate:shine.bitrate 
                           ~channels 
  in
  let samplerate_converter =
    Audio_converter.Samplerate.create channels
  in
  let samplerate = shine.samplerate in
  let src_freq = float (Frame.audio_of_seconds 1.) in
  let dst_freq = float samplerate in
  (* Shine accepts data of a fixed length.. *)
  let samples = Shine.samples_per_pass enc in
  let data = Audio.create channels samples in
  let buf = G.create () in
  let encoded = Buffer.create 1024 in
  let encode frame start len =
    let start = Frame.audio_of_master start in
    let b = AFrame.content_of_type ~channels frame start in
    let len = Frame.audio_of_master len in
    let b,start,len =
      if src_freq <> dst_freq then
        let b = Audio_converter.Samplerate.resample
          samplerate_converter (dst_freq /. src_freq)
          b start len
        in
        b,0,Array.length b.(0)
      else
        Audio.copy b,start,len
    in
    G.put buf b start len ;
    while (G.length buf > samples) do
      let l = G.get buf samples in
      let f (b,o,o',l) = 
        Audio.blit b o data o' l
      in
      List.iter f l ;
      Buffer.add_string encoded (Shine.encode_buffer enc data)
    done ;
    let ret = Buffer.contents encoded in
    Buffer.reset encoded;
    ret
  in
  let stop () = Shine.flush enc in
  { Encoder.
     insert_metadata = (fun m -> ()) ;
     header = None ;
     encode = encode ;
     stop = stop }

let () = Encoder.plug#register "SHINE"
  (function
     | Encoder.Shine m -> Some (fun _ _ -> encoder m)
     | _ -> None)