]> git.rkrishnan.org Git - pihpsdr.git/commitdiff
tx heartbeat also for new protocol
authorc vw <dl1ycf@darc.de>
Thu, 12 Dec 2019 15:46:12 +0000 (16:46 +0100)
committerc vw <dl1ycf@darc.de>
Thu, 12 Dec 2019 15:46:12 +0000 (16:46 +0100)
audio.c
audio.h
new_protocol.c
old_protocol.c
portaudio.c

diff --git a/audio.c b/audio.c
index 832a8ea22753618edd3246e4c2fbb99b135f396f..f9312f376446dbf2c075fd24019e8e83ba9aa029 100644 (file)
--- a/audio.c
+++ b/audio.c
@@ -73,6 +73,14 @@ AUDIO_DEVICE input_devices[MAX_AUDIO_DEVICES];
 int n_output_devices;
 AUDIO_DEVICE output_devices[MAX_AUDIO_DEVICES];
 
+//
+// Ring buffer for "local microphone" samples
+//
+#define MICRINGLEN 2048
+float  *mic_ring_buffer=NULL;
+int     mic_ring_read_pt=0;
+int     mic_ring_write_pt=0;
+
 int audio_open_output(RECEIVER *rx) {
   int err;
   snd_pcm_hw_params_t *hw_params;
@@ -239,6 +247,13 @@ g_print("audio_open_input: mic_buffer: size=%d channels=%d sample=%ld bytes\n",m
       break;
   }
 
+g_print("audio_open_input: allocating ring buffer\n");
+  mic_ring_buffer=(float *) malloc(MICRINGLEN * sizeof(float));
+  mic_ring_read_pt = mic_ring_write_pt=0;
+  if (mic_ring_buffer == NULL) {
+    return -1;
+  }
+
 g_print("audio_open_input: creating mic_read_thread\n");
   GError *error;
   mic_read_thread_id = g_thread_try_new("local mic",mic_read_thread,NULL,&error);
@@ -281,6 +296,10 @@ g_print("audio_close_input: free mic buffer\n");
     g_free(mic_buffer);
     mic_buffer=NULL;
   }
+  if (mic_ring_buffer != NULL) {
+    free(mic_ring_buffer);
+    mic_ring_buffer=NULL;
+  }
 }
 
 //
@@ -470,6 +489,7 @@ g_print("mic_read_thread: snd_pcm_start\n");
         }
       }
     } else {
+      int newpt;
       // process the mic input
       for(i=0;i<mic_buffer_size;i++) {
         switch(record_audio_format) {
@@ -488,13 +508,24 @@ g_print("mic_read_thread: snd_pcm_start\n");
         }
         switch(protocol) {
           case ORIGINAL_PROTOCOL:
-            old_protocol_process_local_mic(sample);
-            break;
           case NEW_PROTOCOL:
-            new_protocol_process_local_mic(sample);
+           //
+           // put sample into ring buffer
+           //
+           if (mic_ring_buffer) {
+             newpt=mic_ring_write_pt +1;
+             if (newpt == MICRINGLEN) newpt=0;
+             if (newpt != mic_ring_read_pt) {
+               // buffer space available, do the write
+               mic_ring_buffer[mic_ring_write_pt]=sample;
+               // atomic update of mic_ring_write_pt
+               mic_ring_write_pt=newpt;
+             }
+            }
             break;
 #ifdef SOAPYSDR
           case SOAPYSDR_PROTOCOL:
+            // Note that this call ends up deeply in the TX engine
             soapy_protocol_process_local_mic(sample);
             break;
 #endif
@@ -508,6 +539,26 @@ g_print("mic_read_thread: exiting\n");
   return NULL;
 }
 
+//
+// Utility function for retrieving mic samples
+// from ring buffer
+//
+float audio_get_next_mic_sample() {
+  int newpt;
+  float sample;
+  if ((mic_ring_buffer == NULL) || (mic_ring_read_pt == mic_ring_write_pt)) {
+    // no buffer, or nothing in buffer: insert silence
+    sample=0.0;
+  } else {
+    newpt = mic_ring_read_pt+1;
+    if (newpt == MICRINGLEN) newpt=0;
+    sample=mic_ring_buffer[mic_ring_read_pt];
+    // atomic update of read pointer
+    mic_ring_read_pt=newpt;
+  }
+  return sample;
+}
+
 void audio_get_cards() {
   snd_ctl_card_info_t *info;
   snd_pcm_info_t *pcminfo;
diff --git a/audio.h b/audio.h
index a477b3dae5fc3fb63be4a19b7907105964ab55af..234c184e7d9cb85424132a3ae2dd7140a4adc8bf 100644 (file)
--- a/audio.h
+++ b/audio.h
@@ -45,4 +45,5 @@ extern int audio_write(RECEIVER *rx,float left_sample,float right_sample);
 extern int cw_audio_write(float sample);
 extern void audio_get_cards();
 char * audio_get_error_string(int err);
+float  audio_get_next_mic_sample();
 #endif
index 4fe00bbf6a5876e595c3bdc76a41f453137af9e4..a43c9613c9f6bb8df4c5b0219cc793d8f5e5f2ac 100644 (file)
@@ -1533,9 +1533,11 @@ fprintf(stderr,"mic_line_thread\n");
     sem_post(&mic_line_sem_ready);
     sem_wait(&mic_line_sem_buffer);
 #endif
-    if(!transmitter->local_microphone) {
-      process_mic_data(mic_bytes_read);
-    }
+//
+//  process mic data even if local mic is used,
+//  since this is our pace-maker
+//
+    process_mic_data(mic_bytes_read);
     free(mic_line_buffer);
   }
 }
@@ -1834,7 +1836,7 @@ static void process_mic_data(int bytes) {
   for(i=0;i<MIC_SAMPLES;i++) {
     sample=(short)(mic_line_buffer[b++]<<8);
     sample |= (short) (mic_line_buffer[b++]&0xFF);
-    fsample = (float) sample * 0.00003051;
+    fsample = transmitter->local_microphone ? audio_get_next_mic_sample() : (float) sample * 0.00003051;
 #ifdef FREEDV
     if(active_receiver->freedv) {
       add_freedv_mic_sample(transmitter,fsample);
@@ -1847,18 +1849,6 @@ static void process_mic_data(int bytes) {
   }
 }
 
-void new_protocol_process_local_mic(float sample) {
-#ifdef FREEDV
-  if(active_receiver->freedv) {
-    add_freedv_mic_sample(transmitter,sample);
-  } else {
-#endif
-    add_mic_sample(transmitter,sample);
-#ifdef FREEDV
-  }
-#endif
-}
-
 void new_protocol_cw_audio_samples(short left_audio_sample,short right_audio_sample) {
   int rc;
   int mode=transmitter->mode;
index 4c05757e6f186f8b29580fe36d7cf780b3e98999..b804a92846a0c3cd4361d935a0845b1ee2770287 100644 (file)
@@ -252,11 +252,6 @@ static unsigned char ep6_inbuffer[EP6_BUFFER_SIZE];
 static unsigned char usb_buffer_block = 0;
 #endif
 
-#define MICRINGLEN 2048
-float mic_ring_buffer[MICRINGLEN];
-int   mic_ring_read_pt=0;
-int   mic_ring_write_pt=0;
-
 void old_protocol_stop() {
   metis_start_stop(0);
 }
@@ -994,22 +989,7 @@ static void process_ozy_input_buffer(unsigned char  *buffer) {
 
       mic_samples++;
       if(mic_samples>=mic_sample_divisor) { // reduce to 48000
-        if (!transmitter->local_microphone) {
-          // take mic sample from SDR
-          fsample = (float) mic_sample * 0.00003051;
-        } else {
-          // take mic sample from local mic buffer
-          if (mic_ring_read_pt == mic_ring_write_pt) {
-            // nothing in buffer: insert silence
-            fsample=0.0;
-          } else {
-            int newpt = mic_ring_read_pt+1;
-            if (newpt == MICRINGLEN) newpt=0;
-            fsample=mic_ring_buffer[mic_ring_read_pt];
-            // atomic update of read pointer
-            mic_ring_read_pt=newpt;
-          }
-        }
+        fsample = transmitter->local_microphone ? audio_get_next_mic_sample() : (float) mic_sample * 0.00003051;
 #ifdef FREEDV
         if(active_receiver->freedv) {
           add_freedv_mic_sample(transmitter,fsample);
@@ -1096,21 +1076,6 @@ void old_protocol_iq_samples(int isample,int qsample) {
   }
 }
 
-//
-// This function now simply puts the mic sample
-// into a ring buffer
-//
-void old_protocol_process_local_mic(float sample) {
-    int newpt;  // value of write pointer after a successful write
-    newpt=mic_ring_write_pt +1;
-    if (newpt == MICRINGLEN) newpt=0;
-    if (newpt != mic_ring_read_pt) {
-      // buffer space available, do the write
-      mic_ring_buffer[mic_ring_write_pt]=sample;
-      mic_ring_write_pt=newpt;
-    }
-}
-
 /*
 static void process_bandscope_buffer(char  *buffer) {
 }
index 111a524184b55a46768bf17b4db6ed4baab30424..1e009a437e8f4971547eaaef7489b5210fcc522e 100644 (file)
@@ -49,6 +49,14 @@ int n_output_devices=0;
 
 #define BUFFER_SIZE 256
 
+//
+// Ring buffer for "local microphone" samples
+//
+#define MICRINGLEN 2048
+float  *mic_ring_buffer=NULL;
+int     mic_ring_read_pt=0;
+int     mic_ring_write_pt=0;
+
 //
 // AUDIO_GET_CARDS
 //
@@ -171,6 +179,12 @@ int audio_open_input()
     return -1;
   }
 
+  mic_ring_buffer=(float *) malloc(MICRINGLEN * sizeof(float));
+  mic_ring_read_pt = mic_ring_write_pt=0;
+  if (mic_ring_buffer == NULL) {
+    return -1;
+  }
+
   err = Pa_StartStream(record_handle);
   if (err != paNoError) {
     fprintf(stderr, "PORTAUDIO ERROR: AOI start stream:%s\n",Pa_GetErrorText(err));
@@ -188,59 +202,69 @@ int pa_mic_cb(const void *inputBuffer, void *outputBuffer, unsigned long framesP
              void *userdata)
 {
   float *in = (float *)inputBuffer;
-  int i;
-  gfloat sample;
-
+  int i, newpt;
+  float sample;
 
   if (in == NULL) {
-    //
-    // We could just do nothing, but rather send a bunch of silence
-    // Note the mic samples flying in are the "heart-beat" of the TX engine.
-    //
-    for (i=0; i<BUFFER_SIZE; i++) {
-      sample=0.0;
-      switch(protocol) {
-        case ORIGINAL_PROTOCOL:
-          old_protocol_process_local_mic(sample);
-          break;
-        case NEW_PROTOCOL:
-          new_protocol_process_local_mic(sample);
-          break;
-#ifdef SOAPYSDR
-        case SOAPYSDR_PROTOCOL:
-          soapy_protocol_process_local_mic(sample);
-          break;
-#endif
-        default:
-          break;
-      }
-    }
-  } else {
-    //
-    // send the samples in the buffer
-    //
-    for (i=0; i<framesPerBuffer; i++) {
-      sample=in[i];
-      switch(protocol) {
-        case ORIGINAL_PROTOCOL:
-          old_protocol_process_local_mic(sample);
-          break;
-        case NEW_PROTOCOL:
-          new_protocol_process_local_mic(sample);
-          break;
+    // This should not happen, so we do not send silence etc.
+    g_print("PortAudio error: bogus audio buffer in callback\n");
+    return paContinue;
+  }
+  //
+  // send the samples in the buffer
+  //
+  for (i=0; i<framesPerBuffer; i++) {
+    sample=in[i];
+    switch(protocol) {
+      case ORIGINAL_PROTOCOL:
+      case NEW_PROTOCOL:
+       //
+       // put sample into ring buffer
+       //
+       if (mic_ring_buffer != NULL) {
+         newpt=mic_ring_write_pt +1;
+         if (newpt == MICRINGLEN) newpt=0;
+         if (newpt != mic_ring_read_pt) {
+           // buffer space available, do the write
+           mic_ring_buffer[mic_ring_write_pt]=sample;
+           // atomic update of mic_ring_write_pt
+           mic_ring_write_pt=newpt;
+         }
+       }
+       break;
 #ifdef SOAPYSDR
-        case SOAPYSDR_PROTOCOL:
-          soapy_protocol_process_local_mic(sample);
-          break;
+      case SOAPYSDR_PROTOCOL:
+       // Note that this call ends up deeply in the TX engine
+       soapy_protocol_process_local_mic(sample);
+       break;
 #endif
-        default:
-          break;
-      }
+      default:
+       break;
     }
   }
   return paContinue;
 }
 
+//
+// Utility function for retrieving mic samples
+// from ring buffer
+//
+float audio_get_next_mic_sample() {
+  int newpt;
+  float sample;
+  if ((mic_ring_buffer == NULL) || (mic_ring_read_pt == mic_ring_write_pt)) {
+    // no buffer, or nothing in buffer: insert silence
+    sample=0.0;
+  } else {
+    newpt = mic_ring_read_pt+1;
+    if (newpt == MICRINGLEN) newpt=0;
+    sample=mic_ring_buffer[mic_ring_read_pt];
+    // atomic update of read pointer
+    mic_ring_read_pt=newpt;
+  }
+  return sample;
+}
+
 //
 // AUDIO_OPEN_OUTPUT
 //
@@ -335,6 +359,10 @@ void audio_close_input()
     }
     record_handle=NULL;
   }
+  if (mic_ring_buffer != NULL) {
+    free(mic_ring_buffer);
+    mic_ring_buffer=NULL;
+  }
 }
 
 //