2 * SBG (SBaGen) file format decoder
3 * Copyright (c) 2011 Nicolas George
5 * This file is part of FFmpeg.
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 #include "libavutil/intreadwrite.h"
26 #include "libavutil/log.h"
27 #include "libavutil/opt.h"
28 #include "libavutil/time_internal.h"
32 #define SBG_SCALE (1 << 16)
33 #define DAY (24 * 60 * 60)
34 #define DAY_TS ((int64_t)DAY * AV_TIME_BASE)
55 int8_t in, out, slide;
67 /* bell: freq constant, ampl decreases exponentially, can be approx lin */
69 struct sbg_timestamp {
71 char type; /* 0 for relative, 'N' for now, 'T' for absolute */
74 struct sbg_script_definition {
77 int elements, nb_elements;
78 char type; /* 'S' or 'B' */
81 struct sbg_script_synth {
85 enum sbg_synth_type type;
91 struct sbg_script_tseq {
92 struct sbg_timestamp ts;
99 struct sbg_script_event {
101 int64_t ts_int, ts_trans, ts_next;
102 int elements, nb_elements;
103 struct sbg_fade fade;
107 struct sbg_script_definition *def;
108 struct sbg_script_synth *synth;
109 struct sbg_script_tseq *tseq;
110 struct sbg_script_tseq *block_tseq;
111 struct sbg_script_event *events;
118 int64_t opt_fade_time;
119 int64_t opt_duration;
122 uint8_t opt_start_at_first;
123 uint8_t opt_end_at_last;
130 struct sbg_script scs;
131 struct sbg_timestamp current_time;
133 int nb_def_max, nb_synth_max, nb_tseq_max, nb_block_tseq_max;
138 enum ws_interval_type {
139 WS_SINE = MKTAG('S','I','N','E'),
140 WS_NOISE = MKTAG('N','O','I','S'),
145 enum ws_interval_type type;
152 struct ws_intervals {
153 struct ws_interval *inter;
158 static void *alloc_array_elem(void **array, size_t elsize,
159 int *size, int *max_size)
163 if (*size == *max_size) {
164 int m = FFMAX(32, FFMIN(*max_size, INT_MAX / 2) * 2);
167 *array = av_realloc_f(*array, m, elsize);
172 ret = (char *)*array + elsize * *size;
173 memset(ret, 0, elsize);
178 static int str_to_time(const char *str, int64_t *rtime)
180 const char *cur = str;
185 if (*cur < '0' || *cur > '9')
187 hours = strtol(cur, &end, 10);
188 if (end == cur || *end != ':' || end[1] < '0' || end[1] > '9')
191 minutes = strtol(cur, &end, 10);
196 seconds = strtod(cur + 1, &end);
200 *rtime = (hours * 3600 + minutes * 60 + seconds) * AV_TIME_BASE;
204 static inline int is_space(char c)
206 return c == ' ' || c == '\t' || c == '\r';
209 static inline int scale_double(void *log, double d, double m, int *r)
212 if (m < INT_MIN || m >= INT_MAX) {
214 av_log(log, AV_LOG_ERROR, "%g is too large\n", d);
215 return AVERROR(EDOM);
221 static int lex_space(struct sbg_parser *p)
225 while (p->cursor < p->end && is_space(*p->cursor))
227 return p->cursor > c;
230 static int lex_char(struct sbg_parser *p, char c)
232 int r = p->cursor < p->end && *p->cursor == c;
238 static int lex_double(struct sbg_parser *p, double *r)
243 if (p->cursor == p->end || is_space(*p->cursor) || *p->cursor == '\n')
245 d = strtod(p->cursor, &end);
246 if (end > p->cursor) {
254 static int lex_fixed(struct sbg_parser *p, const char *t, int l)
256 if (p->end - p->cursor < l || memcmp(p->cursor, t, l))
262 static int lex_line_end(struct sbg_parser *p)
264 if (p->cursor < p->end && *p->cursor == '#') {
266 while (p->cursor < p->end && *p->cursor != '\n')
269 if (p->cursor == p->end)
270 /* simulate final LF for files lacking it */
272 if (*p->cursor != '\n')
280 static int lex_wsword(struct sbg_parser *p, struct sbg_string *rs)
282 char *s = p->cursor, *c = s;
284 if (s == p->end || *s == '\n')
286 while (c < p->end && *c != '\n' && !is_space(*c))
289 rs->e = p->cursor = c;
294 static int lex_name(struct sbg_parser *p, struct sbg_string *rs)
296 char *s = p->cursor, *c = s;
298 while (c < p->end && ((*c >= 'a' && *c <= 'z') || (*c >= 'A' && *c <= 'Z')
299 || (*c >= '0' && *c <= '9') || *c == '_' || *c == '-'))
304 rs->e = p->cursor = c;
308 static int lex_time(struct sbg_parser *p, int64_t *rt)
310 int r = str_to_time(p->cursor, rt);
315 #define FORWARD_ERROR(c) \
319 return errcode ? errcode : AVERROR_INVALIDDATA; \
322 static int parse_immediate(struct sbg_parser *p)
324 snprintf(p->err_msg, sizeof(p->err_msg),
325 "immediate sequences not yet implemented");
326 return AVERROR_PATCHWELCOME;
329 static int parse_preprogrammed(struct sbg_parser *p)
331 snprintf(p->err_msg, sizeof(p->err_msg),
332 "preprogrammed sequences not yet implemented");
333 return AVERROR_PATCHWELCOME;
336 static int parse_optarg(struct sbg_parser *p, char o, struct sbg_string *r)
338 if (!lex_wsword(p, r)) {
339 snprintf(p->err_msg, sizeof(p->err_msg),
340 "option '%c' requires an argument", o);
341 return AVERROR_INVALIDDATA;
346 static int parse_options(struct sbg_parser *p)
348 struct sbg_string ostr, oarg;
354 if (p->cursor == p->end || *p->cursor != '-')
356 while (lex_char(p, '-') && lex_wsword(p, &ostr)) {
357 for (; ostr.s < ostr.e; ostr.s++) {
361 p->scs.opt_start_at_first = 1;
364 p->scs.opt_end_at_last = 1;
373 FORWARD_ERROR(parse_optarg(p, opt, &oarg));
374 v = strtod(oarg.s, &tptr);
375 if (oarg.e != tptr) {
376 snprintf(p->err_msg, sizeof(p->err_msg),
377 "syntax error for option -F");
378 return AVERROR_INVALIDDATA;
380 p->scs.opt_fade_time = v * AV_TIME_BASE / 1000;
383 FORWARD_ERROR(parse_optarg(p, opt, &oarg));
384 r = str_to_time(oarg.s, &p->scs.opt_duration);
385 if (oarg.e != oarg.s + r) {
386 snprintf(p->err_msg, sizeof(p->err_msg),
387 "syntax error for option -L");
388 return AVERROR_INVALIDDATA;
392 FORWARD_ERROR(parse_optarg(p, opt, &oarg));
393 r = str_to_time(oarg.s, &p->scs.start_ts);
394 if (oarg.e != oarg.s + r) {
395 snprintf(p->err_msg, sizeof(p->err_msg),
396 "syntax error for option -T");
397 return AVERROR_INVALIDDATA;
401 FORWARD_ERROR(parse_optarg(p, opt, &oarg));
402 tptr = av_malloc(oarg.e - oarg.s + 1);
404 return AVERROR(ENOMEM);
405 memcpy(tptr, oarg.s, oarg.e - oarg.s);
406 tptr[oarg.e - oarg.s] = 0;
407 av_free(p->scs.opt_mix);
408 p->scs.opt_mix = tptr;
411 FORWARD_ERROR(parse_optarg(p, opt, &oarg));
412 v = strtod(oarg.s, &tptr);
413 if (oarg.e != tptr) {
414 snprintf(p->err_msg, sizeof(p->err_msg),
415 "syntax error for option -q");
416 return AVERROR_INVALIDDATA;
419 snprintf(p->err_msg, sizeof(p->err_msg),
420 "speed factor other than 1 not supported");
421 return AVERROR_PATCHWELCOME;
425 FORWARD_ERROR(parse_optarg(p, opt, &oarg));
426 r = strtol(oarg.s, &tptr, 10);
427 if (oarg.e != tptr) {
428 snprintf(p->err_msg, sizeof(p->err_msg),
429 "syntax error for option -r");
430 return AVERROR_INVALIDDATA;
433 snprintf(p->err_msg, sizeof(p->err_msg),
434 "invalid sample rate");
435 return AVERROR_PATCHWELCOME;
437 p->scs.sample_rate = r;
440 snprintf(p->err_msg, sizeof(p->err_msg),
441 "unknown option: '%c'", *ostr.s);
442 return AVERROR_INVALIDDATA;
448 return parse_immediate(p);
450 return parse_preprogrammed(p);
452 if (!lex_line_end(p))
453 return AVERROR_INVALIDDATA;
459 static int parse_timestamp(struct sbg_parser *p,
460 struct sbg_timestamp *rts, int64_t *rrel)
462 int64_t abs = 0, rel = 0, dt;
466 if (lex_fixed(p, "NOW", 3)) {
470 r = lex_time(p, &abs);
474 while (lex_char(p, '+')) {
475 if (!lex_time(p, &dt))
476 return AVERROR_INVALIDDATA;
482 return AVERROR_INVALIDDATA;
490 static int parse_fade(struct sbg_parser *p, struct sbg_fade *fr)
492 struct sbg_fade f = {0};
494 if (lex_char(p, '<'))
495 f.in = SBG_FADE_SILENCE;
496 else if (lex_char(p, '-'))
497 f.in = SBG_FADE_SAME;
498 else if (lex_char(p, '='))
499 f.in = SBG_FADE_ADAPT;
502 if (lex_char(p, '>'))
503 f.out = SBG_FADE_SILENCE;
504 else if (lex_char(p, '-'))
505 f.out = SBG_FADE_SAME;
506 else if (lex_char(p, '='))
507 f.out = SBG_FADE_ADAPT;
509 return AVERROR_INVALIDDATA;
514 static int parse_time_sequence(struct sbg_parser *p, int inblock)
516 struct sbg_timestamp ts;
519 struct sbg_fade fade = { SBG_FADE_SAME, SBG_FADE_SAME, 0 };
520 struct sbg_string name;
521 struct sbg_script_tseq *tseq;
523 r = parse_timestamp(p, &ts, &rel_ts);
530 return AVERROR_INVALIDDATA;
531 p->current_time.type = ts.type;
532 p->current_time.t = ts.t;
533 } else if(!inblock && !p->current_time.type) {
534 snprintf(p->err_msg, sizeof(p->err_msg),
535 "relative time without previous absolute time");
536 return AVERROR_INVALIDDATA;
538 ts.type = p->current_time.type;
539 ts.t = p->current_time.t + rel_ts;
540 r = parse_fade(p, &fade);
544 if (!lex_name(p, &name))
545 return AVERROR_INVALIDDATA;
547 if (lex_fixed(p, "->", 2)) {
548 fade.slide = SBG_FADE_ADAPT;
551 if (!lex_line_end(p))
552 return AVERROR_INVALIDDATA;
554 alloc_array_elem((void **)&p->scs.block_tseq, sizeof(*tseq),
555 &p->nb_block_tseq, &p->nb_block_tseq_max) :
556 alloc_array_elem((void **)&p->scs.tseq, sizeof(*tseq),
557 &p->scs.nb_tseq, &p->nb_tseq_max);
559 return AVERROR(ENOMEM);
562 tseq->name_len = name.e - name.s;
567 static int parse_wave_def(struct sbg_parser *p, int wavenum)
569 snprintf(p->err_msg, sizeof(p->err_msg),
570 "waveform definitions not yet implemented");
571 return AVERROR_PATCHWELCOME;
574 static int parse_block_def(struct sbg_parser *p,
575 struct sbg_script_definition *def)
580 if (!lex_line_end(p))
581 return AVERROR_INVALIDDATA;
582 tseq = p->nb_block_tseq;
584 r = parse_time_sequence(p, 1);
590 if (!lex_char(p, '}'))
591 return AVERROR_INVALIDDATA;
593 if (!lex_line_end(p))
594 return AVERROR_INVALIDDATA;
596 def->elements = tseq;
597 def->nb_elements = p->nb_block_tseq - tseq;
598 if (!def->nb_elements)
599 return AVERROR_INVALIDDATA;
603 static int parse_volume(struct sbg_parser *p, int *vol)
607 if (!lex_char(p, '/'))
609 if (!lex_double(p, &v))
610 return AVERROR_INVALIDDATA;
611 if (scale_double(p->log, v, 0.01, vol))
612 return AVERROR(ERANGE);
616 static int parse_synth_channel_sine(struct sbg_parser *p,
617 struct sbg_script_synth *synth)
619 double carrierf, beatf;
620 int carrier, beat, vol;
622 if (!lex_double(p, &carrierf))
624 if (!lex_double(p, &beatf))
626 FORWARD_ERROR(parse_volume(p, &vol));
627 if (scale_double(p->log, carrierf, 1, &carrier) < 0 ||
628 scale_double(p->log, beatf, 1, &beat) < 0)
629 return AVERROR(EDOM);
630 synth->type = SBG_TYPE_SINE;
631 synth->carrier = carrier;
637 static int parse_synth_channel_pink(struct sbg_parser *p,
638 struct sbg_script_synth *synth)
642 if (!lex_fixed(p, "pink", 4))
644 FORWARD_ERROR(parse_volume(p, &vol));
645 synth->type = SBG_TYPE_NOISE;
650 static int parse_synth_channel_bell(struct sbg_parser *p,
651 struct sbg_script_synth *synth)
656 if (!lex_fixed(p, "bell", 4))
658 if (!lex_double(p, &carrierf))
659 return AVERROR_INVALIDDATA;
660 FORWARD_ERROR(parse_volume(p, &vol));
661 if (scale_double(p->log, carrierf, 1, &carrier) < 0)
662 return AVERROR(EDOM);
663 synth->type = SBG_TYPE_BELL;
664 synth->carrier = carrier;
669 static int parse_synth_channel_mix(struct sbg_parser *p,
670 struct sbg_script_synth *synth)
674 if (!lex_fixed(p, "mix", 3))
676 FORWARD_ERROR(parse_volume(p, &vol));
677 synth->type = SBG_TYPE_MIX;
682 static int parse_synth_channel_spin(struct sbg_parser *p,
683 struct sbg_script_synth *synth)
685 double carrierf, beatf;
686 int carrier, beat, vol;
688 if (!lex_fixed(p, "spin:", 5))
690 if (!lex_double(p, &carrierf))
691 return AVERROR_INVALIDDATA;
692 if (!lex_double(p, &beatf))
693 return AVERROR_INVALIDDATA;
694 FORWARD_ERROR(parse_volume(p, &vol));
695 if (scale_double(p->log, carrierf, 1, &carrier) < 0 ||
696 scale_double(p->log, beatf, 1, &beat) < 0)
697 return AVERROR(EDOM);
698 synth->type = SBG_TYPE_SPIN;
699 synth->carrier = carrier;
705 static int parse_synth_channel(struct sbg_parser *p)
708 struct sbg_script_synth *synth;
710 synth = alloc_array_elem((void **)&p->scs.synth, sizeof(*synth),
711 &p->scs.nb_synth, &p->nb_synth_max);
713 return AVERROR(ENOMEM);
714 r = lex_char(p, '-');
716 r = parse_synth_channel_pink(p, synth);
718 r = parse_synth_channel_bell(p, synth);
720 r = parse_synth_channel_mix(p, synth);
722 r = parse_synth_channel_spin(p, synth);
723 /* Unimplemented: wave%d:%f%f/vol (carrier, beat) */
725 r = parse_synth_channel_sine(p, synth);
731 static int parse_synth_def(struct sbg_parser *p,
732 struct sbg_script_definition *def)
736 synth = p->scs.nb_synth;
738 r = parse_synth_channel(p);
741 if (!r || !lex_space(p))
745 if (synth == p->scs.nb_synth)
746 return AVERROR_INVALIDDATA;
747 if (!lex_line_end(p))
748 return AVERROR_INVALIDDATA;
750 def->elements = synth;
751 def->nb_elements = p->scs.nb_synth - synth;
755 static int parse_named_def(struct sbg_parser *p)
757 char *cursor_save = p->cursor;
758 struct sbg_string name;
759 struct sbg_script_definition *def;
761 if (!lex_name(p, &name) || !lex_char(p, ':') || !lex_space(p)) {
762 p->cursor = cursor_save;
765 if (name.e - name.s == 6 && !memcmp(name.s, "wave", 4) &&
766 name.s[4] >= '0' && name.s[4] <= '9' &&
767 name.s[5] >= '0' && name.s[5] <= '9') {
768 int wavenum = (name.s[4] - '0') * 10 + (name.s[5] - '0');
769 return parse_wave_def(p, wavenum);
771 def = alloc_array_elem((void **)&p->scs.def, sizeof(*def),
772 &p->scs.nb_def, &p->nb_def_max);
774 return AVERROR(ENOMEM);
776 def->name_len = name.e - name.s;
777 if (lex_char(p, '{'))
778 return parse_block_def(p, def);
779 return parse_synth_def(p, def);
782 static void free_script(struct sbg_script *s)
787 av_freep(&s->block_tseq);
788 av_freep(&s->events);
789 av_freep(&s->opt_mix);
792 static int parse_script(void *log, char *script, int script_len,
793 struct sbg_script *rscript)
795 struct sbg_parser sp = {
798 .end = script + script_len,
804 .start_ts = AV_NOPTS_VALUE,
805 .sample_rate = 44100,
806 .opt_fade_time = 60 * AV_TIME_BASE,
812 while (sp.cursor < sp.end) {
813 r = parse_options(&sp);
816 if (!r && !lex_line_end(&sp))
819 while (sp.cursor < sp.end) {
820 r = parse_named_def(&sp);
822 r = parse_time_sequence(&sp, 0);
824 r = lex_line_end(&sp) ? 1 : AVERROR_INVALIDDATA;
831 free_script(&sp.scs);
833 if (r == AVERROR_INVALIDDATA)
834 snprintf(sp.err_msg, sizeof(sp.err_msg), "syntax error");
835 if (log && *sp.err_msg) {
836 const char *ctx = sp.cursor;
837 const char *ectx = av_x_if_null(memchr(ctx, '\n', sp.end - sp.cursor),
839 int lctx = ectx - ctx;
840 const char *quote = "\"";
841 if (lctx > 0 && ctx[lctx - 1] == '\r')
844 ctx = "the end of line";
848 av_log(log, AV_LOG_ERROR, "Error line %d: %s near %s%.*s%s.\n",
849 sp.line_no, sp.err_msg, quote, lctx, ctx, quote);
854 static int read_whole_file(AVIOContext *io, int max_size, char **rbuf)
857 int size = 0, bufsize = 0, r;
860 if (bufsize - size < 1024) {
861 bufsize = FFMIN(FFMAX(2 * bufsize, 8192), max_size);
862 if (bufsize - size < 2) {
863 size = AVERROR(EFBIG);
866 buf = av_realloc_f(buf, bufsize, 1);
868 size = AVERROR(ENOMEM);
872 r = avio_read(io, buf, bufsize - size - 1);
873 if (r == AVERROR_EOF)
887 static void expand_timestamps(void *log, struct sbg_script *s)
890 int64_t now, cur_ts, delta = 0;
892 for (i = 0; i < s->nb_tseq; i++)
893 nb_rel += s->tseq[i].ts.type == 'N';
894 if (nb_rel == s->nb_tseq) {
895 /* All ts are relative to NOW: consider NOW = 0 */
897 if (s->start_ts != AV_NOPTS_VALUE)
898 av_log(log, AV_LOG_WARNING,
899 "Start time ignored in a purely relative script.\n");
900 } else if (nb_rel == 0 && s->start_ts != AV_NOPTS_VALUE ||
901 s->opt_start_at_first) {
902 /* All ts are absolute and start time is specified */
903 if (s->start_ts == AV_NOPTS_VALUE)
904 s->start_ts = s->tseq[0].ts.t;
907 /* Mixed relative/absolute ts: expand */
909 struct tm *tm, tmpbuf;
911 av_log(log, AV_LOG_WARNING,
912 "Scripts with mixed absolute and relative timestamps can give "
913 "unexpected results (pause, seeking, time zone change).\n");
916 tm = localtime_r(&now0, &tmpbuf);
917 now = tm ? tm->tm_hour * 3600 + tm->tm_min * 60 + tm->tm_sec :
919 av_log(log, AV_LOG_INFO, "Using %02d:%02d:%02d as NOW.\n",
920 (int)(now / 3600), (int)(now / 60) % 60, (int)now % 60);
922 for (i = 0; i < s->nb_tseq; i++) {
923 if (s->tseq[i].ts.type == 'N') {
924 s->tseq[i].ts.t += now;
925 s->tseq[i].ts.type = 'T'; /* not necessary */
929 if (s->start_ts == AV_NOPTS_VALUE)
930 s->start_ts = s->opt_start_at_first ? s->tseq[0].ts.t : now;
931 s->end_ts = s->opt_duration ? s->start_ts + s->opt_duration :
932 AV_NOPTS_VALUE; /* may be overridden later by -E option */
934 for (i = 0; i < s->nb_tseq; i++) {
935 if (s->tseq[i].ts.t + delta < cur_ts)
937 cur_ts = s->tseq[i].ts.t += delta;
941 static int expand_tseq(void *log, struct sbg_script *s, int *nb_ev_max,
942 int64_t t0, struct sbg_script_tseq *tseq)
945 struct sbg_script_definition *def;
946 struct sbg_script_tseq *be;
947 struct sbg_script_event *ev;
950 av_log(log, AV_LOG_ERROR, "Recursion loop on \"%.*s\"\n",
951 tseq->name_len, tseq->name);
952 return AVERROR(EINVAL);
955 for (i = 0; i < s->nb_def; i++) {
956 if (s->def[i].name_len == tseq->name_len &&
957 !memcmp(s->def[i].name, tseq->name, tseq->name_len))
960 if (i >= s->nb_def) {
961 av_log(log, AV_LOG_ERROR, "Tone-set \"%.*s\" not defined\n",
962 tseq->name_len, tseq->name);
963 return AVERROR(EINVAL);
966 if (def->type == 'B') {
967 be = s->block_tseq + def->elements;
968 for (i = 0; i < def->nb_elements; i++) {
969 r = expand_tseq(log, s, nb_ev_max, t0, &be[i]);
974 ev = alloc_array_elem((void **)&s->events, sizeof(*ev),
975 &s->nb_events, nb_ev_max);
977 return AVERROR(ENOMEM);
979 ev->elements = def->elements;
980 ev->nb_elements = def->nb_elements;
981 ev->fade = tseq->fade;
987 static int expand_script(void *log, struct sbg_script *s)
989 int i, r, nb_events_max = 0;
991 expand_timestamps(log, s);
992 for (i = 0; i < s->nb_tseq; i++) {
993 r = expand_tseq(log, s, &nb_events_max, 0, &s->tseq[i]);
998 av_log(log, AV_LOG_ERROR, "No events in script\n");
999 return AVERROR_INVALIDDATA;
1001 if (s->opt_end_at_last)
1002 s->end_ts = s->events[s->nb_events - 1].ts;
1006 static int add_interval(struct ws_intervals *inter,
1007 enum ws_interval_type type, uint32_t channels, int ref,
1008 int64_t ts1, int32_t f1, int32_t a1,
1009 int64_t ts2, int32_t f2, int32_t a2)
1011 struct ws_interval *i, *ri;
1014 ri = &inter->inter[ref];
1015 /* ref and new intervals are constant, identical and adjacent */
1016 if (ri->type == type && ri->channels == channels &&
1017 ri->f1 == ri->f2 && ri->f2 == f1 && f1 == f2 &&
1018 ri->a1 == ri->a2 && ri->a2 == a1 && a1 == a2 &&
1024 i = alloc_array_elem((void **)&inter->inter, sizeof(*i),
1025 &inter->nb_inter, &inter->max_inter);
1027 return AVERROR(ENOMEM);
1031 i->channels = channels;
1036 i->phi = ref >= 0 ? ref | 0x80000000 : 0;
1037 return i - inter->inter;
1040 static int add_bell(struct ws_intervals *inter, struct sbg_script *s,
1041 int64_t ts1, int64_t ts2, int32_t f, int32_t a)
1043 /* SBaGen uses an exponential decrease every 50ms.
1044 We approximate it with piecewise affine segments. */
1045 int32_t cpoints[][2] = {
1055 int64_t dt = s->sample_rate / 20, ts3 = ts1, ts4;
1056 for (i = 0; i < FF_ARRAY_ELEMS(cpoints); i++) {
1057 ts4 = FFMIN(ts2, ts1 + cpoints[i][0] * dt);
1058 r = add_interval(inter, WS_SINE, 3, -1,
1059 ts3, f, a, ts4, f, cpoints[i][1]);
1068 static int generate_interval(void *log, struct sbg_script *s,
1069 struct ws_intervals *inter,
1070 int64_t ts1, int64_t ts2,
1071 struct sbg_script_synth *s1,
1072 struct sbg_script_synth *s2,
1077 if (ts2 <= ts1 || (s1->vol == 0 && s2->vol == 0))
1083 if (s1->beat == 0 && s2->beat == 0) {
1084 r = add_interval(inter, WS_SINE, 3, s1->ref.l,
1085 ts1, s1->carrier, s1->vol,
1086 ts2, s2->carrier, s2->vol);
1089 s2->ref.l = s2->ref.r = r;
1091 r = add_interval(inter, WS_SINE, 1, s1->ref.l,
1092 ts1, s1->carrier + s1->beat / 2, s1->vol,
1093 ts2, s2->carrier + s2->beat / 2, s2->vol);
1097 r = add_interval(inter, WS_SINE, 2, s1->ref.r,
1098 ts1, s1->carrier - s1->beat / 2, s1->vol,
1099 ts2, s2->carrier - s2->beat / 2, s2->vol);
1107 if (transition == 2) {
1108 r = add_bell(inter, s, ts1, ts2, s1->carrier, s2->vol);
1115 av_log(log, AV_LOG_WARNING, "Spinning noise not implemented, "
1116 "using pink noise instead.\n");
1118 case SBG_TYPE_NOISE:
1119 /* SBaGen's pink noise generator uses:
1120 - 1 band of white noise, mean square: 1/3;
1121 - 9 bands of subsampled white noise with linear
1122 interpolation, mean square: 2/3 each;
1123 with 1/10 weight each: the total mean square is 7/300.
1124 Our pink noise generator uses 8 bands of white noise with
1125 rectangular subsampling: the total mean square is 1/24.
1126 Therefore, to match SBaGen's volume, we must multiply vol by
1127 sqrt((7/300) / (1/24)) = sqrt(14/25) =~ 0.748
1129 r = add_interval(inter, WS_NOISE, 3, s1->ref.l,
1130 ts1, 0, s1->vol - s1->vol / 4,
1131 ts2, 0, s2->vol - s2->vol / 4);
1134 s2->ref.l = s2->ref.r = r;
1138 /* Unimplemented: silence; warning present elsewhere */
1140 av_log(log, AV_LOG_ERROR,
1141 "Type %d is not implemented\n", s1->type);
1142 return AVERROR_PATCHWELCOME;
1147 static int generate_plateau(void *log, struct sbg_script *s,
1148 struct ws_intervals *inter,
1149 struct sbg_script_event *ev1)
1151 int64_t ts1 = ev1->ts_int, ts2 = ev1->ts_trans;
1153 struct sbg_script_synth *s1;
1155 for (i = 0; i < ev1->nb_elements; i++) {
1156 s1 = &s->synth[ev1->elements + i];
1157 r = generate_interval(log, s, inter, ts1, ts2, s1, s1, 0);
1166 ts1 ts2 ts1 tsmid ts2
1171 ''''....____ ''....''
1173 compatible transition incompatible transition
1176 static int generate_transition(void *log, struct sbg_script *s,
1177 struct ws_intervals *inter,
1178 struct sbg_script_event *ev1,
1179 struct sbg_script_event *ev2)
1181 int64_t ts1 = ev1->ts_trans, ts2 = ev1->ts_next;
1182 /* (ts1 + ts2) / 2 without overflow */
1183 int64_t tsmid = (ts1 >> 1) + (ts2 >> 1) + (ts1 & ts2 & 1);
1184 enum sbg_fade_type type = ev1->fade.slide | (ev1->fade.out & ev2->fade.in);
1185 int nb_elements = FFMAX(ev1->nb_elements, ev2->nb_elements);
1186 struct sbg_script_synth *s1, *s2, s1mod, s2mod, smid;
1189 for (pass = 0; pass < 2; pass++) {
1190 /* pass = 0 -> compatible and first half of incompatible
1191 pass = 1 -> second half of incompatible
1192 Using two passes like that ensures that the intervals are generated
1193 in increasing order according to their start timestamp.
1194 Otherwise it would be necessary to sort them
1195 while keeping the mutual references.
1197 for (i = 0; i < nb_elements; i++) {
1198 s1 = i < ev1->nb_elements ? &s->synth[ev1->elements + i] : &s1mod;
1199 s2 = i < ev2->nb_elements ? &s->synth[ev2->elements + i] : &s2mod;
1200 s1mod = s1 != &s1mod ? *s1 : (struct sbg_script_synth){ 0 };
1201 s2mod = s2 != &s2mod ? *s2 : (struct sbg_script_synth){ 0 };
1202 if (ev1->fade.slide) {
1203 /* for slides, and only for slides, silence ("-") is equivalent
1204 to anything with volume 0 */
1205 if (s1mod.type == SBG_TYPE_NONE) {
1208 } else if (s2mod.type == SBG_TYPE_NONE) {
1213 if (s1mod.type == s2mod.type &&
1214 s1mod.type != SBG_TYPE_BELL &&
1215 (type == SBG_FADE_ADAPT ||
1216 (s1mod.carrier == s2mod.carrier &&
1217 s1mod.beat == s2mod.beat))) {
1218 /* compatible: single transition */
1220 r = generate_interval(log, s, inter,
1221 ts1, ts2, &s1mod, &s2mod, 3);
1224 s2->ref = s2mod.ref;
1227 /* incompatible: silence at midpoint */
1231 r = generate_interval(log, s, inter,
1232 ts1, tsmid, &s1mod, &smid, 1);
1238 r = generate_interval(log, s, inter,
1239 tsmid, ts2, &smid, &s2mod, 2);
1242 s2->ref = s2mod.ref;
1251 ev1 trats ev2 intts endts ev3
1256 '''....________________....''' '''...._______________
1258 \_________/\______________/\_________/\______________/\_________/\_____________/
1259 tr x->1 int1 tr 1->2 int2 tr 2->3 int3
1262 static int generate_intervals(void *log, struct sbg_script *s, int sample_rate,
1263 struct ws_intervals *inter)
1265 int64_t trans_time = s->opt_fade_time / 2;
1266 struct sbg_script_event ev0, *ev1, *ev2;
1270 /* SBaGen handles the time before and after the extremal events,
1271 and the corresponding transitions, as if the sequence were cyclic
1272 with a 24-hours period. */
1273 period = s->events[s->nb_events - 1].ts - s->events[0].ts;
1274 period = (period + (DAY_TS - 1)) / DAY_TS * DAY_TS;
1275 period = FFMAX(period, DAY_TS);
1277 /* Prepare timestamps for transitions */
1278 for (i = 0; i < s->nb_events; i++) {
1279 ev1 = &s->events[i];
1280 ev2 = &s->events[(i + 1) % s->nb_events];
1281 ev1->ts_int = ev1->ts;
1282 ev1->ts_trans = ev1->fade.slide ? ev1->ts
1283 : ev2->ts + (ev1 < ev2 ? 0 : period);
1285 for (i = 0; i < s->nb_events; i++) {
1286 ev1 = &s->events[i];
1287 ev2 = &s->events[(i + 1) % s->nb_events];
1288 if (!ev1->fade.slide) {
1289 ev1->ts_trans = FFMAX(ev1->ts_int, ev1->ts_trans - trans_time);
1290 ev2->ts_int = FFMIN(ev2->ts_trans, ev2->ts_int + trans_time);
1292 ev1->ts_next = ev2->ts_int + (ev1 < ev2 ? 0 : period);
1295 /* Pseudo event before the first one */
1296 ev0 = s->events[s->nb_events - 1];
1297 ev0.ts_int -= period;
1298 ev0.ts_trans -= period;
1299 ev0.ts_next -= period;
1301 /* Convert timestamps */
1302 for (i = -1; i < s->nb_events; i++) {
1303 ev1 = i < 0 ? &ev0 : &s->events[i];
1304 ev1->ts_int = av_rescale(ev1->ts_int, sample_rate, AV_TIME_BASE);
1305 ev1->ts_trans = av_rescale(ev1->ts_trans, sample_rate, AV_TIME_BASE);
1306 ev1->ts_next = av_rescale(ev1->ts_next, sample_rate, AV_TIME_BASE);
1309 /* Generate intervals */
1310 for (i = 0; i < s->nb_synth; i++)
1311 s->synth[i].ref.l = s->synth[i].ref.r = -1;
1312 for (i = -1; i < s->nb_events; i++) {
1313 ev1 = i < 0 ? &ev0 : &s->events[i];
1314 ev2 = &s->events[(i + 1) % s->nb_events];
1315 r = generate_plateau(log, s, inter, ev1);
1318 r = generate_transition(log, s, inter, ev1, ev2);
1322 if (!inter->nb_inter)
1323 av_log(log, AV_LOG_WARNING, "Completely silent script.\n");
1327 static int encode_intervals(struct sbg_script *s, AVCodecContext *avc,
1328 struct ws_intervals *inter)
1330 int i, edata_size = 4;
1333 for (i = 0; i < inter->nb_inter; i++) {
1334 edata_size += inter->inter[i].type == WS_SINE ? 44 :
1335 inter->inter[i].type == WS_NOISE ? 32 : 0;
1337 return AVERROR(ENOMEM);
1339 if (ff_alloc_extradata(avc, edata_size))
1340 return AVERROR(ENOMEM);
1341 edata = avc->extradata;
1343 #define ADD_EDATA32(v) do { AV_WL32(edata, (v)); edata += 4; } while(0)
1344 #define ADD_EDATA64(v) do { AV_WL64(edata, (v)); edata += 8; } while(0)
1345 ADD_EDATA32(inter->nb_inter);
1346 for (i = 0; i < inter->nb_inter; i++) {
1347 ADD_EDATA64(inter->inter[i].ts1);
1348 ADD_EDATA64(inter->inter[i].ts2);
1349 ADD_EDATA32(inter->inter[i].type);
1350 ADD_EDATA32(inter->inter[i].channels);
1351 switch (inter->inter[i].type) {
1353 ADD_EDATA32(inter->inter[i].f1);
1354 ADD_EDATA32(inter->inter[i].f2);
1355 ADD_EDATA32(inter->inter[i].a1);
1356 ADD_EDATA32(inter->inter[i].a2);
1357 ADD_EDATA32(inter->inter[i].phi);
1360 ADD_EDATA32(inter->inter[i].a1);
1361 ADD_EDATA32(inter->inter[i].a2);
1365 if (edata != avc->extradata + edata_size)
1370 static av_cold int sbg_read_probe(AVProbeData *p)
1373 struct sbg_script script = { 0 };
1375 r = parse_script(NULL, p->buf, p->buf_size, &script);
1376 score = r < 0 || !script.nb_def || !script.nb_tseq ? 0 :
1377 AVPROBE_SCORE_MAX / 3;
1378 free_script(&script);
1382 static av_cold int sbg_read_header(AVFormatContext *avf)
1384 struct sbg_demuxer *sbg = avf->priv_data;
1387 struct sbg_script script = { 0 };
1389 struct ws_intervals inter = { 0 };
1391 r = read_whole_file(avf->pb, sbg->max_file_size, &buf);
1394 r = parse_script(avf, buf, r, &script);
1397 if (!sbg->sample_rate)
1398 sbg->sample_rate = script.sample_rate;
1400 script.sample_rate = sbg->sample_rate;
1401 if (!sbg->frame_size)
1402 sbg->frame_size = FFMAX(1, sbg->sample_rate / 10);
1404 av_log(avf, AV_LOG_WARNING, "Mix feature not implemented: "
1405 "-m is ignored and mix channels will be silent.\n");
1406 r = expand_script(avf, &script);
1410 r = generate_intervals(avf, &script, sbg->sample_rate, &inter);
1414 st = avformat_new_stream(avf, NULL);
1416 return AVERROR(ENOMEM);
1417 st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
1418 st->codec->codec_id = AV_CODEC_ID_FFWAVESYNTH;
1419 st->codec->channels = 2;
1420 st->codec->channel_layout = AV_CH_LAYOUT_STEREO;
1421 st->codec->sample_rate = sbg->sample_rate;
1422 st->codec->frame_size = sbg->frame_size;
1423 avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
1424 st->probe_packets = 0;
1425 st->start_time = av_rescale(script.start_ts,
1426 sbg->sample_rate, AV_TIME_BASE);
1427 st->duration = script.end_ts == AV_NOPTS_VALUE ? AV_NOPTS_VALUE :
1428 av_rescale(script.end_ts - script.start_ts,
1429 sbg->sample_rate, AV_TIME_BASE);
1430 st->cur_dts = st->start_time;
1431 r = encode_intervals(&script, st->codec, &inter);
1435 av_free(inter.inter);
1436 free_script(&script);
1440 av_free(inter.inter);
1441 free_script(&script);
1446 static int sbg_read_packet(AVFormatContext *avf, AVPacket *packet)
1450 ts = avf->streams[0]->cur_dts;
1451 end_ts = ts + avf->streams[0]->codec->frame_size;
1452 if (avf->streams[0]->duration != AV_NOPTS_VALUE)
1453 end_ts = FFMIN(avf->streams[0]->start_time + avf->streams[0]->duration,
1457 if (av_new_packet(packet, 12) < 0)
1458 return AVERROR(ENOMEM);
1459 packet->dts = packet->pts = ts;
1460 packet->duration = end_ts - ts;
1461 AV_WL64(packet->data + 0, ts);
1462 AV_WL32(packet->data + 8, packet->duration);
1463 return packet->size;
1466 static int sbg_read_seek2(AVFormatContext *avf, int stream_index,
1467 int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
1469 if (flags || stream_index > 0)
1470 return AVERROR(EINVAL);
1471 if (stream_index < 0)
1472 ts = av_rescale_q(ts, AV_TIME_BASE_Q, avf->streams[0]->time_base);
1473 avf->streams[0]->cur_dts = ts;
1477 static int sbg_read_seek(AVFormatContext *avf, int stream_index,
1478 int64_t ts, int flags)
1480 return sbg_read_seek2(avf, stream_index, ts, ts, ts, 0);
1483 static const AVOption sbg_options[] = {
1484 { "sample_rate", "", offsetof(struct sbg_demuxer, sample_rate),
1485 AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX,
1486 AV_OPT_FLAG_DECODING_PARAM },
1487 { "frame_size", "", offsetof(struct sbg_demuxer, frame_size),
1488 AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX,
1489 AV_OPT_FLAG_DECODING_PARAM },
1490 { "max_file_size", "", offsetof(struct sbg_demuxer, max_file_size),
1491 AV_OPT_TYPE_INT, { .i64 = 5000000 }, 0, INT_MAX,
1492 AV_OPT_FLAG_DECODING_PARAM },
1496 static const AVClass sbg_demuxer_class = {
1497 .class_name = "sbg_demuxer",
1498 .item_name = av_default_item_name,
1499 .option = sbg_options,
1500 .version = LIBAVUTIL_VERSION_INT,
1503 AVInputFormat ff_sbg_demuxer = {
1505 .long_name = NULL_IF_CONFIG_SMALL("SBaGen binaural beats script"),
1506 .priv_data_size = sizeof(struct sbg_demuxer),
1507 .read_probe = sbg_read_probe,
1508 .read_header = sbg_read_header,
1509 .read_packet = sbg_read_packet,
1510 .read_seek = sbg_read_seek,
1511 .read_seek2 = sbg_read_seek2,
1512 .extensions = "sbg",
1513 .priv_class = &sbg_demuxer_class,