func newEcho(delay time.Duration) *echo { h, err := portaudio.DefaultHostApi() chk(err) p := portaudio.LowLatencyParameters(h.DefaultInputDevice, h.DefaultOutputDevice) p.Input.Channels = 1 p.Output.Channels = 1 e := &echo{buffer: make([]float32, int(p.SampleRate*delay.Seconds()))} e.Stream, err = portaudio.OpenStream(p, e.processAudio) chk(err) return e }
func (a *Audio) Start() error { host, err := portaudio.DefaultHostApi() if err != nil { return err } parameters := portaudio.HighLatencyParameters(nil, host.DefaultOutputDevice) stream, err := portaudio.OpenStream(parameters, a.Callback) if err != nil { return err } if err := stream.Start(); err != nil { return err } a.stream = stream return nil }
func main() { portaudio.Initialize() defer portaudio.Terminate() h, err := portaudio.DefaultHostApi() chk(err) stream, err := portaudio.OpenStream(portaudio.HighLatencyParameters(nil, h.DefaultOutputDevice), func(out []int32) { for i := range out { out[i] = int32(rand.Uint32()) } }) chk(err) defer stream.Close() chk(stream.Start()) time.Sleep(time.Second) chk(stream.Stop()) }
func (m *Meter) Initialize() { hs, err := portaudio.HostApis() if err != nil { fmt.Println("portaudio.HostApis failed:", err) panic(err) } m.Fast = make(map[string]*MeterFast) m.Fast["i"] = &MeterFast{} m.Fast["o"] = &MeterFast{} for _, hai := range hs { apistr := hai.Type.String() if hai.Name != apistr { apistr = fmt.Sprintf("%s \"%s\"", apistr, hai.Name) } all := make(map[string][]*MeterFastDev) for k := range m.Fast { all[k] = make([]*MeterFastDev, 0, len(hai.Devices)) } minLatency := make(map[string]float64) for i, d := range hai.Devices { appendLowLatency := func(k string, numch int, latency float64) { // some devices do not support low latency, indicated by a latency of -1 if numch > 0 && latency > 0 { all[k] = append(all[k], &MeterFastDev{"", i, d, latency}) cur, ok := minLatency[k] if !ok || cur > latency { minLatency[k] = latency } } } appendLowLatency("i", d.MaxInputChannels, d.DefaultLowInputLatency.Seconds()) appendLowLatency("o", d.MaxOutputChannels, d.DefaultLowOutputLatency.Seconds()) } for k, s := range all { for _, d := range s { if (d.Latency - minLatency[k]) >= 1e-3 { continue } d.Name = d.DevInfo.Name switch { case hai.DefaultInputDevice == d.DevInfo && hai.DefaultOutputDevice == d.DevInfo: d.Name = d.Name + " (default_in_out)" case hai.DefaultInputDevice == d.DevInfo: d.Name = d.Name + " (default_in)" case hai.DefaultOutputDevice == d.DevInfo: d.Name = d.Name + " (default_out)" } m.Fast[k].Dev = append(m.Fast[k].Dev, d) } } } for k, s := range m.Fast { if len(s.Dev) < 1 { fmt.Printf("Warning(ch.%s): no known latency on any device. making something up...", k) h, err := portaudio.DefaultHostApi() if err != nil { fmt.Printf("portaudio.DefaultHostApi failed: ", err) panic(err) } defdev := make(map[string]*portaudio.DeviceInfo) defdev["i"] = h.DefaultInputDevice defdev["o"] = h.DefaultOutputDevice m.Fast[k].Dev = append(m.Fast[k].Dev, &MeterFastDev{ Name: "defdev" + k, haiIndex: 0, // Completely made up. DevInfo: defdev[k], Latency: 1000, // Completely made up. }) } } }