Audio input works.
authorbruceperens <bruceperens@01035d8c-6547-0410-b346-abe4f91aad63>
Wed, 12 Mar 2014 21:17:11 +0000 (21:17 +0000)
committerbruceperens <bruceperens@01035d8c-6547-0410-b346-abe4f91aad63>
Wed, 12 Mar 2014 21:17:11 +0000 (21:17 +0000)
Also code handler for overlong audio input delays, as with a paused program.

git-svn-id: https://svn.code.sf.net/p/freetel/code@1430 01035d8c-6547-0410-b346-abe4f91aad63

freedv-server/source/platform/linux/audio_in_alsa.cpp

index 54b000fe8976f434aad8d5bbd464cc2f557a3751..4421031762f476e9802599b5b16d9e5b52fb457b 100644 (file)
@@ -14,6 +14,9 @@ namespace FreeDV {
   /// Audio input "ALSA", Uses the Linux ALSA Audio API.
   class AudioInALSA : public AudioInput {
   private:
+    static const int   overlong_delay = 300;
+    static const int   delay_goal = 50;
+
     char * const       parameters;
     snd_pcm_t *                handle;
 
@@ -52,7 +55,7 @@ namespace FreeDV {
     const unsigned int         channels = 1;
     const unsigned int         rate = 48000;
     const int                  soft_resample = 0;
-    const unsigned int         latency = 10000;
+    const unsigned int         latency = 0;
     int                                error;
 
     handle = 0;
@@ -129,14 +132,40 @@ namespace FreeDV {
     int                        error;
 
     error = snd_pcm_avail_delay(handle, &available, &delay);
+
+    // If the program has been paused, there will be a long queue of incoming
+    // audio samples and a corresponding delay. This can also happen if the
+    // incoming audio interface runs at a faster rate than the outgoing one.
+    if ( delay >= overlong_delay && available > 0 ) {
+      int dropped = 0;
+
+      while ( delay > delay_goal ) {
+        std::int16_t   buffer[1000];
+
+        int            samples = min(available, delay - delay_goal);
+        const int      length = min(sizeof(buffer) / sizeof(*buffer),
+                        samples);
+
+       if ( snd_pcm_readi(handle, buffer, length) < 0 )
+          break;
+        dropped += length;
+        if ( snd_pcm_avail_delay(handle, &available, &delay) < 0 )
+          break;
+      }
+      std::cerr << "ALSA input: long delay, dropped "
+       << dropped << " queued audio samples." << std::endl;
+
+    }
+
     if ( error == -EPIPE ) {
       snd_pcm_recover(handle, error, 1);
       available = snd_pcm_avail_delay(handle, &available, &delay);
       std::cerr << "ALSA read underrun." << std::endl;
     }
-    if ( error >= 0 ) {
+
+    if ( error >= 0 )
       return available;
-    }
+
     else if ( error == -EPIPE )
       return 0;
     else {