-- GENERATED by C->Haskell Compiler, version 0.28.2 Switcheroo, 1 April 2016 (Haskell)
-- Edit the ORIGNAL .chs file instead!


{-# LINE 1 "Util/Audio/RubberbandC.chs" #-}
-- Copyright 2020 Evan Laforge
-- This program is distributed under the terms of the GNU General Public
-- License 3.0, see COPYING or http://www.gnu.org/licenses/gpl-3.0.txt

-- | Low level bindings to the rubberband library.
module Util.Audio.RubberbandC where
import qualified Foreign.C.Types as C2HSImp
import qualified Foreign.Marshal.Utils as C2HSImp
import qualified Foreign.Ptr as C2HSImp


import           Data.Bits ((.|.))
import           Foreign (Ptr, castPtr)
import qualified Foreign.C as C




type Frames = C.CUInt

-- RubberBandOption is actually several overlapping options.
data Option = ProcessOffline
            | StretchElastic
            | TransientsCrisp
            | DetectorCompound
            | PhaseLaminar
            | ThreadingAuto
            | WindowStandard
            | SmoothingOff
            | FormantShifted
            | PitchHighSpeed
            | ChannelsApart
            | ProcessRealTime
            | StretchPrecise
            | TransientsMixed
            | TransientsSmooth
            | DetectorPercussive
            | DetectorSoft
            | PhaseIndependent
            | ThreadingNever
            | ThreadingAlways
            | WindowShort
            | WindowLong
            | SmoothingOn
            | FormantPreserved
            | PitchHighQuality
            | PitchHighConsistency
            | ChannelsTogether
  deriving (Eq,Show)
instance Enum Option where
  succ ProcessOffline = ProcessRealTime
  succ StretchElastic = ProcessRealTime
  succ TransientsCrisp = ProcessRealTime
  succ DetectorCompound = ProcessRealTime
  succ PhaseLaminar = ProcessRealTime
  succ ThreadingAuto = ProcessRealTime
  succ WindowStandard = ProcessRealTime
  succ SmoothingOff = ProcessRealTime
  succ FormantShifted = ProcessRealTime
  succ PitchHighSpeed = ProcessRealTime
  succ ChannelsApart = ProcessRealTime
  succ ProcessRealTime = StretchPrecise
  succ StretchPrecise = TransientsMixed
  succ TransientsMixed = TransientsSmooth
  succ TransientsSmooth = DetectorPercussive
  succ DetectorPercussive = DetectorSoft
  succ DetectorSoft = PhaseIndependent
  succ PhaseIndependent = ThreadingNever
  succ ThreadingNever = ThreadingAlways
  succ ThreadingAlways = WindowShort
  succ WindowShort = WindowLong
  succ WindowLong = SmoothingOn
  succ SmoothingOn = FormantPreserved
  succ FormantPreserved = PitchHighQuality
  succ PitchHighQuality = PitchHighConsistency
  succ PitchHighConsistency = ChannelsTogether
  succ ChannelsTogether = error "Option.succ: ChannelsTogether has no successor"

  pred ProcessRealTime = ProcessOffline
  pred StretchPrecise = ProcessRealTime
  pred TransientsMixed = StretchPrecise
  pred TransientsSmooth = TransientsMixed
  pred DetectorPercussive = TransientsSmooth
  pred DetectorSoft = DetectorPercussive
  pred PhaseIndependent = DetectorSoft
  pred ThreadingNever = PhaseIndependent
  pred ThreadingAlways = ThreadingNever
  pred WindowShort = ThreadingAlways
  pred WindowLong = WindowShort
  pred SmoothingOn = WindowLong
  pred FormantPreserved = SmoothingOn
  pred PitchHighQuality = FormantPreserved
  pred PitchHighConsistency = PitchHighQuality
  pred ChannelsTogether = PitchHighConsistency
  pred ProcessOffline = error "Option.pred: ProcessOffline has no predecessor"
  pred StretchElastic = error "Option.pred: StretchElastic has no predecessor"
  pred TransientsCrisp = error "Option.pred: TransientsCrisp has no predecessor"
  pred DetectorCompound = error "Option.pred: DetectorCompound has no predecessor"
  pred PhaseLaminar = error "Option.pred: PhaseLaminar has no predecessor"
  pred ThreadingAuto = error "Option.pred: ThreadingAuto has no predecessor"
  pred WindowStandard = error "Option.pred: WindowStandard has no predecessor"
  pred SmoothingOff = error "Option.pred: SmoothingOff has no predecessor"
  pred FormantShifted = error "Option.pred: FormantShifted has no predecessor"
  pred PitchHighSpeed = error "Option.pred: PitchHighSpeed has no predecessor"
  pred ChannelsApart = error "Option.pred: ChannelsApart has no predecessor"

  enumFromTo from to = go from
    where
      end = fromEnum to
      go v = case compare (fromEnum v) end of
                 LT -> v : go (succ v)
                 EQ -> [v]
                 GT -> []

  enumFrom from = enumFromTo from ChannelsTogether

  fromEnum ProcessOffline = 0
  fromEnum StretchElastic = 0
  fromEnum TransientsCrisp = 0
  fromEnum DetectorCompound = 0
  fromEnum PhaseLaminar = 0
  fromEnum ThreadingAuto = 0
  fromEnum WindowStandard = 0
  fromEnum SmoothingOff = 0
  fromEnum FormantShifted = 0
  fromEnum PitchHighSpeed = 0
  fromEnum ChannelsApart = 0
  fromEnum ProcessRealTime = 1
  fromEnum StretchPrecise = 16
  fromEnum TransientsMixed = 256
  fromEnum TransientsSmooth = 512
  fromEnum DetectorPercussive = 1024
  fromEnum DetectorSoft = 2048
  fromEnum PhaseIndependent = 8192
  fromEnum ThreadingNever = 65536
  fromEnum ThreadingAlways = 131072
  fromEnum WindowShort = 1048576
  fromEnum WindowLong = 2097152
  fromEnum SmoothingOn = 8388608
  fromEnum FormantPreserved = 16777216
  fromEnum PitchHighQuality = 33554432
  fromEnum PitchHighConsistency = 67108864
  fromEnum ChannelsTogether = 268435456

  toEnum 0 = ProcessOffline
  toEnum 1 = ProcessRealTime
  toEnum 16 = StretchPrecise
  toEnum 256 = TransientsMixed
  toEnum 512 = TransientsSmooth
  toEnum 1024 = DetectorPercussive
  toEnum 2048 = DetectorSoft
  toEnum 8192 = PhaseIndependent
  toEnum 65536 = ThreadingNever
  toEnum 131072 = ThreadingAlways
  toEnum 1048576 = WindowShort
  toEnum 2097152 = WindowLong
  toEnum 8388608 = SmoothingOn
  toEnum 16777216 = FormantPreserved
  toEnum 33554432 = PitchHighQuality
  toEnum 67108864 = PitchHighConsistency
  toEnum 268435456 = ChannelsTogether
  toEnum unmatched = error ("Option.toEnum: Cannot match " ++ show unmatched)

{-# LINE 20 "Util/Audio/RubberbandC.chs" #-}



makeOptions :: [Option] -> C.CInt
makeOptions = fromIntegral . foldr (.|.) 0 . map fromEnum

defaultOptions :: [Option]
defaultOptions = []

percussiveOptions :: [Option]
percussiveOptions = [WindowShort, PhaseIndependent]

newtype State = State (C2HSImp.Ptr (State))
{-# LINE 32 "Util/Audio/RubberbandC.chs" #-}


-- RubberBandState rubberband_new(unsigned int sampleRate,
--                                unsigned int channels,
--                                RubberBandOptions options,
--                                double initialTimeRatio,
--                                double initialPitchScale);
rubberband_new :: (Frames) -> (Int) -> ([Option]) -> (Double) -> (Double) -> IO ((State))
rubberband_new a1 a2 a3 a4 a5 =
  let {a1' = id a1} in 
  let {a2' = fromIntegral a2} in 
  let {a3' = makeOptions a3} in 
  let {a4' = realToFrac a4} in 
  let {a5' = realToFrac a5} in 
  rubberband_new'_ a1' a2' a3' a4' a5' >>= \res ->
  let {res' = id res} in
  return (res')

{-# LINE 42 "Util/Audio/RubberbandC.chs" #-}


rubberband_delete :: (State) -> IO ()
rubberband_delete a1 =
  let {a1' = id a1} in 
  rubberband_delete'_ a1' >>
  return ()

{-# LINE 44 "Util/Audio/RubberbandC.chs" #-}


-- void rubberband_study(RubberBandState, const float *const *input,
-- unsigned int samples, int final);
rubberband_study :: (State) -> (Ptr (Ptr Float)) -> (Frames) -> (Bool) -> IO ()
rubberband_study a1 a2 a3 a4 =
  let {a1' = id a1} in 
  let {a2' = castPtr a2} in 
  let {a3' = id a3} in 
  let {a4' = C2HSImp.fromBool a4} in 
  rubberband_study'_ a1' a2' a3' a4' >>
  return ()

{-# LINE 50 "Util/Audio/RubberbandC.chs" #-}


-- void rubberband_process(RubberBandState, const float *const *input,
-- unsigned int samples, int final);
rubberband_process :: (State) -> (Ptr (Ptr Float)) -> (Frames) -> (Bool) -> IO ()
rubberband_process a1 a2 a3 a4 =
  let {a1' = id a1} in 
  let {a2' = castPtr a2} in 
  let {a3' = id a3} in 
  let {a4' = C2HSImp.fromBool a4} in 
  rubberband_process'_ a1' a2' a3' a4' >>
  return ()

{-# LINE 56 "Util/Audio/RubberbandC.chs" #-}


-- int rubberband_available(const RubberBandState);
-- -1 on final completion
rubberband_available :: (State) -> IO ((Int))
rubberband_available a1 =
  let {a1' = id a1} in 
  rubberband_available'_ a1' >>= \res ->
  let {res' = fromIntegral res} in
  return (res')

{-# LINE 60 "Util/Audio/RubberbandC.chs" #-}


-- Write up to the given Frames to the pointers.
-- unsigned int rubberband_retrieve(const RubberBandState,
-- float *const *output, unsigned int samples);
rubberband_retrieve :: (State) -> (Ptr (Ptr Float)) -> (Frames) -> IO ((Frames))
rubberband_retrieve a1 a2 a3 =
  let {a1' = id a1} in 
  let {a2' = castPtr a2} in 
  let {a3' = id a3} in 
  rubberband_retrieve'_ a1' a2' a3' >>= \res ->
  let {res' = id res} in
  return (res')

{-# LINE 67 "Util/Audio/RubberbandC.chs" #-}


-- void rubberband_set_expected_input_duration(RubberBandState,
-- unsigned int samples);
rubberband_set_expected_input_duration :: (State) -> (Frames) -> IO ()
rubberband_set_expected_input_duration a1 a2 =
  let {a1' = id a1} in 
  let {a2' = id a2} in 
  rubberband_set_expected_input_duration'_ a1' a2' >>
  return ()

{-# LINE 71 "Util/Audio/RubberbandC.chs" #-}


-- unsigned int rubberband_get_samples_required(const RubberBandState);
rubberband_get_samples_required :: (State) -> IO ((Frames))
rubberband_get_samples_required a1 =
  let {a1' = id a1} in 
  rubberband_get_samples_required'_ a1' >>= \res ->
  let {res' = id res} in
  return (res')

{-# LINE 74 "Util/Audio/RubberbandC.chs" #-}


-- void rubberband_set_time_ratio(RubberBandState, double ratio);
-- void rubberband_set_pitch_scale(RubberBandState, double scale);
--
-- double rubberband_get_time_ratio(const RubberBandState);
-- double rubberband_get_pitch_scale(const RubberBandState);
--
-- unsigned int rubberband_get_latency(const RubberBandState);
--
-- void rubberband_set_transients_option(RubberBandState,
-- RubberBandOptions options);
-- void rubberband_set_detector_option(RubberBandState,
-- RubberBandOptions options);
-- void rubberband_set_phase_option(RubberBandState, RubberBandOptions options);
-- void rubberband_set_formant_option(RubberBandState,
-- RubberBandOptions options);
-- void rubberband_set_pitch_option(RubberBandState, RubberBandOptions options);
--
-- void rubberband_set_max_process_size(RubberBandState, unsigned int samples);
-- void rubberband_set_key_frame_map(RubberBandState,
-- unsigned int keyframecount, unsigned int *from, unsigned int *to);
--
-- unsigned int rubberband_get_channel_count(const RubberBandState);
--
-- void rubberband_calculate_stretch(RubberBandState);
--
-- void rubberband_set_debug_level(RubberBandState, int level);
-- void rubberband_set_default_debug_level(int level);

foreign import ccall safe "Util/Audio/RubberbandC.chs.h rubberband_new"
  rubberband_new'_ :: (C2HSImp.CUInt -> (C2HSImp.CUInt -> (C2HSImp.CInt -> (C2HSImp.CDouble -> (C2HSImp.CDouble -> (IO (State)))))))

foreign import ccall safe "Util/Audio/RubberbandC.chs.h rubberband_delete"
  rubberband_delete'_ :: ((State) -> (IO ()))

foreign import ccall safe "Util/Audio/RubberbandC.chs.h rubberband_study"
  rubberband_study'_ :: ((State) -> ((C2HSImp.Ptr (C2HSImp.Ptr C2HSImp.CFloat)) -> (C2HSImp.CUInt -> (C2HSImp.CInt -> (IO ())))))

foreign import ccall safe "Util/Audio/RubberbandC.chs.h rubberband_process"
  rubberband_process'_ :: ((State) -> ((C2HSImp.Ptr (C2HSImp.Ptr C2HSImp.CFloat)) -> (C2HSImp.CUInt -> (C2HSImp.CInt -> (IO ())))))

foreign import ccall safe "Util/Audio/RubberbandC.chs.h rubberband_available"
  rubberband_available'_ :: ((State) -> (IO C2HSImp.CInt))

foreign import ccall safe "Util/Audio/RubberbandC.chs.h rubberband_retrieve"
  rubberband_retrieve'_ :: ((State) -> ((C2HSImp.Ptr (C2HSImp.Ptr C2HSImp.CFloat)) -> (C2HSImp.CUInt -> (IO C2HSImp.CUInt))))

foreign import ccall safe "Util/Audio/RubberbandC.chs.h rubberband_set_expected_input_duration"
  rubberband_set_expected_input_duration'_ :: ((State) -> (C2HSImp.CUInt -> (IO ())))

foreign import ccall safe "Util/Audio/RubberbandC.chs.h rubberband_get_samples_required"
  rubberband_get_samples_required'_ :: ((State) -> (IO C2HSImp.CUInt))