]> git.rkrishnan.org Git - pihpsdr.git/commitdiff
Fixed ALSA audio problems
authorJohn Melton G0ORX <john.d.melton@googlemail.com>
Sat, 23 Nov 2019 10:46:54 +0000 (10:46 +0000)
committerJohn Melton G0ORX <john.d.melton@googlemail.com>
Sat, 23 Nov 2019 10:46:54 +0000 (10:46 +0000)
audio.c
audio.h
receiver.c
receiver.h

diff --git a/audio.c b/audio.c
index c6137beb7fad0753e9c8a0dd78271490833bd4c1..3275599ec44387eef171dfd50b8274efd8bcf6d8 100644 (file)
--- a/audio.c
+++ b/audio.c
@@ -59,6 +59,12 @@ static GThread *mic_read_thread_id;
 
 static int running=FALSE;
 
+#define FORMATS 3
+static snd_pcm_format_t formats[3]={
+  SND_PCM_FORMAT_FLOAT_LE,
+  SND_PCM_FORMAT_S32_LE,
+  SND_PCM_FORMAT_S16_LE};
+
 static void *mic_read_thread(void *arg);
 
 
@@ -72,15 +78,15 @@ int audio_open_output(RECEIVER *rx) {
   snd_pcm_hw_params_t *hw_params;
   unsigned int rate=48000;
   unsigned int channels=2;
-  int soft_resample=0;
-  unsigned int latency=50000;
+  int soft_resample=1;
+  unsigned int latency=125000;
 
   if(rx->audio_name==NULL) {
     rx->local_audio=0;
     return -1;
   }
 
-fprintf(stderr,"audio_open_output: rx=%d %s buffer_size=%d\n",rx->id,rx->audio_name,rx->local_audio_buffer_size);
+g_print("audio_open_output: rx=%d %s buffer_size=%d\n",rx->id,rx->audio_name,rx->local_audio_buffer_size);
 
   int i;
   char hw[128];
@@ -93,31 +99,54 @@ fprintf(stderr,"audio_open_output: rx=%d %s buffer_size=%d\n",rx->id,rx->audio_n
   }
   hw[i]='\0';
   
-fprintf(stderr,"audio_open_output: hw=%s\n",hw);
-
-  g_mutex_lock(&rx->local_audio_mutex);
+g_print("audio_open_output: hw=%s\n",hw);
+
+  for(i=0;i<FORMATS;i++) {
+    g_mutex_lock(&rx->local_audio_mutex);
+    if ((err = snd_pcm_open (&rx->playback_handle, hw, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK)) < 0) {
+      g_print("audio_open_output: cannot open audio device %s (%s)\n", 
+              hw,
+              snd_strerror (err));
+      g_mutex_unlock(&rx->local_audio_mutex);
+      return err;
+    }
+g_print("audio_open_output: handle=%p\n",rx->playback_handle);
 
-  if ((err = snd_pcm_open (&rx->playback_handle, hw, SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
-    fprintf (stderr, "audio_open_output: cannot open audio device %s (%s)\n", 
-            hw,
-            snd_strerror (err));
-    g_mutex_unlock(&rx->local_audio_mutex);
-    return -1;
+g_print("audio_open_output: trying format %s (%s)\n",snd_pcm_format_name(formats[i]),snd_pcm_format_description(formats[i]));
+    if ((err = snd_pcm_set_params (rx->playback_handle,formats[i],SND_PCM_ACCESS_RW_INTERLEAVED,channels,rate,soft_resample,latency)) < 0) {
+      g_print("audio_open_output: snd_pcm_set_params failed: %s\n",snd_strerror(err));
+      g_mutex_unlock(&rx->local_audio_mutex);
+      audio_close_output(rx);
+      continue;
+    } else {
+g_print("audio_open_output: using format %s (%s)\n",snd_pcm_format_name(formats[i]),snd_pcm_format_description(formats[i]));
+      rx->local_audio_format=formats[i];
+      break;
+    }
   }
 
-fprintf(stderr,"audio_open_output: handle=%p\n",rx->playback_handle);
-
-  if ((err = snd_pcm_set_params (rx->playback_handle,SND_PCM_FORMAT_FLOAT_LE,SND_PCM_ACCESS_RW_INTERLEAVED,channels,rate,soft_resample,latency)) < 0) {
-    g_print("audio_open_output: snd_pcm_set_params failed: %s\n",snd_strerror(err));
-    g_mutex_unlock(&rx->local_audio_mutex);
-    audio_close_output(rx);
-    return -1;
+  if(i>=FORMATS) {
+    g_print("audio_open_output: cannot find usable format\n");
+    return err;
   }
 
   rx->local_audio_buffer_offset=0;
-  rx->local_audio_buffer=g_new0(float,2*rx->local_audio_buffer_size);
+  switch(rx->local_audio_format) {
+  case SND_PCM_FORMAT_S16_LE:
+g_print("audio_open_output: local_audio_buffer: size=%d sample=%ld\n",rx->local_audio_buffer_size,sizeof(gint16));
+    rx->local_audio_buffer=g_new0(gint16,2*rx->local_audio_buffer_size);
+    break;
+  case SND_PCM_FORMAT_S32_LE:
+g_print("audio_open_output: local_audio_buffer: size=%d sample=%ld\n",rx->local_audio_buffer_size,sizeof(gint32));
+    rx->local_audio_buffer=g_new0(gint32,2*rx->local_audio_buffer_size);
+    break;
+  case SND_PCM_FORMAT_FLOAT_LE:
+g_print("audio_open_output: local_audio_buffer: size=%d sample=%ld\n",rx->local_audio_buffer_size,sizeof(float));
+    rx->local_audio_buffer=g_new0(float,2*rx->local_audio_buffer_size);
+    break;
+  }
   
-  fprintf(stderr,"audio_open_output: rx=%d audio_device=%d handle=%p buffer=%p size=%d\n",rx->id,rx->audio_device,rx->playback_handle,rx->local_audio_buffer,rx->local_audio_buffer_size);
+  g_print("audio_open_output: rx=%d audio_device=%d handle=%p buffer=%p size=%d\n",rx->id,rx->audio_device,rx->playback_handle,rx->local_audio_buffer,rx->local_audio_buffer_size);
 
   g_mutex_unlock(&rx->local_audio_mutex);
   return 0;
@@ -137,7 +166,7 @@ int audio_open_input() {
     transmitter->local_microphone=0;
     return -1;
   }
-fprintf(stderr,"audio_open_input: %s\n",transmitter->microphone_name);
+g_print("audio_open_input: %s\n",transmitter->microphone_name);
 
   int i;
   char hw[64];
@@ -158,7 +187,7 @@ fprintf(stderr,"audio_open_input: %s\n",transmitter->microphone_name);
       break;
   }
   
-  fprintf(stderr,"audio_open_input: mic_buffer_size=%d\n",mic_buffer_size);
+  g_print("audio_open_input: mic_buffer_size=%d\n",mic_buffer_size);
   i=0;
   while(transmitter->microphone_name[i]!=' ') {
     hw[i]=transmitter->microphone_name[i];
@@ -167,69 +196,69 @@ fprintf(stderr,"audio_open_input: %s\n",transmitter->microphone_name);
   hw[i]='\0';
 
 
-  fprintf(stderr,"audio_open_input: hw=%s\n",hw);
+  g_print("audio_open_input: hw=%s\n",hw);
 
-  if ((err = snd_pcm_open (&record_handle, hw, SND_PCM_STREAM_CAPTURE, 0)) < 0) {
-    fprintf (stderr, "audio_open_input: cannot open audio device %s (%s)\n",
+  if ((err = snd_pcm_open (&record_handle, hw, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK)) < 0) {
+    g_print("audio_open_input: cannot open audio device %s (%s)\n",
             hw,
             snd_strerror (err));
-    return -1;
+    return err;
   }
 
   if ((err = snd_pcm_set_params (record_handle,SND_PCM_FORMAT_FLOAT_LE,SND_PCM_ACCESS_RW_INTERLEAVED,channels,rate,soft_resample,latency)) < 0) {
     g_print("audio_open_input: snd_pcm_set_params failed: %s\n",snd_strerror(err));
     audio_close_input();
-    return -1;
+    return err;
   }
 
 /*
   if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) {
-    fprintf (stderr, "audio_open_input: cannot allocate hardware parameter structure (%s)\n",
+    g_print("audio_open_input: cannot allocate hardware parameter structure (%s)\n",
             snd_strerror (err));
     audio_close_input();
-    return -1;
+    return err;
   }
 
   if ((err = snd_pcm_hw_params_any (record_handle, hw_params)) < 0) {
-    fprintf (stderr, "audio_open_input: cannot initialize hardware parameter structure (%s)\n",
+    g_print("audio_open_input: cannot initialize hardware parameter structure (%s)\n",
             snd_strerror (err));
     audio_close_input();
-    return -1;
+    return err;
   }
 
   if ((err = snd_pcm_hw_params_set_access (record_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
-    fprintf (stderr, "audio_open_input: cannot set access type (%s)\n",
+    g_print("audio_open_input: cannot set access type (%s)\n",
             snd_strerror (err));
     audio_close_input();
-    return -1;
+    return err;
 }
 
   if ((err = snd_pcm_hw_params_set_format (record_handle, hw_params, SND_PCM_FORMAT_FLOAT_LE)) < 0) {
-    fprintf (stderr, "audio_open_input: cannot set sample format (%s)\n",
+    g_print("audio_open_input: cannot set sample format (%s)\n",
             snd_strerror (err));
     audio_close_input();
-    return -1;
+    return err;
   }
 
   if ((err = snd_pcm_hw_params_set_rate_near (record_handle, hw_params, &rate, &dir)) < 0) {
-    fprintf (stderr, "audio_open_input: cannot set sample rate (%s)\n",
+    g_print("audio_open_input: cannot set sample rate (%s)\n",
             snd_strerror (err));
     audio_close_input();
-    return -1;
+    return err;
   }
 
   if ((err = snd_pcm_hw_params_set_channels (record_handle, hw_params, 1)) < 0) {
-    fprintf (stderr, "audio_open_input: cannot set channel count (%s)\n",
+    g_print("audio_open_input: cannot set channel count (%s)\n",
             snd_strerror (err));
     audio_close_input();
-    return -1;
+    return err;
   }
 
   if ((err = snd_pcm_hw_params (record_handle, hw_params)) < 0) {
-    fprintf (stderr, "audio_open_input: cannot set parameters (%s)\n",
+    g_print("audio_open_input: cannot set parameters (%s)\n",
             snd_strerror (err));
     audio_close_input();
-    return -1;
+    return err;
   }
 
   snd_pcm_hw_params_free (hw_params);
@@ -242,7 +271,7 @@ fprintf(stderr,"audio_open_input: %s\n",transmitter->microphone_name);
   mic_read_thread_id = g_thread_new( "local mic", mic_read_thread, NULL);
   if(!mic_read_thread_id )
   {
-    fprintf(stderr,"g_thread_new failed on mic_read_thread\n");
+    g_print("g_thread_new failed on mic_read_thread\n");
   }
 
 
@@ -250,7 +279,7 @@ fprintf(stderr,"audio_open_input: %s\n",transmitter->microphone_name);
 }
 
 void audio_close_output(RECEIVER *rx) {
-fprintf(stderr,"audio_close_output: rx=%d handle=%p buffer=%p\n",rx->id,rx->playback_handle,rx->local_audio_buffer);
+g_print("audio_close_output: rx=%d handle=%p buffer=%p\n",rx->id,rx->playback_handle,rx->local_audio_buffer);
   g_mutex_lock(&rx->local_audio_mutex);
   if(rx->playback_handle!=NULL) {
     snd_pcm_close (rx->playback_handle);
@@ -285,12 +314,31 @@ int cw_audio_write(float sample){
   snd_pcm_sframes_t delay;
   long rc;
   long trim;
+  float *float_buffer;
+  gint32 *long_buffer;
+  gint16 *short_buffer;
        
   RECEIVER *rx = active_receiver;
  
   if(rx->playback_handle!=NULL && rx->local_audio_buffer!=NULL) {
-    rx->local_audio_buffer[(rx->local_audio_buffer_offset*2)]=sample;
-    rx->local_audio_buffer[(rx->local_audio_buffer_offset*2)+1]=sample;
+
+    switch(rx->local_audio_format) {
+      case SND_PCM_FORMAT_S16_LE:
+        short_buffer=(gint16 *)rx->local_audio_buffer;
+        short_buffer[rx->local_audio_buffer_offset*2]=(gint16)(sample*32767.0F);
+        short_buffer[(rx->local_audio_buffer_offset*2)+1]=(gint16)(sample*32767.0F);
+        break;
+      case SND_PCM_FORMAT_S32_LE:
+        long_buffer=(gint32 *)rx->local_audio_buffer;
+        long_buffer[rx->local_audio_buffer_offset*2]=(gint32)(sample*4294967295.0F);
+        long_buffer[(rx->local_audio_buffer_offset*2)+1]=(gint32)(sample*4294967295.0F);
+        break;
+      case SND_PCM_FORMAT_FLOAT_LE:
+        float_buffer=(float *)rx->local_audio_buffer;
+        float_buffer[rx->local_audio_buffer_offset*2]=sample;
+        float_buffer[(rx->local_audio_buffer_offset*2)+1]=sample;
+        break;
+    }
     rx->local_audio_buffer_offset++;
 
     if(rx->local_audio_buffer_offset>=rx->local_audio_buffer_size) {
@@ -301,7 +349,7 @@ int cw_audio_write(float sample){
       if(snd_pcm_delay(rx->playback_handle,&delay)==0) {
         if(delay>2048) {
           trim=delay-2048;
-fprintf(stderr,"audio delay=%ld trim=%ld\n",delay,trim);
+g_print("audio delay=%ld trim=%ld\n",delay,trim);
         }
       }
 */
@@ -310,8 +358,8 @@ fprintf(stderr,"audio delay=%ld trim=%ld\n",delay,trim);
           if(rc<0) {
             if(rc==-EPIPE) {
               if ((rc = snd_pcm_prepare (rx->playback_handle)) < 0) {
-                fprintf (stderr, "audio_write: cannot prepare audio interface for use %ld (%s)\n", rc, snd_strerror (rc));
-                return -1;
+                g_print("audio_write: cannot prepare audio interface for use %ld (%s)\n", rc, snd_strerror (rc));
+                return rc;
               } else {
                 // ignore short write
               }
@@ -335,6 +383,9 @@ int audio_write(RECEIVER *rx,float left_sample,float right_sample) {
   long rc;
   long trim;
   int mode=modeUSB;
+  float *float_buffer;
+  gint32 *long_buffer;
+  gint16 *short_buffer;
 
   g_mutex_lock(&rx->local_audio_mutex);
 
@@ -357,8 +408,23 @@ int audio_write(RECEIVER *rx,float left_sample,float right_sample) {
   }
 
   if(rx->playback_handle!=NULL && rx->local_audio_buffer!=NULL) {
-    rx->local_audio_buffer[rx->local_audio_buffer_offset*2]=left_sample;
-    rx->local_audio_buffer[(rx->local_audio_buffer_offset*2)+1]=right_sample;
+    switch(rx->local_audio_format) {
+      case SND_PCM_FORMAT_S16_LE:
+        short_buffer=(gint16 *)rx->local_audio_buffer;
+        short_buffer[rx->local_audio_buffer_offset*2]=(gint16)(left_sample*32767.0F);
+        short_buffer[(rx->local_audio_buffer_offset*2)+1]=(gint16)(right_sample*32767.0F);
+        break;
+      case SND_PCM_FORMAT_S32_LE:
+        long_buffer=(gint32 *)rx->local_audio_buffer;
+        long_buffer[rx->local_audio_buffer_offset*2]=(gint32)(left_sample*4294967295.0F);
+        long_buffer[(rx->local_audio_buffer_offset*2)+1]=(gint32)(right_sample*4294967295.0F);
+        break;
+      case SND_PCM_FORMAT_FLOAT_LE:
+        float_buffer=(float *)rx->local_audio_buffer;
+        float_buffer[rx->local_audio_buffer_offset*2]=left_sample;
+        float_buffer[(rx->local_audio_buffer_offset*2)+1]=right_sample;
+        break;
+    }
     rx->local_audio_buffer_offset++;
 
     if(rx->local_audio_buffer_offset>=rx->local_audio_buffer_size) {
@@ -369,7 +435,7 @@ int audio_write(RECEIVER *rx,float left_sample,float right_sample) {
       if(snd_pcm_delay(rx->playback_handle,&delay)==0) {
         if(delay>max_delay) {
           trim=delay-max_delay;
-fprintf(stderr,"audio delay=%ld trim=%ld audio_buffer_size=%d\n",delay,trim,rx->local_audio_buffer_size);
+g_print("audio delay=%ld trim=%ld audio_buffer_size=%d\n",delay,trim,rx->local_audio_buffer_size);
         }
       }
 
@@ -378,10 +444,10 @@ fprintf(stderr,"audio delay=%ld trim=%ld audio_buffer_size=%d\n",delay,trim,rx->
           if(rc<0) {
             if(rc==-EPIPE) {
               if ((rc = snd_pcm_prepare (rx->playback_handle)) < 0) {
-                fprintf (stderr, "audio_write: cannot prepare audio interface for use %ld (%s)\n", rc, snd_strerror (rc));
+                g_print("audio_write: cannot prepare audio interface for use %ld (%s)\n", rc, snd_strerror (rc));
                 rx->local_audio_buffer_offset=0;
                 g_mutex_unlock(&rx->local_audio_mutex);
-                return -1;
+                return rc;
               }
             } else {
               // ignore short write
@@ -399,20 +465,20 @@ fprintf(stderr,"audio delay=%ld trim=%ld audio_buffer_size=%d\n",delay,trim,rx->
 static void *mic_read_thread(gpointer arg) {
   int rc;
   if ((rc = snd_pcm_prepare (record_handle)) < 0) {
-    fprintf (stderr, "mic_read_thread: cannot prepare audio interface for use (%s)\n",
+    g_print("mic_read_thread: cannot prepare audio interface for use (%s)\n",
             snd_strerror (rc));
     return NULL;
   }
-fprintf(stderr,"mic_read_thread: mic_buffer_size=%d\n",mic_buffer_size);
+g_print("mic_read_thread: mic_buffer_size=%d\n",mic_buffer_size);
   while(running) {
     if ((rc = snd_pcm_readi (record_handle, mic_buffer, mic_buffer_size)) != mic_buffer_size) {
       if(running) {
         if(rc<0) {
-          fprintf (stderr, "mic_read_thread: read from audio interface failed (%s)\n",
+          g_print("mic_read_thread: read from audio interface failed (%s)\n",
                   snd_strerror (rc));
           running=FALSE;
         } else {
-          fprintf(stderr,"mic_read_thread: read %d\n",rc);
+          g_print("mic_read_thread: read %d\n",rc);
         }
       }
     } else {
@@ -434,7 +500,7 @@ fprintf(stderr,"mic_read_thread: mic_buffer_size=%d\n",mic_buffer_size);
       }
     }
   }
-fprintf(stderr,"mic_read_thread: exiting\n");
+g_print("mic_read_thread: exiting\n");
   return NULL;
 }
 
@@ -447,7 +513,7 @@ void audio_get_cards() {
   char *device_id;
   int card = -1;
 
-fprintf(stderr,"audio_get_cards\n");
+g_print("audio_get_cards\n");
 
   n_input_devices=0;
   n_output_devices=0;
@@ -486,7 +552,7 @@ fprintf(stderr,"audio_get_cards\n");
           strcpy(input_devices[n_input_devices].description,device_id);
           input_devices[n_input_devices].index=i;
           n_input_devices++;
-fprintf(stderr,"input_device: %s\n",device_id);
+g_print("input_device: %s\n",device_id);
         }
       }
 
@@ -502,7 +568,7 @@ fprintf(stderr,"input_device: %s\n",device_id);
           strcpy(output_devices[n_output_devices].description,device_id);
           input_devices[n_output_devices].index=i;
           n_output_devices++;
-fprintf(stderr,"output_device: %s\n",device_id);
+g_print("output_device: %s\n",device_id);
         }
       }
     }
@@ -536,7 +602,7 @@ fprintf(stderr,"output_device: %s\n",device_id);
           output_devices[n_output_devices].description[i]='\0';
           input_devices[n_output_devices].index=i;
           n_output_devices++;
-fprintf(stderr,"output_device: name=%s descr=%s\n",name,descr);
+g_print("output_device: name=%s descr=%s\n",name,descr);
         }
       }
     }
@@ -551,4 +617,8 @@ fprintf(stderr,"output_device: name=%s descr=%s\n",name,descr);
   }
   snd_device_name_free_hint(hints);
 }
+
+char * audio_get_error_string(int err) {
+  return (char *)snd_strerror(err);
+}
 #endif
diff --git a/audio.h b/audio.h
index 7fe7d6f84b81c1d1f13027704fd96e3b19a921ea..a477b3dae5fc3fb63be4a19b7907105964ab55af 100644 (file)
--- a/audio.h
+++ b/audio.h
@@ -44,4 +44,5 @@ extern void audio_close_output(RECEIVER *rx);
 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);
 #endif
index 10a9cacebb83e366dc494c0470d5d1f0d7d3ae5a..2931fc22743f11fffd3b0bee79d5f574e9460595 100644 (file)
@@ -469,6 +469,8 @@ fprintf(stderr,"receiver_restore_state: id=%d\n",rx->id);
   sprintf(name,"receiver.%d.local_audio_buffer_size",rx->id);
   value=getProperty(name);
   if(value) rx->local_audio_buffer_size=atoi(value);
+// force minimum of 2048 samples for buffer size
+  if(rx->local_audio_buffer_size<2048) rx->local_audio_buffer_size=2048;
   sprintf(name,"receiver.%d.audio_name",rx->id);
   value=getProperty(name);
   if(value) {
@@ -816,9 +818,9 @@ fprintf(stderr,"create_pure_signal_receiver: id=%d buffer_size=%d\n",id,buffer_s
     // display only the central part.
     // 
     if (protocol == ORIGINAL_PROTOCOL) {
-       rx->pixels=2*(sample_rate/48000) * width;
+       rx->pixels=(sample_rate/48000) * width;
     } else {
-      rx->pixels = 8*width;
+      rx->pixels = 4*width;
     }
   }
   // allocate buffers
@@ -868,7 +870,7 @@ fprintf(stderr,"create_pure_signal_receiver: id=%d buffer_size=%d\n",id,buffer_s
   
   rx->playback_handle=NULL;
   rx->local_audio_buffer=NULL;
-  rx->local_audio_buffer_size=1024;
+  rx->local_audio_buffer_size=2048;
   rx->local_audio=0;
   g_mutex_init(&rx->local_audio_mutex);
   rx->audio_name=NULL;
@@ -1015,7 +1017,7 @@ fprintf(stderr,"create_receiver: id=%d default adc=%d\n",rx->id, rx->adc);
   rx->local_audio=0;
   g_mutex_init(&rx->local_audio_mutex);
   rx->local_audio_buffer=NULL;
-  rx->local_audio_buffer_size=1024;
+  rx->local_audio_buffer_size=2048;
   rx->audio_name=NULL;
   rx->mute_when_not_active=0;
   rx->audio_channel=STEREO;
@@ -1182,11 +1184,11 @@ g_print("receiver_change_sample_rate: id=%d rate=%d scale=%d buffer_size=%d outp
   if (rx->id == PS_RX_FEEDBACK) {
     float *fp, *ofp;
     if (protocol == ORIGINAL_PROTOCOL) {
-      rx->pixels = 2* scale * rx->width;
+      rx->pixels = scale * rx->width;
     } else {
       // We should never arrive here, since the sample rate of the
       // PS feedback receiver is fixed.
-      rx->pixels = 8 * rx->width;
+      rx->pixels = 4 * rx->width;
     }
     // make sure pixel_samples is always a valid pointer
     // ... probably pure DL1YCF's paranoia
index 0bc53454409083bc5550af4aee3c192638d586ff..b15277464c7ffa563ef4b5d00237c84d7e43fa5d 100644 (file)
@@ -116,10 +116,11 @@ typedef struct _receiver {
   PaStream *playback_handle;
 #else
   snd_pcm_t *playback_handle;
+  snd_pcm_format_t local_audio_format;
 #endif
   gint local_audio_buffer_size;
   gint local_audio_buffer_offset;
-  float *local_audio_buffer;
+  void *local_audio_buffer;
   GMutex local_audio_mutex;
 
   gint low_latency;