func newStereoSine(freqL, freqR, sampleRate float64) *stereoSine { s := &stereoSine{nil, freqL / sampleRate, 0, freqR / sampleRate, 0} var err error s.Stream, err = portaudio.OpenDefaultStream(0, 2, sampleRate, 0, s.processAudio) chk(err) return s }
func main() { if len(os.Args) < 2 { fmt.Println("missing required argument: input file name") return } fmt.Println("Playing. Press Ctrl-C to stop.") sig := make(chan os.Signal, 1) signal.Notify(sig, os.Interrupt, os.Kill) fileName := os.Args[1] f, err := os.Open(fileName) chk(err) defer f.Close() id, data, err := readChunk(f) chk(err) if id.String() != "FORM" { fmt.Println("bad file format") return } _, err = data.Read(id[:]) chk(err) if id.String() != "AIFF" { fmt.Println("bad file format") return } var c commonChunk var audio io.Reader for { id, chunk, err := readChunk(data) if err == io.EOF { break } chk(err) switch id.String() { case "COMM": chk(binary.Read(chunk, binary.BigEndian, &c)) case "SSND": chunk.Seek(8, 1) //ignore offset and block audio = chunk default: fmt.Printf("ignoring unknown chunk '%s'\n", id) } } //assume 44100 sample rate, mono, 32 bit portaudio.Initialize() defer portaudio.Terminate() out := make([]int32, 8192) stream, err := portaudio.OpenDefaultStream(0, 1, 44100, len(out), &out) chk(err) defer stream.Close() chk(stream.Start()) defer stream.Stop() for remaining := int(c.NumSamples); remaining > 0; remaining -= len(out) { if len(out) > remaining { out = out[:remaining] } err := binary.Read(audio, binary.BigEndian, out) if err == io.EOF { break } chk(err) chk(stream.Write()) select { case <-sig: return default: } } }
func main() { if len(os.Args) < 2 { fmt.Println("missing required argument: output file name") return } fmt.Println("Recording. Press Ctrl-C to stop.") sig := make(chan os.Signal, 1) signal.Notify(sig, os.Interrupt, os.Kill) fileName := os.Args[1] if !strings.HasSuffix(fileName, ".aiff") { fileName += ".aiff" } f, err := os.Create(fileName) chk(err) // form chunk _, err = f.WriteString("FORM") chk(err) chk(binary.Write(f, binary.BigEndian, int32(0))) //total bytes _, err = f.WriteString("AIFF") chk(err) // common chunk _, err = f.WriteString("COMM") chk(err) chk(binary.Write(f, binary.BigEndian, int32(18))) //size chk(binary.Write(f, binary.BigEndian, int16(1))) //channels chk(binary.Write(f, binary.BigEndian, int32(0))) //number of samples chk(binary.Write(f, binary.BigEndian, int16(32))) //bits per sample _, err = f.Write([]byte{0x40, 0x0e, 0xac, 0x44, 0, 0, 0, 0, 0, 0}) //80-bit sample rate 44100 chk(err) // sound chunk _, err = f.WriteString("SSND") chk(err) chk(binary.Write(f, binary.BigEndian, int32(0))) //size chk(binary.Write(f, binary.BigEndian, int32(0))) //offset chk(binary.Write(f, binary.BigEndian, int32(0))) //block nSamples := 0 defer func() { // fill in missing sizes totalBytes := 4 + 8 + 18 + 8 + 8 + 4*nSamples _, err = f.Seek(4, 0) chk(err) chk(binary.Write(f, binary.BigEndian, int32(totalBytes))) _, err = f.Seek(22, 0) chk(err) chk(binary.Write(f, binary.BigEndian, int32(nSamples))) _, err = f.Seek(42, 0) chk(err) chk(binary.Write(f, binary.BigEndian, int32(4*nSamples+8))) chk(f.Close()) }() portaudio.Initialize() defer portaudio.Terminate() in := make([]int32, 64) stream, err := portaudio.OpenDefaultStream(1, 0, 44100, len(in), in) chk(err) defer stream.Close() chk(stream.Start()) for { chk(stream.Read()) chk(binary.Write(f, binary.BigEndian, in)) nSamples += len(in) select { case <-sig: return default: } } chk(stream.Stop()) }