Merge pull request #1 from atsampson/master
[calfbox.git] / drvjunk / omega.c
blob3611bb1a2d402b25b75532a004615ea89e4c3141
1 #include <libusb-1.0/libusb.h>
3 #include <assert.h>
4 #include <errno.h>
5 #include <math.h>
6 #include <malloc.h>
7 #include <memory.h>
8 #include <sched.h>
9 #include <stdio.h>
10 #include <unistd.h>
12 // interface 1 altsetting 1 endpoint 01 (out) bits 16 channels 2 mps 192
13 // interface 2 altsetting 1 endpoint 83 (in) bits 16 channels 2 mps 192
15 int samples_captured = 0;
16 int samples_played = 0;
18 static struct libusb_context *usbctx;
19 static int omega_timeout = 1000;
21 int epOUT = 0x01, epIN = 0x83;
23 void init_usb()
25 libusb_init(&usbctx);
26 libusb_set_debug(usbctx, 3);
29 struct libusb_device_handle *open_omega()
31 struct libusb_device_handle *handle;
32 handle = libusb_open_device_with_vid_pid(usbctx, 0x1210, 0x0002);
33 if (!handle)
35 printf("Lexicon Omega not found after reset.\n");
36 return NULL;
38 if (libusb_set_configuration(handle, 1))
40 libusb_close(handle);
41 return NULL;
44 if (libusb_claim_interface(handle, 1))
45 goto error;
46 if (libusb_claim_interface(handle, 2))
47 goto error;
48 if (libusb_claim_interface(handle, 7))
49 goto error;
50 if (libusb_set_interface_alt_setting(handle, 1, 1))
51 goto error;
52 if (libusb_set_interface_alt_setting(handle, 2, 1))
53 goto error;
55 return handle;
57 error:
58 libusb_close(handle);
59 return NULL;
62 #define EP_CONTROL_UNDEFINED 0
63 #define SAMPLING_FREQ_CONTROL 1
64 #define PITCH_CONTROL 2
66 #define SET_CUR 0x01
67 #define GET_CUR 0x81
68 #define SET_MIN 0x02
69 #define GET_MIN 0x82
70 #define SET_MAX 0x03
71 #define GET_MAX 0x83
72 #define SET_RES 0x04
73 #define GET_RES 0x84
74 #define SET_MEM 0x05
75 #define GET_MEM 0x85
76 #define GET_STAT 0xFF
78 int configure_omega(struct libusb_device_handle *h, int sample_rate)
80 uint8_t freq_data[3];
81 freq_data[0] = sample_rate & 0xFF;
82 freq_data[1] = (sample_rate & 0xFF00) >> 8;
83 freq_data[2] = (sample_rate & 0xFF0000) >> 16;
84 if (libusb_control_transfer(h, 0x22, 0x01, 256, epOUT, freq_data, 3, omega_timeout) != 3)
85 return -1;
86 if (libusb_control_transfer(h, 0x22, 0x01, 256, epIN, freq_data, 3, omega_timeout) != 3)
87 return -1;
88 // libusb_control_transfer(dev, 0x22, 0x01,
89 return 0;
92 // 192 bytes = 1ms@48000 (48 samples)
94 #define NUM_PLAY_BUFS 2
95 #define PLAY_PACKET_COUNT 2
96 #define PLAY_PACKET_SIZE 192
98 static float phase = 0;
99 static int phase2 = 0;
101 static int desync = 0;
102 static int samples_sent = 0;
104 static int srate = 48000;
106 void play_callback(struct libusb_transfer *transfer)
108 int i;
109 //printf("Play Callback! %d %p status %d\n", (int)transfer->length, transfer->buffer, (int)transfer->status);
111 samples_played += transfer->length / 4;
112 int nsamps = srate / 1000;
113 if (desync >= 1000 * transfer->num_iso_packets && nsamps < PLAY_PACKET_SIZE/4)
114 nsamps++;
115 // printf("desync = %d nsamps = %d!\n", desync, nsamps);
116 int tlen = 0;
117 for (i = 0; i < transfer->num_iso_packets; i++)
119 tlen += transfer->iso_packet_desc[i].actual_length;
120 if (transfer->iso_packet_desc[i].status)
121 printf("ISO error: index = %d i = %d status = %d\n", (int)transfer->user_data, i, transfer->iso_packet_desc[i].status);
123 // printf("actual length = %d!\n", tlen);
125 transfer->length = nsamps * transfer->num_iso_packets * 4;
126 libusb_set_iso_packet_lengths(transfer, nsamps * 4);
128 desync += transfer->num_iso_packets * srate;
129 desync -= tlen / 4 * 1000;
131 int16_t *data = (int16_t*)transfer->buffer;
132 for (i = 0; i < transfer->length / 4; i ++)
134 float v = 16000 * sin(phase);
135 //phase += (phase2 & 4096) ? 0.02 : 0.04;
136 phase += (phase2 & 16384) ? 0.04: 0.02;
137 //phase += 0.2 * cos(phase2 / 16384.0);
138 phase2++;
139 if (phase > 2 * M_PI)
140 phase -= 2 * M_PI;
141 int vi = (int)v;
142 data[i * 2] = vi;
143 data[i * 2 + 1] = vi;
145 libusb_submit_transfer(transfer);
148 void play_stuff(struct libusb_device_handle *h, int index)
150 struct libusb_transfer *t;
151 int i;
152 int packets = PLAY_PACKET_COUNT;
153 t = libusb_alloc_transfer(packets);
154 int tsize = srate * 4 / 1000;
155 uint8_t *buf = (uint8_t *)malloc(PLAY_PACKET_SIZE*packets);
156 //int ssf = 0;
158 for (i = 0; i < tsize * packets; i++)
159 buf[i] = 0;
161 libusb_fill_iso_transfer(t, h, epOUT, buf, tsize * packets, packets, play_callback, (void *)index, 20000);
162 libusb_set_iso_packet_lengths(t, tsize);
163 libusb_submit_transfer(t);
166 #define NUM_RECORD_BUFS 2
167 #define NUM_REC_PACKETS 2
168 #define REC_PACKET_SIZE 192
170 static uint8_t *record_buffers[NUM_RECORD_BUFS];
171 // struct libusb_transfer *record_transfers[NUM_RECORD_BUFS];
173 float filt = 0;
175 void record_callback(struct libusb_transfer *transfer)
177 int i;
178 // printf("Record callback! %p index %d len %d\n", transfer, (int)transfer->user_data, transfer->length);
179 samples_captured += transfer->length / 4;
181 float avg = 0;
182 int16_t *bufz = (int16_t*)transfer->buffer;
183 int items = transfer->length / 4;
184 for (i = 0; i < items; i ++)
186 int16_t *buf = &bufz[i * 2];
187 if (fabs(buf[0]) > avg)
188 avg = fabs(buf[0]);
189 if (fabs(buf[1]) > avg)
190 avg = fabs(buf[1]);
192 if (avg)
193 printf("%12.6f dBFS\r", 6 * log(avg / 32767 / items) / log(2.0));
194 libusb_submit_transfer(transfer);
197 void record_stuff(struct libusb_device_handle *h, int index)
199 // 0x02
200 struct libusb_transfer *t;
202 record_buffers[index] = (uint8_t*)malloc(NUM_REC_PACKETS * REC_PACKET_SIZE);
203 memset(record_buffers[index], 0, NUM_REC_PACKETS * REC_PACKET_SIZE);
205 t = libusb_alloc_transfer(NUM_REC_PACKETS);
206 libusb_fill_iso_transfer(t, h, epIN, record_buffers[index], NUM_REC_PACKETS * REC_PACKET_SIZE, NUM_REC_PACKETS, record_callback, (void *)index, 1000);
207 libusb_set_iso_packet_lengths(t, REC_PACKET_SIZE);
208 if (libusb_submit_transfer(t))
209 goto error;
210 return;
211 error:
212 printf("Record setup failed for index=%d\n", index);
215 void usb_main_loop()
217 struct sched_param p;
218 p.sched_priority = 10;
219 sched_setscheduler(0, SCHED_FIFO, &p);
220 while(1) {
221 struct timeval tv = {
222 .tv_sec = 0,
223 .tv_usec = 100
225 libusb_handle_events_timeout(usbctx, &tv);
229 int main(int argc, char *argv[])
231 struct libusb_device_handle *h;
232 int i;
234 init_usb();
235 h = open_omega();
236 if (!h)
238 printf("Lexicon Omega could not be opened.\n");
239 return 2;
242 // 10: 4 3 3 - 16 bit
243 // 30: 2 2 1 2 2 2 1 - 24 bit
244 // 50: 4 3 3
245 // 70: 2 2 1 2 2 2 1
246 printf("Error = %d\n", configure_omega(h, srate));
247 usleep(1);
248 for (i = 0; i < NUM_PLAY_BUFS; i++)
249 play_stuff(h, i);
250 for (i = 0; i < NUM_RECORD_BUFS; i++)
251 record_stuff(h, i);
252 usb_main_loop();
253 return 0;