static long ep4_sequence;
static uint32_t last_seq_num=-0xffffffff;
-static int suppress_ozy_packet = 0;
static int tx_fifo_flag = 0;
static int current_rx=0;
static GMutex dump_mutex;
+//
+// To avoid race conditions, we need a mutex covering the next three functions
+// that are called both by the RX and TX thread, and are filling and sending the
+// output buffer.
+//
+static pthread_mutex_t send_audio_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+//
+// This mutex "protects" ozy_send_buffer. This is necessary only for
+// TCP and USB-OZY connections.
+//
+static pthread_mutex_t send_ozy_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+
+
//
// Ring buffer for outgoing samples.
// Samples going to the radio are produces in big chunks.
}
void old_protocol_stop() {
+ //
+ // Mutex is needed since in the TCP case, sending TX IQ packets
+ // must not occur while the "stop" packet is sent.
+ //
+ pthread_mutex_lock(&send_ozy_mutex);
#ifdef USBOZY
if(device!=DEVICE_OZY) {
#endif
#ifdef USBOZY
}
#endif
+ pthread_mutex_unlock(&send_ozy_mutex);
}
void old_protocol_run() {
- //
- // Several things done in metis_restart are also needed for
- // USBOZY
- //
g_print("%s\n",__FUNCTION__);
+ pthread_mutex_lock(&send_ozy_mutex);
metis_restart();
+ pthread_mutex_unlock(&send_ozy_mutex);
}
void old_protocol_set_mic_sample_rate(int rate) {
void old_protocol_init(int rx,int pixels,int rate) {
int i;
g_print("old_protocol_init: num_hpsdr_receivers=%d\n",how_many_receivers());
+ pthread_mutex_lock(&send_ozy_mutex);
old_protocol_set_mic_sample_rate(rate);
}
metis_restart();
+ pthread_mutex_unlock(&send_ozy_mutex);
}
g_print( "old_protocol: receive_thread\n");
running=1;
- //metis_restart();
-
length=sizeof(addr);
while(running) {
// ship out two buffers with 2*63 samples
// the k-loop could be done with 1-2 memcpy
//
- for (int j=0; j<2; j++) {
- unsigned char *p=output_buffer+8;
- for (int k=0; k<63; k++) {
- *p++ = TXRINGBUF[txring_outptr++];
- *p++ = TXRINGBUF[txring_outptr++];
- *p++ = TXRINGBUF[txring_outptr++];
- *p++ = TXRINGBUF[txring_outptr++];
- *p++ = TXRINGBUF[txring_outptr++];
- *p++ = TXRINGBUF[txring_outptr++];
- *p++ = TXRINGBUF[txring_outptr++];
- *p++ = TXRINGBUF[txring_outptr++];
- if (txring_outptr >= TXRINGBUFLEN) txring_outptr=0;
+ if (pthread_mutex_trylock(&send_ozy_mutex)) {
+ //
+ // This can only happen if the GUI thread initiates
+ // a protocol stop/start sequence, as it does e.g.
+ // when changing the number of receivers, changing
+ // the sample rate, en/dis-abling PURESIGNAL or
+ // DIVERSITY, or executing the RESTART button.
+ // In these cases, the TX ring buffer is reset anywas
+ // so we do not have to do anything here.
+ //
+ } else {
+ for (int j=0; j<2; j++) {
+ unsigned char *p=output_buffer+8;
+ for (int k=0; k<63; k++) {
+ *p++ = TXRINGBUF[txring_outptr++];
+ *p++ = TXRINGBUF[txring_outptr++];
+ *p++ = TXRINGBUF[txring_outptr++];
+ *p++ = TXRINGBUF[txring_outptr++];
+ *p++ = TXRINGBUF[txring_outptr++];
+ *p++ = TXRINGBUF[txring_outptr++];
+ *p++ = TXRINGBUF[txring_outptr++];
+ *p++ = TXRINGBUF[txring_outptr++];
+ if (txring_outptr >= TXRINGBUFLEN) txring_outptr=0;
+ }
+ ozy_send_buffer();
}
- ozy_send_buffer();
- }
- micsamplecount=0;
+ micsamplecount=0;
+ pthread_mutex_unlock(&send_ozy_mutex);
+ }
}
}
}
}
-//
-// To avoid race conditions, we need a mutex covering the next three functions
-// that are called both by the RX and TX thread, and are filling and sending the
-// output buffer.
-//
-
-static pthread_mutex_t send_buffer_mutex = PTHREAD_MUTEX_INITIALIZER;
-
void old_protocol_audio_samples(RECEIVER *rx,short left_audio_sample,short right_audio_sample) {
if(!isTransmitting()) {
- pthread_mutex_lock(&send_buffer_mutex);
+ pthread_mutex_lock(&send_audio_mutex);
if (txring_flag) {
//
// First time we arrive here after a TX->RX transition:
TXRINGBUF[txring_inptr++]=0;
TXRINGBUF[txring_inptr++]=0;
if (txring_inptr >= TXRINGBUFLEN) txring_inptr=0;
- pthread_mutex_unlock(&send_buffer_mutex);
+ pthread_mutex_unlock(&send_audio_mutex);
}
}
//
void old_protocol_iq_samples_with_sidetone(int isample, int qsample, int side) {
if(isTransmitting()) {
- pthread_mutex_lock(&send_buffer_mutex);
+ pthread_mutex_lock(&send_audio_mutex);
if (!txring_flag) {
//
// First time we arrive here after a RX->TX transition:
TXRINGBUF[txring_inptr++]=qsample >> 8;
TXRINGBUF[txring_inptr++]=qsample;
if (txring_inptr >= TXRINGBUFLEN) txring_inptr=0;
- pthread_mutex_unlock(&send_buffer_mutex);
+ pthread_mutex_unlock(&send_audio_mutex);
}
}
void old_protocol_iq_samples(int isample,int qsample) {
if(isTransmitting()) {
- pthread_mutex_lock(&send_buffer_mutex);
+ pthread_mutex_lock(&send_audio_mutex);
if (!txring_flag) {
//
// First time we arrive here after a RX->TX transition:
TXRINGBUF[txring_inptr++]=qsample >> 8;
TXRINGBUF[txring_inptr++]=qsample;
if (txring_inptr >= TXRINGBUFLEN) txring_inptr=0;
- pthread_mutex_unlock(&send_buffer_mutex);
+ pthread_mutex_unlock(&send_audio_mutex);
}
}
break;
}
*/
- //
- // DL1YCF:
- // Although the METIS offset is not used for OZY, we have to maintain it
- // since it triggers the "alternating" sending of C0=0 and C0!=0
- // C+C packets in ozy_send_buffer().
- //
- if (metis_offset == 8) {
- metis_offset = 520;
- } else {
- metis_offset = 8;
- }
}
#endif
metis_buffer[6]=(send_sequence>>8)&0xFF;
metis_buffer[7]=(send_sequence)&0xFF;
- //
- // When using UDP, the buffer will ALWAYS be sent. However, when using TCP,
- // we must be able to suppress sending buffers HERE asynchronously
- // when we want to sent a METIS start or stop packet. This is so because TCP
- // is a byte stream, and data from two sources might end up interleaved
- // In order not to confuse the SDR, we increase the sequence number only
- // for packets actually sent.
- //
- if (!suppress_ozy_packet) {
- // send the buffer
- send_sequence++;
- metis_send_buffer(&metis_buffer[0],1032);
- }
+ send_sequence++;
+ metis_send_buffer(&metis_buffer[0],1032);
+
metis_offset=8;
}
for (i=0; i<8; i++) {
ozy_send_buffer();
}
-
- usleep(250000);
+ usleep(100000);
// start the data flowing
+ // No mutex here, since metis_restart() is mutex protected
#ifdef USBOZY
if(device!=DEVICE_OZY) {
#endif
metis_start_stop(1);
+ usleep(100000);
#ifdef USBOZY
}
#endif
unsigned char buffer[1032];
g_print("%s: %d\n",__FUNCTION__,command);
+ //
+ // Clear TX IQ ring buffer
+ //
+ txring_inptr = 0;
+ txring_outptr = 0;
#ifdef USBOZY
if(device!=DEVICE_OZY)
{
// Stop the sending of TX/audio packets (1032-byte-length) and wait a while
// Then, send the start/stop buffer with a length of 1032
//
- suppress_ozy_packet=1;
usleep(100000);
for(i=4;i<1032;i++) {
buffer[i]=0x00;
// This prevents mangling of data from TX/audio and Start/Stop packets.
//
usleep(100000);
- suppress_ozy_packet=0;
}
if (command == 0 && tcp_socket >= 0) {
// We just have sent a METIS stop in TCP