Thanks for your thoughts.
Not having heard from the authors, I'll try to keep my follow up as
port-audio specific as possible.
Regarding the scheduling, with or without Go's portaudio bindings, yes Go's
scheduling introduces uncertainty about when a buffer can be scheduled.
However, this is also often true at the OS level (their are N cpus and M OS
threads/procs to schedule which is at best very hard to control). Go
doesn't have an option for a real-time priority OS thread. I don't think
any Go code will be able to compete for reliability/robustness as compared
to actual real time support. But real time thread support is also, to my
understanding, often not used, (except JACK and I would suspect Go-Jack
bindings violates the real time principle behind JACK). Since their are 2
schedulers (OS and Go runtime) to deal with with Go, I would guess that
1. Without realtime support; and with or without go, one needs to test for
reliability under system load.
2. In some contexts, the Go scheduler may help, and in some it may hurt.
3. If Go communicates directly with the host in a well tested and
engineered way, then it may help to not use the port audio bindings.
The Go garbage collector is low latency for large heaps, probably low
enough for sound apps without tight latency needs. For sound apps without
large heaps or which are smart about memory, GC in Go seems to me to not be
a huge issue for relatively low latency sound apps. Again speaking
independently of Go portaudio bindings or Go connecting directly to the
Also, it appears to me that portaudio has put tons of work and had tons of
testing related to what configurations of interfacing the host it uses and
how it maps these configurations to it's public interface. My intuition is
that a lot of robustness is more related to this level than Go scheduling
via bindings or not, and this is where we hope to learn most from
portaudio. The zikichombo sio project is still a long way from port audio
in this respect.
But there is still the question of the request on the part of the port
audio project to give back any modifications and that this list be used to
discuss portaudio specific topics to help port-audio advance. I want to be
sure to respect that. I don't want to push the topic of using go bindings
for portaudio or not outside the scope and purpose of the portaudio list,
and I'm happy to share anything we learn along the way that might help
Post by sqweek Post by Scott Cotton
ZikiChombo <http://zikichombo.org> has started a Golang project
<http://github.com/zikichombo.org/sio> similar to port audio. I am
writing to solicit feedback and know-how from the portaudio community. It
is early in our project lifecycle and we would like to learn as much as
possible from port audio and share back anything we do differently (there
are some things we plan to do differently outlined in this github PR
Cool! I can't really speak for the developers, but as someone who uses
portaudio within go (via https://github.com/gordonklaus/portaudio) I
figure I can offer some feedback. Audio processing in go is an interesting
one, because you don't have precise control over thread scheduling. I'm
sure you're aware of audio processing's soft-realtime requirements and the
audible artifacts which result if they are not satisfied.
Go's scheduler works by ensuring that N threads are active at any one
time, where N is customisable via runtime.GOMAXPROCS. Historically it
defaulted to 1, but I think that may have changed in more recent versions?
Anyway, when it comes time for an audio buffer to be processed, the
OS/audio driver triggers an event and some thread within your process wakes
up to handle the buffer. This is all happening at the system level; nothing
to do with go yet. But if you want to implement audio processing in go,
then your callback has to enter the go runtime to invoke the processing
code. Maybe you can see where this is going - because the go runtime
ensures that only N threads are running user code at any one time, if there
are already N active threads when the audio callback fires, then the audio
processing doesn't get to happen until another thread yields or finishes
For my use case I wasn't doing significant processing in my callback
routine so I just switched to portaudio's blocking interface (which still
involves a callback at the C level, but avoids invoking go's scheduler). It
occurs to me I should probably file a bug report, but it was also a fair
while ago I was experimenting with this stuff (I think go 1.6).
To be clear it's not like I was getting tons of audio glitches when using
a go audio callback, but I also wasn't satisfied that its worst case
performance provided a robust solution in terms of underruns.
Portaudio mailing list
President, IRI France SAS