resample.c
上传用户:xiejiait
上传日期:2007-01-06
资源大小:881k
文件大小:27k
源码类别:

SCSI/ASPI

开发平台:

MultiPlatform

  1. /* @(#)resample.c 1.2 99/12/19 Copyright 1998,1999 Heiko Eissfeldt */
  2. #ifndef lint
  3. static char     sccsid[] =
  4. "@(#)resample.c 1.2 99/12/19 Copyright 1998,1999 Heiko Eissfeldt";
  5. #endif
  6. /* resampling module 
  7.  *
  8.  * The audio data has been read. Here are the
  9.  * functions to ensure a correct continuation
  10.  * of the output stream and to convert to a
  11.  * lower sample rate.
  12.  *
  13.  */
  14. #undef DEBUG_VOTE_ENDIANESS
  15. #undef DEBUG_SHIFTS /* simulate bad cdrom drives */
  16. #undef DEBUG_MATCHING
  17. #undef SHOW_JITTER
  18. #undef CHECK_MEM
  19. #include "config.h"
  20. #include <timedefs.h>
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #if defined (HAVE_UNISTD_H) && (HAVE_UNISTD_H == 1)
  24. #include <sys/types.h>
  25. #include <unistd.h>
  26. #endif
  27. #include <standard.h>
  28. #include <strdefs.h>
  29. #include <limits.h>
  30. #include <assert.h>
  31. #include <math.h>
  32. #include <scg/scsitransp.h>
  33. #include "mytype.h"
  34. #include "cdda2wav.h"
  35. #include "interface.h"
  36. #include "byteorder.h"
  37. #include "ringbuff.h"
  38. #include "resample.h"
  39. #include "sndconfig.h"
  40. #include "global.h"
  41. int waitforsignal = 0; /* flag: wait for any audio response */
  42. int any_signal = 0;
  43. short undersampling; /* conversion factor */
  44. short samples_to_do; /* loop variable for conversion */
  45. int Halved; /* interpolate due to non integral divider */
  46. static long lsum = 0, rsum = 0;        /* accumulator for left/right channel */
  47. static long ls2 = 0, rs2 = 0, ls3 = 0, rs3 = 0, auxl = 0, auxr = 0;
  48. 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));
  49. 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));
  50. 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));
  51. static const unsigned char *sync_buffers __PR((const unsigned char *const newbuf));
  52. static long interpolate __PR((long p1, long p2, long p3));
  53. static void emit_sample __PR((long lsumval, long rsumval, long channels));
  54. static void change_endianness __PR((UINT4 *pSam, unsigned int Samples));
  55. static void swap_channels __PR((UINT4 *pSam, unsigned int Samples));
  56. static int guess_endianess __PR((UINT4 *p, short *p2, unsigned int SamplesToDo));
  57. #ifdef CHECK_MEM
  58. static void
  59. check_mem __PR((const unsigned char *p, unsigned long amount, const unsigned char *q, unsigned line, char *file));
  60. static void check_mem(p, amount, q, line, file)
  61. const unsigned char *p;
  62. unsigned long amount;
  63. const unsigned char *q;
  64. unsigned line;
  65. char *file;
  66. {
  67. if (p < q || p+amount > q + ENTRY_SIZE) {
  68. fprintf(stderr, "file %s, line %u: invalid buffer range (%p - %p), allowed is (%p - %p)n",
  69. file,line,p, p+amount-1, q, q + ENTRY_SIZE-1);
  70. exit(1);
  71. }
  72. }
  73. #endif
  74. #ifdef DEBUG_MATCHING
  75. int memcmp(const void * a, const void * b, size_t c)
  76. {
  77.   return 1;
  78. }
  79. #endif
  80. static const unsigned char *
  81. my_symmemmem (HAYSTACK, HAYSTACK_LEN, NEEDLE, NEEDLE_LEN)
  82. const unsigned char * HAYSTACK;
  83. const size_t HAYSTACK_LEN;
  84. const unsigned char * const NEEDLE;
  85. const size_t NEEDLE_LEN;
  86. {
  87.   const unsigned char * const UPPER_LIMIT = HAYSTACK + HAYSTACK_LEN - NEEDLE_LEN - 1;
  88.   const unsigned char * HAYSTACK2 = HAYSTACK-1;
  89.   while (HAYSTACK <= UPPER_LIMIT) {
  90.     if (memcmp(NEEDLE, HAYSTACK, NEEDLE_LEN) == 0) {
  91.       return HAYSTACK;
  92.     } else {
  93.       if (memcmp(NEEDLE, HAYSTACK2, NEEDLE_LEN) == 0) {
  94.         return HAYSTACK2;
  95.       }
  96.       HAYSTACK2--;
  97.       HAYSTACK++;
  98.     }
  99.   }
  100. #ifdef DEBUG_MATCHING
  101.   HAYSTACK2++;
  102.   HAYSTACK--;
  103.   fprintf(stderr, "scompared %p-%p with %p-%p (%p)n",
  104.    NEEDLE, NEEDLE + NEEDLE_LEN-1,
  105.  HAYSTACK2, HAYSTACK + NEEDLE_LEN-1, HAYSTACK);
  106. #endif
  107.   return NULL;
  108. }
  109. static const unsigned char *
  110. my_memmem (HAYSTACK, HAYSTACK_LEN, NEEDLE, NEEDLE_LEN)
  111. const unsigned char * HAYSTACK;
  112. const size_t HAYSTACK_LEN;
  113. const unsigned char * const NEEDLE;
  114. const size_t NEEDLE_LEN;
  115. {
  116.   const unsigned char * const UPPER_LIMIT = HAYSTACK + HAYSTACK_LEN - NEEDLE_LEN;
  117.   while (HAYSTACK <= UPPER_LIMIT) {
  118.     if (memcmp(NEEDLE, HAYSTACK, NEEDLE_LEN) == 0) {
  119.       return HAYSTACK;
  120.     } else {
  121.       HAYSTACK++;
  122.     }
  123.   }
  124. #ifdef DEBUG_MATCHING
  125.   HAYSTACK--;
  126.   fprintf(stderr, "fcompared %p-%p with %p-%p (%p)n",
  127.    NEEDLE, NEEDLE + NEEDLE_LEN-1,
  128.  HAYSTACK - HAYSTACK_LEN + NEEDLE_LEN, HAYSTACK + NEEDLE_LEN-1,
  129.  HAYSTACK);
  130. #endif
  131.   return NULL;
  132. }
  133. static const unsigned char *
  134. my_memrmem (HAYSTACK, HAYSTACK_LEN, NEEDLE, NEEDLE_LEN)
  135. const unsigned char * HAYSTACK;
  136. const size_t HAYSTACK_LEN;
  137. const unsigned char * const NEEDLE;
  138. const size_t NEEDLE_LEN;
  139. {
  140.   const unsigned char * const LOWER_LIMIT = HAYSTACK - (HAYSTACK_LEN - 1);
  141.   while (HAYSTACK >= LOWER_LIMIT) {
  142.     if (memcmp(NEEDLE, HAYSTACK, NEEDLE_LEN) == 0) {
  143.       return HAYSTACK;
  144.     } else {
  145.       HAYSTACK--;
  146.     }
  147.   }
  148. #ifdef DEBUG_MATCHING
  149.   HAYSTACK++;
  150.   fprintf(stderr, "bcompared %p-%p with %p-%p (%p)n",
  151.    NEEDLE, NEEDLE + NEEDLE_LEN-1,
  152.  HAYSTACK, HAYSTACK + (HAYSTACK_LEN - 1),
  153.  HAYSTACK + (HAYSTACK_LEN - 1) - NEEDLE_LEN - 1);
  154. #endif
  155.   return NULL;
  156. }
  157. /* find continuation in new buffer */
  158. static const unsigned char *
  159. sync_buffers(newbuf)
  160. const unsigned char * const newbuf;
  161. {
  162.     const unsigned char *retval = newbuf;
  163.     if (global.overlap != 0) {
  164.       /* find position of SYNC_SIZE bytes 
  165.  of the old buffer in the new buffer */
  166.       size_t haystack_len;
  167.       const size_t needle_len = SYNC_SIZE;
  168.       const unsigned char * const oldbuf = (const unsigned char *) (get_previous_read_buffer()->data);
  169.       const unsigned char * haystack;
  170.       const unsigned char * needle;
  171.       /* compare the previous buffer with the new one
  172.        *
  173.        * 1. symmetrical search:
  174.        *   look for the last SYNC_SIZE bytes of the previous buffer
  175.        *   in the new buffer (from the optimum to the outer positions).
  176.        *
  177.        * 2. if the first approach did not find anything do forward search
  178.        *   look for the last SYNC_SIZE bytes of the previous buffer
  179.        *   in the new buffer (from behind the overlap to the end).
  180.        *   
  181.        */
  182.       haystack_len = min((global.nsectors - global.overlap)*CD_FRAMESIZE_RAW
  183.  +SYNC_SIZE+1,
  184.        global.overlap*CD_FRAMESIZE_RAW);
  185.       /* expected here */
  186.       haystack = newbuf + CD_FRAMESIZE_RAW*global.overlap - SYNC_SIZE;
  187.       needle = oldbuf + CD_FRAMESIZE_RAW*global.nsectors - SYNC_SIZE; 
  188. #ifdef DEBUG_MATCHING
  189. fprintf(stderr, "oldbuf    %p-%p  new %p-%p %u %u %un",
  190. oldbuf, oldbuf + CD_FRAMESIZE_RAW*global.nsectors - 1,
  191. newbuf, newbuf + CD_FRAMESIZE_RAW*global.nsectors - 1,
  192. CD_FRAMESIZE_RAW*global.nsectors, global.nsectors, global.overlap);
  193. #endif
  194.       retval = my_symmemmem(haystack, haystack_len, needle, needle_len);
  195.       if (retval != NULL) {
  196. retval += SYNC_SIZE;
  197.       } else {
  198. /* fallback to asymmetrical search */
  199. /* if there is no asymmetrical part left, return with 'not found' */
  200. if (2*global.overlap == global.nsectors) {
  201.   retval = NULL;
  202. } else if (2*global.overlap > global.nsectors) {
  203.   /* the asymmetrical part is in front, search backwards */
  204.           haystack_len = (2*global.overlap-global.nsectors)*CD_FRAMESIZE_RAW;
  205.           haystack = newbuf + haystack_len - 1;
  206.           retval = my_memrmem(haystack, haystack_len, needle, needle_len);
  207. } else {
  208.   /* the asymmetrical part is at the end, search forward */
  209.           haystack = newbuf + 2*(global.overlap*CD_FRAMESIZE_RAW - SYNC_SIZE);
  210.           haystack_len = (global.nsectors-2*global.overlap)*CD_FRAMESIZE_RAW + 2*SYNC_SIZE;
  211.           retval = my_memmem(haystack, haystack_len, needle, needle_len);
  212. }
  213.         if (retval != NULL)
  214.   retval += SYNC_SIZE;
  215.       }
  216. #ifdef SHOW_JITTER
  217.       if (retval) {
  218. fprintf(stderr,"%dn",
  219. retval-(newbuf+global.overlap*CD_FRAMESIZE_RAW));
  220.       } else {
  221. fprintf(stderr,"no matchn");
  222.       }
  223. #endif
  224.     }
  225.     return retval;
  226. }
  227. /* quadratic interpolation
  228.  * p1, p3 span the interval 0 - 2. give interpolated value for 1/2 */
  229. static long int 
  230. interpolate( p1, p2, p3)
  231. long int p1;
  232. long int p2;
  233. long int p3;
  234. {
  235.   return (3L*p1 + 6L*p2 - p3)/8L;
  236. }
  237. static unsigned char *pStart; /* running ptr defining end of output buffer */
  238. static unsigned char *pDst; /* start of output buffer */
  239. /*
  240.  * Write the filtered sample into the output buffer.
  241.  */
  242. static void 
  243. emit_sample( lsumval, rsumval, channels )
  244. long lsumval;
  245. long rsumval;
  246. long channels;
  247. {
  248.     if (global.findminmax) {
  249.        if (rsumval > global.maxamp[0]) global.maxamp[0] = rsumval;
  250.        if (rsumval < global.minamp[0]) global.minamp[0] = rsumval;
  251.        if (lsumval < global.minamp[1]) global.minamp[1] = lsumval;
  252.        if (lsumval > global.maxamp[1]) global.maxamp[1] = lsumval;
  253.     }
  254.     /* convert to output format */
  255.     if ( channels == 1 ) {
  256. short sum;       /* mono section */
  257. sum = ( lsumval + rsumval ) >> (global.sh_bits + 1);
  258. if ( global.sh_bits == 8 ) {
  259.     if ( ( (char) sum) != '' ) {
  260. if ( any_signal == 0 ) {
  261.     pStart = (unsigned char *) pDst;
  262.     any_signal = 1;
  263. }
  264.     }
  265.     *pDst++ = ( unsigned char ) sum + ( 1 << 7 );
  266. } else {
  267.     short * myptr = (short *) pDst;
  268.     if ( sum != 0 ) {
  269. if ( any_signal == 0 ) {
  270.     pStart = (unsigned char *) pDst;
  271.     any_signal = 1;
  272. }
  273.     }
  274.     *myptr = sum;
  275.     pDst += sizeof( short );
  276. }
  277.     } else {
  278. /* stereo section */
  279. lsumval >>= global.sh_bits;
  280. rsumval >>= global.sh_bits;
  281. if ( global.sh_bits == 8 ) {
  282.     if ( (( char ) lsumval != '') || (( char ) rsumval != '')) {
  283. if ( any_signal == 0 ) {
  284.     pStart = (unsigned char *) pDst;
  285.     any_signal = 1;
  286. }
  287.     }
  288.     *pDst++ = ( unsigned char )( short ) lsumval + ( 1 << 7 );
  289.     *pDst++ = ( unsigned char )( short ) rsumval + ( 1 << 7 );
  290. } else {
  291.     short * myptr = (short *) pDst;
  292.     if ( (( short ) lsumval != 0) || (( short ) rsumval != 0)) {
  293. if ( any_signal == 0 ) {
  294.     pStart = (unsigned char *) pDst;
  295.     any_signal = 1;
  296. }
  297.     }
  298.     *myptr++ = ( short ) lsumval;
  299.     *myptr   = ( short ) rsumval;
  300.     pDst += 2*sizeof( short );
  301. }
  302.     }
  303. }
  304. static void change_endianness(pSam, Samples)
  305. UINT4 *pSam;
  306. unsigned int Samples;
  307. {
  308.   UINT4 *pend = (pSam + Samples);
  309.   /* type UINT4 may not be greater than the assumed biggest type */
  310. #if (SIZEOF_LONG_INT < 4)
  311. error type unsigned long is too small
  312. #endif
  313. #if (SIZEOF_LONG_INT == 4)
  314.   unsigned long *plong = (unsigned long *)pSam;
  315.   for (; plong < pend;) {
  316.     *plong = ((*plong >> 8L) & UINT_C(0x00ff00ff)) |
  317.              ((*plong << 8L) & UINT_C(0xff00ff00));
  318.     plong++;
  319.   }
  320. #else  /* sizeof long unsigned > 4 bytes */
  321. #if (SIZEOF_LONG_INT == 8)
  322. #define INTEGRAL_LONGS (SIZEOF_LONG_INT-1UL)
  323.   register unsigned long *plong;
  324.   unsigned long *pend0 = (unsigned long *) (((unsigned long) pend) & ~ INTEGRAL_LONGS);
  325.   if (((unsigned long) pSam) & INTEGRAL_LONGS) {
  326.     *pSam = ((*pSam >> 8L) & UINT_C(0x00ff00ff)) |
  327.             ((*pSam << 8L) & UINT_C(0xff00ff00));
  328.     pSam++;
  329.   }
  330.   plong = (unsigned long *)pSam;
  331.   for (; plong < pend0;) {
  332.     *plong = ((*plong >> 8L) & ULONG_C(0x00ff00ff00ff00ff)) |
  333.              ((*plong << 8L) & ULONG_C(0xff00ff00ff00ff00));
  334.     plong++;
  335.   }
  336.   if (((unsigned long *) pend) != pend0) {
  337.     UINT4 *pint = (UINT4 *) pend0;
  338.     for (;pint < pend;) {
  339.       *pint = ((*pint >> 8) & UINT_C(0x00ff00ff)) |
  340.               ((*pint << 8) & UINT_C(0xff00ff00));
  341.       pint++;
  342.     }
  343.   }
  344. #else  /* sizeof long unsigned > 4 bytes but not 8 */
  345.   {
  346.     UINT4 *pint = pSam;
  347.     for (;pint < pend;) {
  348.       *pint = ((*pint >> 8) & UINT_C(0x00ff00ff)) |
  349.               ((*pint << 8) & UINT_C(0xff00ff00));
  350.       pint++;
  351.     }
  352.   }
  353. #endif
  354. #endif
  355. }
  356. static void swap_channels(pSam, Samples)
  357. UINT4 *pSam;
  358. unsigned int Samples;
  359. {
  360.   UINT4 *pend = (pSam + Samples);
  361.   /* type UINT4 may not be greater than the assumed biggest type */
  362. #if (SIZEOF_LONG_INT < 4)
  363. error type unsigned long is too small
  364. #endif
  365. #if (SIZEOF_LONG_INT == 4)
  366.   unsigned long *plong = (unsigned long *)pSam;
  367.   for (; plong < pend;) {
  368.     *plong = ((*plong >> 16L) & UINT_C(0x0000ffff)) |
  369.              ((*plong << 16L) & UINT_C(0xffff0000));
  370.     plong++;
  371.   }
  372. #else  /* sizeof long unsigned > 4 bytes */
  373. #if (SIZEOF_LONG_INT == 8)
  374. #define INTEGRAL_LONGS (SIZEOF_LONG_INT-1UL)
  375.   register unsigned long *plong;
  376.   unsigned long *pend0 = (unsigned long *) (((unsigned long) pend) & ~ INTEGRAL_LONGS);
  377.   if (((unsigned long) pSam) & INTEGRAL_LONGS) {
  378.     *pSam = ((*pSam >> 16L) & UINT_C(0x0000ffff)) |
  379.             ((*pSam << 16L) & UINT_C(0xffff0000));
  380.     pSam++;
  381.   }
  382.   plong = (unsigned long *)pSam;
  383.   for (; plong < pend0;) {
  384.     *plong = ((*plong >> 16L) & ULONG_C(0x0000ffff0000ffff)) |
  385.              ((*plong << 16L) & ULONG_C(0xffff0000ffff0000));
  386.     plong++;
  387.   }
  388.   if (((unsigned long *) pend) != pend0) {
  389.     UINT4 *pint = (UINT4 *) pend0;
  390.     for (;pint < pend;) {
  391.       *pint = ((*pint >> 16L) & UINT_C(0x0000ffff)) |
  392.               ((*pint << 16L) & UINT_C(0xffff0000));
  393.       pint++;
  394.     }
  395.   }
  396. #else  /* sizeof long unsigned > 4 bytes but not 8 */
  397.   {
  398.     UINT4 *pint = pSam;
  399.     for (;pint < pend;) {
  400.       *pint = ((*pint >> 16L) & UINT_C(0x0000ffff)) |
  401.               ((*pint << 16L) & UINT_C(0xffff0000));
  402.       pint++;
  403.     }
  404.   }
  405. #endif
  406. #endif
  407. }
  408. #ifdef ECHO_TO_SOUNDCARD
  409. static long ReSampleBuffer __PR((unsigned char *p, unsigned char *newp, long samples));
  410. static long ReSampleBuffer( p, newp, samples)
  411. unsigned char *p;
  412. unsigned char *newp;
  413. long samples;
  414. {
  415. double idx=0;
  416. long    di=0,si=0;
  417. if (global.playback_rate == 100.0) {
  418. memcpy(newp, p, 4* samples);
  419. di = samples;
  420. } else while( si < samples ){
  421. memcpy( newp+(di*4), p+(si*4), 4 );
  422. idx += (double)(global.playback_rate/100.0);
  423. si = (long)idx;
  424. di++;
  425. }
  426. return di;
  427. }
  428. #endif
  429. static int guess_endianess(p, p2, SamplesToDo)
  430. UINT4 *p;
  431. short *p2;
  432. unsigned SamplesToDo;
  433. {
  434.     /* analyse samples */
  435.     int vote_for_little = 0;
  436.     int vote_for_big = 0;
  437.     int total_votes;
  438.     while (((UINT4 *)p2 - p) + (unsigned) 1 < SamplesToDo) {
  439.       unsigned char *p3 = (unsigned char *)p2;
  440. #if MY_LITTLE_ENDIAN == 1
  441.       int diff_lowl = *(p2+0) - *(p2+2);
  442.       int diff_lowr = *(p2+1) - *(p2+3);
  443.       int diff_bigl = ((*(p3  ) << 8) + *(p3+1)) - ((*(p3+4) << 8) + *(p3+5));
  444.       int diff_bigr = ((*(p3+2) << 8) + *(p3+3)) - ((*(p3+6) << 8) + *(p3+7));
  445. #else
  446.       int diff_lowl = ((*(p3+1) << 8) + *(p3  )) - ((*(p3+5) << 8) + *(p3+4));
  447.       int diff_lowr = ((*(p3+3) << 8) + *(p3+2)) - ((*(p3+7) << 8) + *(p3+6));
  448.       int diff_bigl = *(p2+0) - *(p2+2);
  449.       int diff_bigr = *(p2+1) - *(p2+3);
  450. #endif
  451.       if ((abs(diff_lowl) + abs(diff_lowr)) <
  452.   (abs(diff_bigl) + abs(diff_bigr))) {
  453. vote_for_little++;
  454.       } else {
  455. if ((abs(diff_lowl) + abs(diff_lowr)) >
  456.     (abs(diff_bigl) + abs(diff_bigr))) {
  457.   vote_for_big++;
  458. }
  459.       }
  460.       p2 += 2;
  461.    }
  462. #ifdef DEBUG_VOTE_ENDIANESS
  463.    if (global.quiet != 1)
  464.      fprintf(stderr, "votes for little: %4d,  votes for big: %4dn", 
  465. vote_for_little, vote_for_big);
  466. #endif
  467.    total_votes = vote_for_big + vote_for_little;
  468.    if (total_votes < 3
  469.        || abs(vote_for_big - vote_for_little) < total_votes/3) {
  470.      return -1;
  471.    } else {
  472. if (vote_for_big > vote_for_little)
  473. return 1;
  474. else
  475. return 0;
  476.    }
  477. }
  478. int jitterShift = 0; 
  479. unsigned char *synchronize(p, SamplesToDo, TotSamplesDone)
  480. UINT4 *p;
  481. unsigned SamplesToDo;
  482. unsigned TotSamplesDone;
  483. {
  484.   static int jitter = 0;
  485.   char *pSrc;                   /* start of cdrom buffer */
  486.   /* if endianess is unknown, guess endianess based on 
  487.      differences between succesive samples. If endianess
  488.      is correct, the differences are smaller than with the
  489.      opposite byte order.
  490.    */
  491.   if ((*in_lendian) < 0) {
  492.     short *p2 = (short *)p;
  493.     /* skip constant samples */
  494.     while ((((UINT4 *)p2 - p) + (unsigned) 1 < SamplesToDo)
  495.            && *p2 == *(p2+2)) p2++;
  496.     if (((UINT4 *)p2 - p) + (unsigned) 1 < SamplesToDo) {
  497.       switch (guess_endianess(p, p2, SamplesToDo)) {
  498.         case -1: break;
  499.         case  1: (*in_lendian) = 0;
  500. #if 0
  501.          if (global.quiet != 1)
  502.    fprintf(stderr, "big endian detectedn");
  503. #endif
  504. break;
  505.         case  0: (*in_lendian) = 1;
  506. #if 0
  507.          if (global.quiet != 1)
  508.    fprintf(stderr, "little endian detectedn");
  509. #endif
  510. break;
  511.       }
  512.     }
  513.   }
  514.   /* ENDIAN ISSUES:
  515.    * the individual endianess of cdrom/cd-writer, cpu, 
  516.    * sound card and audio output format need a careful treatment.
  517.    *
  518.    * For possible sample processing (rate conversion) we need
  519.    * the samples in cpu byte order. This is the first conversion.
  520.    *
  521.    * After processing it depends on the endianness of the output
  522.    * format, whether a second conversion is needed.
  523.    *
  524.    */
  525.   if (global.need_hostorder && (*in_lendian) != MY_LITTLE_ENDIAN) {
  526.     /* change endianess of delivered samples to native cpu order */
  527.     change_endianness(p, SamplesToDo);
  528.   }
  529.   /* synchronisation code */
  530.   if (TotSamplesDone != 0 && global.overlap != 0 && SamplesToDo > CD_FRAMESAMPLES) {
  531.     pSrc = (char *) sync_buffers((unsigned char *)p);
  532.     if (!pSrc ) {
  533.       return NULL;
  534.     }
  535.     if (pSrc) {
  536.       jitter = ((unsigned char *)pSrc - (((unsigned char *)p) + global.overlap*CD_FRAMESIZE_RAW))/4;
  537.       jitterShift += jitter;
  538.       SamplesToDo -= jitter + global.overlap*CD_FRAMESAMPLES;
  539. #if 0
  540.       fprintf(stderr,
  541.     "Length: pre %d, diff1 %ld, diff2 %ld, min %ldn", SamplesToDo,
  542.    (TotSamplesWanted - TotSamplesDone),
  543.    SamplesNeeded((TotSamplesWanted - TotSamplesDone), undersampling),
  544.    min(SamplesToDo, SamplesNeeded((TotSamplesWanted - TotSamplesDone), undersampling)));
  545. #endif
  546.     }
  547.   } else {
  548.     pSrc = ( char * ) p;
  549.   }
  550.   return (unsigned char *) pSrc;
  551. }
  552. /* convert cdda data to required output format
  553.  * sync code for unreliable cdroms included
  554.  * 
  555.  */
  556. long 
  557. SaveBuffer (p, SamplesToDo, TotSamplesDone)
  558. UINT4 *p;
  559. unsigned long SamplesToDo;
  560. unsigned long *TotSamplesDone;
  561. {
  562.   UINT4 *pSrc;                   /* start of cdrom buffer */
  563.   UINT4 *pSrcStop;               /* end of cdrom buffer */
  564.   /* in case of different endianness between host and output format,
  565.      copy in a seperate buffer and modify the local copy */
  566.   if ( ((!global.need_hostorder && global.need_big_endian == (*in_lendian)) ||
  567.  (global.need_hostorder && global.need_big_endian != MY_BIG_ENDIAN))
  568.       && global.OutSampleSize > 1) {
  569.      static UINT4 *localoutputbuffer;
  570.      if (localoutputbuffer == NULL) {
  571.        localoutputbuffer = (UINT4 *) malloc(global.nsectors*CD_FRAMESIZE_RAW);
  572.        if (localoutputbuffer == NULL) {
  573.          perror("cannot allocate local buffer");
  574.          return 1;
  575.        }
  576.      }
  577.      memcpy(localoutputbuffer, p, SamplesToDo*4);
  578.      p = localoutputbuffer;
  579.   }
  580.   pSrc = p;
  581.   pDst = (unsigned char *) p;
  582.   pStart = ( unsigned char * ) pSrc;
  583.   pSrcStop = pSrc + SamplesToDo;
  584.   /* code for subsampling and output stage */
  585.   if (global.ismono && global.findmono) {
  586.     short *pmm;
  587.     for (pmm = (short *)pStart; (UINT4 *) pmm < pSrcStop; pmm += 2) {
  588.       if (*pmm != *(pmm+1)) {
  589.         global.ismono = 0;
  590.         break;
  591.       }
  592.     }
  593.   }
  594.   /* optimize the case of no conversion */
  595.   if (1 && undersampling == 1 && samples_to_do == 1 &&
  596.        global.channels == 2 && global.OutSampleSize == 2 && Halved == 0) {
  597.     /* output format is the original cdda format ->
  598.      * just forward the buffer 
  599.      */
  600.       
  601.     if ( waitforsignal != 0 && any_signal == 0) {
  602.       int *myptr = (int *)pStart;
  603.       while ((UINT4 *)myptr < pSrcStop && *myptr == 0) myptr++;
  604.       pStart = (unsigned char *) myptr;
  605.       /* scan for first signal */
  606.       if ( (UINT4 *)pStart != pSrcStop ) {
  607. /* first non null amplitude is found in buffer */
  608. any_signal = 1;
  609.       }
  610.     }
  611.     pDst = (unsigned char *) pSrcStop; /* set pDst to end */
  612.     if (global.deemphasize) {
  613.       /* this implements an attenuation treble shelving filter 
  614.          to undo the effect of pre-emphasis. The filter is of
  615.          a recursive first order */
  616.       static short lastin[2] = { 0, 0 };
  617.       static double lastout[2] = { 0.0, 0.0 };
  618.       short *pmm;
  619.       /* Here is the gnuplot file for the frequency response
  620.          of the deemphasis. The error is below +-0.1dB
  621. # first define the ideal filter. We use the tenfold sampling frequency.
  622. T=1./441000.
  623. OmegaU=1./15E-6
  624. OmegaL=15./50.*OmegaU
  625. V0=OmegaL/OmegaU
  626. H0=V0-1.
  627. B=V0*tan(OmegaU*T/2.)
  628. # the coefficients follow
  629. a1=(B - 1.)/(B + 1.)
  630. b0=(1.0 + (1.0 - a1) * H0/2.)
  631. b1=(a1 + (a1 - 1.0) * H0/2.)
  632. # helper variables
  633. D=b1/b0
  634. o=2*pi*T
  635. H2(f)=b0*sqrt((1+2*cos(f*o)*D+D*D)/(1+2*cos(f*o)*a1+a1*a1))
  636. # now approximate the ideal curve with a fitted one for sampling frequency
  637. # of 44100 Hz.
  638. T2=1./44100.
  639. V02=0.3365
  640. OmegaU2=1./19E-6
  641. B2=V02*tan(OmegaU2*T2/2.)
  642. # the coefficients follow
  643. a12=(B2 - 1.)/(B2 + 1.)
  644. b02=(1.0 + (1.0 - a12) * (V02-1.)/2.)
  645. b12=(a12 + (a12 - 1.0) * (V02-1.)/2.)
  646. # helper variables
  647. D2=b12/b02
  648. o2=2*pi*T2
  649. H(f)=b02*sqrt((1+2*cos(f*o2)*D2+D2*D2)/(1+2*cos(f*o2)*a12+a12*a12))
  650. # plot best, real, ideal, level with halved attenuation,
  651. #      level at full attentuation, 10fold magnified error
  652. set logscale x
  653. set grid xtics ytics mxtics mytics
  654. plot [f=1000:20000] [-12:2] 20*log10(H(f)),20*log10(H2(f)),  20*log10(OmegaL/(2*pi*f)), 0.5*20*log10(V0), 20*log10(V0), 200*log10(H(f)/H2(f))
  655. pause -1 "Hit return to continue"
  656.        */
  657. #ifdef TEST
  658. #define V0 0.3365
  659. #define OMEGAG (1./19e-6)
  660. #define T (1./44100.)
  661. #define H0 (V0-1.)
  662. #define B (V0*tan((OMEGAG * T)/2.0))
  663. #define a1 ((B - 1.)/(B + 1.))
  664. #define b0  (1.0 + (1.0 - a1) * H0/2.0)
  665. #define b1  (a1 + (a1 - 1.0) * H0/2.0)
  666. #else
  667. #define a1 -0.62786881719628784282
  668. #define b0  0.45995451989513153057
  669. #define b1  -0.08782333709141937339
  670. #endif
  671.       for (pmm = (short *)pStart; pmm < (short *)pDst;) {
  672.         lastout[0] = *pmm * b0 + lastin[0] * b1 - lastout[0] * a1;
  673.         lastin[0] = *pmm;
  674.         *pmm++ = lastout[0] > 0.0 ? lastout[0] + 0.5 : lastout[0] - 0.5;
  675.         lastout[1] = *pmm * b0 + lastin[1] * b1 - lastout[1] * a1;
  676.         lastin[1] = *pmm;
  677.         *pmm++ = lastout[1] > 0.0 ? lastout[1] + 0.5 : lastout[1] - 0.5;
  678.       }
  679.     }
  680.     if (global.swapchannels == 1) {
  681. swap_channels((UINT4 *)pStart, SamplesToDo);
  682.     }
  683.     if (global.findminmax) {
  684.       short *pmm;
  685.       for (pmm = (short *)pStart; pmm < (short *)pDst; pmm++) {
  686.         if (*pmm < global.minamp[1]) global.minamp[1] = *pmm;
  687.         if (*pmm > global.maxamp[1]) global.maxamp[1] = *pmm;
  688.         pmm++;
  689.         if (*pmm < global.minamp[0]) global.minamp[0] = *pmm;
  690.         if (*pmm > global.maxamp[0]) global.maxamp[0] = *pmm;
  691.       }
  692.     }
  693.   } else {
  694. #define none_missing 0
  695. #define one_missing 1
  696. #define two_missing 2
  697. #define collecting 3
  698.     static int sample_state = collecting;
  699.     static int Toggle_on = 0;
  700.     if (global.channels == 2 && global.swapchannels == 1) {
  701. swap_channels((UINT4 *)pStart, SamplesToDo);
  702.     }
  703.     /* conversion required */
  704.     while ( pSrc < pSrcStop ) {
  705.   
  706. long l,r;
  707. long iSamples_left = (pSrcStop - pSrc) / sizeof(short) / 2;
  708. short *myptr = (short *) pSrc;
  709. /* LSB l, MSB l */
  710. l = *myptr++; /* left channel */
  711. r = *myptr++; /* right channel */
  712. pSrc = (UINT4 *) myptr;
  713. switch (sample_state) {
  714. case two_missing:
  715. two__missing:
  716.     ls2 += l; rs2 += r;
  717.     if (undersampling > 1) {
  718. ls3 += l; rs3 += r;
  719.     }
  720.     sample_state = one_missing;
  721.     break;
  722. case one_missing:
  723.     auxl = l; auxr = r;
  724.     ls3 += l; rs3 += r;
  725.     sample_state = none_missing;
  726.     /* FALLTHROUGH */
  727. none__missing:
  728. case none_missing:
  729.     /* Filtered samples are complete. Now interpolate and scale. */
  730.     if (Halved != 0 && Toggle_on == 0) {
  731.                 lsum = interpolate(lsum, ls2, ls3)/(int) undersampling;
  732.         rsum = interpolate(rsum, rs2, rs3)/(int) undersampling;
  733.             } else {
  734. lsum /= (int) undersampling;
  735. rsum /= (int) undersampling;
  736.             }
  737.     emit_sample(lsum, rsum, global.channels);
  738.     /* reload counter */
  739.     samples_to_do = undersampling - 1;
  740.     lsum = auxl;
  741.     rsum = auxr;
  742.     /* reset sample register */
  743.     auxl = ls2 = ls3 = 0;
  744.     auxr = rs2 = rs3 = 0;
  745.     Toggle_on ^= 1;
  746.     sample_state = collecting;
  747.     break;
  748. case collecting:
  749.     if ( samples_to_do > 0) {
  750. samples_to_do--;
  751. if (Halved != 0 && Toggle_on == 0) {
  752.     /* Divider x.5 : we need data for quadratic interpolation */
  753.     iSamples_left--;
  754.     lsum += l; rsum += r;
  755.     if ( samples_to_do < undersampling - 1) {
  756. ls2 += l; rs2 += r;
  757.     }
  758.     if ( samples_to_do < undersampling - 2) {
  759. ls3 += l; rs3 += r;
  760.     }
  761. } else {
  762.     /* integral divider */
  763.     lsum += l;
  764.     rsum += r;
  765.     iSamples_left--;
  766. }
  767.     } else {
  768.         if (Halved != 0 && Toggle_on == 0) {
  769.     sample_state = two_missing;
  770.     goto two__missing;
  771. } else {
  772.     auxl = l;
  773.     auxr = r;
  774.     sample_state = none_missing;
  775.     goto none__missing;
  776. }
  777.     }
  778.     break;
  779. } /* switch state */
  780.     } /* while */
  781.     /* flush_buffer */
  782.     if ((samples_to_do == 0 && Halved == 0))
  783.     {
  784. if (Halved != 0 && Toggle_on == 0) {
  785.     lsum = interpolate(lsum, ls2, ls3)/(int) undersampling;
  786.     rsum = interpolate(rsum, rs2, rs3)/(int) undersampling;
  787. } else {
  788.     lsum /= (int) undersampling;
  789.     rsum /= (int) undersampling;
  790. }
  791. emit_sample(lsum, rsum, global.channels);
  792. /* reload counter */
  793. samples_to_do = undersampling;
  794. /* reset sample register */
  795. lsum = auxl = ls2 = ls3 = 0;
  796. rsum = auxr = rs2 = rs3 = 0;
  797. Toggle_on ^= 1;
  798. sample_state = collecting;
  799.     }
  800.   } /* if optimize else */
  801.   if ( waitforsignal == 0 ) pStart = (unsigned char *)p;
  802.   else if (any_signal != 0) global.SkippedSamples += ((UINT4 *)pStart - p);
  803.   else global.SkippedSamples += (pSrcStop - p);
  804.   if ( waitforsignal == 0 || any_signal != 0) {
  805.     int retval = 0;
  806.     unsigned outlen;
  807.     assert(pDst >= pStart);
  808.     outlen = (size_t) (pDst - pStart);
  809.     if (outlen <= 0) return 0;
  810. #ifdef ECHO_TO_SOUNDCARD
  811.     /* this assumes the soundcard needs samples in native cpu byte order */
  812.     if (global.echo != 0) {
  813.                static unsigned char *newp;
  814.                unsigned    newlen;
  815.                newlen = (100*(outlen/4))/global.playback_rate;
  816.                newlen = (newlen*4);
  817.                if ( (newp != NULL) || (newp = (unsigned char *) malloc( 2*global.nsectors*CD_FRAMESIZE_RAW+32 )) ) {
  818. newlen = 4*ReSampleBuffer( pStart, newp, outlen/4 );
  819. write_snd_device((char *)newp, newlen);
  820.                }
  821.     }
  822. #endif
  823.     if ( global.no_file != 0 ) {
  824.         *TotSamplesDone += SamplesToDo;
  825.         return 0;
  826.     }
  827.     if ( (!global.need_hostorder && global.need_big_endian == (*in_lendian)) ||
  828.  (global.need_hostorder && global.need_big_endian != MY_BIG_ENDIAN)) {
  829.       if ( global.OutSampleSize > 1) {
  830.         /* change endianness from input sample or native cpu order 
  831.            to required output endianness */
  832.         change_endianness((UINT4 *)pStart, outlen/4);
  833.       }
  834.     }
  835.     if ((unsigned)(retval = write ( global.audio, pStart, outlen )) == outlen) {
  836.         *TotSamplesDone += SamplesToDo;
  837. return 0;
  838.     } else {
  839.         fprintf(stderr, "write(audio, 0x%p, %u) = %dn",pStart,outlen,retval);
  840.         perror("Probably disk space exhausted");
  841.         return 1;
  842.     }
  843.   } else return 0;
  844. }