/src/ffmpeg/libavcodec/dsd.c
Line | Count | Source |
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 <string.h> |
25 | | #include "libavutil/attributes.h" |
26 | | #include "libavutil/reverse.h" |
27 | | #include "libavutil/thread.h" |
28 | | #include "dsd.h" |
29 | | |
30 | 1.27G | #define CTABLES ((HTAPS + 7) / 8) /** number of "8 MACs" lookup tables */ |
31 | | |
32 | | /* |
33 | | * Properties of this 96-tap lowpass filter when applied on a signal |
34 | | * with sampling rate of 44100*64 Hz: |
35 | | * |
36 | | * () has a delay of 17 microseconds. |
37 | | * |
38 | | * () flat response up to 48 kHz |
39 | | * |
40 | | * () if you downsample afterwards by a factor of 8, the |
41 | | * spectrum below 70 kHz is practically alias-free. |
42 | | * |
43 | | * () stopband rejection is about 160 dB |
44 | | * |
45 | | * The coefficient tables ("ctables") take only 6 Kibi Bytes and |
46 | | * should fit into a modern processor's fast cache. |
47 | | */ |
48 | | |
49 | | /** |
50 | | * The 2nd half (48 coeffs) of a 96-tap symmetric lowpass filter |
51 | | */ |
52 | | static const double htaps[HTAPS] = { |
53 | | 0.09950731974056658, 0.09562845727714668, 0.08819647126516944, |
54 | | 0.07782552527068175, 0.06534876523171299, 0.05172629311427257, |
55 | | 0.0379429484910187, 0.02490921351762261, 0.0133774746265897, |
56 | | 0.003883043418804416, -0.003284703416210726, -0.008080250212687497, |
57 | | -0.01067241812471033, -0.01139427235000863, -0.0106813877974587, |
58 | | -0.009007905078766049, -0.006828859761015335, -0.004535184322001496, |
59 | | -0.002425035959059578, -0.0006922187080790708, 0.0005700762133516592, |
60 | | 0.001353838005269448, 0.001713709169690937, 0.001742046839472948, |
61 | | 0.001545601648013235, 0.001226696225277855, 0.0008704322683580222, |
62 | | 0.0005381636200535649, 0.000266446345425276, 7.002968738383528e-05, |
63 | | -5.279407053811266e-05, -0.0001140625650874684, -0.0001304796361231895, |
64 | | -0.0001189970287491285, -9.396247155265073e-05, -6.577634378272832e-05, |
65 | | -4.07492895872535e-05, -2.17407957554587e-05, -9.163058931391722e-06, |
66 | | -2.017460145032201e-06, 1.249721855219005e-06, 2.166655190537392e-06, |
67 | | 1.930520892991082e-06, 1.319400334374195e-06, 7.410039764949091e-07, |
68 | | 3.423230509967409e-07, 1.244182214744588e-07, 3.130441005359396e-08 |
69 | | }; |
70 | | |
71 | | static double ctables_lsbf[CTABLES][256]; |
72 | | static double ctables_msbf[CTABLES][256]; |
73 | | |
74 | | static av_cold void dsd_ctables_tableinit(void) |
75 | 6 | { |
76 | 6 | int t, e, m, sign; |
77 | 6 | double acc[CTABLES]; |
78 | 1.54k | for (e = 0; e < 256; ++e) { |
79 | 1.53k | memset(acc, 0, sizeof(acc)); |
80 | 13.8k | for (m = 0; m < 8; ++m) { |
81 | 12.2k | sign = (((e >> (7 - m)) & 1) * 2 - 1); |
82 | 86.0k | for (t = 0; t < CTABLES; ++t) |
83 | 73.7k | acc[t] += sign * htaps[t * 8 + m]; |
84 | 12.2k | } |
85 | 10.7k | for (t = 0; t < CTABLES; ++t) { |
86 | 9.21k | ctables_msbf[CTABLES - 1 - t][e] = acc[t]; |
87 | 9.21k | ctables_lsbf[CTABLES - 1 - t][ff_reverse[e]] = acc[t]; |
88 | 9.21k | } |
89 | 1.53k | } |
90 | 6 | } |
91 | | |
92 | | av_cold void ff_init_dsd_data(void) |
93 | 63.2k | { |
94 | 63.2k | static AVOnce init_static_once = AV_ONCE_INIT; |
95 | 63.2k | ff_thread_once(&init_static_once, dsd_ctables_tableinit); |
96 | 63.2k | } |
97 | | |
98 | | void ff_dsd2pcm_translate(DSDContext* s, size_t samples, int lsbf, |
99 | | const uint8_t *src, ptrdiff_t src_stride, |
100 | | float *dst, ptrdiff_t dst_stride) |
101 | 2.30M | { |
102 | 2.30M | uint8_t buf[FIFOSIZE]; |
103 | 2.30M | unsigned pos, i; |
104 | 2.30M | uint8_t* p; |
105 | 2.30M | double sum; |
106 | 2.30M | const double (*const ctables)[256] = lsbf ? ctables_lsbf : ctables_msbf; |
107 | | |
108 | 2.30M | pos = s->pos; |
109 | | |
110 | 2.30M | memcpy(buf, s->buf, sizeof(buf)); |
111 | | |
112 | 93.1M | while (samples-- > 0) { |
113 | 90.7M | buf[pos] = *src; |
114 | 90.7M | src += src_stride; |
115 | | |
116 | 90.7M | p = buf + ((pos - CTABLES) & FIFOMASK); |
117 | 90.7M | *p = ff_reverse[*p]; |
118 | | |
119 | 90.7M | sum = 0.0; |
120 | 635M | for (i = 0; i < CTABLES; i++) { |
121 | 544M | uint8_t a = buf[(pos - i) & FIFOMASK]; |
122 | 544M | uint8_t b = buf[(pos - (CTABLES*2 - 1) + i) & FIFOMASK]; |
123 | 544M | sum += ctables[i][a] + ctables[i][b]; |
124 | 544M | } |
125 | | |
126 | 90.7M | *dst = (float)sum; |
127 | 90.7M | dst += dst_stride; |
128 | | |
129 | 90.7M | pos = (pos + 1) & FIFOMASK; |
130 | 90.7M | } |
131 | | |
132 | 2.30M | s->pos = pos; |
133 | 2.30M | memcpy(s->buf, buf, sizeof(buf)); |
134 | 2.30M | } |