?? output_linux.c
字號:
/* * * output_linux.c * * Copyright (C) Aaron Holtzman - May 1999 * * This file is part of ac3dec, a free Dolby AC-3 stream decoder. * * ac3dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * ac3dec 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */#ifdef HAVE_CONFIG_H# include <config.h>#endif#include <stdio.h>#include <errno.h>#include <string.h>#include <unistd.h>#include <fcntl.h>#include <math.h>#include <sys/soundcard.h>#include <sys/ioctl.h>#include "ac3.h"#include "decode.h"#include "debug.h"#include "output.h"#include "downmix.h"#include "ring_buffer.h"#define BUFFER_SIZE 1024 static char dev[] = "/dev/dsp";static int fd;//FIXME uncomment all the matlab calls in this module// and you'll get a handy matlab output file// of the signal.//#include "matlab.h"//static matlab_file_t *foo;///* * open the audio device for writing to */int output_open(int bits, int rate, int channels){ int tmp; /* * Open the device driver */ fd=open(dev,O_WRONLY | O_NDELAY); if(fd < 0) { dprintf("%s: Opening audio device %s\n", strerror(errno), dev); goto ERR; } dprintf("Opened audio device \"%s\"\n",dev); fcntl(fd,F_SETFL,O_NONBLOCK); tmp = (32 << 16) | (ffs(1024) - 1); ioctl(fd,SNDCTL_DSP_SETFRAGMENT,&tmp); tmp = bits; ioctl(fd,SNDCTL_DSP_SAMPLESIZE,&tmp); tmp = channels == 2 ? 1 : 0; ioctl(fd,SNDCTL_DSP_STEREO,&tmp); tmp = rate; ioctl(fd,SNDCTL_DSP_SPEED, &tmp); /* Initialize the ring buffer */ rb_init(); //FIXME remove // foo = matlab_open("foo.m"); // return 1;ERR: if(fd >= 0) { close(fd); } return 0;}voidoutput_flush(void){ int i,j = 0; sint_16 *out_buf = 0; i = 0; do { out_buf = rb_begin_read(); if(out_buf) i = write(fd, out_buf,BUFFER_SIZE); else break; if(i == BUFFER_SIZE) { rb_end_read(); j++; } } while(i == BUFFER_SIZE); //FIXME remove //fprintf(stderr,"(output) Flushed %d blocks, wrote %d bytes last frame\n",j,i);}/* * play the sample to the already opened file descriptor */void output_play(bsi_t *bsi,stream_samples_t *samples){ int i; float *left,*right; float norm = 1.0; float left_tmp = 0.0; float right_tmp = 0.0; sint_16 *out_buf; if(fd < 0) return; out_buf = rb_begin_write(); /* Keep trying to dump frames from the ring buffer until we get a * write slot available */ while(!out_buf) { usleep(5000); output_flush(); out_buf = rb_begin_write(); } //FIXME remove //matlab_write(foo,samples->channel[0],512); //Downmix if necessary downmix(bsi,samples); //Determine a normalization constant if the signal exceeds //100% digital [-1.0,1.0] // //perhaps use the dynamic range info to do this instead for(i=0; i< 256;i++) { left_tmp = samples->channel[0][i]; right_tmp = samples->channel[1][i]; if(left_tmp > norm) norm = left_tmp; if(left_tmp < -norm) norm = -left_tmp; if(right_tmp > norm) norm = right_tmp; if(right_tmp < -norm) norm = -right_tmp; } norm = 32000.0/norm; /* Take the floating point audio data and convert it into * 16 bit signed PCM data */ left = samples->channel[0]; right = samples->channel[1]; for(i=0; i < 256; i++) { // if((fabs(*left * norm) > 32768.0) || (fabs(*right * norm) > 32768.0)) // printf("clipping (%f, %f)\n",*left,*right); out_buf[i * 2 ] = (sint_16) (*left++ * norm); out_buf[i * 2 + 1] = (sint_16) (*right++ * norm); } rb_end_write();}voidoutput_close(void){ close(fd);}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -