openbsd-ports/comms/gpsk31/patches/patch-src_server-main_C
2010-07-01 01:57:33 +00:00

538 lines
15 KiB
Plaintext

$OpenBSD: patch-src_server-main_C,v 1.2 2010/07/01 01:57:33 jakemsr Exp $
--- src/server-main.C.orig Wed Jun 30 17:19:24 2010
+++ src/server-main.C Wed Jun 30 17:35:40 2010
@@ -20,21 +20,14 @@
*/
-#include <sys/mman.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/un.h>
-#include <netinet/in.h>
-#include <sys/time.h>
#include <fcntl.h>
-#include <sys/soundcard.h>
#include <sys/ioctl.h>
+#include <poll.h>
#include "psk31-receiver.h"
#include "psk31-transmitter.h"
#include "psk31-fft.h"
@@ -56,13 +49,15 @@
#define RX 0
// receive / transmit state information
-int full_duplex;
+int full_duplex = 0;
int chans;
int size;
int bits;
-static char *audio_path="/dev/dsp";
+static char *audio_path=NULL;
static char *ptt_path=NULL;
-static int audiofd=-1, pttfd=-1;
+static int pttfd=-1;
+static struct sio_hdl *hdl;
+static struct sio_par par;
static int ptt_invert=0;
static int ctl_ptt(int onoff);
int scconfig[2]; /* [0]=8bit/16bit [1]=mono/stereo */
@@ -125,7 +120,16 @@ typedef struct
#define N_BUFFERS 6
static buffer_t buffers[N_BUFFERS];
+long long realpos, playpos;
+static void onmove(void *addr, int delta)
+{
+ struct sio_par *par = (struct sio_par *)addr;
+
+ realpos += delta * par->bps * par->pchan;
+}
+
+
static void init_buffer()
{
int i;
@@ -203,216 +207,177 @@ buffer_t *b = buffers+bufnr;
*/
int init_audio ()
{
- int val;
- int speed = 8000;
+ uint speed = 8000;
int frags;
+ int want_bits, want_chans, retval = 0;
pthread_mutex_lock(&mutex_fd); //get the mutex for soundcard fd
- if (audiofd > 2)
+ if (hdl != NULL)
{
- close (audiofd);
- usleep (50000); //strange
- audiofd = -1;
+ sio_close(hdl);
+ hdl = NULL;
}
/* Open the soundcard */
- if (audiofd < 0)
+ if (hdl == NULL)
{
if (trDir == RX)
{
- audiofd = open(audio_path, O_RDONLY|O_NONBLOCK);
+ /* audio_path */
+ hdl = sio_open(NULL, SIO_REC, 0);
}
else
{
- audiofd = open(audio_path, O_WRONLY|O_NONBLOCK);
+ hdl = sio_open(NULL, SIO_PLAY, 0);
}
}
- if (audiofd < 0)
+ if (hdl == NULL)
{
- fprintf (stderr, "init_audio: can't open %s\n", audio_path);
+ fprintf (stderr, "init_audio: can't open ");
+ if (audio_path == NULL)
+ fprintf (stderr, "default sndio device\n");
+ else
+ fprintf (stderr, "%s\n", audio_path);
return -1;
}
+ sio_initpar(&par);
+
/* check parameter to see if 8 or 16 bits was requested */
/* return 1 or 2 if set 8 or 16 bits format failed */
- switch (scconfig[0])
+ want_bits = scconfig[0];
+ switch (want_bits)
{
case 0: /* 8 bits requested */
- val=AFMT_U8;
- if (ioctl(audiofd, SNDCTL_DSP_SETFMT, &val) <0)
- {
- /* ioctl failed */
- fprintf (stderr, "init_audio: ioctl SETFMT 8 failed\n");
- return -1;
- }
-
- /* see if 8 bit worked */
- if (val == AFMT_U8)
- {
- /* we can use 8 bit */
- size = 1;
- bits = 8;
- // fprintf (stderr, "init_audio: trying 8 bit ");
- }
- else /* 8 bit failed */
- {
- fprintf (stderr, "init_audio: failed to set to 8 bits\n");
- return 1;
- }
+ par.bits = 8;
+ par.sig = 0;
break;
-
case 1: /* 16 bits requested */
- val=AFMT_S16_NE;
- if (ioctl(audiofd, SNDCTL_DSP_SETFMT, &val) <0)
- {
- /* ioctl failed */
- fprintf (stderr, "init_audio: ioctl SETFMT 16 failed\n");
- return -1;
- }
-
- /* see if 16 bit worked */
- if (val == AFMT_S16_NE)
- {
- /* we can use 16 bit */
- size = 2;
- bits = 16;
- // fprintf (stderr, "init_audio: trying 16 bit ");
- }
- else /* set 16 bit failed */
- {
- fprintf (stderr, "init_audio: failed to set to 16 bits\n");
- return 2;
- }
+ par.bits = 16;
+ par.sig = 1;
break;
-
- default: /* Invalid request */
- fprintf (stderr, "\ninit_audio: invalid 8 or 16 bit request\n");
+ default:
+ fprintf (stderr, "\ninit_audio: invalid bit-depth request\n");
return -1;
}
/* check parameter to see if MONO or STEREO was requested */
/* return 3 or 4 if set mono or stereo format failed */
+ want_chans = scconfig[1];
switch (scconfig[1])
{
case 0: /* mono requested */
- val=MONO;
- if( ioctl(audiofd, SNDCTL_DSP_STEREO, &val)<0 )
- {
- /* ioctl failed */
- fprintf (stderr,"\ninit_audio: ioctl failed - MONO\n");
- return -1;
- }
- /* see if mono worked */
- if (val == MONO)
- {
- /* we can use mono */
- fprintf (stderr, "mono format\n");
- chans = MONO;
- }
+ if (trDir == RX)
+ par.rchan = 1;
else
- {
- /* set mono failed */
- fprintf (stderr, "\ninit_audio: request for mono failed\n");
- return 3;
- }
+ par.pchan = 1;
break;
-
case 1: /* stereo request */
- val = STEREO;
- if( ioctl(audiofd, SNDCTL_DSP_STEREO, &val)<0 )
- {
- fprintf (stderr, "\ninit_audio: ioctl failed - STEREO\n");
- return -1;
- }
- /* see if stereo worked */
- if (val == STEREO)
- {
- /* we can use stereo */
- fprintf (stderr, "stereo format\n");
- size = size * 2;
- chans = STEREO;
- }
+ if (trDir == RX)
+ par.rchan = 2;
else
- {
- /* set stereo failed */
- fprintf (stderr, "\ninit_audio: request for stereo failed\n");
- return 4;
- }
+ par.pchan = 2;
break;
-
default:
- fprintf (stderr, "\ninit_audio: invalid mono or stereo request\n");
- return -1;
+ fprintf (stderr, "\ninit_audio: invalid mono or stereo request\n");
+ return -1;
}
- /* setup the rest */
- val = speed;
- if (ioctl(audiofd, SNDCTL_DSP_SPEED, &val) < 0)
+ if (want_bits == 0)
+ frags = 8;
+ else
+ frags = 10;
+
+ if (want_chans == 1)
+ frags++;
+
+ par.appbufsz = 1 << frags;
+
+ par.rate = speed;
+
+ if (!sio_setpar(hdl, &par) || !sio_getpar(hdl, &par))
{
- fprintf (stderr, "init_audio: ioctl SPEED failed\n");
+ fprintf (stderr, "init_audio: error setting parameters\n");
return -1;
}
- if (val == speed)
+ if (want_bits == 0 && (par.bits != 8 || par.sig != 0))
{
- fprintf (stderr,"init_audio: using %d sample rate\n", val);
+ fprintf (stderr, "init_audio: could not set 8-bit mode\n");
+ retval = 1;
}
- else
+ else if (want_bits == 1 && (par.bits != 16 || par.sig != 1))
{
- fprintf(stderr,"inexact sampling rate: "
- "request for %d resulted in %d\n",speed,val);
+ fprintf (stderr, "init_audio: could not set 16-bit mode\n");
+ retval = 2;
}
- if (bits == 8)
- frags = 0x00020008;
+ if (par.bits == 8 && par.sig == 0)
+ {
+ size = 1;
+ bits = 8;
+ }
+ else if (par.bits == 16 && par.sig == 1)
+ {
+ size = 2;
+ bits = 16;
+ }
else
- frags = 0x0002000A;
+ {
+ fprintf (stderr, "init_audio: could not get usable format\n");
+ return -1;
+ }
- if (chans == STEREO)
- frags++;
+ if (want_chans == 0 &&
+ ((trDir == RX && par.rchan != 1) || (trDir == TX && par.pchan != 1)))
+ {
+ fprintf (stderr, "\ninit_audio: request for mono failed\n");
+ retval = 3;
+ }
+ else if (want_chans == 1 &&
+ ((trDir == RX && par.rchan != 2) || (trDir == TX && par.pchan != 2)))
+ {
+ fprintf (stderr, "\ninit_audio: request for stereo failed\n");
+ retval = 4;
+ }
- val = frags;
- ioctl(audiofd, SNDCTL_DSP_SETFRAGMENT, &val);
+ if ((trDir == RX && par.rchan == 1) || (trDir == TX && par.pchan == 1))
+ {
+ fprintf (stderr, "mono format\n");
+ chans = MONO;
+ }
+ else if ((trDir == RX && par.rchan == 2) || (trDir == TX && par.pchan == 2))
+ {
+ fprintf (stderr, "stereo format\n");
+ size = size * 2;
+ chans = STEREO;
+ }
-/*****************************************************/
-#if 0
- audio_buf_info inInfo, outInfo;
- if (ioctl(audiofd, SNDCTL_DSP_GETISPACE, &inInfo))
- perror ("init_audio: SNDCTL_DSP_GETOSPACE");
- if (ioctl(audiofd, SNDCTL_DSP_GETOSPACE, &outInfo))
- perror ("init_audio: SNDCTL_DSP_GETOSPACE");
-
-printf ("In fragments=0x%08x fragstotal=0x%08x fragsize=0x%08x\n",
- inInfo.fragments, inInfo.fragstotal, inInfo.fragsize);
-printf ("Out fragments=0x%08x fragstotal=0x%08x fragsize=0x%08x\n",
- outInfo.fragments, outInfo.fragstotal, outInfo.fragsize);
-#endif
-/*****************************************************/
-
- // Check if the device is operating in full duplex mode
- if( ioctl(audiofd, SNDCTL_DSP_GETCAPS, &val)<0 )
- perror("Warning: GETCAPS on audio device failed");
+ if (abs(par.rate - speed) < speed * 1.03)
+ {
+ fprintf (stderr, "init_audio: using %d sample rate\n", speed);
+ }
else
- if(val&DSP_CAP_DUPLEX)
- full_duplex=1;
- fprintf(stderr,"init_audio: using %s duplex mode\n",
- full_duplex ? "full" : "half");
+ {
+ fprintf(stderr, "could not set sampling rate: "
+ "request for %d resulted in %d\n", speed, par.rate);
+ return -1;
+ }
-/*****************************************************/
-#if 0
- val = 0;
- if (ioctl(audiofd, SNDCTL_DSP_SETTRIGGER, &val) == -1)
- perror("ioctl: SNDCTL_DSP_SETTRIGGER");
- val = PCM_ENABLE_INPUT;
- if (ioctl(audiofd, SNDCTL_DSP_SETTRIGGER, &val) == -1)
- perror("ioctl: SNDCTL_DSP_SETTRIGGER");
-#endif
-/*****************************************************/
+ realpos = playpos = 0;
+ if (trDir == TX)
+ sio_onmove(hdl, onmove, &par);
+ if (!sio_start(hdl))
+ {
+ fprintf (stderr, "init_audio: could not start audio\n");
+ return -1;
+ }
+
// fprintf (stderr, "init_audio: size=%d\n", size);
pthread_mutex_unlock(&mutex_fd);
- return 0;
+ return retval;
}
@@ -461,10 +426,7 @@ static void *master_thr_func(void *dummy)
void master_handler(void)
{
int res;
- fd_set rset, wset, eset;
- struct timeval tm;
int dcd;
- static short odd;
buffers[COMM_RXCH].psk31rx->get_info(NULL,NULL,NULL,NULL,
NULL,&dcd,NULL,NULL);
@@ -487,13 +449,6 @@ void master_handler(void)
lastMode = trDir;
}
- FD_ZERO(&rset); FD_ZERO(&wset); FD_ZERO(&eset);
- FD_SET(audiofd, &rset);
- FD_SET(audiofd, &eset);
- if (trDir == TX)
- FD_SET(audiofd, &wset);
- tm.tv_sec=0; tm.tv_usec=50000; /* 50ms */
- res=select(audiofd+1, &rset, &wset, &eset, &tm);
/* In my older version I had the problem, that there exist
* sound drivers which do not support select correctly. So this
* code tries to read/write from/to the audiodevice without
@@ -502,61 +457,54 @@ void master_handler(void)
if (trDir == RX)
{
- short sample[2], save;
+ short buf[128];
+ int s = 0, todo;
+ char *p, *end;
- for (;;)
- {
- pthread_mutex_lock (&mutex_fd); // grab the mutex for the fd
- odd++;
- res = read(audiofd, &sample, size);
- if (res == 0)
- {
- break;
- }
- else if (res != size)
- {
- // fprintf(stderr,"%d %d\n",res,errno);
- if (errno == EINTR)
- {
- break;
- }
- if (errno == EAGAIN || errno == EBUSY)
- {
- break;
- }
- perror ("Audio read failed");
+ pthread_mutex_lock (&mutex_fd); // grab the mutex for the fd
+ p = (char *)buf;
+ todo = sizeof(buf);
+ while (todo > 0) {
+ res = sio_read(hdl, p, todo);
+ if (res == 0)
+ {
+ fprintf (stderr, "Audio read failed");
exit (1);
- }
- pthread_mutex_unlock (&mutex_fd); // release mutex for fd
+ }
+ todo -= res;
+ p += res;
+ }
+ pthread_mutex_unlock (&mutex_fd); // release mutex for fd
+ for (p = (char *)buf, end = p + sizeof(buf); p < end;)
+ {
/******* for S16_NE stereo *******/
if (chans == STEREO && bits == 16)
{
/* two signed 16 bits to one signed short */
- sample[0] = sample[0] | sample[1];
+ s = (((short *)p)[0] + ((short *)p)[1]) / 2;
+ p += 2 * sizeof(short);
}
/******* for S16_NE mono *******/
if (chans == MONO && bits == 16)
{
- /* nothing to do for this one */
+ s = ((short *)p)[0];
+ p += sizeof(short);
}
/******* for U8 stereo *******/
if (chans==STEREO && bits == 8)
{
- /* two unsigned 8 bit to a signed short */
- save = (((sample[0]>>8)&0xFF) - 128) * 128; //low
- sample[0] = ((sample[0]&0xFF) - 128) * 128; //high
- sample[0] = sample[0] | save; //mixed
+ s = 128 * (p[0] ^ 0x80) + (p[1] ^ 0x80);
+ p += 2;
}
/******* for U8 mono *******/
if (chans == MONO && bits == 8)
- {
- /* unsigned 8 bit to signed short */
- sample[0] = ((sample[0]&0xFF) - 128) * 128;
-
+ {
+ s = 256 * (p[0] ^ 0x80);
+ p++;
}
/*****************************/
@@ -569,7 +517,7 @@ void master_handler(void)
pthread_mutex_unlock(&mutex_rx);
continue;
}
- res = rx->process_rx_sample (sample[0]);
+ res = rx->process_rx_sample (s);
pthread_mutex_unlock(&mutex_rx);
if(res!=NO_CHAR)
{
@@ -597,13 +545,14 @@ void master_handler(void)
char buffer[128];
for(;;)
{
- res=read(audiofd, buffer, 128);
+ res=sio_read(hdl, buffer, 128);
if(res!=128) break;
}
}
pthread_mutex_lock (&mutex_fd);
pthread_mutex_lock(&mutex_tx);
+ psk31tx->set_audiofd(hdl);
res=psk31tx->processor();
pthread_mutex_unlock(&mutex_tx);
pthread_mutex_unlock (&mutex_fd);
@@ -742,7 +691,7 @@ int server_main(char *audio, char *ptt, char *datadir)
psk31fft->set_parameters(1024, 1024, psk31_fft::MODE_RXDATA);
buffers[COMM_RXCH].psk31rx = new psk31_receiver(psk31fft);
psk31tx = new psk31_transmitter();
- psk31tx->set_audiofd(audiofd);
+ psk31tx->set_audiofd(hdl);
#ifdef USE_PTHREAD