Revision
14699
Author
gmaruzz
Date
2009-08-31 12:06:51 -0500 (Mon, 31 Aug 2009)

Log Message

celliax: audio sync, alsa init when needed, volume of samples

Modified Paths

Diff

Modified: freeswitch/branches/gmaruzz/mod_celliax/celliax.h (14698 => 14699)


--- freeswitch/branches/gmaruzz/mod_celliax/celliax.h	2009-08-31 14:33:41 UTC (rev 14698)
+++ freeswitch/branches/gmaruzz/mod_celliax/celliax.h	2009-08-31 17:06:51 UTC (rev 14699)
@@ -552,3 +552,7 @@
 int alsa_read(private_t * tech_pvt, short *data, int datalen);
 
 #endif /* CELLIAX_ALSA */
+
+
+void celliax_store_boost(char *s, double *boost);
+int celliax_sound_boost(void * data, int samples_num, double boost);

Modified: freeswitch/branches/gmaruzz/mod_celliax/celliax_protocol.c (14698 => 14699)


--- freeswitch/branches/gmaruzz/mod_celliax/celliax_protocol.c	2009-08-31 14:33:41 UTC (rev 14698)
+++ freeswitch/branches/gmaruzz/mod_celliax/celliax_protocol.c	2009-08-31 17:06:51 UTC (rev 14699)
@@ -3707,6 +3707,7 @@
 			ERRORA("device [%s], snd_pcm_close failed with error '%s'\n", SKYPIAX_P_LOG, tech_pvt->alsapname, snd_strerror(err));
 			return -1;
 		}
+tech_pvt->alsap = NULL;
 	}
 	if (tech_pvt->alsac) {
 		err = snd_pcm_drop(tech_pvt->alsac);
@@ -3719,6 +3720,7 @@
 			ERRORA("device [%s], snd_pcm_close failed with error '%s'\n", SKYPIAX_P_LOG, tech_pvt->alsacname, snd_strerror(err));
 			return -1;
 		}
+tech_pvt->alsac = NULL;
 	}
 
 	return 0;
@@ -5067,4 +5069,58 @@
     return RESULT_SUCCESS;
 }
 
+/************************************************/
 
+/* LUIGI RIZZO's magic */
+/* boost support. BOOST_SCALE * 10 ^(BOOST_MAX/20) must
+ * be representable in 16 bits to avoid overflows.
+ */
+#define BOOST_SCALE     (1<<9)
+#define BOOST_MAX       40          /* slightly less than 7 bits */
+
+/*
+ * store the boost factor
+ */
+void celliax_store_boost(char *s, double *boost)
+{
+  private_t * tech_pvt  = NULL;
+
+  if (sscanf(s, "%lf", boost) != 1) {
+    ERRORA("invalid boost <%s>\n", SKYPIAX_P_LOG, s);
+    return;
+  }
+  if (*boost < -BOOST_MAX) {
+    WARNINGA("boost %s too small, using %d\n", SKYPIAX_P_LOG, s, -BOOST_MAX);
+    *boost = -BOOST_MAX;
+  } else if (*boost > BOOST_MAX) {
+    WARNINGA("boost %s too large, using %d\n", SKYPIAX_P_LOG, s, BOOST_MAX);
+    *boost = BOOST_MAX;
+  }
+  *boost = exp(log(10) * *boost / 20) * BOOST_SCALE;
+  if (option_debug > 1)
+    DEBUGA_SKYPE("setting boost %s to %f\n", SKYPIAX_P_LOG, s, *boost);
+}
+
+
+int celliax_sound_boost(void * data, int samples_num, double boost)
+{
+/* LUIGI RIZZO's magic */
+  if (boost != 0) {             /* scale and clip values */
+    int i, x;
+
+    int16_t *ptr = (int16_t *) data;
+
+    for (i = 0; i < samples_num; i++) {
+      x = (ptr[i] * boost) / BOOST_SCALE;
+      if (x > 32767) {
+        x = 32767;
+      } else if (x < -32768) {
+        x = -32768;
+      }
+      ptr[i] = x;
+    }
+  }
+  return 0;
+}
+
+

Modified: freeswitch/branches/gmaruzz/mod_celliax/mod_celliax.c (14698 => 14699)


--- freeswitch/branches/gmaruzz/mod_celliax/mod_celliax.c	2009-08-31 14:33:41 UTC (rev 14698)
+++ freeswitch/branches/gmaruzz/mod_celliax/mod_celliax.c	2009-08-31 17:06:51 UTC (rev 14699)
@@ -258,6 +258,11 @@
 	//teletone_dtmf_detect_init(&tech_pvt->dtmf_detect, tech_pvt->read_codec.implementation->actual_samples_per_second);
 	teletone_dtmf_detect_init(&tech_pvt->dtmf_detect, 8000);
 
+	if(alsa_init(tech_pvt)){
+		ERRORA("alsa_init failed\n", SKYPIAX_P_LOG);
+		return SWITCH_STATUS_FALSE;
+
+	}
 	if (switch_core_timer_init(&tech_pvt->timer_read, "soft", 20, tech_pvt->read_codec.implementation->samples_per_packet, celliax_module_pool) !=
 		SWITCH_STATUS_SUCCESS) {
 		ERRORA("setup timer failed\n", SKYPIAX_P_LOG);
@@ -483,6 +488,7 @@
 		switch_core_timer_destroy(&tech_pvt->timer_read);
 		switch_core_timer_destroy(&tech_pvt->timer_write);
 
+		alsa_shutdown(tech_pvt);
 
 		*tech_pvt->session_uuid_str = '\0';
 		tech_pvt->interface_state = SKYPIAX_STATE_IDLE;
@@ -682,11 +688,18 @@
 
 	//if ((samples = snd_pcm_readi(tech_pvt->alsac, tech_pvt->read_frame.data, tech_pvt->read_codec.implementation->samples_per_packet)) > 0) 
 	if ((samples = alsa_read(tech_pvt, tech_pvt->read_frame.data, tech_pvt->read_codec.implementation->samples_per_packet)) > 0) {
+
 		tech_pvt->read_frame.datalen = samples * 2;
 		tech_pvt->read_frame.samples = samples;
 
 		//switch_core_timer_check(&tech_pvt->timer, SWITCH_TRUE);
 		tech_pvt->read_frame.timestamp = tech_pvt->timer_read.samplecount;
+
+celliax_sound_boost(tech_pvt->read_frame.data, tech_pvt->read_frame.samples, tech_pvt->capture_boost);
+
+
+
+
 		*frame = &tech_pvt->read_frame;
 
 		//status = SWITCH_STATUS_SUCCESS;
@@ -813,11 +826,12 @@
 #endif
 
 		switch_core_timer_next(&tech_pvt->timer_write);
-	sent = frame->datalen;
+	//sent = frame->datalen;
 
 	//ERRORA("PLAY \n", SKYPIAX_P_LOG);
 	//snd_pcm_writei(tech_pvt->alsap, (short *) frame->data, (int) (frame->datalen / 2));
 
+celliax_sound_boost(frame->data, frame->samples, tech_pvt->playback_boost);
 	sent = alsa_write(tech_pvt, frame->data, (int) (frame->datalen));
 //DEBUGA_SKYPE("sent=%d \n", SKYPIAX_P_LOG, sent);
 
@@ -855,6 +869,8 @@
 {
 	switch_channel_t *channel;
 	private_t *tech_pvt;
+int samples;
+short tmp_buffer[1280];
 
 	channel = switch_core_session_get_channel(session);
 	switch_assert(channel != NULL);
@@ -869,6 +885,18 @@
 			channel_answer_channel(session);
 		}
 		break;
+case SWITCH_MESSAGE_INDICATE_AUDIO_SYNC:
+
+		WARNINGA("%s CHANNEL got SWITCH_MESSAGE_INDICATE_AUDIO_SYNC\n", SKYPIAX_P_LOG, switch_channel_get_name(channel));
+	while ((samples = alsa_read(tech_pvt, tmp_buffer, tech_pvt->read_codec.implementation->samples_per_packet * 4)) > 160) {
+		WARNINGA("read %d samples\n", SKYPIAX_P_LOG, samples);
+}
+		switch_core_timer_sync(&tech_pvt->timer_read);
+		switch_core_timer_sync(&tech_pvt->timer_write);
+
+break;
+
+
 	default:
 		{
 			DEBUGA_SKYPE("MSG_ID=%d\n", SKYPIAX_P_LOG, msg->message_id);
@@ -1455,7 +1483,11 @@
 				globals.SKYPIAX_INTERFACES[interface_id].alsa_capture_is_mono = 1;
 
 
+				globals.SKYPIAX_INTERFACES[interface_id].capture_boost = 0;
+				globals.SKYPIAX_INTERFACES[interface_id].playback_boost = 0;
 
+celliax_store_boost("5", &globals.SKYPIAX_INTERFACES[interface_id].capture_boost);
+celliax_store_boost("5", &globals.SKYPIAX_INTERFACES[interface_id].playback_boost);
 /*********************/
 				DEBUGA_SKYPE
 					("interface_id=%d globals.SKYPIAX_INTERFACES[interface_id].X11_display=%s\n",
@@ -1522,6 +1554,7 @@
 
 				switch_sleep(100000);
 
+#ifdef NOTDEF
 				res = alsa_init(&globals.SKYPIAX_INTERFACES[interface_id]);
 				if (res == -1) {
 					ERRORA("Failed initializing sound device\n", SKYPIAX_P_LOG);
@@ -1531,7 +1564,6 @@
 					//return NULL;
 				}
 
-#ifdef NOTDEF
 				switch_threadattr_create(&celliax_signaling_thread_attr, celliax_module_pool);
 				switch_threadattr_stacksize_set(celliax_signaling_thread_attr, SWITCH_THREAD_STACKSIZE);
 				switch_thread_create(&globals.SKYPIAX_INTERFACES[interface_id].celliax_signaling_thread, celliax_signaling_thread_attr,
@@ -1666,7 +1698,7 @@
 
 
 
-		alsa_shutdown(&globals.SKYPIAX_INTERFACES[interface_id]);
+		//alsa_shutdown(&globals.SKYPIAX_INTERFACES[interface_id]);
 			if (globals.SKYPIAX_INTERFACES[interface_id].celliax_signaling_thread) {
 #ifdef WIN32
 				switch_file_write(tech_pvt->SkypiaxHandles.fdesc[1], "sciutati", &howmany);	// let's the controldev_thread die