// ALSA module, used by Linux
+#include "quakedef.h"
#include <alsa/asoundlib.h>
-#include "quakedef.h"
#include "snd_main.h"
if (suggested != NULL)
{
- memcpy (suggested, requested, sizeof (suggested));
+ memcpy (suggested, requested, sizeof (*suggested));
if (requested->width < 1)
suggested->width = 1;
Con_Printf ("SndSys_Init: suggesting sound width = %hu\n",
suggested->width);
}
-
+
return false;
}
-
+
if (pcm_handle != NULL)
{
Con_Print ("SndSys_Init: WARNING: Init called before Shutdown!\n");
SndSys_Shutdown ();
}
-
+
// Determine the name of the PCM handle we'll use
switch (requested->channels)
{
pcm_name = com_argv[i + 1];
// Open the audio device
- Con_DPrintf ("SndSys_Init: PCM device is \"%s\"\n", pcm_name);
+ Con_Printf ("SndSys_Init: PCM device is \"%s\"\n", pcm_name);
err = snd_pcm_open (&pcm_handle, pcm_name, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
- if (err != 0)
+ if (err < 0)
{
Con_Printf ("SndSys_Init: can't open audio device \"%s\" (%s)\n",
pcm_name, snd_strerror (err));
return false;
}
-
+
// Allocate the hardware parameters
err = snd_pcm_hw_params_malloc (&hw_params);
- if (err != 0)
+ if (err < 0)
{
Con_Printf ("SndSys_Init: can't allocate hardware parameters (%s)\n",
snd_strerror (err));
goto init_error;
}
err = snd_pcm_hw_params_any (pcm_handle, hw_params);
- if (err != 0)
+ if (err < 0)
{
Con_Printf ("SndSys_Init: can't initialize hardware parameters (%s)\n",
snd_strerror (err));
// Set the access type
err = snd_pcm_hw_params_set_access (pcm_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED);
- if (err != 0)
+ if (err < 0)
{
Con_Printf ("SndSys_Init: can't set access type (%s)\n",
snd_strerror (err));
else
snd_pcm_format = SND_PCM_FORMAT_S16;
err = snd_pcm_hw_params_set_format (pcm_handle, hw_params, snd_pcm_format);
- if (err != 0)
+ if (err < 0)
{
Con_Printf ("SndSys_Init: can't set sound width to %hu (%s)\n",
requested->width, snd_strerror (err));
// Set the sound channels
err = snd_pcm_hw_params_set_channels (pcm_handle, hw_params, requested->channels);
- if (err != 0)
+ if (err < 0)
{
Con_Printf ("SndSys_Init: can't set sound channels to %hu (%s)\n",
requested->channels, snd_strerror (err));
// Set the sound speed
err = snd_pcm_hw_params_set_rate (pcm_handle, hw_params, requested->speed, 0);
- if (err != 0)
+ if (err < 0)
{
Con_Printf ("SndSys_Init: can't set sound speed to %u (%s)\n",
requested->speed, snd_strerror (err));
buffer_size = requested->speed / 5;
err = snd_pcm_hw_params_set_buffer_size_near (pcm_handle, hw_params, &buffer_size);
- if (err != 0)
+ if (err < 0)
{
Con_Printf ("SndSys_Init: can't set sound buffer size to %lu (%s)\n",
buffer_size, snd_strerror (err));
buffer_size /= NB_PERIODS;
err = snd_pcm_hw_params_set_period_size_near(pcm_handle, hw_params, &buffer_size, 0);
- if (err != 0)
+ if (err < 0)
{
Con_Printf ("SndSys_Init: can't set sound period size to %lu (%s)\n",
buffer_size, snd_strerror (err));
}
err = snd_pcm_hw_params (pcm_handle, hw_params);
- if (err != 0)
+ if (err < 0)
{
Con_Printf ("SndSys_Init: can't set hardware parameters (%s)\n",
snd_strerror (err));
snd_renderbuffer = Snd_CreateRingBuffer(requested, 0, NULL);
expected_delay = 0;
alsasoundtime = 0;
- alsaspeakerlayout = true;
-
+ if (snd_channellayout.integer == SND_CHANNELLAYOUT_AUTO)
+ Cvar_SetValueQuick (&snd_channellayout, SND_CHANNELLAYOUT_ALSA);
+
return true;
// It's not very clean, but it avoids a lot of duplicated code.
init_error:
-
+
if (hw_params != NULL)
snd_pcm_hw_params_free (hw_params);
SndSys_Shutdown ();
// 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)
+ if (err < 0)
{
- Con_DPrintf ("SndSys_Recover: unable to recover (%s)\n",
+ Con_Printf ("SndSys_Recover: unable to recover (%s)\n",
snd_strerror (err));
// TOCHECK: should we stop the playback ?
return false;
}
-
- Con_DPrint ("SndSys_Recover: recovered successfully\n");
return true;
}
written = snd_pcm_writei (pcm_handle, buffer, nbframes);
if (written < 0)
{
- Con_Printf ("SndSys_Write: audio write returned %ld (%s)!\n",
- written, snd_strerror (written));
+ 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_Printf ("SndSys_Write: audio write failed again (error %ld: %s)!\n",
- written, snd_strerror (written));
+ 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;
}
unsigned int startoffset, factor;
snd_pcm_uframes_t limit, nbframes;
snd_pcm_sframes_t written;
-
+
if (pcm_handle == NULL ||
snd_renderbuffer->startframe == snd_renderbuffer->endframe)
return;
factor = snd_renderbuffer->format.width * snd_renderbuffer->format.channels;
limit = snd_renderbuffer->maxframes - startoffset;
nbframes = snd_renderbuffer->endframe - snd_renderbuffer->startframe;
-//Con_DPrintf(">> SndSys_Submit: startframe=%u, endframe=%u (%u frames), maxframes=%u, startoffset=%u\n",
-// snd_renderbuffer->startframe, snd_renderbuffer->endframe,
-// nbframes, snd_renderbuffer->maxframes, startoffset);
if (nbframes > limit)
{
-//Con_DPrintf(">> SndSys_Submit: 2 phases-submit\n");
written = SndSys_Write (&snd_renderbuffer->ring[startoffset * factor], limit);
- if (written < 0)
+ if (written < 0 || (snd_pcm_uframes_t)written != limit)
return;
- snd_renderbuffer->startframe += written;
- expected_delay += written;
-//Con_DPrintf(">> SndSys_Submit: %ld/%ld frames written\n", written, limit);
- if ((snd_pcm_uframes_t)written != limit)
- return;
-
nbframes -= limit;
startoffset = 0;
}
-//else Con_DPrintf(">> SndSys_Submit: 1 phase-submit\n");
written = SndSys_Write (&snd_renderbuffer->ring[startoffset * factor], nbframes);
if (written < 0)
return;
-//Con_DPrintf(">> SndSys_Submit: %ld/%ld frames written\n", written, nbframes);
- snd_renderbuffer->startframe += written;
- expected_delay += written;
}
return 0;
err = snd_pcm_delay (pcm_handle, &delay);
- if (err != 0)
+ if (err < 0)
{
- Con_DPrintf ("SndSys_GetSoundTime: can't get playback delay (%s)\n",
- snd_strerror (err));
+ if (developer.integer >= 1000 && vid_activewindow)
+ Con_DPrintf ("SndSys_GetSoundTime: can't get playback delay (%s)\n",
+ snd_strerror (err));
if (! SndSys_Recover (err))
return 0;
err = snd_pcm_delay (pcm_handle, &delay);
- if (err != 0)
+ if (err < 0)
{
Con_DPrintf ("SndSys_GetSoundTime: can't get playback delay, again (%s)\n",
snd_strerror (err));
}
}
-//Con_DPrintf(">> SndSys_GetSoundTime: expected_delay=%ld, delay=%ld\n",
-// expected_delay, delay);
if (expected_delay < delay)
{
- Con_Printf ("SndSys_GetSoundTime: expected_delay(%ld) < delay(%ld)\n",
- expected_delay, delay);
+ Con_DPrintf ("SndSys_GetSoundTime: expected_delay(%ld) < delay(%ld)\n",
+ expected_delay, delay);
timediff = 0;
}
else
timediff = expected_delay - delay;
expected_delay = delay;
-
+
alsasoundtime += (unsigned int)timediff;
-
+
return alsasoundtime;
}