parent
b1ea4e574f
commit
b2089bb529
@ -0,0 +1,48 @@ |
||||
AM_CPPFLAGS = -Wall -Wextra -g $(all_includes) -fstack-check $(FUSE_CFLAGS)
|
||||
|
||||
bin_PROGRAMS = \
|
||||
zeitansage
|
||||
|
||||
zeitansage_SOURCES = \
|
||||
zeitansage.c \
|
||||
image.c \
|
||||
samples.c \
|
||||
main.c
|
||||
zeitansage_LDADD = \
|
||||
$(COMMON_LA) \
|
||||
$(top_builddir)/src/liboptions/liboptions.a \
|
||||
$(top_builddir)/src/libdebug/libdebug.a \
|
||||
$(top_builddir)/src/libmobile/libmobile.a \
|
||||
$(top_builddir)/src/libdisplay/libdisplay.a \
|
||||
$(top_builddir)/src/libjitter/libjitter.a \
|
||||
$(top_builddir)/src/libtimer/libtimer.a \
|
||||
$(top_builddir)/src/libsamplerate/libsamplerate.a \
|
||||
$(top_builddir)/src/libemphasis/libemphasis.a \
|
||||
$(top_builddir)/src/libfsk/libfsk.a \
|
||||
$(top_builddir)/src/libfm/libfm.a \
|
||||
$(top_builddir)/src/libfilter/libfilter.a \
|
||||
$(top_builddir)/src/libwave/libwave.a \
|
||||
$(top_builddir)/src/libmncc/libmncc.a \
|
||||
$(top_builddir)/src/libsample/libsample.a \
|
||||
$(ALSA_LIBS) \
|
||||
-lm
|
||||
|
||||
if HAVE_ALSA |
||||
zeitansage_LDADD += \
|
||||
$(top_builddir)/src/libsound/libsound.a \
|
||||
$(ALSA_LIBS)
|
||||
endif |
||||
|
||||
if HAVE_SDR |
||||
zeitansage_LDADD += \
|
||||
$(top_builddir)/src/libsdr/libsdr.a \
|
||||
$(top_builddir)/src/libam/libam.a \
|
||||
$(top_builddir)/src/libfft/libfft.a \
|
||||
$(UHD_LIBS) \
|
||||
$(SOAPY_LIBS)
|
||||
endif |
||||
|
||||
if HAVE_ALSA |
||||
AM_CPPFLAGS += -DHAVE_ALSA
|
||||
endif |
||||
|
@ -0,0 +1,91 @@ |
||||
#include <stdio.h> |
||||
#include <string.h> |
||||
#include "../libmobile/image.h" |
||||
|
||||
const char *image[] = { |
||||
"", |
||||
" @G___________________________", |
||||
" / \\", |
||||
" / ___________________ \\", |
||||
" @w()@G|-------/ \\-------|", |
||||
" @w() @G\\_____| @Y\\ @r| / @G|_____/", |
||||
" @w() @G| @r\\ @Y\\ @r/ @G|", |
||||
" @w() (@G| @Y\\ @G | @y\"@BBeim naechsten Ton ist es", |
||||
" @w() () @G| @r-- @Y| @r-- @G| @B17 Urrr,", |
||||
" @w() () @G| @Y| @G| @B55 Minuten", |
||||
" @w()()() @G| @r/ \\ @G| @Bund 20 Sekunden.@y\"", |
||||
" @G| @r/ | \\ @G|", |
||||
" @G| |", |
||||
" @G\\_________________/", |
||||
"", |
||||
" @W* Zeitansage: 1191 *", |
||||
"", |
||||
NULL |
||||
}; |
||||
|
||||
void print_image(void) |
||||
{ |
||||
int i, j; |
||||
|
||||
for (i = 0; image[i]; i++) { |
||||
for (j = 0; j < (int)strlen(image[i]); j++) { |
||||
if (image[i][j] == '@') { |
||||
j++; |
||||
switch(image[i][j]) { |
||||
case 'k': /* black */ |
||||
printf("\033[0;30m"); |
||||
break; |
||||
case 'r': /* red */ |
||||
printf("\033[0;31m"); |
||||
break; |
||||
case 'g': /* green */ |
||||
printf("\033[0;32m"); |
||||
break; |
||||
case 'y': /* yellow */ |
||||
printf("\033[0;33m"); |
||||
break; |
||||
case 'b': /* blue */ |
||||
printf("\033[0;34m"); |
||||
break; |
||||
case 'm': /* magenta */ |
||||
printf("\033[0;35m"); |
||||
break; |
||||
case 'c': /* cyan */ |
||||
printf("\033[0;36m"); |
||||
break; |
||||
case 'w': /* white */ |
||||
printf("\033[0;37m"); |
||||
break; |
||||
case 'K': /* bright black */ |
||||
printf("\033[1;30m"); |
||||
break; |
||||
case 'R': /* bright red */ |
||||
printf("\033[1;31m"); |
||||
break; |
||||
case 'G': /* bright green */ |
||||
printf("\033[1;32m"); |
||||
break; |
||||
case 'Y': /* bright yellow */ |
||||
printf("\033[1;33m"); |
||||
break; |
||||
case 'B': /* bright blue */ |
||||
printf("\033[1;34m"); |
||||
break; |
||||
case 'M': /* bright magenta */ |
||||
printf("\033[1;35m"); |
||||
break; |
||||
case 'C': /* bright cyan */ |
||||
printf("\033[1;36m"); |
||||
break; |
||||
case 'W': /* bright white */ |
||||
printf("\033[1;37m"); |
||||
break; |
||||
} |
||||
} else |
||||
printf("%c", image[i][j]); |
||||
} |
||||
printf("\n"); |
||||
} |
||||
printf("\033[0;39m"); |
||||
} |
||||
|
@ -0,0 +1,103 @@ |
||||
/* Zeitansage main
|
||||
* |
||||
* (C) 2020 by Andreas Eversberg <jolly@eversberg.eu> |
||||
* All Rights Reserved |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License as published by |
||||
* the Free Software Foundation, either version 3 of the License, or |
||||
* (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
|
||||
#include <stdio.h> |
||||
#include <stdint.h> |
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
#include <errno.h> |
||||
#include "../libsample/sample.h" |
||||
#include "../libdebug/debug.h" |
||||
#include "../libmobile/call.h" |
||||
#include "../libmobile/main_mobile.h" |
||||
#include "../liboptions/options.h" |
||||
#include "zeitansage.h" |
||||
#include "samples.h" |
||||
|
||||
double audio_level_dBm = -16.0; |
||||
int alerting = 0; |
||||
|
||||
|
||||
void print_help(const char *arg0) |
||||
{ |
||||
main_mobile_print_help(arg0, "-c hw:0,0 "); |
||||
/* - - */ |
||||
printf(" -G --gain\n"); |
||||
printf(" Gain of audio level relative to 1 mW on a 600 Ohm line. (default = %.0f)\n", audio_level_dBm); |
||||
printf(" -A --alerting\n"); |
||||
printf(" Play as early audio while alerting. Don't send a connect.\n"); |
||||
main_mobile_print_hotkeys(); |
||||
} |
||||
|
||||
static void add_options(void) |
||||
{ |
||||
main_mobile_add_options(); |
||||
option_add('G', "gain", 1); |
||||
option_add('A', "alerting", 0); |
||||
} |
||||
|
||||
static int handle_options(int short_option, int argi, char **argv) |
||||
{ |
||||
switch (short_option) { |
||||
case 'G': |
||||
audio_level_dBm = atof(argv[argi]); |
||||
break; |
||||
case 'A': |
||||
alerting = 1; |
||||
send_patterns = 0; |
||||
break; |
||||
default: |
||||
return main_mobile_handle_options(short_option, argi, argv); |
||||
} |
||||
|
||||
return 1; |
||||
} |
||||
|
||||
int main(int argc, char *argv[]) |
||||
{ |
||||
int rc, argi; |
||||
|
||||
/* init system specific tones */ |
||||
init_samples(); |
||||
|
||||
main_mobile_init(); |
||||
|
||||
/* handle options / config file */ |
||||
add_options(); |
||||
rc = options_config_file("~/.osmocom/analog/zeitansage.conf", handle_options); |
||||
if (rc < 0) |
||||
return 0; |
||||
argi = options_command_line(argc, argv, handle_options); |
||||
if (argi <= 0) |
||||
return argi; |
||||
|
||||
/* inits */ |
||||
fm_init(fast_math); |
||||
zeit_init(audio_level_dBm, alerting); |
||||
|
||||
main_mobile(&quit, latency, interval, NULL, "1191", 4); |
||||
|
||||
//fail:
|
||||
/* exits */ |
||||
zeit_exit(); |
||||
fm_exit(); |
||||
|
||||
return 0; |
||||
} |
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,3 @@ |
||||
|
||||
void init_samples(void); |
||||
|
@ -0,0 +1,406 @@ |
||||
/* Zeitansage processing
|
||||
* |
||||
* (C) 2020 by Andreas Eversberg <jolly@eversberg.eu> |
||||
* All Rights Reserved |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License as published by |
||||
* the Free Software Foundation, either version 3 of the License, or |
||||
* (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
|
||||
#include <stdio.h> |
||||
#include <stdint.h> |
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
#include <errno.h> |
||||
#include <math.h> |
||||
#include <time.h> |
||||
#include "../libsample/sample.h" |
||||
#include "../libdebug/debug.h" |
||||
#include "../libmobile/call.h" |
||||
#include "../libmncc/cause.h" |
||||
#include "zeitansage.h" |
||||
|
||||
#define db2level(db) pow(10, (double)(db) / 20.0) |
||||
|
||||
/* list of calls */ |
||||
zeit_call_t *zeit_call_list = NULL; |
||||
|
||||
double audio_gain; |
||||
double early_audio; |
||||
|
||||
#define BEEP_TIME 16000 /* adjust distance from beep in samples */ |
||||
|
||||
int16_t *bntie_spl; |
||||
int bntie_size; |
||||
int bntie_time; /* sample index when intro is over */ |
||||
int16_t *urrr_spl[24]; |
||||
int urrr_size[24]; |
||||
int urrr_time; /* sample index when hour is over */ |
||||
int16_t *minuten_spl[60]; |
||||
int minuten_size[60]; |
||||
int minuten_time; /* sample index when minute is over */ |
||||
int16_t *sekunden_spl[60]; |
||||
int sekunden_size[60]; |
||||
int sekunden_time; /* sample index when second is over */ |
||||
int16_t *tut_spl; |
||||
int tut_size; |
||||
int tut_time; /* sample index when beep is over */ |
||||
|
||||
static const char *call_state_name(enum zeit_call_state state) |
||||
{ |
||||
static char invalid[16]; |
||||
|
||||
switch (state) { |
||||
case ZEIT_CALL_NULL: |
||||
return "(NULL)"; |
||||
case ZEIT_CALL_BEEP: |
||||
return "BEEP"; |
||||
case ZEIT_CALL_INTRO: |
||||
return "INTRO"; |
||||
case ZEIT_CALL_HOUR: |
||||
return "HOUR"; |
||||
case ZEIT_CALL_MINUTE: |
||||
return "MINUTE"; |
||||
case ZEIT_CALL_SECOND: |
||||
return "SECOND"; |
||||
case ZEIT_CALL_PAUSE: |
||||
return "PAUSE"; |
||||
} |
||||
|
||||
sprintf(invalid, "invalid(%d)", state); |
||||
return invalid; |
||||
} |
||||
|
||||
static void zeit_display_status(void) |
||||
{ |
||||
zeit_call_t *call; |
||||
|
||||
display_status_start(); |
||||
for (call = zeit_call_list; call; call = call->next) |
||||
display_status_subscriber(call->caller_id, call_state_name(call->state)); |
||||
display_status_end(); |
||||
} |
||||
|
||||
|
||||
static void call_new_state(zeit_call_t *call, enum zeit_call_state new_state) |
||||
{ |
||||
if (call->state == new_state) |
||||
return; |
||||
PDEBUG(DZEIT, DEBUG_DEBUG, "State change: %s -> %s\n", call_state_name(call->state), call_state_name(new_state)); |
||||
call->state = new_state; |
||||
zeit_display_status(); |
||||
} |
||||
|
||||
/* global init */ |
||||
int zeit_init(double audio_level_dBm, int alerting) |
||||
{ |
||||
int i; |
||||
|
||||
/* the recordings are speech level, so we apply gain as is */ |
||||
audio_gain = db2level(audio_level_dBm); |
||||
|
||||
early_audio = alerting; |
||||
|
||||
/* get maximum length for each speech segment */ |
||||
tut_time = BEEP_TIME; |
||||
bntie_time = bntie_size + tut_time; |
||||
urrr_time = 0; |
||||
for (i = 0; i < 24; i++) { |
||||
if (urrr_size[i] > urrr_time) |
||||
urrr_time = urrr_size[i]; |
||||
} |
||||
urrr_time += bntie_time; |
||||
minuten_time = 0; |
||||
for (i = 0; i < 60; i++) { |
||||
if (minuten_size[i] > minuten_time) |
||||
minuten_time = minuten_size[i]; |
||||
} |
||||
minuten_time += urrr_time; |
||||
sekunden_time = 0; |
||||
for (i = 0; i < 60; i += 10) { |
||||
if (sekunden_size[i] > sekunden_time) |
||||
sekunden_time = sekunden_size[i]; |
||||
} |
||||
sekunden_time += minuten_time; |
||||
|
||||
PDEBUG(DZEIT, DEBUG_DEBUG, "Total time to play anouncement, starting with beep: %.2f seconds\n", (double)sekunden_time / 8000.0); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
/* global exit */ |
||||
void zeit_exit(void) |
||||
{ |
||||
} |
||||
|
||||
/* calculate what time to speak */ |
||||
static void zeit_calc_time(zeit_call_t *call, time_t time_sec) |
||||
{ |
||||
struct tm *tm; |
||||
|
||||
/* we speak 10 seconds in advance */ |
||||
time_sec += 10; |
||||
|
||||
tm = localtime(&time_sec); |
||||
call->h = tm->tm_hour; |
||||
call->m = tm->tm_min; |
||||
call->s = tm->tm_sec; |
||||
|
||||
PDEBUG(DZEIT, DEBUG_INFO, "The time at the next beep is: %d:%02d:%02d\n", call->h, call->m, call->s); |
||||
} |
||||
|
||||
static void call_timeout(struct timer *timer); |
||||
|
||||
/* Create call instance */ |
||||
static zeit_call_t *zeit_call_create(uint32_t callref, const char *id) |
||||
{ |
||||
zeit_call_t *call, **callp; |
||||
double now, time_offset; |
||||
time_t time_sec; |
||||
|
||||
PDEBUG(DZEIT, DEBUG_INFO, "Creating call instance to play time for caller '%s'.\n", id); |
||||
|
||||
/* create */ |
||||
call = calloc(1, sizeof(*call)); |
||||
if (!call) { |
||||
PDEBUG(DZEIT, DEBUG_ERROR, "No mem!\n"); |
||||
abort(); |
||||
} |
||||
|
||||
/* init */ |
||||
call->callref = callref; |
||||
strncpy(call->caller_id, id, sizeof(call->caller_id) - 1); |
||||
timer_init(&call->timer, call_timeout, call); |
||||
now = get_time(); |
||||
time_offset = fmod(now, 10.0); |
||||
time_sec = (int)floor(now / 10.0) * 10; |
||||
call->spl_time = (int)(time_offset * 8000.0); |
||||
zeit_calc_time(call, time_sec); |
||||
timer_start(&call->timer, 10.0 - time_offset); |
||||
|
||||
/* link */ |
||||
callp = &zeit_call_list; |
||||
while ((*callp)) |
||||
callp = &(*callp)->next; |
||||
(*callp) = call; |
||||
|
||||
return call; |
||||
} |
||||
|
||||
/* Destroy call instance */ |
||||
static void zeit_call_destroy(zeit_call_t *call) |
||||
{ |
||||
zeit_call_t **callp; |
||||
|
||||
/* unlink */ |
||||
callp = &zeit_call_list; |
||||
while ((*callp) != call) |
||||
callp = &(*callp)->next; |
||||
(*callp) = call->next; |
||||
|
||||
/* cleanup */ |
||||
timer_exit(&call->timer); |
||||
|
||||
/* destroy */ |
||||
free(call); |
||||
|
||||
/* update display */ |
||||
zeit_display_status(); |
||||
} |
||||
|
||||
/* play samples for one call */ |
||||
static void call_play(zeit_call_t *call) |
||||
{ |
||||
int i = 0; |
||||
int16_t chunk[160]; |
||||
sample_t spl[160]; |
||||
int16_t *play_spl; /* current sample */ |
||||
int play_size; /* current size of sample*/ |
||||
int play_index; /* current sample index */ |
||||
int play_max; /* total length to plax */ |
||||
int spl_time; /* sample offset from start of 10 minutes */ |
||||
|
||||
spl_time = call->spl_time; |
||||
|
||||
next_sample: |
||||
/* select sample from current sample time stamp */ |
||||
if (spl_time < tut_time) { |
||||
play_index = spl_time; |
||||
play_max = tut_time; |
||||
play_size = tut_size; |
||||
play_spl = tut_spl; |
||||
call_new_state(call, ZEIT_CALL_BEEP); |
||||
} else |
||||
if (spl_time < bntie_time) { |
||||
play_index = spl_time - tut_time; |
||||
play_max = bntie_time - tut_time; |
||||
play_size = bntie_size; |
||||
play_spl = bntie_spl; |
||||
call_new_state(call, ZEIT_CALL_INTRO); |
||||
} else |
||||
if (spl_time < urrr_time) { |
||||
play_index = spl_time - bntie_time; |
||||
play_max = urrr_time - bntie_time; |
||||
play_size = urrr_size[call->h]; |
||||
play_spl = urrr_spl[call->h]; |
||||
call_new_state(call, ZEIT_CALL_HOUR); |
||||
} else |
||||
if (spl_time < minuten_time) { |
||||
play_index = spl_time - urrr_time; |
||||
play_max = minuten_time - urrr_time; |
||||
play_size = minuten_size[call->m]; |
||||
play_spl = minuten_spl[call->m]; |
||||
call_new_state(call, ZEIT_CALL_MINUTE); |
||||
} else |
||||
if (spl_time < sekunden_time) { |
||||
play_index = spl_time - minuten_time; |
||||
play_max = sekunden_time - minuten_time; |
||||
play_size = sekunden_size[call->s]; |
||||
play_spl = sekunden_spl[call->s]; |
||||
call_new_state(call, ZEIT_CALL_SECOND); |
||||
} else { |
||||
play_index = 0; |
||||
play_max = 0; |
||||
play_size = 0; |
||||
play_spl = NULL; |
||||
call_new_state(call, ZEIT_CALL_PAUSE); |
||||
} |
||||
|
||||
while (i < 160) { |
||||
if (!play_size) { |
||||
chunk[i++] = 0.0; |
||||
continue; |
||||
} |
||||
/* go to next sample */ |
||||
if (play_index == play_max) |
||||
goto next_sample; |
||||
/* announcement or silence, if finished or not set */ |
||||
if (play_index < play_size) |
||||
chunk[i++] = play_spl[play_index]; |
||||
else |
||||
chunk[i++] = 0.0; |
||||
play_index++; |
||||
spl_time++; |
||||
} |
||||
|
||||
call->spl_time = spl_time; |
||||
|
||||
/* convert to samples, apply gain and send toward fixed network */ |
||||
int16_to_samples(spl, chunk, 160); |
||||
for (i = 0; i < 160; i++) |
||||
spl[i] *= audio_gain; |
||||
call_up_audio(call->callref, spl, 160); |
||||
} |
||||
|
||||
/* loop through all calls and play the announcement */ |
||||
void call_down_clock(void) |
||||
{ |
||||
zeit_call_t *call; |
||||
|
||||
for (call = zeit_call_list; call; call = call->next) { |
||||
/* no callref */ |
||||
if (!call->callref) |
||||
continue; |
||||
/* beep or announcement */ |
||||
call_play(call); |
||||
} |
||||
} |
||||
|
||||
/* Timeout handling */ |
||||
static void call_timeout(struct timer *timer) |
||||
{ |
||||
zeit_call_t *call = (zeit_call_t *)timer->priv; |
||||
double now, time_offset; |
||||
time_t time_sec; |
||||
|
||||
PDEBUG(DZEIT, DEBUG_INFO, "Beep!\n"); |
||||
|
||||
now = get_time(); |
||||
|
||||
time_offset = fmod(now, 10.0); |
||||
time_sec = (int)floor(now / 10.0) * 10; |
||||
/* if somehow the timer fires (a tiny bit) before the 10 seconds start */ |
||||
if (time_offset > 5.0) { |
||||
time_offset -= 10.0; |
||||
time_sec += 10; |
||||
} |
||||
call->spl_time = 0; |
||||
zeit_calc_time(call, time_sec); |
||||
timer_start(&call->timer, 10.0 - time_offset); |
||||
} |
||||
|
||||
/* Call control starts call towards clock */ |
||||
int call_down_setup(int callref, const char __attribute__((unused)) *caller_id, enum number_type __attribute__((unused)) caller_type, const char *dialing) |
||||
{ |
||||
zeit_call_t __attribute__((unused)) *call; |
||||
|
||||
/* create call process to page station or send out-of-order message */ |
||||
call = zeit_call_create(callref, caller_id); |
||||
if (early_audio) { |
||||
call_up_alerting(callref); |
||||
call_up_early(callref); |
||||
} else |
||||
call_up_answer(callref, dialing); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
void call_down_answer(int __attribute__((unused)) callref) |
||||
{ |
||||
} |
||||
|
||||
static void _release(int callref, int __attribute__((unused)) cause) |
||||
{ |
||||
zeit_call_t *call; |
||||
|
||||
PDEBUG(DZEIT, DEBUG_INFO, "Call has been disconnected by network.\n"); |
||||
|
||||
for (call = zeit_call_list; call; call = call->next) { |
||||
if (call->callref == callref) |
||||
break; |
||||
} |
||||
if (!call) { |
||||
PDEBUG(DZEIT, DEBUG_NOTICE, "Outgoing disconnect, but no callref!\n"); |
||||
call_up_release(callref, CAUSE_INVALCALLREF); |
||||
return; |
||||
} |
||||
|
||||
zeit_call_destroy(call); |
||||
} |
||||
|
||||
/* Call control sends disconnect.
|
||||
* A queued ID will be kept until transmitted by mobile station. |
||||
*/ |
||||
void call_down_disconnect(int callref, int cause) |
||||
{ |
||||
_release(callref, cause); |
||||
|
||||
call_up_release(callref, cause); |
||||
} |
||||
|
||||
/* Call control releases call toward mobile station. */ |
||||
void call_down_release(int callref, int cause) |
||||
{ |
||||
_release(callref, cause); |
||||
} |
||||
|
||||
/* Receive audio from call instance. */ |
||||
void call_down_audio(int __attribute__((unused)) callref, sample_t __attribute__((unused)) *samples, int __attribute__((unused)) count) |
||||
{ |
||||
} |
||||
|
||||
void dump_info(void) {} |
||||
|
||||
void sender_receive(sender_t __attribute__((unused)) *sender, sample_t __attribute__((unused)) *samples, int __attribute__((unused)) length, double __attribute__((unused)) rf_level_db) {} |
||||
void sender_send(sender_t __attribute__((unused)) *sender, sample_t __attribute__((unused)) *samples, uint8_t __attribute__((unused)) *power, int __attribute__((unused)) length) {} |
||||
|
@ -0,0 +1,29 @@ |
||||
#include "../libfm/fm.h" |
||||
#include "../libmobile/sender.h" |
||||
#include "../libtimer/timer.h" |
||||
|
||||
/* current state of incoming call */ |
||||
enum zeit_call_state { |
||||
ZEIT_CALL_NULL = 0, |
||||
ZEIT_CALL_BEEP, /* play beep at the beginnung of each 10 seconds period */ |
||||
ZEIT_CALL_INTRO, /* play intro sample */ |
||||
ZEIT_CALL_HOUR, /* play hour sample */ |
||||
ZEIT_CALL_MINUTE, /* play minute sample */ |
||||
ZEIT_CALL_SECOND, /* play second sample */ |
||||
ZEIT_CALL_PAUSE, /* pause until next 10 seconds period */ |
||||
}; |
||||
|
||||
/* instance of incoming call */ |
||||
typedef struct zeit_call { |
||||
struct zeit_call *next; |
||||
int callref; /* call reference */ |
||||
struct timer timer; |
||||
enum zeit_call_state state; /* current state */ |
||||
char caller_id[32]; /* caller id to be displayed */ |
||||
int spl_time; /* sample offset within 10 seconds */ |
||||
int h, m, s; /* what hour, minute, second to play */ |
||||
} zeit_call_t; |
||||
|
||||
int zeit_init(double audio_level_dBm, int alerting); |
||||
void zeit_exit(void); |
||||
|
Loading…
Reference in new issue