fluid-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [fluid-dev] Fluidsynth stops playing when stdout is piped


From: Matt Giuca
Subject: Re: [fluid-dev] Fluidsynth stops playing when stdout is piped
Date: Mon, 31 Jan 2011 12:08:30 +1100


subprocess.Popen(["fluidsynth", "-sli","-a", 'alsa', "-j",
'/usr/share/sounds/sf2/FluidR3_GM.sf2'], stdout=subprocess.PIPE,
stderr=subprocess.PIPE)

This renders the screen output invisible, but if I have a number of
simultaneous connections sending commands, after a short time the audio stops,
and when the program exits, all the missing notes are played at once!

I have a guess as to what might be happening. The way pipes work, there is a short buffer (provided by the OS) which the sender can put data into without being read. Once the buffer is full, the sender cannot send any more data until the receiver reads. (Think of it like an actual water pipe with an "in" and an "out" end -- if you turn the tap off at the "out" end, and pump water through the "in" end, you can pump a certain amount of water just fine, but once the pipe is full of water, you can't put any more in. Once somebody turns the tap on, though, you can now continue to send more water through the "in" end.)

So if you set up a subprocess.Popen, with pipes for stdout and stderr, the process (in this case, FS), may be writing to stdout and/or stderr while it plays music. If your Python script is not continuously reading from stdout and/or stderr, then it will work for awhile, but then once the buffer becomes full, FS will try to write to (say) stdout, and block. Unless it is multithreaded*, this will freeze all activities, including the music, until the buffer is unblocked (which would be the case if the socket closes; it becomes and error and the program resumes normally). So when you disconnect, suddenly all the music will come rushing out (do they get played in the correct time, or do you hear all the notes literally at the same time?).

*I suspect FS is threaded in such a way that there is one thread per connection, hence "I leave the same instance of fluidsynth running,
subsequent instances of my program which connect to it do not crash" -- each connection to FluidSynth has its own thread, but per each connection, it will block when the buffer is full.

The solution is to make sure your Python program is always reading from both stdout and stderr, even if it just means discarding the output. One thing I noticed is that FS prints "> " prompts... maybe you are not reading those properly and eventually that print is blocking. If you need to open a file exclusively for the purpose of discarding the output (maybe you aren't interested in the contents of stderr, but you don't want it printing to your console; nor do you want it to block -- you just want to read and discard all the output), then you should be able to arrange it by passing stderr=open(os.path.devnull) to Popen (though I haven't tried it).

Matt

reply via email to

[Prev in Thread] Current Thread [Next in Thread]