Index: quisk-3.5.11/sdriqpkg/sdriq.c
===================================================================
--- quisk-3.5.11.orig/sdriqpkg/sdriq.c	2012-01-30 21:54:27.000000000 -0500
+++ quisk-3.5.11/sdriqpkg/sdriq.c	2012-01-30 23:30:08.000000000 -0500
@@ -18,10 +18,19 @@
 #endif
 
 #include <complex.h>
-
+#define SOUND_MODULE 1
 #include "quisk.h"
 #include "sdriq.h"
 
+static struct sound_conf *quisk_sound_state;
+static ty_sample_start *pt_sample_start;
+static ty_sample_stop  *pt_sample_stop;
+static ty_sample_read  *pt_sample_read;
+static double (*pQuiskGetConfigDouble)(const char * name, double deflt);
+static char * (*pQuiskGetConfigString)(const char * name, char * deflt);
+static double (*pQuiskTimeSec)(void);
+static void (*pQuiskSleepMicrosec)(int usec);
+
 // This module provides access to the SDR-IQ by RfSpace.  It is the source
 // for the Python extension module sdriq.  It can be used as a model for an
 // extension module for other hardware.  Read the end of this file for more
@@ -73,7 +82,7 @@
 		return 0;
 
 	if (FT_GetQueueStatus(quisk_sdriq_fd, &rx_bytes) != FT_OK) {
-		quisk_sound_state.read_error++;
+		quisk_sound_state->read_error++;
 		return 0;
 	}
 	if (rx_bytes > bufsize)
@@ -85,7 +94,7 @@
 		return bytes;
 	}
 	else {
-		quisk_sound_state.read_error++;
+		quisk_sound_state->read_error++;
 		return 0;	
 	}
 }
@@ -116,7 +125,7 @@
 	res = read(quisk_sdriq_fd, buf, bufsize);
 	if (res < 0) {
 		if (errno != EAGAIN && errno != EWOULDBLOCK) {
-			quisk_sound_state.read_error++;
+			quisk_sound_state->read_error++;
 		}
 		return 0;
 	}
@@ -159,7 +168,7 @@
 	case 5:
 		sdr_status = data[0];
 		if (data[0] == 0x20)
-			quisk_sound_state.overrange++;
+			quisk_sound_state->overrange++;
 #if DEBUG
 		if (data[0] == 0x20)
 			printf ("Got overrange (clip)\n");
@@ -199,7 +208,7 @@
 	if (nparams)
 		memcpy(buf + 4, params, nparams);
 	if (Write(buf, length) != length) {
-		quisk_sound_state.read_error++;
+		quisk_sound_state->read_error++;
 #if DEBUG
 		printf("get_item write error\n");
 #endif
@@ -228,7 +237,7 @@
 	if (nparams)
 		memcpy(buf + 4, params, nparams);
 	if (Write(buf, length) != length) {
-		quisk_sound_state.read_error++;
+		quisk_sound_state->read_error++;
 #if DEBUG
 		printf("set_item write error\n");
 #endif
@@ -391,7 +400,7 @@
 		goto start_here;		// process the next state
 	}
 	else if (state == 9) {		// try to re-synchronize
-		quisk_sound_state.read_error++;
+		quisk_sound_state->read_error++;
 #if DEBUG
 		printf ("Lost sync: type %d  length %d\n", type, length);
 #endif
@@ -405,7 +414,7 @@
 		while (1) {		// look for the start of data blocks "\x00\x80"
 			res = Read(buf, 1);
 			if (res != 1) {
-				QuiskSleepMicrosec(SDRIQ_MSEC * 1000);
+				(*pQuiskSleepMicrosec)(SDRIQ_MSEC * 1000);
 			}
 			else if (state == 9) {		// look for 0x00
 				if (buf[0] == 0x00)
@@ -450,7 +459,7 @@
 	buf[7] = value & 0xFF;
 	buf[8] = 0;
 	if (Write(buf, 9) != 9) {
-		quisk_sound_state.read_error++;
+		quisk_sound_state->read_error++;
 #if DEBUG
 		printf ("set_ad6620 write error\n");
 #endif
@@ -470,7 +479,7 @@
 		sdr_recv(NULL, 0);
 		if (sdr_ack != -1)
 			break;
-		QuiskSleepMicrosec(SDRIQ_MSEC * 1000);
+		(*pQuiskSleepMicrosec)(SDRIQ_MSEC * 1000);
 	}
 #if DEBUG
 	if (sdr_ack != 1)
@@ -666,7 +675,7 @@
 	sdr_serial[0] = 0;
 	sdr_idle = -1;			// unknown state
 	set_item(0x0018, 4, "\x81\x01\x00\x00");
-	QuiskSleepMicrosec(1000000);
+	(*pQuiskSleepMicrosec)(1000000);
 	while (1) {		// read and discard any available output
 		if (Read(buf1024, 1024) == 0)
 			break;
@@ -691,7 +700,7 @@
 		sdr_recv(NULL, 0);
 		if (sdr_name[0] != 0)
 			break;
-		QuiskSleepMicrosec(SDRIQ_MSEC * 1000);
+		(*pQuiskSleepMicrosec)(SDRIQ_MSEC * 1000);
 	}
 	if (sdr_name[0]) {		// we got a response
 		snprintf(buf, bufsize, "Capture from %s serial %s.",
@@ -711,10 +720,10 @@
 	static double time0 = 0;	// time in seconds
 	double timer;				// time remaining from last poll usec
 
-	timer = quisk_sound_state.data_poll_usec - (QuiskTimeSec() - time0) * 1e6;
+	timer = quisk_sound_state->data_poll_usec - ((*pQuiskTimeSec)() - time0) * 1e6;
 	if (timer > 1000.0)	// see if enough time has elapsed
-		QuiskSleepMicrosec((int)timer);		// wait for the remainder of the poll interval
-	time0 = QuiskTimeSec();		// reset starting time value
+		(*pQuiskSleepMicrosec)((int)timer);		// wait for the remainder of the poll interval
+	time0 = (*pQuiskTimeSec)();		// reset starting time value
 }
 
 // End of most SDR-IQ specific code.
@@ -751,7 +760,7 @@
 		sdr_recv(samples, 2048);
 		if (sdr_idle == 1)
 			break;
-		QuiskSleepMicrosec(1000);
+		(*pQuiskSleepMicrosec)(1000);
 	}
 #if DEBUG
 	if (msec < 1001)
@@ -809,13 +818,13 @@
 	if (!PyArg_ParseTuple (args, ""))
 		return NULL;
 
-	name = QuiskGetConfigString("sdriq_name", "NoName");
-	sdriq_clock = QuiskGetConfigDouble("sdriq_clock", 66666667.0);
+	name = (*pQuiskGetConfigString)("sdriq_name", "NoName");
+	sdriq_clock = (*pQuiskGetConfigDouble)("sdriq_clock", 66666667.0);
 
 // Record our C-language Start/Stop/Read functions for use by sound.c.
-	pt_sample_start = &quisk_start_sdriq;
-	pt_sample_stop = &quisk_stop_sdriq;
-	pt_sample_read = &quisk_read_sdriq;
+	*pt_sample_start = &quisk_start_sdriq;
+	*pt_sample_stop = &quisk_stop_sdriq;
+	*pt_sample_read = &quisk_read_sdriq;
 //////////////
 	quisk_open_sdriq(name, buf, 128);		// SDR-IQ specific
 	return PyString_FromString(buf);		// return a string message
@@ -867,5 +876,79 @@
 // Initialization, and registration of public symbol "initsdriq":
 PyMODINIT_FUNC initsdriq (void)
 {
+  PyObject *c_api_object;
+  PyObject *module;
+
+  module = PyImport_ImportModule("quisk._quisk");
+  if (module == NULL)
+    return;
+
+  c_api_object = PyObject_GetAttrString(module, "_C_sound_state");
+  if (c_api_object == NULL) {
+    Py_DECREF(module);
+    return;
+  }
+  if (PyCObject_Check(c_api_object))
+    quisk_sound_state = (struct sound_conf *)PyCObject_AsVoidPtr(c_api_object);
+
+  c_api_object = PyObject_GetAttrString(module, "_C_sample_start");
+  if (c_api_object == NULL) {
+    Py_DECREF(module);
+    return;
+  }
+  if (PyCObject_Check(c_api_object))
+    pt_sample_start = (ty_sample_start *)PyCObject_AsVoidPtr(c_api_object);
+
+  c_api_object = PyObject_GetAttrString(module, "_C_sample_stop");
+  if (c_api_object == NULL) {
+    Py_DECREF(module);
+    return;
+  }
+  if (PyCObject_Check(c_api_object))
+    pt_sample_stop = (ty_sample_stop *)PyCObject_AsVoidPtr(c_api_object);
+
+  c_api_object = PyObject_GetAttrString(module, "_C_sample_read");
+  if (c_api_object == NULL) {
+    Py_DECREF(module);
+    return;
+  }
+  if (PyCObject_Check(c_api_object))
+    pt_sample_read = (ty_sample_read *)PyCObject_AsVoidPtr(c_api_object);
+
+  c_api_object = PyObject_GetAttrString(module, "_C_GetConfigDouble");
+  if (c_api_object == NULL) {
+    Py_DECREF(module);
+    return;
+  }
+  if (PyCObject_Check(c_api_object))
+    pQuiskGetConfigDouble = (double (*)(const char * name, double deflt))PyCObject_AsVoidPtr(c_api_object);
+
+  c_api_object = PyObject_GetAttrString(module, "_C_GetConfigString");
+  if (c_api_object == NULL) {
+    Py_DECREF(module);
+    return;
+  }
+  if (PyCObject_Check(c_api_object))
+    pQuiskGetConfigString = (char * (*)(const char * name, char *deflt))PyCObject_AsVoidPtr(c_api_object);
+
+  c_api_object = PyObject_GetAttrString(module, "_C_TimeSec");
+  if (c_api_object == NULL) {
+    Py_DECREF(module);
+    return;
+  }
+  if (PyCObject_Check(c_api_object))
+    pQuiskTimeSec = (double (*)(void))PyCObject_AsVoidPtr(c_api_object);
+
+  c_api_object = PyObject_GetAttrString(module, "_C_SleepMicrosec");
+  if (c_api_object == NULL) {
+    Py_DECREF(module);
+    return;
+  }
+  if (PyCObject_Check(c_api_object))
+    pQuiskSleepMicrosec = (void (*)(int usec))PyCObject_AsVoidPtr(c_api_object);
+
+  Py_DECREF(c_api_object);
+  Py_DECREF(module);
+
 	Py_InitModule ("sdriq", QuiskMethods);
 }
