Created
January 18, 2015 22:36
-
-
Save matthewpalmer/3bd07172c07eb8fcdae5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Data.Complex | |
import Data.List | |
import Foreign.Marshal.Array | |
import RTLSDR | |
import FFT | |
import Plot | |
import Spectrum | |
bufSize = 512 | |
sampleRate = 1280000 | |
frequency = 433420000 -- ~100 MHz | |
calibrationError = 0 | |
main = do | |
getSignal frequency | |
getSignal frequency = do | |
dev <- open 0 | |
case dev of | |
Nothing -> putStrLn "Error opening device" | |
Just dev -> do | |
setSampleRate dev sampleRate | |
setCenterFreq dev frequency | |
setTunerGainMode dev False | |
resetBuffer dev | |
allocaArray bufSize $ \ptr -> do | |
res <- readSync dev ptr bufSize | |
case res of | |
False -> putStrLn "Error reading from device" | |
True -> do | |
res <- peekArray bufSize ptr | |
let complexes = map fromIntegral res | |
coeffs = fft complexes | |
-- First entry in the FFT coefficients is always garbage for some reason | |
spectrum = Spectrum.computeSpectrum (tail coeffs) (fromIntegral sampleRate) | |
absoluteSpectrum = absolutivize (fromIntegral frequency + calibrationError) spectrum | |
f = length coeffs | |
ms = map Data.Complex.magnitude coeffs | |
cfreq <- getFreqCorrection dev | |
--case cfreq of | |
--Just cfreq -> do | |
print $ "center: " ++ (show cfreq) | |
--print res | |
--print spectrum | |
--Plot.plot (spectrum) ("Centre: " ++ (show frequency) ++ "Hz") (show frequency ++ "-r.png") | |
Plot.plot (absoluteSpectrum) ("Centre: " ++ (show frequency) ++ "Hz") (show frequency ++ "-a.png") | |
putStr $ (show frequency) ++ "\t" | |
print $ sum ms | |
--print spectrum | |
close dev | |
getSignal (frequency {-+ 100000-}) | |
-- Convert the computed spectrum to one with an x axis relative to our input frequency | |
--relativize :: Double -> [(Double, Double)] -> [(Double, Double)] | |
--relativize center readings = | |
-- numReadings = fromIntegral(length readings) | |
-- intervalSize = (fst $ head $ tail readings) - (fst $ head readings) | |
-- middleFreq = readings !! (numReadings / 2) | |
absolutivize :: Double -> [(Double, Double)] -> [(Double, Double)] | |
absolutivize center readings = zip absoluteFrequencies magnitudes | |
where absoluteFrequencies = map (+ center) offsets | |
magnitudes = map snd readings | |
frequencies = map fst readings | |
middleFrequency = frequencies !! (fromIntegral(length frequencies) `div` 2) | |
offsets = map (\x -> (-) x middleFrequency) frequencies | |
{- | |
If we have a collection of pairs like | |
[(0.0,429.7772578325535),(2500.0,885.4309962413882),(5000.0,287.8264854491852)] | |
and suppose our center frequency is 108MHz. | |
First, split the frequencies from the magnitudes. | |
frequencies = map fst pairs | |
magnitudes = map snd pairs | |
We get our intervalSize by the difference between the 1st and 2nd frequencies. | |
intervalSize = (head $ tail frequencies) - (head frequencies) | |
The middle element in frequencies maps to our absolute center (108MHz). | |
middleValue = pairs !! (length pairs / 2) | |
Then convert each pair into a + or - relative value from the middleValue, e.g. | |
[0.0, 2500.0, 5000.0] => offsets = [-2500.0, 0.0, +2500.0] | |
Finally, add these +/- values to the center frequency | |
map (+centerFrequency) offsets | |
-} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment