diff --git a/bower.json b/bower.json index f82290b..cf6a761 100644 --- a/bower.json +++ b/bower.json @@ -18,28 +18,28 @@ "tests" ], "dependencies": { - "purescript-arrays": "^4.2.0", - "purescript-foldable-traversable": "^3.6.0", - "purescript-lists": "^4.10.0", + "purescript-arrays": "^5.1.1", + "purescript-foldable-traversable": "^4.1.1", + "purescript-lists": "^5.3.0", "purescript-math": "^2.1.0", - "purescript-maybe": "^3.0.0", - "purescript-tuples": "^4.1.0", - "purescript-strings": "^3.3.1", - "purescript-eff": "^3.1.0", - "purescript-aff": "^4.0.0", + "purescript-maybe": "^4.0.1", + "purescript-tuples": "^5.1.0", + "purescript-strings": "^4.0.1", + "purescript-effect": "^2.0.0", + "purescript-aff": "^5.0.2", "purescript-arraybuffer-types": "^2.0.0", - "jacereda/purescript-arraybuffer": "^6.0.0" + "jacereda/purescript-arraybuffer": "^8.0.2" }, "devDependencies": { - "purescript-console": "^3.0.0", - "purescript-psci-support": "^3.0.0", - "purescript-dom": "^4.16.0", - "purescript-js-timers": "^3.0.0", - "purescript-affjax": "^5.0.0", - "purescript-assert": "^3.0.0", - "purescript-refs": "^3.0.0" - }, - "resolutions": { - "purescript-arraybuffer-types": "^2.0.0" + "purescript-console": "^4.2.0", + "purescript-psci-support": "^4.0.0", + "purescript-web-dom": "^1.0.0", + "purescript-web-events": "^1.0.1", + "purescript-web-html": "^1.2.0", + "purescript-js-timers": "^4.0.1", + "purescript-affjax": "^7.0.0", + "purescript-assert": "^4.0.0", + "purescript-exceptions": "^4.0.0", + "purescript-refs": "^4.1.0" } } diff --git a/examples/decodeAsync/Main.purs b/examples/decodeAsync/Main.purs index f8b06c6..a7c2ee1 100644 --- a/examples/decodeAsync/Main.purs +++ b/examples/decodeAsync/Main.purs @@ -4,60 +4,43 @@ import Prelude import Audio.WebAudio.AudioBufferSourceNode (setBuffer, startBufferSource) import Audio.WebAudio.BaseAudioContext (createBufferSource, currentTime, decodeAudioDataAsync, destination, newAudioContext) -import Audio.WebAudio.Types (AudioContext, AudioBuffer, AUDIO, connect) -import Control.Monad.Aff (Aff, Fiber, launchAff) -import Control.Monad.Eff (Eff) -import Control.Monad.Eff.Class (liftEff) +import Audio.WebAudio.Types (AudioContext, AudioBuffer, connect) +import Effect.Aff (Aff, Fiber, launchAff) +import Effect (Effect) +import Effect.Class (liftEffect) import Control.Parallel (parallel, sequential) import Data.Either (Either(..)) -import Data.HTTP.Method (Method(..)) import Data.Traversable (traverse) import Data.Maybe (Maybe(..)) import Data.Array ((!!)) -import Network.HTTP.Affjax (AJAX, affjax, defaultRequest) +import Affjax (get) +import Affjax.ResponseFormat (arrayBuffer, ResponseFormatError) type ElapsedTime = Number -- | load a single sound buffer resource and decode it -loadSoundBuffer :: ∀ eff. - AudioContext - -> String - -> Aff - ( ajax :: AJAX - , audio :: AUDIO - | eff - ) - AudioBuffer +loadSoundBuffer :: AudioContext + -> String + -> Aff (Either ResponseFormatError AudioBuffer) loadSoundBuffer ctx fileName = do - res <- affjax $ defaultRequest { url = fileName, method = Left GET } - buffer <- decodeAudioDataAsync ctx res.response - pure buffer + res <- get arrayBuffer fileName + traverse (decodeAudioDataAsync ctx) res.body -- | load and decode an array of audio buffers from a set of resources -loadSoundBuffers :: ∀ e. - AudioContext - -> (Array String) - -> Aff - ( ajax :: AJAX - , audio :: AUDIO - | e - ) - (Array AudioBuffer) +loadSoundBuffers :: AudioContext + -> Array String + -> Aff (Array (Either ResponseFormatError AudioBuffer)) loadSoundBuffers ctx fileNames = sequential $ traverse (\name -> parallel (loadSoundBuffer ctx name)) fileNames -- | Play a sound at a sepcified elapsed time -playSoundAt :: ∀ eff. - AudioContext - -> Maybe AudioBuffer - -> ElapsedTime - -> Eff - ( audio :: AUDIO - | eff ) - Unit +playSoundAt :: AudioContext + -> Maybe (Either ResponseFormatError AudioBuffer) + -> ElapsedTime + -> Effect Unit playSoundAt ctx mbuffer elapsedTime = case mbuffer of - Just buffer -> + Just (Right buffer) -> do startTime <- currentTime ctx src <- createBufferSource ctx @@ -69,26 +52,14 @@ playSoundAt ctx mbuffer elapsedTime = _ -> pure unit -main :: ∀ eff. - Eff - ( ajax :: AJAX - , audio :: AUDIO - | eff - ) - (Fiber - ( ajax :: AJAX - , audio :: AUDIO - | eff - ) - Unit - ) +main :: Effect (Fiber Unit) main = launchAff $ do - ctx <- liftEff newAudioContext + ctx <- liftEffect newAudioContext buffers <- loadSoundBuffers ctx ["hihat.wav", "kick.wav", "snare.wav"] - _ <- liftEff $ playSoundAt ctx (buffers !! 0) 0.0 - _ <- liftEff $ playSoundAt ctx (buffers !! 1) 0.5 - _ <- liftEff $ playSoundAt ctx (buffers !! 2) 1.0 - _ <- liftEff $ playSoundAt ctx (buffers !! 0) 1.5 - _ <- liftEff $ playSoundAt ctx (buffers !! 1) 2.0 - _ <- liftEff $ playSoundAt ctx (buffers !! 2) 2.5 + _ <- liftEffect $ playSoundAt ctx (buffers !! 0) 0.0 + _ <- liftEffect $ playSoundAt ctx (buffers !! 1) 0.5 + _ <- liftEffect $ playSoundAt ctx (buffers !! 2) 1.0 + _ <- liftEffect $ playSoundAt ctx (buffers !! 0) 1.5 + _ <- liftEffect $ playSoundAt ctx (buffers !! 1) 2.0 + _ <- liftEffect $ playSoundAt ctx (buffers !! 2) 2.5 pure unit diff --git a/examples/gain/Main.purs b/examples/gain/Main.purs index a72e58b..d74c5cb 100644 --- a/examples/gain/Main.purs +++ b/examples/gain/Main.purs @@ -6,29 +6,23 @@ import Audio.WebAudio.BaseAudioContext (createGain, currentTime, destination, ne import Audio.WebAudio.AudioContext (createMediaElementSource) import Audio.WebAudio.AudioParam (setValueAtTime) import Audio.WebAudio.GainNode (gain) -import Audio.WebAudio.Types (connect, AUDIO) -import Control.Monad.Eff (Eff) -import Control.Monad.Eff.Console (CONSOLE, logShow) -import Control.Monad.Eff.Exception (EXCEPTION, throw) -import DOM (DOM) -import DOM.HTML (window) -import DOM.HTML.Types (htmlDocumentToNonElementParentNode) -import DOM.HTML.Window (document) -import DOM.Node.NonElementParentNode (getElementById) +import Audio.WebAudio.Types (connect) +import Effect (Effect) +import Effect.Console (logShow) +import Effect.Exception (throw) +import Web.HTML (window) +import Web.HTML.HTMLDocument (toNonElementParentNode) as HTMLDocument +import Web.HTML.Window (document) +import Web.DOM.NonElementParentNode (getElementById) import Data.Maybe (Maybe(..)) -import Data.Newtype (wrap) -- | 3 secs after the audio begins playing, set the value (i.e., volume) -- | of the gain node to 0.3 (i.e., a 70% reduction) -main :: Eff ( dom :: DOM - , audio :: AUDIO - , console :: CONSOLE - , exception :: EXCEPTION - ) Unit +main :: Effect Unit main = do - doc <- map htmlDocumentToNonElementParentNode (window >>= document) - noise <- getElementById (wrap "noise") doc + doc <- map HTMLDocument.toNonElementParentNode (window >>= document) + noise <- getElementById "noise" doc case noise of Just el -> void do cx <- newAudioContext diff --git a/examples/square-wave/Main.purs b/examples/square-wave/Main.purs index 7cdae20..b6102e0 100644 --- a/examples/square-wave/Main.purs +++ b/examples/square-wave/Main.purs @@ -3,30 +3,30 @@ module SquareWave where import Prelude -import Audio.WebAudio.Types (AUDIO, AudioContext, GainNode, OscillatorNode, AudioContextState(..), connect) +import Audio.WebAudio.Types (AudioContext, GainNode, OscillatorNode, AudioContextState(..), connect) import Audio.WebAudio.BaseAudioContext (createGain, createOscillator, currentTime, destination, newAudioContext, resume, state, suspend) import Audio.WebAudio.AudioParam (getValue, setValue, setValueAtTime) import Audio.WebAudio.GainNode (gain) import Audio.WebAudio.Oscillator (OscillatorType(..), frequency, setOscillatorType, startOscillator) -import Control.Monad.Eff (Eff) -import Control.Monad.Eff.Exception (EXCEPTION, throw) -import Control.Monad.Eff.Ref (REF, Ref, newRef, readRef, writeRef) -import Control.Monad.Eff.Timer (IntervalId, TIMER, clearInterval, setInterval) -import DOM (DOM) -import DOM.Event.EventTarget (addEventListener, eventListener) -import DOM.Event.Types (EventTarget) -import DOM.HTML (window) -import DOM.HTML.Types (htmlDocumentToParentNode) -import DOM.HTML.Window (document) -import DOM.Node.ParentNode (querySelector) +import Effect (Effect) +import Effect.Exception (throw) +import Effect.Ref (Ref) +import Effect.Ref (new, read, write) as Ref +import Effect.Timer (IntervalId, clearInterval, setInterval) +import Web.Event.EventTarget (EventTarget, addEventListener, eventListener) +--import Web.Event.Types (EventTarget) +import Web.HTML (window) +import Web.HTML.HTMLDocument (toParentNode) as HTMLDocument +import Web.HTML.Window (document) +import Web.DOM.ParentNode (querySelector) import Data.Maybe (Maybe(..)) import Data.Newtype (wrap) import Unsafe.Coerce (unsafeCoerce) -beep :: ∀ e. AudioContext +beep :: AudioContext -> OscillatorNode -> GainNode - -> Eff (audio :: AUDIO, timer :: TIMER | e) Unit + -> Effect Unit beep ctx osc g = do freqParam <- frequency osc f <- getValue freqParam @@ -38,31 +38,24 @@ beep ctx osc g = do _ <- setValueAtTime 0.001 (t + 0.2) gainParam pure unit -controls :: - ∀ e. Ref IntervalId - -> AudioContext - -> OscillatorNode - -> GainNode - -> Eff (audio :: AUDIO, timer :: TIMER, ref :: REF | e) Unit +controls :: Ref IntervalId + -> AudioContext + -> OscillatorNode + -> GainNode + -> Effect Unit controls ref ctx osc g = do s <- state ctx if (s == SUSPENDED) then do resume ctx t <- setInterval 1000 $ beep ctx osc g - writeRef ref t + Ref.write t ref else do suspend ctx - val <- readRef ref + val <- Ref.read ref clearInterval val -main :: - ∀ e. Eff ( audio :: AUDIO - , dom :: DOM - , exception :: EXCEPTION - , timer :: TIMER - , ref :: REF | e - ) Unit +main :: Effect Unit main = do ctx <- newAudioContext @@ -78,15 +71,19 @@ main = do suspend ctx - let id = unsafeCoerce (newRef 0) :: Ref IntervalId + let id = unsafeCoerce (Ref.new 0) :: Ref IntervalId - doc <- map htmlDocumentToParentNode (window >>= document) + doc <- map HTMLDocument.toParentNode (window >>= document) play <- querySelector (wrap "#play") doc case play of - Just e -> addEventListener (wrap "click") (eventListener \_ -> controls id ctx osc g) false (unsafeCoerce e :: EventTarget) + Just e -> do + listener <- eventListener \_ -> controls id ctx osc g + addEventListener (wrap "click") listener false (unsafeCoerce e :: EventTarget) Nothing -> throw "No 'play' button" stop <- querySelector (wrap "#stop") doc case stop of - Just e -> addEventListener (wrap "click") (eventListener \_ -> controls id ctx osc g) false (unsafeCoerce e :: EventTarget) + Just e -> do + listener <- eventListener \_ -> controls id ctx osc g + addEventListener (wrap "click") listener false (unsafeCoerce e :: EventTarget) Nothing -> throw "No 'stop' button" pure unit diff --git a/package.json b/package.json index d0b8685..5e84ca7 100644 --- a/package.json +++ b/package.json @@ -37,5 +37,6 @@ ], "license": "MIT", "devDependencies": { + "text-encoding": "^0.7.0" } } diff --git a/src/Audio/WebAudio/AnalyserNode.purs b/src/Audio/WebAudio/AnalyserNode.purs index 95f5694..d7bc5de 100644 --- a/src/Audio/WebAudio/AnalyserNode.purs +++ b/src/Audio/WebAudio/AnalyserNode.purs @@ -7,8 +7,8 @@ module Audio.WebAudio.AnalyserNode import Prelude (Unit) import Data.ArrayBuffer.Types (ByteLength, Uint8Array, Float32Array) -import Audio.WebAudio.Types (AnalyserNode, AUDIO) -import Control.Monad.Eff (Eff) +import Audio.WebAudio.Types (AnalyserNode) +import Effect (Effect) import Audio.WebAudio.Utils (unsafeGetProp, unsafeSetProp) @@ -16,42 +16,42 @@ import Audio.WebAudio.Utils (unsafeGetProp, unsafeSetProp) -- | from 32 to 32768; its default value is 2048. -- | If its value is not a power of 2, or it is outside the specified range, -- | the exception INDEX_SIZE_ERR is thrown. -fftSize :: ∀ eff. AnalyserNode -> (Eff (audio :: AUDIO | eff) ByteLength) +fftSize :: AnalyserNode -> Effect ByteLength fftSize n = unsafeGetProp "fftSize" n -setFftSize :: ∀ eff. ByteLength -> AnalyserNode -> (Eff (audio :: AUDIO | eff) Unit) +setFftSize :: ByteLength -> AnalyserNode -> Effect Unit setFftSize size n = unsafeSetProp "fftSize" n size -frequencyBinCount :: ∀ eff. AnalyserNode -> (Eff (audio :: AUDIO | eff) ByteLength) +frequencyBinCount :: AnalyserNode -> Effect ByteLength frequencyBinCount n = unsafeGetProp "frequencyBinCount" n -setFrequencyBinCount :: ∀ eff. ByteLength -> AnalyserNode -> (Eff (audio :: AUDIO | eff) Unit) +setFrequencyBinCount :: ByteLength -> AnalyserNode -> Effect Unit setFrequencyBinCount count n = unsafeSetProp "frequencyBinCount" n count -minDecibels :: ∀ eff. AnalyserNode -> (Eff (audio :: AUDIO | eff) Number) +minDecibels :: AnalyserNode -> Effect Number minDecibels n = unsafeGetProp "minDecibels" n -setMinDecibels :: ∀ eff. Number -> AnalyserNode -> (Eff (audio :: AUDIO | eff) Unit) +setMinDecibels :: Number -> AnalyserNode -> Effect Unit setMinDecibels db n = unsafeSetProp "minDecibels" n db -maxDecibels :: ∀ eff. AnalyserNode -> (Eff (audio :: AUDIO | eff) Number) +maxDecibels :: AnalyserNode -> Effect Number maxDecibels n = unsafeGetProp "maxDecibels" n -setMaxDecibels :: ∀ eff. Number -> AnalyserNode -> (Eff (audio :: AUDIO | eff) Unit) +setMaxDecibels :: Number -> AnalyserNode -> Effect Unit setMaxDecibels db n = unsafeSetProp "maxDecibels" n db -smoothingTimeConstant :: ∀ eff. AnalyserNode -> (Eff (audio :: AUDIO | eff) Number) +smoothingTimeConstant :: AnalyserNode -> Effect Number smoothingTimeConstant n = unsafeGetProp "smoothingTimeConstant" n -setSmoothingTimeConstant :: ∀ eff. Number -> AnalyserNode -> (Eff (audio :: AUDIO | eff) Unit) +setSmoothingTimeConstant :: Number -> AnalyserNode -> Effect Unit setSmoothingTimeConstant tc n = unsafeSetProp "smoothingTimeConstant" n tc -foreign import getFloatFrequencyData :: ∀ eff. AnalyserNode -> Float32Array -> (Eff (audio :: AUDIO | eff) Unit) +foreign import getFloatFrequencyData :: AnalyserNode -> Float32Array -> Effect Unit -foreign import getByteFrequencyData :: ∀ eff. AnalyserNode -> Uint8Array -> (Eff (audio :: AUDIO | eff) Unit) +foreign import getByteFrequencyData :: AnalyserNode -> Uint8Array -> Effect Unit -foreign import getFloatTimeDomainData :: ∀ eff. AnalyserNode -> Float32Array -> (Eff (audio :: AUDIO | eff) Unit) +foreign import getFloatTimeDomainData :: AnalyserNode -> Float32Array -> Effect Unit -foreign import getByteTimeDomainData :: ∀ eff. AnalyserNode -> Uint8Array -> (Eff (audio :: AUDIO | eff) Unit) +foreign import getByteTimeDomainData :: AnalyserNode -> Uint8Array -> Effect Unit diff --git a/src/Audio/WebAudio/AudioBufferSourceNode.purs b/src/Audio/WebAudio/AudioBufferSourceNode.purs index 2d71d53..35ec5e3 100644 --- a/src/Audio/WebAudio/AudioBufferSourceNode.purs +++ b/src/Audio/WebAudio/AudioBufferSourceNode.purs @@ -3,39 +3,39 @@ module Audio.WebAudio.AudioBufferSourceNode , loop, setLoop, loopStart, setLoopStart, loopEnd, setLoopEnd ) where import Prelude -import Control.Monad.Eff (Eff) -import Audio.WebAudio.Types (AudioBuffer, AudioBufferSourceNode, AUDIO) +import Effect (Effect) +import Audio.WebAudio.Types (AudioBuffer, AudioBufferSourceNode) import Audio.WebAudio.Utils (unsafeGetProp, unsafeSetProp) foreign import setBuffer - :: ∀ eff. AudioBuffer + :: AudioBuffer -> AudioBufferSourceNode - -> (Eff (audio :: AUDIO | eff) Unit) + -> Effect Unit foreign import startBufferSource - :: ∀ eff. Number + :: Number -> AudioBufferSourceNode - -> (Eff (audio :: AUDIO | eff) Unit) + -> Effect Unit foreign import stopBufferSource - :: ∀ eff. Number + :: Number -> AudioBufferSourceNode - -> (Eff (audio :: AUDIO | eff) Unit) + -> Effect Unit -loop :: ∀ eff. AudioBufferSourceNode -> (Eff (audio :: AUDIO | eff) Boolean) +loop :: AudioBufferSourceNode -> Effect Boolean loop = unsafeGetProp "loop" -setLoop :: ∀ eff. Boolean -> AudioBufferSourceNode -> (Eff (audio :: AUDIO | eff) Unit) +setLoop :: Boolean -> AudioBufferSourceNode -> Effect Unit setLoop l n = unsafeSetProp "loop" n l -loopStart :: ∀ eff. AudioBufferSourceNode -> (Eff (audio :: AUDIO | eff) Number) +loopStart :: AudioBufferSourceNode -> Effect Number loopStart = unsafeGetProp "loopStart" -setLoopStart :: ∀ eff. Number -> AudioBufferSourceNode -> (Eff (audio :: AUDIO | eff) Unit) +setLoopStart :: Number -> AudioBufferSourceNode -> Effect Unit setLoopStart l n = unsafeSetProp "loopStart" n l -loopEnd :: ∀ eff. AudioBufferSourceNode -> (Eff (audio :: AUDIO | eff) Number) +loopEnd :: AudioBufferSourceNode -> Effect Number loopEnd = unsafeGetProp "loopEnd" -setLoopEnd :: ∀ eff. Number -> AudioBufferSourceNode -> (Eff (audio :: AUDIO | eff) Unit) +setLoopEnd :: Number -> AudioBufferSourceNode -> Effect Unit setLoopEnd l n = unsafeSetProp "loopEnd" n l diff --git a/src/Audio/WebAudio/AudioContext.purs b/src/Audio/WebAudio/AudioContext.purs index 254ea53..d719d91 100644 --- a/src/Audio/WebAudio/AudioContext.purs +++ b/src/Audio/WebAudio/AudioContext.purs @@ -2,13 +2,13 @@ module Audio.WebAudio.AudioContext ( createMediaElementSource ) where -import Audio.WebAudio.Types (AUDIO, AudioContext, MediaElementAudioSourceNode) -import Control.Monad.Eff (Eff) +import Audio.WebAudio.Types (AudioContext, MediaElementAudioSourceNode) +import Effect (Effect) -- | Creates a MediaElementAudioSourceNode given an HTMLMediaElement. As a consequence of -- | calling this method, audio playback from the HTMLMediaElement will be re-routed into -- | the processing graph of the AudioContext. foreign import createMediaElementSource - :: ∀ elt eff. AudioContext + :: ∀ elt. AudioContext -> elt -- |^ a DOM element from which to construct the source node. todo: HTML? - -> (Eff (audio :: AUDIO | eff) MediaElementAudioSourceNode) + -> Effect MediaElementAudioSourceNode diff --git a/src/Audio/WebAudio/AudioParam.purs b/src/Audio/WebAudio/AudioParam.purs index 3e01480..d1b2436 100644 --- a/src/Audio/WebAudio/AudioParam.purs +++ b/src/Audio/WebAudio/AudioParam.purs @@ -4,26 +4,23 @@ module Audio.WebAudio.AudioParam ) where import Prelude (Unit) -import Control.Monad.Eff (Eff) -import Audio.WebAudio.Types (AudioParam, AUDIO, Value, Seconds) +import Effect (Effect) +import Audio.WebAudio.Types (AudioParam, Value, Seconds) -foreign import setValue - :: ∀ eff. Value -> AudioParam -> (Eff (audio :: AUDIO | eff) Unit) +foreign import setValue :: Value -> AudioParam -> Effect Unit -foreign import setValueAtTime - :: ∀ eff. Value -> Seconds -> AudioParam -> (Eff (audio :: AUDIO | eff) Value) +foreign import setValueAtTime :: Value -> Seconds -> AudioParam -> Effect Value foreign import setTargetAtTime - :: ∀ eff. Value -> Seconds -> Seconds -> AudioParam -> (Eff (audio :: AUDIO | eff) Value) + :: Value -> Seconds -> Seconds -> AudioParam -> Effect Value -foreign import getValue - :: ∀ eff. AudioParam -> (Eff (audio :: AUDIO | eff) Value) +foreign import getValue :: AudioParam -> Effect Value foreign import linearRampToValueAtTime - :: ∀ eff. Value -> Seconds -> AudioParam -> (Eff (audio :: AUDIO | eff) Value) + :: Value -> Seconds -> AudioParam -> Effect Value foreign import exponentialRampToValueAtTime - :: ∀ eff. Value -> Seconds -> AudioParam -> (Eff (audio :: AUDIO | eff) Value) + :: Value -> Seconds -> AudioParam -> Effect Value foreign import cancelScheduledValues - :: ∀ eff. Value -> AudioParam -> (Eff (audio :: AUDIO | eff) Value) + :: Value -> AudioParam -> Effect Value diff --git a/src/Audio/WebAudio/BaseAudioContext.purs b/src/Audio/WebAudio/BaseAudioContext.purs index a74306b..3a982f7 100644 --- a/src/Audio/WebAudio/BaseAudioContext.purs +++ b/src/Audio/WebAudio/BaseAudioContext.purs @@ -9,46 +9,38 @@ module Audio.WebAudio.BaseAudioContext import Prelude import Audio.WebAudio.Types - ( AUDIO, AudioBuffer, AudioBufferSourceNode, AudioContext + ( AudioBuffer, AudioBufferSourceNode, AudioContext , DestinationNode, GainNode, OscillatorNode , DelayNode, BiquadFilterNode, AnalyserNode , StereoPannerNode, DynamicsCompressorNode, ConvolverNode , Seconds, Value, AudioContextState(..)) import Audio.WebAudio.Utils (unsafeGetProp) -import Control.Monad.Eff (Eff) -import Control.Monad.Eff.Console (CONSOLE) -import Control.Monad.Aff (Aff) -import Control.Monad.Aff.Compat (EffFnAff, fromEffFnAff) +import Effect (Effect) +import Effect.Aff (Aff) +import Effect.Aff.Compat (EffectFnAff, fromEffectFnAff) import Data.ArrayBuffer.Types (ArrayBuffer) -- | The audio graph whose AudioDestinationNode is routed to a real-time output device -- | that produces a signal directed at the user. -- | var context = new AudioContext() -foreign import newAudioContext - :: ∀ eff. (Eff (audio :: AUDIO | eff) AudioContext) +foreign import newAudioContext :: Effect AudioContext -- | An AudioDestinationNode with a single input representing the final destination for all audio. -destination - :: ∀ eff. AudioContext - -> (Eff (audio :: AUDIO | eff) DestinationNode) +destination :: AudioContext -> Effect DestinationNode destination = unsafeGetProp "destination" -- | The sample rate (in sample-frames per second) at which the BaseAudioContext handles audio. -foreign import sampleRate - :: ∀ eff. AudioContext - -> (Eff (audio :: AUDIO | eff) Value) +foreign import sampleRate :: AudioContext -> Effect Value -foreign import currentTime - :: ∀ eff. AudioContext - -> (Eff (audio :: AUDIO | eff) Seconds) +foreign import currentTime :: AudioContext -> Effect Seconds -- | An AudioListener which is used for 3D spatialization. -- | todo: listener :: .. -foreign import _state :: ∀ eff. AudioContext -> Eff (audio :: AUDIO | eff) String +foreign import _state :: AudioContext -> Effect String -- | Describes the current state of this BaseAudioContext. (reaonly) -state :: ∀ eff. AudioContext -> Eff (audio :: AUDIO | eff) AudioContextState +state :: AudioContext -> Effect AudioContextState state ctx = do s <- _state ctx pure $ @@ -58,9 +50,9 @@ state ctx = do "closed" -> CLOSED _ -> CLOSED -- ^avoid making a Partial instance -foreign import suspend :: ∀ eff. AudioContext -> Eff (audio :: AUDIO | eff) Unit +foreign import suspend :: AudioContext -> Effect Unit -foreign import resume :: ∀ eff. AudioContext -> Eff (audio :: AUDIO | eff) Unit +foreign import resume :: AudioContext -> Effect Unit -- | Closes the audio context, releasing any system audio resources used by the BaseAudioContext. -- | todo: close :: .. @@ -71,73 +63,70 @@ foreign import resume :: ∀ eff. AudioContext -> Eff (audio :: AUDIO | eff) Un -- | Asynchronously decodes the audio file data contained in the ArrayBuffer. foreign import decodeAudioData - :: ∀ eff f. - AudioContext + :: AudioContext -> ArrayBuffer - -> (AudioBuffer -> Eff (audio :: AUDIO | eff) Unit) -- sucesss - -> (String -> Eff (console :: CONSOLE | eff) Unit) -- failure - -> (Eff (audio :: AUDIO | f) Unit) + -> (AudioBuffer -> Effect Unit) -- sucesss + -> (String -> Effect Unit) -- failure + -> Effect Unit foreign import decodeAudioDataAsyncImpl - :: ∀ eff. - AudioContext + :: AudioContext -> ArrayBuffer - -> EffFnAff (audio :: AUDIO | eff) AudioBuffer + -> EffectFnAff AudioBuffer -- | decode the Audio Buffer asynchronously decodeAudioDataAsync - :: ∀ eff. - AudioContext + :: AudioContext -> ArrayBuffer - -> Aff (audio :: AUDIO | eff) AudioBuffer + -> Aff AudioBuffer decodeAudioDataAsync ctx = - fromEffFnAff <<< (decodeAudioDataAsyncImpl ctx) + fromEffectFnAff <<< (decodeAudioDataAsyncImpl ctx) -- | Creates an AudioBufferSourceNode. foreign import createBufferSource - :: ∀ eff. AudioContext - -> (Eff (audio :: AUDIO | eff) AudioBufferSourceNode) + :: AudioContext + -> Effect AudioBufferSourceNode -- | Create a GainNode. foreign import createGain - :: ∀ eff. AudioContext - -> (Eff (audio :: AUDIO | eff) GainNode) + :: AudioContext + -> Effect GainNode -- | Create an OscillatorNode foreign import createOscillator - :: ∀ eff. AudioContext - -> (Eff (audio :: AUDIO | eff) OscillatorNode) + :: AudioContext + -> Effect OscillatorNode -- | Create a DelayNode. -- | createDelay also has an alternative constructor with a maximum delay -- | note, if you don't set a max, it defaults to 1.0 and any attempt to set a greater value gives -- | "paramDelay.delayTime.value 2 outside nominal range [0, 1]; value will be clamped." foreign import createDelay - :: ∀ eff. AudioContext - -> (Eff (audio :: AUDIO | eff) DelayNode) + :: AudioContext + -> Effect DelayNode -- | Create a BiquadFilterNode. foreign import createBiquadFilter - :: ∀ eff. AudioContext - -> (Eff (audio :: AUDIO | eff) BiquadFilterNode) + :: AudioContext + -> Effect BiquadFilterNode -- | create an AnalyserNode. foreign import createAnalyser - :: ∀ eff. AudioContext - -> (Eff (audio :: AUDIO | eff) AnalyserNode) + :: AudioContext + -> Effect AnalyserNode -- | Create a StereoPannerNode, foreign import createStereoPanner - :: ∀ eff. AudioContext - -> (Eff (audio :: AUDIO | eff) StereoPannerNode) + :: AudioContext + -> Effect StereoPannerNode -- | Create a DynamicsCompressorNode. foreign import createDynamicsCompressor - :: ∀ eff. AudioContext - -> (Eff (audio :: AUDIO | eff) DynamicsCompressorNode) + :: AudioContext + -> Effect DynamicsCompressorNode -- | Create a ConvolverNode. foreign import createConvolver - :: ∀ eff. AudioContext - -> (Eff (audio :: AUDIO | eff) ConvolverNode) + :: AudioContext + -> Effect ConvolverNode diff --git a/src/Audio/WebAudio/BiquadFilterNode.purs b/src/Audio/WebAudio/BiquadFilterNode.purs index a924e72..4a683d6 100644 --- a/src/Audio/WebAudio/BiquadFilterNode.purs +++ b/src/Audio/WebAudio/BiquadFilterNode.purs @@ -6,7 +6,7 @@ import Audio.WebAudio.Types import Audio.WebAudio.Utils (unsafeGetProp, unsafeSetProp) import Prelude (class Show, class Eq, class Ord, Unit, show, (<$>)) -import Control.Monad.Eff (Eff) +import Effect (Effect) data BiquadFilterType = Lowpass @@ -42,17 +42,17 @@ readBiquadFilterType "notch" = Notch readBiquadFilterType "allpass" = Allpass readBiquadFilterType _ = Lowpass -filterType :: ∀ eff. BiquadFilterNode -> (Eff (audio :: AUDIO | eff) BiquadFilterType) +filterType :: BiquadFilterNode -> Effect BiquadFilterType filterType n = readBiquadFilterType <$> unsafeGetProp "type" n -setFilterType :: ∀ eff. BiquadFilterType -> BiquadFilterNode -> (Eff (audio :: AUDIO | eff) Unit) +setFilterType :: BiquadFilterType -> BiquadFilterNode -> Effect Unit setFilterType t n = unsafeSetProp "type" n (show t) -filterFrequency :: ∀ eff. BiquadFilterNode -> (Eff (audio :: AUDIO | eff) AudioParam) +filterFrequency :: BiquadFilterNode -> Effect AudioParam filterFrequency = unsafeGetProp "frequency" -quality :: ∀ eff. BiquadFilterNode -> (Eff (audio :: AUDIO | eff) AudioParam) +quality :: BiquadFilterNode -> Effect AudioParam quality = unsafeGetProp "Q" foreign import gain - :: forall eff. BiquadFilterNode -> (Eff (audio :: AUDIO | eff) AudioParam) + :: BiquadFilterNode -> Effect AudioParam diff --git a/src/Audio/WebAudio/ConvolverNode.purs b/src/Audio/WebAudio/ConvolverNode.purs index 65e2d39..1d8ca1d 100644 --- a/src/Audio/WebAudio/ConvolverNode.purs +++ b/src/Audio/WebAudio/ConvolverNode.purs @@ -1,17 +1,17 @@ module Audio.WebAudio.ConvolverNode (setBuffer, normalize, isNormalized) where import Prelude (Unit) -import Control.Monad.Eff (Eff) -import Audio.WebAudio.Types (AudioBuffer, ConvolverNode, AUDIO) +import Effect (Effect) +import Audio.WebAudio.Types (AudioBuffer, ConvolverNode) import Audio.WebAudio.Utils (unsafeGetProp, unsafeSetProp) foreign import setBuffer - :: ∀ eff. AudioBuffer + :: AudioBuffer -> ConvolverNode - -> (Eff (audio :: AUDIO | eff) Unit) + -> Effect Unit -normalize :: ∀ eff. Boolean -> ConvolverNode -> (Eff (audio :: AUDIO | eff) Unit) +normalize :: Boolean -> ConvolverNode -> Effect Unit normalize l n = unsafeSetProp "normalize" n l -isNormalized :: ∀ eff. ConvolverNode -> (Eff (audio :: AUDIO | eff) Boolean) +isNormalized :: ConvolverNode -> Effect Boolean isNormalized = unsafeGetProp "normalize" diff --git a/src/Audio/WebAudio/DelayNode.purs b/src/Audio/WebAudio/DelayNode.purs index eed71c3..3c0d844 100644 --- a/src/Audio/WebAudio/DelayNode.purs +++ b/src/Audio/WebAudio/DelayNode.purs @@ -1,8 +1,8 @@ module Audio.WebAudio.DelayNode (delayTime) where -import Control.Monad.Eff (Eff) -import Audio.WebAudio.Types (AudioParam, DelayNode, AUDIO) +import Effect (Effect) +import Audio.WebAudio.Types (AudioParam, DelayNode) import Audio.WebAudio.Utils (unsafeGetProp) -delayTime :: ∀ eff. DelayNode -> (Eff (audio :: AUDIO | eff) AudioParam) +delayTime :: DelayNode -> Effect AudioParam delayTime = unsafeGetProp "delayTime" diff --git a/src/Audio/WebAudio/DynamicsCompressorNode.purs b/src/Audio/WebAudio/DynamicsCompressorNode.purs index 3fee506..b2ec119 100644 --- a/src/Audio/WebAudio/DynamicsCompressorNode.purs +++ b/src/Audio/WebAudio/DynamicsCompressorNode.purs @@ -1,24 +1,24 @@ module Audio.WebAudio.DynamicsCompressorNode where -import Control.Monad.Eff (Eff) -import Audio.WebAudio.Types (AudioParam, DynamicsCompressorNode, AUDIO) +import Effect (Effect) +import Audio.WebAudio.Types (AudioParam, DynamicsCompressorNode) import Audio.WebAudio.Utils (unsafeGetProp) foreign import threshold - :: forall eff. DynamicsCompressorNode -> (Eff (audio :: AUDIO | eff) AudioParam) + :: DynamicsCompressorNode -> Effect AudioParam foreign import knee - :: forall eff. DynamicsCompressorNode -> (Eff (audio :: AUDIO | eff) AudioParam) + :: DynamicsCompressorNode -> Effect AudioParam foreign import ratio - :: forall eff. DynamicsCompressorNode -> (Eff (audio :: AUDIO | eff) AudioParam) + :: DynamicsCompressorNode -> Effect AudioParam -- | reduction is read-only -reduction :: ∀ eff. DynamicsCompressorNode -> (Eff (audio :: AUDIO | eff) Number) +reduction :: DynamicsCompressorNode -> Effect Number reduction n = unsafeGetProp "reduction" n foreign import attack - :: forall eff. DynamicsCompressorNode -> (Eff (audio :: AUDIO | eff) AudioParam) + :: DynamicsCompressorNode -> Effect AudioParam foreign import release - :: forall eff. DynamicsCompressorNode -> (Eff (audio :: AUDIO | eff) AudioParam) + :: DynamicsCompressorNode -> Effect AudioParam diff --git a/src/Audio/WebAudio/GainNode.purs b/src/Audio/WebAudio/GainNode.purs index 8692a5b..3795054 100644 --- a/src/Audio/WebAudio/GainNode.purs +++ b/src/Audio/WebAudio/GainNode.purs @@ -1,13 +1,13 @@ module Audio.WebAudio.GainNode (gain, setGain) where import Prelude (Unit, (=<<)) -import Control.Monad.Eff (Eff) -import Audio.WebAudio.Types (AudioParam, GainNode, AUDIO) +import Effect (Effect) +import Audio.WebAudio.Types (AudioParam, GainNode) import Audio.WebAudio.AudioParam (setValue) foreign import gain - :: forall eff. GainNode -> (Eff (audio :: AUDIO | eff) AudioParam) + :: GainNode -> Effect AudioParam -setGain :: ∀ eff. Number -> GainNode -> (Eff (audio :: AUDIO | eff) Unit) +setGain :: Number -> GainNode -> Effect Unit setGain num node = setValue num =<< gain node diff --git a/src/Audio/WebAudio/Oscillator.purs b/src/Audio/WebAudio/Oscillator.purs index f6271a5..dd6136e 100644 --- a/src/Audio/WebAudio/Oscillator.purs +++ b/src/Audio/WebAudio/Oscillator.purs @@ -4,8 +4,8 @@ module Audio.WebAudio.Oscillator , stopOscillator) where import Prelude -import Control.Monad.Eff (Eff) -import Audio.WebAudio.Types (AudioParam, OscillatorNode, AUDIO) +import Effect (Effect) +import Audio.WebAudio.Types (AudioParam, OscillatorNode) import Audio.WebAudio.Utils (unsafeGetProp, unsafeSetProp) import Audio.WebAudio.AudioParam (setValue) @@ -29,25 +29,25 @@ readOscillatorType _ = Sine derive instance eqOscillatorType :: Eq OscillatorType derive instance ordOscillatorType :: Ord OscillatorType -frequency :: ∀ eff. OscillatorNode -> (Eff (audio :: AUDIO| eff) AudioParam) +frequency :: OscillatorNode -> Effect AudioParam frequency = unsafeGetProp "frequency" -setFrequency :: ∀ eff. Number -> OscillatorNode -> (Eff (audio :: AUDIO| eff) Unit) +setFrequency :: Number -> OscillatorNode -> Effect Unit setFrequency num node = setValue num =<< frequency node -detune :: ∀ eff. OscillatorNode -> (Eff (audio :: AUDIO | eff) AudioParam) +detune :: OscillatorNode -> Effect AudioParam detune = unsafeGetProp "detune" -setDetune :: ∀ eff. Number -> OscillatorNode -> (Eff (audio :: AUDIO | eff) Unit) +setDetune :: Number -> OscillatorNode -> Effect Unit setDetune num node = setValue num =<< detune node -oscillatorType :: ∀ eff. OscillatorNode -> (Eff (audio :: AUDIO | eff) OscillatorType) +oscillatorType :: OscillatorNode -> Effect OscillatorType oscillatorType n = readOscillatorType <$> unsafeGetProp "type" n -setOscillatorType :: ∀ eff. OscillatorType -> OscillatorNode -> (Eff (audio :: AUDIO | eff) Unit) +setOscillatorType :: OscillatorType -> OscillatorNode -> Effect Unit setOscillatorType t n = unsafeSetProp "type" n $ show t -foreign import startOscillator :: ∀ eff. Number -> OscillatorNode -> (Eff (audio :: AUDIO | eff) Unit) -foreign import stopOscillator :: ∀ eff. Number -> OscillatorNode -> (Eff (audio :: AUDIO | eff) Unit) +foreign import startOscillator :: Number -> OscillatorNode -> Effect Unit +foreign import stopOscillator :: Number -> OscillatorNode -> Effect Unit diff --git a/src/Audio/WebAudio/StereoPannerNode.purs b/src/Audio/WebAudio/StereoPannerNode.purs index d4c075a..5b7c223 100644 --- a/src/Audio/WebAudio/StereoPannerNode.purs +++ b/src/Audio/WebAudio/StereoPannerNode.purs @@ -1,7 +1,7 @@ module Audio.WebAudio.StereoPannerNode where -import Control.Monad.Eff (Eff) -import Audio.WebAudio.Types (AudioParam, StereoPannerNode, AUDIO) +import Effect (Effect) +import Audio.WebAudio.Types (AudioParam, StereoPannerNode) foreign import pan - :: forall eff. StereoPannerNode -> (Eff (audio :: AUDIO | eff) AudioParam) + :: StereoPannerNode -> Effect AudioParam diff --git a/src/Audio/WebAudio/Types.purs b/src/Audio/WebAudio/Types.purs index 9fd077e..0ee3faa 100644 --- a/src/Audio/WebAudio/Types.purs +++ b/src/Audio/WebAudio/Types.purs @@ -4,14 +4,13 @@ module Audio.WebAudio.Types , AudioParam, DestinationNode, BiquadFilterNode , GainNode, MediaElementAudioSourceNode , DelayNode, OscillatorNode, AnalyserNode, StereoPannerNode - , DynamicsCompressorNode, ConvolverNode, AUDIO + , DynamicsCompressorNode, ConvolverNode , AudioContextState(..), AudioContextPlaybackCategory(..) , Value, Seconds , connect, disconnect, connectParam) where -import Control.Monad.Eff (kind Effect, Eff) +import Effect (Effect) import Prelude (class Show, class Eq, Unit, pure, unit) -foreign import data AUDIO :: Effect foreign import data AudioBuffer :: Type foreign import data AudioBufferSourceNode :: Type @@ -69,9 +68,9 @@ instance audioNodeDynamicsCConvolverNode :: RawAudioNode ConvolverNode -- | a web audio node that is connectable/disconnectable from another node -- | or whose parameter(s) may be connectable from another node class Connectable target where - connect :: ∀ eff source. RawAudioNode source => source -> target -> (Eff (audio :: AUDIO | eff) Unit) - disconnect :: ∀ eff source. RawAudioNode source => source -> target -> (Eff (audio :: AUDIO | eff) Unit) - connectParam :: ∀ eff source. RawAudioNode source => source -> target -> String -> (Eff (audio :: AUDIO| eff) Unit) + connect :: ∀ source. RawAudioNode source => source -> target -> Effect Unit + disconnect :: ∀ source. RawAudioNode source => source -> target -> Effect Unit + connectParam :: ∀ source. RawAudioNode source => source -> target -> String -> Effect Unit instance connectableGainNode :: Connectable GainNode where connect = nodeConnect @@ -154,15 +153,15 @@ instance connectableAudioNode :: Connectable AudioNode where connectParam s (Destination n) p = pure unit -- foreign import connect -foreign import nodeConnect :: ∀ m n eff. RawAudioNode m => RawAudioNode n => m +foreign import nodeConnect :: ∀ m n. RawAudioNode m => RawAudioNode n => m -> n - -> (Eff (audio :: AUDIO | eff) Unit) + -> Effect Unit -- There are multiple disconnect options - this one seems the most useful -- foreign import disconnectRawA -foreign import nodeDisconnect :: ∀ m n eff. RawAudioNode m => RawAudioNode n => m +foreign import nodeDisconnect :: ∀ m n. RawAudioNode m => RawAudioNode n => m -> n - -> (Eff (audio :: AUDIO | eff) Unit) + -> Effect Unit -- | Connect a source Node to a parameter on a destination Node. -- | the String parameter names an audio parameter on the target node, n @@ -174,10 +173,10 @@ foreign import nodeDisconnect :: ∀ m n eff. RawAudioNode m => RawAudioNode n -- | The Web-Audio JavaScript requires the original parameter, not a copy -- | -- | This is very unsafe. The parameter must exist on the target. -foreign import unsafeConnectParam :: ∀ m n eff. RawAudioNode m => RawAudioNode n => m +foreign import unsafeConnectParam :: ∀ m n. RawAudioNode m => RawAudioNode n => m -> n -> String - -> (Eff (audio :: AUDIO | eff) Unit) + -> Effect Unit data AudioNode = Gain GainNode diff --git a/src/Audio/WebAudio/Utils.purs b/src/Audio/WebAudio/Utils.purs index bdecddc..8478eae 100644 --- a/src/Audio/WebAudio/Utils.purs +++ b/src/Audio/WebAudio/Utils.purs @@ -2,23 +2,23 @@ module Audio.WebAudio.Utils ( createUint8Buffer, createFloat32Buffer, unsafeGetProp, unsafeSetProp) where import Prelude -import Control.Monad.Eff (Eff) +import Effect (Effect) import Data.ArrayBuffer.Types (ByteLength, Uint8Array, Float32Array) -import Data.ArrayBuffer.ArrayBuffer (ARRAY_BUFFER, create) as ArrayBuffer +import Data.ArrayBuffer.ArrayBuffer (create) as ArrayBuffer import Data.ArrayBuffer.DataView (whole) import Data.ArrayBuffer.Typed (asUint8Array, asFloat32Array) -foreign import unsafeSetProp :: forall obj val eff. String -> obj -> val -> (Eff eff Unit) -foreign import unsafeGetProp :: forall obj val eff. String -> obj -> (Eff eff val) +foreign import unsafeSetProp :: forall obj val. String -> obj -> val -> Effect Unit +foreign import unsafeGetProp :: forall obj val. String -> obj -> Effect val -- | create an unsigned 8-bit integer buffer for use with an analyser node -createUint8Buffer :: ∀ e. ByteLength -> Eff (arrayBuffer :: ArrayBuffer.ARRAY_BUFFER | e) Uint8Array +createUint8Buffer :: ByteLength -> Effect Uint8Array createUint8Buffer len = map (whole >>> asUint8Array) $ ArrayBuffer.create len -- | create a Float 32 buffer for use with an analyser node -createFloat32Buffer :: ∀ e. ByteLength -> Eff (arrayBuffer :: ArrayBuffer.ARRAY_BUFFER | e) Float32Array +createFloat32Buffer :: ByteLength -> Effect Float32Array createFloat32Buffer len = map (whole >>> asFloat32Array) $ ArrayBuffer.create len