Annotation of src/usr.bin/aucat/dsp.h, Revision 1.6
1.6 ! ratchov 1: /* $OpenBSD: dsp.h,v 1.5 2016/06/08 04:36:48 ratchov Exp $ */
1.1 ratchov 2: /*
3: * Copyright (c) 2012 Alexandre Ratchov <alex@caoua.org>
4: *
5: * Permission to use, copy, modify, and distribute this software for any
6: * purpose with or without fee is hereby granted, provided that the above
7: * copyright notice and this permission notice appear in all copies.
8: *
9: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16: */
17: #ifndef DSP_H
18: #define DSP_H
19:
20: #include <sys/types.h>
21: #include "defs.h"
22:
23: /*
24: * Samples are numbers in the interval [-1, 1[, note that 1, the upper
25: * boundary is excluded. We represent them as signed fixed point numbers
26: * of ADATA_BITS. We also assume that 2^(ADATA_BITS - 1) fits in a int.
27: */
28: #ifndef ADATA_BITS
29: #define ADATA_BITS 16
30: #endif
31: #define ADATA_LE (BYTE_ORDER == LITTLE_ENDIAN)
32: #define ADATA_UNIT (1 << (ADATA_BITS - 1))
33:
34: #if ADATA_BITS == 16
35:
36: #define ADATA_MUL(x,y) (((int)(x) * (int)(y)) >> (ADATA_BITS - 1))
37: #define ADATA_MULDIV(x,y,z) ((int)(x) * (int)(y) / (int)(z))
38:
39: typedef short adata_t;
40:
41: #elif ADATA_BITS == 24
42:
43: #if defined(__i386__) && defined(__GNUC__)
44:
45: static inline int
46: fp24_mul(int x, int a)
47: {
48: int res;
49:
50: asm volatile (
51: "imull %2\n\t"
52: "shrdl $23, %%edx, %%eax\n\t"
53: : "=a" (res)
54: : "a" (x), "r" (a)
55: : "%edx"
56: );
57: return res;
58: }
59:
60: static inline int
61: fp24_muldiv(int x, int a, int b)
62: {
63: int res;
64:
65: asm volatile (
66: "imull %2\n\t"
67: "idivl %3\n\t"
68: : "=a" (res)
69: : "a" (x), "d" (a), "r" (b)
70: );
71: return res;
72: }
73:
74: #define ADATA_MUL(x,y) fp24_mul(x, y)
75: #define ADATA_MULDIV(x,y,z) fp24_muldiv(x, y, z);
76:
77: #elif defined(__amd64__) || defined(__sparc64__)
78:
79: #define ADATA_MUL(x,y) \
80: ((int)(((long long)(x) * (long long)(y)) >> (ADATA_BITS - 1)))
81: #define ADATA_MULDIV(x,y,z) \
82: ((int)((long long)(x) * (long long)(y) / (long long)(z)))
83:
84: #else
85: #error "no 24-bit code for this architecture"
86: #endif
87:
88: typedef int adata_t;
89:
90: #else
91: #error "only 16-bit and 24-bit precisions are supported"
92: #endif
93:
94: /*
1.6 ! ratchov 95: * The FIR is sampled and stored in a table of fixed-point numbers
! 96: * with 23 fractional bits. For convenience, we use the same fixed-point
! 97: * numbers to represent time and to walk through the table.
! 98: */
! 99: #define RESAMP_BITS 23
! 100: #define RESAMP_UNIT (1 << RESAMP_BITS)
! 101:
! 102: /*
! 103: * Filter window length (the time unit is RESAMP_UNIT)
! 104: */
! 105: #define RESAMP_LENGTH (8 * RESAMP_UNIT)
! 106:
! 107: /*
! 108: * Time between samples of the FIR (the time unit is RESAMP_UNIT)
! 109: */
! 110: #define RESAMP_STEP_BITS (RESAMP_BITS - 6)
! 111: #define RESAMP_STEP (1 << RESAMP_STEP_BITS)
! 112:
! 113: /*
! 114: * Maximum downsample/upsample ratio we support, must be a power of two.
! 115: * The ratio between the max and the min sample rates is 192kHz / 4kHz = 48,
! 116: * so we can use 64
! 117: */
! 118: #define RESAMP_RATIO 64
! 119:
! 120: /*
1.1 ratchov 121: * Maximum size of the encording string (the longest possible
122: * encoding is ``s24le3msb'').
123: */
124: #define ENCMAX 10
125:
126: /*
127: * Default bytes per sample for the given bits per sample.
128: */
129: #define APARAMS_BPS(bits) (((bits) <= 8) ? 1 : (((bits) <= 16) ? 2 : 4))
130:
131: struct aparams {
132: unsigned int bps; /* bytes per sample */
133: unsigned int bits; /* actually used bits */
134: unsigned int le; /* 1 if little endian, 0 if big endian */
135: unsigned int sig; /* 1 if signed, 0 if unsigned */
136: unsigned int msb; /* 1 if msb justified, 0 if lsb justified */
137: };
138:
139: struct resamp {
1.6 ! ratchov 140: #define RESAMP_NCTX (RESAMP_LENGTH / RESAMP_UNIT * RESAMP_RATIO)
1.1 ratchov 141: unsigned int ctx_start;
142: adata_t ctx[NCHAN_MAX * RESAMP_NCTX];
1.6 ! ratchov 143: int filt_cutoff, filt_step;
1.1 ratchov 144: unsigned int iblksz, oblksz;
145: int diff;
146: int nch;
147: };
148:
149: struct conv {
150: int bfirst; /* bytes to skip at startup */
151: unsigned int bps; /* bytes per sample */
152: unsigned int shift; /* shift to get 32bit MSB */
153: unsigned int bias; /* bias of unsigned samples */
154: int bnext; /* to reach the next byte */
155: int snext; /* to reach the next sample */
156: int nch;
157: };
158:
159: struct cmap {
160: int istart;
161: int inext;
162: int onext;
163: int ostart;
164: int nch;
165: };
166:
167: #define MIDI_TO_ADATA(m) (aparams_ctltovol[m] << (ADATA_BITS - 16))
168: extern int aparams_ctltovol[128];
169:
170: void aparams_init(struct aparams *);
171: void aparams_log(struct aparams *);
172: int aparams_strtoenc(struct aparams *, char *);
173: int aparams_enctostr(struct aparams *, char *);
174: int aparams_native(struct aparams *);
175:
1.4 ratchov 176: void resamp_getcnt(struct resamp *, int *, int *);
1.3 ratchov 177: void resamp_do(struct resamp *, adata_t *, adata_t *, int, int);
1.1 ratchov 178: void resamp_init(struct resamp *, unsigned int, unsigned int, int);
179: void enc_do(struct conv *, unsigned char *, unsigned char *, int);
180: void enc_sil_do(struct conv *, unsigned char *, int);
181: void enc_init(struct conv *, struct aparams *, int);
182: void dec_do(struct conv *, unsigned char *, unsigned char *, int);
183: void dec_do_float(struct conv *, unsigned char *, unsigned char *, int);
184: void dec_do_ulaw(struct conv *, unsigned char *, unsigned char *, int, int);
185: void dec_init(struct conv *, struct aparams *, int);
186: void cmap_add(struct cmap *, void *, void *, int, int);
187: void cmap_copy(struct cmap *, void *, void *, int, int);
188: void cmap_init(struct cmap *, int, int, int, int, int, int, int, int);
189:
190: #endif /* !defined(DSP_H) */