spectrogram: add golang spectrogram generator

This commit is contained in:
Trek H 2022-03-10 16:18:26 +10:30
parent c4e4cc750f
commit 943a61f359
3 changed files with 132 additions and 0 deletions

126
exp/spectrogram/main.go Normal file
View File

@ -0,0 +1,126 @@
/*
DESCRIPTION
AUTHORS
Trek Hopton <trek@ausocean.org>
LICENSE
Copyright (C) 2020 the Australian Ocean Lab (AusOcean)
It is free software: you can redistribute it and/or modify them
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
It 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.
You should have received a copy of the GNU General Public License
in gpl.txt. If not, see http://www.gnu.org/licenses.
*/
// Package spectrogram is a program that generates a spectrogram given an audio file.
// package main
package main
import (
"flag"
"fmt"
"image"
"image/draw"
"log"
"os"
"github.com/trekhopton/spectrogram"
"github.com/xigh/go-wavreader"
)
func main() {
flag.Parse()
if flag.NArg() == 0 {
fmt.Printf("usage: fft [options] file.wav\n")
return
}
name := flag.Arg(0)
r, err := os.Open(name)
if err != nil {
log.Fatal(err)
}
defer r.Close()
wr, err := wavreader.New(r)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s: %dHz, %d channels, %d samples, %v\n",
name, wr.Rate(), wr.Chans(), wr.Len(), wr.Duration())
start := *spectrogram.OFFSET
if start > wr.Len() {
log.Fatalf("offset bigger than file")
}
length := *spectrogram.LENGTH
if start+length > wr.Len() {
log.Printf("length too long\n")
length = wr.Len() - start
}
length = wr.Len()
samples := make([]float64, length)
for i := uint64(0); i < length; i++ {
s, err := wr.At(0, start+i)
if err != nil {
log.Fatal(err)
}
samples[i] = float64(s)
}
if *spectrogram.PREEMP > 0 {
for i := len(samples) - 1; i > 0; i-- {
samples[i] = samples[i] - *spectrogram.PREEMP*samples[i-1]
}
}
W := int(*spectrogram.WIDTH)
H := int(*spectrogram.HEIGHT)
B := int(*spectrogram.BINS)
bounds := image.Rect(-20, -20, W+20, H+40+B)
img := spectrogram.NewImage128(bounds)
bg0 := spectrogram.ParseColor(*spectrogram.BG0)
fmt.Printf("bg0: %.8x\n", bg0)
draw.Draw(img, img.Bounds(), image.NewUniform(bg0), image.ZP, draw.Src)
fmt.Println("drawwav:")
i0 := img.Sub(image.Rect(0, 0, W, H))
spectrogram.Drawwav(i0, samples)
fmt.Println("drawfft:")
i1 := img.Sub(image.Rect(0, H+20, W, H+20+B))
spectrogram.Drawfft(i1, samples, wr.Rate(), uint32(B))
a0, s0 := img.Stats()
fmt.Printf("img stats: %d reads, %d writes\n", a0, s0)
fmt.Printf("saving %q\n", *spectrogram.OUT)
err = spectrogram.SavePng(img, *spectrogram.OUT)
if err != nil {
log.Fatalf("savePng failed: %v", err)
}
fmt.Printf("saved %q\n", *spectrogram.OUT)
a1, s1 := img.Stats()
fmt.Printf("img stats: %d reads, %d writes\n", a1, s1)
}

2
go.mod
View File

@ -12,6 +12,8 @@ require (
github.com/kidoman/embd v0.0.0-20170508013040-d3d8c0c5c68d github.com/kidoman/embd v0.0.0-20170508013040-d3d8c0c5c68d
github.com/mewkiz/flac v1.0.5 github.com/mewkiz/flac v1.0.5
github.com/pkg/errors v0.9.1 github.com/pkg/errors v0.9.1
github.com/trekhopton/spectrogram v1.0.0
github.com/xigh/go-wavreader v0.0.0-20210516212152-f49019aa7352
github.com/yobert/alsa v0.0.0-20180630182551-d38d89fa843e github.com/yobert/alsa v0.0.0-20180630182551-d38d89fa843e
gocv.io/x/gocv v0.29.0 gocv.io/x/gocv v0.29.0
gonum.org/v1/gonum v0.9.3 gonum.org/v1/gonum v0.9.3

4
go.sum
View File

@ -83,6 +83,10 @@ github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/trekhopton/spectrogram v1.0.0 h1:Y1+G+oTDtNCrnuEjgm91s8Uyi0dF6vjwB+VTLECPoKw=
github.com/trekhopton/spectrogram v1.0.0/go.mod h1:ea0tlSV7WC0Rqq9PcY2DGN88Lw13lAhCOPFUK8U/2zk=
github.com/xigh/go-wavreader v0.0.0-20210516212152-f49019aa7352 h1:iK7SnIgPre4wrUN7HpIhZpfP7884mcc7CQS3FeyGTes=
github.com/xigh/go-wavreader v0.0.0-20210516212152-f49019aa7352/go.mod h1:SiPEYpvfimzIRkLfaOYXVNGbQGVmgQZ6BQHcKyj/iic=
github.com/yobert/alsa v0.0.0-20180630182551-d38d89fa843e h1:3NIzz7weXhh3NToPgbtlQtKiVgerEaG4/nY2skGoGG0= github.com/yobert/alsa v0.0.0-20180630182551-d38d89fa843e h1:3NIzz7weXhh3NToPgbtlQtKiVgerEaG4/nY2skGoGG0=
github.com/yobert/alsa v0.0.0-20180630182551-d38d89fa843e/go.mod h1:CaowXBWOiSGWEpBBV8LoVnQTVPV4ycyviC9IBLj8dRw= github.com/yobert/alsa v0.0.0-20180630182551-d38d89fa843e/go.mod h1:CaowXBWOiSGWEpBBV8LoVnQTVPV4ycyviC9IBLj8dRw=
github.com/yryz/ds18b20 v0.0.0-20180211073435-3cf383a40624/go.mod h1:MqFju5qeLDFh+S9PqxYT7TEla8xeW7bgGr/69q3oki0= github.com/yryz/ds18b20 v0.0.0-20180211073435-3cf383a40624/go.mod h1:MqFju5qeLDFh+S9PqxYT7TEla8xeW7bgGr/69q3oki0=