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

📄 resample.c

📁 刻录光盘的程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/* @(#)resample.c	1.2 99/12/19 Copyright 1998,1999 Heiko Eissfeldt */#ifndef lintstatic char     sccsid[] ="@(#)resample.c	1.2 99/12/19 Copyright 1998,1999 Heiko Eissfeldt";#endif/* resampling module  * * The audio data has been read. Here are the * functions to ensure a correct continuation * of the output stream and to convert to a * lower sample rate. * */#undef DEBUG_VOTE_ENDIANESS#undef DEBUG_SHIFTS		/* simulate bad cdrom drives */#undef DEBUG_MATCHING#undef SHOW_JITTER#undef CHECK_MEM#include "config.h"#include <timedefs.h>#include <stdio.h>#include <stdlib.h>#if defined (HAVE_UNISTD_H) && (HAVE_UNISTD_H == 1)#include <sys/types.h>#include <unistd.h>#endif#include <standard.h>#include <strdefs.h>#include <limits.h>#include <assert.h>#include <math.h>#include <scg/scsitransp.h>#include "mytype.h"#include "cdda2wav.h"#include "interface.h"#include "byteorder.h"#include "ringbuff.h"#include "resample.h"#include "sndconfig.h"#include "global.h"int waitforsignal = 0;	/* flag: wait for any audio response */int any_signal = 0;short undersampling;	/* conversion factor */short samples_to_do;	/* loop variable for conversion */int Halved;		/* interpolate due to non integral divider */static long lsum = 0, rsum = 0;	       /* accumulator for left/right channel */static long ls2 = 0, rs2 = 0, ls3 = 0, rs3 = 0, auxl = 0, auxr = 0;static const unsigned char *my_symmemmem	__PR((const unsigned char *HAYSTACK, const size_t HAYSTACK_LEN, const unsigned char *const NEEDLE, const size_t NEEDLE_LEN));static const unsigned char *my_memmem	__PR((const unsigned char *HAYSTACK, const size_t HAYSTACK_LEN, const unsigned char *const NEEDLE, const size_t NEEDLE_LEN));static const unsigned char *my_memrmem	__PR((const unsigned char *HAYSTACK, const size_t HAYSTACK_LEN, const unsigned char *const NEEDLE, const size_t NEEDLE_LEN));static const unsigned char *sync_buffers	__PR((const unsigned char *const newbuf));static long interpolate				__PR((long p1, long p2, long p3));static void emit_sample				__PR((long lsumval, long rsumval, long channels));static void change_endianness			__PR((UINT4 *pSam, unsigned int Samples));static void swap_channels			__PR((UINT4 *pSam, unsigned int Samples));static int guess_endianess			__PR((UINT4 *p, short *p2, unsigned int SamplesToDo));#ifdef CHECK_MEMstatic voidcheck_mem __PR((const unsigned char *p, unsigned long amount, const unsigned char *q, unsigned line, char *file));static void check_mem(p, amount, q, line, file)	const unsigned char *p;	unsigned long amount;	const unsigned char *q;	unsigned line;	char *file;{	if (p < q || p+amount > q + ENTRY_SIZE) {		fprintf(stderr, "file %s, line %u: invalid buffer range (%p - %p), allowed is (%p - %p)\n",			file,line,p, p+amount-1, q, q + ENTRY_SIZE-1);		exit(1);	}}#endif#ifdef DEBUG_MATCHINGint memcmp(const void * a, const void * b, size_t c){  return 1;}#endifstatic const unsigned char *my_symmemmem (HAYSTACK, HAYSTACK_LEN, NEEDLE, NEEDLE_LEN)	const unsigned char * HAYSTACK;	const size_t HAYSTACK_LEN;	const unsigned char * const NEEDLE;	const size_t NEEDLE_LEN;{  const unsigned char * const UPPER_LIMIT = HAYSTACK + HAYSTACK_LEN - NEEDLE_LEN - 1;  const unsigned char * HAYSTACK2 = HAYSTACK-1;  while (HAYSTACK <= UPPER_LIMIT) {    if (memcmp(NEEDLE, HAYSTACK, NEEDLE_LEN) == 0) {      return HAYSTACK;    } else {      if (memcmp(NEEDLE, HAYSTACK2, NEEDLE_LEN) == 0) {        return HAYSTACK2;      }      HAYSTACK2--;      HAYSTACK++;    }  }#ifdef DEBUG_MATCHING  HAYSTACK2++;  HAYSTACK--;  fprintf(stderr, "scompared %p-%p with %p-%p (%p)\n", 	 NEEDLE, NEEDLE + NEEDLE_LEN-1,	 HAYSTACK2, HAYSTACK + NEEDLE_LEN-1, HAYSTACK);#endif  return NULL;}static const unsigned char *my_memmem (HAYSTACK, HAYSTACK_LEN, NEEDLE, NEEDLE_LEN)	const unsigned char * HAYSTACK;	const size_t HAYSTACK_LEN;	const unsigned char * const NEEDLE;	const size_t NEEDLE_LEN;{  const unsigned char * const UPPER_LIMIT = HAYSTACK + HAYSTACK_LEN - NEEDLE_LEN;  while (HAYSTACK <= UPPER_LIMIT) {    if (memcmp(NEEDLE, HAYSTACK, NEEDLE_LEN) == 0) {      return HAYSTACK;    } else {      HAYSTACK++;    }  }#ifdef DEBUG_MATCHING  HAYSTACK--;  fprintf(stderr, "fcompared %p-%p with %p-%p (%p)\n", 	 NEEDLE, NEEDLE + NEEDLE_LEN-1,	 HAYSTACK - HAYSTACK_LEN + NEEDLE_LEN, HAYSTACK + NEEDLE_LEN-1,	 HAYSTACK);#endif  return NULL;}static const unsigned char *my_memrmem (HAYSTACK, HAYSTACK_LEN, NEEDLE, NEEDLE_LEN)	const unsigned char * HAYSTACK;	const size_t HAYSTACK_LEN;	const unsigned char * const NEEDLE;	const size_t NEEDLE_LEN;{  const unsigned char * const LOWER_LIMIT = HAYSTACK - (HAYSTACK_LEN - 1);  while (HAYSTACK >= LOWER_LIMIT) {    if (memcmp(NEEDLE, HAYSTACK, NEEDLE_LEN) == 0) {      return HAYSTACK;    } else {      HAYSTACK--;    }  }#ifdef DEBUG_MATCHING  HAYSTACK++;  fprintf(stderr, "bcompared %p-%p with %p-%p (%p)\n", 	 NEEDLE, NEEDLE + NEEDLE_LEN-1,	 HAYSTACK, HAYSTACK + (HAYSTACK_LEN - 1),	 HAYSTACK + (HAYSTACK_LEN - 1) - NEEDLE_LEN - 1);#endif  return NULL;}/* find continuation in new buffer */static const unsigned char *sync_buffers(newbuf)	const unsigned char * const newbuf;{    const unsigned char *retval = newbuf;    if (global.overlap != 0) {      /* find position of SYNC_SIZE bytes 	 of the old buffer in the new buffer */      size_t haystack_len;      const size_t needle_len = SYNC_SIZE;      const unsigned char * const oldbuf = (const unsigned char *) (get_previous_read_buffer()->data);      const unsigned char * haystack;      const unsigned char * needle;      /* compare the previous buffer with the new one       *       * 1. symmetrical search:       *   look for the last SYNC_SIZE bytes of the previous buffer       *   in the new buffer (from the optimum to the outer positions).       *       * 2. if the first approach did not find anything do forward search       *   look for the last SYNC_SIZE bytes of the previous buffer       *   in the new buffer (from behind the overlap to the end).       *          */      haystack_len = min((global.nsectors - global.overlap)*CD_FRAMESIZE_RAW			 +SYNC_SIZE+1,     			 global.overlap*CD_FRAMESIZE_RAW);      /* expected here */      haystack = newbuf + CD_FRAMESIZE_RAW*global.overlap - SYNC_SIZE;      needle = oldbuf + CD_FRAMESIZE_RAW*global.nsectors - SYNC_SIZE; #ifdef DEBUG_MATCHING	fprintf(stderr, "oldbuf    %p-%p  new %p-%p %u %u %u\n",		oldbuf, oldbuf + CD_FRAMESIZE_RAW*global.nsectors - 1,		newbuf, newbuf + CD_FRAMESIZE_RAW*global.nsectors - 1,		CD_FRAMESIZE_RAW*global.nsectors, global.nsectors, global.overlap);#endif      retval = my_symmemmem(haystack, haystack_len, needle, needle_len);      if (retval != NULL) {	retval += SYNC_SIZE;      } else {	/* fallback to asymmetrical search */	/* if there is no asymmetrical part left, return with 'not found' */	if (2*global.overlap == global.nsectors) {	  retval = NULL;	} else if (2*global.overlap > global.nsectors) {	  /* the asymmetrical part is in front, search backwards */          haystack_len = (2*global.overlap-global.nsectors)*CD_FRAMESIZE_RAW;          haystack = newbuf + haystack_len - 1;          retval = my_memrmem(haystack, haystack_len, needle, needle_len);	} else {	  /* the asymmetrical part is at the end, search forward */          haystack = newbuf + 2*(global.overlap*CD_FRAMESIZE_RAW - SYNC_SIZE);          haystack_len = (global.nsectors-2*global.overlap)*CD_FRAMESIZE_RAW + 2*SYNC_SIZE;          retval = my_memmem(haystack, haystack_len, needle, needle_len);	}        if (retval != NULL)	  retval += SYNC_SIZE;      }#ifdef SHOW_JITTER      if (retval) {	fprintf(stderr,"%d\n",		retval-(newbuf+global.overlap*CD_FRAMESIZE_RAW));      } else {	fprintf(stderr,"no match\n");      }#endif    }    return retval;}/* quadratic interpolation * p1, p3 span the interval 0 - 2. give interpolated value for 1/2 */static long int interpolate( p1, p2, p3)	long int p1;	long int p2;	long int p3;{  return (3L*p1 + 6L*p2 - p3)/8L;}static unsigned char *pStart;	/* running ptr defining end of output buffer */static unsigned char *pDst;	/* start of output buffer *//* * Write the filtered sample into the output buffer. */static void emit_sample( lsumval, rsumval, channels )	long lsumval;	long rsumval;	long channels;{    if (global.findminmax) {       if (rsumval > global.maxamp[0]) global.maxamp[0] = rsumval;       if (rsumval < global.minamp[0]) global.minamp[0] = rsumval;       if (lsumval < global.minamp[1]) global.minamp[1] = lsumval;       if (lsumval > global.maxamp[1]) global.maxamp[1] = lsumval;    }    /* convert to output format */    if ( channels == 1 ) {	short sum;       /* mono section */	sum = ( lsumval + rsumval ) >> (global.sh_bits + 1);	if ( global.sh_bits == 8 ) {	    if ( ( (char) sum) != '\0' ) {		if ( any_signal == 0 ) {		    pStart = (unsigned char *) pDst;		    any_signal = 1;		}	    }	    *pDst++ = ( unsigned char ) sum + ( 1 << 7 );	} else {	    short * myptr = (short *) pDst;	    if ( sum != 0 ) {		if ( any_signal == 0 ) {		    pStart = (unsigned char *) pDst;		    any_signal = 1;		}	    }	    *myptr = sum;	    pDst += sizeof( short );	}    } else {	/* stereo section */	lsumval >>= global.sh_bits;	rsumval >>= global.sh_bits;	if ( global.sh_bits == 8 ) {	    if ( (( char ) lsumval != '\0') || (( char ) rsumval != '\0')) {		if ( any_signal == 0 ) {		    pStart = (unsigned char *) pDst;		    any_signal = 1;		}	    }	    *pDst++ = ( unsigned char )( short ) lsumval + ( 1 << 7 );	    *pDst++ = ( unsigned char )( short ) rsumval + ( 1 << 7 );	} else {	    short * myptr = (short *) pDst;	    if ( (( short ) lsumval != 0) || (( short ) rsumval != 0)) {		if ( any_signal == 0 ) {		    pStart = (unsigned char *) pDst;		    any_signal = 1;		}	    }	    *myptr++ = ( short ) lsumval;	    *myptr   = ( short ) rsumval;	    pDst += 2*sizeof( short );	}    }}static void change_endianness(pSam, Samples)	UINT4 *pSam;	unsigned int Samples;{  UINT4 *pend = (pSam + Samples);  /* type UINT4 may not be greater than the assumed biggest type */#if (SIZEOF_LONG_INT < 4)error type unsigned long is too small#endif#if (SIZEOF_LONG_INT == 4)  unsigned long *plong = (unsigned long *)pSam;  for (; plong < pend;) {    *plong = ((*plong >> 8L) & UINT_C(0x00ff00ff)) |             ((*plong << 8L) & UINT_C(0xff00ff00));    plong++;  }#else  /* sizeof long unsigned > 4 bytes */#if (SIZEOF_LONG_INT == 8)#define INTEGRAL_LONGS (SIZEOF_LONG_INT-1UL)  register unsigned long *plong;  unsigned long *pend0 = (unsigned long *) (((unsigned long) pend) & ~ INTEGRAL_LONGS);  if (((unsigned long) pSam) & INTEGRAL_LONGS) {    *pSam = ((*pSam >> 8L) & UINT_C(0x00ff00ff)) |            ((*pSam << 8L) & UINT_C(0xff00ff00));    pSam++;  }  plong = (unsigned long *)pSam;  for (; plong < pend0;) {    *plong = ((*plong >> 8L) & ULONG_C(0x00ff00ff00ff00ff)) |             ((*plong << 8L) & ULONG_C(0xff00ff00ff00ff00));    plong++;  }  if (((unsigned long *) pend) != pend0) {    UINT4 *pint = (UINT4 *) pend0;    for (;pint < pend;) {      *pint = ((*pint >> 8) & UINT_C(0x00ff00ff)) |              ((*pint << 8) & UINT_C(0xff00ff00));      pint++;    }  }#else  /* sizeof long unsigned > 4 bytes but not 8 */  {    UINT4 *pint = pSam;    for (;pint < pend;) {      *pint = ((*pint >> 8) & UINT_C(0x00ff00ff)) |              ((*pint << 8) & UINT_C(0xff00ff00));      pint++;    }  }#endif#endif}static void swap_channels(pSam, Samples)	UINT4 *pSam;	unsigned int Samples;{  UINT4 *pend = (pSam + Samples);  /* type UINT4 may not be greater than the assumed biggest type */#if (SIZEOF_LONG_INT < 4)error type unsigned long is too small#endif#if (SIZEOF_LONG_INT == 4)  unsigned long *plong = (unsigned long *)pSam;  for (; plong < pend;) {    *plong = ((*plong >> 16L) & UINT_C(0x0000ffff)) |             ((*plong << 16L) & UINT_C(0xffff0000));    plong++;  }#else  /* sizeof long unsigned > 4 bytes */#if (SIZEOF_LONG_INT == 8)#define INTEGRAL_LONGS (SIZEOF_LONG_INT-1UL)  register unsigned long *plong;  unsigned long *pend0 = (unsigned long *) (((unsigned long) pend) & ~ INTEGRAL_LONGS);  if (((unsigned long) pSam) & INTEGRAL_LONGS) {    *pSam = ((*pSam >> 16L) & UINT_C(0x0000ffff)) |            ((*pSam << 16L) & UINT_C(0xffff0000));    pSam++;  }  plong = (unsigned long *)pSam;  for (; plong < pend0;) {    *plong = ((*plong >> 16L) & ULONG_C(0x0000ffff0000ffff)) |             ((*plong << 16L) & ULONG_C(0xffff0000ffff0000));    plong++;  }  if (((unsigned long *) pend) != pend0) {    UINT4 *pint = (UINT4 *) pend0;    for (;pint < pend;) {      *pint = ((*pint >> 16L) & UINT_C(0x0000ffff)) |              ((*pint << 16L) & UINT_C(0xffff0000));      pint++;    }  }#else  /* sizeof long unsigned > 4 bytes but not 8 */  {    UINT4 *pint = pSam;    for (;pint < pend;) {      *pint = ((*pint >> 16L) & UINT_C(0x0000ffff)) |              ((*pint << 16L) & UINT_C(0xffff0000));      pint++;    }  }#endif#endif}#ifdef	ECHO_TO_SOUNDCARDstatic long ReSampleBuffer			__PR((unsigned char *p, unsigned char *newp, long samples));static long ReSampleBuffer( p, newp, samples)	unsigned char *p;	unsigned char *newp;	long samples;{	double idx=0;	long    di=0,si=0;	if (global.playback_rate == 100.0) {		memcpy(newp, p, 4* samples);		di = samples;	} else while( si < samples ){

⌨️ 快捷键说明

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