]> Sergey Matveev's repositories - vors.git/blob - cmd/vad/main.go
vors-vad automatically starts rec
[vors.git] / cmd / vad / main.go
1 // VoRS -- Vo(IP) Really Simple
2 // Copyright (C) 2024 Sergey Matveev <stargrave@stargrave.org>
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, version 3 of the License.
7 //
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 // GNU Affero General Public License for more details.
12 //
13 // You should have received a copy of the GNU Affero General Public License
14 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
15
16 package main
17
18 import (
19         "flag"
20         "fmt"
21         "io"
22         "log"
23         "os"
24         "strconv"
25
26         vors "go.stargrave.org/vors/internal"
27 )
28
29 func usage() {
30         fmt.Fprintf(os.Stderr, "Usage: vors-vad [-rec ...] THRESHOLD\n")
31         flag.PrintDefaults()
32 }
33
34 func main() {
35         recCmd := flag.String("rec", "rec "+vors.SoxParams, "rec command")
36         flag.Usage = usage
37         flag.Parse()
38         log.SetFlags(log.Lmicroseconds | log.Lshortfile)
39         if len(flag.Args()) != 1 {
40                 usage()
41                 os.Exit(1)
42         }
43         thres, err := strconv.ParseUint(flag.Arg(0), 10, 64)
44         if err != nil {
45                 log.Fatal(err)
46         }
47         buf := make([]byte, 2*vors.FrameLen)
48         pcm := make([]int16, vors.FrameLen)
49         cmd := vors.MakeCmd(*recCmd)
50         mic, err := cmd.StdoutPipe()
51         if err != nil {
52                 log.Fatal(err)
53         }
54         err = cmd.Start()
55         if err != nil {
56                 log.Fatal(err)
57         }
58         var rms uint64
59         var i int
60         for {
61                 _, err = io.ReadFull(mic, buf)
62                 if err != nil {
63                         panic(err)
64                 }
65                 for i = 0; i < vors.FrameLen; i++ {
66                         pcm[i] = int16(uint16(buf[i*2+0]) | (uint16(buf[i*2+1]) << 8))
67                 }
68                 rms = vors.RMS(pcm)
69                 if rms > thres {
70                         fmt.Println(rms)
71                 }
72         }
73 }