Stereo channels' arbitrary swap

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

 



Hello,

I'm trying to play a stereo raw file (a blank channel, and the other one with sound), and I'm facing a synchronization problem : the two channels sometimes swap (left becomes right and right becomes left). It's like it sometimes misses a sample, so the interleaved frames seem to shift.

How can I prevent it? Is it possible?
I attached my source code for analysis.

It's getting less frequent when I increase FRAME_SIZE, but as the application is for voice streaming, period time and frame size have to be as low as possible, because of low latency issue.

I feel it's a real time issue.

My configuration :
- SOC TI Davinci DM365 (ARM9 architecture)
- Linux 3.4.9-rt17
- alsa-lib-1.0.26
- WM8731 audio codec

Cyril


#include <alsa/asoundlib.h>

#define SAMPLE_RATE 8
#define PERIOD_TIME 10

#define FRAME_SIZE (2*SAMPLE_RATE*PERIOD_TIME)

static snd_pcm_t *pcm_handle_speaker = NULL;
static snd_output_t *log_speaker;


void soundinitSpeaker(void)
{
   int i;
   snd_pcm_stream_t stream;
   snd_pcm_hw_params_t *hwparams;
   snd_pcm_uframes_t buffer_size;
   char *device_file = "plughw:0,0";

   // might be used in case of error even without verbose.
   snd_output_stdio_attach(&log_speaker, stdout, 0);

   stream = SND_PCM_STREAM_PLAYBACK;

   if (snd_pcm_open(&pcm_handle_speaker, device_file, stream, 0) < 0)
   {
      fprintf(stdout, "Playback : Error opening PCM device %s\n", device_file);
      exit(-1);
   }

   snd_pcm_hw_params_alloca(&hwparams);
   if (snd_pcm_hw_params_any(pcm_handle_speaker, hwparams) < 0)
   {
      fprintf(stdout, "Playback : Can't configure the PCM device %s\n", device_file);
      exit(-1);
   }

   // now try to configure the device's hardware parameters
   if (snd_pcm_hw_params_set_access(pcm_handle_speaker, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED) < 0)
   {
      fprintf(stdout, "Playback : Error setting interleaved access mode.\n");
      exit(-1);
   }

   // Here we request mu-law sound format.  ALSA can handle the
   //  conversion to linear PCM internally, if the device used is a
   //  "plughw" and not "hw".
   int snd_format = SND_PCM_FORMAT_MU_LAW;
   if (snd_pcm_hw_params_set_format(pcm_handle_speaker, hwparams, snd_format) < 0)
   {
      fprintf(stdout, "Playback : Error setting PCM format\n");
      exit(-1);
   }

   if (snd_pcm_hw_params_set_channels(pcm_handle_speaker, hwparams, 2) < 0)
   {
      fprintf(stdout, "Playback : Error setting channels to 2\n");
      exit(-1);
   }

   unsigned int sample_rate = SAMPLE_RATE * 1000;
   int dir = 0;
   if (snd_pcm_hw_params_set_rate_near(pcm_handle_speaker, hwparams, &sample_rate, &dir) < 0)
   {
      fprintf(stdout, "Playback : The rate %d Hz is not supported. Try a plughw device.\n", sample_rate);
      exit(-1);
   }

   int buffer_time = 800 * 1000;
   if (snd_pcm_hw_params_set_buffer_time_near(pcm_handle_speaker, hwparams, &buffer_time, &dir) < 0)
   {
      fprintf(stdout, "Playback : Error setting buffer time to %d\n", buffer_time);
      exit(-1);
   }

   int period_time = PERIOD_TIME * 1000;
   if (snd_pcm_hw_params_set_period_time_near(pcm_handle_speaker, hwparams, &period_time, &dir) < 0)
   {
      fprintf(stdout, "Playback : Error setting period time to %d\n", period_time);
      exit(-1);
   }

   if (snd_pcm_hw_params(pcm_handle_speaker, hwparams) < 0)
   {
      fprintf(stdout, "Playback : Error setting hardware parameters.\n");
      exit(-1);
   }

   // ready to enter the SND_PCM_STATE_PREPARED status 
   if (snd_pcm_prepare(pcm_handle_speaker) < 0)
   {
      fprintf(stdout, "Playback : Can't enter prepared state\n");
      exit(-1);
   }

   snd_pcm_dump(pcm_handle_speaker, log_speaker);


}







int main(int argc, char *argv[])
{
   int i;
   char filename[128];
   FILE *input_file, *debug_file;
   char * liste_options = "f:";
   int option;
   char buff_audio[2*FRAME_SIZE];
   snd_pcm_status_t *status;


   while ((option = getopt (argc, argv, liste_options)) != -1)
   {
      switch (option)
      {
        case 'f':
            strcpy(filename, optarg);
            input_file = fopen(filename, "r");
           break;
        default :
           break;
      }
   }

   soundinitSpeaker();

   
   while (1)
   {
      if (input_file != NULL)
      {
         memset (buff_audio, 0xFF, sizeof(buff_audio));

         if (fread (buff_audio, FRAME_SIZE*2, 1, input_file) > 0)
         {
            snd_pcm_writei(pcm_handle_speaker, buff_audio, FRAME_SIZE);
         }
         else
         {
            fclose(input_file);
            input_file = fopen(filename, "r");
         }
      }
   }




}
------------------------------------------------------------------------------
This SF.net email is sponsored by Windows:

Build for Windows Store.

http://p.sf.net/sfu/windows-dev2dev
_______________________________________________
Alsa-user mailing list
Alsa-user@xxxxxxxxxxxxxxxxxxxxx
https://lists.sourceforge.net/lists/listinfo/alsa-user

[Index of Archives]     [ALSA Devel]     [Linux Audio Users]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [Yosemite Photos]     [KDE Users]     [Fedora Tools]

  Powered by Linux