blob: cbedd120fbf2756154f0f723eebb362133e80d1a
1 | /* |
2 | * SBG (SBaGen) file format decoder |
3 | * Copyright (c) 2011 Nicolas George |
4 | * |
5 | * This file is part of FFmpeg. |
6 | * |
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. |
11 | * |
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. |
16 | * |
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 |
20 | */ |
21 | |
22 | #include <stdio.h> |
23 | #include <stdlib.h> |
24 | #include <time.h> |
25 | #include "libavutil/intreadwrite.h" |
26 | #include "libavutil/log.h" |
27 | #include "libavutil/opt.h" |
28 | #include "libavutil/time_internal.h" |
29 | #include "avformat.h" |
30 | #include "internal.h" |
31 | |
32 | #define SBG_SCALE (1 << 16) |
33 | #define DAY (24 * 60 * 60) |
34 | #define DAY_TS ((int64_t)DAY * AV_TIME_BASE) |
35 | |
36 | struct sbg_demuxer { |
37 | AVClass *class; |
38 | int sample_rate; |
39 | int frame_size; |
40 | int max_file_size; |
41 | }; |
42 | |
43 | struct sbg_string { |
44 | char *s; |
45 | char *e; |
46 | }; |
47 | |
48 | enum sbg_fade_type { |
49 | SBG_FADE_SILENCE = 0, |
50 | SBG_FADE_SAME = 1, |
51 | SBG_FADE_ADAPT = 3, |
52 | }; |
53 | |
54 | struct sbg_fade { |
55 | int8_t in, out, slide; |
56 | }; |
57 | |
58 | enum sbg_synth_type { |
59 | SBG_TYPE_NONE, |
60 | SBG_TYPE_SINE, |
61 | SBG_TYPE_NOISE, |
62 | SBG_TYPE_BELL, |
63 | SBG_TYPE_MIX, |
64 | SBG_TYPE_SPIN, |
65 | }; |
66 | |
67 | /* bell: freq constant, ampl decreases exponentially, can be approx lin */ |
68 | |
69 | struct sbg_timestamp { |
70 | int64_t t; |
71 | char type; /* 0 for relative, 'N' for now, 'T' for absolute */ |
72 | }; |
73 | |
74 | struct sbg_script_definition { |
75 | char *name; |
76 | int name_len; |
77 | int elements, nb_elements; |
78 | char type; /* 'S' or 'B' */ |
79 | }; |
80 | |
81 | struct sbg_script_synth { |
82 | int carrier; |
83 | int beat; |
84 | int vol; |
85 | enum sbg_synth_type type; |
86 | struct { |
87 | int l, r; |
88 | } ref; |
89 | }; |
90 | |
91 | struct sbg_script_tseq { |
92 | struct sbg_timestamp ts; |
93 | char *name; |
94 | int name_len; |
95 | int lock; |
96 | struct sbg_fade fade; |
97 | }; |
98 | |
99 | struct sbg_script_event { |
100 | int64_t ts; |
101 | int64_t ts_int, ts_trans, ts_next; |
102 | int elements, nb_elements; |
103 | struct sbg_fade fade; |
104 | }; |
105 | |
106 | struct sbg_script { |
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; |
112 | int nb_def; |
113 | int nb_tseq; |
114 | int nb_events; |
115 | int nb_synth; |
116 | int64_t start_ts; |
117 | int64_t end_ts; |
118 | int64_t opt_fade_time; |
119 | int64_t opt_duration; |
120 | char *opt_mix; |
121 | int sample_rate; |
122 | uint8_t opt_start_at_first; |
123 | uint8_t opt_end_at_last; |
124 | }; |
125 | |
126 | struct sbg_parser { |
127 | void *log; |
128 | char *script, *end; |
129 | char *cursor; |
130 | struct sbg_script scs; |
131 | struct sbg_timestamp current_time; |
132 | int nb_block_tseq; |
133 | int nb_def_max, nb_synth_max, nb_tseq_max, nb_block_tseq_max; |
134 | int line_no; |
135 | char err_msg[128]; |
136 | }; |
137 | |
138 | enum ws_interval_type { |
139 | WS_SINE = MKTAG('S','I','N','E'), |
140 | WS_NOISE = MKTAG('N','O','I','S'), |
141 | }; |
142 | |
143 | struct ws_interval { |
144 | int64_t ts1, ts2; |
145 | enum ws_interval_type type; |
146 | uint32_t channels; |
147 | int32_t f1, f2; |
148 | int32_t a1, a2; |
149 | uint32_t phi; |
150 | }; |
151 | |
152 | struct ws_intervals { |
153 | struct ws_interval *inter; |
154 | int nb_inter; |
155 | int max_inter; |
156 | }; |
157 | |
158 | static void *alloc_array_elem(void **array, size_t elsize, |
159 | int *size, int *max_size) |
160 | { |
161 | void *ret; |
162 | |
163 | if (*size == *max_size) { |
164 | int m = FFMAX(32, FFMIN(*max_size, INT_MAX / 2) * 2); |
165 | if (*size >= m) |
166 | return NULL; |
167 | *array = av_realloc_f(*array, m, elsize); |
168 | if (!*array) |
169 | return NULL; |
170 | *max_size = m; |
171 | } |
172 | ret = (char *)*array + elsize * *size; |
173 | memset(ret, 0, elsize); |
174 | (*size)++; |
175 | return ret; |
176 | } |
177 | |
178 | static int str_to_time(const char *str, int64_t *rtime) |
179 | { |
180 | const char *cur = str; |
181 | char *end; |
182 | int hours, minutes; |
183 | double seconds = 0; |
184 | |
185 | if (*cur < '0' || *cur > '9') |
186 | return 0; |
187 | hours = strtol(cur, &end, 10); |
188 | if (end == cur || *end != ':' || end[1] < '0' || end[1] > '9') |
189 | return 0; |
190 | cur = end + 1; |
191 | minutes = strtol(cur, &end, 10); |
192 | if (end == cur) |
193 | return 0; |
194 | cur = end; |
195 | if (*end == ':'){ |
196 | seconds = strtod(cur + 1, &end); |
197 | if (end > cur + 1) |
198 | cur = end; |
199 | } |
200 | *rtime = (hours * 3600 + minutes * 60 + seconds) * AV_TIME_BASE; |
201 | return cur - str; |
202 | } |
203 | |
204 | static inline int is_space(char c) |
205 | { |
206 | return c == ' ' || c == '\t' || c == '\r'; |
207 | } |
208 | |
209 | static inline int scale_double(void *log, double d, double m, int *r) |
210 | { |
211 | m *= d * SBG_SCALE; |
212 | if (m < INT_MIN || m >= INT_MAX) { |
213 | if (log) |
214 | av_log(log, AV_LOG_ERROR, "%g is too large\n", d); |
215 | return AVERROR(EDOM); |
216 | } |
217 | *r = m; |
218 | return 0; |
219 | } |
220 | |
221 | static int lex_space(struct sbg_parser *p) |
222 | { |
223 | char *c = p->cursor; |
224 | |
225 | while (p->cursor < p->end && is_space(*p->cursor)) |
226 | p->cursor++; |
227 | return p->cursor > c; |
228 | } |
229 | |
230 | static int lex_char(struct sbg_parser *p, char c) |
231 | { |
232 | int r = p->cursor < p->end && *p->cursor == c; |
233 | |
234 | p->cursor += r; |
235 | return r; |
236 | } |
237 | |
238 | static int lex_double(struct sbg_parser *p, double *r) |
239 | { |
240 | double d; |
241 | char *end; |
242 | |
243 | if (p->cursor == p->end || is_space(*p->cursor) || *p->cursor == '\n') |
244 | return 0; |
245 | d = strtod(p->cursor, &end); |
246 | if (end > p->cursor) { |
247 | *r = d; |
248 | p->cursor = end; |
249 | return 1; |
250 | } |
251 | return 0; |
252 | } |
253 | |
254 | static int lex_fixed(struct sbg_parser *p, const char *t, int l) |
255 | { |
256 | if (p->end - p->cursor < l || memcmp(p->cursor, t, l)) |
257 | return 0; |
258 | p->cursor += l; |
259 | return 1; |
260 | } |
261 | |
262 | static int lex_line_end(struct sbg_parser *p) |
263 | { |
264 | if (p->cursor < p->end && *p->cursor == '#') { |
265 | p->cursor++; |
266 | while (p->cursor < p->end && *p->cursor != '\n') |
267 | p->cursor++; |
268 | } |
269 | if (p->cursor == p->end) |
270 | /* simulate final LF for files lacking it */ |
271 | return 1; |
272 | if (*p->cursor != '\n') |
273 | return 0; |
274 | p->cursor++; |
275 | p->line_no++; |
276 | lex_space(p); |
277 | return 1; |
278 | } |
279 | |
280 | static int lex_wsword(struct sbg_parser *p, struct sbg_string *rs) |
281 | { |
282 | char *s = p->cursor, *c = s; |
283 | |
284 | if (s == p->end || *s == '\n') |
285 | return 0; |
286 | while (c < p->end && *c != '\n' && !is_space(*c)) |
287 | c++; |
288 | rs->s = s; |
289 | rs->e = p->cursor = c; |
290 | lex_space(p); |
291 | return 1; |
292 | } |
293 | |
294 | static int lex_name(struct sbg_parser *p, struct sbg_string *rs) |
295 | { |
296 | char *s = p->cursor, *c = s; |
297 | |
298 | while (c < p->end && ((*c >= 'a' && *c <= 'z') || (*c >= 'A' && *c <= 'Z') |
299 | || (*c >= '0' && *c <= '9') || *c == '_' || *c == '-')) |
300 | c++; |
301 | if (c == s) |
302 | return 0; |
303 | rs->s = s; |
304 | rs->e = p->cursor = c; |
305 | return 1; |
306 | } |
307 | |
308 | static int lex_time(struct sbg_parser *p, int64_t *rt) |
309 | { |
310 | int r = str_to_time(p->cursor, rt); |
311 | p->cursor += r; |
312 | return r > 0; |
313 | } |
314 | |
315 | #define FORWARD_ERROR(c) \ |
316 | do { \ |
317 | int errcode = c; \ |
318 | if (errcode <= 0) \ |
319 | return errcode ? errcode : AVERROR_INVALIDDATA; \ |
320 | } while (0) |
321 | |
322 | static int parse_immediate(struct sbg_parser *p) |
323 | { |
324 | snprintf(p->err_msg, sizeof(p->err_msg), |
325 | "immediate sequences not yet implemented"); |
326 | return AVERROR_PATCHWELCOME; |
327 | } |
328 | |
329 | static int parse_preprogrammed(struct sbg_parser *p) |
330 | { |
331 | snprintf(p->err_msg, sizeof(p->err_msg), |
332 | "preprogrammed sequences not yet implemented"); |
333 | return AVERROR_PATCHWELCOME; |
334 | } |
335 | |
336 | static int parse_optarg(struct sbg_parser *p, char o, struct sbg_string *r) |
337 | { |
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; |
342 | } |
343 | return 1; |
344 | } |
345 | |
346 | static int parse_options(struct sbg_parser *p) |
347 | { |
348 | struct sbg_string ostr, oarg; |
349 | char mode = 0; |
350 | int r; |
351 | char *tptr; |
352 | double v; |
353 | |
354 | if (p->cursor == p->end || *p->cursor != '-') |
355 | return 0; |
356 | while (lex_char(p, '-') && lex_wsword(p, &ostr)) { |
357 | for (; ostr.s < ostr.e; ostr.s++) { |
358 | char opt = *ostr.s; |
359 | switch (opt) { |
360 | case 'S': |
361 | p->scs.opt_start_at_first = 1; |
362 | break; |
363 | case 'E': |
364 | p->scs.opt_end_at_last = 1; |
365 | break; |
366 | case 'i': |
367 | mode = 'i'; |
368 | break; |
369 | case 'p': |
370 | mode = 'p'; |
371 | break; |
372 | case 'F': |
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; |
379 | } |
380 | p->scs.opt_fade_time = v * AV_TIME_BASE / 1000; |
381 | break; |
382 | case 'L': |
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; |
389 | } |
390 | break; |
391 | case 'T': |
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; |
398 | } |
399 | break; |
400 | case 'm': |
401 | FORWARD_ERROR(parse_optarg(p, opt, &oarg)); |
402 | tptr = av_malloc(oarg.e - oarg.s + 1); |
403 | if (!tptr) |
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; |
409 | break; |
410 | case 'q': |
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; |
417 | } |
418 | if (v != 1) { |
419 | snprintf(p->err_msg, sizeof(p->err_msg), |
420 | "speed factor other than 1 not supported"); |
421 | return AVERROR_PATCHWELCOME; |
422 | } |
423 | break; |
424 | case 'r': |
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; |
431 | } |
432 | if (r < 40) { |
433 | snprintf(p->err_msg, sizeof(p->err_msg), |
434 | "invalid sample rate"); |
435 | return AVERROR_PATCHWELCOME; |
436 | } |
437 | p->scs.sample_rate = r; |
438 | break; |
439 | default: |
440 | snprintf(p->err_msg, sizeof(p->err_msg), |
441 | "unknown option: '%c'", *ostr.s); |
442 | return AVERROR_INVALIDDATA; |
443 | } |
444 | } |
445 | } |
446 | switch (mode) { |
447 | case 'i': |
448 | return parse_immediate(p); |
449 | case 'p': |
450 | return parse_preprogrammed(p); |
451 | case 0: |
452 | if (!lex_line_end(p)) |
453 | return AVERROR_INVALIDDATA; |
454 | return 1; |
455 | } |
456 | return AVERROR_BUG; |
457 | } |
458 | |
459 | static int parse_timestamp(struct sbg_parser *p, |
460 | struct sbg_timestamp *rts, int64_t *rrel) |
461 | { |
462 | int64_t abs = 0, rel = 0, dt; |
463 | char type = 0; |
464 | int r; |
465 | |
466 | if (lex_fixed(p, "NOW", 3)) { |
467 | type = 'N'; |
468 | r = 1; |
469 | } else { |
470 | r = lex_time(p, &abs); |
471 | if (r) |
472 | type = 'T'; |
473 | } |
474 | while (lex_char(p, '+')) { |
475 | if (!lex_time(p, &dt)) |
476 | return AVERROR_INVALIDDATA; |
477 | rel += dt; |
478 | r = 1; |
479 | } |
480 | if (r) { |
481 | if (!lex_space(p)) |
482 | return AVERROR_INVALIDDATA; |
483 | rts->type = type; |
484 | rts->t = abs; |
485 | *rrel = rel; |
486 | } |
487 | return r; |
488 | } |
489 | |
490 | static int parse_fade(struct sbg_parser *p, struct sbg_fade *fr) |
491 | { |
492 | struct sbg_fade f = {0}; |
493 | |
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; |
500 | else |
501 | return 0; |
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; |
508 | else |
509 | return AVERROR_INVALIDDATA; |
510 | *fr = f; |
511 | return 1; |
512 | } |
513 | |
514 | static int parse_time_sequence(struct sbg_parser *p, int inblock) |
515 | { |
516 | struct sbg_timestamp ts; |
517 | int64_t rel_ts; |
518 | int r; |
519 | struct sbg_fade fade = { SBG_FADE_SAME, SBG_FADE_SAME, 0 }; |
520 | struct sbg_string name; |
521 | struct sbg_script_tseq *tseq; |
522 | |
523 | r = parse_timestamp(p, &ts, &rel_ts); |
524 | if (!r) |
525 | return 0; |
526 | if (r < 0) |
527 | return r; |
528 | if (ts.type) { |
529 | if (inblock) |
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; |
537 | } |
538 | ts.type = p->current_time.type; |
539 | ts.t = p->current_time.t + rel_ts; |
540 | r = parse_fade(p, &fade); |
541 | if (r < 0) |
542 | return r; |
543 | lex_space(p); |
544 | if (!lex_name(p, &name)) |
545 | return AVERROR_INVALIDDATA; |
546 | lex_space(p); |
547 | if (lex_fixed(p, "->", 2)) { |
548 | fade.slide = SBG_FADE_ADAPT; |
549 | lex_space(p); |
550 | } |
551 | if (!lex_line_end(p)) |
552 | return AVERROR_INVALIDDATA; |
553 | tseq = inblock ? |
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); |
558 | if (!tseq) |
559 | return AVERROR(ENOMEM); |
560 | tseq->ts = ts; |
561 | tseq->name = name.s; |
562 | tseq->name_len = name.e - name.s; |
563 | tseq->fade = fade; |
564 | return 1; |
565 | } |
566 | |
567 | static int parse_wave_def(struct sbg_parser *p, int wavenum) |
568 | { |
569 | snprintf(p->err_msg, sizeof(p->err_msg), |
570 | "waveform definitions not yet implemented"); |
571 | return AVERROR_PATCHWELCOME; |
572 | } |
573 | |
574 | static int parse_block_def(struct sbg_parser *p, |
575 | struct sbg_script_definition *def) |
576 | { |
577 | int r, tseq; |
578 | |
579 | lex_space(p); |
580 | if (!lex_line_end(p)) |
581 | return AVERROR_INVALIDDATA; |
582 | tseq = p->nb_block_tseq; |
583 | while (1) { |
584 | r = parse_time_sequence(p, 1); |
585 | if (r < 0) |
586 | return r; |
587 | if (!r) |
588 | break; |
589 | } |
590 | if (!lex_char(p, '}')) |
591 | return AVERROR_INVALIDDATA; |
592 | lex_space(p); |
593 | if (!lex_line_end(p)) |
594 | return AVERROR_INVALIDDATA; |
595 | def->type = 'B'; |
596 | def->elements = tseq; |
597 | def->nb_elements = p->nb_block_tseq - tseq; |
598 | if (!def->nb_elements) |
599 | return AVERROR_INVALIDDATA; |
600 | return 1; |
601 | } |
602 | |
603 | static int parse_volume(struct sbg_parser *p, int *vol) |
604 | { |
605 | double v; |
606 | |
607 | if (!lex_char(p, '/')) |
608 | return 0; |
609 | if (!lex_double(p, &v)) |
610 | return AVERROR_INVALIDDATA; |
611 | if (scale_double(p->log, v, 0.01, vol)) |
612 | return AVERROR(ERANGE); |
613 | return 1; |
614 | } |
615 | |
616 | static int parse_synth_channel_sine(struct sbg_parser *p, |
617 | struct sbg_script_synth *synth) |
618 | { |
619 | double carrierf, beatf; |
620 | int carrier, beat, vol; |
621 | |
622 | if (!lex_double(p, &carrierf)) |
623 | return 0; |
624 | if (!lex_double(p, &beatf)) |
625 | beatf = 0; |
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; |
632 | synth->beat = beat; |
633 | synth->vol = vol; |
634 | return 1; |
635 | } |
636 | |
637 | static int parse_synth_channel_pink(struct sbg_parser *p, |
638 | struct sbg_script_synth *synth) |
639 | { |
640 | int vol; |
641 | |
642 | if (!lex_fixed(p, "pink", 4)) |
643 | return 0; |
644 | FORWARD_ERROR(parse_volume(p, &vol)); |
645 | synth->type = SBG_TYPE_NOISE; |
646 | synth->vol = vol; |
647 | return 1; |
648 | } |
649 | |
650 | static int parse_synth_channel_bell(struct sbg_parser *p, |
651 | struct sbg_script_synth *synth) |
652 | { |
653 | double carrierf; |
654 | int carrier, vol; |
655 | |
656 | if (!lex_fixed(p, "bell", 4)) |
657 | return 0; |
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; |
665 | synth->vol = vol; |
666 | return 1; |
667 | } |
668 | |
669 | static int parse_synth_channel_mix(struct sbg_parser *p, |
670 | struct sbg_script_synth *synth) |
671 | { |
672 | int vol; |
673 | |
674 | if (!lex_fixed(p, "mix", 3)) |
675 | return 0; |
676 | FORWARD_ERROR(parse_volume(p, &vol)); |
677 | synth->type = SBG_TYPE_MIX; |
678 | synth->vol = vol; |
679 | return 1; |
680 | } |
681 | |
682 | static int parse_synth_channel_spin(struct sbg_parser *p, |
683 | struct sbg_script_synth *synth) |
684 | { |
685 | double carrierf, beatf; |
686 | int carrier, beat, vol; |
687 | |
688 | if (!lex_fixed(p, "spin:", 5)) |
689 | return 0; |
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; |
700 | synth->beat = beat; |
701 | synth->vol = vol; |
702 | return 1; |
703 | } |
704 | |
705 | static int parse_synth_channel(struct sbg_parser *p) |
706 | { |
707 | int r; |
708 | struct sbg_script_synth *synth; |
709 | |
710 | synth = alloc_array_elem((void **)&p->scs.synth, sizeof(*synth), |
711 | &p->scs.nb_synth, &p->nb_synth_max); |
712 | if (!synth) |
713 | return AVERROR(ENOMEM); |
714 | r = lex_char(p, '-'); |
715 | if (!r) |
716 | r = parse_synth_channel_pink(p, synth); |
717 | if (!r) |
718 | r = parse_synth_channel_bell(p, synth); |
719 | if (!r) |
720 | r = parse_synth_channel_mix(p, synth); |
721 | if (!r) |
722 | r = parse_synth_channel_spin(p, synth); |
723 | /* Unimplemented: wave%d:%f%f/vol (carrier, beat) */ |
724 | if (!r) |
725 | r = parse_synth_channel_sine(p, synth); |
726 | if (r <= 0) |
727 | p->scs.nb_synth--; |
728 | return r; |
729 | } |
730 | |
731 | static int parse_synth_def(struct sbg_parser *p, |
732 | struct sbg_script_definition *def) |
733 | { |
734 | int r, synth; |
735 | |
736 | synth = p->scs.nb_synth; |
737 | while (1) { |
738 | r = parse_synth_channel(p); |
739 | if (r < 0) |
740 | return r; |
741 | if (!r || !lex_space(p)) |
742 | break; |
743 | } |
744 | lex_space(p); |
745 | if (synth == p->scs.nb_synth) |
746 | return AVERROR_INVALIDDATA; |
747 | if (!lex_line_end(p)) |
748 | return AVERROR_INVALIDDATA; |
749 | def->type = 'S'; |
750 | def->elements = synth; |
751 | def->nb_elements = p->scs.nb_synth - synth; |
752 | return 1; |
753 | } |
754 | |
755 | static int parse_named_def(struct sbg_parser *p) |
756 | { |
757 | char *cursor_save = p->cursor; |
758 | struct sbg_string name; |
759 | struct sbg_script_definition *def; |
760 | |
761 | if (!lex_name(p, &name) || !lex_char(p, ':') || !lex_space(p)) { |
762 | p->cursor = cursor_save; |
763 | return 0; |
764 | } |
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); |
770 | } |
771 | def = alloc_array_elem((void **)&p->scs.def, sizeof(*def), |
772 | &p->scs.nb_def, &p->nb_def_max); |
773 | if (!def) |
774 | return AVERROR(ENOMEM); |
775 | def->name = name.s; |
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); |
780 | } |
781 | |
782 | static void free_script(struct sbg_script *s) |
783 | { |
784 | av_freep(&s->def); |
785 | av_freep(&s->synth); |
786 | av_freep(&s->tseq); |
787 | av_freep(&s->block_tseq); |
788 | av_freep(&s->events); |
789 | av_freep(&s->opt_mix); |
790 | } |
791 | |
792 | static int parse_script(void *log, char *script, int script_len, |
793 | struct sbg_script *rscript) |
794 | { |
795 | struct sbg_parser sp = { |
796 | .log = log, |
797 | .script = script, |
798 | .end = script + script_len, |
799 | .cursor = script, |
800 | .line_no = 1, |
801 | .err_msg = "", |
802 | .scs = { |
803 | /* default values */ |
804 | .start_ts = AV_NOPTS_VALUE, |
805 | .sample_rate = 44100, |
806 | .opt_fade_time = 60 * AV_TIME_BASE, |
807 | }, |
808 | }; |
809 | int r; |
810 | |
811 | lex_space(&sp); |
812 | while (sp.cursor < sp.end) { |
813 | r = parse_options(&sp); |
814 | if (r < 0) |
815 | goto fail; |
816 | if (!r && !lex_line_end(&sp)) |
817 | break; |
818 | } |
819 | while (sp.cursor < sp.end) { |
820 | r = parse_named_def(&sp); |
821 | if (!r) |
822 | r = parse_time_sequence(&sp, 0); |
823 | if (!r) |
824 | r = lex_line_end(&sp) ? 1 : AVERROR_INVALIDDATA; |
825 | if (r < 0) |
826 | goto fail; |
827 | } |
828 | *rscript = sp.scs; |
829 | return 1; |
830 | fail: |
831 | free_script(&sp.scs); |
832 | if (!*sp.err_msg) |
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), |
838 | sp.end); |
839 | int lctx = ectx - ctx; |
840 | const char *quote = "\""; |
841 | if (lctx > 0 && ctx[lctx - 1] == '\r') |
842 | lctx--; |
843 | if (lctx == 0) { |
844 | ctx = "the end of line"; |
845 | lctx = strlen(ctx); |
846 | quote = ""; |
847 | } |
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); |
850 | } |
851 | return r; |
852 | } |
853 | |
854 | static int read_whole_file(AVIOContext *io, int max_size, char **rbuf) |
855 | { |
856 | char *buf = NULL; |
857 | int size = 0, bufsize = 0, r; |
858 | |
859 | while (1) { |
860 | if (bufsize - size < 1024) { |
861 | bufsize = FFMIN(FFMAX(2 * bufsize, 8192), max_size); |
862 | if (bufsize - size < 2) { |
863 | size = AVERROR(EFBIG); |
864 | goto fail; |
865 | } |
866 | buf = av_realloc_f(buf, bufsize, 1); |
867 | if (!buf) { |
868 | size = AVERROR(ENOMEM); |
869 | goto fail; |
870 | } |
871 | } |
872 | r = avio_read(io, buf, bufsize - size - 1); |
873 | if (r == AVERROR_EOF) |
874 | break; |
875 | if (r < 0) |
876 | goto fail; |
877 | size += r; |
878 | } |
879 | buf[size] = 0; |
880 | *rbuf = buf; |
881 | return size; |
882 | fail: |
883 | av_free(buf); |
884 | return size; |
885 | } |
886 | |
887 | static void expand_timestamps(void *log, struct sbg_script *s) |
888 | { |
889 | int i, nb_rel = 0; |
890 | int64_t now, cur_ts, delta = 0; |
891 | |
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 */ |
896 | 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; |
905 | now = s->start_ts; |
906 | } else { |
907 | /* Mixed relative/absolute ts: expand */ |
908 | time_t now0; |
909 | struct tm *tm, tmpbuf; |
910 | |
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"); |
914 | #undef time |
915 | time(&now0); |
916 | tm = localtime_r(&now0, &tmpbuf); |
917 | now = tm ? tm->tm_hour * 3600 + tm->tm_min * 60 + tm->tm_sec : |
918 | now0 % DAY; |
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); |
921 | now *= AV_TIME_BASE; |
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 */ |
926 | } |
927 | } |
928 | } |
929 | if (s->start_ts == AV_NOPTS_VALUE) |
930 | s->start_ts = (s->opt_start_at_first && s->tseq) ? 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 */ |
933 | cur_ts = now; |
934 | for (i = 0; i < s->nb_tseq; i++) { |
935 | if (s->tseq[i].ts.t + delta < cur_ts) |
936 | delta += DAY_TS; |
937 | cur_ts = s->tseq[i].ts.t += delta; |
938 | } |
939 | } |
940 | |
941 | static int expand_tseq(void *log, struct sbg_script *s, int *nb_ev_max, |
942 | int64_t t0, struct sbg_script_tseq *tseq) |
943 | { |
944 | int i, r; |
945 | struct sbg_script_definition *def; |
946 | struct sbg_script_tseq *be; |
947 | struct sbg_script_event *ev; |
948 | |
949 | if (tseq->lock++) { |
950 | av_log(log, AV_LOG_ERROR, "Recursion loop on \"%.*s\"\n", |
951 | tseq->name_len, tseq->name); |
952 | return AVERROR(EINVAL); |
953 | } |
954 | t0 += tseq->ts.t; |
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)) |
958 | break; |
959 | } |
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); |
964 | } |
965 | def = &s->def[i]; |
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]); |
970 | if (r < 0) |
971 | return r; |
972 | } |
973 | } else { |
974 | ev = alloc_array_elem((void **)&s->events, sizeof(*ev), |
975 | &s->nb_events, nb_ev_max); |
976 | if (!ev) |
977 | return AVERROR(ENOMEM); |
978 | ev->ts = tseq->ts.t; |
979 | ev->elements = def->elements; |
980 | ev->nb_elements = def->nb_elements; |
981 | ev->fade = tseq->fade; |
982 | } |
983 | tseq->lock--; |
984 | return 0; |
985 | } |
986 | |
987 | static int expand_script(void *log, struct sbg_script *s) |
988 | { |
989 | int i, r, nb_events_max = 0; |
990 | |
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]); |
994 | if (r < 0) |
995 | return r; |
996 | } |
997 | if (!s->nb_events) { |
998 | av_log(log, AV_LOG_ERROR, "No events in script\n"); |
999 | return AVERROR_INVALIDDATA; |
1000 | } |
1001 | if (s->opt_end_at_last) |
1002 | s->end_ts = s->events[s->nb_events - 1].ts; |
1003 | return 0; |
1004 | } |
1005 | |
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) |
1010 | { |
1011 | struct ws_interval *i, *ri; |
1012 | |
1013 | if (ref >= 0) { |
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 && |
1019 | ri->ts2 == ts1) { |
1020 | ri->ts2 = ts2; |
1021 | return ref; |
1022 | } |
1023 | } |
1024 | i = alloc_array_elem((void **)&inter->inter, sizeof(*i), |
1025 | &inter->nb_inter, &inter->max_inter); |
1026 | if (!i) |
1027 | return AVERROR(ENOMEM); |
1028 | i->ts1 = ts1; |
1029 | i->ts2 = ts2; |
1030 | i->type = type; |
1031 | i->channels = channels; |
1032 | i->f1 = f1; |
1033 | i->f2 = f2; |
1034 | i->a1 = a1; |
1035 | i->a2 = a2; |
1036 | i->phi = ref >= 0 ? ref | 0x80000000 : 0; |
1037 | return i - inter->inter; |
1038 | } |
1039 | |
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) |
1042 | { |
1043 | /* SBaGen uses an exponential decrease every 50ms. |
1044 | We approximate it with piecewise affine segments. */ |
1045 | int32_t cpoints[][2] = { |
1046 | { 2, a }, |
1047 | { 4, a - a / 4 }, |
1048 | { 8, a / 2 }, |
1049 | { 16, a / 4 }, |
1050 | { 25, a / 10 }, |
1051 | { 50, a / 80 }, |
1052 | { 75, 0 }, |
1053 | }; |
1054 | int i, r; |
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]); |
1060 | if (r < 0) |
1061 | return r; |
1062 | ts3 = ts4; |
1063 | a = cpoints[i][1]; |
1064 | } |
1065 | return 0; |
1066 | } |
1067 | |
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, |
1073 | int transition) |
1074 | { |
1075 | int r; |
1076 | |
1077 | if (ts2 <= ts1 || (s1->vol == 0 && s2->vol == 0)) |
1078 | return 0; |
1079 | switch (s1->type) { |
1080 | case SBG_TYPE_NONE: |
1081 | break; |
1082 | case SBG_TYPE_SINE: |
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); |
1087 | if (r < 0) |
1088 | return r; |
1089 | s2->ref.l = s2->ref.r = r; |
1090 | } else { |
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); |
1094 | if (r < 0) |
1095 | return r; |
1096 | s2->ref.l = r; |
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); |
1100 | if (r < 0) |
1101 | return r; |
1102 | s2->ref.r = r; |
1103 | } |
1104 | break; |
1105 | |
1106 | case SBG_TYPE_BELL: |
1107 | if (transition == 2) { |
1108 | r = add_bell(inter, s, ts1, ts2, s1->carrier, s2->vol); |
1109 | if (r < 0) |
1110 | return r; |
1111 | } |
1112 | break; |
1113 | |
1114 | case SBG_TYPE_SPIN: |
1115 | av_log(log, AV_LOG_WARNING, "Spinning noise not implemented, " |
1116 | "using pink noise instead.\n"); |
1117 | /* fall through */ |
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 |
1128 | */ |
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); |
1132 | if (r < 0) |
1133 | return r; |
1134 | s2->ref.l = s2->ref.r = r; |
1135 | break; |
1136 | |
1137 | case SBG_TYPE_MIX: |
1138 | /* Unimplemented: silence; warning present elsewhere */ |
1139 | default: |
1140 | av_log(log, AV_LOG_ERROR, |
1141 | "Type %d is not implemented\n", s1->type); |
1142 | return AVERROR_PATCHWELCOME; |
1143 | } |
1144 | return 0; |
1145 | } |
1146 | |
1147 | static int generate_plateau(void *log, struct sbg_script *s, |
1148 | struct ws_intervals *inter, |
1149 | struct sbg_script_event *ev1) |
1150 | { |
1151 | int64_t ts1 = ev1->ts_int, ts2 = ev1->ts_trans; |
1152 | int i, r; |
1153 | struct sbg_script_synth *s1; |
1154 | |
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); |
1158 | if (r < 0) |
1159 | return r; |
1160 | } |
1161 | return 0; |
1162 | } |
1163 | |
1164 | /* |
1165 | |
1166 | ts1 ts2 ts1 tsmid ts2 |
1167 | | | | | | |
1168 | v v v | v |
1169 | ____ ____ v ____ |
1170 | ''''.... ''.. ..'' |
1171 | ''''....____ ''....'' |
1172 | |
1173 | compatible transition incompatible transition |
1174 | */ |
1175 | |
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) |
1180 | { |
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; |
1187 | int pass, i, r; |
1188 | |
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. |
1196 | */ |
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) { |
1206 | s1mod = s2mod; |
1207 | s1mod.vol = 0; |
1208 | } else if (s2mod.type == SBG_TYPE_NONE) { |
1209 | s2mod = s1mod; |
1210 | s2mod.vol = 0; |
1211 | } |
1212 | } |
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 */ |
1219 | if (!pass) { |
1220 | r = generate_interval(log, s, inter, |
1221 | ts1, ts2, &s1mod, &s2mod, 3); |
1222 | if (r < 0) |
1223 | return r; |
1224 | s2->ref = s2mod.ref; |
1225 | } |
1226 | } else { |
1227 | /* incompatible: silence at midpoint */ |
1228 | if (!pass) { |
1229 | smid = s1mod; |
1230 | smid.vol = 0; |
1231 | r = generate_interval(log, s, inter, |
1232 | ts1, tsmid, &s1mod, &smid, 1); |
1233 | if (r < 0) |
1234 | return r; |
1235 | } else { |
1236 | smid = s2mod; |
1237 | smid.vol = 0; |
1238 | r = generate_interval(log, s, inter, |
1239 | tsmid, ts2, &smid, &s2mod, 2); |
1240 | if (r < 0) |
1241 | return r; |
1242 | s2->ref = s2mod.ref; |
1243 | } |
1244 | } |
1245 | } |
1246 | } |
1247 | return 0; |
1248 | } |
1249 | |
1250 | /* |
1251 | ev1 trats ev2 intts endts ev3 |
1252 | | | | | | | |
1253 | v v v v v v |
1254 | ________________ |
1255 | .... .... .... |
1256 | '''....________________....''' '''...._______________ |
1257 | |
1258 | \_________/\______________/\_________/\______________/\_________/\_____________/ |
1259 | tr x->1 int1 tr 1->2 int2 tr 2->3 int3 |
1260 | */ |
1261 | |
1262 | static int generate_intervals(void *log, struct sbg_script *s, int sample_rate, |
1263 | struct ws_intervals *inter) |
1264 | { |
1265 | int64_t trans_time = s->opt_fade_time / 2; |
1266 | struct sbg_script_event ev0, *ev1, *ev2; |
1267 | int64_t period; |
1268 | int i, r; |
1269 | |
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); |
1276 | |
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); |
1284 | } |
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); |
1291 | } |
1292 | ev1->ts_next = ev2->ts_int + (ev1 < ev2 ? 0 : period); |
1293 | } |
1294 | |
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; |
1300 | |
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); |
1307 | } |
1308 | |
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); |
1316 | if (r < 0) |
1317 | return r; |
1318 | r = generate_transition(log, s, inter, ev1, ev2); |
1319 | if (r < 0) |
1320 | return r; |
1321 | } |
1322 | if (!inter->nb_inter) |
1323 | av_log(log, AV_LOG_WARNING, "Completely silent script.\n"); |
1324 | return 0; |
1325 | } |
1326 | |
1327 | static int encode_intervals(struct sbg_script *s, AVCodecParameters *par, |
1328 | struct ws_intervals *inter) |
1329 | { |
1330 | int i, edata_size = 4; |
1331 | uint8_t *edata; |
1332 | |
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; |
1336 | if (edata_size < 0) |
1337 | return AVERROR(ENOMEM); |
1338 | } |
1339 | if (ff_alloc_extradata(par, edata_size)) |
1340 | return AVERROR(ENOMEM); |
1341 | edata = par->extradata; |
1342 | |
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) { |
1352 | case WS_SINE: |
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); |
1358 | break; |
1359 | case WS_NOISE: |
1360 | ADD_EDATA32(inter->inter[i].a1); |
1361 | ADD_EDATA32(inter->inter[i].a2); |
1362 | break; |
1363 | } |
1364 | } |
1365 | if (edata != par->extradata + edata_size) |
1366 | return AVERROR_BUG; |
1367 | return 0; |
1368 | } |
1369 | |
1370 | static av_cold int sbg_read_probe(AVProbeData *p) |
1371 | { |
1372 | int r, score; |
1373 | struct sbg_script script = { 0 }; |
1374 | |
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); |
1379 | return score; |
1380 | } |
1381 | |
1382 | static av_cold int sbg_read_header(AVFormatContext *avf) |
1383 | { |
1384 | struct sbg_demuxer *sbg = avf->priv_data; |
1385 | int r; |
1386 | char *buf = NULL; |
1387 | struct sbg_script script = { 0 }; |
1388 | AVStream *st; |
1389 | struct ws_intervals inter = { 0 }; |
1390 | |
1391 | r = read_whole_file(avf->pb, sbg->max_file_size, &buf); |
1392 | if (r < 0) |
1393 | goto fail; |
1394 | r = parse_script(avf, buf, r, &script); |
1395 | if (r < 0) |
1396 | goto fail; |
1397 | if (!sbg->sample_rate) |
1398 | sbg->sample_rate = script.sample_rate; |
1399 | else |
1400 | script.sample_rate = sbg->sample_rate; |
1401 | if (!sbg->frame_size) |
1402 | sbg->frame_size = FFMAX(1, sbg->sample_rate / 10); |
1403 | if (script.opt_mix) |
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); |
1407 | if (r < 0) |
1408 | goto fail; |
1409 | av_freep(&buf); |
1410 | r = generate_intervals(avf, &script, sbg->sample_rate, &inter); |
1411 | if (r < 0) |
1412 | goto fail; |
1413 | |
1414 | st = avformat_new_stream(avf, NULL); |
1415 | if (!st) |
1416 | return AVERROR(ENOMEM); |
1417 | st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; |
1418 | st->codecpar->codec_id = AV_CODEC_ID_FFWAVESYNTH; |
1419 | st->codecpar->channels = 2; |
1420 | st->codecpar->channel_layout = AV_CH_LAYOUT_STEREO; |
1421 | st->codecpar->sample_rate = sbg->sample_rate; |
1422 | st->codecpar->frame_size = sbg->frame_size; |
1423 | avpriv_set_pts_info(st, 64, 1, st->codecpar->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->codecpar, &inter); |
1432 | if (r < 0) |
1433 | goto fail; |
1434 | |
1435 | av_free(inter.inter); |
1436 | free_script(&script); |
1437 | return 0; |
1438 | |
1439 | fail: |
1440 | av_free(inter.inter); |
1441 | free_script(&script); |
1442 | av_free(buf); |
1443 | return r; |
1444 | } |
1445 | |
1446 | static int sbg_read_packet(AVFormatContext *avf, AVPacket *packet) |
1447 | { |
1448 | int64_t ts, end_ts; |
1449 | |
1450 | ts = avf->streams[0]->cur_dts; |
1451 | end_ts = ts + avf->streams[0]->codecpar->frame_size; |
1452 | if (avf->streams[0]->duration != AV_NOPTS_VALUE) |
1453 | end_ts = FFMIN(avf->streams[0]->start_time + avf->streams[0]->duration, |
1454 | end_ts); |
1455 | if (end_ts <= ts) |
1456 | return AVERROR_EOF; |
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; |
1464 | } |
1465 | |
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) |
1468 | { |
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; |
1474 | return 0; |
1475 | } |
1476 | |
1477 | static int sbg_read_seek(AVFormatContext *avf, int stream_index, |
1478 | int64_t ts, int flags) |
1479 | { |
1480 | return sbg_read_seek2(avf, stream_index, ts, ts, ts, 0); |
1481 | } |
1482 | |
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 }, |
1493 | { NULL }, |
1494 | }; |
1495 | |
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, |
1501 | }; |
1502 | |
1503 | AVInputFormat ff_sbg_demuxer = { |
1504 | .name = "sbg", |
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, |
1514 | }; |
1515 |