summaryrefslogtreecommitdiffstats
path: root/zvok.c
diff options
context:
space:
mode:
authorAnton Luka Šijanec <anton@sijanec.eu>2023-04-09 13:27:14 +0200
committerAnton Luka Šijanec <anton@sijanec.eu>2023-04-09 13:27:14 +0200
commit097f7712a179dcc5a75b727bd8d84ba41b10a36f (patch)
treea799b4b18ce5dea90f0b15f63526969f2dc1a6cc /zvok.c
parentremove.stdio (diff)
downloadsoča-097f7712a179dcc5a75b727bd8d84ba41b10a36f.tar
soča-097f7712a179dcc5a75b727bd8d84ba41b10a36f.tar.gz
soča-097f7712a179dcc5a75b727bd8d84ba41b10a36f.tar.bz2
soča-097f7712a179dcc5a75b727bd8d84ba41b10a36f.tar.lz
soča-097f7712a179dcc5a75b727bd8d84ba41b10a36f.tar.xz
soča-097f7712a179dcc5a75b727bd8d84ba41b10a36f.tar.zst
soča-097f7712a179dcc5a75b727bd8d84ba41b10a36f.zip
Diffstat (limited to 'zvok.c')
-rw-r--r--zvok.c70
1 files changed, 55 insertions, 15 deletions
diff --git a/zvok.c b/zvok.c
index 079b1f3..68fda35 100644
--- a/zvok.c
+++ b/zvok.c
@@ -8,17 +8,57 @@
#include <fcntl.h>
#define ABS(x) ((x) < 0 ? -(x) : (x))
#define NUM "4"
-struct record_context {
- int glasnost;
+void dummyhandler (struct context * rc, float * samples, int samples_num, enum action) { // does nothing
+}
+enum action {
+ kys, // this is the last time function will be called, free handler data and NULL it
+ dtmf_1,
+ dtmf_2,
+ dtmf_3,
+ dtmf_4,
+ dtmf_5,
+ dtmf_6,
+ dtmf_7,
+ dtmf_8,
+ dtmf_9,
+ dtmf_0,
+ dtmf_a,
+ dtmf_b,
+ dtmf_c,
+ dtmf_d,
+ dtmf_zvezdica,
+ dtmf_lojtra,
+ band,
+ spodnja,
+ zgornja,
+ oranžna,
+ plava
+};
+enum state {
+ silence, // initial state, waiting on line for relation. when changing to silence, kill handler.
+ carrier,
+ forbidden, // dtmf # detected
+ called, // set immediately if calling number is empty
+ nonsense, // set if menu handler doesn't understand and we shouldn't respond
+ handler, // call handler on every action
+ playing // ptt is held down and samples are being sent
+};
+struct context {
+ double glasnost; // delete
+ unsigned roger1; // micros when roger1 was received. when roger2 is received and this time is less than 1000, roger was completely received. if this is greater than 1000, reset to 0 indicating no roger1 was present. on completely received roger, kill handler and switch to playing state. switch to playing state only upon completely hearing roger.
+ enum state state;
+ double * samples; // samples to play
+ unsigned samples_length; // when playing, if samples_length is longer than 60 seconds, cut playback for safety -- we could do this in hardware as well.
+ unsigned eot; // micros when transmission will be over and we have to release PTT
+ void * handler_data; // assert that it's NULL after sending kys to handler
};
static enum SoundIoFormat prioritized_formats[] = {
- // SoundIoFormatFloat32NE,
// SoundIoFormatFloat32FE,
///SoundIoFormatS32NE,
// SoundIoFormatS32FE,
///SoundIoFormatS24NE,
// SoundIoFormatS24FE,
- SoundIoFormatS16NE,
+ // SoundIoFormatS16NE,
// SoundIoFormatS16FE,
// SoundIoFormatFloat64NE,
// SoundIoFormatFloat64FE,
@@ -33,20 +73,20 @@ static enum SoundIoFormat prioritized_formats[] = {
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 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;
+ double glasnost = 0;
if (!frame_count)
return;
- if (!areas) // HOLE because of overrun!
+ if (!areas) // HOLE because of overrun! -- kill handler and change to silence/initial state
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);
+ glasnost += ABS(* (float *) areas[ch].ptr);
vzorcev++;
areas[ch].ptr += areas[ch].step;
}
@@ -127,11 +167,11 @@ int main (void) {
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 (44100 <= selected_device->sample_rates[i].max && 44100 >= selected_device->sample_rates[i].min)
+ sample_rate = 44100;
}
if (!sample_rate) {
- error_at_line(0, 0, __FILE__, __LINE__, "naprava ne podpira vzorčenja");
+ error_at_line(0, 0, __FILE__, __LINE__, "naprava ne podpira vzorčenja na željeni frekvenci");
r = 5;
goto r;
}
@@ -159,22 +199,22 @@ int main (void) {
r = 8;
goto r;
}
- sample_rate = 8000;
+ // 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 };
+ struct 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);
+ if (instream->bytes_per_sample != 4) {
+ error_at_line(0, 0, __FILE__, __LINE__, "nisem pričakoval vzorcev, velikih po %d bajtov", instream->bytes_per_sample);
r = 10;
goto r;
}