(** This module perform audio resampling, rematrixing and sample format conversion operations. *)

open Avutil
open Swresample_options

(**/**)
type vector_kind = Str | P_Str | Fa | P_Fa | Ba | P_Ba | Frm
(**/**)


(** Audio data modules for Swresample module input and output parameterization. *)
module type AudioData = sig
  type t val vk : vector_kind val sf : Avutil.Sample_format.t
end

type options = [dither_type | engine | filter_type]

type ('i, 'o) ctx

(** Functor building an implementation of the swresample structure with parameterized input an output audio data types *)
module Make (I : AudioData) (O : AudioData) : sig

  type t = (I.t, O.t) ctx

  val create : ?options:options list -> Channel_layout.t -> ?in_sample_format:Sample_format.t -> int -> Channel_layout.t -> ?out_sample_format:Sample_format.t -> int -> t
  (** [Swresample.create in_cl ~in_sample_format:in_sf in_sr out_cl ~out_sample_format:out_sf out_sr] create a Swresample.t with [in_cl] channel layout, [in_sf] sample format and [in_sr] sample rate as input format and [out_cl] channel layout, [out_sf] sample format and [out_sr] sample rate as output format.
If a sample format parameter is not provided, the sample format defined by the associated AudioData module is used.
@raise Error "Swresample input/output sample format undefined" if a sample format parameter is not provided and the associated AudioData module does not define a sample format as is the case for Bytes and Frame. *)

  val from_codec : ?options:options list -> audio Avcodec.params -> Channel_layout.t -> ?out_sample_format:Sample_format.t -> int -> t
  (** [Swresample.from_codec in_ac out_cl ~out_sample_format:out_sf out_sr] do the same as {!Swresample.create} with the [in_ac] audio codec properties as input format. *)


  val to_codec : ?options:options list -> Channel_layout.t -> ?in_sample_format:Sample_format.t -> int -> audio Avcodec.params -> t
  (** [Swresample.to_codec in_cl ~in_sample_format:in_sf in_sr out_ac] do the same as {!Swresample.create} with the [out_ac] audio codec properties as output format. *)


  val from_codec_to_codec : ?options:options list -> audio Avcodec.params -> audio Avcodec.params -> t
  (** [Swresample.from_codec_to_codec in_ac out_ac] do the same as {!Swresample.create} with the [in_ac] audio codec properties as input format and the [out_ac] audio codec properties as output format. *)

  val reuse_output : t -> bool -> unit
  (** [Swresample.reuse_output ro] enables or disables the reuse of {!Swresample.convert} output according to the value of [ro]. Reusing the output reduces the number of memory allocations. In this cas, the data returned by {!Swresample.convert} is invalidated by a new call to this function. *)

  val convert : t -> I.t -> O.t
  (** [Swresample.convert rsp iad] resample and convert the [iad] input audio data to the output audio data according to the [rsp] resampler context format.
@raise Error if the conversion failed. *)
end

    
(** Byte string with undefined sample format for interleaved channels. The sample format must be passed to the create function. *)
module Bytes : sig
  type t = bytes val vk : vector_kind val sf : Sample_format.t
end

(** Unsigned 8 bit sample format byte string for interleaved channels. *)
module U8Bytes : sig
  type t = bytes val vk : vector_kind val sf : Sample_format.t
end

(** Signed 16 bit sample format byte string for interleaved channels. *)
module S16Bytes : sig
  type t = bytes val vk : vector_kind val sf : Sample_format.t
end

(** Signed 32 bit sample format byte string for interleaved channels. *)
module S32Bytes : sig
  type t = bytes val vk : vector_kind val sf : Sample_format.t
end

(** Float 32 bit sample format byte string for interleaved channels. *)
module FltBytes : sig
  type t = bytes val vk : vector_kind val sf : Sample_format.t
end

(** Float 64 bit sample format byte string for interleaved channels. *)
module DblBytes : sig
  type t = bytes val vk : vector_kind val sf : Sample_format.t
end

(** Unsigned 8 bit sample format byte string for planar channels. *)
module U8PlanarBytes : sig
  type t = bytes array val vk : vector_kind val sf : Sample_format.t
end

(** Signed 16 bit sample format byte string for planar channels. *)
module S16PlanarBytes : sig
  type t = bytes array val vk : vector_kind val sf : Sample_format.t
end

(** Signed 32 bit sample format byte string for planar channels. *)
module S32PlanarBytes : sig
  type t = bytes array val vk : vector_kind val sf : Sample_format.t
end

(** Float 32 bit sample format byte string for planar channels. *)
module FltPlanarBytes : sig
  type t = bytes array val vk : vector_kind val sf : Sample_format.t
end

(** Float 64 bit sample format byte string for planar channels. *)
module DblPlanarBytes : sig
  type t = bytes array val vk : vector_kind val sf : Sample_format.t
end

(** Float 64 bit sample format array for interleaved channels. *)
module FloatArray : sig
  type t = float array val vk : vector_kind val sf : Sample_format.t
end

(** Float 64 bit sample format array for planar channels. *)
module PlanarFloatArray : sig
  type t = float array array val vk : vector_kind val sf : Sample_format.t
end

type u8ba = (int, Bigarray.int8_unsigned_elt, Bigarray.c_layout) Bigarray.Array1.t
type s16ba = (int, Bigarray.int16_signed_elt, Bigarray.c_layout) Bigarray.Array1.t
type s32ba = (int32, Bigarray.int32_elt, Bigarray.c_layout) Bigarray.Array1.t
type f32ba = (float, Bigarray.float32_elt, Bigarray.c_layout) Bigarray.Array1.t
type f64ba = (float, Bigarray.float64_elt, Bigarray.c_layout) Bigarray.Array1.t

(** Unsigned 8 bit sample format bigarray for interleaved channels. *)
module U8BigArray : sig
  type t = u8ba val vk : vector_kind val sf : Sample_format.t
end

(** Signed 16 bit sample format bigarray for interleaved channels. *)
module S16BigArray : sig
  type t = s16ba val vk : vector_kind val sf : Sample_format.t
end

(** Signed 32 bit sample format bigarray for interleaved channels. *)
module S32BigArray : sig
  type t = s32ba val vk : vector_kind val sf : Sample_format.t
end

(** Float 32 bit sample format bigarray for interleaved channels. *)
module FltBigArray : sig
  type t = f32ba val vk : vector_kind val sf : Sample_format.t
end

(** Float 64 bit sample format bigarray for interleaved channels. *)
module DblBigArray : sig
  type t = f64ba val vk : vector_kind val sf : Sample_format.t
end

(** Unsigned 8 bit sample format bigarray for planar channels. *)
module U8PlanarBigArray : sig
  type t = u8ba array val vk : vector_kind val sf : Sample_format.t
end

(** Signed 16 bit sample format bigarray for planar channels. *)
module S16PlanarBigArray : sig
  type t = s16ba array val vk : vector_kind val sf : Sample_format.t
end

(** Signed 32 bit sample format bigarray for planar channels. *)
module S32PlanarBigArray : sig
  type t = s32ba array val vk : vector_kind val sf : Sample_format.t
end

(** Float 32 bit sample format bigarray for planar channels. *)
module FltPlanarBigArray : sig
  type t = f32ba array val vk : vector_kind val sf : Sample_format.t
end

(** Float 64 bit sample format bigarray for planar channels. *)
module DblPlanarBigArray : sig
  type t = f64ba array val vk : vector_kind val sf : Sample_format.t
end

(** Audio frame with undefined sample format. The sample format must be passed to the create function. *)
module Frame : sig
  type t = audio frame val vk : vector_kind val sf : Sample_format.t
end

(** Unsigned 8 bit sample format audio frame for interleaved channels. *)
module U8Frame : sig
  type t = audio frame val vk : vector_kind val sf : Sample_format.t
end

(** Signed 16 bit sample format audio frame for interleaved channels. *)
module S16Frame : sig
  type t = audio frame val vk : vector_kind val sf : Sample_format.t
end

(** Signed 32 bit sample format audio frame for interleaved channels. *)
module S32Frame : sig
  type t = audio frame val vk : vector_kind val sf : Sample_format.t
end

(** Float 32 bit sample format audio frame for interleaved channels. *)
module FltFrame : sig
  type t = audio frame val vk : vector_kind val sf : Sample_format.t
end

(** Float 64 bit sample format audio frame for interleaved channels. *)
module DblFrame : sig
  type t = audio frame val vk : vector_kind val sf : Sample_format.t
end

(** Unsigned 8 bit sample format audio frame for planar channels. *)
module U8PlanarFrame : sig
  type t = audio frame val vk : vector_kind val sf : Sample_format.t
end

(** Signed 16 bit sample format audio frame for planar channels. *)
module S16PlanarFrame : sig
  type t = audio frame val vk : vector_kind val sf : Sample_format.t
end

(** Signed 32 bit sample format audio frame for planar channels. *)
module S32PlanarFrame : sig
  type t = audio frame val vk : vector_kind val sf : Sample_format.t
end

(** Float 32 bit sample format audio frame for planar channels. *)
module FltPlanarFrame : sig
  type t = audio frame val vk : vector_kind val sf : Sample_format.t
end

(** Float 64 bit sample format audio frame for planar channels. *)
module DblPlanarFrame : sig
  type t = audio frame val vk : vector_kind val sf : Sample_format.t
end

