message(STATUS "FreeDV version: ${FREEDV_VERSION}")
# Work around for not using a svn working copy.
-add_definitions(-DSVN_REVISION="Unversioned directory")
add_definitions(-D_NO_AUTOTOOLS_)
+find_program(SVNVERSION_PATH svnversion)
+if(SVNVERSION_PATH)
+ execute_process(COMMAND ${SVNVERSION_PATH} .
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ RESULT_VARIABLE SVN_REVISION_RESULT
+ OUTPUT_VARIABLE SVN_CURRENT_REVISION
+ ERROR_QUIET
+ )
+else()
+ set(SVN_REVISION_RESULT 1)
+endif()
+if(SVN_REVISION_RESULT EQUAL 0)
+string(STRIP ${SVN_CURRENT_REVISION} SVN_REVISION)
+add_definitions(-DSVN_REVISION="${SVN_REVISION}")
+else()
+add_definitions(-DSVN_REVISION="Unversioned directory")
+endif()
+
# Set default build flags.
"Download and build static samplerate instead of the system library.")
set(USE_STATIC_SOX FALSE CACHE BOOL
"Download and build static sox instead of the system library.")
-set(USE_STATIC_LIBCTB FALSE CACHE BOOL
- "Download and build static libctb instead of the system library.")
set(USE_STATIC_CODEC2 FALSE CACHE BOOL
"Download and build static codec2 instead of the system library.")
set(BOOTSTRAP_WXWIDGETS FALSE CACHE BOOL
set(USE_STATIC_SNDFILE TRUE FORCE)
set(USE_STATIC_SAMPLERATE TRUE FORCE)
set(USE_STATIC_SOX TRUE FORCE)
- set(USE_STATIC_LIBCTB TRUE FORCE)
set(USE_STATIC_CODEC2 TRUE FORCE)
endif(USE_STATIC_DEPS)
libcodec2.dll
libportaudio-2.dll
libportaudiocpp-0.dll
- libctb-0.16.dll
libsox-2.dll
zlib1.dll
libusb0.dll
#
if(NOT USE_STATIC_PORTAUDIO)
message(STATUS "Looking for portaudio...")
- find_library(PORTAUDIO_LIBS NAMES libportaudio-2.dll portaudio)
- find_path(PORTAUDIO_INCLUDE_DIR portaudio.h)
+ find_library(PORTAUDIO_LIBS NAMES libportaudio-2.dll portaudio HINTS /usr/local/lib/portaudio2)
+ find_path(PORTAUDIO_INCLUDE_DIR portaudio.h HINTS /usr/local/include/portaudio2)
message(STATUS " portaudio library: ${PORTAUDIO_LIBS}")
message(STATUS " portaudio headers: ${PORTAUDIO_INCLUDE_DIR}")
if(PORTAUDIO_LIBS AND PORTAUDIO_INCLUDE_DIR)
include(cmake/BuildCodec2.cmake)
endif(NOT USE_STATIC_CODEC2)
-#
-# Find libctb. Assumes version 0.16
-#
-if(NOT USE_STATIC_LIBCTB)
- message(STATUS "Looking for libctb...")
- find_path(LIBCTB_INCLUDE_DIR NAMES ctb.h ctb-0.16/ctb.h)
- find_library(LIBCTB_LIBRARY NAMES ctb ctb-0.16)
- message(STATUS " libctb library: ${LIBCTB_LIBRARY}")
- message(STATUS " libctb headers: ${LIBCTB_INCLUDE_DIR}")
- if(LIBCTB_LIBRARY AND LIBCTB_INCLUDE_DIR)
- set(CMAKE_REQUIRED_LIBRARIES ${LIBCTB_LIBRARY})
- if(NOT CMAKE_CROSSCOMPILING)
- # Check to make sure linking with libctb works.
- include(CheckCXXSourceCompiles)
- check_cxx_source_compiles("
- #include <ctb-0.16/ctb.h>
- int main() {
- ctb::SerialPort* m_serialPort;
- m_serialPort = new ctb::SerialPort();
- };"
- LIBCTB_LINKS)
- if(NOT LIBCTB_LINKS)
- message(FATAL_ERROR "Linking libctb failed.")
- endif(NOT LIBCTB_LINKS)
- endif(NOT CMAKE_CROSSCOMPILING)
- else(LIBCTB_LIBRARY AND LIBCTB_INCLUDE_DIR)
- message(FATAL_ERROR "libctb not found.
-Linux:
- libctb may not be available in your distribution. Either build and install or use the cmake option to build statically.
-Windws:
-It's easiest to use the cmake option: USE_STATIC_LIBCTB"
- )
- endif(LIBCTB_LIBRARY AND LIBCTB_INCLUDE_DIR)
-else(NOT USE_STATIC_LIBCTB)
- include(cmake/BuildLibctb.cmake)
-endif(NOT USE_STATIC_LIBCTB)
-
-include_directories(${LIBCTB_INCLUDE_DIR})
-list(APPEND FREEDV_LINK_LIBS ${LIBCTB_LIBRARY})
-
# Freedv
add_subdirectory(src)
wxString svnLatestRev("Can't determine latest SVN revision.");
// Try to determine current SVN revision from the Internet
- wxURL url(wxT("http://freetel.svn.sourceforge.net/svnroot/freetel/fdmdv2/"));
+ wxURL url(wxT("http://svn.code.sf.net/p/freetel/code/fdmdv2/"));
if(url.GetError() == wxURL_NOERR)
{
in->Read(html_stream);
//wxLogDebug(htmldata);
- wxString s("<h2>freetel - Revision ");
+ wxString s("<h2>p/freetel/code - Revision ");
int startIndex = htmldata.find(s) + s.Length();
int endIndex = htmldata.find(wxT(": /fdmdv2</h2>"));
svnLatestRev = wxT("Latest svn revision: ") + htmldata.SubString(startIndex, endIndex-1);
#ifdef __WIN32__
#include <wx/msw/registry.h>
#endif
+#ifdef __FreeBSD__
+#include <glob.h>
+#include <string.h>
+#endif
#include <sstream>
m_staticText12->Wrap(-1);
gridSizer200->Add(m_staticText12, 1,wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 2);
- m_txtCtlDevicePath = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
- gridSizer200->Add(m_txtCtlDevicePath, 1, wxEXPAND|wxALIGN_CENTER|wxALIGN_RIGHT, 2);
+ m_cbCtlDevicePath = new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(140, -1), 0, NULL, wxCB_DROPDOWN);
+ gridSizer200->Add(m_cbCtlDevicePath, 1, wxEXPAND|wxALIGN_CENTER|wxALIGN_RIGHT, 2);
bSizer83->Add(gridSizer200, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxALL, 2);
staticBoxSizer31->Add(bSizer83, 1, wxALIGN_CENTER_VERTICAL|wxALL, 1);
m_cbSerialPort->Append(aStr);
#endif
#ifdef __WXGTK__
- /* TODO(Joel): http://stackoverflow.com/questions/2530096/how-to-find-all-serial-devices-ttys-ttyusb-on-linux-without-opening-them */
m_cbSerialPort->Clear();
+ m_cbCtlDevicePath->Clear();
+#ifdef __FreeBSD__
+ glob_t gl;
+ if(glob("/dev/tty*", GLOB_MARK, NULL, &gl)==0) {
+ for(unsigned int i=0; i<gl.gl_pathc; i++) {
+ if(gl.gl_pathv[i][strlen(gl.gl_pathv[i])-1]=='/')
+ continue;
+
+ /* Exclude pseudo TTYs */
+ if(gl.gl_pathv[i][8] >= 'l' && gl.gl_pathv[i][8] <= 's')
+ continue;
+ if(gl.gl_pathv[i][8] >= 'L' && gl.gl_pathv[i][8] <= 'S')
+ continue;
+
+ /* Exclude virtual TTYs */
+ if(gl.gl_pathv[i][8] == 'v')
+ continue;
+
+ /* Exclude initial-state and lock-state devices */
+ if(strchr(gl.gl_pathv[i], '.') != NULL)
+ continue;
+
+ m_cbSerialPort->Append(gl.gl_pathv[i]);
+ m_cbCtlDevicePath->Append(gl.gl_pathv[i]);
+ }
+ globfree(&gl);
+ }
+#else
+ /* TODO(Joel): http://stackoverflow.com/questions/2530096/how-to-find-all-serial-devices-ttys-ttyusb-on-linux-without-opening-them */
m_cbSerialPort->Append("/dev/ttyUSB0");
m_cbSerialPort->Append("/dev/ttyUSB1");
m_cbSerialPort->Append("/dev/ttyS0");
m_cbSerialPort->Append("/dev/ttyS1");
- /*
- m_txtCtlDevicePath->Clear();
- m_txtCtlDevicePath->Append("/dev/ttyUSB0");
- m_txtCtlDevicePath->Append("/dev/ttyUSB1");
- m_txtCtlDevicePath->Append("/dev/ttyS0");
- m_txtCtlDevicePath->Append("/dev/ttyS1");
- */
+ m_cbCtlDevicePath->Clear();
+ m_cbCtlDevicePath->Append("/dev/ttyUSB0");
+ m_cbCtlDevicePath->Append("/dev/ttyUSB1");
+ m_cbCtlDevicePath->Append("/dev/ttyS0");
+ m_cbCtlDevicePath->Append("/dev/ttyS1");
+#endif
#endif
}
m_listCtrlPorts->SetStringSelection(str);
#endif
#ifdef __WXGTK__
- m_txtCtlDevicePath->SetValue(str);
+ m_cbCtlDevicePath->SetValue(str);
#endif
m_rbUseRTS->SetValue(wxGetApp().m_boolUseRTS);
m_ckRTSPos->SetValue(wxGetApp().m_boolRTSPos);
wxGetApp().m_strRigCtrlPort = m_listCtrlPorts->GetStringSelection();
#endif
#ifdef __WXGTK__
- wxGetApp().m_strRigCtrlPort = m_txtCtlDevicePath->GetValue();
+ wxGetApp().m_strRigCtrlPort = m_cbCtlDevicePath->GetValue();
#endif
wxGetApp().m_boolUseRTS = m_rbUseRTS->GetValue();
wxGetApp().m_boolRTSPos = m_ckRTSPos->IsChecked();
wxListBox *m_listCtrlPorts;
wxCheckBox *m_ckUseSerialPTT;
wxStaticText *m_staticText12;
- wxTextCtrl *m_txtCtlDevicePath;
+ wxComboBox *m_cbCtlDevicePath;
wxRadioButton *m_rbUseDTR;
wxCheckBox *m_ckRTSPos;
wxRadioButton *m_rbUseRTS;
wxGetApp().m_boolRTSPos = pConfig->ReadBool(wxT("/Rig/RTSPolarity"), true);
wxGetApp().m_boolUseDTR = pConfig->ReadBool(wxT("/Rig/UseDTR"), false);
wxGetApp().m_boolDTRPos = pConfig->ReadBool(wxT("/Rig/DTRPolarity"), false);
+ com_handle = COM_HANDLE_INVALID;
// -----------------------------------------------------------------------
delete wxConfigBase::Set((wxConfigBase *) NULL);
}
+//----------------------------------------------------------------
+// closeComPort() closes the currently open com port
+//----------------------------------------------------------------
+void MainFrame::closeComPort(void)
+{
+#ifdef _WIN32
+ CloseHandle(com_handle);
+#else
+ close(com_handle);
+#endif
+ com_handle = COM_HANDLE_INVALID;
+}
+
+//----------------------------------------------------------------
+// openComPort() opens the com port specified by the string
+// ie: "COM1" on Windows or "/dev/ttyu0" on FreeBSD
+//----------------------------------------------------------------
+bool MainFrame::openComPort(const char *name)
+{
+ if(com_handle != COM_HANDLE_INVALID)
+ closeComPort();
+#ifdef _WIN32
+ {
+ COMMTIMEOUTS timeouts;
+ DCB dcb;
+
+ if((com_handle=CreateFileA(name
+ ,GENERIC_READ|GENERIC_WRITE /* Access */
+ ,0 /* Share mode */
+ ,NULL /* Security attributes */
+ ,OPEN_EXISTING /* Create access */
+ ,FILE_ATTRIBUTE_NORMAL /* File attributes */
+ ,NULL /* Template */
+ ))==INVALID_HANDLE_VALUE)
+ return false;
+
+ if(GetCommTimeouts(com_handle, &timeouts)) {
+ timeouts.ReadIntervalTimeout=MAXDWORD;
+ timeouts.ReadTotalTimeoutMultiplier=0;
+ timeouts.ReadTotalTimeoutConstant=0; // No-wait read timeout
+ timeouts.WriteTotalTimeoutMultiplier=0;
+ timeouts.WriteTotalTimeoutConstant=5000; // 5 seconds
+ SetCommTimeouts(com_handle,&timeouts);
+ }
+
+ /* Force N-8-1 mode: */
+ if(GetCommState(com_handle, &dcb)==TRUE) {
+ dcb.ByteSize = 8;
+ dcb.Parity = NOPARITY;
+ dcb.StopBits = ONESTOPBIT;
+ SetCommState(com_handle, &dcb);
+ }
+ }
+#else
+ {
+ struct termios t;
+
+ if((com_handle=open(name, O_NONBLOCK|O_RDWR))==COM_HANDLE_INVALID)
+ return false;
+
+ if(tcgetattr(com_handle, &t)==-1) {
+ close(com_handle);
+ com_handle = COM_HANDLE_INVALID;
+ return false;
+ }
+
+ t.c_iflag = (
+ IGNBRK /* ignore BREAK condition */
+ | IGNPAR /* ignore (discard) parity errors */
+ );
+ t.c_oflag = 0; /* No output processing */
+ t.c_cflag = (
+ CS8 /* 8 bits */
+ | CREAD /* enable receiver */
+ /*
+ Fun snippet from the FreeBSD manpage:
+
+ If CREAD is set, the receiver is enabled. Otherwise, no character is
+ received. Not all hardware supports this bit. In fact, this flag is
+ pretty silly and if it were not part of the termios specification it
+ would be omitted.
+ */
+ | CLOCAL /* ignore modem status lines */
+ );
+ t.c_lflag = 0; /* No local modes */
+ if(tcsetattr(com_handle, TCSANOW, &t)==-1) {
+ close(com_handle);
+ com_handle = COM_HANDLE_INVALID;
+ return false;
+ }
+
+ }
+#endif
+ return true;
+}
+
+
+//----------------------------------------------------------------
+// (raise|lower)(RTS|DTR)()
+//
+// Raises/lowers the specified signal
+//----------------------------------------------------------------
+void MainFrame::raiseDTR(void)
+{
+ if(com_handle == COM_HANDLE_INVALID)
+ return;
+#ifdef _WIN32
+ EscapeCommFunction(com_handle, SETDTR);
+#else
+ { // For C89 happiness
+ int flags = TIOCM_DTR;
+ ioctl(com_handle, TIOCMBIS, &flags);
+ }
+#endif
+}
+void MainFrame::raiseRTS(void)
+{
+ if(com_handle == COM_HANDLE_INVALID)
+ return;
+#ifdef _WIN32
+ EscapeCommFunction(com_handle, SETRTS);
+#else
+ { // For C89 happiness
+ int flags = TIOCM_RTS;
+ ioctl(com_handle, TIOCMBIS, &flags);
+ }
+#endif
+}
+void MainFrame::lowerDTR(void)
+{
+ if(com_handle == COM_HANDLE_INVALID)
+ return;
+#ifdef _WIN32
+ EscapeCommFunction(com_handle, CLRDTR);
+#else
+ { // For C89 happiness
+ int flags = TIOCM_DTR;
+ ioctl(com_handle, TIOCMBIC, &flags);
+ }
+#endif
+}
+void MainFrame::lowerRTS(void)
+{
+ if(com_handle == COM_HANDLE_INVALID)
+ return;
+#ifdef _WIN32
+ EscapeCommFunction(com_handle, CLRRTS);
+#else
+ { // For C89 happiness
+ int flags = TIOCM_RTS;
+ ioctl(com_handle, TIOCMBIC, &flags);
+ }
+#endif
+}
+
+
#ifdef _USE_TIMER
//----------------------------------------------------------------
// OnTimer()
exclusive NOR
*/
- if(wxGetApp().m_boolUseSerialPTT && m_serialPort != NULL) {
+ if(wxGetApp().m_boolUseSerialPTT && com_handle != COM_HANDLE_INVALID) {
if (wxGetApp().m_boolUseRTS) {
printf("g_tx: %d m_boolRTSPos: %d serialLine: %d\n", g_tx, wxGetApp().m_boolRTSPos, g_tx == wxGetApp().m_boolRTSPos);
if (g_tx == wxGetApp().m_boolRTSPos)
- m_serialPort->SetLineState(ctb::LinestateRts);
+ raiseRTS();
else
- m_serialPort->ClrLineState(ctb::LinestateRts);
+ lowerRTS();
}
if (wxGetApp().m_boolUseDTR) {
printf("g_tx: %d m_boolDTRPos: %d serialLine: %d\n", g_tx, wxGetApp().m_boolDTRPos, g_tx == wxGetApp().m_boolDTRPos);
if (g_tx == wxGetApp().m_boolDTRPos)
- m_serialPort->SetLineState(ctb::LinestateDtr);
+ raiseDTR();
else
- m_serialPort->ClrLineState(ctb::LinestateDtr);
+ lowerDTR();
}
}
wxString svnLatestRev("Can't determine latest SVN revision.");
// Try to determine current SVN revision from the Internet
- wxURL url(wxT("http://freetel.svn.sourceforge.net/svnroot/freetel/fdmdv2/"));
+ wxURL url(wxT("http://svn.code.sf.net/p/freetel/code/fdmdv2/"));
if(url.GetError() == wxURL_NOERR)
{
in->Read(html_stream);
//wxLogDebug(htmldata);
- wxString s("<h2>freetel - Revision ");
+ wxString s("<h2>p/freetel/code - Revision ");
int startIndex = htmldata.find(s) + s.Length();
int endIndex = htmldata.find(wxT(": /fdmdv2</h2>"));
svnLatestRev = wxT("Latest svn revision: ") + htmldata.SubString(startIndex, endIndex-1);
//----------------------------------------------------------------
void MainFrame::SetupSerialPort(void)
{
- long baudrate;
-
- baudrate = 10;
if(!wxGetApp().m_strRigCtrlPort.IsEmpty())
{
- wxString protocol = _("8N1");
- m_serialPort = new ctb::SerialPort();
- if(m_serialPort->Open(wxGetApp().m_strRigCtrlPort.c_str(), baudrate, protocol.c_str(), ctb::SerialPort::NoFlowControl ) >= 0 )
+ if(openComPort(wxGetApp().m_strRigCtrlPort.c_str()))
{
- m_device = m_serialPort;
// always start PTT in Rx state
SerialPTTRx();
}
else
{
- m_serialPort = NULL;
- m_device = NULL;
wxMessageBox("Couldn't open Serial Port", wxT("About"), wxOK | wxICON_ERROR, this);
-
}
}
}
wxGetApp().m_boolUseRTS, wxGetApp().m_boolRTSPos, wxGetApp().m_boolUseDTR, wxGetApp().m_boolDTRPos);
if(wxGetApp().m_boolRTSPos) // RTS cleared LOW
- m_serialPort->ClrLineState(ctb::LinestateRts);
+ lowerRTS();
else // RTS cleared HIGH
- m_serialPort->SetLineState(ctb::LinestateRts);
+ raiseRTS();
if(wxGetApp().m_boolDTRPos) // DTR cleared LOW
- m_serialPort->ClrLineState(ctb::LinestateDtr);
+ lowerDTR();
else // DTR cleared HIGH
- m_serialPort->SetLineState(ctb::LinestateDtr);
+ raiseDTR();
}
//----------------------------------------------------------------
//----------------------------------------------------------------
void MainFrame::CloseSerialPort(void)
{
- if (m_serialPort != NULL) {
+ if (com_handle != COM_HANDLE_INVALID) {
// always end with PTT in rx state
SerialPTTRx();
- if((m_serialPort != NULL) && m_serialPort->IsOpen()) {
- m_serialPort->Close();
- m_serialPort = NULL;
- m_device = NULL;
- }
+ closeComPort();
}
}
#include <samplerate.h>
#include <hamlib.h>
-#include "ctb-0.16/ctb.h"
-#include "ctb-0.16/portscan.h"
-#include "ctb-0.16/serportx.h"
-#include "ctb-0.16/serport.h"
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <termios.h>
+#include <sys/ioctl.h>
+#endif
#include "codec2.h"
#include "codec2_fdmdv.h"
#define EXCHANGE_DATA_IN 0
#define EXCHANGE_DATA_OUT 1
+#ifdef _WIN32
+#define COM_HANDLE_INVALID INVALID_HANDLE_VALUE
+typedef HANDLE com_handle_t;
+#else
+#define COM_HANDLE_INVALID -1
+typedef int com_handle_t;
+#endif
+
extern int g_nSoundCards;
extern int g_soundCard1InDeviceNum;
extern int g_soundCard1OutDeviceNum;
protected:
- ctb::IOBase* m_device;
- ctb::SerialPort* m_serialPort;
+#ifdef _WIN32
+#define COM_HANDLE_INVALID INVALID_HANDLE_VALUE
+ com_handle_t com_handle;
+#else
+#define COM_HANDLE_INVALID -1
+ com_handle_t com_handle;
+#endif
+ void raiseDTR(void);
+ void lowerDTR(void);
+ void raiseRTS(void);
+ void lowerRTS(void);
+ bool openComPort(const char *port);
+ void closeComPort(void);
void setsnrBeta(bool snrSlow);
/* Reset debug output. */
rig_set_debug(RIG_DEBUG_VERBOSE);
+
+ m_rig = NULL;
}
Hamlib::~Hamlib() {
+ if(m_rig)
+ close();
}
static int build_list(const struct rig_caps *rig, rig_ptr_t rigList) {
printf("rig: %s %s (%d)\n", m_rigList[rig_index]->mfg_name,
m_rigList[rig_index]->model_name, m_rigList[rig_index]->rig_model);
+ if(m_rig) {
+ printf("Closing old hamlib instance!\n");
+ close();
+ }
+
/* Initialise, configure and open. */
m_rig = rig_init(m_rigList[rig_index]->rig_model);
/* TODO: Also use baud rate from the screen. */
}
bool Hamlib::ptt(bool press) {
+ if(!m_rig)
+ return false;
/* TODO(Joel): make ON_DATA and ON configurable. */
ptt_t on = press ? RIG_PTT_ON : RIG_PTT_OFF;
/* TODO(Joel): what should the VFO option be? */
}
void Hamlib::close(void) {
- rig_close(m_rig);
- rig_cleanup(m_rig);
- free(m_rig);
+ if(m_rig) {
+ rig_close(m_rig);
+ rig_cleanup(m_rig);
+ m_rig = NULL;
+ }
}