mirror of https://github.com/wb2osz/direwolf.git
				
				
				
			build under linux and start ALSA implementation
This commit is contained in:
		
							parent
							
								
									aa5176e7b4
								
							
						
					
					
						commit
						52bf2ff5bd
					
				| 
						 | 
				
			
			@ -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 \
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										147
									
								
								audio_ptt.c
								
								
								
								
							
							
						
						
									
										147
									
								
								audio_ptt.c
								
								
								
								
							| 
						 | 
				
			
			@ -2,6 +2,7 @@
 | 
			
		|||
//    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
 | 
			
		||||
| 
						 | 
				
			
			@ -18,3 +19,149 @@
 | 
			
		|||
//
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*------------------------------------------------------------------
 | 
			
		||||
 *
 | 
			
		||||
 * 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>
 | 
			
		||||
 | 
			
		||||
#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_sframes_t frames;
 | 
			
		||||
		  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 = save_audio_config_p->adev[a].samples_per_sec / 10;
 | 
			
		||||
		    int nBufferLength = save_audio_config_p->adev[a].num_channels * nSamples * sizeof(short);
 | 
			
		||||
		    int i;
 | 
			
		||||
 | 
			
		||||
		    pnData = (short*)malloc (nBufferLength);
 | 
			
		||||
 | 
			
		||||
		    if (save_audio_config_p->adev[a].num_channels == 1) {
 | 
			
		||||
			    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 ) );
 | 
			
		||||
			      pnData[i] = sample;
 | 
			
		||||
			    }
 | 
			
		||||
		    }
 | 
			
		||||
		    else {
 | 
			
		||||
			    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 ) );
 | 
			
		||||
			      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;
 | 
			
		||||
			      }
 | 
			
		||||
			    }
 | 
			
		||||
		    }       
 | 
			
		||||
		    
 | 
			
		||||
		    //
 | 
			
		||||
		    // ptt_set on
 | 
			
		||||
		    //
 | 
			
		||||
 | 
			
		||||
		    for (i=0; i<50; i++) {
 | 
			
		||||
			    frames = snd_pcm_writei(handle, pnData, nSamples);
 | 
			
		||||
		    }
 | 
			
		||||
 | 
			
		||||
		    //
 | 
			
		||||
		    // ptt_set off
 | 
			
		||||
		    //
 | 
			
		||||
 | 
			
		||||
		    //
 | 
			
		||||
		    // close
 | 
			
		||||
		    //
 | 
			
		||||
 | 
			
		||||
		    free (pnData);
 | 
			
		||||
		  }
 | 
			
		||||
 | 
			
		||||
		  snd_pcm_close(handle);
 | 
			
		||||
	  }
 | 
			
		||||
#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 != -1) {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -96,33 +96,28 @@ unsigned __stdcall ptt_thread (void *arg)
 | 
			
		|||
        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;
 | 
			
		||||
            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.dwBufferLength = save_audio_config_p->adev[a].num_channels * nSamples * sizeof( short );
 | 
			
		||||
            waveHeader.lpData = malloc( waveHeader.dwBufferLength );
 | 
			
		||||
            waveHeader.dwUser = 0;
 | 
			
		||||
            waveHeader.dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP;
 | 
			
		||||
            waveHeader.dwLoops = 0xFFFF;
 | 
			
		||||
 | 
			
		||||
            pnData = (SHORT*)waveHeader.lpData;
 | 
			
		||||
            pnData = (short*)waveHeader.lpData;
 | 
			
		||||
 | 
			
		||||
            if( save_audio_config_p->adev[a].num_channels == 1 ) {
 | 
			
		||||
                for( i = 0; i < nsamples; i++ ) {
 | 
			
		||||
                    sample = (SHORT)( (double)SHRT_MAX * sin( ( (double)i / (double)nsamples ) * 2.0 * M_PI ) );
 | 
			
		||||
                for( i = 0; i < nSamples; i++ ) {
 | 
			
		||||
                    sample = (short)( (double)SHRT_MAX * sin( ( (double)i / (double)nSamples ) * 2.0 * M_PI ) );
 | 
			
		||||
                    pnData[i] = sample;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                for( i = 0; i < nsamples; i++ ) {
 | 
			
		||||
                    sample = (SHORT)( (double)SHRT_MAX * sin( ( (double)i / (double)nsamples ) * 2.0 * M_PI ) );
 | 
			
		||||
                for( i = 0; i < nSamples; i++ ) {
 | 
			
		||||
                    sample = (short)( (double)SHRT_MAX * sin( ( (double)i / (double)nSamples ) * 2.0 * M_PI ) );
 | 
			
		||||
                    if( channel == ADEVFIRSTCHAN( a ) ) {
 | 
			
		||||
 | 
			
		||||
                        // Stereo, left channel.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										6
									
								
								ptt.c
								
								
								
								
							
							
						
						
									
										6
									
								
								ptt.c
								
								
								
								
							| 
						 | 
				
			
			@ -774,10 +774,8 @@ void ptt_init (struct audio_s *audio_config_p)
 | 
			
		|||
            return;
 | 
			
		||||
          }
 | 
			
		||||
#else
 | 
			
		||||
          int e;
 | 
			
		||||
 | 
			
		||||
          e = pthread_create (&(ptt_tid[j]), NULL, ptt_thread, (void *)(long)ch);
 | 
			
		||||
          if (e != 0) {
 | 
			
		||||
	  audio_ptt_tid[ch] = start_ptt_thread (audio_config_p, ch);
 | 
			
		||||
          if (audio_ptt_tid[ch] == 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 );
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue