- snd_pcm_avail_update (pcm);
- snd_pcm_mmap_begin (pcm, &areas, &offset, &nframes);
- offset *= shm->format.channels;
- nframes *= shm->format.channels;
- shm->samplepos = offset;
- shm->buffer = areas->addr;
- return shm->samplepos;
+Try to recover from errors
+====================
+*/
+static qboolean SndSys_Recover (int err_num)
+{
+ int err;
+
+ // We can only do something on underrun ("broken pipe") errors
+ if (err_num != -EPIPE)
+ return false;
+
+ err = snd_pcm_prepare (pcm_handle);
+ if (err != 0)
+ {
+ Con_DPrintf ("SndSys_Recover: unable to recover (%s)\n",
+ snd_strerror (err));
+
+ // TOCHECK: should we stop the playback ?
+
+ return false;
+ }
+
+ return true;
+}
+
+
+/*
+====================
+SndSys_Write
+====================
+*/
+static snd_pcm_sframes_t SndSys_Write (const unsigned char* buffer, unsigned int nbframes)
+{
+ snd_pcm_sframes_t written;
+
+ written = snd_pcm_writei (pcm_handle, buffer, nbframes);
+ if (written < 0)
+ {
+ if (developer.integer >= 1000 && vid_activewindow)
+ Con_Printf ("SndSys_Write: audio write returned %ld (%s)!\n",
+ written, snd_strerror (written));
+
+ if (SndSys_Recover (written))
+ {
+ written = snd_pcm_writei (pcm_handle, buffer, nbframes);
+ if (written < 0)
+ Con_DPrintf ("SndSys_Write: audio write failed again (error %ld: %s)!\n",
+ written, snd_strerror (written));
+ }
+ }
+ if (written > 0)
+ {
+ snd_renderbuffer->startframe += written;
+ expected_delay += written;
+ }
+
+ return written;