Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: RTL-SDR Support #108

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
language: cpp

dist: trusty
dist: bionic
sudo: false

compiler:
Expand All @@ -14,6 +14,7 @@ addons:
- libmbe-dev
- libsndfile1-dev
- libitpp-dev
- librtlsdr-dev
- portaudio19-dev

before_script:
Expand Down
12 changes: 12 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ find_package(LibSndFile REQUIRED)
find_package(MBE REQUIRED)
find_package(ITPP REQUIRED)
find_package(LibPortAudio)
find_package(RTLSDR)

include_directories(SYSTEM ${LIBSNDFILE_INCLUDE_DIR} ${MBE_INCLUDE_DIR} ${ITPP_INCLUDE_DIR})
set(LIBS ${MBE_LIBRARY} ${LIBSNDFILE_LIBRARY} ${ITPP_LIBRARY})
Expand All @@ -20,9 +21,20 @@ if(PORTAUDIO_FOUND)
add_definitions(-DUSE_PORTAUDIO)
endif(PORTAUDIO_FOUND)

if(RTLSDR_FOUND)
find_package(Threads)
include_directories(SYSTEM ${RTLSDR_INCLUDE_DIRS})
list(APPEND LIBS ${RTLSDR_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
add_definitions(-DUSE_RTLSDR)
endif(RTLSDR_FOUND)

FILE(GLOB SRCS src/*.c src/*.cpp)
FILE(GLOB HEADERS include/*.h include/*.hpp)

if(NOT RTLSDR_FOUND)
list(REMOVE_ITEM SRCS ${CMAKE_CURRENT_SOURCE_DIR}/src/rtl_sdr_fm.cpp)
endif(NOT RTLSDR_FOUND)

configure_file("src/git_ver.c.in" "${CMAKE_CURRENT_BINARY_DIR}/git_ver.c" @ONLY)
list(APPEND SRCS "${CMAKE_CURRENT_BINARY_DIR}/git_ver.c")

Expand Down
4 changes: 2 additions & 2 deletions cmake/FindLibSndFile.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ SET(LIBSNDFILE_NAMES ${LIBSNDFILE_NAMES} sndfile libsndfile)
FIND_LIBRARY(LIBSNDFILE_LIBRARY NAMES ${LIBSNDFILE_NAMES})

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(LIBSNDFILE DEFAULT_MSG LIBSNDFILE_LIBRARY
LIBSNDFILE_INCLUDE_DIR)
find_package_handle_standard_args(LibSndFile DEFAULT_MSG LIBSNDFILE_LIBRARY
LIBSNDFILE_INCLUDE_DIR)
29 changes: 29 additions & 0 deletions cmake/FindRTLSDR.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# - Try to find rtlsdr - the hardware driver for the realtek chip in the dvb receivers
# Once done this will define
# RTLSDR_FOUND - System has rtlsdr
# RTLSDR_LIBRARIES - The rtlsdr libraries
# RTLSDR_INCLUDE_DIRS - The rtlsdr include directories
# RTLSDR_LIB_DIRS - The rtlsdr library directories

if (NOT RTLSDR_FOUND)

find_package(PkgConfig)
pkg_check_modules(RTLSDR_PKG librtlsdr)
set(RTLSDR_DEFINITIONS ${PC_RTLSDR_CFLAGS_OTHER})

find_path(RTLSDR_INCLUDE_DIR
NAMES rtl-sdr.h
HINTS ${RTLSDR_PKG_INCLUDE_DIRS})

find_library(RTLSDR_LIBRARY
NAMES rtlsdr
HINTS ${RTLSDR_PKG_LIBRARY_DIRS})

set(RTLSDR_LIBRARIES ${RTLSDR_LIBRARY})
set(RTLSDR_INCLUDE_DIRS ${RTLSDR_INCLUDE_DIR})

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(RTLSDR DEFAULT_MSG RTLSDR_LIBRARY RTLSDR_INCLUDE_DIR)
mark_as_advanced(RTLSDR_INCLUDE_DIR RTLSDR_LIBRARY)

endif (NOT RTLSDR_FOUND)
6 changes: 3 additions & 3 deletions debian/control
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ Source: dsd
Section: hamradio
Priority: optional
Maintainer: Jared Szechy <jared.szechy@gmail.com>
Build-Depends: debhelper (>= 9), libmbe-dev, libitpp-dev, libsndfile1-dev,
portaudio19-dev, cmake, git, help2man
Build-Depends: debhelper (>= 9), libmbe-dev, libitpp-dev, librtlsdr-dev
libsndfile1-dev, portaudio19-dev, cmake, git, help2man
Standards-Version: 4.1.4
Homepage: https://github.com/szechyjs/dsd
Vcs-Git: https://github.com/szechyjs/dsd.git
Expand All @@ -17,4 +17,4 @@ Pre-Depends: ${misc:Pre-Depends}
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: Digital Speech Decoder
DSD is able to decode several digital voice formats from discriminator tap
audio and synthesize the decoded speech.
audio and synthesize the decoded speech.
10 changes: 9 additions & 1 deletion debian/copyright
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@ Files: src/dstar_header.c include/dstar_header.h include/fcs.h
Copyright: Copyright (C) 2010 by Kristoff Bonne, ON1ARF
License: GPL-2

Files: src/rtl_sdr_fm.cpp
Copyright: Copyright (C) 2012 by Steve Markgraf <steve@steve-m.de>
Copyright (C) 2012 by Hoernchen <la@tfc-server.de>
Copyright (C) 2012 by Kyle Keen <keenerd@gmail.com>
Copyright (C) 2013 by Elias Oenal <EliasOenal@gmail.com>
Copyright (C) 2014 by Kyle Keen <keenerd@gmail.com>
License: GPL-2

Files: include/descramble.h
Copyright: Copyright (C) 2011 by Jonathan Naylor, G4KLX
License: GPL-2
Expand Down Expand Up @@ -103,4 +111,4 @@ License: BSL-1.0
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
DEALINGS IN THE SOFTWARE.
22 changes: 19 additions & 3 deletions include/dsd.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,14 @@
#define PA_LATENCY_OUT 0.100
#endif

#ifdef USE_RTLSDR
#include <rtl-sdr.h>
#endif

/*
* global variables
*/
int exitflag;

static volatile int exitflag;

typedef struct
{
Expand All @@ -85,7 +88,9 @@ typedef struct
#ifdef USE_PORTAUDIO
PaStream* audio_in_pa_stream;
#endif
int audio_in_type; // 0 for device, 1 for file, 2 for portaudio
uint32_t rtlsdr_center_freq;
int rtlsdr_ppm_error;
int audio_in_type; // 0 for device, 1 for file, 2 for portaudio, 3 for rtlsdr
char audio_out_dev[1024];
int audio_out_fd;
SNDFILE *audio_out_file;
Expand Down Expand Up @@ -317,4 +322,15 @@ void processDSTAR_HD (dsd_opts * opts, dsd_state * state);
short dmr_filter(short sample);
short nxdn_filter(short sample);

#ifdef __cplusplus
extern "C" {
#endif
void open_rtlsdr_stream(dsd_opts *opts);
void cleanup_rtlsdr_stream();
void get_rtlsdr_sample(int16_t *sample);
void rtlsdr_sighandler();
#ifdef __cplusplus
}
#endif

#endif // DSD_H
4 changes: 4 additions & 0 deletions src/dsd_audio.c
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,10 @@ openAudioInDevice (dsd_opts * opts)
exit(1);
#endif
}
else if(strncmp(opts->audio_in_dev, "rtl:", 3) == 0)
{
opts->audio_in_type = 3;
}
else
{
struct stat stat_buf;
Expand Down
54 changes: 53 additions & 1 deletion src/dsd_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,8 @@ usage ()
printf (" -n Do not send synthesized speech to audio output device\n");
printf (" -w <file> Output synthesized speech to a .wav file\n");
printf (" -a Display port audio devices\n");
printf (" -c <hertz> RTL-SDR center frequency\n");
printf (" -P <num> RTL-SDR ppm error (default = 0)\n");
printf ("\n");
printf ("Scanner control options:\n");
printf (" -B <num> Serial port baud rate (default=115200)\n");
Expand Down Expand Up @@ -327,6 +329,12 @@ liveScanner (dsd_opts * opts, dsd_state * state)
return;
}
}
#endif
#ifdef USE_RTLSDR
if(opts->audio_in_type == 3)
{
open_rtlsdr_stream(opts);
}
#endif
while (1)
{
Expand Down Expand Up @@ -411,6 +419,14 @@ cleanupAndExit (dsd_opts * opts, dsd_state * state)
}
#endif

#ifdef USE_RTLSDR
if(opts->audio_in_type == 3)
{
// TODO: cleanup demod threads
cleanup_rtlsdr_stream();
}
#endif

printf("\n");
printf("Total audio errors: %i\n", state->debug_audio_errors);
printf("Total header errors: %i\n", state->debug_header_errors);
Expand Down Expand Up @@ -447,6 +463,35 @@ sigfun (int sig)
{
exitflag = 1;
signal (SIGINT, SIG_DFL);
#ifdef USE_RTLSDR
rtlsdr_sighandler();
#endif
}

double atofs(char *s)
{
char last;
int len;
double suff = 1.0;
len = strlen(s);
last = s[len-1];
s[len-1] = '\0';
switch (last) {
case 'g':
case 'G':
suff *= 1e3;
case 'm':
case 'M':
suff *= 1e3;
case 'k':
case 'K':
suff *= 1e3;
suff *= atof(s);
s[len-1] = last;
return suff;
}
s[len-1] = last;
return atof(s);
}

int
Expand All @@ -469,7 +514,7 @@ main (int argc, char **argv)
exitflag = 0;
signal (SIGINT, sigfun);

while ((c = getopt (argc, argv, "haep:qstv:z:i:o:d:g:nw:B:C:R:f:m:u:x:A:S:M:rl")) != -1)
while ((c = getopt (argc, argv, "haep:P:qstv:z:i:o:d:c:g:nw:B:C:R:f:m:u:x:A:S:M:rl")) != -1)
{
opterr = 0;
switch (c)
Expand Down Expand Up @@ -506,6 +551,9 @@ main (int argc, char **argv)
opts.unmute_encrypted_p25 = 1;
}
break;
case 'P':
sscanf (optarg, "%i", &opts.rtlsdr_ppm_error);
break;
case 'q':
opts.errorbars = 0;
opts.verbose = 0;
Expand Down Expand Up @@ -551,6 +599,10 @@ main (int argc, char **argv)
opts.mbe_out_dir[1023] = '\0';
printf ("Writing mbe data files to directory %s\n", opts.mbe_out_dir);
break;
case 'c':
opts.rtlsdr_center_freq = (uint32_t)atofs(optarg);
printf("Using center freq: %i\n", opts.rtlsdr_center_freq);
break;
case 'g':
sscanf (optarg, "%f", &opts.audio_gain);
if (opts.audio_gain < (float) 0 )
Expand Down
27 changes: 17 additions & 10 deletions src/dsd_symbol.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,18 +88,25 @@ getSymbol (dsd_opts * opts, dsd_state * state, int have_sync)
cleanupAndExit (opts, state);
}
}
else
{
else if (opts->audio_in_type == 2)
{
#ifdef USE_PORTAUDIO
PaError err = Pa_ReadStream( opts->audio_in_pa_stream, &sample, 1 );
if( err != paNoError )
{
fprintf( stderr, "An error occured while using the portaudio input stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
}
PaError err = Pa_ReadStream( opts->audio_in_pa_stream, &sample, 1 );
if( err != paNoError )
{
fprintf( stderr, "An error occured while using the portaudio input stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
}
#endif
}
}
else if (opts->audio_in_type == 3)
{
#ifdef USE_RTLSDR
// TODO: need to read demodulated stream here
get_rtlsdr_sample(&sample);
#endif
}

#ifdef TRACE_DSD
state->debug_sample_index++;
Expand Down
Loading