blob: 9104f384767b884f35d10fe5e6ed69ad2554917d
1 | /* |
2 | * Direct Stream Digital (DSD) decoder |
3 | * based on BSD licensed dsd2pcm by Sebastian Gesemann |
4 | * Copyright (c) 2009, 2011 Sebastian Gesemann. All rights reserved. |
5 | * Copyright (c) 2014 Peter Ross |
6 | * |
7 | * This file is part of FFmpeg. |
8 | * |
9 | * FFmpeg is free software; you can redistribute it and/or |
10 | * modify it under the terms of the GNU Lesser General Public |
11 | * License as published by the Free Software Foundation; either |
12 | * version 2.1 of the License, or (at your option) any later version. |
13 | * |
14 | * FFmpeg is distributed in the hope that it will be useful, |
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
17 | * Lesser General Public License for more details. |
18 | * |
19 | * You should have received a copy of the GNU Lesser General Public |
20 | * License along with FFmpeg; if not, write to the Free Software |
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
22 | */ |
23 | |
24 | #include "libavcodec/internal.h" |
25 | #include "libavcodec/mathops.h" |
26 | #include "avcodec.h" |
27 | #include "dsd_tablegen.h" |
28 | #include "dsd.h" |
29 | |
30 | static av_cold void dsd_ctables_tableinit(void) |
31 | { |
32 | int t, e, m, sign; |
33 | double acc[CTABLES]; |
34 | for (e = 0; e < 256; ++e) { |
35 | memset(acc, 0, sizeof(acc)); |
36 | for (m = 0; m < 8; ++m) { |
37 | sign = (((e >> (7 - m)) & 1) * 2 - 1); |
38 | for (t = 0; t < CTABLES; ++t) |
39 | acc[t] += sign * htaps[t * 8 + m]; |
40 | } |
41 | for (t = 0; t < CTABLES; ++t) |
42 | ctables[CTABLES - 1 - t][e] = acc[t]; |
43 | } |
44 | } |
45 | |
46 | av_cold void ff_init_dsd_data(void) |
47 | { |
48 | static int done = 0; |
49 | if (done) |
50 | return; |
51 | dsd_ctables_tableinit(); |
52 | done = 1; |
53 | } |
54 | |
55 | void ff_dsd2pcm_translate(DSDContext* s, size_t samples, int lsbf, |
56 | const unsigned char *src, ptrdiff_t src_stride, |
57 | float *dst, ptrdiff_t dst_stride) |
58 | { |
59 | unsigned pos, i; |
60 | unsigned char* p; |
61 | double sum; |
62 | |
63 | pos = s->pos; |
64 | |
65 | while (samples-- > 0) { |
66 | s->buf[pos] = lsbf ? ff_reverse[*src] : *src; |
67 | src += src_stride; |
68 | |
69 | p = s->buf + ((pos - CTABLES) & FIFOMASK); |
70 | *p = ff_reverse[*p]; |
71 | |
72 | sum = 0.0; |
73 | for (i = 0; i < CTABLES; i++) { |
74 | unsigned char a = s->buf[(pos - i) & FIFOMASK]; |
75 | unsigned char b = s->buf[(pos - (CTABLES*2 - 1) + i) & FIFOMASK]; |
76 | sum += ctables[i][a] + ctables[i][b]; |
77 | } |
78 | |
79 | *dst = (float)sum; |
80 | dst += dst_stride; |
81 | |
82 | pos = (pos + 1) & FIFOMASK; |
83 | } |
84 | |
85 | s->pos = pos; |
86 | } |
87 |