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.
 | ||||
|  | @ -191,4 +186,4 @@ unsigned __stdcall ptt_thread (void *arg) | |||
| 
 | ||||
|     return 0; | ||||
| } | ||||
| #endif | ||||
| #endif | ||||
|  |  | |||
							
								
								
									
										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