]> git.rkrishnan.org Git - pihpsdr.git/commitdiff
small fixes
authorc vw <dl1ycf@darc.de>
Mon, 16 Dec 2019 14:38:39 +0000 (15:38 +0100)
committerc vw <dl1ycf@darc.de>
Mon, 16 Dec 2019 14:38:39 +0000 (15:38 +0100)
audio.c
ext.c
ext.h
midi3.c
portaudio.c
receiver.c
transmitter.c
vfo.c

diff --git a/audio.c b/audio.c
index a55aad1e0915485e8874f3e9572a51ff3a50a9c9..3ea1be7f4180d94ddeee4171503bc534b008037e 100644 (file)
--- a/audio.c
+++ b/audio.c
@@ -282,6 +282,7 @@ g_print("audio_close_output: rx=%d handle=%p buffer=%p\n",rx->id,rx->playback_ha
 }
 
 void audio_close_input() {
+  void *p;
 g_print("audio_close_input\n");
   running=FALSE;
   if(mic_read_thread_id!=NULL) {
@@ -299,9 +300,18 @@ g_print("audio_close_input: free mic buffer\n");
     g_free(mic_buffer);
     mic_buffer=NULL;
   }
+  //
+  // We do not want to do a mutex lock/unlock for every single mic sample
+  // accessed. Since only the ring buffer is maintained by the functions
+  // audio_get_next_mic_sample() and in the "mic read thread",
+  // it is more than enough to wait 2 msec after setting mic_ring_buffer to NULL
+  // before actually releasing the storage.
+  //
   if (mic_ring_buffer != NULL) {
-    free(mic_ring_buffer);
+    p=mic_ring_buffer;
     mic_ring_buffer=NULL;
+    usleep(2);
+    g_free(p);
   }
 }
 
@@ -321,6 +331,7 @@ int cw_audio_write(float sample){
        
   RECEIVER *rx = active_receiver;
  
+  g_mutex_lock(&rx->local_audio_mutex);
   if(rx->playback_handle!=NULL && rx->local_audio_buffer!=NULL) {
 
     switch(rx->local_audio_format) {
@@ -360,6 +371,7 @@ g_print("audio delay=%ld trim=%ld\n",delay,trim);
             if(rc==-EPIPE) {
               if ((rc = snd_pcm_prepare (rx->playback_handle)) < 0) {
                 g_print("audio_write: cannot prepare audio interface for use %ld (%s)\n", rc, snd_strerror (rc));
+                g_mutex_unlock(&rx->local_audio_mutex);
                 return rc;
               } else {
                 // ignore short write
@@ -371,6 +383,7 @@ g_print("audio delay=%ld trim=%ld\n",delay,trim);
       rx->local_audio_buffer_offset=0;
     }
   }
+  g_mutex_unlock(&rx->local_audio_mutex);
   return 0;
 }
 
@@ -388,8 +401,6 @@ int audio_write(RECEIVER *rx,float left_sample,float right_sample) {
   gint32 *long_buffer;
   gint16 *short_buffer;
 
-  g_mutex_lock(&rx->local_audio_mutex);
-
   if(can_transmit) {
     mode=transmitter->mode;
   }
@@ -404,10 +415,12 @@ int audio_write(RECEIVER *rx,float left_sample,float right_sample) {
   //
 
   if (rx == active_receiver && isTransmitting() && (mode==modeCWU || mode==modeCWL)) {
-    g_mutex_unlock(&rx->local_audio_mutex);
     return 0;
   }
 
+  // lock AFTER checking the "quick return" condition but BEFORE checking the pointers
+  g_mutex_lock(&rx->local_audio_mutex);
+
   if(rx->playback_handle!=NULL && rx->local_audio_buffer!=NULL) {
     switch(rx->local_audio_format) {
       case SND_PCM_FORMAT_S16_LE:
@@ -515,7 +528,9 @@ g_print("mic_read_thread: snd_pcm_start\n");
            //
            // put sample into ring buffer
            //
-           if (mic_ring_buffer) {
+           if (mic_ring_buffer != NULL) {
+              // the "existence" of the ring buffer is now guaranteed for 1 msec,
+             // see audio_close_input().
              newpt=mic_ring_write_pt +1;
              if (newpt == MICRINGLEN) newpt=0;
              if (newpt != mic_ring_read_pt) {
@@ -553,6 +568,8 @@ float audio_get_next_mic_sample() {
     // no buffer, or nothing in buffer: insert silence
     sample=0.0;
   } else {
+    // the "existence" of the ring buffer is now guaranteed for 1 msec,
+    // see audio_close_input(),
     newpt = mic_ring_read_pt+1;
     if (newpt == MICRINGLEN) newpt=0;
     sample=mic_ring_buffer[mic_ring_read_pt];
@@ -685,6 +702,11 @@ g_print("input_device: name=%s descr=%s\n",name,descr);
 #endif
     }
 
+//
+//  For these three items, use free() instead of g_free(),
+//  since these have been allocated by ALSA via
+//  snd_device_name_get_hint()
+//
     if (name != NULL)
       free(name);
     if (descr != NULL)
diff --git a/ext.c b/ext.c
index 6feb74db9613845711ff3b99495387bf8795b93b..15d9b6f414142512b3240222b7d94c75340074f7 100644 (file)
--- a/ext.c
+++ b/ext.c
@@ -39,6 +39,7 @@
 #include "filter.h"
 #include "band.h"
 #include "bandstack.h"
+#include "noise_menu.h"
 #include "wdsp.h"
 
 // The following calls functions can be called usig g_idle_add
@@ -613,3 +614,7 @@ int ext_set_rf_gain(void *data) {
   return 0;
 }
 
+int ext_update_noise(void *data) {
+  update_noise();
+  return 0;
+}
diff --git a/ext.h b/ext.h
index 8e69e95e0927dd6301bc959a7bfb56691483442d..6fe1858ffacc253c9168396330752e18185c9b50 100644 (file)
--- a/ext.h
+++ b/ext.h
@@ -107,3 +107,4 @@ int ext_diversity_update(void *data);
 int ext_sat_update(void *data);
 int ext_set_rf_gain(void *data);
 
+int ext_update_noise(void *data);
diff --git a/midi3.c b/midi3.c
index 45df600e97164294b7d28a93f82e22244a710e54..505ea0d67cc1c3b1740aae675bb655f0e3c5f824 100644 (file)
--- a/midi3.c
+++ b/midi3.c
@@ -367,6 +367,7 @@ void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) {
                active_receiver->nr = 1;
                active_receiver->nr2= 0;
              }
+             g_idle_add(ext_update_noise, NULL);
              g_idle_add(ext_vfo_update, NULL);
            }
            break;
index 23122e82de1ec1ca784d0b6bf43a5880b0aeb63f..3073ecede6dc783122fb02f4dab458927d2095d0 100644 (file)
@@ -222,6 +222,8 @@ int pa_mic_cb(const void *inputBuffer, void *outputBuffer, unsigned long framesP
        // put sample into ring buffer
        //
        if (mic_ring_buffer != NULL) {
+          // the "existence" of the ring buffer is now guaranteed for 1 msec,
+          // see audio_close_input(),
          newpt=mic_ring_write_pt +1;
          if (newpt == MICRINGLEN) newpt=0;
          if (newpt != mic_ring_read_pt) {
@@ -256,6 +258,8 @@ float audio_get_next_mic_sample() {
     // no buffer, or nothing in buffer: insert silence
     sample=0.0;
   } else {
+    // the "existence" of the ring buffer is now guaranteed for 1 msec,
+    // see audio_close_input(),
     newpt = mic_ring_read_pt+1;
     if (newpt == MICRINGLEN) newpt=0;
     sample=mic_ring_buffer[mic_ring_read_pt];
@@ -300,7 +304,7 @@ int audio_open_output(RECEIVER *rx)
     return -1;
   }
 
-
+  g_mutex_lock(&rx->local_audio_mutex);
   bzero( &outputParameters, sizeof( outputParameters ) ); //not necessary if you are filling in all the fields
   outputParameters.channelCount = 1;   // Always MONO
   outputParameters.device = padev;
@@ -319,6 +323,7 @@ int audio_open_output(RECEIVER *rx)
     rx->playback_handle = NULL;
     if (rx->local_audio_buffer) g_free(rx->local_audio_buffer);
     rx->local_audio_buffer = NULL;
+    g_mutex_unlock(&rx->local_audio_mutex);
     return -1;
   }
 
@@ -328,12 +333,14 @@ int audio_open_output(RECEIVER *rx)
     rx->playback_handle=NULL;
     if (rx->local_audio_buffer) g_free(rx->local_audio_buffer);
     rx->local_audio_buffer = NULL;
+    g_mutex_unlock(&rx->local_audio_mutex);
     return -1;
   }
   // Write one buffer to avoid under-flow errors
   // (this gives us 5 msec to pass before we have to call audio_write the first time)
   bzero(rx->local_audio_buffer, (size_t) BUFFER_SIZE*sizeof(float));
   err=Pa_WriteStream(rx->playback_handle, rx->local_audio_buffer, (unsigned long) BUFFER_SIZE);
+  g_mutex_unlock(&rx->local_audio_mutex);
   return 0;
 }
 
@@ -345,6 +352,7 @@ int audio_open_output(RECEIVER *rx)
 void audio_close_input()
 {
   PaError err;
+  void *p;
 
   fprintf(stderr,"AudioCloseInput: %s\n", transmitter->microphone_name);
 
@@ -359,9 +367,18 @@ void audio_close_input()
     }
     record_handle=NULL;
   }
+  //
+  // We do not want to do a mutex lock/unlock for every single mic sample
+  // accessed. Since only the ring buffer is maintained by the functions
+  // audio_get_next_mic_sample() and in the "mic callback" function,
+  // it is more than enough to wait 2 msec after setting mic_ring_buffer to NULL
+  // before actually releasing the storage.
+  //
   if (mic_ring_buffer != NULL) {
-    g_free(mic_ring_buffer);
+    p=mic_ring_buffer;
     mic_ring_buffer=NULL;
+    usleep(2);
+    g_free(p);
   }
 }
 
@@ -375,7 +392,7 @@ void audio_close_output(RECEIVER *rx) {
 
   fprintf(stderr,"AudioCloseOutput: %s\n", rx->audio_name);
 
-// free the buffer first, this then indicates to audio_write to do nothing
+  g_mutex_lock(&rx->local_audio_mutex);
   if(rx->local_audio_buffer!=NULL) {
     g_free(rx->local_audio_buffer);
     rx->local_audio_buffer=NULL;
@@ -392,6 +409,7 @@ void audio_close_output(RECEIVER *rx) {
     }
     rx->playback_handle=NULL;
   }
+  g_mutex_unlock(&rx->local_audio_mutex);
 }
 
 //
@@ -404,8 +422,12 @@ void audio_close_output(RECEIVER *rx) {
 int audio_write (RECEIVER *rx, float left, float right)
 {
   PaError err;
-  int mode=transmitter->mode;
+  int mode=modeUSB;
   float *buffer = rx->local_audio_buffer;
+
+  if (can_transmit) {
+    mode=transmitter->mode;
+  }
   //
   // We have to stop the stream here if a CW side tone may occur.
   // This might cause underflows, but we cannot use audio_write
@@ -414,8 +436,11 @@ int audio_write (RECEIVER *rx, float left, float right)
   // If *not* doing CW, the stream continues because we might wish
   // to listen to this rx while transmitting.
   //
-  if (rx == active_receiver && isTransmitting() && (mode==modeCWU || mode==modeCWL)) return 0;
+  if (rx == active_receiver && isTransmitting() && (mode==modeCWU || mode==modeCWL)) {
+    return 0;
+  }
 
+  g_mutex_lock(&rx->local_audio_mutex);
   if (rx->playback_handle != NULL && rx->local_audio_buffer != NULL) {
     buffer[rx->local_audio_buffer_offset++] = (left+right)*0.5;  //   mix to MONO   
     if (rx->local_audio_buffer_offset == BUFFER_SIZE) {
@@ -424,6 +449,7 @@ int audio_write (RECEIVER *rx, float left, float right)
       // do not check on errors, there will be underflows every now and then
     }
   }
+  g_mutex_unlock(&rx->local_audio_mutex);
   return 0;
 }
 
index 46bb5b05c38036c81e2cf9a84ba4366fe37d8ddd..a0cfeda1bdcdd96427d75fe0d206a8f1767fbebb 100644 (file)
@@ -813,10 +813,13 @@ fprintf(stderr,"create_pure_signal_receiver: id=%d buffer_size=%d\n",id,buffer_s
     //
     // need a buffer for pixels for the spectrum of the feedback
     // signal (MON button).
-    // NewProtocol: Since we want to display only 48 kHz instead of
-    // 192 kHz, we make a spectrum with four times the pixels and then
+    // NewProtocol: Since we want to display only 24 kHz instead of
+    // 192 kHz, we make a spectrum with eight times the pixels and then
     // display only the central part.
+    //
+    // Also need a mutex, when changing sample rate
     // 
+    g_mutex_init(&rx->mutex);
     if (protocol == ORIGINAL_PROTOCOL) {
        rx->pixels=(sample_rate/24000) * width;
     } else {
@@ -828,7 +831,7 @@ fprintf(stderr,"create_pure_signal_receiver: id=%d buffer_size=%d\n",id,buffer_s
   rx->iq_input_buffer=g_new(double,2*rx->buffer_size);
   //rx->audio_buffer=NULL;
   rx->audio_sequence=0L;
-  rx->pixel_samples=malloc(sizeof(float)*(rx->pixels));
+  rx->pixel_samples=g_new(float,rx->pixels);
 
   rx->samples=0;
   rx->displaying=0;
@@ -1179,13 +1182,11 @@ void receiver_change_sample_rate(RECEIVER *rx,int sample_rate) {
   rx->sample_rate=sample_rate;
   int scale=rx->sample_rate/48000;
   rx->output_samples=rx->buffer_size/scale;
-  rx->audio_output_buffer=g_new(gdouble,2*rx->output_samples);
   rx->hz_per_pixel=(double)rx->sample_rate/(double)rx->width;
 
 g_print("receiver_change_sample_rate: id=%d rate=%d scale=%d buffer_size=%d output_samples=%d\n",rx->id,sample_rate,scale,rx->buffer_size,rx->output_samples);
 #ifdef PURESIGNAL
   if (rx->id == PS_RX_FEEDBACK) {
-    float *fp, *ofp;
     if (protocol == ORIGINAL_PROTOCOL) {
       rx->pixels = 2* scale * rx->width;
     } else {
@@ -1193,12 +1194,8 @@ g_print("receiver_change_sample_rate: id=%d rate=%d scale=%d buffer_size=%d outp
       // PS feedback receiver is fixed.
       rx->pixels = 8 * rx->width;
     }
-    // make sure pixel_samples is always a valid pointer
-    // ... probably pure DL1YCF's paranoia
-    fp=malloc(sizeof(float)*rx->pixels);
-    ofp=rx->pixel_samples;
-    rx->pixel_samples=fp;
-    free(ofp);
+    g_free(rx->pixel_samples);
+    rx->pixel_samples=g_new(float,rx->pixels);
     init_analyzer(rx);
     fprintf(stderr,"PS FEEDBACK change sample rate:id=%d rate=%d buffer_size=%d output_samples=%d\n",
                    rx->id, rx->sample_rate, rx->buffer_size, rx->output_samples);
@@ -1206,6 +1203,10 @@ g_print("receiver_change_sample_rate: id=%d rate=%d scale=%d buffer_size=%d outp
     return;
   }
 #endif
+  if (rx->audio_output_buffer != NULL) {
+    g_free(rx->audio_output_buffer);
+  }
+  rx->audio_output_buffer=g_new(gdouble,2*rx->output_samples);
 
   SetChannelState(rx->id,0,1);
   init_analyzer(rx);
@@ -1460,7 +1461,7 @@ void full_rx_buffer(RECEIVER *rx) {
 
   g_mutex_lock(&rx->mutex);
 
-  // noise blanker works on origianl IQ samples
+  // noise blanker works on original IQ samples
   if(rx->nb) {
      xanbEXT (rx->id, rx->iq_input_buffer, rx->iq_input_buffer);
   }
index 6425ee7d263317827d4d182961d389a78b767de5..c554d91bd21fbc0bb2122d5c5c286cfb28344a98 100644 (file)
@@ -386,6 +386,7 @@ static gboolean update_display(gpointer data) {
 #ifdef PURESIGNAL
     if(tx->puresignal && tx->feedback) {
       RECEIVER *rx_feedback=receiver[PS_RX_FEEDBACK];
+      g_mutex_lock(&rx_feedback->mutex);
       GetPixels(rx_feedback->id,0,rx_feedback->pixel_samples,&rc);
       int full  = rx_feedback->pixels;  // number of pixels in the feedback spectrum
       int width = tx->pixels;           // number of pixels to copy from the feedback spectrum
@@ -394,6 +395,7 @@ static gboolean update_display(gpointer data) {
       float *rfp=rx_feedback->pixel_samples+start;
       // if full == width, then we just copy all samples
       memcpy(tfp, rfp, width*sizeof(float));
+      g_mutex_unlock(&rx_feedback->mutex);
     } else {
 #endif
       GetPixels(tx->id,0,tx->pixel_samples,&rc);
diff --git a/vfo.c b/vfo.c
index bcd2f692d202f1a0280a8c73e01b92a85ea87bd3..e227faa37bbe94234c0e60a003dba20e4d160178 100644 (file)
--- a/vfo.c
+++ b/vfo.c
@@ -50,7 +50,6 @@
 #include "new_menu.h"
 #include "rigctl.h"
 #include "ext.h"
-#include "noise_menu.h"
 #ifdef FREEDV
 #include "freedv.h"
 #endif
@@ -400,7 +399,7 @@ void vfo_mode_changed(int m) {
   active_receiver->snb=mode_settings[m].snb;
 
   // make changes effective
-  update_noise();
+  g_idle_add(ext_update_noise, NULL);
   switch(id) {
     case 0:
       receiver_mode_changed(receiver[0]);