mirror of https://github.com/wb2osz/direwolf.git
				
				
				
			add audio channel option for ptt (Windows only)
This commit is contained in:
		
							parent
							
								
									72cd5dbc26
								
							
						
					
					
						commit
						3b59838237
					
				| 
						 | 
					@ -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 \
 | 
							hdlc_rec2.o multi_modem.o redecode.o rdq.o rrbb.o dlq.o \
 | 
				
			||||||
		fcs_calc.o ax25_pad.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 \
 | 
							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 \
 | 
							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 \
 | 
							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 \
 | 
							dwgps.o dwgpsnmea.o dtime_now.o \
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										10
									
								
								audio.h
								
								
								
								
							
							
						
						
									
										10
									
								
								audio.h
								
								
								
								
							| 
						 | 
					@ -196,6 +196,16 @@ struct audio_s {
 | 
				
			||||||
	        int ptt_invert;		/* Invert the output. */
 | 
						        int ptt_invert;		/* Invert the output. */
 | 
				
			||||||
	        int ptt_invert2;	/* Invert the secondary 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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef USE_HAMLIB
 | 
					#ifdef USE_HAMLIB
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	        int ptt_model;		/* HAMLIB model.  -1 for AUTO.  2 for rigctld.  Others are radio model. */
 | 
						        int ptt_model;		/* HAMLIB model.  -1 for AUTO.  2 for rigctld.  Others are radio model. */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,20 @@
 | 
				
			||||||
 | 
					// 
 | 
				
			||||||
 | 
					//    This file is part of Dire Wolf, an amateur radio packet TNC.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//    Copyright (C) 2011, 2012, 2013, 2014, 2015  John Langner, WB2OSZ
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//    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/>.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,193 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//    This file is part of Dire Wolf, an amateur radio packet TNC.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//    Copyright (C) 2011, 2012, 2013, 2014, 2015  John Langner, WB2OSZ
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//    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_win.c
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Purpose:   	Interface to audio device commonly called a "sound card" for
 | 
				
			||||||
 | 
					 *		historical reasons.		
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *		This version uses the native Windows sound interface.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *---------------------------------------------------------------*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if __WIN32__
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <assert.h>
 | 
				
			||||||
 | 
					#include <ctype.h>
 | 
				
			||||||
 | 
					#include <io.h>
 | 
				
			||||||
 | 
					#include <fcntl.h>
 | 
				
			||||||
 | 
					#include <math.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <windows.h>		
 | 
				
			||||||
 | 
					#include <mmsystem.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef WAVE_FORMAT_96M16
 | 
				
			||||||
 | 
					#define WAVE_FORMAT_96M16 0x40000
 | 
				
			||||||
 | 
					#define WAVE_FORMAT_96S16 0x80000
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "direwolf.h"
 | 
				
			||||||
 | 
					#include "audio.h"
 | 
				
			||||||
 | 
					#include "audio_stats.h"
 | 
				
			||||||
 | 
					#include "textcolor.h"
 | 
				
			||||||
 | 
					#include "ptt.h"
 | 
				
			||||||
 | 
					#include "demod.h"		/* for alevel_t & demod_get_audio_level() */
 | 
				
			||||||
 | 
					#include "audio_ptt.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct audio_s          *save_audio_config_p;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static unsigned __stdcall ptt_thread ( void *arg );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					HANDLE start_ptt_thread (struct audio_s *pa , int ch)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    save_audio_config_p = pa;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return (HANDLE)_beginthreadex (NULL, 0, ptt_thread, (void*)(long)ch, 0, NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unsigned __stdcall ptt_thread (void *arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    WAVEFORMATEX wf;
 | 
				
			||||||
 | 
					    HWAVEOUT hWaveOut;
 | 
				
			||||||
 | 
					    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 );
 | 
				
			||||||
 | 
					    int err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if( save_audio_config_p->adev[a].defined ) {
 | 
				
			||||||
 | 
					        wf.wFormatTag = WAVE_FORMAT_PCM;
 | 
				
			||||||
 | 
					        wf.nChannels = save_audio_config_p->adev[a].num_channels;
 | 
				
			||||||
 | 
					        wf.nSamplesPerSec = save_audio_config_p->adev[a].samples_per_sec;
 | 
				
			||||||
 | 
					        wf.wBitsPerSample = save_audio_config_p->adev[a].bits_per_sample;
 | 
				
			||||||
 | 
					        wf.nBlockAlign = ( wf.wBitsPerSample / 8 ) * wf.nChannels;
 | 
				
			||||||
 | 
					        wf.nAvgBytesPerSec = wf.nBlockAlign * wf.nSamplesPerSec;
 | 
				
			||||||
 | 
					        wf.cbSize = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          /*
 | 
				
			||||||
 | 
					          * Open the audio output device.
 | 
				
			||||||
 | 
					          * Soundcard is only possibility at this time.
 | 
				
			||||||
 | 
					          */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        err = waveOutOpen ( &hWaveOut, atoi( save_audio_config_p->adev[a].adevice_out ), &wf, (DWORD_PTR)NULL, 0, CALLBACK_NULL );
 | 
				
			||||||
 | 
					        if( err == MMSYSERR_NOERROR ) {
 | 
				
			||||||
 | 
					            WAVEHDR waveHeader;
 | 
				
			||||||
 | 
					            SHORT* pnData;
 | 
				
			||||||
 | 
					            SHORT sample;
 | 
				
			||||||
 | 
					            int nsamples = save_audio_config_p->adev[a].samples_per_sec / freq;
 | 
				
			||||||
 | 
					            int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if( save_audio_config_p->adev[a].num_channels == 1 ) {
 | 
				
			||||||
 | 
					                waveHeader.dwBufferLength = 1 * nsamples * sizeof( SHORT );
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else {
 | 
				
			||||||
 | 
					                waveHeader.dwBufferLength = 2 * nsamples * sizeof( SHORT );
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            waveHeader.lpData = malloc( waveHeader.dwBufferLength );
 | 
				
			||||||
 | 
					            waveHeader.dwUser = 0;
 | 
				
			||||||
 | 
					            waveHeader.dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP;
 | 
				
			||||||
 | 
					            waveHeader.dwLoops = 0xFFFF;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            pnData = (SHORT*)waveHeader.lpData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if( save_audio_config_p->adev[a].num_channels == 1 ) {
 | 
				
			||||||
 | 
					                for( i = 0; i < nsamples; i++ ) {
 | 
				
			||||||
 | 
					                    sample = (SHORT)( 32000.0 * sin( ( (double)i / (double)nsamples ) * 2.0 * M_PI ) );
 | 
				
			||||||
 | 
					                    pnData[i] = sample;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else {
 | 
				
			||||||
 | 
					                for( i = 0; i < nsamples; i++ ) {
 | 
				
			||||||
 | 
					                    sample = (SHORT)( 32000.0 * sin( ( (double)i / (double)nsamples ) * 2.0 * M_PI ) );
 | 
				
			||||||
 | 
					                    if( channel == ADEVFIRSTCHAN( a ) ) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        // Stereo, left channel.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        pnData[i*2 + 0] = sample;
 | 
				
			||||||
 | 
					                        pnData[i*2 + 1] = 0;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    else {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        // Stereo, right channel.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        pnData[i*2 + 0] = 0;
 | 
				
			||||||
 | 
					                        pnData[i*2 + 1] = sample;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            err = waveOutPrepareHeader ( hWaveOut, &waveHeader, sizeof( WAVEHDR ) );
 | 
				
			||||||
 | 
					            if( err == MMSYSERR_NOERROR ) {
 | 
				
			||||||
 | 
					                HANDLE handles[3];
 | 
				
			||||||
 | 
					                DWORD dwWait;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                handles[0] = save_audio_config_p->achan[ch].octrl[OCTYPE_PTT].ptt_start;
 | 
				
			||||||
 | 
					                handles[1] = save_audio_config_p->achan[ch].octrl[OCTYPE_PTT].ptt_stop;
 | 
				
			||||||
 | 
					                handles[2] = save_audio_config_p->achan[ch].octrl[OCTYPE_PTT].ptt_close;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                while( 1 )
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    dwWait = WaitForMultipleObjects ( 3, handles, FALSE, INFINITE );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    if( dwWait == WAIT_OBJECT_0 + 0 )
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        //
 | 
				
			||||||
 | 
					                        // ptt_set on
 | 
				
			||||||
 | 
					                        //
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        waveOutWrite ( hWaveOut, &waveHeader, sizeof( WAVEHDR ) );
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    else if( dwWait == WAIT_OBJECT_0 + 1 )
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        //
 | 
				
			||||||
 | 
					                        // ptt_set off
 | 
				
			||||||
 | 
					                        //
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        waveOutReset ( hWaveOut );
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    else if( dwWait == WAIT_OBJECT_0 + 2 )
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        //
 | 
				
			||||||
 | 
					                        // close
 | 
				
			||||||
 | 
					                        //
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        waveOutReset ( hWaveOut );
 | 
				
			||||||
 | 
					                        waveOutUnprepareHeader ( hWaveOut, &waveHeader, sizeof( WAVEHDR ) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            waveOutClose ( hWaveOut );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            free( waveHeader.lpData );
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										50
									
								
								config.c
								
								
								
								
							
							
						
						
									
										50
									
								
								config.c
								
								
								
								
							| 
						 | 
					@ -666,7 +666,9 @@ void config_init (char *fname, struct audio_s *p_audio_config,
 | 
				
			||||||
	    p_audio_config->achan[channel].octrl[ot].ptt_lpt_bit = 0;
 | 
						    p_audio_config->achan[channel].octrl[ot].ptt_lpt_bit = 0;
 | 
				
			||||||
	    p_audio_config->achan[channel].octrl[ot].ptt_invert = 0;
 | 
						    p_audio_config->achan[channel].octrl[ot].ptt_invert = 0;
 | 
				
			||||||
	    p_audio_config->achan[channel].octrl[ot].ptt_invert2 = 0;
 | 
						    p_audio_config->achan[channel].octrl[ot].ptt_invert2 = 0;
 | 
				
			||||||
	  }
 | 
					        p_audio_config->achan[channel].octrl[ot].ptt_channel = 0;
 | 
				
			||||||
 | 
					        p_audio_config->achan[channel].octrl[ot].ptt_frequency = PTT_FREQ_DEFAULT;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  p_audio_config->achan[channel].dwait = DEFAULT_DWAIT;				
 | 
						  p_audio_config->achan[channel].dwait = DEFAULT_DWAIT;				
 | 
				
			||||||
	  p_audio_config->achan[channel].slottime = DEFAULT_SLOTTIME;				
 | 
						  p_audio_config->achan[channel].slottime = DEFAULT_SLOTTIME;				
 | 
				
			||||||
| 
						 | 
					@ -1582,8 +1584,52 @@ void config_init (char *fname, struct audio_s *p_audio_config,
 | 
				
			||||||
	      dw_printf ("Config file line %d: %s with RIG is only available when hamlib support is enabled.\n", line, otname);
 | 
						      dw_printf ("Config file line %d: %s with RIG is only available when hamlib support is enabled.\n", line, otname);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
        else if (strcasecmp( t, "CHN") == 0) {
 | 
					        else if (strcasecmp( t, "CHANNEL") == 0) {
 | 
				
			||||||
 | 
					          t = split(NULL, 0);
 | 
				
			||||||
 | 
					          if (t == NULL) {
 | 
				
			||||||
 | 
					            text_color_set( DW_COLOR_ERROR );
 | 
				
			||||||
 | 
					            dw_printf ("Config file line %d: Missing channel number for %s.\n", line, otname);
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          int channel_ptt = atoi(t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          if (channel_ptt < 0 || channel_ptt >= MAX_CHANS) {
 | 
				
			||||||
 | 
					            text_color_set( DW_COLOR_ERROR );
 | 
				
			||||||
 | 
					            dw_printf ( "Config file line %d: Invalid PTT channel number for %s.\n", line, otname );
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          if (channel == channel_ptt) {
 | 
				
			||||||
 | 
					            text_color_set( DW_COLOR_ERROR );
 | 
				
			||||||
 | 
					            dw_printf ( "Config file line %d: PTT channel number must not be the same as the channel number itself.\n", line );
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          int freq_ptt = PTT_FREQ_DEFAULT;
 | 
				
			||||||
 | 
					          
 | 
				
			||||||
 | 
					          t = split(NULL, 0);
 | 
				
			||||||
 | 
					          if (t != NULL) {
 | 
				
			||||||
 | 
					            freq_ptt = atoi(t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (freq_ptt < PTT_FREQ_MIN || freq_ptt > PTT_FREQ_MAX) {
 | 
				
			||||||
 | 
					              text_color_set( DW_COLOR_ERROR );
 | 
				
			||||||
 | 
					              dw_printf ("Config file line %d: Invalid value %d for PTT frequency. Using default of %d.\n",
 | 
				
			||||||
 | 
					                  line, freq_ptt, PTT_FREQ_DEFAULT );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              freq_ptt = PTT_FREQ_DEFAULT;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          p_audio_config->achan[channel].octrl[ot].ptt_method = PTT_METHOD_AUDIO;
 | 
					          p_audio_config->achan[channel].octrl[ot].ptt_method = PTT_METHOD_AUDIO;
 | 
				
			||||||
 | 
					          p_audio_config->achan[channel].octrl[ot].ptt_channel = channel_ptt;
 | 
				
			||||||
 | 
					          p_audio_config->achan[channel].octrl[ot].ptt_frequency = freq_ptt;
 | 
				
			||||||
 | 
					#ifdef __WIN32__
 | 
				
			||||||
 | 
					          p_audio_config->achan[channel].octrl[ot].ptt_start = CreateEvent (NULL, FALSE, FALSE, NULL);
 | 
				
			||||||
 | 
					          p_audio_config->achan[channel].octrl[ot].ptt_stop = CreateEvent (NULL, FALSE, FALSE, NULL);
 | 
				
			||||||
 | 
					          p_audio_config->achan[channel].octrl[ot].ptt_close = CreateEvent (NULL, FALSE, FALSE, NULL);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else  {
 | 
					        else  {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,6 +38,14 @@
 | 
				
			||||||
#define MAX_RIGS MAX_CHANS
 | 
					#define MAX_RIGS MAX_CHANS
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * PTT frequency settings
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define PTT_FREQ_MIN        50
 | 
				
			||||||
 | 
					#define PTT_FREQ_MAX        20000
 | 
				
			||||||
 | 
					#define PTT_FREQ_DEFAULT    1000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Get audio device number for given channel.
 | 
					 * Get audio device number for given channel.
 | 
				
			||||||
 * and first channel for given device.
 | 
					 * and first channel for given device.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										60
									
								
								ptt.c
								
								
								
								
							
							
						
						
									
										60
									
								
								ptt.c
								
								
								
								
							| 
						 | 
					@ -126,6 +126,7 @@ typedef int HANDLE;
 | 
				
			||||||
#include "textcolor.h"
 | 
					#include "textcolor.h"
 | 
				
			||||||
#include "audio.h"
 | 
					#include "audio.h"
 | 
				
			||||||
#include "ptt.h"
 | 
					#include "ptt.h"
 | 
				
			||||||
 | 
					#include "audio_ptt.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if __WIN32__
 | 
					#if __WIN32__
 | 
				
			||||||
| 
						 | 
					@ -357,6 +358,13 @@ void ptt_init (struct audio_s *audio_config_p)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int ch;
 | 
						int ch;
 | 
				
			||||||
	HANDLE fd = INVALID_HANDLE_VALUE;
 | 
						HANDLE fd = INVALID_HANDLE_VALUE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if __WIN32__
 | 
				
			||||||
 | 
					    HANDLE audio_ptt_th[MAX_CHANS];
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					    pthread_t audio_ptt_tid[MAX_CHANS];
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if __WIN32__
 | 
					#if __WIN32__
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
	int using_gpio;
 | 
						int using_gpio;
 | 
				
			||||||
| 
						 | 
					@ -386,7 +394,7 @@ void ptt_init (struct audio_s *audio_config_p)
 | 
				
			||||||
	    if (ptt_debug_level >= 2) {
 | 
						    if (ptt_debug_level >= 2) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	      text_color_set(DW_COLOR_DEBUG);
 | 
						      text_color_set(DW_COLOR_DEBUG);
 | 
				
			||||||
              dw_printf ("ch=%d, %s method=%d, device=%s, line=%d, gpio=%d, lpt_bit=%d, invert=%d\n",
 | 
					              dw_printf ("ch=%d, %s method=%d, device=%s, line=%d, gpio=%d, lpt_bit=%d, invert=%d, channel=%d, freq=%d\n",
 | 
				
			||||||
		ch,
 | 
							ch,
 | 
				
			||||||
		otnames[ot],
 | 
							otnames[ot],
 | 
				
			||||||
		audio_config_p->achan[ch].octrl[ot].ptt_method, 
 | 
							audio_config_p->achan[ch].octrl[ot].ptt_method, 
 | 
				
			||||||
| 
						 | 
					@ -394,7 +402,9 @@ void ptt_init (struct audio_s *audio_config_p)
 | 
				
			||||||
		audio_config_p->achan[ch].octrl[ot].ptt_line,
 | 
							audio_config_p->achan[ch].octrl[ot].ptt_line,
 | 
				
			||||||
		audio_config_p->achan[ch].octrl[ot].ptt_gpio,
 | 
							audio_config_p->achan[ch].octrl[ot].ptt_gpio,
 | 
				
			||||||
		audio_config_p->achan[ch].octrl[ot].ptt_lpt_bit,
 | 
							audio_config_p->achan[ch].octrl[ot].ptt_lpt_bit,
 | 
				
			||||||
		audio_config_p->achan[ch].octrl[ot].ptt_invert);
 | 
							audio_config_p->achan[ch].octrl[ot].ptt_invert,
 | 
				
			||||||
 | 
					        audio_config_p->achan[ch].octrl[ot].ptt_channel,
 | 
				
			||||||
 | 
					        audio_config_p->achan[ch].octrl[ot].ptt_frequency );
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
	  }
 | 
						  }
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -501,6 +511,7 @@ void ptt_init (struct audio_s *audio_config_p)
 | 
				
			||||||
	        ptt_set (ot, ch, 0);
 | 
						        ptt_set (ot, ch, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	      }    /* if serial method. */
 | 
						      }    /* if serial method. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    }	 /* for each output type. */
 | 
						    }	 /* for each output type. */
 | 
				
			||||||
	  }    /* if channel valid. */
 | 
						  }    /* if channel valid. */
 | 
				
			||||||
	}    /* For each channel. */
 | 
						}    /* For each channel. */
 | 
				
			||||||
| 
						 | 
					@ -747,6 +758,35 @@ void ptt_init (struct audio_s *audio_config_p)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					    * Set up audio channel.
 | 
				
			||||||
 | 
					    */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (ch = 0; ch<MAX_CHANS; ch++) {
 | 
				
			||||||
 | 
					      if (audio_config_p->achan[ch].valid) {
 | 
				
			||||||
 | 
					        if (audio_config_p->achan[ch].octrl[OCTYPE_PTT].ptt_method == PTT_METHOD_AUDIO) {
 | 
				
			||||||
 | 
					#if __WIN32__
 | 
				
			||||||
 | 
					          audio_ptt_th[ch] = start_ptt_thread (audio_config_p, ch);
 | 
				
			||||||
 | 
					          if (audio_ptt_th[ch] == NULL) {
 | 
				
			||||||
 | 
					            text_color_set(DW_COLOR_ERROR);
 | 
				
			||||||
 | 
					            dw_printf ("Could not create audio_ptt thread on channel %d for PTT of channel %d.\n", 
 | 
				
			||||||
 | 
					                audio_config_p->achan[ch].octrl[OCTYPE_PTT].ptt_channel, ch);
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					          int e;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          e = pthread_create (&(ptt_tid[j]), NULL, ptt_thread, (void *)(long)ch);
 | 
				
			||||||
 | 
					          if (e != 0) {
 | 
				
			||||||
 | 
					            text_color_set(DW_COLOR_ERROR);
 | 
				
			||||||
 | 
					            dw_printf ("Could not create audio_ptt thread on channel %d for PTT of channel %d.\n",
 | 
				
			||||||
 | 
					                audio_config_p->achan[ch].octrl[OCTYPE_PTT].ptt_channel, ch );
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Why doesn't it transmit?  Probably forgot to specify PTT option. */
 | 
					/* Why doesn't it transmit?  Probably forgot to specify PTT option. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -968,7 +1008,21 @@ void ptt_set (int ot, int chan, int ptt_signal)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if( save_audio_config_p->achan[chan].octrl[ot].ptt_method == PTT_METHOD_AUDIO ) {
 | 
				
			||||||
 | 
					        if( ptt_signal ) {
 | 
				
			||||||
 | 
					#ifdef __WIN32__
 | 
				
			||||||
 | 
					            SetEvent( save_audio_config_p->achan[chan].octrl[ot].ptt_start );
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					#ifdef __WIN32__
 | 
				
			||||||
 | 
					            SetEvent( save_audio_config_p->achan[chan].octrl[ot].ptt_stop );
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
} /* end ptt_set */
 | 
					} /* end ptt_set */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*-------------------------------------------------------------------
 | 
					/*-------------------------------------------------------------------
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue