Entschuldigung für das lange Codebeispiel, bitte beziehen Sie sich nur auf Zeile 30: A.openDeviceCallback =
. micSpec
ist eine Factory-Funktion für Objekte des Typs A.OpenDeviceSpec. Ich bin unzufrieden mit der Parameterliste dieser Funktion.Wie eine Aktion übergeben?
{-# OPTIONS_GHC -Wall #-}
-- Dependant on cabal packages: sdl2, wave.
module Main where
import qualified Control.Concurrent as C
--import qualified Control.Monad as M
import qualified Data.Vector.Storable.Mutable as V
import qualified Data.Set as S
import Foreign.ForeignPtr as P
import qualified SDL
import qualified SDL.Audio as A
import qualified Codec.Audio.Wave as W
import qualified System.IO as IO
import qualified Statistics.Sample as St
micSpec :: IO.Handle -> A.OpenDeviceSpec
micSpec h = A.OpenDeviceSpec {A.openDeviceFreq = A.Mandate 48000
,A.openDeviceFormat = A.Mandate A.Signed16BitNativeAudio
,A.openDeviceChannels = A.Mandate A.Mono
,A.openDeviceSamples = 4096
,A.openDeviceCallback = \_ (V.MVector size ptr) -> P.withForeignPtr ptr (\p -> IO.hPutBuf h p size)
,A.openDeviceUsage = A.ForCapture
,A.openDeviceName = Nothing}
waveSpec :: W.Wave
waveSpec = W.Wave {W.waveFileFormat = W.WaveVanilla
, W.waveSampleRate = 48000
, W.waveSampleFormat = W.SampleFormatPcmInt 16
, W.waveChannelMask = S.singleton W.SpeakerFrontCenter
, W.waveDataOffset = 0
, W.waveDataSize = 0
, W.waveSamplesTotal = 0
, W.waveOtherChunks = []}
record :: IO.Handle -> IO()
record h = do
SDL.initialize [SDL.InitAudio]
(dev, _) <- A.openAudioDevice $ micSpec h
A.setAudioDevicePlaybackState dev A.Play
-- _ <- M.forever (C.threadDelay maxBound)
_ <- C.threadDelay 10000000
return()
main :: IO()
main = W.writeWaveFile "mic.rec" waveSpec record
Im Rahmen eines solchen einfachen Programm, das benötigt A.OpenDeviceSpec
Objekt ist eine Reihe von Konstanten, plus eine Aktion. Momentan wird die Aktion inline erstellt ... weil ich es nur so geschafft habe, ohne Typinformationen herumzugeben.
Meine Intuition von C ist in den Linien der
type Cb = A.AudioFormat t -> A.IOVector t -> IO()
micSpec :: Cb -> A.OpenDeviceSpec
, aber ich konnte es nicht machen.
Dieser Link ist kaputt. – leftaroundabout
Ich glaube nicht, dass ich die Frage vollständig verstehe. –
@ ThomasM.DuBuisson Wie kann ich eine Funktion definieren Int -> IO() -> Int? Ist das möglich oder sinnvoll? – Vorac