diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | fourier.c | 2 | ||||
-rwxr-xr-x | frekvence.php | 8 | ||||
-rw-r--r-- | makefile | 5 | ||||
-rw-r--r-- | zvok.c | 70 |
5 files changed, 65 insertions, 21 deletions
@@ -8,3 +8,4 @@ sio_record.c frekvence.h fourier naprave +zvok @@ -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; @@ -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 @@ -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; } |