mirror of https://bitbucket.org/ausocean/av.git
spectrogram: add golang spectrogram generator
This commit is contained in:
parent
c4e4cc750f
commit
943a61f359
|
@ -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
2
go.mod
|
@ -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
4
go.sum
|
@ -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=
|
||||||
|
|
Loading…
Reference in New Issue