1

I have connected IMX board to pc back to back. I am running a binary in board which sends audio frames every 5.7ms with 1024 bytes. The pc receives the frames and writes using

printf("snd_pcm_avail %d \n",snd_pcm_avail (FMWK.FMWK_Handler.playback_handle));

err = snd_pcm_writei(FMWK.FMWK_Handler.playback_handle, OutputPointer, PERIOD_BYTES);

When the playback is happening, after every 6seconds i get broken pipe

Logs when sucessful playback is running

snd_pcm_avail 32 
snd_pcm_avail 17 
snd_pcm_avail 81 
snd_pcm_avail 25 
snd_pcm_avail 89 
snd_pcm_avail 32 
snd_pcm_avail 17 
snd_pcm_avail 81 
snd_pcm_avail 32 
snd_pcm_avail 17 
snd_pcm_avail 81 
snd_pcm_avail 25 
snd_pcm_avail 89 
snd_pcm_avail 32 
snd_pcm_avail 17 
snd_pcm_avail 81 

Approximately it is decreasing by 56 When after 5 seconds the avail increases and the buffer overflows the configured limit of buffer_size=256

Logs:

snd_pcm_avail 89 
snd_pcm_avail 112 
snd_pcm_avail 96 
snd_pcm_avail 120 
snd_pcm_avail 104 
snd_pcm_avail 129 
snd_pcm_avail 153 
snd_pcm_avail 137 
snd_pcm_avail 160 
snd_pcm_avail 184 
snd_pcm_avail 168 
snd_pcm_avail 193 
snd_pcm_avail 176 
snd_pcm_avail 201 
snd_pcm_avail 224 
snd_pcm_avail 209 
snd_pcm_avail 232 
snd_pcm_avail 217 
snd_pcm_avail 240 
snd_pcm_avail -32 
   (AVB Info)     12:26:11 PM.606306  (Slave)               ==> Broken pipe
snd_pcm_avail 256 
snd_pcm_avail 48 

I have set period_size as 128

I am not sure whether iam missing something in initial configuration of snd_pcm? It is 44.1khz audio.

apomene
  • 14,282
  • 9
  • 46
  • 72
user3659653
  • 73
  • 2
  • 12
  • Where do these audio frames come from? How do you measure the 5.7 ms? – CL. May 21 '14 at 08:27
  • We have implemented a timer in the sender side which sends 1024 bytes every 5.7ms. – user3659653 May 21 '14 at 09:17
  • @user3659653: You must not use the system timer (using ALSA) to determine when to send the next frame. Yes, the sane thing is to expect, this to work. But unfortunately the process scheduler granularity is on the order of ms itself, so you can't time to +/-0.1ms accuracy. It's more like +/-2ms accuracy you can effectively get. Also the DAC clock and your system timer clock won't run in sync (this is a huge design folly of the PC architecture, which could be easily done away with by the next revision of the peripheral interconnect standards), so you must rely only on the DAC sample clock. – datenwolf May 21 '14 at 09:55
  • Datenwolf thanks for the reply. How do i derive the timing from the DAC as there is no abstraction or interface to read in the userspace.How can be obtain the codec clock to the user space,is there any alsa interface which provides this ADC/DAC clock? – user3659653 May 21 '14 at 10:29
  • Daten how to reply on DAC clock in both sender and receiver?..Is there any way to get the timing of the DAC/ADC? – user3659653 May 23 '14 at 05:14

2 Answers2

3

What happens there is, that your program can not keep up with the playback of the PCM data by the device. When the "Broken pipe" happens the audio device it waiting for new samples, but your program didn't deliver them in time.

The situation you ran into is the bane of online audio systems; unfortunately the existing Linux audio architecture (ALSA) does not a very good job; PulseAudio + RealtimeKit tried (IMHO not very successfully) to plaster over the cracks, by doing weird and crazy voodoo to not starve ALSA drivers; things get not better by some drivers being broken and not reporting the position of the playback head properly.

In your case here are two things you can do:

  • Use larger frames (more samples in a buffer)
  • Queue more frames (queue several buffers) and keep a minimum number of frames in the queue
datenwolf
  • 159,371
  • 13
  • 185
  • 298
  • Datenwolf thanks for the reply. But according to the avail values is it not the pcm having large amount of data for playback but it is not used for playback at the same rate? I will try the second option. – user3659653 May 21 '14 at 10:30
2

Audio devices typically have their own sample clock which is not synchronized with the system clock.

So you cannot use the system clock to control how fast to send samples to the device; it will run either too fast or too slow on almost all systems.

To send samples at the correct speed, just try to write your samples as fast as possible; snd_pcm_write* will automatically wait if the buffer is full.

If you cannot control the sender's speed from the receiver (because they are not on the same machine, and you do not have a protocol that provides feedback), you have to measure the relative speeds of the sender and receiver, and resample the data appropriately.

CL.
  • 173,858
  • 17
  • 217
  • 259
  • Yes, clock synchronization is the major bane of computer audio. As you may or may not know I'm currently developing a new audio subsystem for Linux and major parts of the code deal with making the troubles of clock mismatch go away. I'll never understand why the PC platform didn't simply add a system wide distributed 10MHz clock of which all timers are derived from. That would make things so much easier: If the GPU's vertical retrace was based on the very same clock as the audio DAC sample clock you'd have a perfect relationship between video frames and audio frames. – datenwolf May 21 '14 at 09:50
  • Of course all professional equipment works using external word clock everything gets synchronized to. Audio interfaces, cameras, graphics cards, etc. everything gets connected to a common clock and all of a sudden all the problems go away. – datenwolf May 21 '14 at 09:51
  • CL -> How can we obtain the relative ADC and DAC speed if they are running in two independent systems. Is there any ioctl or alsa interface which provides the clock of ADC/DAC to userspace application. – user3659653 May 21 '14 at 10:34
  • You have to count samples. – CL. May 21 '14 at 10:45