aboutsummaryrefslogtreecommitdiffstats
path: root/include/fresample.h
blob: 1fc8824b18c113ebfb66b53aa8556115119db103 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
/* Copyright 2012 Dietrich Epp <depp@zdome.net> */
#pragma once
#include <stddef.h>
#include <string_view>
#include "../lib/param.h"
#include "../lib/filter.h"
#include "../lib/types.h"

#define LFR_PUBLIC
#if defined(LFR_IMPLEMENTATION)
# define LFR_PRIVATE
#endif

#if defined(_MSC_VER)
# define LFR_INT64 __int64
#endif

#if defined(__GNUC__)
# undef LFR_PRIVATE
# undef LFR_PUBLIC
# if defined(LFR_IMPLEMENTATION)
#  define LFR_PRIVATE __attribute__((visibility("hidden")))
#  if defined(__ELF__)
#   define LFR_PUBLIC __attribute__((visibility("protected")))
#  else
#   define LFR_PUBLIC __attribute__((visibility("default")))
#  endif
# else
#  define LFR_PUBLIC
# endif
# define LFR_INT64 long long
#endif

#if defined(_M_X64) || defined(__x86_64__)
# define LFR_CPU_X64 1
# define LFR_CPU_X86 1
#elif defined(_M_IX86) || defined(__i386__)
# define LFR_CPU_X86 1
#elif defined(__ppc64__)
# define LFR_CPU_PPC64 1
# define LFR_CPU_PPC 1
#elif defined(__ppc__)
# define LFR_CPU_PPC 1
#endif

#define LFR_LITTLE_ENDIAN 1234
#define LFR_BIG_ENDIAN 4321

#if defined(__BYTE_ORDER__)
# if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
#  define LFR_BYTE_ORDER LFR_BIG_ENDIAN
# elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#  define LFR_BYTE_ORDER LFR_LITTLE_ENDIAN
# endif
#elif defined(__BIG_ENDIAN__)
# define LFR_BYTE_ORDER LFR_BIG_ENDIAN
#elif defined(__LITTLE_ENDIAN__)
# define LFR_BYTE_ORDER LFR_LITTLE_ENDIAN
#endif

#if !defined(LFR_BYTE_ORDER)
# if defined(LFR_CPU_X86)
#  define LFR_BYTE_ORDER LFR_LITTLE_ENDIAN
# elif defined(LFR_CPU_PPC)
#  define LFR_BYTE_ORDER LFR_BIG_ENDIAN
# else
#  error "cannot determine machine byte order"
# endif
#endif

/* ========================================
   CPU features
   ======================================== */

/*
  CPU features to use or disable.
*/
enum {
#if defined(LFR_CPU_X86)
    LFR_CPUF_MMX     = (1u << 0),
    LFR_CPUF_SSE     = (1u << 1),
    LFR_CPUF_SSE2    = (1u << 2),
    LFR_CPUF_SSE3    = (1u << 3),
    LFR_CPUF_SSSE3   = (1u << 4),
    LFR_CPUF_SSE4_1  = (1u << 5),
    LFR_CPUF_SSE4_2  = (1u << 6),
#else
    LFR_CPUF_MMX     = 0u,
    LFR_CPUF_SSE     = 0u,
    LFR_CPUF_SSE2    = 0u,
    LFR_CPUF_SSE3    = 0u,
    LFR_CPUF_SSSE3   = 0u,
    LFR_CPUF_SSE4_1  = 0u,
    LFR_CPUF_SSE4_2  = 0u,
#endif

#if defined(LFR_CPU_PPC)
    LFR_CPUF_ALTIVEC = (1u << 0),
#else
    LFR_CPUF_ALTIVEC = 0u,
#endif

    LFR_CPUF_NONE = 0u,
    LFR_CPUF_ALL = 0xffffffffu
};

/*
  Information about a CPU flag.
*/
struct lfr_cpuf {
    char name[8];
    unsigned flag;
};

/*
  Array of names for the CPU features this architecture supports.
  Names are the lower case version of the flag names above, e.g.,
  LFR_CPUF_MMX becomes "mmx".  Terminated by a zeroed entry.
*/
LFR_PUBLIC extern const struct lfr_cpuf LFR_CPUF[];

/*
  Set which CPU features are allowed or disallowed.  This is primarily
  used for comparing the performance and correctness of vector
  implementations and scalar implementations.  It can also be used to
  prohibit features that your CPU supports but which your OS does not.

  Returns the CPU flags actually enabled, which will be the
  intersection of the set of allowed flags (the argument) with the set
  of features that the current CPU actually supports.
*/
LFR_PUBLIC unsigned
lfr_setcpufeatures(unsigned flags);

#if LFR_BYTE_ORDER == LFR_BIG_ENDIAN
# define LFR_FMT_S16_NATIVE LFR_FMT_S16BE
# define LFR_FMT_S16_SWAPPED LFR_FMT_S16LE
# define LFR_FMT_F32_NATIVE LFR_FMT_F32BE
# define LFR_FMT_F32_SWAPPED LFR_FMT_F32LE
#else
# define LFR_FMT_S16_NATIVE LFR_FMT_S16LE
# define LFR_FMT_S16_SWAPPED LFR_FMT_S16BE
# define LFR_FMT_F32_NATIVE LFR_FMT_F32LE
# define LFR_FMT_F32_SWAPPED LFR_FMT_F32BE
#endif

/*
  Swap the byte order on 16-bit data.  The destination can either be
  the same buffer as the source, or it can be a non-overlapping
  buffer.  Behavior is undefined if the two buffers partially overlap.
*/
LFR_PUBLIC void
lfr_swap16(void *dest, const void *src, size_t count);

/* ========================================
   Resampling parameters
   ======================================== */

/*
  Names for filter quality presets.
*/
enum {
    /*
      Low quality: Currently, quality 0..3 are identical, since
      further reductions in quality do not increase performance.
    */
    LFR_QUALITY_LOW = 2,

    /*
      Medium quality: Transition band of 23%, nominal attenuation of
      60 dB.  Actual attenuation may be higher.
    */
    LFR_QUALITY_MEDIUM = 5,

    /*
      High quality: Transition band of 10%, nominal attenuation of 96
      dB.  It is not normally reasonable to increase quality beyond
      this level unless you are competing for the prettiest
      spectrogram.
    */
    LFR_QUALITY_HIGH = 8,

    /*
      Ultra quality: Transition band of 3%, nominal attenuation of 120
      dB.  Filter coefficients may not fit in L2 cache.  Impulse
      response may be several milliseconds long.
    */
    LFR_QUALITY_ULTRA = 10
};

/*
  Get the name of a parameter, or return NULL if the paramater does
  not exist.
*/
LFR_PUBLIC std::string_view lfr_param_name(lfr_param_t pname);

/*
  Get the index of a parameter by name, or return -1 if the parameter
  does not exist.
*/
LFR_PUBLIC int lfr_param_lookup(const std::string_view& pname);

/* ========================================
   Resampling
   ======================================== */

/*
  Get the name of a filter info query, or return NULL if the info query
  does not exist.
*/
LFR_PUBLIC std::string_view
lfr_info_name(int pname);

/*
  Get the index of a filter info query by name, or return -1 if the
  info query does not exist.
*/
LFR_PUBLIC int
lfr_info_lookup(const std::string_view& pname);

/*
  Get a function for resampling native 16-bit data with the given
  number of channels.  Returns NULL if no such function is available.
  This will always return non-NULL for mono and stereo data.
*/
LFR_PUBLIC lfr_resample_func_t
lfr_resample_s16func(int nchan, const struct lfr_filter *filter);