📄 pcm.c
字号:
/*** Copyright (C) 1999-2004 Erik de Castro Lopo <erikd@mega-nerd.com>**** This program is free software; you can redistribute it and/or modify** it under the terms of the GNU Lesser General Public License as published by** the Free Software Foundation; either version 2.1 of the License, or** (at your option) any later version.**** This program is distributed in the hope that it will be useful,** but WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the** GNU Lesser General Public License for more details.**** You should have received a copy of the GNU Lesser General Public License** along with this program; if not, write to the Free Software** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.*/#include "sndfile.h"#include "config.h"#include "sfendian.h"#include "float_cast.h"#include "common.h"/* Need to be able to handle 3 byte (24 bit) integers. So defined a** type and use SIZEOF_TRIBYTE instead of (tribyte).*/typedef void tribyte ;#define SIZEOF_TRIBYTE 3static sf_count_t pcm_read_sc2s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;static sf_count_t pcm_read_uc2s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;static sf_count_t pcm_read_bes2s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;static sf_count_t pcm_read_les2s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;static sf_count_t pcm_read_bet2s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;static sf_count_t pcm_read_let2s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;static sf_count_t pcm_read_bei2s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;static sf_count_t pcm_read_lei2s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;static sf_count_t pcm_read_sc2i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;static sf_count_t pcm_read_uc2i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;static sf_count_t pcm_read_bes2i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;static sf_count_t pcm_read_les2i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;static sf_count_t pcm_read_bet2i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;static sf_count_t pcm_read_let2i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;static sf_count_t pcm_read_bei2i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;static sf_count_t pcm_read_lei2i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;static sf_count_t pcm_read_sc2f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;static sf_count_t pcm_read_uc2f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;static sf_count_t pcm_read_bes2f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;static sf_count_t pcm_read_les2f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;static sf_count_t pcm_read_bet2f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;static sf_count_t pcm_read_let2f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;static sf_count_t pcm_read_bei2f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;static sf_count_t pcm_read_lei2f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;static sf_count_t pcm_read_sc2d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;static sf_count_t pcm_read_uc2d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;static sf_count_t pcm_read_bes2d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;static sf_count_t pcm_read_les2d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;static sf_count_t pcm_read_bet2d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;static sf_count_t pcm_read_let2d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;static sf_count_t pcm_read_bei2d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;static sf_count_t pcm_read_lei2d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;static sf_count_t pcm_write_s2sc (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;static sf_count_t pcm_write_s2uc (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;static sf_count_t pcm_write_s2bes (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;static sf_count_t pcm_write_s2les (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;static sf_count_t pcm_write_s2bet (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;static sf_count_t pcm_write_s2let (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;static sf_count_t pcm_write_s2bei (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;static sf_count_t pcm_write_s2lei (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;static sf_count_t pcm_write_i2sc (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;static sf_count_t pcm_write_i2uc (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;static sf_count_t pcm_write_i2bes (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;static sf_count_t pcm_write_i2les (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;static sf_count_t pcm_write_i2bet (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;static sf_count_t pcm_write_i2let (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;static sf_count_t pcm_write_i2bei (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;static sf_count_t pcm_write_i2lei (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;static sf_count_t pcm_write_f2sc (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;static sf_count_t pcm_write_f2uc (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;static sf_count_t pcm_write_f2bes (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;static sf_count_t pcm_write_f2les (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;static sf_count_t pcm_write_f2bet (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;static sf_count_t pcm_write_f2let (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;static sf_count_t pcm_write_f2bei (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;static sf_count_t pcm_write_f2lei (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;static sf_count_t pcm_write_d2sc (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;static sf_count_t pcm_write_d2uc (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;static sf_count_t pcm_write_d2bes (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;static sf_count_t pcm_write_d2les (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;static sf_count_t pcm_write_d2bet (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;static sf_count_t pcm_write_d2let (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;static sf_count_t pcm_write_d2bei (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;static sf_count_t pcm_write_d2lei (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;/*-----------------------------------------------------------------------------------------------*/enum{ /* Char type for 8 bit files. */ SF_CHARS_SIGNED = 200, SF_CHARS_UNSIGNED = 201} ;/*-----------------------------------------------------------------------------------------------*/intpcm_init (SF_PRIVATE *psf){ int chars = 0 ; if (psf->bytewidth == 0 || psf->sf.channels == 0) return SFE_INTERNAL ; psf->blockwidth = psf->bytewidth * psf->sf.channels ; if ((psf->sf.format & SF_FORMAT_SUBMASK) == SF_FORMAT_PCM_S8) chars = SF_CHARS_SIGNED ; else if ((psf->sf.format & SF_FORMAT_SUBMASK) == SF_FORMAT_PCM_U8) chars = SF_CHARS_UNSIGNED ; if (psf->mode == SFM_READ || psf->mode == SFM_RDWR) { switch (psf->bytewidth * 0x10000 + psf->endian + chars) { case (0x10000 + SF_ENDIAN_BIG + SF_CHARS_SIGNED) : case (0x10000 + SF_ENDIAN_LITTLE + SF_CHARS_SIGNED) : psf->read_short = pcm_read_sc2s ; psf->read_int = pcm_read_sc2i ; psf->read_float = pcm_read_sc2f ; psf->read_double = pcm_read_sc2d ; break ; case (0x10000 + SF_ENDIAN_BIG + SF_CHARS_UNSIGNED) : case (0x10000 + SF_ENDIAN_LITTLE + SF_CHARS_UNSIGNED) : psf->read_short = pcm_read_uc2s ; psf->read_int = pcm_read_uc2i ; psf->read_float = pcm_read_uc2f ; psf->read_double = pcm_read_uc2d ; break ; case (2 * 0x10000 + SF_ENDIAN_BIG) : psf->read_short = pcm_read_bes2s ; psf->read_int = pcm_read_bes2i ; psf->read_float = pcm_read_bes2f ; psf->read_double = pcm_read_bes2d ; break ; case (3 * 0x10000 + SF_ENDIAN_BIG) : psf->read_short = pcm_read_bet2s ; psf->read_int = pcm_read_bet2i ; psf->read_float = pcm_read_bet2f ; psf->read_double = pcm_read_bet2d ; break ; case (4 * 0x10000 + SF_ENDIAN_BIG) : psf->read_short = pcm_read_bei2s ; psf->read_int = pcm_read_bei2i ; psf->read_float = pcm_read_bei2f ; psf->read_double = pcm_read_bei2d ; break ; case (2 * 0x10000 + SF_ENDIAN_LITTLE) : psf->read_short = pcm_read_les2s ; psf->read_int = pcm_read_les2i ; psf->read_float = pcm_read_les2f ; psf->read_double = pcm_read_les2d ; break ; case (3 * 0x10000 + SF_ENDIAN_LITTLE) : psf->read_short = pcm_read_let2s ; psf->read_int = pcm_read_let2i ; psf->read_float = pcm_read_let2f ; psf->read_double = pcm_read_let2d ; break ; case (4 * 0x10000 + SF_ENDIAN_LITTLE) : psf->read_short = pcm_read_lei2s ; psf->read_int = pcm_read_lei2i ; psf->read_float = pcm_read_lei2f ; psf->read_double = pcm_read_lei2d ; break ; default : psf_log_printf (psf, "pcm.c returning SFE_UNIMPLEMENTED\n") ; return SFE_UNIMPLEMENTED ; } ; } ; if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR) { switch (psf->bytewidth * 0x10000 + psf->endian + chars) { case (0x10000 + SF_ENDIAN_BIG + SF_CHARS_SIGNED) : case (0x10000 + SF_ENDIAN_LITTLE + SF_CHARS_SIGNED) : psf->write_short = pcm_write_s2sc ; psf->write_int = pcm_write_i2sc ; psf->write_float = pcm_write_f2sc ; psf->write_double = pcm_write_d2sc ; break ; case (0x10000 + SF_ENDIAN_BIG + SF_CHARS_UNSIGNED) : case (0x10000 + SF_ENDIAN_LITTLE + SF_CHARS_UNSIGNED) : psf->write_short = pcm_write_s2uc ; psf->write_int = pcm_write_i2uc ; psf->write_float = pcm_write_f2uc ; psf->write_double = pcm_write_d2uc ; break ; case (2 * 0x10000 + SF_ENDIAN_BIG) : psf->write_short = pcm_write_s2bes ; psf->write_int = pcm_write_i2bes ; psf->write_float = pcm_write_f2bes ; psf->write_double = pcm_write_d2bes ; break ; case (3 * 0x10000 + SF_ENDIAN_BIG) : psf->write_short = pcm_write_s2bet ; psf->write_int = pcm_write_i2bet ; psf->write_float = pcm_write_f2bet ; psf->write_double = pcm_write_d2bet ; break ; case (4 * 0x10000 + SF_ENDIAN_BIG) : psf->write_short = pcm_write_s2bei ; psf->write_int = pcm_write_i2bei ; psf->write_float = pcm_write_f2bei ; psf->write_double = pcm_write_d2bei ; break ; case (2 * 0x10000 + SF_ENDIAN_LITTLE) : psf->write_short = pcm_write_s2les ; psf->write_int = pcm_write_i2les ; psf->write_float = pcm_write_f2les ; psf->write_double = pcm_write_d2les ; break ; case (3 * 0x10000 + SF_ENDIAN_LITTLE) : psf->write_short = pcm_write_s2let ; psf->write_int = pcm_write_i2let ; psf->write_float = pcm_write_f2let ; psf->write_double = pcm_write_d2let ; break ; case (4 * 0x10000 + SF_ENDIAN_LITTLE) : psf->write_short = pcm_write_s2lei ; psf->write_int = pcm_write_i2lei ; psf->write_float = pcm_write_f2lei ; psf->write_double = pcm_write_d2lei ; break ; default : psf_log_printf (psf, "pcm.c returning SFE_UNIMPLEMENTED\n") ; return SFE_UNIMPLEMENTED ; } ; } ; if (psf->filelength > psf->dataoffset) { psf->datalength = (psf->dataend > 0) ? psf->dataend - psf->dataoffset : psf->filelength - psf->dataoffset ; } else psf->datalength = 0 ; psf->sf.frames = psf->datalength / psf->blockwidth ; return 0 ;} /* pcm_init *//*==============================================================================*/static inline voidsc2s_array (signed char *src, int count, short *dest){ while (--count >= 0) { dest [count] = src [count] << 8 ; } ;} /* sc2s_array */static inline voiduc2s_array (unsigned char *src, int count, short *dest){ while (--count >= 0) { dest [count] = (((short) src [count]) - 0x80) << 8 ; } ;} /* uc2s_array */static inline voidlet2s_array (tribyte *src, int count, short *dest){ unsigned char *ucptr ; ucptr = ((unsigned char*) src) + 3 * count ; while (--count >= 0) { ucptr -= 3 ; dest [count] = LET2H_SHORT_PTR (ucptr) ; } ;} /* let2s_array */static inline voidbet2s_array (tribyte *src, int count, short *dest){ unsigned char *ucptr ; ucptr = ((unsigned char*) src) + 3 * count ; while (--count >= 0) { ucptr -= 3 ; dest [count] = BET2H_SHORT_PTR (ucptr) ; } ;} /* bet2s_array */static inline voidlei2s_array (int *src, int count, short *dest){ int value ; while (--count >= 0) { value = LEI2H_INT (src [count]) ; dest [count] = value >> 16 ; } ;} /* lei2s_array */static inline voidbei2s_array (int *src, int count, short *dest){ int value ; while (--count >= 0) { value = BEI2H_INT (src [count]) ; dest [count] = value >> 16 ; } ;} /* bei2s_array *//*--------------------------------------------------------------------------*/static inline voidsc2i_array (signed char *src, int count, int *dest){ while (--count >= 0) { dest [count] = ((int) src [count]) << 24 ; } ;} /* sc2i_array */static inline voiduc2i_array (unsigned char *src, int count, int *dest){ while (--count >= 0) { dest [count] = (((int) src [count]) - 128) << 24 ; } ;} /* uc2i_array */static inline voidbes2i_array (short *src, int count, int *dest){ short value ; while (--count >= 0) { value = BES2H_SHORT (src [count]) ; dest [count] = value << 16 ; } ;} /* bes2i_array */static inline voidles2i_array (short *src, int count, int *dest){ short value ; while (--count >= 0) { value = LES2H_SHORT (src [count]) ; dest [count] = value << 16 ; } ;} /* les2i_array */static inline voidbet2i_array (tribyte *src, int count, int *dest){ unsigned char *ucptr ; ucptr = ((unsigned char*) src) + 3 * count ; while (--count >= 0) { ucptr -= 3 ; dest [count] = BET2H_INT_PTR (ucptr) ; } ;} /* bet2i_array */static inline voidlet2i_array (tribyte *src, int count, int *dest){ unsigned char *ucptr ; ucptr = ((unsigned char*) src) + 3 * count ; while (--count >= 0) { ucptr -= 3 ; dest [count] = LET2H_INT_PTR (ucptr) ; } ;} /* let2i_array *//*--------------------------------------------------------------------------*/static inline voidsc2f_array (signed char *src, int count, float *dest, float normfact){ while (--count >= 0) dest [count] = ((float) src [count]) * normfact ;} /* sc2f_array */static inline voiduc2f_array (unsigned char *src, int count, float *dest, float normfact){ while (--count >= 0) dest [count] = (((int) src [count]) - 128) * normfact ;} /* uc2f_array */static inline voidles2f_array (short *src, int count, float *dest, float normfact){ short value ; while (--count >= 0) { value = src [count] ; value = LES2H_SHORT (value) ; dest [count] = ((float) value) * normfact ; } ;} /* les2f_array */static inline voidbes2f_array (short *src, int count, float *dest, float normfact){ short value ; while (--count >= 0) { value = src [count] ; value = BES2H_SHORT (value) ; dest [count] = ((float) value) * normfact ; } ;} /* bes2f_array */static inline voidlet2f_array (tribyte *src, int count, float *dest, float normfact){ unsigned char *ucptr ; int value ; ucptr = ((unsigned char*) src) + 3 * count ; while (--count >= 0) { ucptr -= 3 ; value = LET2H_INT_PTR (ucptr) ; dest [count] = ((float) value) * normfact ; } ;} /* let2f_array */static inline voidbet2f_array (tribyte *src, int count, float *dest, float normfact){ unsigned char *ucptr ; int value ; ucptr = ((unsigned char*) src) + 3 * count ; while (--count >= 0) { ucptr -= 3 ; value = BET2H_INT_PTR (ucptr) ; dest [count] = ((float) value) * normfact ; } ;} /* bet2f_array */static inline voidlei2f_array (int *src, int count, float *dest, float normfact){ int value ; while (--count >= 0) { value = src [count] ; value = LEI2H_INT (value) ; dest [count] = ((float) value) * normfact ; } ;} /* lei2f_array */static inline voidbei2f_array (int *src, int count, float *dest, float normfact){ int value ; while (--count >= 0) { value = src [count] ; value = BEI2H_INT (value) ; dest [count] = ((float) value) * normfact ; } ;} /* bei2f_array *//*--------------------------------------------------------------------------*/static inline voidsc2d_array (signed char *src, int count, double *dest, double normfact){ while (--count >= 0) dest [count] = ((double) src [count]) * normfact ;} /* sc2d_array */static inline void
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -