*/
+#include <gtk/gtk.h>
+
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sched.h>
#include <semaphore.h>
-#include <pulse/simple.h>
-#include <pulse/error.h>
+#include <alsa/asoundlib.h>
#include "audio.h"
+#include "new_protocol.h"
#include "radio.h"
int audio = 0;
-//int audio_buffer_size = 2016; // samples (both left and right)
int audio_buffer_size = 256; // samples (both left and right)
+int mic_buffer_size = 720; // samples (both left and right)
-static pa_simple *stream;
+static snd_pcm_t *playback_handle=NULL;
+static snd_pcm_t *record_handle=NULL;
// each buffer contains 63 samples of left and right audio at 16 bits
#define AUDIO_SAMPLES 63
#define AUDIO_BUFFERS 10
#define AUDIO_BUFFER_SIZE (AUDIO_SAMPLE_SIZE*AUDIO_CHANNELS*audio_buffer_size)
-static unsigned char *audio_buffer;
+#define MIC_BUFFER_SIZE (AUDIO_SAMPLE_SIZE*AUDIO_CHANNELS*mic_buffer_size)
+
+static unsigned char *audio_buffer=NULL;
static int audio_offset=0;
-int audio_init() {
+static unsigned char *mic_buffer=NULL;
- static const pa_sample_spec spec= {
- .format = PA_SAMPLE_S16RE,
- .rate = 48000,
- .channels = 2
- };
+static pthread_t mic_read_thread_id;
- int error;
+static int running=FALSE;
-fprintf(stderr,"audio_init audio_buffer_size=%d\n",audio_buffer_size);
+static void *mic_read_thread(void *arg);
- audio_buffer=(unsigned char *)malloc(AUDIO_BUFFER_SIZE);
+char *input_devices[16];
+int n_input_devices=0;
+int n_selected_input_device=-1;
- if (!(stream = pa_simple_new(NULL, "pihpsdr", PA_STREAM_PLAYBACK, NULL, "playback", &spec, NULL, NULL, &error))) {
- fprintf(stderr, __FILE__": pa_simple_new() failed: %s\n", pa_strerror(error));
- return -1;
- }
+char *output_devices[16];
+int n_output_devices=0;
+int n_selected_output_device=-1;
+
+int audio_open_output() {
+ int err;
+ snd_pcm_hw_params_t *hw_params;
+ int rate=48000;
+ int dir=0;
+
+
+ if(n_selected_output_device<0 || n_selected_output_device>=n_output_devices) {
+ n_selected_output_device=-1;
+ return -1;
+ }
+
+ int i;
+ char hw[16];
+ char *selected=output_devices[n_selected_output_device];
+
+fprintf(stderr,"audio_open_output: selected=%d:%s\n",n_selected_output_device,selected);
+
+ i=0;
+ while(selected[i]!=' ') {
+ hw[i]=selected[i];
+ i++;
+ }
+ hw[i]='\0';
+
+ if ((err = snd_pcm_open (&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));
+ return -1;
+ }
- return 0;
+
+ if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) {
+ fprintf (stderr, "audio_open_output: cannot allocate hardware parameter structure (%s)\n",
+ snd_strerror (err));
+ return -1;
+ }
+
+ if ((err = snd_pcm_hw_params_any (playback_handle, hw_params)) < 0) {
+ fprintf (stderr, "audio_open_output: cannot initialize hardware parameter structure (%s)\n",
+ snd_strerror (err));
+ return -1;
+ }
+
+ if ((err = snd_pcm_hw_params_set_access (playback_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
+ fprintf (stderr, "audio_open_output: cannot set access type (%s)\n",
+ snd_strerror (err));
+ return -1;
}
+
+ if ((err = snd_pcm_hw_params_set_format (playback_handle, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) {
+ fprintf (stderr, "audio_open_output: cannot set sample format (%s)\n",
+ snd_strerror (err));
+ return -1;
+ }
+
+
+ if ((err = snd_pcm_hw_params_set_rate_near (playback_handle, hw_params, &rate, &dir)) < 0) {
+ fprintf (stderr, "audio_open_output: cannot set sample rate (%s)\n",
+ snd_strerror (err));
+ return -1;
+ }
+
+ if ((err = snd_pcm_hw_params_set_channels (playback_handle, hw_params, 2)) < 0) {
+ fprintf (stderr, "audio_open_output: cannot set channel count (%s)\n",
+ snd_strerror (err));
+ return -1;
+ }
+
+ if ((err = snd_pcm_hw_params (playback_handle, hw_params)) < 0) {
+ fprintf (stderr, "audio_open_output: cannot set parameters (%s)\n",
+ snd_strerror (err));
+ return -1;
+ }
+
+ snd_pcm_hw_params_free (hw_params);
-void audio_close() {
- pa_simple_free(stream);
+ audio_offset=0;
+ audio_buffer=(unsigned char *)malloc(AUDIO_BUFFER_SIZE);
+
+ return 0;
+}
+
+int audio_open_input() {
+ int err;
+ snd_pcm_hw_params_t *hw_params;
+ int rate=48000;
+ int dir=0;
+
+ if(n_selected_output_device<0 || n_selected_output_device>=n_output_devices) {
+ n_selected_output_device=-1;
+ return -1;
+ }
+
+ int i;
+ char hw[16];
+ char *selected=input_devices[n_selected_input_device];
+ fprintf(stderr,"audio_open_input: selected=%d:%s\n",n_selected_input_device,selected);
+
+ i=0;
+ while(selected[i]!=' ') {
+ hw[i]=selected[i];
+ i++;
+ }
+ hw[i]='\0';
+
+
+ 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",
+ hw,
+ snd_strerror (err));
+ return -1;
+ }
+
+ if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) {
+ fprintf (stderr, "audio_open_input: cannot allocate hardware parameter structure (%s)\n",
+ snd_strerror (err));
+ return -1;
+ }
+
+ if ((err = snd_pcm_hw_params_any (record_handle, hw_params)) < 0) {
+ fprintf (stderr, "audio_open_input: cannot initialize hardware parameter structure (%s)\n",
+ snd_strerror (err));
+ return -1;
+ }
+
+ 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",
+ snd_strerror (err));
+ return -1;
}
-void audio_write(short left_sample,short right_sample) {
- int result;
+ if ((err = snd_pcm_hw_params_set_format (record_handle, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) {
+ fprintf (stderr, "audio_open_input: cannot set sample format (%s)\n",
+ snd_strerror (err));
+ return -1;
+ }
+
+ 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",
+ snd_strerror (err));
+ return -1;
+ }
+
+ 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",
+ snd_strerror (err));
+ return -1;
+ }
+
+ if ((err = snd_pcm_hw_params (record_handle, hw_params)) < 0) {
+ fprintf (stderr, "audio_open_input: cannot set parameters (%s)\n",
+ snd_strerror (err));
+ return -1;
+ }
+
+ snd_pcm_hw_params_free (hw_params);
+
+ mic_buffer=(unsigned char *)malloc(MIC_BUFFER_SIZE);
+
+ running=TRUE;
+ err=pthread_create(&mic_read_thread_id,NULL,mic_read_thread,NULL);
+ if(err != 0) {
+ fprintf(stderr,"pthread_create failed on mic_read_thread: rc=%d\n", err);
+ return -1;
+ }
+
+ return 0;
+}
+
+void audio_close_output() {
+ if(playback_handle!=NULL) {
+ snd_pcm_close (playback_handle);
+ playback_handle=NULL;
+ }
+ if(audio_buffer!=NULL) {
+ free(audio_buffer);
+ audio_buffer=NULL;
+ }
+}
+
+void audio_close_input() {
+ running=FALSE;
+ if(record_handle!=NULL) {
+ snd_pcm_close (record_handle);
+ record_handle=NULL;
+ }
+ if(mic_buffer!=NULL) {
+ free(mic_buffer);
+ mic_buffer=NULL;
+ }
+}
+
+int audio_write(short left_sample,short right_sample) {
int error;
- audio_buffer[audio_offset++]=left_sample>>8;
- audio_buffer[audio_offset++]=left_sample;
- audio_buffer[audio_offset++]=right_sample>>8;
- audio_buffer[audio_offset++]=right_sample;
-
- if(audio_offset==AUDIO_BUFFER_SIZE) {
-//fprintf(stderr,"pa_simple_write...");
- result=pa_simple_write(stream, audio_buffer, (size_t)AUDIO_BUFFER_SIZE, &error);
-//fprintf(stderr,"%d\n",result);
- if(result< 0) {
- fprintf(stderr, __FILE__": pa_simple_write() failed: %s\n", pa_strerror(error));
- //_exit(1);
+ if(playback_handle!=NULL && audio_buffer!=NULL) {
+ audio_buffer[audio_offset++]=left_sample;
+ audio_buffer[audio_offset++]=left_sample>>8;
+ audio_buffer[audio_offset++]=right_sample;
+ audio_buffer[audio_offset++]=right_sample>>8;
+
+ if(audio_offset==AUDIO_BUFFER_SIZE) {
+
+ if ((error = snd_pcm_writei (playback_handle, audio_buffer, audio_buffer_size)) != audio_buffer_size) {
+ if(error==-EPIPE) {
+ if ((error = snd_pcm_prepare (playback_handle)) < 0) {
+ fprintf (stderr, "audio_write: cannot prepare audio interface for use (%s)\n",
+ snd_strerror (error));
+ return -1;
+ }
+ if ((error = snd_pcm_writei (playback_handle, audio_buffer, audio_buffer_size)) != audio_buffer_size) {
+ fprintf (stderr, "audio_write: write to audio interface failed (%s)\n",
+ snd_strerror (error));
+ return -1;
+ }
+ }
+ }
+ audio_offset=0;
+ }
+ }
+ return 0;
+}
+
+static void *mic_read_thread(void *arg) {
+ int error;
+ if ((error = snd_pcm_prepare (record_handle)) < 0) {
+ fprintf (stderr, "mic_read_thread: cannot prepare audio interface for use (%s)\n",
+ snd_strerror (error));
+ return;
+ }
+ while(running) {
+ if ((error = snd_pcm_readi (record_handle, mic_buffer, mic_buffer_size)) != mic_buffer_size) {
+ if(running) {
+ fprintf (stderr, "mic_read_thread: read from audio interface failed (%s)\n",
+ snd_strerror (error));
+ running=FALSE;
+ }
+ break;
+ } else {
+ // process the mic input
+ switch(protocol) {
+ case ORIGINAL_PROTOCOL:
+ break;
+ case NEW_PROTOCOL:
+ new_protocol_process_local_mic(mic_buffer,1);
+ break;
+ default:
+ break;
+ }
}
- audio_offset=0;
}
+
}
+void audio_get_cards(int input) {
+ snd_ctl_card_info_t *info;
+ snd_pcm_info_t *pcminfo;
+ snd_ctl_card_info_alloca(&info);
+ snd_pcm_info_alloca(&pcminfo);
+ int i;
+
+ if(input) {
+ for(i=0;i<n_input_devices;i++) {
+ free(input_devices[i]);
+ }
+ n_input_devices=0;
+ } else {
+ for(i=0;i<n_output_devices;i++) {
+ free(output_devices[i]);
+ }
+ n_output_devices=0;
+ }
+ int card = -1;
+ while (snd_card_next(&card) >= 0 && card >= 0) {
+ int err = 0;
+ snd_ctl_t *handle;
+ char name[20];
+ snprintf(name, sizeof(name), "hw:%d", card);
+ if ((err = snd_ctl_open(&handle, name, 0)) < 0) {
+ continue;
+ }
+
+ if ((err = snd_ctl_card_info(handle, info)) < 0) {
+ snd_ctl_close(handle);
+ continue;
+ }
+
+ int dev = -1;
+ while (snd_ctl_pcm_next_device(handle, &dev) >= 0 && dev >= 0) {
+ snd_pcm_info_set_device(pcminfo, dev);
+ snd_pcm_info_set_subdevice(pcminfo, 0);
+ snd_pcm_info_set_stream(pcminfo, input ? SND_PCM_STREAM_CAPTURE
+ : SND_PCM_STREAM_PLAYBACK);
+ if ((err = snd_ctl_pcm_info(handle, pcminfo)) < 0) {
+ continue;
+ }
+
+ char *device_id=malloc(64);
+
+ snprintf(device_id, 64, "plughw:%d,%d %s", card, dev, snd_ctl_card_info_get_name(info));
+ if(input) {
+fprintf(stderr,"input_device: %s\n",device_id);
+ input_devices[n_input_devices++]=device_id;
+ } else {
+ output_devices[n_output_devices++]=device_id;
+fprintf(stderr,"output_device: %s\n",device_id);
+ }
+
+ }
+
+ snd_ctl_close(handle);
+
+ }
+}
#ifndef _AUDIO_H
#define _AUDIO_H
-extern int audio;
-extern int audio_buffer_size;
+extern char *input_devices[];
+extern int n_input_devices;
+extern int n_selected_input_device;
-int audio_init();
-void audio_close();
-void audio_write(short left_sample,short right_sample);
-/*
-void audio_write(double *buffer,int samples);
-*/
+extern char *output_devices[];
+extern int n_output_devices;
+extern int n_selected_output_device;
+
+extern int audio_open_output();
+extern int audio_open_input();
+extern void audio_close_output();
+extern void audio_close_input();
+extern int audio_write(short left_sample,short right_sample);
+extern void audio_get_cards();
#endif
lime_protocol_set_frequency(saved_frequency);
}
-fprintf(stderr,"lime_protocol_init: audio_init\n");
- if(audio_init()!=0) {
+fprintf(stderr,"lime_protocol_init: audio_open_output\n");
+ if(audio_open_output()!=0) {
local_audio=false;
- fprintf(stderr,"audio_init failed\n");
+ fprintf(stderr,"audio_open_output failed\n");
}
fprintf(stderr,"lime_protocol_init: create receive_thread\n");
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
+
+#include "audio.h"
#include "main.h"
#include "channel.h"
#include "discovered.h"
fprintf(stderr,"init\n");
+ audio_get_cards(0);
+ audio_get_cards(1);
+
cursor_arrow=gdk_cursor_new(GDK_ARROW);
cursor_watch=gdk_cursor_new(GDK_WATCH);
static void local_audio_cb(GtkWidget *widget, gpointer data) {
if(local_audio) {
local_audio=0;
- audio_close();
+ audio_close_output();
} else {
- if(audio_init()==0) {
+ if(audio_open_output()==0) {
local_audio=1;
}
}
}
+static void local_output_changed_cb(GtkWidget *widget, gpointer data) {
+ n_selected_output_device=(int)(long)data;
+fprintf(stderr,"local_output_changed: %d\n",n_selected_output_device);
+
+ if(local_audio) {
+ audio_close_output();
+ if(audio_open_output()==0) {
+ local_audio=1;
+ }
+ }
+}
+
+static void local_microphone_cb(GtkWidget *widget, gpointer data) {
+ if(local_microphone) {
+ local_microphone=0;
+ audio_close_input();
+ } else {
+ if(audio_open_input()==0) {
+ local_microphone=1;
+ }
+ }
+}
+
+static void local_input_changed_cb(GtkWidget *widget, gpointer data) {
+ n_selected_input_device=(int)(long)data;
+fprintf(stderr,"local_input_changed: %d\n",n_selected_input_device);
+ if(local_microphone) {
+ audio_close_input();
+ if(audio_open_input()==0) {
+ local_microphone=1;
+ }
+ }
+}
+
static void toolbar_dialog_buttons_cb(GtkWidget *widget, gpointer data) {
toolbar_dialog_buttons=toolbar_dialog_buttons==1?0:1;
update_toolbar_labels();
GtkWidget *general_label=gtk_label_new("General");
GtkWidget *general_grid=gtk_grid_new();
+ gtk_grid_set_column_spacing (GTK_GRID(general_grid),10);
//gtk_grid_set_row_homogeneous(GTK_GRID(general_grid),TRUE);
- gtk_grid_set_column_homogeneous(GTK_GRID(general_grid),TRUE);
+ //gtk_grid_set_column_homogeneous(GTK_GRID(general_grid),TRUE);
GtkWidget *vfo_divisor_label=gtk_label_new("VFO Encoder Divisor: ");
g_signal_connect(rx_preamp_b,"toggled",G_CALLBACK(rx_preamp_cb),NULL);
*/
- GtkWidget *linein_b=gtk_check_button_new_with_label("Mic Line In");
- //gtk_widget_override_font(linein_b, pango_font_description_from_string("Arial 18"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (linein_b), mic_linein);
- gtk_widget_show(linein_b);
- gtk_grid_attach(GTK_GRID(general_grid),linein_b,1,2,1,1);
- g_signal_connect(linein_b,"toggled",G_CALLBACK(linein_cb),NULL);
-
- GtkWidget *micboost_b=gtk_check_button_new_with_label("Mic Boost");
- //gtk_widget_override_font(micboost_b, pango_font_description_from_string("Arial 18"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (micboost_b), mic_boost);
- gtk_widget_show(micboost_b);
- gtk_grid_attach(GTK_GRID(general_grid),micboost_b,1,3,1,1);
- g_signal_connect(micboost_b,"toggled",G_CALLBACK(micboost_cb),NULL);
-
- GtkWidget *local_audio_b=gtk_check_button_new_with_label("Local Audio");
- //gtk_widget_override_font(local_audio_b, pango_font_description_from_string("Arial 18"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (local_audio_b), local_audio);
- gtk_widget_show(local_audio_b);
- gtk_grid_attach(GTK_GRID(general_grid),local_audio_b,1,4,1,1);
- g_signal_connect(local_audio_b,"toggled",G_CALLBACK(local_audio_cb),NULL);
-
- GtkWidget *b_toolbar_dialog_buttons=gtk_check_button_new_with_label("Buttons Display Dialog");
- //gtk_widget_override_font(b_toolbar_dialog_buttons, pango_font_description_from_string("Arial 18"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_toolbar_dialog_buttons), toolbar_dialog_buttons);
- gtk_widget_show(b_toolbar_dialog_buttons);
- gtk_grid_attach(GTK_GRID(general_grid),b_toolbar_dialog_buttons,1,5,1,1);
- g_signal_connect(b_toolbar_dialog_buttons,"toggled",G_CALLBACK(toolbar_dialog_buttons_cb),(gpointer *)NULL);
-
if((protocol==NEW_PROTOCOL && device==NEW_DEVICE_ORION) ||
(protocol==NEW_PROTOCOL && device==NEW_DEVICE_ORION2) ||
(protocol==ORIGINAL_PROTOCOL && device==DEVICE_ORION)) {
//gtk_widget_override_font(ptt_ring_b, pango_font_description_from_string("Arial 18"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ptt_ring_b), mic_ptt_tip_bias_ring==0);
gtk_widget_show(ptt_ring_b);
- gtk_grid_attach(GTK_GRID(general_grid),ptt_ring_b,1,6,1,1);
+ gtk_grid_attach(GTK_GRID(general_grid),ptt_ring_b,1,5,1,1);
g_signal_connect(ptt_ring_b,"pressed",G_CALLBACK(ptt_ring_cb),NULL);
GtkWidget *ptt_tip_b=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(ptt_ring_b),"PTT On Tip, Mic and Bias on Ring");
//gtk_widget_override_font(ptt_tip_b, pango_font_description_from_string("Arial 18"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ptt_tip_b), mic_ptt_tip_bias_ring==1);
gtk_widget_show(ptt_tip_b);
- gtk_grid_attach(GTK_GRID(general_grid),ptt_tip_b,1,7,1,1);
+ gtk_grid_attach(GTK_GRID(general_grid),ptt_tip_b,1,6,1,1);
g_signal_connect(ptt_tip_b,"pressed",G_CALLBACK(ptt_tip_cb),NULL);
GtkWidget *ptt_b=gtk_check_button_new_with_label("PTT Enabled");
//gtk_widget_override_font(ptt_b, pango_font_description_from_string("Arial 18"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ptt_b), mic_ptt_enabled);
gtk_widget_show(ptt_b);
- gtk_grid_attach(GTK_GRID(general_grid),ptt_b,1,8,1,1);
+ gtk_grid_attach(GTK_GRID(general_grid),ptt_b,1,7,1,1);
g_signal_connect(ptt_b,"toggled",G_CALLBACK(ptt_cb),NULL);
GtkWidget *bias_b=gtk_check_button_new_with_label("BIAS Enabled");
//gtk_widget_override_font(bias_b, pango_font_description_from_string("Arial 18"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (bias_b), mic_bias_enabled);
gtk_widget_show(bias_b);
- gtk_grid_attach(GTK_GRID(general_grid),bias_b,1,9,1,1);
+ gtk_grid_attach(GTK_GRID(general_grid),bias_b,1,8,1,1);
g_signal_connect(bias_b,"toggled",G_CALLBACK(bias_cb),NULL);
}
//gtk_widget_override_font(alex_b, pango_font_description_from_string("Arial 18"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (alex_b), filter_board==ALEX);
gtk_widget_show(alex_b);
- gtk_grid_attach(GTK_GRID(general_grid),alex_b,2,2,1,1);
+ gtk_grid_attach(GTK_GRID(general_grid),alex_b,1,2,1,1);
GtkWidget *apollo_b=gtk_check_button_new_with_label("APOLLO");
//gtk_widget_override_font(apollo_b, pango_font_description_from_string("Arial 18"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (apollo_b), filter_board==APOLLO);
gtk_widget_show(apollo_b);
- gtk_grid_attach(GTK_GRID(general_grid),apollo_b,2,3,1,1);
+ gtk_grid_attach(GTK_GRID(general_grid),apollo_b,1,3,1,1);
g_signal_connect(alex_b,"toggled",G_CALLBACK(alex_cb),apollo_b);
g_signal_connect(apollo_b,"toggled",G_CALLBACK(apollo_cb),alex_b);
id=gtk_notebook_append_page(GTK_NOTEBOOK(notebook),general_grid,general_label);
+
+
+ GtkWidget *audio_label=gtk_label_new("Audio");
+ GtkWidget *audio_grid=gtk_grid_new();
+ //gtk_grid_set_row_homogeneous(GTK_GRID(audio_grid),TRUE);
+ gtk_grid_set_column_spacing (GTK_GRID(audio_grid),10);
+
+ if(protocol==ORIGINAL_PROTOCOL || protocol==NEW_PROTOCOL) {
+ GtkWidget *linein_b=gtk_check_button_new_with_label("Mic Line In");
+ //gtk_widget_override_font(linein_b, pango_font_description_from_string("Arial 18"));
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (linein_b), mic_linein);
+ gtk_widget_show(linein_b);
+ gtk_grid_attach(GTK_GRID(audio_grid),linein_b,0,0,1,1);
+ g_signal_connect(linein_b,"toggled",G_CALLBACK(linein_cb),NULL);
+
+ GtkWidget *micboost_b=gtk_check_button_new_with_label("Mic Boost");
+ //gtk_widget_override_font(micboost_b, pango_font_description_from_string("Arial 18"));
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (micboost_b), mic_boost);
+ gtk_widget_show(micboost_b);
+ gtk_grid_attach(GTK_GRID(audio_grid),micboost_b,0,1,1,1);
+ g_signal_connect(micboost_b,"toggled",G_CALLBACK(micboost_cb),NULL);
+ }
+
+
+ if(n_output_devices>0) {
+ GtkWidget *local_audio_b=gtk_check_button_new_with_label("Local Audio");
+ //gtk_widget_override_font(local_audio_b, pango_font_description_from_string("Arial 18"));
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (local_audio_b), local_audio);
+ gtk_widget_show(local_audio_b);
+ gtk_grid_attach(GTK_GRID(audio_grid),local_audio_b,1,0,1,1);
+ g_signal_connect(local_audio_b,"toggled",G_CALLBACK(local_audio_cb),NULL);
+
+ for(i=0;i<n_output_devices;i++) {
+ GtkWidget *output;
+ if(i==0) {
+ output=gtk_radio_button_new_with_label(NULL,output_devices[i]);
+ } else {
+ output=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(output),output_devices[i]);
+ }
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (output), n_selected_output_device==i);
+ gtk_widget_show(output);
+ gtk_grid_attach(GTK_GRID(audio_grid),output,1,i+1,1,1);
+ g_signal_connect(output,"pressed",G_CALLBACK(local_output_changed_cb),(gpointer *)i);
+ }
+ }
+
+ if(n_input_devices>0) {
+ GtkWidget *local_audio_b=gtk_check_button_new_with_label("Microphone Audio");
+ //gtk_widget_override_font(local_audio_b, pango_font_description_from_string("Arial 18"));
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (local_audio_b), local_audio);
+ gtk_widget_show(local_audio_b);
+ gtk_grid_attach(GTK_GRID(audio_grid),local_audio_b,2,0,1,1);
+ g_signal_connect(local_audio_b,"toggled",G_CALLBACK(local_input_changed_cb),NULL);
+
+ for(i=0;i<n_input_devices;i++) {
+ GtkWidget *input;
+ if(i==0) {
+ input=gtk_radio_button_new_with_label(NULL,input_devices[i]);
+ } else {
+ input=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(input),input_devices[i]);
+ }
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (input), n_selected_input_device==i);
+ gtk_widget_show(input);
+ gtk_grid_attach(GTK_GRID(audio_grid),input,2,i+1,1,1);
+ g_signal_connect(input,"pressed",G_CALLBACK(local_microphone_cb),(gpointer *)i);
+ }
+ }
+
+ id=gtk_notebook_append_page(GTK_NOTEBOOK(notebook),audio_grid,audio_label);
+
+
GtkWidget *ant_label=gtk_label_new("Ant");
ant_grid=gtk_grid_new();
gtk_grid_set_row_homogeneous(GTK_GRID(ant_grid),TRUE);
gtk_grid_attach(GTK_GRID(display_grid),b_display_toolbar,3,7,1,1);
g_signal_connect(b_display_toolbar,"toggled",G_CALLBACK(display_toolbar_cb),(gpointer *)NULL);
+ GtkWidget *b_toolbar_dialog_buttons=gtk_check_button_new_with_label("Buttons Display Dialog");
+ //gtk_widget_override_font(b_toolbar_dialog_buttons, pango_font_description_from_string("Arial 18"));
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_toolbar_dialog_buttons), toolbar_dialog_buttons);
+ gtk_widget_show(b_toolbar_dialog_buttons);
+ gtk_grid_attach(GTK_GRID(display_grid),b_toolbar_dialog_buttons,0,8,1,1);
+ g_signal_connect(b_toolbar_dialog_buttons,"toggled",G_CALLBACK(toolbar_dialog_buttons_cb),(gpointer *)NULL);
id=gtk_notebook_append_page(GTK_NOTEBOOK(notebook),display_grid,display_label);
fprintf(stderr,"menu_init: width=%d height=%d\n",width,height);
+ audio_get_cards(1); // input
+ audio_get_cards(0); // output
+
parent_window=parent;
box=gtk_box_new(GTK_ORIENTATION_HORIZONTAL,0);
fprintf(stderr,"new_protocol_init: %d\n",rx);
if(local_audio) {
- if(audio_init()!=0) {
- fprintf(stderr,"audio_init failed\n");
+ if(audio_open_output()!=0) {
+ fprintf(stderr,"audio_open_output failed\n");
local_audio=0;
}
}
+ if(local_microphone) {
+ if(audio_open_input()!=0) {
+ fprintf(stderr,"audio_open_input failed\n");
+ local_microphone=0;
+ }
+ }
+
new_protocol_calc_buffers();
rc=sem_init(&response_sem, 0, 0);
buffer[331]=phase>>8;
buffer[332]=phase;
- double d=drive;
- if(tune) {
- d=tune_drive;
+ int power=0;
+ if(isTransmitting()) {
+ double d=drive;
+ if(tune) {
+ d=tune_drive;
+ }
+ d=d*((double)band->pa_calibration/100.0);
+ power=(int)(d*255.0);
}
- d=d*((double)band->pa_calibration/100.0);
- int power=(int)(d*255.0);
+
buffer[345]=power&0xFF;
fprintf(stderr,"power=%d\n",power);
process_high_priority(buffer);
break;
case MIC_LINE_TO_HOST_PORT:
- process_mic_data(buffer);
+ if(!local_microphone) {
+ process_mic_data(buffer);
+ }
break;
default:
break;
double micsampledouble;
sequence=((buffer[0]&0xFF)<<24)+((buffer[1]&0xFF)<<16)+((buffer[2]&0xFF)<<8)+(buffer[3]&0xFF);
- if(isTransmitting()) {
+// if(isTransmitting()) {
b=4;
int i,j,s;
for(i=0;i<720;i++) {
micsample = (int)((signed char) buffer[b++]) << 8;
micsample |= (int)((unsigned char)buffer[b++] & 0xFF);
#ifdef FREEDV
- if(mode==modeFREEDV) {
+ if(mode==modeFREEDV && isTransmitting()) {
if(freedv_samples==0) { // 48K to 8K
int modem_samples=mod_sample_freedv(micsample);
if(modem_samples!=0) {
} else {
#endif
micsampledouble = (double)micsample/32767.0; // 16 bit sample
- if(mode==modeCWL || mode==modeCWU || tune) {
+ if(mode==modeCWL || mode==modeCWU || tune || !isTransmitting()) {
micinputbuffer[micsamples*2]=0.0;
micinputbuffer[(micsamples*2)+1]=0.0;
} else {
#endif
}
- }
+// }
}
for(t=0;t<6;t++) { // 8k to 48k
if(local_audio) {
audio_write(leftaudiosample,rightaudiosample);
+ leftaudiosample=0;
+ rightaudiosample=0;
}
+
audiobuffer[audioindex++]=leftaudiosample>>8;
audiobuffer[audioindex++]=leftaudiosample;
audiobuffer[audioindex++]=rightaudiosample>>8;
audiobuffer[audioindex++]=rightaudiosample;
+
if(audioindex>=sizeof(audiobuffer)) {
// insert the sequence
audiobuffer[0]=audiosequence>>24;
}
}
+void *new_protocol_process_local_mic(unsigned char *buffer,int le) {
+ int b;
+ int leftmicsample;
+ int rightmicsample;
+ double leftmicsampledouble;
+ double rightmicsampledouble;
+
+// if(isTransmitting()) {
+ b=0;
+ int i,j,s;
+ for(i=0;i<720;i++) {
+ if(le) {
+ leftmicsample = (int)((unsigned char)buffer[b++] & 0xFF);
+ leftmicsample |= (int)((signed char) buffer[b++]) << 8;
+ //rightmicsample = (int)((unsigned char)buffer[b++] & 0xFF);
+ //rightmicsample |= (int)((signed char) buffer[b++]) << 8;
+ rightmicsample=leftmicsample;
+ } else {
+ leftmicsample = (int)((signed char) buffer[b++]) << 8;
+ leftmicsample |= (int)((unsigned char)buffer[b++] & 0xFF);
+ rightmicsample = (int)((signed char) buffer[b++]) << 8;
+ rightmicsample |= (int)((unsigned char)buffer[b++] & 0xFF);
+ }
+#ifdef FREEDV
+ if(mode==modeFREEDV && isTransmitting()) {
+ if(freedv_samples==0) { // 48K to 8K
+ int modem_samples=mod_sample_freedv(leftmicsample);
+ if(modem_samples!=0) {
+ for(s=0;s<modem_samples;s++) {
+ for(j=0;j<freedv_resample;j++) { // 8K to 48K
+ leftmicsample=mod_out[s];
+ leftmicsampledouble=(double)leftmicsample/32767.0; // 16 bit sample 2^16-1
+ micinputbuffer[micsamples*2]=leftmicsampledouble*mic_gain;
+ micinputbuffer[(micsamples*2)+1]=leftmicsampledouble*mic_gain;
+ micsamples++;
+ if(micsamples==BUFFER_SIZE) {
+ full_tx_buffer();
+ micsamples=0;
+ }
+ }
+ }
+ }
+ }
+ freedv_samples++;
+ if(freedv_samples==freedv_resample) {
+ freedv_samples=0;
+ }
+ } else {
+#endif
+ leftmicsampledouble = (double)leftmicsample/32767.0; // 16 bit sample
+ rightmicsampledouble = (double)rightmicsample/32767.0; // 16 bit sample
+ if(mode==modeCWL || mode==modeCWU || tune || !isTransmitting()) {
+ micinputbuffer[micsamples*2]=0.0;
+ micinputbuffer[(micsamples*2)+1]=0.0;
+ } else {
+ micinputbuffer[micsamples*2]=leftmicsampledouble*mic_gain;
+ micinputbuffer[(micsamples*2)+1]=rightmicsampledouble*mic_gain;
+ }
+
+ micsamples++;
+
+ if(micsamples==BUFFER_SIZE) {
+ full_tx_buffer();
+ micsamples=0;
+ }
+#ifdef FREEDV
+ }
+#endif
+
+ }
+// }
+
+}
+
void* new_protocol_timer_thread(void* arg) {
int count=0;
fprintf(stderr,"new_protocol_timer_thread\n");
int getTune();
int isTransmitting();
+void *new_protocol_process_local_mic(unsigned char *buffer,int le);
#endif
//int result=sem_init(&frequency_changed_sem, 0, 1);
if(local_audio) {
- if(audio_init()!=0) {
- fprintf(stderr,"audio_init failed\n");
+ if(audio_open_output()!=0) {
+ fprintf(stderr,"audio_open_output failed\n");
local_audio=0;
}
}
#include <semaphore.h>
#include <math.h>
+#include "audio.h"
#include "discovered.h"
//#include "discovery.h"
#include "mode.h"
int alc=TXA_ALC_PK;
int local_audio=0;
+int local_microphone=0;
int eer_pwm_min=100;
int eer_pwm_max=800;
if(value) alc=atoi(value);
value=getProperty("local_audio");
if(value) local_audio=atoi(value);
+ value=getProperty("n_selected_output_device");
+ if(value) n_selected_output_device=atoi(value);
+ value=getProperty("local_microphone");
+ if(value) local_microphone=atoi(value);
+ value=getProperty("n_selected_input_device");
+ if(value) n_selected_input_device=atoi(value);
bandRestoreState();
sem_post(&property_sem);
}
setProperty("alc",value);
sprintf(value,"%d",local_audio);
setProperty("local_audio",value);
+ sprintf(value,"%d",n_selected_output_device);
+ setProperty("n_selected_output_device",value);
+ sprintf(value,"%d",local_microphone);
+ setProperty("local_microphone",value);
+ sprintf(value,"%d",n_selected_input_device);
+ setProperty("n_selected_input_device",value);
bandSaveState();
saveProperties(property_path);
extern int alc;
extern int local_audio;
+extern int local_microphone;
extern int eer_pwm_min;
extern int eer_pwm_max;
-rm -rf /usr/local/lib/libwdsp.so
-rm -rf /usr/local/lib/libpsk.so
-rm -rf /usr/local/lib/libcodec2.so
-rm -rf /usr/local/lib/libSoapySDR.so
-cp libwdsp.so /usr/local/lib
-cp libpsk.so /usr/local/lib
-cp libcodec2.so.0.5 /usr/local/lib
-cp libSoapySDR.so.0.5-1 /usr/local/lib
-cd /usr/local/lib; ln -s libcodec2.so.0.5 libcodec2.so
-cd /usr/local/lib; ln -s libSoapySDR.so.0.5-1 libSoapySDR.so.0.5.0
-cd /usr/local/lib; ln -s libSoapySDR.so.0.5-1 libSoapySDR.so
-ldconfig
+sudo apt-get -y install libfftw3-3
+sudo apt-get -y install xscreensaver
+wget abyz.co.uk/rpi/pigpio/pigpio.zip
+unzip pigpio.zip
+cd PIGPIO; make; sudo make install
+sudo rm -rf /usr/local/lib/libwdsp.so
+sudo rm -rf /usr/local/lib/libpsk.so
+sudo rm -rf /usr/local/lib/libcodec2.so
+sudo rm -rf /usr/local/lib/libSoapySDR.so
+sudo cp libwdsp.so /usr/local/lib
+sudo cp libpsk.so /usr/local/lib
+sudo cp libcodec2.so.0.5 /usr/local/lib
+sudo cp libSoapySDR.so.0.5-1 /usr/local/lib
+sudo cd /usr/local/lib; ln -s libcodec2.so.0.5 libcodec2.so
+sudo cd /usr/local/lib; ln -s libSoapySDR.so.0.5-1 libSoapySDR.so.0.5.0
+sudo cd /usr/local/lib; ln -s libSoapySDR.so.0.5-1 libSoapySDR.so
+sudo ldconfig