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

📄 obuffer.cc

📁 ac3的解码程序
💻 CC
字号:
/*   File: obuffer.cc      Description:   Audio output buffer implementation*/#ifdef __GNUG__#pragma implementation#endif#include <stdio.h>#include <stdlib.h>#include <string.h>#include <String.h>#include <unistd.h>#include <fcntl.h>#include <sys/ioctl.h>#include <sys/types.h>#ifndef LINUX#include <stropts.h>#endif#include <fstream.h>#ifdef IRIXextern "C" {#include <dmedia/audio.h>}#endif#ifdef SOLARIS#include <sys/audioio.h>#endif#ifdef LINUX#include <sys/soundcard.h>#endif#include <memory.h>#include <sys/select.h>#include <sys/time.h>  // Time#ifndef LINUXextern "C" {int ioctl(int, int, ...);}#else#define IOCTL(a,b,c)		ioctl(a,b,&c)#endif#include "athread.hh"#include <errno.h>#include "error.hh"#include "debug.hh"#include "util.hh"#include "sync.hh"#include "mpeg2const.hh"#include "mpeg2buff.hh"#include "astream.hh"#include "crc.hh"#include "header.hh"#include "obuffer.hh"ShortObuffer::ShortObuffer(uint32 number_of_channels){#ifdef DEBUG  if (!number_of_channels || number_of_channels > MAXCHANNELS){    String err("ShortObuffer: number of channels has to be in [1, ");    err+=itoa(MAXCHANNELS);    err+="]!";    error(err.chars());    athr_exit(0);  }#endif  channels = number_of_channels;  for (unsigned int i=0; i<number_of_channels; i++) bufferp[i]=buffer+i;}void ShortObuffer::append(uint32 channel, int16 value){#ifdef DEBUG  if (channel >= channels){    error("illegal channelnumber in ShortObuffer::append()!");    athr_exit(0);  }  if (bufferp[channel] - buffer >= OBUFFERSIZE){    error("ShortObuffer: buffer overflow!");    athr_exit(0);  }#endif  *bufferp[channel] = value;  bufferp[channel] += channels;}void ShortObuffer::write_buffer (int fd){  int length = (int)((char *)bufferp[0] - (char *)buffer);  if (write (fd, buffer, length) != length)    warning("couldn't write all samples");  for (unsigned int i=0; i<channels; i++) bufferp[i]=buffer+i;}#ifdef IRIX  IrixObuffer::IrixObuffer(uint32 number_of_channels, Header* header){#ifdef DEBUG  if (!number_of_channels || number_of_channels > MAXCHANNELS){    cerr << "IrixObuffer: number of channels has to be in [1, " <<  MAXCHANNELS << "] !\n";    exit(1);  }#endif  channels = number_of_channels;  for (int i = 0; i < number_of_channels; ++i) bufferp[i] = buffer + i;    // open an audio port and configure it:    ALconfig config;  if (!(config = ALnewconfig())){    error("ALnewconfig failed!");    exit(1);  }  ALsetwidth(config, AL_SAMPLE_16);  if (channels == 1)    ALsetchannels(config, AL_MONO);  else  ALsetchannels(config, AL_STEREO);  if (!(port = ALopenport("MPEG audio player", "w", config))){    error("can't allocate an audio port!");    exit (1);  }    // set sample rate:  long pvbuffer[2] = { AL_OUTPUT_RATE, 0 };  pvbuffer[1] = header->frequency ();  ALsetparams(AL_DEFAULT_DEVICE, pvbuffer, 2);  ALfreeconfig(config);}IrixObuffer::~IrixObuffer(){  while (ALgetfilled(port) > 0) sleep (1);  ALcloseport(port);}// All inline to avoid linking problem!void IrixObuffer::append(uint32 channel, int16 value){#ifdef DEBUG  if (channel >= channels){    error("illegal channelnumber in IrixObuffer::append()!");    athr_exit(0);  }  if (bufferp[channel] - buffer >= OBUFFERSIZE){    error("IrixObuffer: buffer overflow!");    athr_exit(0);  }#endif  *bufferp[channel] = value;  bufferp[channel] += channels;}void IrixObuffer::write_buffer(int /* dummy */){  ALwritesamps(port, buffer, (long)(bufferp[0] - buffer));  for (int i = 0; i < channels; ++i) bufferp[i] = buffer + i;}#endif // IRIX#ifdef SOLARISint SparcObuffer::audio_fd = -1;SparcObuffer::SparcObuffer (uint32 number_of_channels, Header *header,			    bool use_speaker, bool use_headphone, bool use_line_out){  channels=number_of_channels;#ifdef DEBUG  if (!number_of_channels || number_of_channels > MAXCHANNELS){    cerr << "SparcObuffer: 0 < number of channels < " << MAXCHANNELS << "!\n";    exit (1);  }#endif  for (unsigned int i=0; i<number_of_channels; i++) bufferp[i]=buffer+i;  if (audio_fd < 0){    error("SparcObuffer::audio_fd has to be initialized by SparcObuffer::class_suitable()!");    athr_exit(0);  }  // configure the device:  audio_info info;  AUDIO_INITINFO (&info);  info.output_muted = False;  info.play.sample_rate = header->frequency ();  info.play.channels = channels;  info.play.precision = 16;  info.play.encoding = AUDIO_ENCODING_LINEAR;//  info.play.gain=AUDIO_MAX_GAIN/3;  if (use_speaker)    info.play.port |= AUDIO_SPEAKER;  if (use_headphone)    info.play.port |= AUDIO_HEADPHONE;  if (use_line_out)    info.play.port |= AUDIO_LINE_OUT;  info.play.buffer_size=OBUFFERSIZE;  info.play.samples=0;  info.play.eof=0;  info.play.pause=0;  info.play.error=0;  info.play.waiting=0;  info.play.balance = AUDIO_MID_BALANCE;  if (ioctl(audio_fd, AUDIO_SETINFO, &info)){    error("configuration of /dev/audio failed");    athr_exit(0);  }}static int droppedframes=0;static timeval timeout;SparcObuffer::~SparcObuffer (void){  ioctl(audio_fd, AUDIO_DRAIN);  close (audio_fd);  msg("Number of interrupted frames: ");  message(itoa(droppedframes));}void SparcObuffer::append(uint32 channel, int16 value){#ifdef DEBUG  if (channel >= channels){    cerr << "illegal channelnumber in SparcObuffer::append()!\n";    exit (1);  }  if (bufferp[channel] - buffer >= OBUFFERSIZE){    cerr << "buffer overflow!\n";    exit (1);  }#endif  *bufferp[channel] = value;  bufferp[channel] += channels;}void SparcObuffer::write_buffer(int){  int length = (int)((char*) bufferp[0] - (char*) buffer);#ifdef SPARC5  // This stuff seems useful on a SUN Sparc 5   static fd_set wfs;  FD_ZERO(&wfs);  FD_SET(audio_fd, &wfs);  if (select(FD_SETSIZE, 0, &wfs, 0, &timeout)>=0){    if (FD_ISSET(audio_fd, &wfs)){#endif      if (write(audio_fd, buffer, length) != length){        message("Warning: couldn't write all samples to /dev/audio");      }#ifdef SPARC5    }    else {      ioctl(audio_fd, I_FLUSH, FLUSHW);    // flush current stuff and replace by new      msg("flush audio");      droppedframes++;      if (write(audio_fd, buffer, length) != length){        message("Warning: couldn't write all samples to /dev/audio");      }    }  }#endif  for (unsigned int i=0; i<channels; i++) bufferp[i]=buffer+i;}int SparcObuffer::open_audio_device (void){  int fd=0;  // just check  if ((fd=open("/dev/audio", O_WRONLY | O_NDELAY)) < 0) //     if (errno == EBUSY){      cerr << "Sorry, the audio device is busy!\n";      exit (1);    }    else{      perror ("can't open /dev/audio for writing");      exit (1);    }  ioctl(fd, I_FLUSH, FLUSHRW);  close(fd);  /* now open (blocking) // | O_NDELAY)) */  if ((fd=open("/dev/audio", O_WRONLY))< 0){     if (errno == EBUSY){      error("Sorry, the audio device is busy!");      athr_exit(0);    }    else {      error("can't open /dev/audio for writing");      athr_exit(0);    }  }  ioctl(fd, I_FLUSH, FLUSHW);  // next time out  timeout.tv_sec=0;             // length/5513;  // length/5513=length*8 / 44100 (bps)   timeout.tv_usec=752600;  // (long int) (length*181);   // length*181= length*8/ 44100 * 1000000}void SparcObuffer::get_device_type (int fd, audio_device *devtype){  if (ioctl (fd, AUDIO_GETDEV, devtype)){    error("ioctl on /dev/audio");    athr_exit(0);  }}bool SparcObuffer::class_suitable (void){  audio_fd=open_audio_device();      // check for the CS4231 or dbri audio device  audio_device devtype;  get_device_type(audio_fd, &devtype);  // Sparc 5: CS4321, Sparc 10: dbri  return (!strcmp (devtype.name, "SUNW,CS4231") || !strcmp (devtype.name, "SUNW,dbri")) ? True : False;}#endif // SOLARIS#ifdef LINUXint LinuxObuffer::audio_fd = -1;LinuxObuffer::LinuxObuffer (uint32 number_of_channels,Header *header) {  int abuf_size;  int sample_rate;  int sample_bits=16;  int chan = channels=number_of_channels;  #ifdef DEBUG  if (!number_of_channels || number_of_channels > MAXCHANNELS){    cerr << "LinuxObuffer: 0 < number of channels < " << MAXCHANNELS << "!\n";    exit (1);  }#endif  for (unsigned int i=0; i<number_of_channels; i++) bufferp[i]=buffer+i;  if (audio_fd < 0){    error("LinuxObuffer::audio_fd has to be initialized by LinuxObuffer::class_suitable()!");    athr_exit(0);  }  IOCTL(audio_fd, SNDCTL_DSP_GETBLKSIZE, abuf_size);  if (abuf_size < 4096 || abuf_size > 65536) {    if (abuf_size == -1) {      error ("LinuxObuffer::abufsize failure");    } else {      error("Invalid audio buffers size \n");    }    athr_exit (0);  }  // configure the device:  sample_rate = header->frequency ();  if (IOCTL(audio_fd, SNDCTL_DSP_SPEED, sample_rate) < 0) {    error("unable to set audio speed");    athr_exit (0);  }  if ( IOCTL(audio_fd, SNDCTL_DSP_CHANNELS, chan) < 0 ) {    printf("LinuxObuffer::amount of channels (%d) not supported\n",chan);    athr_exit(0);  }  chan--;  if ( IOCTL(audio_fd, SNDCTL_DSP_STEREO, chan) < 0 ) {    printf("LinuxObuffer::Error when setting stereo\n");    athr_exit(0);  }  IOCTL(audio_fd, SNDCTL_DSP_SAMPLESIZE, sample_bits);}static int droppedframes=0;static timeval timeout;LinuxObuffer::~LinuxObuffer (void){  ioctl(audio_fd, SNDCTL_DSP_SYNC,NULL);  close (audio_fd);  msg("Number of interrupted frames: ");  message(itoa(droppedframes));}void LinuxObuffer::append(uint32 channel, int16 value){#ifdef DEBUG  if (channel >= channels){    cerr << "illegal channelnumber in SparcObuffer::append()!\n";    exit (1);  }  if (bufferp[channel] - buffer >= OBUFFERSIZE){    cerr << "buffer overflow!\n";    exit (1);  }#endif  *bufferp[channel] = value;  bufferp[channel] += channels;}void LinuxObuffer::write_buffer(int){  int length = (int)((char*) bufferp[0] - (char*) buffer);      if (write(audio_fd, buffer, length) != length){        message("Warning: couldn't write all samples to /dev/audio");      }  for (unsigned int i=0; i<channels; i++) bufferp[i]=buffer+i;}int LinuxObuffer::open_audio_device (void){  int fd=0;  // just check  if ((fd=open("/dev/dsp", O_WRONLY | O_NDELAY)) < 0) //     if (errno == EBUSY){      cerr << "Sorry, the audio device is busy!\n";      exit (1);    }    else{      perror ("can't open /dev/audio for writing");      exit (1);    }  ioctl(fd, SNDCTL_DSP_SYNC,NULL);  close(fd);  /* now open (blocking) // | O_NDELAY)) */  if ((fd=open("/dev/dsp", O_WRONLY))< 0){     if (errno == EBUSY){      error("Sorry, the audio device is busy!");      athr_exit(0);    }    else {      error("can't open /dev/audio for writing");      athr_exit(0);    }  }  ioctl(fd, SNDCTL_DSP_SYNC,NULL);  // next time out  timeout.tv_sec=0;             // length/5513;  // length/5513=length*8 / 44100 (bps)   timeout.tv_usec=752600;  // (long int) (length*181);   // length*181= length*8/ 44100 * 1000000  return fd;}bool LinuxObuffer::class_suitable (void){  audio_fd=open_audio_device();      // check for audio device  if (audio_fd == -1)    return False;  return True;}#endif // LINUX

⌨️ 快捷键说明

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