⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gsm610.c

📁 Audacity是一款用於錄音和編輯聲音的、免費的開放源碼軟體。它可以執行於Mac OS X、Microsoft Windows、GNU/Linux和其它作業系統
💻 C
📖 第 1 页 / 共 2 页
字号:
/*** 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 "config.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include "sndfile.h"#include "sfendian.h"#include "float_cast.h"#include "common.h"#include "wav_w64.h"#include "GSM610/gsm.h"#define	GSM610_BLOCKSIZE		33#define	GSM610_SAMPLES			160typedef struct gsm610_tag{	int				blocks ;	int				blockcount, samplecount ;	int				samplesperblock, blocksize ;	int				(*decode_block)	(SF_PRIVATE *psf, struct gsm610_tag *pgsm610) ;	int				(*encode_block)	(SF_PRIVATE *psf, struct gsm610_tag *pgsm610) ;	short			samples [WAV_W64_GSM610_SAMPLES] ;	unsigned char	block [WAV_W64_GSM610_BLOCKSIZE] ;	gsm				gsm_data ;} GSM610_PRIVATE ;static sf_count_t	gsm610_read_s	(SF_PRIVATE *psf, short *ptr, sf_count_t len) ;static sf_count_t	gsm610_read_i	(SF_PRIVATE *psf, int *ptr, sf_count_t len) ;static sf_count_t	gsm610_read_f	(SF_PRIVATE *psf, float *ptr, sf_count_t len) ;static sf_count_t	gsm610_read_d	(SF_PRIVATE *psf, double *ptr, sf_count_t len) ;static sf_count_t	gsm610_write_s	(SF_PRIVATE *psf, short *ptr, sf_count_t len) ;static sf_count_t	gsm610_write_i	(SF_PRIVATE *psf, int *ptr, sf_count_t len) ;static sf_count_t	gsm610_write_f	(SF_PRIVATE *psf, float *ptr, sf_count_t len) ;static sf_count_t	gsm610_write_d	(SF_PRIVATE *psf, double *ptr, sf_count_t len) ;static	int gsm610_read_block	(SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610, short *ptr, int len) ;static	int gsm610_write_block	(SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610, short *ptr, int len) ;static	int	gsm610_decode_block	(SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610) ;static	int	gsm610_encode_block	(SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610) ;static	int	gsm610_wav_decode_block	(SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610) ;static	int	gsm610_wav_encode_block	(SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610) ;static sf_count_t	gsm610_seek	(SF_PRIVATE *psf, int mode, sf_count_t offset) ;static int	gsm610_close	(SF_PRIVATE *psf) ;/*============================================================================================** WAV GSM610 initialisation function.*/intgsm610_init	(SF_PRIVATE *psf){	GSM610_PRIVATE	*pgsm610 ;	int		true_flag = 1 ;	if (psf->mode == SFM_RDWR)		return SFE_BAD_MODE_RW ;	psf->sf.seekable = SF_FALSE ;	if (! (pgsm610 = malloc (sizeof (GSM610_PRIVATE))))		return SFE_MALLOC_FAILED ;	psf->fdata = (void*) pgsm610 ;	memset (pgsm610, 0, sizeof (GSM610_PRIVATE)) ;/*============================================================Need separate gsm_data structs for encode and decode.============================================================*/	if (! (pgsm610->gsm_data = gsm_create ()))		return SFE_MALLOC_FAILED ;	if ((psf->sf.format & SF_FORMAT_TYPEMASK) == SF_FORMAT_WAV ||				(psf->sf.format & SF_FORMAT_TYPEMASK) == SF_FORMAT_W64)	{	gsm_option (pgsm610->gsm_data, GSM_OPT_WAV49, &true_flag) ;		pgsm610->encode_block = gsm610_wav_encode_block ;		pgsm610->decode_block = gsm610_wav_decode_block ;		pgsm610->samplesperblock = WAV_W64_GSM610_SAMPLES ;		pgsm610->blocksize = WAV_W64_GSM610_BLOCKSIZE ;		}	else	{	pgsm610->encode_block = gsm610_encode_block ;		pgsm610->decode_block = gsm610_decode_block ;		pgsm610->samplesperblock = GSM610_SAMPLES ;		pgsm610->blocksize = GSM610_BLOCKSIZE ;		} ;	if (psf->mode == SFM_READ)	{	if (psf->datalength % pgsm610->blocksize)		{	psf_log_printf (psf, "*** Warning : data chunk seems to be truncated.\n") ;			pgsm610->blocks = psf->datalength / pgsm610->blocksize + 1 ;			}		else			pgsm610->blocks = psf->datalength / pgsm610->blocksize ;		psf->sf.frames = pgsm610->samplesperblock * pgsm610->blocks ;		pgsm610->decode_block (psf, pgsm610) ;	/* Read first block. */		psf->read_short		= gsm610_read_s ;		psf->read_int		= gsm610_read_i ;		psf->read_float		= gsm610_read_f ;		psf->read_double	= gsm610_read_d ;		} ;	if (psf->mode == SFM_WRITE)	{	pgsm610->blockcount = 0 ;		pgsm610->samplecount = 0 ;		psf->write_short	= gsm610_write_s ;		psf->write_int		= gsm610_write_i ;		psf->write_float	= gsm610_write_f ;		psf->write_double	= gsm610_write_d ;		} ;	psf->close = gsm610_close ;	psf->seek = gsm610_seek ;	psf->filelength = psf_get_filelen (psf) ;	psf->datalength = psf->filelength - psf->dataoffset ;	return 0 ;} /* gsm610_init *//*============================================================================================** GSM 6.10 Read Functions.*/static intgsm610_wav_decode_block	(SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610){	int	k ;	pgsm610->blockcount ++ ;	pgsm610->samplecount = 0 ;	if (pgsm610->blockcount > pgsm610->blocks)	{	memset (pgsm610->samples, 0, WAV_W64_GSM610_SAMPLES * sizeof (short)) ;		return 1 ;		} ;	if ((k = psf_fread (pgsm610->block, 1, WAV_W64_GSM610_BLOCKSIZE, psf)) != WAV_W64_GSM610_BLOCKSIZE)		psf_log_printf (psf, "*** Warning : short read (%d != %d).\n", k, WAV_W64_GSM610_BLOCKSIZE) ;	if (gsm_decode (pgsm610->gsm_data, pgsm610->block, pgsm610->samples) < 0)	{	psf_log_printf (psf, "Error from gsm_decode() on frame : %d\n", pgsm610->blockcount) ;		return 0 ;		} ;	if (gsm_decode (pgsm610->gsm_data, pgsm610->block + (WAV_W64_GSM610_BLOCKSIZE + 1) / 2, pgsm610->samples + WAV_W64_GSM610_SAMPLES / 2) < 0)	{	psf_log_printf (psf, "Error from gsm_decode() on frame : %d.5\n", pgsm610->blockcount) ;		return 0 ;		} ;	return 1 ;} /* gsm610_wav_decode_block */static intgsm610_decode_block	(SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610){	int	k ;	pgsm610->blockcount ++ ;	pgsm610->samplecount = 0 ;	if (pgsm610->blockcount > pgsm610->blocks)	{	memset (pgsm610->samples, 0, GSM610_SAMPLES * sizeof (short)) ;		return 1 ;		} ;	if ((k = psf_fread (pgsm610->block, 1, GSM610_BLOCKSIZE, psf)) != GSM610_BLOCKSIZE)		psf_log_printf (psf, "*** Warning : short read (%d != %d).\n", k, GSM610_BLOCKSIZE) ;	if (gsm_decode (pgsm610->gsm_data, pgsm610->block, pgsm610->samples) < 0)	{	psf_log_printf (psf, "Error from gsm_decode() on frame : %d\n", pgsm610->blockcount) ;		return 0 ;		} ;	return 1 ;} /* gsm610_decode_block */static intgsm610_read_block	(SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610, short *ptr, int len){	int	count, total = 0, indx = 0 ;	while (indx < len)	{	if (pgsm610->blockcount >= pgsm610->blocks && pgsm610->samplecount >= pgsm610->samplesperblock)		{	memset (&(ptr [indx]), 0, (size_t) ((len - indx) * sizeof (short))) ;			return total ;			} ;		if (pgsm610->samplecount >= pgsm610->samplesperblock)			pgsm610->decode_block (psf, pgsm610) ;		count = pgsm610->samplesperblock - pgsm610->samplecount ;		count = (len - indx > count) ? count : len - indx ;		memcpy (&(ptr [indx]), &(pgsm610->samples [pgsm610->samplecount]), count * sizeof (short)) ;		indx += count ;		pgsm610->samplecount += count ;		total = indx ;		} ;	return total ;} /* gsm610_read_block */static sf_count_tgsm610_read_s	(SF_PRIVATE *psf, short *ptr, sf_count_t len){	GSM610_PRIVATE 	*pgsm610 ;	int			readcount, count ;	sf_count_t	total = 0 ;	if (! psf->fdata)		return 0 ;	pgsm610 = (GSM610_PRIVATE*) psf->fdata ;	while (len > 0)	{	readcount = (len > 0x10000000) ? 0x1000000 : (int) len ;		count = gsm610_read_block (psf, pgsm610, ptr, readcount) ;		total += count ;		len -= count ;		if (count != readcount)			break ;		} ;	return total ;} /* gsm610_read_s */static sf_count_tgsm610_read_i	(SF_PRIVATE *psf, int *ptr, sf_count_t len){	GSM610_PRIVATE *pgsm610 ;	short		*sptr ;	int			k, bufferlen, readcount = 0, count ;	sf_count_t	total = 0 ;	if (! psf->fdata)		return 0 ;	pgsm610 = (GSM610_PRIVATE*) psf->fdata ;	sptr = psf->u.sbuf ;	bufferlen = ARRAY_LEN (psf->u.sbuf) ;	while (len > 0)	{	readcount = (len >= bufferlen) ? bufferlen : len ;		count = gsm610_read_block (psf, pgsm610, sptr, readcount) ;		for (k = 0 ; k < readcount ; k++)			ptr [total + k] = sptr [k] << 16 ;		total += count ;		len -= readcount ;		} ;	return total ;} /* gsm610_read_i */static sf_count_tgsm610_read_f	(SF_PRIVATE *psf, float *ptr, sf_count_t len){	GSM610_PRIVATE *pgsm610 ;	short		*sptr ;	int			k, bufferlen, readcount = 0, count ;	sf_count_t	total = 0 ;	float		normfact ;	if (! psf->fdata)		return 0 ;	pgsm610 = (GSM610_PRIVATE*) psf->fdata ;	normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x8000) : 1.0 ;	sptr = psf->u.sbuf ;	bufferlen = ARRAY_LEN (psf->u.sbuf) ;	while (len > 0)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -