Annotation of src/usr.bin/sndiod/dsp.h, Revision 1.1
1.1 ! ratchov 1: /* $OpenBSD$ */
! 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: /*
! 95: * Maximum size of the encording string (the longest possible
! 96: * encoding is ``s24le3msb'').
! 97: */
! 98: #define ENCMAX 10
! 99:
! 100: /*
! 101: * Default bytes per sample for the given bits per sample.
! 102: */
! 103: #define APARAMS_BPS(bits) (((bits) <= 8) ? 1 : (((bits) <= 16) ? 2 : 4))
! 104:
! 105: struct aparams {
! 106: unsigned int bps; /* bytes per sample */
! 107: unsigned int bits; /* actually used bits */
! 108: unsigned int le; /* 1 if little endian, 0 if big endian */
! 109: unsigned int sig; /* 1 if signed, 0 if unsigned */
! 110: unsigned int msb; /* 1 if msb justified, 0 if lsb justified */
! 111: };
! 112:
! 113: struct resamp {
! 114: #define RESAMP_NCTX 2
! 115: unsigned int ctx_start;
! 116: adata_t ctx[NCHAN_MAX * RESAMP_NCTX];
! 117: unsigned int iblksz, oblksz;
! 118: int diff;
! 119: int idelta, odelta; /* remainder of ipos/opos */
! 120: int nch;
! 121: };
! 122:
! 123: struct conv {
! 124: int bfirst; /* bytes to skip at startup */
! 125: unsigned int bps; /* bytes per sample */
! 126: unsigned int shift; /* shift to get 32bit MSB */
! 127: int sigbit; /* sign bits to XOR */
! 128: int bnext; /* to reach the next byte */
! 129: int snext; /* to reach the next sample */
! 130: int nch;
! 131: };
! 132:
! 133: struct cmap {
! 134: int istart;
! 135: int inext;
! 136: int onext;
! 137: int ostart;
! 138: int nch;
! 139: };
! 140:
! 141: #define MIDI_TO_ADATA(m) (aparams_ctltovol[m] << (ADATA_BITS - 16))
! 142: extern int aparams_ctltovol[128];
! 143:
! 144: void aparams_init(struct aparams *);
! 145: void aparams_log(struct aparams *);
! 146: int aparams_strtoenc(struct aparams *, char *);
! 147: int aparams_enctostr(struct aparams *, char *);
! 148: int aparams_native(struct aparams *);
! 149:
! 150: int resamp_do(struct resamp *, adata_t *, adata_t *, int);
! 151: void resamp_init(struct resamp *, unsigned int, unsigned int, int);
! 152: void enc_do(struct conv *, unsigned char *, unsigned char *, int);
! 153: void enc_sil_do(struct conv *, unsigned char *, int);
! 154: void enc_init(struct conv *, struct aparams *, int);
! 155: void dec_do(struct conv *, unsigned char *, unsigned char *, int);
! 156: void dec_init(struct conv *, struct aparams *, int);
! 157: void cmap_add(struct cmap *, void *, void *, int, int);
! 158: void cmap_copy(struct cmap *, void *, void *, int, int);
! 159: void cmap_init(struct cmap *, int, int, int, int, int, int, int, int);
! 160:
! 161: #endif /* !defined(DSP_H) */