William Yang wrote:
I am running SRS 4.1 beta on S10u5 and also see this problem...initially I thought it might have just been XMMS, but you are right as it is the same version that I have running on SRS 4.0 on S10u5 without this problem. It does go away if I pick ESD plugin. I noticed that the timer also gets funky with streams. What I see with local audio files is that the timer is counting play time from the time XMMS was launched. *From:* Joshua Clulow <mailto:[EMAIL PROTECTED]>
    I'm running the new SRS 4.1 beta bits on SXCE (snv_87) and its all
    working very well so far, except for some minor craziness with XMMS...

    When playing audio through the Solaris audio plugin (which uses the Sun
    Ray utaudio device in $AUDIODEV) XMMS seems unable to keep track of
    what
    point in the audio file it's up to -- either giving outrageously high
    times or not moving the bar along at all (or both).  The audio itself
    plays just as well as it ever did and this copy of XMMS works fine on
    the currently GA SRS 4 (i.e. before I upgraded to the new SRS beta.)

So, in the interests of science I have introduced some debugging output into the XMMS code to see what was going on. It turns out that the behaviour of the utaudio device has changed and is no longer in line with what audio(7I) describes as expected.

From audio(7I):
     "The play.samples and record.samples  fields  are  zeroed  at
     open() and are incremented each time a data sample is copied
     to or from the associated STREAMS queue."

In other words the "samples" field in the audio_prinfo structure "play" within the audio_info returned from an AUDIO_GETINFO ioctl on the audio device ought to start counting at 0 every time you open() the audio device in question. The utaudio device certainly used to work this way before the latest beta of the Sun Ray software, but this behaviour no longer seems to apply.

XMMS close()s the device at the end of each song and then open()s it again for a new song, expecting that play.samples will return to 0 every time it does so. I can fix the "broken" XMMS behaviour by storing the current value of play.samples when the device is open()ed and using it as an offset when calculating playback progress -- but I don't think the software should have to compensate for this behaviour, given the specification in the manpage.

While I can work around the problem in XMMS, I don't know what other applications (if any!) depend on this particular behaviour and may break. A potential workaround for XMMS is attached as a patch in case anybody wants it -- it works for me, any feedback would be appreciated.

I tried sending some feedback to [EMAIL PROTECTED] a while ago (about this and other issues) but I've not received a reply so I'm just posting my findings/fixes here for the moment.

--


Regards,

Joshua M. Clulow
IT Consultant
JMCtech - http://www.jmctech.com.au/
ABN:    49 933 254 106
Mobile: +61 (412) 421 925
E-mail: [EMAIL PROTECTED]
--- xmms-1.2.11/Output/solaris/audio.c  Sun May 15 10:01:20 2005
+++ xmms-1.2.11/Output/solaris/audio.c  Sun Aug 31 11:36:06 2008
@@ -20,40 +20,41 @@
 #include <glib.h>
 #include <libxmms/util.h>
 #include <pthread.h>
 
 
 /*****************************************************************************/
 
 /* This is the maximum data we're willing to send to the audio device and
    when we should refill it. */
 #define SUN_AUDIO_CACHE 16384
 
 /*****************************************************************************/
 
 static char *buffer_ptr = NULL;
 static char *buffer_end = NULL;
 static char *buffer_read = NULL;
 static char *buffer_write = NULL;
 static int buffer_len = 0;
 static pthread_mutex_t buflock = PTHREAD_MUTEX_INITIALIZER;
 
+static uint_t bugfix_offset;
 static gint time_offset = 0;
 static gint byte_offset = 0;
 
 static gboolean paused = FALSE;
 static gboolean playing = FALSE;
 static gboolean aopen = FALSE;
 static gboolean prebuffer, remove_prebuffer;
 static int prebuffer_size;
 static volatile gint flush = -1;
 
 static gint audiofd = -2;
 static audio_info_t adinfo;
 static pthread_t buffer_thread;
 
 static uint_t audio_scount = 0;
 
 static struct {
     gboolean is_signed;
     gboolean is_bigendian;
     uint_t sample_rate;
@@ -189,41 +190,44 @@
                        xmms_usleep(10000);
                }
        }
 }
 
 gint abuffer_get_written_time(void)
 {
        if (!playing)
                return 0;
     
        return ((double)byte_offset * 1000.0) / stream_attrs.bps;
 }
 
 gint abuffer_get_output_time(void)
 {
        if (!aopen || !playing)
                return 0;
     
        ioctl(audiofd, AUDIO_GETINFO, &adinfo);
 
-       return time_offset + ((double)adinfo.play.samples * 1000) / 
adinfo.play.sample_rate;
+       /* In case the audio(7I) device does not zero play.samples on open()
+          like it is supposed to, use the zero-offset stored when the device
+          was opened. --JMC (31-AUG-2008) */
+       return time_offset + ((double)(adinfo.play.samples - bugfix_offset) * 
1000) / adinfo.play.sample_rate;
 }
 
 gint abuffer_used(void)
 {
        int retval;
        pthread_mutex_lock(&buflock);
        if(buffer_write >= buffer_read)
                retval = buffer_write - buffer_read;
        else
                retval = buffer_len - (buffer_read - buffer_write);
        pthread_mutex_unlock(&buflock);
        return retval;
 }
 
 /*
  * Doesn't free the buffer. Just returns the number of bytes
  * in the buffer available to write.
  */
 gint abuffer_free(void)
 {
@@ -490,40 +494,45 @@
        /* Open audio device if it's not already open */
        if (audiofd < 0)
        {
                if ((audiofd = open(get_audiodev(), O_WRONLY )) == -1)
                {
                        perror("xmms Solaris Output plugin");
                        return 1;
                }
        }
        else
        {
                fprintf(stderr, "xmms: Warning: Attempted to reopen audio 
device.\n");
        }
 
        /* Initialise audio device */
        abuffer_set_audio_params();     
 
        /* Get the audio info */
        ioctl(audiofd, AUDIO_GETINFO, &adinfo);
 
+       /* In case the audio(7I) device does not zero play.samples on open()
+          like it is supposed to, save the current sample count to use as a 
+          zero-offset later. --JMC (31-AUG-2008) */
+       bugfix_offset = adinfo.play.samples;
+       
        /* We should be playing */
        playing = TRUE;
 
        /* NOTE: What is flush for? */
        flush = -1;
 
        /* We aren't paused */
        paused = FALSE;
 
        /* We're open */
        aopen = TRUE;
 
        prebuffer = TRUE;
        remove_prebuffer = FALSE;
 
        /* We're at the beginning */
        time_offset = 0;
        byte_offset = 0;
 
        audio_scount = 0;
_______________________________________________
SunRay-Users mailing list
[email protected]
http://www.filibeto.org/mailman/listinfo/sunray-users

Reply via email to