Add incremental read support
M bqaudiostream.sig +9 -1
@@ 43,12 43,20 @@ signature BQ_AUDIOREADSTREAM = sig
         estimate; reading may stop earlier or continue beyond. *)
     val estimated_frame_count : t -> int option
 
+    (** Return true if the stream has explicit support for synchronous
+        incremental reading (i.e. reading while the file is still
+        being written without returning early on EOF). *)
+    val has_incremental_support : t -> bool
+
+    (** Set timeouts for incremental reading, in milliseconds. *)
+    val set_incremental_timeouts : t * { retry : int, total : int } -> unit
+
     (** Return the track name for the given stream, if available. *)
     val track_name : t -> string option
 
     (** Return the artist name for the given stream, if available. *)
     val artist_name : t -> string option
-
+                                           
     (** Read interleaved audio data from the given stream. The given
         number of frames n will be read, if available, and the
         returned vector will have at most n * channels values in

          
M ffi/bqaudiostream.sml +7 -1
@@ 63,7 63,13 @@ structure BqAudioReadStream :>
         case bqar_get_estimated_frame_count t of
             0 => NONE
           | n => SOME (Int64.toInt n)
-        
+
+    fun has_incremental_support t =
+        bqar_has_incremental_support t
+
+    fun set_incremental_timeouts (t, { retry, total }) =
+        bqar_set_incremental_timeouts (t, retry, total)
+                      
     fun rate t =
         Int64.toInt (bqar_get_retrieval_sample_rate t)
                              

          
M ffi/impl-bqaudiostream.cpp +11 -0
@@ 144,6 144,17 @@ extern "C" {
 	else return 0;
     }
 
+    Bool bqar_has_incremental_support(Pointer sptr) {
+	stream_rec *rsr = reinterpret_cast<stream_rec *>(sptr);
+	if (rsr->rstream) return rsr->rstream->hasIncrementalSupport();
+	else return false;
+    }
+
+    void bqar_set_incremental_timeouts(Pointer sptr, int64_t retry, int64_t total) {
+	stream_rec *rsr = reinterpret_cast<stream_rec *>(sptr);
+	if (rsr->rstream) rsr->rstream->setIncrementalTimeouts(retry, total);
+    }
+    
     int64_t bqar_get_retrieval_sample_rate(Pointer sptr) {
 	stream_rec *rsr = reinterpret_cast<stream_rec *>(sptr);
 	if (rsr->rstream) return rsr->rstream->getRetrievalSampleRate();

          
M ffi/import-bqaudiostream.sml +8 -0
@@ 46,6 46,14 @@ structure ImportBqAudioStream = struct
         _import "bqar_get_estimated_frame_count" private:
         audiostreamhandle -> Int64.int;
 
+    val bqar_has_incremental_support =
+        _import "bqar_has_incremental_support" private:
+        audiostreamhandle -> bool;
+
+    val bqar_set_incremental_timeouts =
+        _import "bqar_set_incremental_timeouts" private:
+        audiostreamhandle * Int64.int * Int64.int -> unit;
+    
     val bqar_get_retrieval_sample_rate =
         _import "bqar_get_retrieval_sample_rate" private:
         audiostreamhandle -> Int64.int;

          
M sml/bqaudiostream.sml +2 -0
@@ 53,6 53,8 @@ functor BqAudioReadStreamFn (S: READ_STR
           | SOME e => if Real.== (ratio, 1.0)
                       then SOME e
                       else SOME (Real.round (ratio * Real.fromInt e))
+    fun has_incremental_support (t : t) = false
+    fun set_incremental_timeouts (t, timeouts) = ()
 
     open IoResult