From 6521f346fcc60563f3ccca671005c98d366f54c1 Mon Sep 17 00:00:00 2001 From: ilyapashuk Date: Tue, 24 Aug 2021 17:13:30 +0300 Subject: [PATCH 1/5] add sinusoid tone generation --- examples/tone-player/main.go | 20 ++++++++++++++++ toner.go | 45 ++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 examples/tone-player/main.go create mode 100644 toner.go diff --git a/examples/tone-player/main.go b/examples/tone-player/main.go new file mode 100644 index 0000000..06c2006 --- /dev/null +++ b/examples/tone-player/main.go @@ -0,0 +1,20 @@ +package main + +import "os" +import "fmt" +import "github.com/faiface/beep" +import "github.com/faiface/beep/speaker" +import "strconv" + +func main() { +f,_ := strconv.Atoi(os.Args[1]) +speaker.Init(beep.SampleRate(48000), 4800) +s := beep.SinTone(beep.SampleRate(48000), f) +rb := make([][2]float64,20) +s.Stream(rb) +fmt.Println(rb) +speaker.Play(s) +for { + +} +} \ No newline at end of file diff --git a/toner.go b/toner.go new file mode 100644 index 0000000..090efe5 --- /dev/null +++ b/toner.go @@ -0,0 +1,45 @@ +// tones generator + + +package beep + +import "math" + +// simple sinusoid tone generator +type toneStreamer struct { +stat float64 +delta float64 +} + +// create streamer which will produce infinite sinusoid tone with the given frequency +// use other wrappers of this package to change amplitude or add time limit +// sampleRate must be at least two times grater then frequency, otherwise this function will panic +func SinTone(sr SampleRate, freq int) Streamer { +if int(sr) / freq < 2 { +panic("samplerate must be at least 2 times grater then frequency") +} +r := new(toneStreamer) +r.stat = 0.0 +srf := float64(sr) +ff := float64(freq) +steps := srf / ff +r.delta = 1.0 / steps +return r +} + +func (c *toneStreamer) nextSample() float64 { +r := math.Sin(c.stat * 2.0 * math.Pi) +_,c.stat = math.Modf(c.stat + c.delta) +return r +} + +func (c *toneStreamer) Stream(buf [][2]float64) (int, bool) { +for i := 0; i < len(buf); i++ { +s := c.nextSample() +buf[i] = [2]float64{s,s} +} +return len(buf),true +} +func (_ *toneStreamer) Err() error { +return nil +} \ No newline at end of file From 7ac400afc64a53530515ea1b812e40b0c3f64441 Mon Sep 17 00:00:00 2001 From: ilyapashuk Date: Tue, 31 Aug 2021 17:25:35 +0300 Subject: [PATCH 2/5] tone generator moved to separate subpackage --- examples/tone-player/main.go | 9 +++------ toner.go => generators/toner.go | 3 ++- 2 files changed, 5 insertions(+), 7 deletions(-) rename toner.go => generators/toner.go (94%) diff --git a/examples/tone-player/main.go b/examples/tone-player/main.go index 06c2006..9270a9c 100644 --- a/examples/tone-player/main.go +++ b/examples/tone-player/main.go @@ -1,18 +1,15 @@ package main import "os" -import "fmt" -import "github.com/faiface/beep" +import "github.com/faiface/beep/generators" import "github.com/faiface/beep/speaker" +import "github.com/faiface/beep" import "strconv" func main() { f,_ := strconv.Atoi(os.Args[1]) speaker.Init(beep.SampleRate(48000), 4800) -s := beep.SinTone(beep.SampleRate(48000), f) -rb := make([][2]float64,20) -s.Stream(rb) -fmt.Println(rb) +s := generators.SinTone(beep.SampleRate(48000), f) speaker.Play(s) for { diff --git a/toner.go b/generators/toner.go similarity index 94% rename from toner.go rename to generators/toner.go index 090efe5..2283990 100644 --- a/toner.go +++ b/generators/toner.go @@ -1,9 +1,10 @@ // tones generator -package beep +package generators import "math" +import . "github.com/faiface/beep" // simple sinusoid tone generator type toneStreamer struct { From 3bbf86975440ee7d0a3defa439bc473f49895989 Mon Sep 17 00:00:00 2001 From: ilyapashuk Date: Tue, 31 Aug 2021 17:30:22 +0300 Subject: [PATCH 3/5] generator function now returns an error instead of panic --- examples/tone-player/main.go | 5 ++++- generators/toner.go | 9 +++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/examples/tone-player/main.go b/examples/tone-player/main.go index 9270a9c..84c9bcc 100644 --- a/examples/tone-player/main.go +++ b/examples/tone-player/main.go @@ -9,7 +9,10 @@ import "strconv" func main() { f,_ := strconv.Atoi(os.Args[1]) speaker.Init(beep.SampleRate(48000), 4800) -s := generators.SinTone(beep.SampleRate(48000), f) +s,err := generators.SinTone(beep.SampleRate(48000), f) +if err != nil { +panic(err) +} speaker.Play(s) for { diff --git a/generators/toner.go b/generators/toner.go index 2283990..eec31ce 100644 --- a/generators/toner.go +++ b/generators/toner.go @@ -4,6 +4,7 @@ package generators import "math" +import "errors" import . "github.com/faiface/beep" // simple sinusoid tone generator @@ -14,10 +15,10 @@ delta float64 // create streamer which will produce infinite sinusoid tone with the given frequency // use other wrappers of this package to change amplitude or add time limit -// sampleRate must be at least two times grater then frequency, otherwise this function will panic -func SinTone(sr SampleRate, freq int) Streamer { +// sampleRate must be at least two times grater then frequency, otherwise this function will return an error +func SinTone(sr SampleRate, freq int) (Streamer, error) { if int(sr) / freq < 2 { -panic("samplerate must be at least 2 times grater then frequency") +return nil,errors.New("faiface beep tone generator: samplerate must be at least 2 times grater then frequency") } r := new(toneStreamer) r.stat = 0.0 @@ -25,7 +26,7 @@ srf := float64(sr) ff := float64(freq) steps := srf / ff r.delta = 1.0 / steps -return r +return r,nil } func (c *toneStreamer) nextSample() float64 { From 451b3a82a45762b2b9ea39a8b367ed54de4520fb Mon Sep 17 00:00:00 2001 From: ilyapashuk Date: Tue, 31 Aug 2021 17:35:42 +0300 Subject: [PATCH 4/5] code linting --- examples/tone-player/main.go | 31 +++++++++++---------- generators/toner.go | 53 ++++++++++++++++++------------------ 2 files changed, 43 insertions(+), 41 deletions(-) diff --git a/examples/tone-player/main.go b/examples/tone-player/main.go index 84c9bcc..a2f1a64 100644 --- a/examples/tone-player/main.go +++ b/examples/tone-player/main.go @@ -1,20 +1,21 @@ package main -import "os" -import "github.com/faiface/beep/generators" -import "github.com/faiface/beep/speaker" -import "github.com/faiface/beep" -import "strconv" - +import ( + "os" + "github.com/faiface/beep/generators" + "github.com/faiface/beep/speaker" + "github.com/faiface/beep" + "strconv" +) func main() { -f,_ := strconv.Atoi(os.Args[1]) -speaker.Init(beep.SampleRate(48000), 4800) -s,err := generators.SinTone(beep.SampleRate(48000), f) -if err != nil { -panic(err) -} -speaker.Play(s) -for { + f, _ := strconv.Atoi(os.Args[1]) + speaker.Init(beep.SampleRate(48000), 4800) + s, err := generators.SinTone(beep.SampleRate(48000), f) + if err != nil { + panic(err) + } + speaker.Play(s) + for { + } } -} \ No newline at end of file diff --git a/generators/toner.go b/generators/toner.go index eec31ce..01ee03a 100644 --- a/generators/toner.go +++ b/generators/toner.go @@ -1,47 +1,48 @@ // tones generator - package generators -import "math" -import "errors" -import . "github.com/faiface/beep" +import ( + "math" + "errors" + . "github.com/faiface/beep" +) // simple sinusoid tone generator type toneStreamer struct { -stat float64 -delta float64 + stat float64 + delta float64 } // create streamer which will produce infinite sinusoid tone with the given frequency // use other wrappers of this package to change amplitude or add time limit // sampleRate must be at least two times grater then frequency, otherwise this function will return an error func SinTone(sr SampleRate, freq int) (Streamer, error) { -if int(sr) / freq < 2 { -return nil,errors.New("faiface beep tone generator: samplerate must be at least 2 times grater then frequency") -} -r := new(toneStreamer) -r.stat = 0.0 -srf := float64(sr) -ff := float64(freq) -steps := srf / ff -r.delta = 1.0 / steps -return r,nil + if int(sr)/freq < 2 { + return nil, errors.New("faiface beep tone generator: samplerate must be at least 2 times grater then frequency") + } + r := new(toneStreamer) + r.stat = 0.0 + srf := float64(sr) + ff := float64(freq) + steps := srf / ff + r.delta = 1.0 / steps + return r, nil } func (c *toneStreamer) nextSample() float64 { -r := math.Sin(c.stat * 2.0 * math.Pi) -_,c.stat = math.Modf(c.stat + c.delta) -return r + r := math.Sin(c.stat * 2.0 * math.Pi) + _, c.stat = math.Modf(c.stat + c.delta) + return r } func (c *toneStreamer) Stream(buf [][2]float64) (int, bool) { -for i := 0; i < len(buf); i++ { -s := c.nextSample() -buf[i] = [2]float64{s,s} -} -return len(buf),true + for i := 0; i < len(buf); i++ { + s := c.nextSample() + buf[i] = [2]float64{s, s} + } + return len(buf), true } func (_ *toneStreamer) Err() error { -return nil -} \ No newline at end of file + return nil +} From 1a05c2cef93445cf5b5972ee3717fa6939b20c00 Mon Sep 17 00:00:00 2001 From: ilyapashuk Date: Tue, 31 Aug 2021 17:56:12 +0300 Subject: [PATCH 5/5] added usage message for tone-player example --- examples/tone-player/main.go | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/examples/tone-player/main.go b/examples/tone-player/main.go index a2f1a64..93f87d6 100644 --- a/examples/tone-player/main.go +++ b/examples/tone-player/main.go @@ -1,14 +1,29 @@ package main import ( - "os" + "fmt" + "github.com/faiface/beep" "github.com/faiface/beep/generators" "github.com/faiface/beep/speaker" - "github.com/faiface/beep" + "os" "strconv" ) + +func usage() { + fmt.Printf("usage: %s freq\n", os.Args[0]) + fmt.Println("where freq must be an integer from 1 to 24000") + fmt.Println("24000 because samplerate of 48000 is hardcoded") +} func main() { - f, _ := strconv.Atoi(os.Args[1]) + if len(os.Args) < 2 { + usage() + return + } + f, err := strconv.Atoi(os.Args[1]) + if err != nil { + usage() + return + } speaker.Init(beep.SampleRate(48000), 4800) s, err := generators.SinTone(beep.SampleRate(48000), f) if err != nil {