[Tutor] ossaudiodev, pygtk, and flushing buffers

Michael Lange klappnase at freenet.de
Thu May 11 19:15:52 CEST 2006


On Wed, 10 May 2006 09:59:14 -0700
Matthew White <mwhite3 at ttsd.k12.or.us> wrote:

> Hello All,
> 
> I'm writing a little audio player that plays voicemail files.  (I realize
> I'm reinventing the wheel, but it's still fun.)
> 
> The problem I'm experiencing is that I'm hearing the last fraction of
> the sound clip twice, either when the clip is done playing or when the
> program exits.
> 
> I've tried a few things and none of them have worked.  The bit of code
> that does the playing is here:
> 
>     def play(self):
>         if self.data_written < self.file_length:
>             buf = self.data.read(self.buf_size)
>             self.data_written += self.dsp.write(buf)
>             self.percent_done = self.data_written / self.file_length
> 
>         if self.data_written == self.file_length:
>             self._reopen_audio_device()
> 
> This causes the second playing of the "last little bit" when the end of
> the file is reached.  When I don't include the second if statement, the
> "last little bit" gets played when the program exits.
> 
> According to the documentaiton, closing the audio device will flush any
> data in the sound card buffer.  I guess what I'm hearing is that buffered
> clip being flushed.  I've thought about using the mixer device to put the
> volume to zero, flush the buffer, then turning the volume back up again,
> but that seems like a hack.
> 

Hi Matthew,

you never explicitely close the audio device, except when calling self._reopen_audio_device().
According to the OSS programmer's guide (http://www.opensound.com/pguide/index.html ) this is generally considered bad practice,
because no other application will be able to access the audio device. Probably it is not guaranteed that the device's
buffers will be flushed until calling close(), too (maybe calling reset() also flushes the buffers, but after reset() you
should close and reopen the device anyway).
I have not tried it, but I think the effect you describe may depend on the driver in use.

Does it help if you change your play() method like this:

def play(self):
    if self.data_written < self.file_length:
        buf = self.data.read(self.buf_size)
        self.data_written += self.dsp.write(buf)
        self.percent_done = self.data_written / self.file_length
    if self.data_written == self.file_length:
        self.dsp.close()
    # then reopen the device right before starting playback, probably from player.PlayerWindow.play()

? 

There may be a short delay between the call to self.dsp.close() and the actual stopping of playback,
(which can be avoided by calling self.dsp.reset() before self.dsp.close()), however this should not be a problem if you
play the file to the end, I think. 

I hope this helps

Michael






More information about the Tutor mailing list