<commit_before>> {-# LANGUAGE Arrows #-}

try and play two samples
one after another

> module Main where
> import Euterpea hiding (MUI)
> --import Euterpea.IO.Audio.PortAudioChannel
> import Control.Arrow
> import Control.Concurrent
> import Control.Concurrent.STM

> import Euterpea.Experimental
> import System.IO.Unsafe

STM

> type VolChan = TChan Double

GUI

the problem with convertToUISF is that then you ahve to write enough samples
to fill the buffer until the next tick of the clock (uisf at 60fps, audsf at 44k)
so this is a bad idea
    _ <- convertToUISF 60 60


> volume_slider :: UISF () (Double)
> volume_slider = proc _ -> do
>    a <- title "volume"  $ vSlider (0,1) 0 -< ()
>    _ <- display -< 1-a
>    outA -< 1-a

> writeArr :: VolChan -> UISF (Double) ()
> writeArr v = liftAIO (\x -> atomically $ writeTChan v x)

> mixer_board :: VolChan -> UISF () ()
> mixer_board vc = title "Mixer" $ proc _ -> do
>    v <- volume_slider -< ()
>    _ <- writeArr vc -< 1-v
>    returnA -< ()

Audio

> volume_control :: AudSF (Double, Double) (Double)
> volume_control = arr (\(s,v) -> (s* v))

> read_volume :: VolChan -> (AudSF () Double)
> read_volume v =  arr (\x -> unsafePerformIO $ atomically $ peekTChan v)

 read_volume :: AudSF VolChan Double
 read_volume =  arr (\v -> unsafePerformIO $ atomically $ peekTChan v)


wavSF :: FilePath -> IO (AudSF () Double)

                     inSig <- unsafePerformIO $ wavSFInf "input2.wav" -< ()
                     withVol <- read_volume v -< ()
                     appVol <- volume_control -< withVol
                     returnA -< appVol

> wavloop :: VolChan -> IO ()
> wavloop v =
>   let sigToPlay = ((unsafePerformIO $ wavSFInf "input2.wav") &&& read_volume v) >>> volume_control
>   in
>     do
>       playSignal 20 sigToPlay


 main :: IO ()
 main = do
  runUI "UI test" mixer_board
  wavloop

 kGUI :: Kleisli IO () Double
 kGUI = Kleisli (\x -> do runUI "test" mixer_board)

    d <- convertToUISF sr 0.1 myAutomaton -< (f1, f2)

 kAudio :: Kleisli IO Double ()
 kAudio = Kleisli (\v -> do wavloop v)

> main' :: IO ()
> main' = do
>  v <- newTChanIO
>  setNumCapabilities 2
>  forkOn 1 $ runUI "UI Demo" (mixer_board v)
>  forkOn 2 $ wavloop v
>  return ()


foo :: [Int] -> Int
foo = map


use STM to write the UISF value then read in the AudSF thread
 lift monad to arrow to allow for STM to work in arrow?
 at that point i can instead just lift m to arr for runUI and playSingal
 then i can compose the two, and pass state same as uisf deos

 so i want
 Kleisli IO
   IO Monad
      UISF and AudSF

or does kleisli IO replace IO Monad

an exampke of how to use klieslie<commit_msg>i think a basic working version with tchan<commit_after>> {-# LANGUAGE Arrows #-}

try and play two samples
one after another

> module Main where
> import Euterpea hiding (MUI)
> --import Euterpea.IO.Audio.PortAudioChannel
> import Control.Arrow
> import Control.Concurrent
> import Control.Concurrent.STM

> import Control.Monad

> import Euterpea.Experimental
> import System.IO.Unsafe

STM

> type VolChan = TChan Double

GUI

the problem with convertToUISF is that then you ahve to write enough samples
to fill the buffer until the next tick of the clock (uisf at 60fps, audsf at 44k)
so this is a bad idea
    _ <- convertToUISF 60 60


> volume_slider :: UISF () (Double)
> volume_slider = proc _ -> do
>    a <- title "volume"  $ vSlider (0,1) 0 -< ()
>    _ <- display -< 1-a
>    outA -< 1-a

> uisfWriter :: VolChan -> UISF (Double) ()
> uisfWriter v = liftAIO (\x -> atomically $ writeTChan v x)

> mixer_board :: VolChan -> UISF () ()
> mixer_board vc = title "Mixer" $ proc _ -> do
>    v <- volume_slider -< ()
>   -- _ <- uisfWriter vc -< 1-v
>    returnA -< ()

Audio

> volume_control :: AudSF (Double, Double) (Double)
> volume_control = arr (\(s,v) -> (s* v))

> -- sfReader :: (Arrow a, Chan b) => Chan b -> (a () b)
> sfReader :: VolChan -> (AudSF () Double)
> sfReader v =  arr (\x -> g $ unsafePerformIO $ atomically $ tryReadTChan v)
>  where
>    g Nothing = 0
>    g (Just x) = x

 wavloop :: VolChan -> IO ()
 wavloop v = do
   foo <- wavSFInf "input2.wav"
   let sigPlay = (foo &&& sfReader v) >>> volume_control
   playSignal 20 sigPlay


   let sigToPlay = ((unsafePerformIO $ wavSFInf "input2.wav") &&& sfReader v) >>> volume_control
   in
     do
       playSignal 20 sigToPlay

playSignal wants a pure signal,
need a playImpureSignal


> main' :: IO ()
> main' = do
>  v <- newTChanIO
>  setNumCapabilities 2
>  forkOn 1 $ runMUI' "UI Demo" (mixer_board v)
> -- forkOn 2 $ outFile "test.wav" 10 $ sfReader v
> -- forkOn 2 $ forever $ (atomically $ isEmptyTChan v) >>= print
> --forkOn 2 $ wavloop v
>  return ()


foo :: [Int] -> Int
foo = map


use STM to write the UISF value then read in the AudSF thread
 lift monad to arrow to allow for STM to work in arrow?
 at that point i can instead just lift m to arr for runUI and playSingal
 then i can compose the two, and pass state same as uisf deos

 so i want
 Kleisli IO
   IO Monad
      UISF and AudSF

or does kleisli IO replace IO Monad

wavSF :: FilePath -> IO (AudSF () Double)

                     inSig <- unsafePerformIO $ wavSFInf "input2.wav" -< ()
                     withVol <- read_volume v -< ()
                     appVol <- volume_control -< withVol
                     returnA -< appVol

 main :: IO ()
 main = do
  runUI "UI test" mixer_board
  wavloop

 kGUI :: Kleisli IO () Double
 kGUI = Kleisli (\x -> do runUI "test" mixer_board)

    d <- convertToUISF sr 0.1 myAutomaton -< (f1, f2)

 kAudio :: Kleisli IO Double ()
 kAudio = Kleisli (\v -> do wavloop v)

an exampke of how to use klieslie
{'fraction_non_alphanumeric': 0.11485532815808046, 'fraction_numerical': 0.010232886379675371, 'mean_word_length': 2.712508185985593, 'pattern_counts': {'":': 0, '<': 46, '<?xml version=': 0, '>': 122, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '430780', 'n_tokens_mistral': 2098, 'n_tokens_neox': 1961, 'n_words': 702}