Skip to content

Instantly share code, notes, and snippets.

@Shinpeim
Last active August 29, 2015 14:05
Show Gist options
  • Save Shinpeim/e35f782ff0e971b7fd51 to your computer and use it in GitHub Desktop.
Save Shinpeim/e35f782ff0e971b7fd51 to your computer and use it in GitHub Desktop.
package main
import (
"bufio"
"code.google.com/p/portaudio-go/portaudio"
"errors"
"fmt"
"os"
"strconv"
"strings"
"time"
)
const sampleRate = 44100
func main() {
portaudio.Initialize()
defer portaudio.Terminate()
scanner := bufio.NewScanner(os.Stdin)
for {
fmt.Print("freq sec: ")
freq, sec, err := readFreqAndSecFromScanner(scanner)
if err != nil {
fmt.Println("invalid format")
continue
}
osc := &squareOsc{freq}
go play(osc, sec)
}
}
func readFreqAndSecFromScanner(scanner *bufio.Scanner) (freq float64, sec time.Duration, err error) {
if !scanner.Scan() {
return 0, 0, scanner.Err()
}
input := scanner.Text()
words := strings.Split(input, " ")
if len(words) < 2 {
return 0, 0, errors.New("invalid size")
}
freq, freqErr := strconv.ParseFloat(words[0], 64)
if freqErr != nil {
return 0, 0, freqErr
}
secI, secErr := strconv.Atoi(words[1])
if secErr != nil {
return 0, 0, secErr
}
sec = time.Duration(secI)
return freq, sec, nil
}
func play(osc Osc, sec time.Duration) {
stream, err := portaudio.OpenDefaultStream(0, 1, sampleRate, 0, osc.process)
panicIfError(err)
defer stream.Close()
panicIfError(stream.Start())
time.Sleep(sec * time.Second)
panicIfError(stream.Stop())
}
type Osc interface {
process(out [][]float32)
}
type squareOsc struct {
freq float64
}
func (osc *squareOsc) powerInNthSample(n int) float32 {
leng := int(sampleRate / osc.freq)
if n%int(leng) < int(leng)/2 {
return 0.1
} else {
return -0.1
}
}
func (osc *squareOsc) process(out [][]float32) {
for i := range out[0] {
out[0][i] = osc.powerInNthSample(i)
}
}
func panicIfError(err error) {
if err != nil {
fmt.Println(err)
panic(err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment