summaryrefslogtreecommitdiffstats
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
parentremove.stdio (diff)
downloadsoča-master.tar
soča-master.tar.gz
soča-master.tar.bz2
soča-master.tar.lz
soča-master.tar.xz
soča-master.tar.zst
soča-master.zip
-rw-r--r--.gitignore1
-rw-r--r--fourier.c2
-rwxr-xr-xfrekvence.php8
-rw-r--r--makefile5
-rw-r--r--zvok.c70
5 files changed, 65 insertions, 21 deletions
diff --git a/.gitignore b/.gitignore
index cd15f56..fa16199 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,3 +8,4 @@ sio_record.c
frekvence.h
fourier
naprave
+zvok
diff --git a/fourier.c b/fourier.c
index d432f7b..6df913d 100644
--- a/fourier.c
+++ b/fourier.c
@@ -25,7 +25,7 @@ void add_sample (struct fourier * f, double received) {
f->sums[frekvenca] += received*cpow(M_E, -2*M_PI*I*frekvence[frekvenca]*f->sample/f->rate);
f->sums[frekvenca] -= f->samples[f->sample % SAMPLES]*cpow(M_E, -2*M_PI*I*frekvence[frekvenca]*(f->sample-SAMPLES)/f->rate);
}
- int najv[3] = { 0 };
+ int najv[3] = { 0 }; // XXX refactor this to support roger_drugi decoding
double val[3] = { 0 };
for (unsigned i = 0; i < FREKVENC; i++)
for (int j = 0; j < 3; j++) {
diff --git a/frekvence.php b/frekvence.php
index c085d21..16b950e 100755
--- a/frekvence.php
+++ b/frekvence.php
@@ -14,9 +14,9 @@ $i = <<<HEREDOC
1000 zgornja_tipka
1450 oranžna_tipka
1750 plava_tipka
+1092 roger_prvi
+869 roger_drugi
HEREDOC;
-// 1092 roger_prvi preveč mažeta 3. vrstico dtmfjev
-// 869 roger_drugi če dodaš, moraš popraviti tudi v $t spodaj - ZAMIKI!
// 123 ctcss_123 nesmiselno zaznavati skupaj - ctcss je treba zaznavati posebej!
$f = [];
foreach (explode("\n", $i) as $l) {
@@ -60,9 +60,9 @@ spodnja
zgornja
oranžna
plava
+roger1
+roger2
HEREDOC;
-// roger1
-// roger2
// ctcss
$t = explode("\n", trim($t));
echo "enum ton {" . PHP_EOL;
diff --git a/makefile b/makefile
index 32eed24..eac2b44 100644
--- a/makefile
+++ b/makefile
@@ -3,7 +3,7 @@ CC=cc
MYCFLAGS=-O0 -Wall -Wextra -Wformat -pedantic -g -I. # -fsanitize=address
MYLDFLAGS=
-default: ptt naprave fourier
+default: ptt naprave fourier zvok
ptt: ptt.c
$(CC) $(MYCFLAGS) $(CFLAGS) $< -o$@ $(MYLDFLAGS) $(LDFLAGS)
@@ -14,6 +14,9 @@ naprave: naprave.c
fourier: fourier.c frekvence.h
$(CC) $(MYCFLAGS) $(CFLAGS) $< -o$@ $(MYLDFLAGS) $(LDFLAGS) -lm
+zvok: zvok.c
+ $(CC) $(MYCFLAGS) $(CFLAGS) $< -o$@ $(MYLDFLAGS) $(LDFLAGS) -lsoundio
+
frekvence.h: frekvence.php
./frekvence.php > frekvence.h
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;
}