Update the list of Fortran LUs.

Remove several unused files.
Replace use of rfile2 with fortran I/O using access='stream'.


git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/map65@604 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
Joe Taylor 2007-12-27 18:11:51 +00:00
parent 08e095252a
commit 7bd9e32f04
7 changed files with 11 additions and 900 deletions

View File

@ -34,8 +34,11 @@ C NB: may want to smooth the Tsky map to 10 degrees or so.
read(13) nsky
close(13)
#else
call rfile2(fname,nsky,129600,nr)
if(nr.ne.129600) go to 10
open(13,file=fname,status='old',access='stream',err=10)
read(13) nsky
close(13)
! call rfile2(fname,nsky,129600,nr)
! if(nr.ne.129600) go to 10
#endif
ltsky=.true.
first=.false.

View File

@ -1,13 +1,13 @@
! Fortran logical units used in WSJT6
!
! 10 wave files read from disk
! 10
! 11 decoded.txt
! 12 decoded.ave
! 13 tsky.dat
! 14 azel.dat
! 15
! 16 c:/wsjt.reg
! 17 wave files written to disk
! 16
! 17 saved *.tf2 files
! 18 test file to be transmitted (wsjtgen.f90)
! 19 messages.txt
! 20 bandmap.txt
@ -18,7 +18,7 @@
! 25 meas25.dat
! 26 tmp26.txt
! 27 dphi.txt
! 28 saved *.tf2 files
! 28
! 29 debug.txt
!------------------------------------------------ ftn_init
subroutine ftn_init

View File

@ -1,4 +1,4 @@
#---------------------------------------------------------------------- MAP65
#--------------------------------------------------------------------- MAP65
# $Date$ $Revision$
#
from Tkinter import *

View File

@ -91,6 +91,7 @@ subroutine recvpkt(iarg)
rxnoise=10.0*log10(sqave) - 48.0
kxp=k
! This may be a bad idea, because of non-reentrant Fortran I/O?
if(mode.eq.'Measur') then
npkt=npkt+1
if(npkt.ge.551) then

View File

@ -1,568 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <alsa/asoundlib.h>
#include <inttypes.h>
#include <time.h>
#include <sys/time.h>
#include "fivehz.h"
#if 1
#define ALSA_LOG
#endif
#if 0
#define ALSA_LOG_BUFFERS
#endif
#if 0
#define ALSA_PLAYBACK_LOG
#define ALSA_CAPTURE_LOG
#endif
#define BUFFER_TIME 2000*1000
typedef struct alsa_driver_s {
snd_pcm_t *audio_fd;
int capabilities;
int open_mode;
int has_pause_resume;
int is_paused;
uint32_t output_sample_rate, input_sample_rate;
double sample_rate_factor;
uint32_t num_channels;
uint32_t bits_per_sample;
uint32_t bytes_per_frame;
uint32_t bytes_in_buffer; /* number of bytes writen to audio hardware */
int16_t *app_buffer_y1;
int16_t *app_buffer_y2;
int *app_buffer_offset;
int app_buffer_length;
double *Tsec;
double *tbuf;
int *ibuf;
int *ndsec;
int *tx_ok;
int tx_starting;
int tx_offset;
int *tr_period;
int *nwave;
int *nmode;
int *transmitting;
snd_pcm_uframes_t buffer_size;
snd_pcm_uframes_t period_size;
int32_t mmap;
} alsa_driver_t;
alsa_driver_t alsa_driver_playback;
alsa_driver_t alsa_driver_capture;
void *alsa_capture_buffers[2];
void *alsa_playback_buffers[2];
static snd_output_t *jcd_out;
/*
* open the audio device for writing to
*/
static int ao_alsa_open(alsa_driver_t *this_gen, int32_t *input_rate, snd_pcm_stream_t direction ) {
alsa_driver_t *this = (alsa_driver_t *) this_gen;
char *pcm_device;
snd_pcm_hw_params_t *params;
snd_pcm_sw_params_t *swparams;
snd_pcm_access_mask_t *mask;
snd_pcm_uframes_t period_size_min;
snd_pcm_uframes_t period_size_max;
snd_pcm_uframes_t buffer_size_min;
snd_pcm_uframes_t buffer_size_max;
snd_pcm_format_t format;
uint32_t buffer_time=BUFFER_TIME;
snd_pcm_uframes_t buffer_time_to_size;
int err, dir;
int open_mode=1; /* NONBLOCK */
/* int open_mode=0; BLOCK */
uint32_t rate=*input_rate;
this->input_sample_rate=*input_rate;
snd_pcm_hw_params_alloca(&params);
snd_pcm_sw_params_alloca(&swparams);
err = snd_output_stdio_attach(&jcd_out, stdout, 0);
this->num_channels = 2;
if (direction == SND_PCM_STREAM_PLAYBACK) {
pcm_device="plug:front";
} else {
pcm_device="default";
}
#ifdef ALSA_LOG
printf("audio_alsa_out: Audio Device name = %s\n",pcm_device);
printf("audio_alsa_out: Number of channels = %d\n",this->num_channels);
#endif
if (this->audio_fd) {
printf("audio_alsa_out:Already open...WHY!");
snd_pcm_close (this->audio_fd);
this->audio_fd = NULL;
}
this->bytes_in_buffer = 0;
/*
* open audio device
*/
err=snd_pcm_open(&this->audio_fd, pcm_device, direction, open_mode);
if(err <0 ) {
printf ("audio_alsa_out: snd_pcm_open() of %s failed: %s\n", pcm_device, snd_strerror(err));
printf ("audio_alsa_out: >>> check if another program already uses PCM <<<\n");
return 0;
}
/* printf ("audio_alsa_out: snd_pcm_open() opened %s\n", pcm_device); */
/* We wanted non blocking open but now put it back to normal */
//snd_pcm_nonblock(this->audio_fd, 0);
snd_pcm_nonblock(this->audio_fd, 1);
/*
* configure audio device
*/
err = snd_pcm_hw_params_any(this->audio_fd, params);
if (err < 0) {
printf ("audio_alsa_out: broken configuration for this PCM: no configurations available: %s\n",
snd_strerror(err));
goto close;
}
/* set interleaved access */
if (this->mmap != 0) {
mask = alloca(snd_pcm_access_mask_sizeof());
snd_pcm_access_mask_none(mask);
snd_pcm_access_mask_set(mask, SND_PCM_ACCESS_MMAP_INTERLEAVED);
snd_pcm_access_mask_set(mask, SND_PCM_ACCESS_MMAP_NONINTERLEAVED);
snd_pcm_access_mask_set(mask, SND_PCM_ACCESS_MMAP_COMPLEX);
err = snd_pcm_hw_params_set_access_mask(this->audio_fd, params, mask);
if (err < 0) {
printf ( "audio_alsa_out: mmap not availiable, falling back to compatiblity mode\n");
this->mmap=0;
err = snd_pcm_hw_params_set_access(this->audio_fd, params,
SND_PCM_ACCESS_RW_NONINTERLEAVED);
}
} else {
err = snd_pcm_hw_params_set_access(this->audio_fd, params,
SND_PCM_ACCESS_RW_NONINTERLEAVED);
}
if (err < 0) {
printf ( "audio_alsa_out: access type not available: %s\n", snd_strerror(err));
goto close;
}
/* set the sample format S16 */
/* ALSA automatically appends _LE or _BE depending on the CPU */
format = SND_PCM_FORMAT_S16;
err = snd_pcm_hw_params_set_format(this->audio_fd, params, format );
if (err < 0) {
printf ( "audio_alsa_out: sample format non available: %s\n", snd_strerror(err));
goto close;
}
/* set the number of channels */
err = snd_pcm_hw_params_set_channels(this->audio_fd, params, this->num_channels);
if (err < 0) {
printf ( "audio_alsa_out: Cannot set number of channels to %d (err=%d:%s)\n",
this->num_channels, err, snd_strerror(err));
goto close;
}
#if SND_LIB_VERSION >= 0x010009
/* Restrict a configuration space to contain only real hardware rates */
err = snd_pcm_hw_params_set_rate_resample(this->audio_fd, params, 0);
#endif
/* set the stream rate [Hz] */
dir=0;
err = snd_pcm_hw_params_set_rate_near(this->audio_fd, params, &rate, &dir);
if (err < 0) {
printf ( "audio_alsa_out: rate not available: %s\n", snd_strerror(err));
goto close;
}
this->output_sample_rate = (uint32_t)rate;
if (this->input_sample_rate != this->output_sample_rate) {
printf ( "audio_alsa_out: audio rate : %d requested, %d provided by device/sec\n",
this->input_sample_rate, this->output_sample_rate);
}
buffer_time_to_size = ( (uint64_t)buffer_time * rate) / 1000000;
err = snd_pcm_hw_params_get_buffer_size_min(params, &buffer_size_min);
err = snd_pcm_hw_params_get_buffer_size_max(params, &buffer_size_max);
dir=0;
err = snd_pcm_hw_params_get_period_size_min(params, &period_size_min,&dir);
dir=0;
err = snd_pcm_hw_params_get_period_size_max(params, &period_size_max,&dir);
#ifdef ALSA_LOG_BUFFERS
printf("Buffer size range from %lu to %lu\n",buffer_size_min, buffer_size_max);
printf("Period size range from %lu to %lu\n",period_size_min, period_size_max);
printf("Buffer time size %lu\n",buffer_time_to_size);
#endif
this->buffer_size = buffer_time_to_size;
if (buffer_size_max < this->buffer_size)
this->buffer_size = buffer_size_max;
if (buffer_size_min > this->buffer_size)
this->buffer_size = buffer_size_min;
this->period_size = this->buffer_size/8;
if (this->period_size > 2048)
this->period_size = 2048;
this->buffer_size = this->period_size*8;
#ifdef ALSA_LOG_BUFFERS
printf("To choose buffer_size = %ld\n",this->buffer_size);
printf("To choose period_size = %ld\n",this->period_size);
#endif
#if 0
/* Set period to buffer size ratios at 8 periods to 1 buffer */
dir=-1;
periods=8;
err = snd_pcm_hw_params_set_periods_near(this->audio_fd, params, &periods ,&dir);
if (err < 0) {
xprintf (this->class->xine, XINE_VERBOSITY_DEBUG,
"audio_alsa_out: unable to set any periods: %s\n", snd_strerror(err));
goto close;
}
/* set the ring-buffer time [us] (large enough for x us|y samples ...) */
dir=0;
err = snd_pcm_hw_params_set_buffer_time_near(this->audio_fd, params, &buffer_time, &dir);
if (err < 0) {
xprintf (this->class->xine, XINE_VERBOSITY_DEBUG,
"audio_alsa_out: buffer time not available: %s\n", snd_strerror(err));
goto close;
}
#endif
#if 1
/* set the period time [us] (interrupt every x us|y samples ...) */
dir=0;
err = snd_pcm_hw_params_set_period_size_near(this->audio_fd, params, &(this->period_size), &dir);
if (err < 0) {
printf ( "audio_alsa_out: period time not available: %s\n", snd_strerror(err));
goto close;
}
#endif
dir=0;
err = snd_pcm_hw_params_get_period_size(params, &(this->period_size), &dir);
dir=0;
err = snd_pcm_hw_params_set_buffer_size_near(this->audio_fd, params, &(this->buffer_size));
if (err < 0) {
printf ( "audio_alsa_out: buffer time not available: %s\n", snd_strerror(err));
goto close;
}
err = snd_pcm_hw_params_get_buffer_size(params, &(this->buffer_size));
#ifdef ALSA_LOG_BUFFERS
printf("was set period_size = %ld\n",this->period_size);
printf("was set buffer_size = %ld\n",this->buffer_size);
#endif
if (2*this->period_size > this->buffer_size) {
printf ( "audio_alsa_out: buffer to small, could not use\n");
goto close;
}
/* write the parameters to device */
err = snd_pcm_hw_params(this->audio_fd, params);
if (err < 0) {
printf ( "audio_alsa_out: pcm hw_params failed: %s\n", snd_strerror(err));
goto close;
}
/* Check for pause/resume support */
this->has_pause_resume = ( snd_pcm_hw_params_can_pause (params)
&& snd_pcm_hw_params_can_resume (params) );
// printf( "audio_alsa_out:open pause_resume=%d\n", this->has_pause_resume);
this->sample_rate_factor = (double) this->output_sample_rate / (double) this->input_sample_rate;
this->bytes_per_frame = snd_pcm_frames_to_bytes (this->audio_fd, 1);
/*
* audio buffer size handling
*/
/* Copy current parameters into swparams */
err = snd_pcm_sw_params_current(this->audio_fd, swparams);
if (err < 0) {
printf ( "audio_alsa_out: Unable to determine current swparams: %s\n", snd_strerror(err));
goto close;
}
/* align all transfers to 1 sample */
err = snd_pcm_sw_params_set_xfer_align(this->audio_fd, swparams, 1);
if (err < 0) {
printf ( "audio_alsa_out: Unable to set transfer alignment: %s\n", snd_strerror(err));
goto close;
}
/* allow the transfer when at least period_size samples can be processed */
err = snd_pcm_sw_params_set_avail_min(this->audio_fd, swparams, this->period_size);
if (err < 0) {
printf ( "audio_alsa_out: Unable to set available min: %s\n", snd_strerror(err));
goto close;
}
if (direction == SND_PCM_STREAM_PLAYBACK) {
/* start the transfer when the buffer contains at least period_size samples */
err = snd_pcm_sw_params_set_start_threshold(this->audio_fd, swparams, this->buffer_size);
} else {
err = snd_pcm_sw_params_set_start_threshold(this->audio_fd, swparams, -1);
}
if (err < 0) {
printf ( "audio_alsa_out: Unable to set start threshold: %s\n", snd_strerror(err));
goto close;
}
if (direction == SND_PCM_STREAM_PLAYBACK) {
/* never stop the transfer, even on xruns */
err = snd_pcm_sw_params_set_stop_threshold(this->audio_fd, swparams, this->buffer_size);
} else {
err = snd_pcm_sw_params_set_stop_threshold(this->audio_fd, swparams, this->buffer_size);
}
if (err < 0) {
printf ( "audio_alsa_out: Unable to set stop threshold: %s\n", snd_strerror(err));
goto close;
}
/* Install swparams into current parameters */
err = snd_pcm_sw_params(this->audio_fd, swparams);
if (err < 0) {
printf ( "audio_alsa_out: Unable to set swparams: %s\n", snd_strerror(err));
goto close;
}
#ifdef ALSA_LOG
snd_pcm_dump_setup(this->audio_fd, jcd_out);
snd_pcm_sw_params_dump(swparams, jcd_out);
#endif
return this->output_sample_rate;
close:
snd_pcm_close (this->audio_fd);
this->audio_fd=NULL;
return 0;
}
int16_t zero_buffer[65536];
int playback_callback(alsa_driver_t *alsa_driver_playback) {
alsa_driver_t *this = alsa_driver_playback;
int result;
struct timeval tv;
double stime;
int nsec;
int i,n;
static int ic;
snd_pcm_sframes_t delay;
static short int n2;
int16_t b0[2048];
// printf("playback callback\n");
snd_pcm_delay(this->audio_fd, &delay);
gettimeofday(&tv, NULL);
stime = (double) tv.tv_sec + ((double)tv.tv_usec / 1000000.0) +
*(this->ndsec) * 0.1;
// stime = stime + ((double)delay / (double)(this->output_sample_rate));
*(this->Tsec) = stime;
//printf("PLAY:TIME, %lf, %ld, %ld, %d\n", stime, delay, this->output_sample_rate, *this->ndsec);
if(!(this->tx_starting) && (*(this->tx_ok)) ) {
nsec = (int)stime;
n = nsec / *(this->tr_period);
ic = (int)(stime - *(this->tr_period) * n) * this->output_sample_rate;
ic = ic % *(this->nwave);
this->tx_offset = ic;
}
this->tx_starting = *(this->tx_ok);
*(this->transmitting) = *(this->tx_ok);
if(*(this->tx_ok)) {
/*
alsa_playback_buffers[0] = this->app_buffer_y1 + this->tx_offset;
alsa_playback_buffers[1] = this->app_buffer_y1 + this->tx_offset;
*/
alsa_playback_buffers[0] = b0;
alsa_playback_buffers[1] = b0;
for(i=0; i<this->period_size; i++) {
n2=this->app_buffer_y1[ic];
addnoise_(&n2);
b0[i]=n2;
ic++;
if(ic>=*this->nwave) {
if(*this->nmode==2) {
*this->tx_ok=0;
ic--;
}
else
ic = ic % *this->nwave; //Wrap buffer pointer
}
}
} else {
alsa_playback_buffers[0] = zero_buffer;
alsa_playback_buffers[1] = zero_buffer;
}
result = snd_pcm_writen(this->audio_fd, alsa_playback_buffers, this->period_size);
this->tx_offset += this->period_size;
if (result != this->period_size) {
printf("Playback write failed. Expected %lu samples, sent only %d\n", this->period_size, result);
#ifdef ALSA_PLAYBACK_LOG
snd_pcm_status_t *pcm_stat;
snd_pcm_status_alloca(&pcm_stat);
snd_pcm_status(this->audio_fd, pcm_stat);
snd_pcm_status_dump(pcm_stat, jcd_out);
#endif
}
fivehztx_(); //Call fortran routine
return result;
}
int capture_callback(alsa_driver_t *alsa_driver_capture) {
alsa_driver_t *this = alsa_driver_capture;
int result;
struct timeval tv;
double stime;
int ib;
snd_pcm_sframes_t delay;
#ifdef ALSA_CAPTURE_LOG
printf("capture callback %d samples\n", this->period_size);
#endif
#ifdef ALSA_CAPTURE_LOG
snd_pcm_status_t *pcm_stat;
snd_pcm_status_alloca(&pcm_stat);
snd_pcm_status(this->audio_fd, pcm_stat);
snd_pcm_status_dump(pcm_stat, jcd_out);
#endif
snd_pcm_delay(this->audio_fd, &delay);
gettimeofday(&tv, NULL);
stime = (double) tv.tv_sec + ((double)tv.tv_usec / 1000000.0) +
*(this->ndsec) * 0.1;
// stime = stime - ((double)delay / (double)(this->output_sample_rate));
*(this->Tsec) = stime;
ib=*(this->ibuf);
this->tbuf[ib] = stime;
//printf("CAP:TIME, %d, %lf, %ld, %ld, %d\n",ib, stime, delay, this->output_sample_rate, *this->ndsec);
ib++;
if(ib>=1024)
ib = 0;
*(this->ibuf) = ib;
alsa_capture_buffers[0]=this->app_buffer_y1 + *(this->app_buffer_offset);
alsa_capture_buffers[1]=this->app_buffer_y2 + *(this->app_buffer_offset);
result = snd_pcm_readn(this->audio_fd, alsa_capture_buffers, this->period_size);
*(this->app_buffer_offset) += this->period_size;
if ( *(this->app_buffer_offset) >= this->app_buffer_length )
*(this->app_buffer_offset)=0; /* FIXME: implement proper wrapping */
#ifdef ALSA_CAPTURE_LOG
printf("result=%d\n",result);
snd_pcm_status(this->audio_fd, pcm_stat);
snd_pcm_status_dump(pcm_stat, jcd_out);
#endif
fivehz_(); //Call fortran routine
return result;
}
int playback_xrun(alsa_driver_t *alsa_driver_playback) {
alsa_driver_t *this = alsa_driver_playback;
snd_pcm_status_t *pcm_stat;
snd_pcm_status_alloca(&pcm_stat);
printf("playback xrun\n");
snd_pcm_status(this->audio_fd, pcm_stat);
snd_pcm_status_dump(pcm_stat, jcd_out);
snd_pcm_prepare(this->audio_fd);
return 0;
}
int capture_xrun(alsa_driver_t *alsa_driver_capture) {
alsa_driver_t *this = alsa_driver_capture;
snd_pcm_status_t *pcm_stat;
snd_pcm_status_alloca(&pcm_stat);
printf("capture xrun\n");
snd_pcm_status(this->audio_fd, pcm_stat);
snd_pcm_status_dump(pcm_stat, jcd_out);
return 0;
}
void ao_alsa_loop(void *iarg) {
int playback_nfds;
int capture_nfds;
struct pollfd *pfd;
int nfds;
int capture_index;
unsigned short playback_revents;
unsigned short capture_revents;
playback_nfds = snd_pcm_poll_descriptors_count (
alsa_driver_playback.audio_fd);
capture_nfds = snd_pcm_poll_descriptors_count (
alsa_driver_capture.audio_fd);
pfd = (struct pollfd *) malloc (sizeof (struct pollfd) *
(playback_nfds + capture_nfds));
nfds=0;
snd_pcm_poll_descriptors (alsa_driver_playback.audio_fd,
&pfd[0],
playback_nfds);
nfds += playback_nfds;
snd_pcm_poll_descriptors (alsa_driver_capture.audio_fd,
&pfd[nfds],
capture_nfds);
capture_index = nfds;
nfds += capture_nfds;
while(1) {
if (poll (pfd, nfds, 200000) < 0) {
printf("poll failed\n");
continue;
}
snd_pcm_poll_descriptors_revents(alsa_driver_playback.audio_fd, &pfd[0], playback_nfds, &playback_revents);
snd_pcm_poll_descriptors_revents(alsa_driver_capture.audio_fd, &pfd[capture_index], capture_nfds, &capture_revents);
//if ((playback_revents & POLLERR) || ((capture_revents) & POLLERR)) {
if (((capture_revents) & POLLERR)) {
printf("pollerr\n");
capture_xrun(&alsa_driver_capture);
return;
}
if (((playback_revents) & POLLERR)) {
printf("pollerr\n");
playback_xrun(&alsa_driver_capture);
return;
}
if (playback_revents & POLLOUT) {
playback_callback(&alsa_driver_playback);
}
if (capture_revents & POLLIN) {
capture_callback(&alsa_driver_capture);
}
}
return;
}
void decode1_(void *iarg);
int start_threads_(int *ndevin, int *ndevout, short y1[], short y2[],
int *nbuflen, int *iwrite, short iwave[],
int *nwave, int *nfsample, int *nsamperbuf,
int *TRPeriod, int *TxOK, int *ndebug,
int *Transmitting, double *Tsec, int *ngo, int *nmode,
double tbuf[], int *ibuf, int *ndsec)
{
pthread_t thread1,thread2;
int iret1,iret2;
int iarg1 = 1;
//int32_t rate=11025;
int32_t rate=*nfsample;
alsa_driver_capture.app_buffer_y1 = y1;
alsa_driver_capture.app_buffer_y2 = y2;
alsa_driver_capture.app_buffer_offset = iwrite;
alsa_driver_capture.app_buffer_length = *nbuflen;
alsa_driver_capture.Tsec = Tsec;
alsa_driver_capture.tbuf = tbuf;
alsa_driver_capture.ibuf = ibuf;
alsa_driver_capture.ndsec = ndsec;
alsa_driver_playback.Tsec = Tsec;
alsa_driver_playback.app_buffer_y1 = iwave;
alsa_driver_playback.tx_ok = TxOK;
alsa_driver_playback.tr_period = TRPeriod;
alsa_driver_playback.nwave = nwave;
alsa_driver_playback.nmode = nmode;
alsa_driver_playback.transmitting = Transmitting;
alsa_driver_playback.ndsec = ndsec;
// printf("start_threads: creating thread for decode1\n");
iret1 = pthread_create(&thread1,NULL,(void*)&decode1_,&iarg1);
/* Open audio card. */
printf("Using ALSA sound.\n");
ao_alsa_open(&alsa_driver_playback, &rate, SND_PCM_STREAM_PLAYBACK);
ao_alsa_open(&alsa_driver_capture, &rate, SND_PCM_STREAM_CAPTURE);
/*
* Start audio io thread
*/
iret2 = pthread_create(&thread2, NULL, (void *)&ao_alsa_loop, NULL);
snd_pcm_prepare(alsa_driver_capture.audio_fd);
snd_pcm_start(alsa_driver_capture.audio_fd);
snd_pcm_prepare(alsa_driver_playback.audio_fd);
//snd_pcm_start(alsa_driver_playback.audio_fd);
return 0;
}

View File

@ -1,306 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <inttypes.h>
#include <time.h>
#include <sys/time.h>
#include <fcntl.h>
#include <sys/soundcard.h>
#include <string.h>
#define AUDIOBUFSIZE 4096
#define FRAMESPERBUFFER 1024
#define TIMEOUT 1000L /* select time out for audio device */
/* XXX probably safer to use a local buffer due to the wsjt threaded nature. */
static char rcv_buf[AUDIOBUFSIZE];
static char tx_buf[AUDIOBUFSIZE];
#define MAXDSPNAME 16
extern void decode1_(int *iarg);
void oss_loop(int *iarg);
/*
* local state data referencing some gcom common fortran variables as well
*/
static struct audio_data {
int fd_in; /* Audio fd in; used only locally in this function */
int fd_out; /* Audio fd out; used only locally in this function */
double *Tsec; /* Present time SoundIn,SoundOut */
double *tbuf; /* Tsec at time of input callback SoundIn */
int *iwrite; /* Write pointer to Rx ring buffer SoundIn */
int *ibuf; /* Most recent input buffer# SoundIn */
int *TxOK; /* OK to transmit? SoundIn */
int *ndebug; /* Write debugging info? GUI */
int *ndsec; /* Dsec in units of 0.1 s GUI */
int *Transmitting; /* Actually transmitting? SoundOut */
int *nwave; /* Number of samples in iwave SoundIn */
int *nmode; /* Which WSJT mode? GUI */
int *trperiod; /* Tx or Rx period in seconds GUI */
int nbuflen;
int nfs;
int16_t *y1; /* Ring buffer for audio channel 0 SoundIn */
int16_t *y2; /* Ring buffer for audio channel 1 SoundIn */
short *iwave;
}data;
/*
* start_threads()
* inputs - ndevin device number for input
* - ndevout device number for output
* - y1 short int array for channel 0
* - y2 short int array for channel 1
* - nmax
* - iwrite
* - iwave
* - nwave
* - rate
* - NSPB
* - TRPeriod
* - TxOK
* - ndebug debug output or not?
* - Transmitting
* - Tsec
* - ngo
* - nmode
* - tbuf
* - ibuf
* - ndsec
* output - ?
* side effects - Called from audio_init.f90 to start audio decode and
* OSS thread.
*/
int
start_threads_(int *ndevin, int *ndevout, short y1[], short y2[],
int *nbuflen, int *iwrite, short iwave[],
int *nwave, int *nfsample, int *nsamperbuf,
int *TRPeriod, int *TxOK, int *ndebug,
int *Transmitting, double *Tsec, int *ngo, int *nmode,
double tbuf[], int *ibuf, int *ndsec,
char *PttPort, char *devin_name, char *devout_name)
{
pthread_t thread1,thread2;
int iret1,iret2;
int iarg1 = 1,iarg2 = 2;
int32_t rate=*nfsample;
int samplesize;
int format;
int channels;
double dnfs;
int i;
char *p;
/* Remove space if present */
p = strchr(devin_name, ' ');
if(p != NULL)
*p = '\0';
p = strchr(devout_name, ' ');
if(p != NULL)
*p = '\0';
data.fd_in = open(devin_name, O_RDONLY, 0);
if(data.fd_in < 0) {
fprintf(stderr, "Cannot open %s for input.\n", devin_name);
return (-1);
}
if (*devout_name == '\0') {
close(data.fd_in);
data.fd_in = open(devin_name, O_RDWR, 0);
if(data.fd_in < 0) {
fprintf(stderr, "Cannot open %s for input.\n", devin_name);
return (-1);
}
data.fd_out = data.fd_in;
if(ioctl(data.fd_in, SNDCTL_DSP_SETDUPLEX, 0) < 0) {
fprintf(stderr, "Cannot use %s for full duplex.\n", devin_name);
return(-1);
}
} else {
data.fd_out = open(devout_name, O_WRONLY, 0);
if(data.fd_out < 0) {
fprintf(stderr, "Cannot open %s for output.\n", devout_name);
return (-1);
}
}
data.Tsec = Tsec;
data.tbuf = tbuf;
data.iwrite = iwrite;
data.ibuf = ibuf;
data.TxOK = TxOK;
data.ndebug = ndebug;
data.ndsec = ndsec;
data.Transmitting = Transmitting;
data.y1 = y1;
data.y2 = y2;
data.nbuflen = *nbuflen;
data.nmode = nmode;
data.nwave = nwave;
data.iwave = iwave;
data.nfs = *nfsample;
data.trperiod = TRPeriod;
dnfs=(double)*nfsample;
channels = 2;
if(ioctl (data.fd_in, SNDCTL_DSP_CHANNELS, &channels) == -1) {
fprintf (stderr, "Unable to set 2 channels for input.\n");
return (-1);
}
if(channels != 2) {
fprintf (stderr, "Unable to set 2 channels.\n");
return (-1);
}
format = AFMT_S16_NE;
if(ioctl (data.fd_in, SNDCTL_DSP_SETFMT, &format) == -1) {
fprintf (stderr, "Unable to set format for input.\n");
return (-1);
}
if(ioctl (data.fd_in, SNDCTL_DSP_SPEED, &rate) == -1) {
fprintf (stderr, "Unable to set rate for input\n");
return (-1);
}
printf("Audio OSS streams running normally.\n");
printf("******************************************************************\n");
printf("Opened %s for input.\n", devin_name);
if (*devout_name != '\0')
printf("Opened %s for output.\n", devout_name);
else
printf("Opened %s for output.\n", devin_name);
printf("Rate set = %d\n", rate);
// printf("start_threads: creating thread for oss_loop\n");
iret1 = pthread_create(&thread1, NULL,
(void *(*)(void *))oss_loop, &iarg1);
// printf("start_threads: creating thread for decode1_\n");
iret2 = pthread_create(&thread2, NULL,
(void *(*)(void *))decode1_,&iarg2);
}
/*
* oss_loop
*
* inputs - int pointer NOT USED
* output - none
* side effects -
*/
void
oss_loop(int *iarg)
{
fd_set readfds, writefds;
int nfds = 0;
struct timeval timeout = {0, 0};
struct timeval tv;
int nread;
unsigned int i;
static int n=0;
static int n2=0;
static int ia=0;
static int ib=0;
static int ic=0;
static int16_t *in;
static int16_t *wptr;
static int TxOKz=0;
static int ncall=0;
static int nsec=0;
static double stime;
for (;;) {
FD_ZERO(&readfds );
FD_ZERO(&writefds );
FD_SET(data.fd_in, &readfds);
FD_SET(data.fd_out, &writefds);
timeout.tv_usec = TIMEOUT;
if(select(FD_SETSIZE, &readfds, &writefds, NULL, &timeout) > 0) {
if(FD_ISSET(data.fd_in, &readfds)) {
nread = read (data.fd_in, rcv_buf, AUDIOBUFSIZE);
if(nread <= 0) {
fprintf(stderr, "Read error %d\n", nread);
return;
}
if(nread == AUDIOBUFSIZE) {
/* Get System time */
gettimeofday(&tv, NULL);
stime = (double) tv.tv_sec + ((double)tv.tv_usec / 1000000.0) +
*(data.ndsec) * 0.1;
*(data.Tsec) = stime;
ncall++;
/* increment buffer pointers only if data available */
ia=*(data.iwrite);
ib=*(data.ibuf);
data.tbuf[ib-1] = stime; /* convert to c index to store */
ib++;
if(ib>FRAMESPERBUFFER)
ib=1;
*(data.ibuf) = ib;
in = (int16_t *)rcv_buf; /* XXX */
for(i=0; i<FRAMESPERBUFFER; i++) {
data.y1[ia] = (*in++);
data.y2[ia] = (*in++);
ia++;
}
if(ia >= data.nbuflen)
ia=0; //Wrap buffer pointer if necessary
*(data.iwrite) = ia; /* Save buffer pointer */
fivehz_(); /* Call fortran routine */
}
}
if(FD_ISSET(data.fd_in, &writefds)) {
/* Get System time */
gettimeofday(&tv, NULL);
stime = (double) tv.tv_sec + ((double)tv.tv_usec / 1000000.0) +
*(data.ndsec) * 0.1;
*(data.Tsec) = stime;
if(*(data.TxOK) && (!TxOKz)) {
nsec = (int)stime;
n = nsec / *(data.trperiod);
ic = (int)(stime - *(data.trperiod) * n) * data.nfs;
ic = ic % *(data.nwave);
}
TxOKz = *(data.TxOK);
*(data.Transmitting) = *(data.TxOK);
wptr = (int16_t *)tx_buf; /* XXX */
if(*(data.TxOK)) {
for(i=0 ; i<FRAMESPERBUFFER; i++) {
n2 = data.iwave[ic];
addnoise_(&n2);
*wptr++ = n2; /* left */
*wptr++ = n2; /* right */
ic++;
if(ic >= *(data.nwave)) {
ic = ic % *(data.nwave); /* Wrap buffer pointer if necessary */
if(*(data.nmode) == 2)
*(data.TxOK) = 0;
}
}
} else {
memset(tx_buf, 0, AUDIOBUFSIZE);
}
if(write(data.fd_out, tx_buf, AUDIOBUFSIZE) < 0) {
fprintf(stderr, "Can't write to soundcard.\n");
return;
}
fivehztx_(); /* Call fortran routine */
}
}
}
}

View File

@ -1,19 +0,0 @@
#include <stdio.h>
void wfile3_(char *outfile, char buf[], int *nbytes0)
{
int n,nbytes;
static int first=1;
static FILE *fp=NULL;
nbytes=*nbytes0;
fp = fopen(outfile,"wb");
if(fp == NULL) {
printf("Cannot create %s\n",outfile);
exit(0);
}
n=fwrite(buf,1,nbytes,fp);
fclose(fp);
return(n);
}