The codec encode16() and modem modulate16() can now refuse to encode any
authorbruceperens <bruceperens@01035d8c-6547-0410-b346-abe4f91aad63>
Fri, 21 Mar 2014 22:30:35 +0000 (22:30 +0000)
committerbruceperens <bruceperens@01035d8c-6547-0410-b346-abe4f91aad63>
Fri, 21 Mar 2014 22:30:35 +0000 (22:30 +0000)
data until they get a frame's worth. This simplifies their software, they
just return without processing anything until they get a full-enough FIFO
to process.

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

freedv-server/source/codec_noop.cpp
freedv-server/source/drivers.h
freedv-server/source/modem_noop.cpp
freedv-server/source/run.cpp

index f14ef6ca54e8718ddc8c4d8f8394aecd25a3038b..b3f0b4846c3778171374a778a3213fafe5e46468 100644 (file)
@@ -40,11 +40,16 @@ namespace FreeDV {
     /// \param i The array of audio samples to be encoded, in an array
     /// of signed 16-bit integers.
     /// \param o The encoded data, in an array of unsigned 8-bit integers.
-    /// \param length The number of audio samples to be encoded.
-    /// \return The number of std::uint8_t elements in the encoded array.
+    /// \param data_length The number of 8-bit data to be encoded.
+    /// \param sample_length On call: The number of 16-bit audio samples to
+    /// be encoded. On return: the number of samples that were consumed.
+    /// \return The number of 8-bit data elements in the encoded array.
     virtual std::size_t
-                       encode16(const std::int16_t * i, std::uint8_t * o, \
-                        std::size_t length);
+                       encode16(
+                        const std::int16_t * i,
+                        std::uint8_t * o, \
+                        std::size_t data_length,
+                        std::size_t *sample_length);
 
     /// Return the minimum duration of a frame in milliseconds.
     /// \return The minimum duration of a frame in milliseconds.
@@ -67,8 +72,7 @@ namespace FreeDV {
     std::size_t length = min(*data_length / 2, sample_length);
     length -= length % FrameSamples;
 
-    if ( length < FrameSamples )
-    {
+    if ( length < FrameSamples ) {
       *data_length = 0;
       return 0;
     }
@@ -78,9 +82,21 @@ namespace FreeDV {
   }
 
   std::size_t
-  CodecNoOp::encode16(const std::int16_t * i, std::uint8_t * o, std::size_t length)
+  CodecNoOp::encode16(
+   const std::int16_t * i,
+   std::uint8_t * o,
+   std::size_t data_length,
+   std::size_t *sample_length)
   {
-    memcpy(o, i, length);
+    std::size_t length = min(data_length / 2, *sample_length);
+    length -= length % FrameSamples;
+
+    if ( length < FrameSamples ) {
+      *sample_length = 0;
+      return 0;
+    }
+    memcpy(o, i, length * 2);
+    *sample_length = length / 2;
     return length;
   }
 
index 2a259f08504c3338ddf14087475c8f365a1f35e3..93ead3ec82edbebf3fae139dd8cf94a1fbb643cb 100644 (file)
@@ -336,7 +336,13 @@ public:
     virtual            ~AudioInput() = 0;
 
     /// Read audio into an array of the signed 16-bit integer type.
-    ///
+    /// Depending on the underlying device and its non-blocking status,
+    /// this may write fewer bytes than requested. It's permissible for
+    /// it to write no bytes and return 0.
+    /// \param array The array of audio samples to be read.
+    /// \param length The number of 16-bit audio samples which are to be read.
+    /// \return The number of 16-bit audio samples that were actually read.
+    /// This may be smaller than *length*, or it may be zero.
     virtual std::size_t
     read16(std::int16_t * array, std::size_t length) = 0;
 };
@@ -357,7 +363,14 @@ public:
     virtual            ~AudioOutput() = 0;
 
     /// Write audio from an array of the signed 16-bit integer type.
-    ///
+    /// Depending on the underlying device and its non-blocking status,
+    /// this may write fewer bytes than requested. It's permissible for
+    /// it to write no bytes and return 0.
+    /// \param array The array of audio samples to be written.
+    /// \param length The number of 16-bit audio samples which are to be
+    /// written.
+    /// \return The number of 16-bit audio samples that were actually written.
+    /// This may be smaller than *length*, or it may be zero.
     virtual std::size_t
     write16(const std::int16_t * array, std::size_t length) = 0;
 };
@@ -378,6 +391,11 @@ public:
     virtual            ~Codec() = 0;
 
     /// Decode from data bytes to audio samples.
+    /// Depending on the internal frame size for this particular codec
+    /// and the status of the incoming signal, this may consume and produce
+    /// less data than requested. It need not consume any data until it is
+    /// presented with enough to produce a full frame. It may throw away
+    /// as much incoming data as it likes without producing any.
     /// \param i The encoded data, in an array of unsigned 8-bit integers.
     /// \param o The array of audio samples after decoding, in an array
     /// of signed 16-bit integers.
@@ -387,24 +405,34 @@ public:
     /// \param sample_length The number of audio samples that may be decoded.
     /// \return The number of audio samples that were actually decoded.
     virtual std::size_t
-    decode16(const std::uint8_t * i,
-             std::int16_t * o,
-             std::size_t * data_length,
-             std::size_t sample_length) = 0;
+    decode16(
+     const std::uint8_t * i,
+     std::int16_t * o,
+     std::size_t * data_length,
+     std::size_t sample_length) = 0;
 
 
     /// Encode from audio samples to data bytes.
+    /// Depending on the internal frame size for this particular codec,
+    /// this may consume and produce less data than requested. It need not
+    /// consume any data until it is presented with enough to produce a full
+    /// frame.
     /// \param i The array of audio samples to be encoded, in an array
     /// of signed 16-bit integers.
     /// \param o The encoded data, in an array of unsigned 8-bit integers.
-    /// \param length The number of audio samples to be encoded.
+    /// \param sample_length On call: The number of audio samples to be
+    /// encoded. On return: The number of 16-bit audio samples that were
+    /// consumed.
     /// \return The number of std::uint8_t elements in the encoded array.
     virtual std::size_t
-    encode16(const std::int16_t * i, std::uint8_t * o,
-             std::size_t length) = 0;
+    encode16(
+     const std::int16_t * i,
+     std::uint8_t * o,
+     std::size_t data_length,
+     std::size_t * sample_length) = 0;
 
     /// Return the minimum duration of a frame in milliseconds.
-    /// \return The duration of a frame in milliseconds.
+    /// \return The minimum duration of a frame in milliseconds.
     virtual int
     min_frame_duration() const = 0;
 };
@@ -495,29 +523,44 @@ public:
     virtual            ~Modem() = 0;
 
     /// Demodulate from audio samples to data.
+    /// Depending on the internal frame size for this particular modem and
+    /// the status of the incoming signal, this may consume and produce less
+    /// data than requested. It need not consume any data until it is
+    /// presented with enough to produce a full frame. It may throw away as
+    /// much incoming data as it likes without producing any.
     /// \param i The array of audio samples to be demodulated, in an array
     /// of signed 16-bit integers.
     /// \param o The demodulated data, in an array of unsigned 8-bit integers.
+    /// \param data_length The number of bytes of data that may be demodulated.
     /// \param sample_length On call: The number of audio samples to be
     /// demodulated. On return: The number of audio samples consumed.
-    /// \param data_length The number of bytes of data that may be demodulated.
     /// \return The number of bytes of data that were actually decoded.
     virtual std::size_t
     demodulate16(
         const std::int16_t * i,
         std::uint8_t * o,
-        std::size_t * sample_length,
-        std::size_t data_length) = 0;
+        std::size_t data_length,
+        std::size_t * sample_length) = 0;
 
     /// Modulate from data to audio samples.
+    /// Depending on the internal frame size for this particular modem,
+    /// this may consume and produce less data than requested. It need not
+    /// consume any data until it is presented with enough to produce a full
+    /// frame.
     /// \param i The data, in an array of unsigned 8-bit integers.
     /// \param o The array of audio samples after modulation, in an array
     /// of signed 16-bit integers.
-    /// \param length The number of bytes of data to be modulated.
-    /// \return The number of std::int16_t elements in the modulated array.
+    /// \param data_length On call: The number of bytes of data to be
+    /// modulated. On return: the number of bytes that were consumed.
+    /// \param sample_length On call: The number of audio samples to be
+    /// modulated.
+    /// \return The number of 16-bit audio samples that were produced.
     virtual std::size_t
-    modulate16(const std::uint8_t * i, std::int16_t * o,
-               std::size_t length) = 0;
+    modulate16(
+     const std::uint8_t * i,
+     std::int16_t * o,
+     std::size_t * data_length,
+     std::size_t sample_length) = 0;
 
     /// Return the minimum duration of a frame in milliseconds.
     /// \return The minimum duration of a frame in milliseconds.
index 1ef64212e985dadb44a93369867ec26046560d13..9e77f943dc6781016d9850989c4d4caeb5bfbbbc 100644 (file)
@@ -30,26 +30,30 @@ namespace FreeDV {
     /// \param i The array of audio samples to be demodulated, in an array
     /// of signed 16-bit integers.
     /// \param o The demodulated data, in an array of unsigned 8-bit integers.
+    /// \param data_length The number of bytes of data that may be demodulated.
     /// \param sample_length On call: The number of audio samples to be
     /// demodulated. On return: The number of audio samples consumed.
-    /// \param data_length The number of bytes of data that may be demodulated.
     /// \return The number of bytes of data that were actually decoded.
     virtual std::size_t
                        demodulate16(
                         const std::int16_t * i,
                         std::uint8_t * o,
-                        std::size_t * sample_length,
-                        std::size_t data_length);
+                        std::size_t data_length,
+                        std::size_t * sample_length);
 
     /// Modulate from data to audio samples.
     /// \param i The data, in an array of unsigned 8-bit integers.
     /// \param o The array of audio samples after modulation, in an array
     /// of signed 16-bit integers.
-    /// \param length The number of bytes of data to be modulated.
-    /// \return The number of std::int16_t elements in the modulated array.
+    /// \param data_length On call: The number of bytes of data to be
+    /// modulated. On return: The number of bytes consumed.
+    /// \return The number of 16-bit audio samples in the modulated array.
     virtual std::size_t
-                       modulate16(const std::uint8_t * i, std::int16_t * o, \
-                        std::size_t length);
+                       modulate16(
+                         const std::uint8_t * i,
+                        std::int16_t * o, \
+                        std::size_t *data_length,
+                        std::size_t sample_length);
 
     /// Return the minimum duration of a frame in milliseconds.
     /// \return The minimum duration of a frame in milliseconds.
@@ -76,8 +80,8 @@ namespace FreeDV {
   ModemNoOp::demodulate16(
    const std::int16_t * i,
    std::uint8_t * o,
-   std::size_t * sample_length,
-   std::size_t data_length)
+   std::size_t data_length,
+   std::size_t * sample_length)
   {
     const std::size_t length = min(data_length / 2, *sample_length);
 
@@ -87,12 +91,17 @@ namespace FreeDV {
   }
 
   std::size_t
-  ModemNoOp::modulate16(const std::uint8_t * i, std::int16_t * o, std::size_t length)
+  ModemNoOp::modulate16(
+   const std::uint8_t * i,
+   std::int16_t * o,
+   std::size_t *data_length,
+   std::size_t sample_length)
   {
-    length = length - (length % 2);
+    const std::size_t length = min(*data_length / 2, sample_length);
 
-    memcpy(o, i, length);
-    return length / 2;
+    memcpy(o, i, length * 2);
+    *data_length = length * 2;
+    return length;
   }
 
   int
index 80f47ed4750d9bea4c2d6ec506759fbe03e244cc..0337213697c221b335ffb2b4bcc84763d2fffacc 100644 (file)
@@ -188,8 +188,8 @@ namespace FreeDV {
                            (const std::int16_t *)in_fifo.get(
                             samples_to_demodulate * 2),
                            codec_fifo.put(bytes_to_demodulate),
-                           &samples_to_demodulate,
-                           bytes_to_demodulate);
+                           bytes_to_demodulate,
+                           &samples_to_demodulate);
 
 
       if ( samples_to_demodulate > 0 )