Get the wait-for-output software working correctly.
authorbruceperens <bruceperens@01035d8c-6547-0410-b346-abe4f91aad63>
Wed, 28 May 2014 22:02:30 +0000 (22:02 +0000)
committerbruceperens <bruceperens@01035d8c-6547-0410-b346-abe4f91aad63>
Wed, 28 May 2014 22:02:30 +0000 (22:02 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@1606 01035d8c-6547-0410-b346-abe4f91aad63

freedv-server/source/drivers.h
freedv-server/source/platform/linux/alsa.cpp
freedv-server/source/platform/linux/audio_in_alsa.cpp
freedv-server/source/platform/linux/audio_out_alsa.cpp
freedv-server/source/run.cpp

index 0682e5b800a58956c43a78429d5b7833ce4d0470..6d262583d7127b463087b11ea80f9b08c6e84078 100644 (file)
@@ -60,10 +60,9 @@ const unsigned int   SampleRate = 48000;
 const unsigned int     SamplesPerMillisecond = ((double)SampleRate / 1000.0);
 
 
-/// The number of audio samples in an audio frame. Audio frames must be a
-/// power of two (this is a common hardware requirement) and must be shorter
-/// than any codec/modem frame in the program.
-const unsigned int     AudioFrameSamples = 512;
+/// The number of audio samples in an audio frame. Some systems will require
+/// this to be a power of two (this is a common hardware requirement).
+const unsigned int     AudioFrameSamples = SampleRate / 20;
 
 /// The audio frame duration in milliseconds. The audio interfaces will
 /// use this as a period size.
index e38c46a8c8bccaab2e47320bab9f33a195230898..738a6ffe85070d3307caf1b69963e2462a16d9b2 100644 (file)
@@ -303,13 +303,11 @@ namespace FreeDV {
       if ((error = snd_pcm_sw_params(handle, sw_params)) < 0)
         do_throw(error, name, stream, "ALSA set software parameters");
       
-#if 0
       // Dump sound parameters, for debugging.
       snd_output_t * output = 0;
       snd_output_stdio_attach(&output, stderr, 0);
       fprintf(stderr, "%s\n", name);
       snd_pcm_dump_setup(handle, output);
-#endif
 
       snd_pcm_sw_params_free(sw_params);
 
index e5a194f683673922b9cf095bcedbfec2b8f90536..becad0d5b3db54c6eaf1d946114f1c24514e1a18 100644 (file)
@@ -23,7 +23,7 @@ namespace FreeDV {
   ///
   class AudioInALSA : public AudioInput {
   private:
-    static const int   overlong_delay = AudioFrameSamples * 8;
+    static const int   overlong_delay = AudioFrameSamples * 4;
 
     snd_pcm_t *                handle;
     char * const       parameters;
@@ -83,7 +83,7 @@ namespace FreeDV {
      1,
      SampleRate,
      AudioFrameSamples, 
-     AudioFrameSamples * 2);
+     AudioFrameSamples * 3);
 
     if ( handle == 0 )
       do_throw(-ENODEV);
index d20d983c74e2e3a7c43ae0bfd4424d3f0640d56f..9d9144626cacb813d5826f7de33604e798deb392 100644 (file)
@@ -22,7 +22,7 @@ namespace FreeDV {
 
   // If more than this number of frames are queued for audio output, the
   // latency is too high. Flush the output and print an overlong-delay message.
-  const unsigned int   MaximumDelayFrames = 8;
+  const unsigned int   MaximumDelayFrames = 4;
 
   // At the start of playback, preload the audio output with this many
   // frames of zero data. This delays the output enough to avoid later
@@ -95,7 +95,7 @@ namespace FreeDV {
      1,
      SampleRate,
      AudioFrameSamples,
-     AudioFrameSamples * 2);
+     AudioFrameSamples * 3);
 
     if ( handle == 0 )
       do_throw(-ENODEV);
@@ -206,7 +206,7 @@ namespace FreeDV {
     // If we've not started, allow the first write to be large, but
     // not so large that we'll active the overlong-delay code.
     if ( !started )
-      return AudioFrameSamples * MaximumDelayFrames - FillFrames - 1;
+      return AudioFrameSamples * min(1, (MaximumDelayFrames - FillFrames - 1));
     else
       return available;
   }
index bba6642b9174c33eb09089b5ab1c1603a9422111..5834b488046c03b7a722f2db15bf918219b58079 100644 (file)
@@ -63,6 +63,9 @@ namespace FreeDV {
     /// Run the main loop of FreeDV in half-duplex mode.
     ///
     void               half_duplex();
+
+    /// Wake when there is room in the output device.
+    void               wake_output(AudioDevice *);
   };
   
   Run::Run(Interfaces * interfaces)
@@ -214,22 +217,7 @@ namespace FreeDV {
       else if ( result < 0 )
        std::cerr << "Transmitter I/O error: " << strerror(errno) << std::endl;
     }
-    if ( out_fifo.get_available() > 0 ) {
-      // There are samples queued for the transmitter. Wake when there is room
-      // in its buffer.
-      if ( output_fd_base < 0 ) {
-        output_fd_base = poll_fd_count;
-        add_poll_device(i->transmitter);
-      }
-    }
-    else {
-      // There are no samples queued for the transmitter. Don't wake upon its
-      // buffer availability.
-      if ( output_fd_base > 0 ) {
-        poll_fd_count = output_fd_base;
-        output_fd_base = -1;
-      }
-    }
+    wake_output(i->transmitter);
 
     if ( final ) {
       if ( in_fifo.get_available() == 0
@@ -267,22 +255,7 @@ namespace FreeDV {
       else if ( result < 0 )
        std::cerr << "Transmitter I/O error: " << strerror(errno) << std::endl;
     }
-    if ( out_fifo.get_available() > 0 ) {
-      // There are samples queued for the transmitter. Wake when there is room
-      // in its buffer.
-      if ( output_fd_base < 0 ) {
-        output_fd_base = poll_fd_count;
-        add_poll_device(i->transmitter);
-      }
-    }
-    else {
-      // There are no samples queued for the transmitter. Don't wake upon its
-      // buffer availability.
-      if ( output_fd_base > 0 ) {
-        poll_fd_count = output_fd_base;
-        output_fd_base = -1;
-      }
-    }
+    wake_output(i->transmitter);
 
     if ( final ) {
       if ( in_fifo.get_available() == 0
@@ -367,24 +340,7 @@ namespace FreeDV {
       else if ( result < 0 )
        std::cerr << "Loudspeaker I/O error: " << strerror(errno) << std::endl;
     }
-
-    if ( out_fifo.get_available() > 0 ) {
-      // std::cerr << out_fifo.get_available() / 2 << ' ';
-      // There are samples queued for the loudspeaker. Wake when there is room
-      // in its buffer.
-      if ( output_fd_base < 0 ) {
-        output_fd_base = poll_fd_count;
-        add_poll_device(i->transmitter);
-      }
-    }
-    else {
-      // There are no samples queued for the loudspeaker. Don't wake upon its
-      // buffer availability.
-      if ( output_fd_base > 0 ) {
-        poll_fd_count = output_fd_base;
-        output_fd_base = -1;
-      }
-    }
+    wake_output(i->loudspeaker);
   }
    
   // FIX: Once everything else has been tested, make this program work with
@@ -616,6 +572,28 @@ namespace FreeDV {
     drain_ssb(false);
   }
    
+  void
+  Run::wake_output(AudioDevice * device)
+  {
+    if ( out_fifo.get_available() / 2 > 0 ) {
+      // There are samples queued for the loudspeaker/transmitter.
+      // Wake when there is room
+      // in its buffer.
+      if ( output_fd_base < 0 ) {
+        output_fd_base = poll_fd_count;
+        add_poll_device(device);
+      }
+    }
+    else {
+      // There are no samples queued for the loudspeaker/transmitter.
+      // Don't wake upon its buffer availability.
+      if ( output_fd_base > 0 ) {
+        poll_fd_count = output_fd_base;
+        output_fd_base = -1;
+      }
+    }
+  }
+
   int
   run(Interfaces * i)
   {