|
24 | 24 |
|
25 | 25 | #define PLOSSFAC ((BUFFER_FRAMES) / 64) |
26 | 26 |
|
| 27 | +enum samplesize { |
| 28 | + SIZE_8, SIZE_16, SIZE_24, SIZE_32 |
| 29 | +}; |
| 30 | + |
27 | 31 | static snd_pcm_t * scope_pcm; |
28 | 32 | // Details on the sample format before conversion. |
29 | | -// Two-channel (enables XY mode), if not, acts like a primitive X oscilloscope |
30 | | -static int sf_2c; |
31 | | -static int sf_16b; |
32 | | -static int sf_us; |
| 33 | +// channel count - 2 enables XY mode, 1 acts like a primitive X oscilloscope |
| 34 | +static int sf_chancount; |
| 35 | +// xy mode, uses two channels |
33 | 36 | static int sf_usey; |
| 37 | +static enum samplesize sf_sampsize; |
| 38 | +static int sf_us; |
34 | 39 | static int sf_forceon; |
35 | 40 |
|
36 | 41 | static int camera_width; |
@@ -58,10 +63,10 @@ static oscore_task scope_task; |
58 | 63 | #define SM_ALGORITHM(sample, shr, sub) (((byte) (sample >> shr)) - sub) |
59 | 64 | #define LD_ALGORITHM(typ, shr, sub) \ |
60 | 65 | for (int indx = 0; indx < BUFFER_FRAMES; indx++) { \ |
61 | | - typ sampleA = ((typ *) bufferA)[indx * (sf_2c ? 2 : 1)]; \ |
| 66 | + typ sampleA = ((typ *) bufferA)[indx * sf_chancount]; \ |
62 | 67 | bufferB[indx * 2] = SM_ALGORITHM(sampleA, shr, sub); \ |
63 | | - if (sf_2c && sf_usey) { \ |
64 | | - typ sampleB = ((typ *) bufferA)[(indx * (sf_2c ? 2 : 1)) + 1]; \ |
| 68 | + if (sf_chancount == 2 && sf_usey) { \ |
| 69 | + typ sampleB = ((typ *) bufferA)[(indx * sf_chancount) + 1]; \ |
65 | 70 | bufferB[(indx * 2) + 1] = 255 - SM_ALGORITHM(sampleB, shr, sub); \ |
66 | 71 | } else { \ |
67 | 72 | bufferB[(indx * 2) + 1] = bufferB[indx * 2]; \ |
@@ -104,13 +109,25 @@ static void * thread_func(void * ign) { |
104 | 109 | frames = snd_pcm_recover(scope_pcm, frames, 0); |
105 | 110 | if (frames < 0) |
106 | 111 | printf("Warning: reading totally failed: %i, %s\n", frames, snd_strerror(frames)); |
107 | | - if (sf_16b) { |
| 112 | + if (sf_sampsize == SIZE_32) { |
| 113 | + if (sf_us) { |
| 114 | + LD_ALGORITHM(unsigned int, 24, 0); |
| 115 | + } else { |
| 116 | + LD_ALGORITHM(unsigned int, 24, 0x80); |
| 117 | + } |
| 118 | + } else if (sf_sampsize == SIZE_24) { |
| 119 | + if (sf_us) { |
| 120 | + LD_ALGORITHM(unsigned int, 16, 0); |
| 121 | + } else { |
| 122 | + LD_ALGORITHM(unsigned int, 16, 0x80); |
| 123 | + } |
| 124 | + } else if (sf_sampsize == SIZE_16) { |
108 | 125 | if (sf_us) { |
109 | 126 | LD_ALGORITHM(unsigned short, 8, 0); |
110 | 127 | } else { |
111 | 128 | LD_ALGORITHM(unsigned short, 8, 0x80); |
112 | 129 | } |
113 | | - } else { |
| 130 | + } else if (sf_sampsize == SIZE_8) { |
114 | 131 | if (sf_us) { |
115 | 132 | LD_ALGORITHM(byte, 0, 0); |
116 | 133 | } else { |
@@ -230,48 +247,62 @@ int init(int modulen, char* argstr) { |
230 | 247 | return 1; |
231 | 248 | } |
232 | 249 | free(ourarg); |
233 | | - sf_2c = 0; |
234 | | - sf_16b = 0; |
| 250 | + |
| 251 | + sf_sampsize = SIZE_8; |
235 | 252 | sf_us = 0; |
236 | | - if (sf_usey) { |
237 | | - if (!(code = snd_pcm_set_params(scope_pcm, SND_PCM_FORMAT_S8, SND_PCM_ACCESS_RW_INTERLEAVED, 2, SAMPLE_RATE, 1, 1000))) { |
238 | | - printf("Got BS8C2\n"); |
239 | | - sf_2c = 1; |
240 | | - } else if (!(code = snd_pcm_set_params(scope_pcm, SND_PCM_FORMAT_S16, SND_PCM_ACCESS_RW_INTERLEAVED, 2, SAMPLE_RATE, 1, 1000))) { |
241 | | - printf("Got BS16C2\n"); |
242 | | - sf_16b = 1; |
243 | | - sf_2c = 1; |
244 | | - } else if (!(code = snd_pcm_set_params(scope_pcm, SND_PCM_FORMAT_U8, SND_PCM_ACCESS_RW_INTERLEAVED, 2, SAMPLE_RATE, 1, 1000))) { |
245 | | - printf("Got BU8C2\n"); |
246 | | - sf_2c = 1; |
247 | | - sf_us = 1; |
248 | | - } else if (!(code = snd_pcm_set_params(scope_pcm, SND_PCM_FORMAT_U16, SND_PCM_ACCESS_RW_INTERLEAVED, 2, SAMPLE_RATE, 1, 1000))) { |
249 | | - printf("Got BU16C2\n"); |
250 | | - sf_16b = 1; |
251 | | - sf_2c = 1; |
252 | | - sf_us = 1; |
253 | | - } |
| 253 | + sf_chancount = sf_usey ? 2 : 1; |
| 254 | + |
| 255 | + if (!(code = snd_pcm_set_params(scope_pcm, SND_PCM_FORMAT_S8, SND_PCM_ACCESS_RW_INTERLEAVED, sf_chancount, SAMPLE_RATE, 1, 1000))) { |
| 256 | + sf_sampsize = SIZE_8; |
| 257 | + } else if (!(code = snd_pcm_set_params(scope_pcm, SND_PCM_FORMAT_S16, SND_PCM_ACCESS_RW_INTERLEAVED, sf_chancount, SAMPLE_RATE, 1, 1000))) { |
| 258 | + sf_sampsize = SIZE_16; |
| 259 | + } else if (!(code = snd_pcm_set_params(scope_pcm, SND_PCM_FORMAT_S24, SND_PCM_ACCESS_RW_INTERLEAVED, sf_chancount, SAMPLE_RATE, 1, 1000))) { |
| 260 | + sf_sampsize = SIZE_24; |
| 261 | + } else if (!(code = snd_pcm_set_params(scope_pcm, SND_PCM_FORMAT_S32, SND_PCM_ACCESS_RW_INTERLEAVED, sf_chancount, SAMPLE_RATE, 1, 1000))) { |
| 262 | + sf_sampsize = SIZE_32; |
| 263 | + } else if (!(code = snd_pcm_set_params(scope_pcm, SND_PCM_FORMAT_U8, SND_PCM_ACCESS_RW_INTERLEAVED, sf_chancount, SAMPLE_RATE, 1, 1000))) { |
| 264 | + sf_sampsize = SIZE_8; |
| 265 | + sf_us = 1; |
| 266 | + } else if (!(code = snd_pcm_set_params(scope_pcm, SND_PCM_FORMAT_U16, SND_PCM_ACCESS_RW_INTERLEAVED, sf_chancount, SAMPLE_RATE, 1, 1000))) { |
| 267 | + sf_sampsize = SIZE_16; |
| 268 | + sf_us = 1; |
| 269 | + } else if (!(code = snd_pcm_set_params(scope_pcm, SND_PCM_FORMAT_U24, SND_PCM_ACCESS_RW_INTERLEAVED, sf_chancount, SAMPLE_RATE, 1, 1000))) { |
| 270 | + sf_sampsize = SIZE_24; |
| 271 | + sf_us = 1; |
| 272 | + } else if (!(code = snd_pcm_set_params(scope_pcm, SND_PCM_FORMAT_U32, SND_PCM_ACCESS_RW_INTERLEAVED, sf_chancount, SAMPLE_RATE, 1, 1000))) { |
| 273 | + sf_sampsize = SIZE_32; |
| 274 | + sf_us = 1; |
254 | 275 | } else { |
255 | | - if (!(code = snd_pcm_set_params(scope_pcm, SND_PCM_FORMAT_S8, SND_PCM_ACCESS_RW_INTERLEAVED, 1, SAMPLE_RATE, 1, 1000))) { |
256 | | - printf("Got BS8C1\n"); |
257 | | - } else if (!(code = snd_pcm_set_params(scope_pcm, SND_PCM_FORMAT_S16, SND_PCM_ACCESS_RW_INTERLEAVED, 1, SAMPLE_RATE, 1, 1000))) { |
258 | | - printf("Got BS16C1\n"); |
259 | | - sf_16b = 1; |
260 | | - } else if (!(code = snd_pcm_set_params(scope_pcm, SND_PCM_FORMAT_U8, SND_PCM_ACCESS_RW_INTERLEAVED, 1, SAMPLE_RATE, 1, 1000))) { |
261 | | - printf("Got BU8C1\n"); |
262 | | - sf_us = 1; |
263 | | - } else if (!(code = snd_pcm_set_params(scope_pcm, SND_PCM_FORMAT_U16, SND_PCM_ACCESS_RW_INTERLEAVED, 1, SAMPLE_RATE, 1, 1000))) { |
264 | | - printf("Got BU16C1\n"); |
265 | | - sf_16b = 1; |
266 | | - sf_us = 1; |
267 | | - } else { |
268 | | - printf("Couldn't convince ALSA to give sane settings: %i\n", code); |
269 | | - snd_pcm_close(scope_pcm); |
270 | | - free(bufferC); |
271 | | - return 1; |
272 | | - } |
| 276 | + printf("Couldn't convince ALSA to give sane settings: %i\n", code); |
| 277 | + snd_pcm_close(scope_pcm); |
| 278 | + free(bufferC); |
| 279 | + return 1; |
| 280 | + } |
| 281 | + |
| 282 | + int bytesPerSample; |
| 283 | + int bitsPerSample; |
| 284 | + switch (sf_sampsize) { |
| 285 | + case SIZE_8: |
| 286 | + bytesPerSample = 1; |
| 287 | + bitsPerSample = 8; |
| 288 | + break; |
| 289 | + case SIZE_16: |
| 290 | + bytesPerSample = 2; |
| 291 | + bitsPerSample = 16; |
| 292 | + break; |
| 293 | + case SIZE_24: |
| 294 | + bytesPerSample = 3; |
| 295 | + bitsPerSample = 24; |
| 296 | + break; |
| 297 | + case SIZE_32: |
| 298 | + bytesPerSample = 4; |
| 299 | + bitsPerSample = 32; |
| 300 | + break; |
273 | 301 | } |
274 | | - bufferA = malloc(BUFFER_FRAMES * (sf_2c ? 2 : 1) * (sf_16b ? 2 : 1)); |
| 302 | + |
| 303 | + printf("Got B%c%dC%d\n", sf_us ? 'U' : 'S', bitsPerSample, sf_chancount); |
| 304 | + |
| 305 | + bufferA = malloc(BUFFER_FRAMES * sf_chancount * bytesPerSample); |
275 | 306 | if (!bufferA) { |
276 | 307 | printf("Couldn't allocate working buffer\n"); |
277 | 308 | snd_pcm_close(scope_pcm); |
|
0 commit comments