~gsthnz/mtrnm

42ea82a95d42f2fbc0e847414adee6d4b19eb04e — Gustavo Heinz 1 year, 1 month ago 06f7ff6
Move metronome logic to main, run go fmt
3 files changed, 65 insertions(+), 63 deletions(-)

M main.go
M player.go
M wave.go
M main.go => main.go +24 -12
@@ 3,24 3,36 @@ package main
import (
	"flag"
	"time"
)

const (
	// A4 Note
	A4 = 440.0
	// E4 Note
	E4 = 329.63
)

var (
    sampleRate = 44100
    channelNum = 2
    bitDepthInBytes = 2
	bpm = flag.Int("bpm", 80, "BPM")
	bpm    = flag.Int("bpm", 80, "BPM")
	pulses = flag.Int("p", 4, "Pulses")
)

func main() {
    flag.Parse()
    // TODO Send freq to channel
    ch := make(chan bool)
    go beeper(ch)
    for {
        ch <- true
        time.Sleep(time.Minute / time.Duration(*bpm))
    }
	flag.Parse()
	ch := make(chan float64)
	go beeper(ch)
	i := 0
	for {
		if i == 0 {
			ch <- E4
		} else {
			ch <- A4
		}
		if i == *pulses-1 {
			i = 0
		} else {
			i++
		}
		time.Sleep(time.Minute / time.Duration(*bpm))
	}
}

M player.go => player.go +17 -23
@@ 1,15 1,21 @@
package main

import (
    "time"
    "io"
    "fmt"
	"github.com/hajimehoshi/oto"
	"io"
	"time"
)

var (
	sampleRate      = 44100
	channelNum      = 2
	bitDepthInBytes = 2
	beepDuration    = time.Second / 20
)

func play(context *oto.Context, freq float64, duration time.Duration) error {
	p := context.NewPlayer()
	s := NewSineWave(freq, duration)
	s := newSineWave(freq, duration)
	if _, err := io.Copy(p, s); err != nil {
		return err
	}


@@ 20,26 26,14 @@ func play(context *oto.Context, freq float64, duration time.Duration) error {
}

func beep(c *oto.Context, freq float64) {
    play(c, freq, time.Second/20)
	play(c, freq, beepDuration)
}

func beeper(ch chan bool) {
func beeper(ch chan float64) {
	c, _ := oto.NewContext(sampleRate, channelNum, bitDepthInBytes, 4096)
    defer c.Close()
    i := 0
    for {
        // TODO Move beep logic to main
        <- ch
        fmt.Println("beep", i)
        if i == 0 {
            beep(c, 329.628)
        } else {
            beep(c, 440.0)
        }
        if i == *pulses-1 {
            i = 0
        } else {
            i++
        }
    }
	defer c.Close()
	for {
		freq := <-ch
		beep(c, freq)
	}
}

M wave.go => wave.go +24 -28
@@ 1,14 1,12 @@
package main

import (
    "math"
    "time"
    "io"
	"io"
	"math"
	"time"
)



type SineWave struct {
type sineWave struct {
	freq   float64
	length int64
	pos    int64


@@ 16,17 14,16 @@ type SineWave struct {
	remaining []byte
}


func NewSineWave(freq float64, duration time.Duration) *SineWave {
func newSineWave(freq float64, duration time.Duration) *sineWave {
	l := int64(channelNum) * int64(bitDepthInBytes) * int64(sampleRate) * int64(duration) / int64(time.Second)
	l = l / 4 * 4
	return &SineWave{
	return &sineWave{
		freq:   freq,
		length: l,
	}
}

func (s *SineWave) Read(buf []byte) (int, error) {
func (s *sineWave) Read(buf []byte) (int, error) {
	if len(s.remaining) > 0 {
		n := copy(buf, s.remaining)
		s.remaining = s.remaining[n:]


@@ 49,29 46,28 @@ func (s *SineWave) Read(buf []byte) (int, error) {
		buf = make([]byte, len(origBuf)+4-len(origBuf)%4)
	}

    // From here lies the wave generation
	// From here lies the wave generation
	length := float64(sampleRate) / float64(s.freq)

    // Delay
    var delay_start float64 = 0.8
    var delay_end float64 = 0.6
    decayfac := math.Pow(delay_end/delay_start, 1.0/length)
	// Delay
	var delayStart float64 = 0.8
	var delayEnd float64 = 0.6
	decayFac := math.Pow(delayEnd/delayStart, 1.0/length)

	num := bitDepthInBytes * channelNum
	p := s.pos / int64(num)
    for i := 0; i < len(buf)/num; i++ {
        const max = 32767
        wave_number := math.Sin(2*math.Pi*float64(p)/length) * 0.3 * max
        wave_number *= delay_start
        delay_start *= decayfac
        b := int16(wave_number)
        for ch := 0; ch < channelNum; ch++ {
            buf[num*i+2*ch] = byte(b)
            buf[num*i+1+2*ch] = byte(b >> 8)
        }
        p++
    }
    // Here ends the wave generation
	for i := 0; i < len(buf)/num; i++ {
		const max = 32767
		waveNumber := math.Sin(2*math.Pi*float64(p)/length) * 0.3 * max
		waveNumber *= delayStart
		delayStart *= decayFac
		b := int16(waveNumber)
		for ch := 0; ch < channelNum; ch++ {
			buf[num*i+2*ch] = byte(b)
			buf[num*i+1+2*ch] = byte(b >> 8)
		}
		p++
	}

	s.pos += int64(len(buf))