diff options
author | Anton Luka Šijanec <anton@sijanec.eu> | 2023-02-09 02:08:17 +0100 |
---|---|---|
committer | Anton Luka Šijanec <anton@sijanec.eu> | 2023-02-09 02:08:17 +0100 |
commit | 21f8e1c794cbd90c6ac8cf62e832fdb8a196bcb8 (patch) | |
tree | 9da02c8a0824d48168957e5af8c94071e4b7fc85 /zvok.c | |
parent | razno (diff) | |
download | soča-21f8e1c794cbd90c6ac8cf62e832fdb8a196bcb8.tar soča-21f8e1c794cbd90c6ac8cf62e832fdb8a196bcb8.tar.gz soča-21f8e1c794cbd90c6ac8cf62e832fdb8a196bcb8.tar.bz2 soča-21f8e1c794cbd90c6ac8cf62e832fdb8a196bcb8.tar.lz soča-21f8e1c794cbd90c6ac8cf62e832fdb8a196bcb8.tar.xz soča-21f8e1c794cbd90c6ac8cf62e832fdb8a196bcb8.tar.zst soča-21f8e1c794cbd90c6ac8cf62e832fdb8a196bcb8.zip |
Diffstat (limited to 'zvok.c')
-rw-r--r-- | zvok.c | 225 |
1 files changed, 225 insertions, 0 deletions
@@ -0,0 +1,225 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <error.h> +#include <unistd.h> +#include <soundio/soundio.h> +#include <fcntl.h>> +#define ABS(x) ((x) < 0 ? -(x) : (x)) +#define NUM "4" +struct record_context { + int glasnost; +}; +static enum SoundIoFormat prioritized_formats[] = { + // SoundIoFormatFloat32NE, + // SoundIoFormatFloat32FE, + ///SoundIoFormatS32NE, + // SoundIoFormatS32FE, + ///SoundIoFormatS24NE, + // SoundIoFormatS24FE, + SoundIoFormatS16NE, + // SoundIoFormatS16FE, + // SoundIoFormatFloat64NE, + // SoundIoFormatFloat64FE, + ///SoundIoFormatU32NE, + // SoundIoFormatU32FE, + ///SoundIoFormatU24NE, + // SoundIoFormatU24FE, + // SoundIoFormatU16NE, + // SoundIoFormatU16FE, + ///SoundIoFormatS8, + ///SoundIoFormatU8, + SoundIoFormatInvalid +}; +static void read_callback (struct SoundIoInStream * instream, int frame_count_min __attribute__((unused)), int frame_count_max) { + struct record_context * rc = instream->userdata; + struct SoundIoChannelArea * areas; + int frame_count = frame_count_max; + int err = soundio_instream_begin_read(instream, &areas, &frame_count); + long long vzorcev = 0; + long long glasnost = 0; + if (!frame_count) + return; + if (!areas) // HOLE because of overrun! + rc->glasnost = 0; + else + for (int frame = 0; frame < frame_count; frame++) + for (int ch = 0; ch < instream->layout.channel_count; ch++) { + glasnost += ABS(* (int16_t *) areas[ch].ptr); + vzorcev++; + areas[ch].ptr += areas[ch].step; + } + rc->glasnost = glasnost / vzorcev; + if ((err = soundio_instream_end_read(instream))) + error_at_line(0, 0, __FILE__, __LINE__, "soundio_instream_read_end: %s", soundio_strerror(err)); +} +static void overflow_callback (struct SoundIoInStream * instream __attribute__((unused))) { + static int count = 0; + fprintf(stderr, "overflow %d\n", ++count); +} +static void error_callback (struct SoundIoInStream * instream __attribute__((unused)), int err) { + fprintf(stderr, "error %s\n", soundio_strerror(err)); // TODO this is unrecoverable, make exit of program +} +int main (void) { + struct SoundIoInStream * instream = NULL; + struct SoundIoDevice * selected_device = NULL; + int r = 0; + fprintf(stderr, "z okoljsko spremenljivko ID nastaviš id naprave -- idje izpiše program naprave\nz okoljsko spremenljivko ZALEDJE nastaviš zaledje -- program naprave izpiše možna zaledja\n"); + enum SoundIoBackend backend = SoundIoBackendNone; + char * device_id = getenv("ID"); + if (getenv("ZALEDJE")) { + switch (getenv("ZALEDJE")[0]) { + case 'd': + backend = SoundIoBackendDummy; + break; + case 'a': + backend = SoundIoBackendAlsa; + break; + case 'p': + backend = SoundIoBackendPulseAudio; + break; + case 'j': + backend = SoundIoBackendJack; + break; + case 'c': + backend = SoundIoBackendCoreAudio; + break; + case 'w': + backend = SoundIoBackendWasapi; + break; + } + } + struct SoundIo * soundio = soundio_create(); + if (!soundio) + error_at_line(1, ENOMEM, __FILE__, __LINE__, "soundio_create()"); + int err = (backend == SoundIoBackendNone) ? soundio_connect(soundio) : soundio_connect_backend(soundio, backend); + if (err) { + error_at_line(0, 0, __FILE__, __LINE__, "soundio_connect: %s", soundio_strerror(err)); + r = 2; + goto r; + } + soundio_flush_events(soundio); + if (device_id) { + for (int i = 0; i < soundio_input_device_count(soundio); i++) { + struct SoundIoDevice * device = soundio_get_input_device(soundio, i); + if (!strcmp(device_id, device->id)) { + selected_device = device; + break; + } + soundio_device_unref(device); + } + } else { + int device_index = soundio_default_input_device_index(soundio); + selected_device = soundio_get_input_device(soundio, device_index); + } + if (!selected_device) { + error_at_line(0, 0, __FILE__, __LINE__, "!selected_device"); + r = 3; + goto r; + } + fprintf(stderr, "izbrana naprava je %s\n", selected_device->name); + if (selected_device->probe_error) { + error_at_line(0, 0, __FILE__, __LINE__, "unable to probe device: %s", soundio_strerror(selected_device->probe_error)); + r = 4; + goto r; + } + soundio_device_sort_channel_layouts(selected_device); // TODO poskusi brez + int sample_rate = 0; + for (int i = 0; i < selected_device->sample_rate_count; i++) { + if (selected_device->sample_rates[i].max > sample_rate) + sample_rate = selected_device->sample_rates[i].max; + } + if (!sample_rate) { + error_at_line(0, 0, __FILE__, __LINE__, "naprava ne podpira vzorčenja"); + r = 5; + goto r; + } + if (!selected_device->format_count) { + error_at_line(0, 0, __FILE__, __LINE__, "naprava ne podpira oblik"); + r = 6; + goto r; + } + enum SoundIoFormat fmt = SoundIoFormatInvalid; + for (unsigned i = 0; i < sizeof prioritized_formats/sizeof prioritized_formats[0]; i++) { + if (soundio_device_supports_format(selected_device, prioritized_formats[i])) { + fmt = prioritized_formats[i]; + break; + } + } + if (fmt == SoundIoFormatInvalid) { + // fmt = selected_device->formats[0]; + error_at_line(0, 0, __FILE__, __LINE__, "naprava ne podpira podprte oblike"); + r = 7; + goto r; + } + instream = soundio_instream_create(selected_device); + if (!instream) { + error_at_line(0, 0, __FILE__, __LINE__, "oom"); + r = 8; + goto r; + } + sample_rate = 8000; + fprintf(stderr, "hitrost vzorčenja je %d Hz, %s (prepleten)\n", sample_rate, soundio_format_string(fmt)); + instream->format = fmt; + instream->sample_rate = sample_rate; + instream->read_callback = read_callback; + instream->overflow_callback = overflow_callback; + instream->error_callback = error_callback; + struct record_context rc = { 0 }; + instream->userdata = &rc; + if ((err = soundio_instream_open(instream))) { + error_at_line(0, 0, __FILE__, __LINE__, "soundio_instream_open: %s (%d)", soundio_strerror(err), err); + r = 9; + goto r; + } + if (instream->bytes_per_sample != 2) { + error_at_line(0, 0, __FILE__, __LINE__, "pričakoval sem osembitne vzorce, nisem jih dobil (%d bajtov na vzorec)", instream->bytes_per_sample); + r = 10; + goto r; + } + fprintf(stderr, "pretok: %s\n", instream->layout.name); + if ((err = soundio_instream_start(instream))) { + error_at_line(0, 0, __FILE__, __LINE__, "soundio_instream_start: %s", soundio_strerror(err)); + r = 11; + goto r; + } + int najv_gl = 1; + int leds[] = { open("/sys/class/leds/input" NUM "::numlock/brightness", O_WRONLY), open("/sys/class/leds/input" NUM "::capslock/brightness", O_WRONLY), open("/sys/class/leds/input" NUM "::scrolllock/brightness", O_WRONLY) }; + while (1) { + soundio_flush_events(soundio); + usleep(10000); + if (rc.glasnost > najv_gl) + najv_gl = rc.glasnost; + if (najv_gl < 1) + najv_gl = 1; + printf("glasnost: "); + for (int i = 0; i < 64; i++) + if (((double) rc.glasnost/najv_gl)*64 > i) + printf("@"); + else + printf(" "); + if ((double) rc.glasnost/najv_gl > 0.2) + write(leds[0], "1", 1); + else + write(leds[0], "0", 1); + if ((double) rc.glasnost/najv_gl > 0.5) + write(leds[1], "1", 1); + else + write(leds[1], "0", 1); + if ((double) rc.glasnost/najv_gl > 0.7) + write(leds[2], "1", 1); + else + write(leds[2], "0", 1); + printf("\n"); + if (rc.glasnost < najv_gl/2) + najv_gl -= 5; + } + r: + if (instream) + soundio_instream_destroy(instream); + if (selected_device) + soundio_device_unref(selected_device); + soundio_destroy(soundio); + return r; +} |