• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

gabyfle / SoundML / 32

14 May 2025 11:22PM UTC coverage: 43.312% (-11.7%) from 54.982%
32

push

github

gabyfle
STFT implementation, and various other things

- Modified the testing framework
- Added cosine_sum window function and now using it to compute various window functions
- Added STFT computation (this should close https://github.com/gabyfle/SoundML/issues/8)
- Added tests for STFT to compare results against librosa

50 of 71 new or added lines in 3 files covered. (70.42%)

9 existing lines in 1 file now uncovered.

204 of 471 relevant lines covered (43.31%)

35314.87 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

61.11
/src/window.ml
1
(*****************************************************************************)
2
(*                                                                           *)
3
(*                                                                           *)
4
(*  Copyright (C) 2023                                                       *)
5
(*    Gabriel Santamaria                                                     *)
6
(*                                                                           *)
7
(*                                                                           *)
8
(*  Licensed under the Apache License, Version 2.0 (the "License");          *)
9
(*  you may not use this file except in compliance with the License.         *)
10
(*  You may obtain a copy of the License at                                  *)
11
(*                                                                           *)
12
(*    http://www.apache.org/licenses/LICENSE-2.0                             *)
13
(*                                                                           *)
14
(*  Unless required by applicable law or agreed to in writing, software      *)
15
(*  distributed under the License is distributed on an "AS IS" BASIS,        *)
16
(*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *)
17
(*  See the License for the specific language governing permissions and      *)
18
(*  limitations under the License.                                           *)
19
(*                                                                           *)
20
(*****************************************************************************)
21

22
open Types
23

24
type window = [`Hanning | `Hamming | `Blackman | `Boxcar]
25

26
let kind_of_precision : type a b. (a, b) precision -> (float, a) Bigarray.kind =
27
 fun prec -> match prec with B32 -> Bigarray.Float32 | B64 -> Bigarray.Float64
8✔
28

NEW
29
let cosine_sum ?(fftbins = false) (prec : ('a, 'b) precision) (a : float array)
×
30
    m =
31
  let kd = kind_of_precision prec in
42✔
32
  if m < 0 then invalid_arg "Window length M must be a non-negative integer"
1✔
33
  else if m = 0 then Audio.G.empty kd [|0|]
2✔
34
  else if m = 1 then Audio.G.ones kd [|1|]
2✔
35
  else
36
    let sym = not fftbins in
37✔
37
    let m_extended, needs_trunc =
38
      if not sym then (m + 1, true) else (m, false)
7✔
39
    in
40
    let fac = Audio.G.linspace kd (-.Owl_const.pi) Owl_const.pi m_extended in
37✔
41
    let w = Audio.G.zeros kd [|m_extended|] in
37✔
42
    Array.iteri
37✔
43
      (fun k coeff_val ->
44
        if coeff_val <> 0.0 then
71✔
45
          let term =
70✔
46
            if k = 0 then Audio.G.create kd [|m_extended|] coeff_val
35✔
47
            else
48
              let k_float = float_of_int k in
35✔
49
              let cos_args = Audio.G.mul_scalar fac k_float in
35✔
50
              let cos_terms = Audio.G.cos cos_args in
35✔
51
              Audio.G.mul_scalar cos_terms coeff_val
35✔
52
          in
53
          Audio.G.add_ ~out:w w term )
54
      a ;
55
    if needs_trunc then Audio.G.get_slice [[0; m - 1]] w else w
7✔
56

NEW
57
let hanning ?(fftbins = false) (prec : ('a, 'b) precision) m =
×
58
  cosine_sum ~fftbins prec [|0.5; 1. -. 0.5|] m
24✔
59

NEW
60
let hamming ?(fftbins = false) (prec : ('a, 'b) precision) m =
×
NEW
61
  cosine_sum ~fftbins prec [|0.54; 1. -. 0.54|] m
×
62

NEW
63
let blackman ?(fftbins = false) (prec : ('a, 'b) precision) m =
×
NEW
64
  cosine_sum ~fftbins prec [|0.42; 0.5; 0.08|] m
×
65

NEW
66
let boxcar ?(fftbins = false) (prec : ('a, 'b) precision) (size : int) :
×
67
    (float, 'a) Audio.G.t =
NEW
68
  let kd = kind_of_precision prec in
×
NEW
69
  if size < 0 then failwith "Window length M must be non-negative"
×
NEW
70
  else if size = 0 then Audio.G.empty kd [|0|]
×
NEW
71
  else Audio.G.ones kd [|size|]
×
72
[@@warning "-27"]
73

74
let get (typ : window) (prec : ('a, 'b) precision) :
75
    ?fftbins:bool -> int -> (float, 'a) Audio.G.t =
76
 fun ?fftbins size ->
24✔
77
  match typ with
24✔
78
  | `Hanning ->
24✔
79
      hanning ?fftbins prec size
NEW
80
  | `Hamming ->
×
81
      hamming ?fftbins prec size
NEW
82
  | `Blackman ->
×
83
      blackman ?fftbins prec size
NEW
84
  | `Boxcar ->
×
85
      boxcar ?fftbins prec size
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc