FFmpeg
Loading...
Searching...
No Matches
ffwavesynth.c
Go to the documentation of this file.
1/*
2 * Wavesynth pseudo-codec
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
23#include "libavutil/log.h"
24#include "libavutil/mem.h"
25#include "avcodec.h"
26#include "codec_internal.h"
27#include "decode.h"
28
29
30#define SIN_BITS 14
31#define WS_MAX_CHANNELS 32
32#define INF_TS 0x7FFFFFFFFFFFFFFF
33
34#define PINK_UNIT 128
35
36/*
37 Format of the extradata and packets
38
39 THIS INFORMATION IS NOT PART OF THE PUBLIC API OR ABI.
40 IT CAN CHANGE WITHOUT NOTIFICATION.
41
42 All numbers are in little endian.
43
44 The codec extradata define a set of intervals with uniform content.
45 Overlapping intervals are added together.
46
47 extradata:
48 uint32 number of intervals
49 ... intervals
50
51 interval:
52 int64 start timestamp; time_base must be 1/sample_rate;
53 start timestamps must be in ascending order
54 int64 end timestamp
55 uint32 type
56 uint32 channels mask
57 ... additional information, depends on type
58
59 sine interval (type fourcc "SINE"):
60 int32 start frequency, in 1/(1<<16) Hz
61 int32 end frequency
62 int32 start amplitude, 1<<16 is the full amplitude
63 int32 end amplitude
64 uint32 start phase, 0 is sin(0), 0x20000000 is sin(pi/2), etc.;
65 n | (1<<31) means to match the phase of previous channel #n
66
67 pink noise interval (type fourcc "NOIS"):
68 int32 start amplitude
69 int32 end amplitude
70
71 The input packets encode the time and duration of the requested segment.
72
73 packet:
74 int64 start timestamp
75 int32 duration
76
77*/
78
80 WS_SINE = MKTAG('S','I','N','E'),
81 WS_NOISE = MKTAG('N','O','I','S'),
82};
83
86 uint64_t phi0, dphi0, ddphi;
87 uint64_t amp0, damp;
88 uint64_t phi, dphi, amp;
89 uint32_t channels;
91 int next;
92};
93
107
108#define LCG_A 1284865837
109#define LCG_C 4150755663
110#define LCG_AI 849225893 /* A*AI = 1 [mod 1<<32] */
111
112static uint32_t lcg_next(uint32_t *s)
113{
114 *s = *s * LCG_A + LCG_C;
115 return *s;
116}
117
118static void lcg_seek(uint32_t *s, uint32_t dt)
119{
120 uint32_t a, c, t = *s;
121
122 a = LCG_A;
123 c = LCG_C;
124 while (dt) {
125 if (dt & 1)
126 t = a * t + c;
127 c *= a + 1; /* coefficients for a double step */
128 a *= a;
129 dt >>= 1;
130 }
131 *s = t;
132}
133
134/* Emulate pink noise by summing white noise at the sampling frequency,
135 * white noise at half the sampling frequency (each value taken twice),
136 * etc., with a total of 8 octaves.
137 * This is known as the Voss-McCartney algorithm. */
138
139static void pink_fill(struct wavesynth_context *ws)
140{
141 int32_t vt[7] = { 0 }, v = 0;
142 int i, j;
143
144 ws->pink_pos = 0;
145 if (!ws->pink_need)
146 return;
147 for (i = 0; i < PINK_UNIT; i++) {
148 for (j = 0; j < 7; j++) {
149 if ((i >> j) & 1)
150 break;
151 v -= vt[j];
152 vt[j] = (int32_t)lcg_next(&ws->pink_state) >> 3;
153 v += vt[j];
154 }
155 ws->pink_pool[i] = v + ((int32_t)lcg_next(&ws->pink_state) >> 3);
156 }
157 lcg_next(&ws->pink_state); /* so we use exactly 256 steps */
158}
159
160/**
161 * @return (1<<64) * a / b, without overflow, if a < b
162 */
163static uint64_t frac64(uint64_t a, uint64_t b)
164{
165 uint64_t r = 0;
166 int i;
167
168 if (b < (uint64_t)1 << 32) { /* b small, use two 32-bits steps */
169 a <<= 32;
170 return ((a / b) << 32) | ((a % b) << 32) / b;
171 }
172 if (b < (uint64_t)1 << 48) { /* b medium, use four 16-bits steps */
173 for (i = 0; i < 4; i++) {
174 a <<= 16;
175 r = (r << 16) | (a / b);
176 a %= b;
177 }
178 return r;
179 }
180 for (i = 63; i >= 0; i--) {
181 if (a >= (uint64_t)1 << 63 || a << 1 >= b) {
182 r |= (uint64_t)1 << i;
183 a = (a << 1) - b;
184 } else {
185 a <<= 1;
186 }
187 }
188 return r;
189}
190
191static uint64_t phi_at(struct ws_interval *in, int64_t ts)
192{
193 uint64_t dt = ts - (uint64_t)in->ts_start;
194 uint64_t dt2 = dt & 1 ? /* dt * (dt - 1) / 2 without overflow */
195 dt * ((dt - 1) >> 1) : (dt >> 1) * (dt - 1);
196 return in->phi0 + dt * in->dphi0 + dt2 * in->ddphi;
197}
198
199static void wavesynth_seek(struct wavesynth_context *ws, int64_t ts)
200{
201 int *last, i;
202 struct ws_interval *in;
203
204 last = &ws->cur_inter;
205 for (i = 0; i < ws->nb_inter; i++) {
206 in = &ws->inter[i];
207 if (ts < in->ts_start)
208 break;
209 if (ts >= in->ts_end)
210 continue;
211 *last = i;
212 last = &in->next;
213 in->phi = phi_at(in, ts);
214 in->dphi = in->dphi0 + (ts - in->ts_start) * in->ddphi;
215 in->amp = in->amp0 + (ts - in->ts_start) * in->damp;
216 }
217 ws->next_inter = i;
218 ws->next_ts = i < ws->nb_inter ? ws->inter[i].ts_start : INF_TS;
219 *last = -1;
220 lcg_seek(&ws->dither_state, (uint32_t)ts - (uint32_t)ws->cur_ts);
221 if (ws->pink_need) {
222 uint64_t pink_ts_cur = (ws->cur_ts + (uint64_t)PINK_UNIT - 1) & ~(PINK_UNIT - 1);
223 uint64_t pink_ts_next = ts & ~(PINK_UNIT - 1);
224 int pos = ts & (PINK_UNIT - 1);
225 lcg_seek(&ws->pink_state, (uint32_t)(pink_ts_next - pink_ts_cur) * 2);
226 if (pos) {
227 pink_fill(ws);
228 ws->pink_pos = pos;
229 } else {
230 ws->pink_pos = PINK_UNIT;
231 }
232 }
233 ws->cur_ts = ts;
234}
235
237{
238 struct wavesynth_context *ws = avc->priv_data;
239 struct ws_interval *in;
240 uint8_t *edata, *edata_end;
241 int32_t f1, f2, a1, a2;
242 uint32_t phi;
243 int64_t dphi1, dphi2, dt, cur_ts = -0x8000000000000000;
244 int i;
245
246 if (avc->extradata_size < 4)
247 return AVERROR(EINVAL);
248 edata = avc->extradata;
249 edata_end = edata + avc->extradata_size;
250 ws->nb_inter = AV_RL32(edata);
251 edata += 4;
252 if (ws->nb_inter < 0 || (edata_end - edata) / 24 < ws->nb_inter)
253 return AVERROR(EINVAL);
254 ws->inter = av_calloc(ws->nb_inter, sizeof(*ws->inter));
255 if (!ws->inter)
256 return AVERROR(ENOMEM);
257 for (i = 0; i < ws->nb_inter; i++) {
258 in = &ws->inter[i];
259 if (edata_end - edata < 24)
260 return AVERROR(EINVAL);
261 in->ts_start = AV_RL64(edata + 0);
262 in->ts_end = AV_RL64(edata + 8);
263 in->type = AV_RL32(edata + 16);
264 in->channels = AV_RL32(edata + 20);
265 edata += 24;
266 if (in->ts_start < cur_ts ||
267 in->ts_end <= in->ts_start ||
268 (uint64_t)in->ts_end - in->ts_start > INT64_MAX
269 )
270 return AVERROR(EINVAL);
271 cur_ts = in->ts_start;
272 dt = in->ts_end - in->ts_start;
273 switch (in->type) {
274 case WS_SINE:
275 if (edata_end - edata < 20 || avc->sample_rate <= 0)
276 return AVERROR(EINVAL);
277 f1 = AV_RL32(edata + 0);
278 f2 = AV_RL32(edata + 4);
279 a1 = AV_RL32(edata + 8);
280 a2 = AV_RL32(edata + 12);
281 phi = AV_RL32(edata + 16);
282 edata += 20;
283 dphi1 = frac64(f1, (int64_t)avc->sample_rate << 16);
284 dphi2 = frac64(f2, (int64_t)avc->sample_rate << 16);
285 in->dphi0 = dphi1;
286 in->ddphi = (int64_t)(dphi2 - (uint64_t)dphi1) / dt;
287 if (phi & 0x80000000) {
288 phi &= ~0x80000000;
289 if (phi >= i)
290 return AVERROR(EINVAL);
291 in->phi0 = phi_at(&ws->inter[phi], in->ts_start);
292 } else {
293 in->phi0 = (uint64_t)phi << 33;
294 }
295 break;
296 case WS_NOISE:
297 if (edata_end - edata < 8)
298 return AVERROR(EINVAL);
299 a1 = AV_RL32(edata + 0);
300 a2 = AV_RL32(edata + 4);
301 edata += 8;
302 break;
303 default:
304 return AVERROR(EINVAL);
305 }
306 in->amp0 = (uint64_t)a1 << 32;
307 in->damp = (int64_t)(((uint64_t)a2 << 32) - ((uint64_t)a1 << 32)) / dt;
308 }
309 if (edata != edata_end)
310 return AVERROR(EINVAL);
311 return 0;
312}
313
315{
316 struct wavesynth_context *ws = avc->priv_data;
317 int i, r;
318
320 av_log(avc, AV_LOG_ERROR,
321 "This implementation is limited to %d channels.\n",
323 return AVERROR(EINVAL);
324 }
326 if (r < 0) {
327 av_log(avc, AV_LOG_ERROR, "Invalid intervals definitions.\n");
328 return r;
329 }
330 ws->sin = av_malloc(sizeof(*ws->sin) << SIN_BITS);
331 if (!ws->sin)
332 return AVERROR(ENOMEM);
333 for (i = 0; i < 1 << SIN_BITS; i++)
334 ws->sin[i] = floor(32767 * sin(2 * M_PI * i / (1 << SIN_BITS)));
335 ws->dither_state = MKTAG('D','I','T','H');
336 for (i = 0; i < ws->nb_inter; i++)
337 ws->pink_need += ws->inter[i].type == WS_NOISE;
338 ws->pink_state = MKTAG('P','I','N','K');
339 ws->pink_pos = PINK_UNIT;
340 wavesynth_seek(ws, 0);
342 return 0;
343}
344
347{
348 int32_t amp, *cv;
349 unsigned val;
350 struct ws_interval *in;
351 int i, *last, pink;
352 uint32_t c, all_ch = 0;
353
354 i = ws->cur_inter;
355 last = &ws->cur_inter;
356 if (ws->pink_pos == PINK_UNIT)
357 pink_fill(ws);
358 pink = ws->pink_pool[ws->pink_pos++] >> 16;
359 while (i >= 0) {
360 in = &ws->inter[i];
361 i = in->next;
362 if (ts >= in->ts_end) {
363 *last = i;
364 continue;
365 }
366 last = &in->next;
367 amp = in->amp >> 32;
368 in->amp += in->damp;
369 switch (in->type) {
370 case WS_SINE:
371 val = amp * (unsigned)ws->sin[in->phi >> (64 - SIN_BITS)];
372 in->phi += in->dphi;
373 in->dphi += in->ddphi;
374 break;
375 case WS_NOISE:
376 val = amp * (unsigned)pink;
377 break;
378 default:
379 val = 0;
380 }
381 all_ch |= in->channels;
382 for (c = in->channels, cv = channels; c; c >>= 1, cv++)
383 if (c & 1)
384 *cv += (unsigned)val;
385 }
386 val = (int32_t)lcg_next(&ws->dither_state) >> 16;
387 for (c = all_ch, cv = channels; c; c >>= 1, cv++)
388 if (c & 1)
389 *cv += val;
390}
391
393{
394 int *last, i;
395 struct ws_interval *in;
396
397 last = &ws->cur_inter;
398 for (i = ws->cur_inter; i >= 0; i = ws->inter[i].next)
399 last = &ws->inter[i].next;
400 for (i = ws->next_inter; i < ws->nb_inter; i++) {
401 in = &ws->inter[i];
402 if (ts < in->ts_start)
403 break;
404 if (ts >= in->ts_end)
405 continue;
406 *last = i;
407 last = &in->next;
408 in->phi = in->phi0;
409 in->dphi = in->dphi0;
410 in->amp = in->amp0;
411 }
412 ws->next_inter = i;
413 ws->next_ts = i < ws->nb_inter ? ws->inter[i].ts_start : INF_TS;
414 *last = -1;
415}
416
418 int *rgot_frame, AVPacket *packet)
419{
420 struct wavesynth_context *ws = avc->priv_data;
421 int64_t ts;
422 int duration;
423 int s, c, r;
424 int16_t *pcm;
426
427 *rgot_frame = 0;
428 if (packet->size != 12)
429 return AVERROR_INVALIDDATA;
430 ts = AV_RL64(packet->data);
431 if (ts != ws->cur_ts)
432 wavesynth_seek(ws, ts);
433 duration = AV_RL32(packet->data + 8);
434 if (duration <= 0)
435 return AVERROR(EINVAL);
436 frame->nb_samples = duration;
437 r = ff_get_buffer(avc, frame, 0);
438 if (r < 0)
439 return r;
440 pcm = (int16_t *)frame->data[0];
441 for (s = 0; s < duration; s++, ts+=(uint64_t)1) {
442 memset(channels, 0, avc->ch_layout.nb_channels * sizeof(*channels));
443 if (ts >= ws->next_ts)
446 for (c = 0; c < avc->ch_layout.nb_channels; c++)
447 *(pcm++) = channels[c] >> 16;
448 }
449 ws->cur_ts += (uint64_t)duration;
450 *rgot_frame = 1;
451 return packet->size;
452}
453
455{
456 struct wavesynth_context *ws = avc->priv_data;
457
458 av_freep(&ws->sin);
459 av_freep(&ws->inter);
460 return 0;
461}
462
464 .p.name = "wavesynth",
465 CODEC_LONG_NAME("Wave synthesis pseudo-codec"),
466 .p.type = AVMEDIA_TYPE_AUDIO,
468 .priv_data_size = sizeof(struct wavesynth_context),
470 .close = wavesynth_close,
472 .p.capabilities = AV_CODEC_CAP_DR1,
473 .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
474};
static double val(void *priv, double ch)
Definition aeval.c:77
const FFCodec ff_ffwavesynth_decoder
channels
Definition aptx.h:31
int32_t
Libavcodec external API header.
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define s(width, name)
Definition cbs_vp9.c:198
#define FF_CODEC_DECODE_CB(func)
#define CODEC_LONG_NAME(str)
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
long long int64_t
Definition coverity.c:34
static __device__ float floor(float a)
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition decode.c:1777
static AVFrame * frame
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
static int64_t duration
Definition ffplay.c:330
#define PINK_UNIT
Definition ffwavesynth.c:34
#define LCG_A
static void wavesynth_enter_intervals(struct wavesynth_context *ws, int64_t ts)
static int wavesynth_parse_extradata(AVCodecContext *avc)
static uint64_t phi_at(struct ws_interval *in, int64_t ts)
ws_interval_type
Definition ffwavesynth.c:79
@ WS_NOISE
Definition ffwavesynth.c:81
@ WS_SINE
Definition ffwavesynth.c:80
#define WS_MAX_CHANNELS
Definition ffwavesynth.c:31
static av_cold int wavesynth_close(AVCodecContext *avc)
static av_cold int wavesynth_init(AVCodecContext *avc)
#define SIN_BITS
Definition ffwavesynth.c:30
static int wavesynth_decode(AVCodecContext *avc, AVFrame *frame, int *rgot_frame, AVPacket *packet)
#define LCG_C
static uint64_t frac64(uint64_t a, uint64_t b)
static void lcg_seek(uint32_t *s, uint32_t dt)
static uint32_t lcg_next(uint32_t *s)
static void wavesynth_synth_sample(struct wavesynth_context *ws, int64_t ts, int32_t *channels)
static void wavesynth_seek(struct wavesynth_context *ws, int64_t ts)
static void pink_fill(struct wavesynth_context *ws)
#define INF_TS
Definition ffwavesynth.c:32
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition codec.h:49
@ AV_CODEC_ID_FFWAVESYNTH
Definition codec_id.h:521
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR(e)
Definition error.h:45
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
@ AVMEDIA_TYPE_AUDIO
Definition avutil.h:201
@ AV_SAMPLE_FMT_S16
signed 16 bits
Definition samplefmt.h:58
int a
#define r
Definition input.c:42
#define b
Definition input.c:43
#define AV_RL64(p)
#define AV_RL32(p)
#define av_cold
Definition attributes.h:117
#define MKTAG(a, b, c, d)
Definition macros.h:55
#define M_PI
Definition mathematics.h:67
void * av_calloc(size_t nmemb, size_t size)
Definition mem.c:264
Memory handling functions.
#define av_malloc(s)
Definition ops_static.c:52
ws_interval_type
Definition sbgdec.c:143
unsigned int pos
Definition spdifenc.c:431
int nb_channels
Number of channels in this layout.
main external API structure.
Definition avcodec.h:443
AVChannelLayout ch_layout
Audio channel layout.
Definition avcodec.h:1055
enum AVSampleFormat sample_fmt
audio sample format
Definition avcodec.h:1047
int sample_rate
samples per second
Definition avcodec.h:1040
uint8_t * extradata
Out-of-band global headers that may be used by some codecs.
Definition avcodec.h:526
int extradata_size
Definition avcodec.h:527
void * priv_data
Definition avcodec.h:470
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
This structure stores compressed data.
Definition packet.h:580
int size
Definition packet.h:604
uint8_t * data
Definition packet.h:603
struct ws_interval * inter
Definition ffwavesynth.c:98
uint32_t dither_state
Definition ffwavesynth.c:99
int32_t pink_pool[PINK_UNIT]
int64_t ts_start
Definition ffwavesynth.c:85
uint64_t phi0
Definition ffwavesynth.c:86
int32_t f2
Definition sbgdec.c:152
uint32_t channels
Definition ffwavesynth.c:89
uint64_t dphi0
Definition ffwavesynth.c:86
uint64_t amp
Definition ffwavesynth.c:88
uint64_t dphi
Definition ffwavesynth.c:88
uint64_t phi
Definition ffwavesynth.c:88
int32_t f1
Definition sbgdec.c:152
uint64_t damp
Definition ffwavesynth.c:87
uint64_t ddphi
Definition ffwavesynth.c:86
enum ws_interval_type type
Definition ffwavesynth.c:90
int64_t ts_end
Definition ffwavesynth.c:85
uint64_t amp0
Definition ffwavesynth.c:87
#define av_freep(p)
#define av_log(a,...)
static double a2(void *priv, double x, double y)
Definition vf_xfade.c:2030
static double a1(void *priv, double x, double y)
Definition vf_xfade.c:2029
static double c[64]