Skip to content

Update Makefile #76

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

Closed
wants to merge 12 commits into from
Closed
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: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
# equal to some value. Your mileage my vary.

win := $(shell uname | grep CYGWIN)
ifeq ($(win),)
win := $(shell uname | grep MINGW)
endif
dar := $(shell uname | grep Darwin)

ifneq ($(win),)
Expand Down
2 changes: 1 addition & 1 deletion Makefile.linux
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ direwolf : direwolf.o config.o recv.o demod.o dsp.o demod_afsk.o demod_9600.o hd
hdlc_rec2.o multi_modem.o redecode.o rdq.o rrbb.o dlq.o \
fcs_calc.o ax25_pad.o \
decode_aprs.o symbols.o server.o kiss.o kissnet.o kiss_frame.o hdlc_send.o fcs_calc.o \
gen_tone.o audio.o audio_stats.o digipeater.o pfilter.o dedupe.o tq.o xmit.o morse.o \
gen_tone.o audio.o audio_ptt.o audio_stats.o digipeater.o pfilter.o dedupe.o tq.o xmit.o morse.o \
ptt.o beacon.o encode_aprs.o latlong.o encode_aprs.o latlong.o textcolor.o \
dtmf.o aprs_tt.o tt_user.o tt_text.o igate.o nmea.o serial_port.o log.o telemetry.o \
dwgps.o dwgpsnmea.o dwgpsd.o dtime_now.o \
Expand Down
2 changes: 1 addition & 1 deletion Makefile.win
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ direwolf : direwolf.o config.o recv.o demod.o dsp.o demod_afsk.o demod_9600.o hd
hdlc_rec2.o multi_modem.o redecode.o rdq.o rrbb.o dlq.o \
fcs_calc.o ax25_pad.o \
decode_aprs.o symbols.o server.o kiss.o kissnet.o kiss_frame.o hdlc_send.o fcs_calc.o \
gen_tone.o morse.o audio_win.o audio_stats.o digipeater.o pfilter.o dedupe.o tq.o xmit.o \
gen_tone.o morse.o audio_win.o audio_ptt_win.o audio_stats.o digipeater.o pfilter.o dedupe.o tq.o xmit.o \
ptt.o beacon.o dwgps.o encode_aprs.o latlong.o textcolor.o \
dtmf.o aprs_tt.o tt_user.o tt_text.o igate.o nmea.o serial_port.o log.o telemetry.o \
dwgps.o dwgpsnmea.o dtime_now.o \
Expand Down
2 changes: 1 addition & 1 deletion audio.c
Original file line number Diff line number Diff line change
Expand Up @@ -692,7 +692,6 @@ static int set_oss_params (int a, int fd, struct audio_s *pa)
char message[100];
int ossbuf_size_in_bytes;


err = ioctl (fd, SNDCTL_DSP_CHANNELS, &(pa->adev[a].num_channels));
if (err == -1) {
text_color_set(DW_COLOR_ERROR);
Expand Down Expand Up @@ -1249,6 +1248,7 @@ int audio_flush (int a)
}
if (k < len) {
/* presumably full but didn't block. */
dw_printf("problem\n");
usleep (10000);
}
ptr += k;
Expand Down
21 changes: 20 additions & 1 deletion audio.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,17 @@ enum ptt_method_e {
PTT_METHOD_SERIAL, /* Serial port RTS or DTR. */
PTT_METHOD_GPIO, /* General purpose I/O, Linux only. */
PTT_METHOD_LPT, /* Parallel printer port, Linux only. */
PTT_METHOD_HAMLIB }; /* HAMLib, Linux only. */
PTT_METHOD_HAMLIB, /* HAMLib, Linux only. */
PTT_METHOD_AUDIO }; /* Audio channel. */

typedef enum ptt_method_e ptt_method_t;

enum ptt_audio_state_e {
PTT_AUDIO_STATE_STOP,
PTT_AUDIO_STATE_START,
PTT_AUDIO_STATE_CLOSE };
typedef enum ptt_audio_state_e ptt_audio_state_t;

enum ptt_line_e { PTT_LINE_NONE = 0, PTT_LINE_RTS = 1, PTT_LINE_DTR = 2 }; // Important: 0 for neither.
typedef enum ptt_line_e ptt_line_t;

Expand Down Expand Up @@ -195,6 +202,18 @@ struct audio_s {
int ptt_invert; /* Invert the output. */
int ptt_invert2; /* Invert the secondary output. */

int ptt_channel; /* Channel number for audio PTT. */
int ptt_frequency; /* Audio frequency for audio PTT. */
#if __WIN32__
HANDLE ptt_start; /* Handle for event that starts ptt tone. */
HANDLE ptt_stop; /* Handle for event that stops ptt tone. */
HANDLE ptt_close; /* Handle for event that closes ptt. */
#else
pthread_mutex_t ptt_mutex; /* Mutex for controlling ptt tone state. */
pthread_cond_t ptt_condition; /* Condition for controlling ptt tone state. */
ptt_audio_state_t ptt_state; /* State of ptt tone. */
#endif

#ifdef USE_HAMLIB

int ptt_model; /* HAMLIB model. -1 for AUTO. 2 for rigctld. Others are radio model. */
Expand Down
254 changes: 254 additions & 0 deletions audio_ptt.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,254 @@
//
// This file is part of Dire Wolf, an amateur radio packet TNC.
//
// Copyright (C) 2011, 2012, 2013, 2014, 2015 John Langner, WB2OSZ
// Copyright (C) 2017 Andrew Walker, VA7YAA
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//


/*------------------------------------------------------------------
*
* Module: audio_ptt.c
*
* Purpose: Interface to audio device commonly called a "sound card" for
* historical reasons.
*
* This version uses the native Windows sound interface.
*
*---------------------------------------------------------------*/

#if __WIN32__
#else
#include <limits.h>
#include <math.h>
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>

#if USE_ALSA
#include <alsa/asoundlib.h>
#else
#include <errno.h>
#ifdef __OpenBSD__
#include <soundcard.h>
#else
#include <sys/soundcard.h>
#endif
#endif

#include "direwolf.h"
#include "audio.h"
#include "audio_stats.h"
#include "textcolor.h"
#include "ptt.h"
#include "audio_ptt.h"

#if USE_ALSA
static int set_alsa_params (int a, snd_pcm_t *handle, struct audio_s *pa, char *name, char *dir);
//static void alsa_select_device (char *pick_dev, int direction, char *result);
#else
static int set_oss_params (int a, int fd, struct audio_s *pa);
#endif

static struct audio_s *save_audio_config_p;

static void * ptt_thread (void *arg);

int start_ptt_thread (struct audio_s *pa, int ch)
{
pthread_t tid = 0;
int e;

save_audio_config_p = pa;

e = pthread_create (&tid, NULL, ptt_thread, (void*)(long)ch);

return tid;
}

static void * ptt_thread (void *arg)
{
int ch = (int)(long)arg; // channel number.
int channel = save_audio_config_p->achan[ch].octrl[OCTYPE_PTT].ptt_channel;
int freq = save_audio_config_p->achan[channel].octrl[OCTYPE_PTT].ptt_frequency;
int a = ACHAN2ADEV( channel );

if( save_audio_config_p->adev[a].defined ) {
#if USE_ALSA
snd_pcm_t *handle;
int err;

err = snd_pcm_open (&handle, save_audio_config_p->adev[a].adevice_out, SND_PCM_STREAM_PLAYBACK, 0);
if (err == 0) {
snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE;

err = snd_pcm_set_params (handle, format, SND_PCM_ACCESS_RW_INTERLEAVED,
save_audio_config_p->adev[a].num_channels,
save_audio_config_p->adev[a].samples_per_sec, 1, 500000);
if (err == 0) {
short* pnData;
short sample;
int nSamples = (int)( ( (double)save_audio_config_p->adev[a].samples_per_sec / (double)freq ) * ceil( (double)freq / 5.0 ) );
int nBufferLength = save_audio_config_p->adev[a].num_channels * nSamples * sizeof(short);
int i;
int j;

pnData = (short*)malloc (nBufferLength);

for (i = 0; i < nSamples; i++) {
sample = (short)( (double)SHRT_MAX * sin( ( (double)i * freq / (double)save_audio_config_p->adev[a].samples_per_sec ) * 2.0 * M_PI ) );

for (j = 0; j < save_audio_config_p->adev[a].num_channels; j++) {
if (channel == ADEVFIRSTCHAN( a ) + j) {
pnData[i*save_audio_config_p->adev[a].num_channels + j] = sample;
} else {
pnData[i*save_audio_config_p->adev[a].num_channels + j] = 0;
}
}
}

while (1) {
pthread_mutex_lock (&save_audio_config_p->achan[ch].octrl[OCTYPE_PTT].ptt_mutex);
ptt_audio_state_t ptt_state = save_audio_config_p->achan[ch].octrl[OCTYPE_PTT].ptt_state;
pthread_mutex_unlock (&save_audio_config_p->achan[ch].octrl[OCTYPE_PTT].ptt_mutex);

if (ptt_state == PTT_AUDIO_STATE_STOP) {
snd_pcm_drop (handle);

pthread_mutex_lock (&save_audio_config_p->achan[ch].octrl[OCTYPE_PTT].ptt_mutex);
pthread_cond_wait (&save_audio_config_p->achan[ch].octrl[OCTYPE_PTT].ptt_condition, &save_audio_config_p->achan[ch].octrl[OCTYPE_PTT].ptt_mutex);
ptt_state = save_audio_config_p->achan[ch].octrl[OCTYPE_PTT].ptt_state;
pthread_mutex_unlock (&save_audio_config_p->achan[ch].octrl[OCTYPE_PTT].ptt_mutex);

if (ptt_state == PTT_AUDIO_STATE_START) {
snd_pcm_prepare (handle);
}
}

if (ptt_state == PTT_AUDIO_STATE_START) {
snd_pcm_writei (handle, pnData, nSamples);
}
else if (ptt_state == PTT_AUDIO_STATE_CLOSE) {
snd_pcm_drop (handle);

break;
}
}

free (pnData);
} else {
dw_printf("Failed to configure ALSA device. PTT tone will not be enabled.\n");
}
snd_pcm_close (handle);
} else {
dw_printf("Failed to open ALSA device. PTT tone will not be enabled.\n");
}
#else
int oss_audio_device_fd;

oss_audio_device_fd = open (save_audio_config_p->adev[a].adevice_out, O_WRONLY);
if (oss_audio_device_fd >= 0) {
int devcaps;
int num_channels;
int samples_per_sec;
int bits_per_sample;
int err;

num_channels = save_audio_config_p->adev[a].num_channels;
err = ioctl (oss_audio_device_fd, SNDCTL_DSP_CHANNELS, &num_channels);

if (err != -1) {
samples_per_sec = save_audio_config_p->adev[a].samples_per_sec;
err = ioctl (oss_audio_device_fd, SNDCTL_DSP_SPEED, &samples_per_sec);
}

if (err != -1) {
bits_per_sample = save_audio_config_p->adev[a].bits_per_sample;
err = ioctl (oss_audio_device_fd, SNDCTL_DSP_SETFMT, &bits_per_sample);
}

if (err != -1) {
err = ioctl (oss_audio_device_fd, SNDCTL_DSP_GETCAPS, &devcaps);
}

if (err != -1) {
short* pnData;
short sample;
int nBufferLength;
int nSamples;
int written;
int i;
int j;

nSamples = (int)( ( (double)samples_per_sec / (double)freq ) * ceil( (double)freq / 5.0 ) );
nBufferLength = num_channels * nSamples * sizeof(short);
pnData = (short*)malloc (nBufferLength);

for (i = 0; i < nSamples; i++) {
sample = (short)( (double)SHRT_MAX * sin( ( (double)i * freq / (double)samples_per_sec ) * 2.0 * M_PI ) );

for (j = 0; j < num_channels; j++) {
if (channel == ADEVFIRSTCHAN( a ) + j) {
pnData[i*num_channels + j] = sample;
} else {
pnData[i*num_channels + j] = 0;
}
}
}

while (1) {
pthread_mutex_lock (&save_audio_config_p->achan[ch].octrl[OCTYPE_PTT].ptt_mutex);
ptt_audio_state_t ptt_state = save_audio_config_p->achan[ch].octrl[OCTYPE_PTT].ptt_state;
pthread_mutex_unlock (&save_audio_config_p->achan[ch].octrl[OCTYPE_PTT].ptt_mutex);

if (ptt_state == PTT_AUDIO_STATE_STOP) {
ioctl (oss_audio_device_fd, SNDCTL_DSP_RESET, NULL);

pthread_mutex_lock (&save_audio_config_p->achan[ch].octrl[OCTYPE_PTT].ptt_mutex);
pthread_cond_wait (&save_audio_config_p->achan[ch].octrl[OCTYPE_PTT].ptt_condition, &save_audio_config_p->achan[ch].octrl[OCTYPE_PTT].ptt_mutex);
ptt_state = save_audio_config_p->achan[ch].octrl[OCTYPE_PTT].ptt_state;
pthread_mutex_unlock (&save_audio_config_p->achan[ch].octrl[OCTYPE_PTT].ptt_mutex);
}

if (ptt_state == PTT_AUDIO_STATE_START) {
written = write (oss_audio_device_fd, pnData, nBufferLength);
}
else if (ptt_state == PTT_AUDIO_STATE_CLOSE) {
ioctl (oss_audio_device_fd, SNDCTL_DSP_RESET, NULL);

break;
}
}

free (pnData);
} else {
dw_printf("Failed to configure OSS device. PTT tone will not be enabled.\n");
}
close (oss_audio_device_fd);
} else {
dw_printf("Failed to open OSS device. PTT tone will not be enabled.\n");
}
#endif
}
}

#endif

11 changes: 11 additions & 0 deletions audio_ptt.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

#ifndef AUDIO_PTT_H
#define AUDIO_PTT_H 1

#if __WIN32__
extern HANDLE start_ptt_thread ( struct audio_s *pa, int ch );
#else
extern int start_ptt_thread ( struct audio_s *pa, int ch );
#endif

#endif
Loading