Skip to content

Commit e62bf86

Browse files
authored
Merge pull request #127 from ilyapashuk/master
add sinusoid tone generation
2 parents 00d0eee + 1a05c2c commit e62bf86

File tree

2 files changed

+84
-0
lines changed

2 files changed

+84
-0
lines changed

examples/tone-player/main.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"github.com/faiface/beep"
6+
"github.com/faiface/beep/generators"
7+
"github.com/faiface/beep/speaker"
8+
"os"
9+
"strconv"
10+
)
11+
12+
func usage() {
13+
fmt.Printf("usage: %s freq\n", os.Args[0])
14+
fmt.Println("where freq must be an integer from 1 to 24000")
15+
fmt.Println("24000 because samplerate of 48000 is hardcoded")
16+
}
17+
func main() {
18+
if len(os.Args) < 2 {
19+
usage()
20+
return
21+
}
22+
f, err := strconv.Atoi(os.Args[1])
23+
if err != nil {
24+
usage()
25+
return
26+
}
27+
speaker.Init(beep.SampleRate(48000), 4800)
28+
s, err := generators.SinTone(beep.SampleRate(48000), f)
29+
if err != nil {
30+
panic(err)
31+
}
32+
speaker.Play(s)
33+
for {
34+
35+
}
36+
}

generators/toner.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// tones generator
2+
3+
package generators
4+
5+
import (
6+
"math"
7+
"errors"
8+
. "github.com/faiface/beep"
9+
)
10+
11+
// simple sinusoid tone generator
12+
type toneStreamer struct {
13+
stat float64
14+
delta float64
15+
}
16+
17+
// create streamer which will produce infinite sinusoid tone with the given frequency
18+
// use other wrappers of this package to change amplitude or add time limit
19+
// sampleRate must be at least two times grater then frequency, otherwise this function will return an error
20+
func SinTone(sr SampleRate, freq int) (Streamer, error) {
21+
if int(sr)/freq < 2 {
22+
return nil, errors.New("faiface beep tone generator: samplerate must be at least 2 times grater then frequency")
23+
}
24+
r := new(toneStreamer)
25+
r.stat = 0.0
26+
srf := float64(sr)
27+
ff := float64(freq)
28+
steps := srf / ff
29+
r.delta = 1.0 / steps
30+
return r, nil
31+
}
32+
33+
func (c *toneStreamer) nextSample() float64 {
34+
r := math.Sin(c.stat * 2.0 * math.Pi)
35+
_, c.stat = math.Modf(c.stat + c.delta)
36+
return r
37+
}
38+
39+
func (c *toneStreamer) Stream(buf [][2]float64) (int, bool) {
40+
for i := 0; i < len(buf); i++ {
41+
s := c.nextSample()
42+
buf[i] = [2]float64{s, s}
43+
}
44+
return len(buf), true
45+
}
46+
func (_ *toneStreamer) Err() error {
47+
return nil
48+
}

0 commit comments

Comments
 (0)