More coding to handle frame duration periods in the audio interfaces and the
authorbruceperens <bruceperens@01035d8c-6547-0410-b346-abe4f91aad63>
Thu, 13 Mar 2014 20:01:55 +0000 (20:01 +0000)
committerbruceperens <bruceperens@01035d8c-6547-0410-b346-abe4f91aad63>
Thu, 13 Mar 2014 20:01:55 +0000 (20:01 +0000)
scheduler.

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

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

index 548537c710733dfc2ffe7040ef02896676c1c1b7..0ab42bb883c2010af8d5cff936ff9a3f901d0184 100644 (file)
@@ -14,15 +14,19 @@ namespace FreeDV {
   const unsigned int   SampleRate = 48000;
 
   // The minimum frame duration in milliseconds. The audio interfaces will
-  // use this as a period size. It should be the smallest frame we  expect
-  // a modem/protocol/codec combination to use. If it's too large, latency
-  // will be overlong.
+  // use one half of this as a period size. It should be the smallest frame
+  // we  expect a modem/protocol/codec combination to use. If it's too large,
+  // latency will be overlong.
   const unsigned int   MinimumFrameDuration = 10;
 
   // The maximum frame duration in milliseconds. The audio interfaces will
-  // use 3 times this as a buffer size. It should be the largest frame we
-  // expect a modem/protocol/codec combination to use. If it's too large,
-  // ALSA bugs surface and cause long delays.
+  // use 2 times this as a buffer size. It must be an integer multiple of
+  // MinimumFrameDuration, or ALSA will complain. It should be the largest
+  // frame we expect a modem/protocol/codec combination to use.
+  // If a modem/framer/codec combination specify a frame duration larger than
+  // this, it's an error.
+  // If it's too large, ALSA bugs surface (Or is it my lack of
+  // understanding?) and cause long delays.
   const unsigned int   MaximumFrameDuration = 100;
 
   /// Allocate memory and copy a string into it, so that it is permanently
index 50ba740ef12a52c6fbff18694d12194d5b188bf2..6d0841106ae6f495a055d3f3937fccb6e880ac37 100644 (file)
@@ -59,7 +59,7 @@ namespace FreeDV {
      SND_PCM_ACCESS_RW_INTERLEAVED,
      1,
      SampleRate,
-     (int)ceil(((double)SampleRate / 1000.0) * MinimumFrameDuration),
+     (int)ceil(((double)SampleRate / 1000.0) * MinimumFrameDuration / 2),
      (int)ceil(((double)SampleRate / 1000.0) * MaximumFrameDuration * 2));
 
     snd_pcm_start(handle);
index 763ee0bd8703889d9738fbfe02c077f6c842ed78..5931e11da6c63f9388f659a98ba9a922647d786e 100644 (file)
@@ -61,7 +61,7 @@ namespace FreeDV {
      SND_PCM_ACCESS_RW_INTERLEAVED,
      1,
      SampleRate,
-     period_size,
+     period_size / 2,
      (int)ceil(((double)SampleRate / 1000.0) * MaximumFrameDuration));
   }
 
index dd762f015401a61a46dea8ebe9bede81bdc22d57..35272e8e63d3270156361c978c74a7ff332af35c 100644 (file)
@@ -1,9 +1,10 @@
 /// The main loop of the program.
 
 #include "drivers.h"
-#include <unistd.h>
 #include <iostream>
-#include <fstream>
+#include <sstream>
+#include <stdexcept>
+#include <unistd.h>
 #include <string.h>
 #include <sys/time.h>
 
@@ -22,7 +23,6 @@
 ///
 
 namespace FreeDV {
-
   class Run {
   private:
     const std::size_t  TempSize = 10240;
@@ -197,14 +197,23 @@ namespace FreeDV {
   void
   Run::run()
   {
-    // The no-op codec, modem, and framer may have very small durations.
-    // So we set a minimum here.
-    min_frame_duration = 10;
+    min_frame_duration = MinimumFrameDuration;
     min_frame_duration = max(min_frame_duration, i->modem->min_frame_duration());
     min_frame_duration = max(min_frame_duration, i->codec->min_frame_duration());
     min_frame_duration = max(min_frame_duration, i->framer->min_frame_duration());
 
     std::cerr << "minimum frame duration is " << min_frame_duration << std::endl;
+    if ( min_frame_duration > MaximumFrameDuration ) {
+      std::ostringstream str;
+
+      str << "At " << __FILE__ << ":" << __LINE__ << std::endl;
+      str << "min_frame_duration of " << min_frame_duration;
+      str << " is larger than MaximumFrameDuration of ";
+      str << MaximumFrameDuration << '.' << std::endl;
+      str << "A Modem, Framer, or Codec returned min_frame_duration() that";
+      str << " was too large, or MaximumFrameDuration must be increased.";
+      throw std::runtime_error(str.str().c_str());
+    }
     assert(min_frame_duration < 1000000);
 
     while ( true ) {