No more timer-based operation.
authorbruceperens <bruceperens@01035d8c-6547-0410-b346-abe4f91aad63>
Tue, 18 Mar 2014 18:07:42 +0000 (18:07 +0000)
committerbruceperens <bruceperens@01035d8c-6547-0410-b346-abe4f91aad63>
Tue, 18 Mar 2014 18:07:42 +0000 (18:07 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@1447 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 b2672c18ee15a717dde58253cb2d3eb532034503..edd1b4b3115dd236833cb6a50805d386b4caddf3 100644 (file)
@@ -16,21 +16,10 @@ extern const char * program_name;
 /// drivers.
 const unsigned int     SampleRate = 48000;
 
-// The minimum frame duration in milliseconds. The audio interfaces will
-// 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 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;
+// The audio frame duration in milliseconds. The audio interfaces will
+// use this as a period size. It should be 1/2 of the smallest codec frame
+// size we expect to use.
+const unsigned int     AudioFrameDuration = 10;
 
 /// Allocate memory and copy a string into it, so that it is permanently
 /// stored.
index 2e0ae798cdcf1d803fab0c858d350330fb65a0d7..e93b47c7f0d8e73d67fc372446533a1fee3d3723 100644 (file)
@@ -15,7 +15,7 @@ namespace FreeDV {
   class AudioInALSA : public AudioInput {
   private:
     static const int   overlong_delay = ((double)SampleRate / 1000.0)
-                        * MaximumFrameDuration;
+                        * AudioFrameDuration * 2;
 
     char * const       parameters;
     snd_pcm_t *                handle;
@@ -67,8 +67,8 @@ namespace FreeDV {
      SND_PCM_ACCESS_RW_INTERLEAVED,
      1,
      SampleRate,
-     (int)ceil(((double)SampleRate / 1000.0) * MinimumFrameDuration / 2),
-     (int)ceil(((double)SampleRate / 1000.0) * MaximumFrameDuration));
+     (int)ceil((double)SampleRate / 1000.0) * AudioFrameDuration,
+     (int)ceil((double)SampleRate / 1000.0) * AudioFrameDuration);
 
     snd_pcm_start(handle);
   }
@@ -129,16 +129,13 @@ namespace FreeDV {
   std::size_t
   AudioInALSA::ready()
   {
-    static const int min_frame_size = (int)ceil(
-     ((double)SampleRate * 1000.0) * MinimumFrameDuration);
-
     snd_pcm_sframes_t  available = 0;
     snd_pcm_sframes_t  delay = 0;
     int                        error;
 
     if ( !started ) {
       snd_pcm_start(handle);
-      return min_frame_size;
+      return ((double)SampleRate / 1000.0) * AudioFrameDuration;
     }
 
     error = snd_pcm_avail_delay(handle, &available, &delay);
@@ -158,7 +155,7 @@ namespace FreeDV {
       std::cerr << "ALSA input \"" << parameters << "\": overlong delay, dropped "
        << seconds << " seconds of input." << std::endl;
 
-      return min_frame_size / 2;
+      return 0;
     }
 
     if ( error == -EPIPE ) {
index dca77e804c43addaa263c9226368b802fed2d96a..cf371a41d371f995620c1b9724cf170574dfb046 100644 (file)
@@ -17,7 +17,6 @@ namespace FreeDV {
   private:
     char * const       parameters;
     snd_pcm_t *                handle;
-    std::size_t                min_frame_size;
     bool               started;
 
     void
@@ -57,8 +56,6 @@ namespace FreeDV {
 
   AudioOutALSA::AudioOutALSA(const char * p)
   : AudioOutput("alsa", p), parameters(strdup(p)),
-    min_frame_size(
-     (int)ceil(((double)SampleRate / 1000.0) * MinimumFrameDuration)),
     started(false)
   {
     handle = ALSASetup(
@@ -69,8 +66,8 @@ namespace FreeDV {
      SND_PCM_ACCESS_RW_INTERLEAVED,
      1,
      SampleRate,
-     min_frame_size / 2,
-     min_frame_size * 8);
+     (int)ceil((double)SampleRate / 1000.0) * AudioFrameDuration,
+     (int)ceil((double)SampleRate / 1000.0) * AudioFrameDuration);
     snd_pcm_pause(handle, 1);
   }
 
@@ -134,10 +131,10 @@ namespace FreeDV {
     int                        error;
 
     if ( !started )
-      return min_frame_size;
+      return ((double)SampleRate / 1000.0) * AudioFrameDuration;
 
     error = snd_pcm_avail_delay(handle, &available, &delay);
-    if ( delay > (((double)SampleRate / 1000.0) * MaximumFrameDuration) ) {
+    if ( delay > (((double)SampleRate / 1000.0) * AudioFrameDuration * 2) ) {
       const double seconds = (double)delay / (double)SampleRate;
 
       std::cerr << "ALSA output \"" << parameters
@@ -154,7 +151,7 @@ namespace FreeDV {
       snd_pcm_recover(handle, error, 1);
       snd_pcm_pause(handle, 1);
       started = false;
-      return min_frame_size;
+      return 0;
 
       if ( error < 0 )
         return 0;
index 747a6ff0193ed160865a8e23e605b8c3204401b0..f84ff7479ebf61a54859bd2b8bc956907df3a51c 100644 (file)
@@ -34,8 +34,6 @@ namespace FreeDV {
     FIFO               out_fifo;
     bool               ptt_digital;
     bool               ptt_ssb;
-    std::size_t                min_frame_duration;
-    struct timespec    next_frame_time;
  
     void               key_down();
     void               key_up();
@@ -168,60 +166,16 @@ namespace FreeDV {
       if ( bytes_to_decode > 0 )
         codec_fifo.get_done(bytes_to_decode);
 
-      if ( result > 0 ) {
-       // std::cerr << '.';
+      if ( result > 0 )
         out_fifo.put_done(result * 2);
-
-        // Calculate a time one millisecond short of when the next frame
-        // should start. We can sleep until then.
-        const long duration = ((min_frame_duration - 1) * 1000000);
-
-        next_frame_time.tv_sec = start_time.tv_sec;
-        next_frame_time.tv_nsec = start_time.tv_nsec + duration;
-        next_frame_time.tv_sec += next_frame_time.tv_nsec / 1000000000;
-        next_frame_time.tv_nsec %= 1000000000;
-      }
-      else {
-
-       // std::cerr << '+';
-
-       // Go to sleep for a millisecond and try again. We could poll the
-        // I/O interfaces for ready instead.
-        next_frame_time = start_time;
-        next_frame_time.tv_nsec += 1000000;
-        next_frame_time.tv_sec += next_frame_time.tv_nsec / 1000000000;
-        next_frame_time.tv_nsec %= 1000000000;
-      }
     }
   }
   
   void
   Run::run()
   {
-    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 << "The minimum frame duration is "
-     << min_frame_duration << " milliseconds." << 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," << std::endl;
-      str << "or MaximumFrameDuration must be increased.";
-      throw std::runtime_error(str.str().c_str());
-    }
-    assert(min_frame_duration < 1000000);
-
     while ( true ) {
       receive();
-      clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &next_frame_time, 0);
     }
   }