output_linux.c
上传用户:aoeyumen
上传日期:2007-01-06
资源大小:3329k
文件大小:4k
源码类别:

DVD

开发平台:

Unix_Linux

  1. /*
  2.  *
  3.  *  output_linux.c
  4.  *    
  5.  * Copyright (C) Aaron Holtzman - May 1999
  6.  *
  7.  *  This file is part of ac3dec, a free Dolby AC-3 stream decoder.
  8.  *
  9.  *  ac3dec is free software; you can redistribute it and/or modify
  10.  *  it under the terms of the GNU General Public License as published by
  11.  *  the Free Software Foundation; either version 2, or (at your option)
  12.  *  any later version.
  13.  *   
  14.  *  ac3dec is distributed in the hope that it will be useful,
  15.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  *  GNU General Public License for more details.
  18.  *   
  19.  *  You should have received a copy of the GNU General Public License
  20.  *  along with GNU Make; see the file COPYING.  If not, write to
  21.  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
  22.  *
  23.  *
  24.  */
  25. #ifdef HAVE_CONFIG_H
  26. #  include <config.h>
  27. #endif
  28. #include <stdio.h>
  29. #include <errno.h>
  30. #include <string.h>
  31. #include <unistd.h>
  32. #include <fcntl.h>
  33. #include <math.h>
  34. #include <sys/soundcard.h>
  35. #include <sys/ioctl.h>
  36. #include "ac3.h"
  37. #include "decode.h"
  38. #include "debug.h"
  39. #include "output.h"
  40. #include "downmix.h"
  41. static char dev[] = "/dev/dsp";
  42. static int fd;
  43. //FIXME uncomment all the matlab calls in this module
  44. //      and you'll get a handy matlab output file
  45. //      of the signal.
  46. //#include "matlab.h"
  47. //static matlab_file_t *foo;
  48. //
  49. /*
  50.  * open the audio device for writing to
  51.  */
  52. int output_open( void )
  53. {
  54.   int bits = 16;
  55.   int rate = 48000;
  56.   int stereo = 1;
  57.   int frag = 0x7fff000A; /* 2^10 = 1024 */
  58.   
  59.   /* open device */
  60.   if ((fd = open( dev, O_WRONLY )) == -1) {
  61.     perror(dev);
  62.     return 0;
  63.   }
  64.   /* set sample size */
  65.   if (ioctl(fd, SNDCTL_DSP_SAMPLESIZE, &bits) == -1) {
  66.     perror("SNDCTL_DSP_SAMPLESIZE");
  67.     return 0;
  68.   }
  69.   if (bits != 16) {
  70.     fprintf( stderr, "Device does not support 16 bit samplesn");
  71.     return 0;
  72.   }
  73.   /* set number of channels */
  74.   if (ioctl(fd, SNDCTL_DSP_STEREO, &stereo) == -1) {
  75.     perror("SNDCTL_DSP_STEREO");
  76.     return 0;
  77.   }
  78.   if (stereo != 1) {
  79.     fprintf( stderr, "Device does not support stereon");
  80.     return 0;
  81.   }
  82.   /* set sample rate */
  83.   if (ioctl(fd, SNDCTL_DSP_SPEED, &rate) == -1) {
  84.     perror("SNDCTL_DSP_SPEED");  
  85.   return 0;
  86. }
  87.   if (rate != 48000) {
  88.     fprintf( stderr, "Device does not support %d, appears to support %dn",
  89.              48000, rate );
  90.   }
  91.   /* set fragment size */
  92.   if (ioctl( fd, SNDCTL_DSP_SETFRAGMENT, &frag ) == -1) {
  93.     perror("SNDCTL_DSP_SETFRAGMENT");
  94.     return 0;
  95.   }
  96.   if (ioctl(fd, SNDCTL_DSP_GETBLKSIZE, &frag) == -1) {
  97.     perror("SNDCTL_DSP_GETBLKSIZE");
  98.     return 0;
  99. }
  100.   
  101.   if (frag != 1024) {
  102.     fprintf( stderr, "Device does not support fragment size of 1024n" );
  103.     return 0;
  104. }
  105.   return 1;
  106. }
  107. /*
  108.  * play the sample to the already opened file descriptor
  109.  */
  110. void output_play(bsi_t *bsi,stream_samples_t *samples)
  111. {
  112.   int i;
  113. float *left,*right;
  114. float norm = 1.0;
  115. float left_tmp = 0.0;
  116. float right_tmp = 0.0;
  117.   sint_16 out_buf[1024];
  118. if(fd < 0)
  119. return;
  120. //FIXME remove
  121. //matlab_write(foo,samples->channel[0],512);
  122. //Downmix if necessary 
  123. downmix(bsi,samples);
  124. //Determine a normalization constant if the signal exceeds 
  125. //100% digital [-1.0,1.0]
  126. //
  127. //perhaps use the dynamic range info to do this instead
  128. for(i=0; i< 256;i++)
  129. {
  130.     left_tmp = samples->channel[0][i];
  131.     right_tmp = samples->channel[1][i];
  132. if(left_tmp > norm)
  133. norm = left_tmp;
  134. if(left_tmp < -norm)
  135. norm = -left_tmp;
  136. if(right_tmp > norm)
  137. norm = right_tmp;
  138. if(right_tmp < -norm)
  139. norm = -right_tmp; 
  140. }
  141.   norm = 32768.0/norm;
  142. /* Take the floating point audio data and convert it into
  143.  * 16 bit signed PCM data */
  144. left = samples->channel[0];
  145. right = samples->channel[1];
  146. for(i=0; i < 256; i++)
  147. {
  148. // if((fabs(*left * norm) > 32768.0) || (fabs(*right * norm) > 32768.0))
  149. // printf("clipping (%f, %f)n",*left,*right);
  150. out_buf[i * 2 ]    = (sint_16) (*left++  * norm);
  151. out_buf[i * 2 + 1] = (sint_16) (*right++ * norm);
  152.     }
  153.   if (write(fd, out_buf, 1024) != 1024) {
  154.     fprintf( stderr, "Bytes written not 1024n" );
  155. }
  156. }
  157. void
  158. output_close(void)
  159. {
  160. close(fd);
  161. }