sdr 0.1.0.6 → 0.1.0.8
raw patch · 7 files changed
+95/−64 lines, 7 filesdep ~Chartdep ~Chart-cairodep ~GLFW-bPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependency ranges changed: Chart, Chart-cairo, GLFW-b, OpenGL, QuickCheck, base, dynamic-graph, either, pipes, sdr, time
API changes (from Hackage documentation)
+ SDR.FFT: fftw' :: (Vector v (Complex CDouble)) => Int -> IO (v (Complex CDouble) -> IO (Vector (Complex CDouble)))
+ SDR.FFT: fftwReal' :: (Vector v CDouble) => Int -> IO (v CDouble -> IO (Vector (Complex CDouble)))
+ SDR.Util: combineInit :: (Monad m, MonadTrans t, Monad (t m)) => m (t m a) -> t m a
+ SDR.Util: combineInitTrans :: (Monad (t1 m), Monad (t (t1 m)), MonadTrans t, Monad m, MFunctor t, MonadTrans t1) => (t1 m) ((t m) a) -> t (t1 m) a
- SDR.Serialize: fromByteString :: Storable a => ByteString -> Vector a
+ SDR.Serialize: fromByteString :: forall a. Storable a => ByteString -> Vector a
- SDR.Serialize: fromHandle :: (Storable a) => Int -> Handle -> Producer (Vector a) IO ()
+ SDR.Serialize: fromHandle :: forall a. (Storable a) => Int -> Handle -> Producer (Vector a) IO ()
- SDR.Serialize: toByteString :: Storable a => Vector a -> ByteString
+ SDR.Serialize: toByteString :: forall a. Storable a => Vector a -> ByteString
- SDR.Util: streamRandom :: PrimMonad m => Int -> Producer (Vector Float) m ()
+ SDR.Util: streamRandom :: forall m. PrimMonad m => Int -> Producer (Vector Float) m ()
- SDR.Util: streamString :: (FiniteBits b, Monad m) => [b] -> Int -> Producer (Vector Float) m ()
+ SDR.Util: streamString :: forall m b. (FiniteBits b, Monad m) => [b] -> Int -> Producer (Vector Float) m ()
Files
- benchmarks/Benchmarks.hs +2/−2
- hs_sources/SDR/FFT.hs +38/−20
- hs_sources/SDR/Filter.hs +11/−11
- hs_sources/SDR/FilterDesign.hs +1/−0
- hs_sources/SDR/Util.hs +13/−1
- sdr.cabal +16/−16
- tests/TestSuite.hs +14/−14
benchmarks/Benchmarks.hs view
@@ -1,6 +1,6 @@ {-# LANGUAGE ScopedTypeVariables #-} -import Control.Monad.Primitive +import Control.Monad.Primitive import Control.Monad import Foreign.C.Types import Foreign.Ptr@@ -53,7 +53,7 @@ inBufConv = VG.fromList $ take size $ concat $ repeat [0 .. 255] duplicate :: [a] -> [a]- duplicate = concat . map func + duplicate = concatMap func where func x = [x, x] coeffs2 :: VS.Vector Float
hs_sources/SDR/FFT.hs view
@@ -8,7 +8,9 @@ blackman, -- * FFTs+ fftw', fftw,+ fftwReal', fftwReal, fftwParallel ) where@@ -37,11 +39,11 @@ ptr <- fftwMalloc $ fromIntegral $ elems * sizeOf (undefined :: a) newForeignPtr fftwFreePtr ptr --- | Creates a Pipe that performs a complex to complex DFT.-fftw :: (VG.Vector v (Complex CDouble)) +-- | Creates a function that performs a complex to complex DFT.+fftw' :: (VG.Vector v (Complex CDouble)) => Int -- ^ The size of the input and output buffers- -> IO (Pipe (v (Complex CDouble)) (VS.Vector (Complex CDouble)) IO ())-fftw samples = do+ -> IO (v (Complex CDouble) -> IO (VS.Vector (Complex CDouble)))+fftw' samples = do ina <- mallocForeignBufferAligned samples out <- mallocForeignBufferAligned samples @@ -49,26 +51,34 @@ withForeignPtr out $ \op -> planDFT1d samples ip op Forward fftwEstimate - return $ for cat $ \inv' -> do- out <- lift $ mallocForeignBufferAligned samples- ina <- lift $ mallocForeignBufferAligned samples+ return $ \inv' -> do+ out <- mallocForeignBufferAligned samples+ ina <- mallocForeignBufferAligned samples let inv = VSM.unsafeFromForeignPtr0 ina samples - lift $ copyInto inv inv'+ copyInto inv inv' let (fp, offset, length) = VSM.unsafeToForeignPtr inv - lift $ withForeignPtr fp $ \fpp -> + withForeignPtr fp $ \fpp -> withForeignPtr out $ \op -> executeDFT plan fpp op - yield $ VS.unsafeFromForeignPtr0 out samples+ return $ VS.unsafeFromForeignPtr0 out samples --- | Creates a pipe that performs a real to complex DFT.-fftwReal :: (VG.Vector v CDouble) +-- | Creates a Pipe that performs a complex to complex DFT.+fftw :: (VG.Vector v (Complex CDouble)) + => Int -- ^ The size of the input and output buffers+ -> IO (Pipe (v (Complex CDouble)) (VS.Vector (Complex CDouble)) IO ())+fftw samples = do+ func <- fftw' samples+ return $ for cat $ \dat -> lift (func dat) >>= yield++-- | Creates a function that performs a real to complex DFT.+fftwReal' :: (VG.Vector v CDouble) => Int -- ^ The size of the input Vector- -> IO (Pipe (v CDouble) (VS.Vector (Complex CDouble)) IO ())-fftwReal samples = do+ -> IO (v CDouble -> IO (VS.Vector (Complex CDouble)))+fftwReal' samples = do --Allocate in and out buffers that wont be used because there doesnt seem to be a way to create a plan without them ina <- mallocForeignBufferAligned samples out <- mallocForeignBufferAligned samples@@ -77,19 +87,27 @@ withForeignPtr out $ \op -> planDFTR2C1d samples ip op fftwEstimate - return $ for cat $ \inv' -> do- out <- lift $ mallocForeignBufferAligned ((samples `quot` 2) + 1)- ina <- lift $ mallocForeignBufferAligned samples+ return $ \inv' -> do+ out <- mallocForeignBufferAligned ((samples `quot` 2) + 1)+ ina <- mallocForeignBufferAligned samples let inv = VSM.unsafeFromForeignPtr0 ina samples - lift $ copyInto inv inv'+ copyInto inv inv' let (fp, offset, length) = VSM.unsafeToForeignPtr inv - lift $ withForeignPtr fp $ \fpp -> + withForeignPtr fp $ \fpp -> withForeignPtr out $ \op -> executeDFTR2C plan fpp op - yield $ VS.unsafeFromForeignPtr0 out samples+ return $ VS.unsafeFromForeignPtr0 out samples++-- | Creates a pipe that performs a real to complex DFT.+fftwReal :: (VG.Vector v CDouble) + => Int -- ^ The size of the input Vector+ -> IO (Pipe (v CDouble) (VS.Vector (Complex CDouble)) IO ())+fftwReal samples = do+ func <- fftwReal' samples+ return $ for cat $ \dat -> lift (func dat) >>= yield {-| Creates a pipe that uses multiple threads to perform complex to complex DFTs in a pipelined fashion. Each time a buffer is consumed, it is given to
hs_sources/SDR/Filter.hs view
@@ -144,7 +144,7 @@ } duplicate :: [a] -> [a]-duplicate = concat . map func +duplicate = concatMap func where func x = [x, x] {-# INLINE haskellFilter #-}@@ -158,7 +158,7 @@ let filterOne = filterHighLevel vCoeffs filterCross = filterCrossHighLevel vCoeffs numCoeffsF = length coeffs- return $ Filter {..}+ return Filter {..} mkFilter :: Int -> FilterRR@@ -172,7 +172,7 @@ evaluate vCoeffs let filterOne = filterFunc vCoeffs filterCross = filterCrossHighLevel vCoeffs- return $ Filter {..}+ return Filter {..} -- | Returns a fast Filter data structure implemented in C. For filtering real data with real coefficients. fastFilterCR :: [Float] -- ^ The filter coefficients@@ -208,7 +208,7 @@ evaluate vCoeffs let filterOne = filterFunc vCoeffs filterCross = filterCrossHighLevel vCoeffs2- return $ Filter {..}+ return Filter {..} -- | Returns a fast Filter data structure implemented in C For filtering complex data with real coefficients. fastFilterCC :: [Float] -- ^ The filter coefficients@@ -242,7 +242,7 @@ let filterOne = filterFunc vCoeffs filterCross = filterCrossHighLevel vCoeffs2 numCoeffsF = length coeffs * 2- return $ Filter {..}+ return Filter {..} -- | Returns a fast Filter data structure implemented in C using SSE instructions. For filtering real data with real coefficients. For filters with symmetric coefficients, i.e. 'linear phase'. Coefficient length must be a multiple of 4. fastFilterSymSSER :: [Float] -- ^ The first half of the filter coefficients@@ -287,7 +287,7 @@ evaluate vCoeffs let decimateOne = filterFunc decimationD vCoeffs decimateCross = decimateCrossHighLevel decimationD vCoeffs- return $ Decimator {..}+ return Decimator {..} -- | Returns a fast Decimator data structure implemented in C. For decimating real data with real coefficients. fastDecimatorCR :: Int -- ^ The decimation factor@@ -328,7 +328,7 @@ evaluate vCoeffs let decimateOne = filterFunc decimationD vCoeffs decimateCross = decimateCrossHighLevel decimationD vCoeffs2- return $ Decimator {..}+ return Decimator {..} -- | Returns a fast Decimator data structure implemented in C. For decimating complex data with real coefficients. fastDecimatorCC :: Int -- ^ The decimation factor@@ -367,8 +367,8 @@ let decimateOne = filterFunc decimationD vCoeffs decimateCross = decimateCrossHighLevel decimationD vCoeffs2 numCoeffsD = length coeffs * 2- return $ Decimator {..} + return Decimator {..} -- | Returns a fast Decimator data structure implemented in C using SSE instructions. For decimating real data with real coefficients. For decimators with symmetric coefficients, i.e. 'linear phase'. Coefficient length must be a multiple of 4. fastDecimatorSymSSER :: Int -- ^ The decimation factor -> [Float] -- ^ The first half of the filter coefficients@@ -403,7 +403,7 @@ numCoeffsR = length coeffs func x = (x, x) startDat = 0- return $ Resampler {..}+ return Resampler {..} mkResampler :: Int -> ResampleRR@@ -422,7 +422,7 @@ numCoeffsR = roundUp (length coeffs) (interpolationR * sizeMultiple) func1 group = let offset = interpolationR - 1 - ((interpolationR + group * decimationR - 1) `mod` interpolationR) in ((group, offset), offset) startDat = (0, 0)- return $ Resampler {..}+ return Resampler {..} mkResamplerC :: Int -> ResampleRC@@ -441,7 +441,7 @@ numCoeffsR = roundUp (length coeffs) (interpolationR * sizeMultiple) func1 group = let offset = interpolationR - 1 - ((interpolationR + group * decimationR - 1) `mod` interpolationR) in ((group, offset), offset) startDat = (0, 0)- return $ Resampler {..}+ return Resampler {..} -- | Returns a fast Resampler data structure implemented in C. For filtering real data with real coefficients. fastResamplerCR :: Int -- ^ The interpolation factor
hs_sources/SDR/FilterDesign.hs view
@@ -59,6 +59,7 @@ where func idx = 0.42 - 0.5 * cos((2 * pi * fromIntegral idx) / (fromIntegral size - 1)) + 0.08 * cos((4 * pi * fromIntegral idx) / (fromIntegral size - 1)) +-- | Compute a windowed sinc function windowedSinc :: (Floating n, VG.Vector v n) => Int -- ^ The length -> n -- ^ The cutoff frequency (from 0 to 1)
hs_sources/SDR/Util.hs view
@@ -45,7 +45,11 @@ -- * Automatic gain control agc,- agcPipe+ agcPipe,++ -- * Squashing initialization into the Pipe+ combineInit,+ combineInitTrans ) where import Foreign.C.Types@@ -342,4 +346,12 @@ -> a -- ^ reference -> Pipe (VS.Vector (Complex a)) (VS.Vector (Complex a)) m () agcPipe mu reference = pMapAccum (agc mu reference) 1++-- | Specializes to combineInit :: IO (Pipe a b IO ()) -> Pipe a b IO ()+combineInit :: (Monad m, MonadTrans t, Monad (t m)) => m (t m a) -> t m a+combineInit = join . lift++-- | Specializes to combineInitTrans :: EitherT String IO (Pipe a b IO ()) -> Pipe a b (EitherT String IO) ()+combineInitTrans :: (Monad (t1 m), Monad (t (t1 m)), MonadTrans t, Monad m, MFunctor t, MonadTrans t1) => (t1 m) ((t m) a) -> t (t1 m) a+combineInitTrans = combineInit . fmap (hoist lift)
sdr.cabal view
@@ -1,5 +1,5 @@ name: sdr-version: 0.1.0.6+version: 0.1.0.8 synopsis: A software defined radio library description: Write software defined radio applications in Haskell.@@ -67,23 +67,23 @@ -- other-modules: other-extensions: ScopedTypeVariables, GADTs build-depends: - base >=4.7 && <4.9, + base >=4.7 && <5, fftwRaw >=0.1 && <0.2, bytestring >=0.10 && <0.11, pulse-simple >=0.1 && <0.2, - pipes >=4.1 && <4.2, + pipes >=4.1 && <4.3, pipes-concurrency >=2.0 && <2.1, - either >=4.1 && <4.4, - time >=1.4 && <1.6, + either >=4.1 && <4.5, + time >=1.4 && <1.7, rtlsdr >=0.1 && <0.2, storable-complex >=0.2 && <0.3, pipes-bytestring >=2.0 && <2.2, - dynamic-graph ==0.1.0.8,+ dynamic-graph ==0.1.0.9, array >=0.4 && <0.6, vector >=0.11 && <0.12, tuple >=0.2 && <0.4, - OpenGL >=2.11 && <2.13, - GLFW-b >=1.4.7 && <1.4.8,+ OpenGL >=2.11 && <3.1,+ GLFW-b >=1.4.8 && <1.4.9, primitive >=0.5 && <0.7, colour >=2.3 && <2.4, pango >=0.13 && <0.14, @@ -91,9 +91,9 @@ cairo >=0.13 && <0.14, cereal >=0.4 && <0.6, optparse-applicative >=0.11 && <0.13, - Decimal >=0.4 && <0.5, - Chart >=1.3 && <1.6, - Chart-cairo >=1.3 && <1.6,+ Decimal >=0.4 && <0.5,+ Chart >=1.3 && <1.9, + Chart-cairo >=1.3 && <1.9, mwc-random -- hs-source-dirs: default-language: Haskell2010@@ -114,10 +114,10 @@ type: exitcode-stdio-1.0 main-is: TestSuite.hs build-depends: - base >=4.6 && <4.9, - QuickCheck >=2.8 && <2.9, + base >=4.6 && <5, + QuickCheck >=2.8 && <2.10, vector >=0.11 && <0.12, - sdr ==0.1.0.6, + sdr ==0.1.0.8, primitive >=0.5 && <0.7, storable-complex >=0.2 && <0.3, test-framework >=0.8 && <0.9,@@ -130,10 +130,10 @@ type: exitcode-stdio-1.0 main-is: Benchmarks.hs build-depends: - base >=4.6 && <4.9, + base >=4.6 && <5, criterion >=1.0 && <1.2, vector >=0.11 && <0.12, - sdr ==0.1.0.6, + sdr ==0.1.0.8, primitive >=0.5 && <0.7, storable-complex >=0.2 && <0.3 hs-source-dirs: benchmarks
tests/TestSuite.hs view
@@ -23,11 +23,11 @@ sameResultM eq (x:xs) = do res <- x ress <- sequence xs- return $ and $ map (eq res) ress+ return $ all (eq res) ress sameResult :: (a -> a -> Bool) -> [a] -> Bool sameResult _ [] = True-sameResult eq (x:xs) = and $ map (eq x) xs+sameResult eq (x:xs) = all (eq x) xs tests info = [ testGroup "filters" [@@ -71,7 +71,7 @@ vInput = VS.fromList inBuf num = size - numCoeffs*2 + 1 - res <- run $ sameResultM eqDelta $ map (getResult num $) $ hasFeatures [+ res <- run $ sameResultM eqDelta $ map (getResult num) $ hasFeatures [ (const True, filterHighLevel vCoeffs num vInput), (const True, filterImperative1 vCoeffs num vInput), (const True, filterImperative2 vCoeffs num vInput),@@ -99,7 +99,7 @@ num = size - numCoeffs*2 + 1 vCoeffs2 = VG.fromList $ duplicate $ coeffs ++ reverse coeffs - res <- run $ sameResultM eqDeltaC $ map (getResult num $) $ hasFeatures [+ res <- run $ sameResultM eqDeltaC $ map (getResult num) $ hasFeatures [ (const True, filterHighLevel vCoeffs num vInput), (const True, filterCRC vCoeffs num vInput), (hasSSE42, filterCSSERC vCoeffs2 num vInput),@@ -125,7 +125,7 @@ vInput = VS.fromList inBuf num = (size - numCoeffs*2 + 1) `quot` factor - res <- run $ sameResultM eqDelta $ map (getResult num $) $ hasFeatures [+ res <- run $ sameResultM eqDelta $ map (getResult num) $ hasFeatures [ (const True, decimateHighLevel factor vCoeffs num vInput), (const True, decimateCRR factor vCoeffs num vInput), (hasSSE42, decimateCSSERR factor vCoeffs num vInput),@@ -152,7 +152,7 @@ num = (size - numCoeffs*2 + 1) `quot` factor vCoeffs2 = VG.fromList $ duplicate $ coeffs ++ reverse coeffs - res <- run $ sameResultM eqDeltaC $ map (getResult num $) $ hasFeatures [+ res <- run $ sameResultM eqDeltaC $ map (getResult num) $ hasFeatures [ (const True, decimateHighLevel factor vCoeffs num vInput), (const True, decimateCRC factor vCoeffs num vInput), (hasSSE42, decimateCSSERC factor vCoeffs2 num vInput),@@ -186,7 +186,7 @@ resampler4 <- run $ resampleCSSERR interpolation decimation (coeffs ++ reverse coeffs) resampler5 <- run $ resampleCAVXRR interpolation decimation (coeffs ++ reverse coeffs) - res <- run $ sameResultM eqDelta $ map (getResult num $) $ hasFeatures [+ res <- run $ sameResultM eqDelta $ map (getResult num) $ hasFeatures [ (const True, void . resampleHighLevel interpolation decimation vCoeffs offset num vInput), (const True, void . resampleCRR num interpolation decimation offset vCoeffs vInput), (const True, void . resampler3 group num vInput),@@ -218,7 +218,7 @@ resampler4 <- run $ resampleCSSERC interpolation decimation (coeffs ++ reverse coeffs) resampler5 <- run $ resampleCAVXRC interpolation decimation (coeffs ++ reverse coeffs) - res <- run $ sameResultM eqDeltaC $ map (getResult num $) $ hasFeatures [+ res <- run $ sameResultM eqDeltaC $ map (getResult num) $ hasFeatures [ (const True, void . resampleHighLevel interpolation decimation vCoeffs offset num vInput), (const True, void . resampler3 group num vInput), (hasSSE42, void . resampler4 group num vInput),@@ -234,7 +234,7 @@ testConversionRTLSDR size inBuf = monadicIO $ do let vInput = VS.fromList $ map fromIntegral inBuf - let res = sameResult eqDeltaC $ map (VG.toList $) $ hasFeatures [+ let res = sameResult eqDeltaC $ map VG.toList $ hasFeatures [ (const True, (interleavedIQUnsigned256ToFloat vInput :: VS.Vector (Complex Float))), (const True, interleavedIQUnsignedByteToFloat vInput), (hasSSE42, interleavedIQUnsignedByteToFloatSSE vInput),@@ -250,7 +250,7 @@ testConversionBladeRF size inBuf = monadicIO $ do let vInput = VS.fromList $ map fromIntegral inBuf - let res = sameResult eqDeltaC $ map (VG.toList $) $ hasFeatures [+ let res = sameResult eqDeltaC $ map VG.toList $ hasFeatures [ (const True, (interleavedIQSigned2048ToFloat vInput :: VS.Vector (Complex Float))), (const True, interleavedIQSignedWordToFloat vInput), (hasSSE42, interleavedIQSignedWordToFloatSSE vInput),@@ -268,7 +268,7 @@ testScaleReal size inBuf factor = monadicIO $ do let vInput = VS.fromList inBuf - res <- run $ sameResultM eqDelta $ map (getResult size $) $ hasFeatures [+ res <- run $ sameResultM eqDelta $ map (getResult size) $ hasFeatures [ (const True, scaleC factor vInput), (hasSSE42, scaleCSSE factor vInput), (hasAVX, scaleCAVX factor vInput)@@ -281,14 +281,14 @@ func outBuf out :: VS.Vector a <- VG.freeze outBuf return $ VG.toList out- eqDelta x y = and $ map (uncurry eqDelta') $ zip x y+ eqDelta x y = all (uncurry eqDelta') $ zip x y where eqDelta' x y = abs (x - y) < 0.01- eqDeltaC x y = and $ map (uncurry eqDelta') $ zip x y+ eqDeltaC x y = all (uncurry eqDelta') $ zip x y where eqDelta' x y = magnitude (x - y) < 0.01 duplicate :: [a] -> [a]- duplicate = concat . map func + duplicate = concatMap func where func x = [x, x] main = do