📄 trans_16.c
字号:
/* * linux/sound/oss/dmasound/trans_16.c * * 16 bit translation routines. Only used by Power mac at present. * * See linux/sound/oss/dmasound/dmasound_core.c for copyright and * history prior to 08/02/2001. * * 08/02/2001 Iain Sandoe * split from dmasound_awacs.c * 11/29/2003 Renzo Davoli (King Enzo) * - input resampling (for soft rate < hard rate) * - software line in gain control */#include <linux/soundcard.h>#include <asm/uaccess.h>#include "dmasound.h"static short dmasound_alaw2dma16[] ;static short dmasound_ulaw2dma16[] ;static ssize_t pmac_ct_law(const u_char __user *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft);static ssize_t pmac_ct_s8(const u_char __user *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft);static ssize_t pmac_ct_u8(const u_char __user *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft);static ssize_t pmac_ct_s16(const u_char __user *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft);static ssize_t pmac_ct_u16(const u_char __user *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft);static ssize_t pmac_ctx_law(const u_char __user *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft);static ssize_t pmac_ctx_s8(const u_char __user *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft);static ssize_t pmac_ctx_u8(const u_char __user *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft);static ssize_t pmac_ctx_s16(const u_char __user *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft);static ssize_t pmac_ctx_u16(const u_char __user *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft);static ssize_t pmac_ct_s16_read(const u_char __user *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft);static ssize_t pmac_ct_u16_read(const u_char __user *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft);/*** Translations ************************************************************/static int expand_data; /* Data for expanding */static ssize_t pmac_ct_law(const u_char __user *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft){ short *table = dmasound.soft.format == AFMT_MU_LAW ? dmasound_ulaw2dma16 : dmasound_alaw2dma16; ssize_t count, used; short *p = (short *) &frame[*frameUsed]; int val, stereo = dmasound.soft.stereo; frameLeft >>= 2; if (stereo) userCount >>= 1; used = count = min_t(unsigned long, userCount, frameLeft); while (count > 0) { u_char data; if (get_user(data, userPtr++)) return -EFAULT; val = table[data]; *p++ = val; if (stereo) { if (get_user(data, userPtr++)) return -EFAULT; val = table[data]; } *p++ = val; count--; } *frameUsed += used * 4; return stereo? used * 2: used;}static ssize_t pmac_ct_s8(const u_char __user *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft){ ssize_t count, used; short *p = (short *) &frame[*frameUsed]; int val, stereo = dmasound.soft.stereo; frameLeft >>= 2; if (stereo) userCount >>= 1; used = count = min_t(unsigned long, userCount, frameLeft); while (count > 0) { u_char data; if (get_user(data, userPtr++)) return -EFAULT; val = data << 8; *p++ = val; if (stereo) { if (get_user(data, userPtr++)) return -EFAULT; val = data << 8; } *p++ = val; count--; } *frameUsed += used * 4; return stereo? used * 2: used;}static ssize_t pmac_ct_u8(const u_char __user *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft){ ssize_t count, used; short *p = (short *) &frame[*frameUsed]; int val, stereo = dmasound.soft.stereo; frameLeft >>= 2; if (stereo) userCount >>= 1; used = count = min_t(unsigned long, userCount, frameLeft); while (count > 0) { u_char data; if (get_user(data, userPtr++)) return -EFAULT; val = (data ^ 0x80) << 8; *p++ = val; if (stereo) { if (get_user(data, userPtr++)) return -EFAULT; val = (data ^ 0x80) << 8; } *p++ = val; count--; } *frameUsed += used * 4; return stereo? used * 2: used;}static ssize_t pmac_ct_s16(const u_char __user *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft){ ssize_t count, used; int stereo = dmasound.soft.stereo; short *fp = (short *) &frame[*frameUsed]; frameLeft >>= 2; userCount >>= (stereo? 2: 1); used = count = min_t(unsigned long, userCount, frameLeft); if (!stereo) { short __user *up = (short __user *) userPtr; while (count > 0) { short data; if (get_user(data, up++)) return -EFAULT; *fp++ = data; *fp++ = data; count--; } } else { if (copy_from_user(fp, userPtr, count * 4)) return -EFAULT; } *frameUsed += used * 4; return stereo? used * 4: used * 2;}static ssize_t pmac_ct_u16(const u_char __user *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft){ ssize_t count, used; int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000); int stereo = dmasound.soft.stereo; short *fp = (short *) &frame[*frameUsed]; short __user *up = (short __user *) userPtr; frameLeft >>= 2; userCount >>= (stereo? 2: 1); used = count = min_t(unsigned long, userCount, frameLeft); while (count > 0) { short data; if (get_user(data, up++)) return -EFAULT; data ^= mask; *fp++ = data; if (stereo) { if (get_user(data, up++)) return -EFAULT; data ^= mask; } *fp++ = data; count--; } *frameUsed += used * 4; return stereo? used * 4: used * 2;}static ssize_t pmac_ctx_law(const u_char __user *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft){ unsigned short *table = (unsigned short *) (dmasound.soft.format == AFMT_MU_LAW ? dmasound_ulaw2dma16 : dmasound_alaw2dma16); unsigned int data = expand_data; unsigned int *p = (unsigned int *) &frame[*frameUsed]; int bal = expand_bal; int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed; int utotal, ftotal; int stereo = dmasound.soft.stereo; frameLeft >>= 2; if (stereo) userCount >>= 1; ftotal = frameLeft; utotal = userCount; while (frameLeft) { u_char c; if (bal < 0) { if (userCount == 0) break; if (get_user(c, userPtr++)) return -EFAULT; data = table[c]; if (stereo) { if (get_user(c, userPtr++)) return -EFAULT; data = (data << 16) + table[c]; } else data = (data << 16) + data; userCount--; bal += hSpeed; } *p++ = data; frameLeft--; bal -= sSpeed; } expand_bal = bal; expand_data = data; *frameUsed += (ftotal - frameLeft) * 4; utotal -= userCount; return stereo? utotal * 2: utotal;}static ssize_t pmac_ctx_s8(const u_char __user *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft){ unsigned int *p = (unsigned int *) &frame[*frameUsed]; unsigned int data = expand_data; int bal = expand_bal; int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed; int stereo = dmasound.soft.stereo; int utotal, ftotal; frameLeft >>= 2; if (stereo) userCount >>= 1; ftotal = frameLeft; utotal = userCount; while (frameLeft) { u_char c; if (bal < 0) { if (userCount == 0) break; if (get_user(c, userPtr++)) return -EFAULT; data = c << 8; if (stereo) { if (get_user(c, userPtr++)) return -EFAULT; data = (data << 16) + (c << 8); } else data = (data << 16) + data; userCount--; bal += hSpeed; } *p++ = data; frameLeft--; bal -= sSpeed; } expand_bal = bal; expand_data = data; *frameUsed += (ftotal - frameLeft) * 4; utotal -= userCount; return stereo? utotal * 2: utotal;}static ssize_t pmac_ctx_u8(const u_char __user *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft){ unsigned int *p = (unsigned int *) &frame[*frameUsed]; unsigned int data = expand_data; int bal = expand_bal; int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed; int stereo = dmasound.soft.stereo; int utotal, ftotal; frameLeft >>= 2; if (stereo) userCount >>= 1; ftotal = frameLeft; utotal = userCount; while (frameLeft) { u_char c; if (bal < 0) { if (userCount == 0) break; if (get_user(c, userPtr++)) return -EFAULT; data = (c ^ 0x80) << 8; if (stereo) { if (get_user(c, userPtr++)) return -EFAULT; data = (data << 16) + ((c ^ 0x80) << 8); } else data = (data << 16) + data; userCount--; bal += hSpeed; } *p++ = data; frameLeft--; bal -= sSpeed; } expand_bal = bal; expand_data = data; *frameUsed += (ftotal - frameLeft) * 4; utotal -= userCount; return stereo? utotal * 2: utotal;}static ssize_t pmac_ctx_s16(const u_char __user *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft){ unsigned int *p = (unsigned int *) &frame[*frameUsed]; unsigned int data = expand_data; unsigned short __user *up = (unsigned short __user *) userPtr; int bal = expand_bal; int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed; int stereo = dmasound.soft.stereo; int utotal, ftotal; frameLeft >>= 2; userCount >>= (stereo? 2: 1); ftotal = frameLeft; utotal = userCount; while (frameLeft) { unsigned short c; if (bal < 0) { if (userCount == 0) break; if (get_user(data, up++)) return -EFAULT; if (stereo) { if (get_user(c, up++)) return -EFAULT; data = (data << 16) + c; } else data = (data << 16) + data; userCount--; bal += hSpeed; } *p++ = data; frameLeft--; bal -= sSpeed; } expand_bal = bal; expand_data = data; *frameUsed += (ftotal - frameLeft) * 4; utotal -= userCount; return stereo? utotal * 4: utotal * 2;}static ssize_t pmac_ctx_u16(const u_char __user *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft){ int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000); unsigned int *p = (unsigned int *) &frame[*frameUsed]; unsigned int data = expand_data; unsigned short __user *up = (unsigned short __user *) userPtr; int bal = expand_bal; int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed; int stereo = dmasound.soft.stereo; int utotal, ftotal; frameLeft >>= 2; userCount >>= (stereo? 2: 1); ftotal = frameLeft; utotal = userCount; while (frameLeft) { unsigned short c; if (bal < 0) { if (userCount == 0) break; if (get_user(data, up++)) return -EFAULT; data ^= mask; if (stereo) { if (get_user(c, up++)) return -EFAULT; data = (data << 16) + (c ^ mask); } else data = (data << 16) + data; userCount--; bal += hSpeed; } *p++ = data; frameLeft--; bal -= sSpeed; } expand_bal = bal; expand_data = data; *frameUsed += (ftotal - frameLeft) * 4; utotal -= userCount; return stereo? utotal * 4: utotal * 2;}/* data in routines... */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -