]> git.sesse.net Git - vlc/blobdiff - modules/audio_output/alsa.c
* Move the embedded option to libvlc
[vlc] / modules / audio_output / alsa.c
index f4b554f7762cdba0386bc17e8cc4b71f3820f35b..7b45b4a2b077446956a0f3dc5c2cee2ffdf3691c 100644 (file)
@@ -21,7 +21,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  *****************************************************************************/
 
 /*****************************************************************************
@@ -34,6 +34,7 @@
 #include <vlc/vlc.h>
 
 #include <vlc/aout.h>
+#include <vlc_interaction.h>
 
 #include "aout_internal.h"
 
@@ -201,7 +202,7 @@ static void Probe( aout_instance_t * p_aout,
                     break;
                 case 6:
                     val.i_int = AOUT_VAR_5_1;
-                    text.psz_string = N_("5.1");
+                    text.psz_string = "5.1";
                     var_Change( p_aout, "audio-device",
                                 VLC_VAR_ADDCHOICE, &val, &text );
                     break;
@@ -225,7 +226,7 @@ static void Probe( aout_instance_t * p_aout,
                 var_Set( p_aout, "audio-device", val );
             }
         }
-        
+
         /* Close the previously opened device */
         snd_pcm_close( p_sys->p_snd_pcm );
     }
@@ -322,12 +323,13 @@ static int Open( vlc_object_t *p_this )
     if( (psz_device = config_GetPsz( p_aout, "alsadev" )) == NULL )
     {
         msg_Err( p_aout, "no audio device given (maybe \"default\" ?)" );
+        intf_UserFatal( p_aout, VLC_FALSE, _("No Audio Device"), 
+                        _("No audio device name was given. You might want to " \
+                          "enter \"default\".") );
         free( p_sys );
         return VLC_EGENERIC;
     }
 
-    p_sys->p_status = (snd_pcm_status_t *)malloc(snd_pcm_status_sizeof());
-
     /* Choose the IEC device for S/PDIF output:
        if the device is overriden by the user then it will be the one
        otherwise we compute the default device based on the output format. */
@@ -376,7 +378,6 @@ static int Open( vlc_object_t *p_this )
 
     if ( var_Get( p_aout, "audio-device", &val ) < 0 )
     {
-        free( p_sys->p_status );
         free( p_sys );
         free( psz_device );
         return VLC_EGENERIC;
@@ -413,7 +414,6 @@ static int Open( vlc_object_t *p_this )
     {
         /* This should not happen ! */
         msg_Err( p_aout, "internal: can't find audio-device (%i)", val.i_int );
-        free( p_sys->p_status );
         free( p_sys );
         free( psz_device );
         return VLC_EGENERIC;
@@ -431,7 +431,9 @@ static int Open( vlc_object_t *p_this )
         {
             msg_Err( p_aout, "cannot open ALSA device `%s' (%s)",
                              psz_iec_device, snd_strerror( i_snd_rc ) );
-            free( p_sys->p_status );
+            intf_UserFatal( p_aout, VLC_FALSE, _("Audio output failed"), 
+                            _("VLC could not open the ALSA device \"%s\" (%s)."),
+                            psz_iec_device, snd_strerror( i_snd_rc ) );
             free( p_sys );
             free( psz_device );
             return VLC_EGENERIC;
@@ -464,8 +466,14 @@ static int Open( vlc_object_t *p_this )
                    SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK ) ) == -EBUSY )
             {
                 if( i ) msleep( 100000 /* 100ms */ );
-                else msg_Err( p_aout, "audio device: %s is already in use",
+                else
+                {
+                    msg_Err( p_aout, "audio device: %s is already in use",
                               psz_device );
+                    intf_UserFatal( p_aout, VLC_FALSE, _("Audio output failed"), 
+                                    _("The audio device \"%s\" is already in use."),
+                                    psz_device );
+                }
                 continue;
             }
             break;
@@ -474,7 +482,9 @@ static int Open( vlc_object_t *p_this )
         {
             msg_Err( p_aout, "cannot open ALSA device `%s' (%s)",
                              psz_device, snd_strerror( i_snd_rc ) );
-            free( p_sys->p_status );
+            intf_UserFatal( p_aout, VLC_FALSE, _("Audio output failed"), 
+                            _("VLC could not open the ALSA device \"%s\" (%s)."),
+                            psz_device, snd_strerror( i_snd_rc ) );
             free( p_sys );
             free( psz_device );
             return VLC_EGENERIC;
@@ -572,9 +582,9 @@ static int Open( vlc_object_t *p_this )
 #endif
         if( i_snd_rc < 0 || p_aout->output.output.i_rate != i_old_rate )
         {
-            msg_Warn( p_aout, "The rate %d Hz is not supported by your hardware. "
-                  "Using %d Hz instead.\n", i_old_rate,
-                  p_aout->output.output.i_rate );
+            msg_Warn( p_aout, "The rate %d Hz is not supported by your " \
+                "hardware. Using %d Hz instead.\n", i_old_rate, \
+                p_aout->output.output.i_rate );
         }
 
         /* Set buffer size. */
@@ -678,7 +688,6 @@ error:
 #ifdef ALSA_DEBUG
     snd_output_close( p_sys->p_snd_stderr );
 #endif
-    free( p_sys->p_status );
     free( p_sys );
     return VLC_EGENERIC;
 }
@@ -733,7 +742,6 @@ static void Close( vlc_object_t *p_this )
     snd_output_close( p_sys->p_snd_stderr );
 #endif
 
-    free( p_sys->p_status );
     free( p_sys );
 }
 
@@ -742,6 +750,9 @@ static void Close( vlc_object_t *p_this )
  *****************************************************************************/
 static int ALSAThread( aout_instance_t * p_aout )
 {
+    p_aout->output.p_sys->p_status =
+        (snd_pcm_status_t *)malloc(snd_pcm_status_sizeof());
+
     /* Wait for the exact time to start playing (avoids resampling) */
     vlc_mutex_lock( &p_aout->output.p_sys->lock );
     if( !p_aout->output.p_sys->start_date )
@@ -756,6 +767,7 @@ static int ALSAThread( aout_instance_t * p_aout )
         ALSAFill( p_aout );
     }
 
+    free( p_aout->output.p_sys->p_status );
     return 0;
 }
 
@@ -765,10 +777,8 @@ static int ALSAThread( aout_instance_t * p_aout )
 static void ALSAFill( aout_instance_t * p_aout )
 {
     struct aout_sys_t * p_sys = p_aout->output.p_sys;
-
     aout_buffer_t * p_buffer;
     snd_pcm_status_t * p_status = p_sys->p_status;
-    snd_timestamp_t ts_next;
     int i_snd_rc;
     mtime_t next_date;
 
@@ -793,7 +803,7 @@ static void ALSAFill( aout_instance_t * p_aout )
 
             if( i_snd_rc == 0 )
             {
-                msg_Warn( p_aout, "recovered from buffer underrun" );
+                msg_Dbg( p_aout, "recovered from buffer underrun" );
 
                 /* Reget the status */
                 i_snd_rc = snd_pcm_status( p_sys->p_snd_pcm, p_status );
@@ -822,6 +832,8 @@ static void ALSAFill( aout_instance_t * p_aout )
             /* Here the device should be either in the RUNNING state.
              * p_status is valid. */
 
+#if 0
+    /* This apparently does not work correctly in Alsa 1.0.11 */
             snd_pcm_status_get_tstamp( p_status, &ts_next );
             next_date = (mtime_t)ts_next.tv_sec * 1000000 + ts_next.tv_usec;
             if( next_date )
@@ -830,19 +842,15 @@ static void ALSAFill( aout_instance_t * p_aout )
                         * 1000000 / p_aout->output.output.i_rate;
             }
             else
+#endif
             {
                 /* With screwed ALSA drivers the timestamp is always zero;
                  * use another method then */
-                snd_pcm_sframes_t delay;
-                ssize_t i_bytes = 0;
+                snd_pcm_sframes_t delay = 0;
 
-                if( !snd_pcm_delay( p_sys->p_snd_pcm, &delay ) )
-                {
-                    i_bytes = snd_pcm_frames_to_bytes(p_sys->p_snd_pcm, delay);
-                }
-                next_date = mdate() + (mtime_t)i_bytes * 1000000
-                        / p_aout->output.output.i_bytes_per_frame
-                        / p_aout->output.output.i_rate
+                snd_pcm_delay( p_sys->p_snd_pcm, &delay );
+                next_date = mdate() + (mtime_t)(delay) * 1000000 /
+                          p_aout->output.output.i_rate
                         * p_aout->output.output.i_frame_length;
             }
         }