I am having some issues getting audio timestamps when opening a device
through dmix. When I open the hardware directly, e.g. "hw:0,0", I get all
the timestamps and delay frames. However, when I open through dmix, e..g
"dmix:0,0", the audio timestamps and delay frames are zero.

Below is a test application which illustrates this issue on my setup, it
takes the ALSA device as its argument and I am linking against the latest
stable alsa (1.0.29).

Any help with this would be much appreciated.

-Dan

-------

#include <asoundlib.h>

snd_pcm_t *handle;

int getFramesReady()
{
    int framesReady = 0;
int error;

    if ((error = snd_pcm_wait (handle, 100)) < 0) {
            fprintf (stderr, "poll failed (%s)\n", strerror (errno));
            return 0;
    }

    if ((framesReady = snd_pcm_avail_update (handle)) < 0) {
        if (framesReady == -EPIPE) {
            fprintf (stderr, "an xrun occured\n");
            return 0;
        } else {
            fprintf (stderr, "unknown ALSA avail update return value
(%d)\n",
                 framesReady);
            return 0;
        }
    }

    framesReady = framesReady > 4096 ? 4096 : framesReady;

    return framesReady;
}

long timestamp2ns(snd_htimestamp_t t)
{
      int64_t ns;

      ns = t.tv_sec * 1000000000;
      ns += t.tv_nsec;

      return ns;
}

void printTimestamps()
{
int error;
    snd_pcm_status_t *status;
    snd_pcm_status_alloca(&status);

    if ((error = snd_pcm_status(handle, status)) < 0) {
        fprintf(stderr, "Stream status error: %s\n", snd_strerror(error));
        exit(1);
    }
    snd_htimestamp_t temp_ts;

    snd_pcm_status_get_htstamp(status, &temp_ts);
    printf("host: %ld\n", timestamp2ns(temp_ts));

    snd_pcm_status_get_audio_htstamp(status, &temp_ts);
    printf("audio: %ld\n", timestamp2ns(temp_ts));

    snd_pcm_status_get_trigger_htstamp(status, &temp_ts);
    printf("trigger: %ld\n", timestamp2ns(temp_ts));

    printf("avail: %u\n", snd_pcm_status_get_avail(status));
    printf("delay: %u\n", snd_pcm_status_get_delay(status));
printf("--------------------------------------------\n");
}

int main(int argc, char *argv[])
{
 char *deviceName;
int error;
    snd_pcm_hw_params_t *hwParams;
    snd_pcm_sw_params_t *swParams;

snd_pcm_hw_params_malloc(&hwParams);
snd_pcm_sw_params_malloc(&swParams);

if (argc != 2) {
printf("Needs alsa playback device name as input\n");
return 0;
}
deviceName = argv[1];

    if ((error = snd_pcm_open(&handle, deviceName, SND_PCM_STREAM_PLAYBACK,
SND_PCM_NO_AUTO_RESAMPLE)) < 0) {
        printf("Alsa Device open error: %s\n", snd_strerror(error));
    }
// hw
    snd_pcm_hw_params_any(handle, hwParams);

    if ((error = snd_pcm_hw_params_set_access (handle, hwParams,
SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
        fprintf (stderr, "cannot set access type (%s)\n",
             snd_strerror (error));
        exit (1);
    }

    if ((error = snd_pcm_hw_params (handle, hwParams)) < 0) {
        fprintf (stderr, "cannot set parameters (%s)\n",
             snd_strerror (error));
        exit (1);
    }

// sw
    if ((error = snd_pcm_sw_params_current (handle, swParams)) < 0) {
        fprintf (stderr, "cannot initialize software parameters structure
(%s)\n",
             snd_strerror (error));
        exit (1);
    }
    if ((error = snd_pcm_sw_params_set_avail_min (handle, swParams, 4096))
< 0) {
        fprintf (stderr, "cannot set minimum available count (%s)\n",
             snd_strerror (error));
        exit (1);
    }
    if ((error = snd_pcm_sw_params_set_start_threshold (handle, swParams,
0U)) < 0) {
        fprintf (stderr, "cannot set start mode (%s)\n",
             snd_strerror (error));
        exit (1);
    }

    if ((error = snd_pcm_sw_params_set_tstamp_mode(handle, swParams,
SND_PCM_TSTAMP_ENABLE)) < 0) {
         fprintf(stderr,"Unable to set tstamp mode : %s\n",
snd_strerror(error));
         exit(1);
     }

    // write sw params
    if ((error = snd_pcm_sw_params (handle, swParams)) < 0) {
        fprintf (stderr, "cannot set software parameters (%s)\n",
             snd_strerror (error));
        exit (1);
    }


//start
    if ((error = snd_pcm_prepare (handle)) < 0) {
        fprintf (stderr, "cannot prepare audio interface for use (%s)\n",
             snd_strerror (error));
        exit (1);
    }

char buf[102400] = {0};
while (1) {
usleep(100);
        int32_t framesReady = getFramesReady();

        if (framesReady) {
printTimestamps();

if ((error = snd_pcm_writei (handle, buf, framesReady)) < 0) {
fprintf (stderr, "write failed (%s)\n", snd_strerror (error));
}
        }
}
}
------------------------------------------------------------------------------
One dashboard for servers and applications across Physical-Virtual-Cloud 
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
http://ad.doubleclick.net/ddm/clk/290420510;117567292;y
_______________________________________________
Alsa-user mailing list
Alsa-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/alsa-user

Reply via email to