[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    arts/flow
From:       Allan Sandfeld Jensen <kde () carewolf ! com>
Date:       2004-03-31 21:21:22
Message-ID: 20040331212122.1A30999B5 () office ! kde ! org
[Download RAW message or body]

CVS commit by carewolf: 

Avoid infinite loops when playing through DMix.

CCMAIL: 70802@bugs.kde.org


  M +45 -25    audioioalsa9.cc   1.7


--- arts/flow/audioioalsa9.cc  #1.6:1.7
@@ -72,5 +72,7 @@ protected:
         int m_period_size, m_periods;
         bool inProgress;
+        bool restartIOHandling;
 
+        void startIO();
         int poll2iomanager(int pollTypes);
         int setPcmParams(snd_pcm_t *pcm);
@@ -118,4 +120,6 @@ AudioIOALSA::AudioIOALSA()
         m_pcm_capture = NULL;
         inProgress = false;
+        restartIOHandling = false;
+        audio_read_fd = audio_write_fd = -1;
 }
 
@@ -196,14 +200,6 @@ bool AudioIOALSA::open()
                   (float)(2.0 * _samplingRate * _channels)*1000.0);
 
-        /* watch PCM file descriptor(s) */
-        Dispatcher::the()->ioManager()->remove(this, IOType::all);
-        audio_read_fd = audio_write_fd = -1;
-        if (_direction & directionWrite) {
-                audio_write_fd = watchDescriptor(m_pcm_playback);
-        }
-        if (_direction & directionRead) {
-                audio_read_fd = watchDescriptor(m_pcm_capture);
-        }
 
+        startIO();
         /* restore the format value */
         switch (m_format) {
@@ -311,4 +307,16 @@ int AudioIOALSA::getParam(AudioParam p)
 }
 
+void AudioIOALSA::startIO()
+{
+        /* watch PCM file descriptor(s) */
+        if (m_pcm_playback) {
+                audio_write_fd = watchDescriptor(m_pcm_playback);
+        }
+        if (m_pcm_capture) {
+                audio_read_fd = watchDescriptor(m_pcm_capture);
+        }
+
+}
+
 int AudioIOALSA::poll2iomanager(int pollTypes)
 {
@@ -352,5 +360,4 @@ int AudioIOALSA::xrun(snd_pcm_t *pcm)
         if ((err = snd_pcm_prepare(pcm)) < 0)
                 return err;
-        if (pcm == m_pcm_capture)
                 snd_pcm_start(pcm); // ignore error here..
         return 0;
@@ -367,5 +374,4 @@ int AudioIOALSA::resume(snd_pcm_t *pcm)
                 if ((err = snd_pcm_prepare(pcm)) < 0)
                         return err;
-                if (pcm == m_pcm_capture)
                         snd_pcm_start(pcm); // ignore error here..
         }
@@ -395,4 +401,8 @@ int AudioIOALSA::read(void *buffer, int 
 int AudioIOALSA::write(void *buffer, int size)
 {
+        // DMix has an annoying habit of returning instantantly on the returned
+        // poll-descriptor. So we block here to avoid an infinity loop.
+        while(snd_pcm_wait(m_pcm_playback, 1) == 0);
+
         int frames = snd_pcm_bytes_to_frames(m_pcm_playback, size);
         int length;
@@ -416,5 +426,13 @@ void AudioIOALSA::notifyIO(int fd, int t
     int todo = 0;
 
-    if (inProgress) return;
+        if(inProgress)
+        {
+                if(!restartIOHandling)
+                {
+                        Dispatcher::the()->ioManager()->remove(this,IOType::all);
+                        restartIOHandling = true;
+                }
+                return;
+        }
 
     // We can't trust the type as ALSA might have read-type events,
@@ -425,8 +443,10 @@ void AudioIOALSA::notifyIO(int fd, int t
     if (type & IOType::except) todo |= AudioSubSystem::ioExcept;
 
+        restartIOHandling = false;
     inProgress = true;
     AudioSubSystem::the()->handleIO(todo);
     inProgress = false;
 
+        if (restartIOHandling) startIO();
 }
 


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic