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

📄 audio_oss.c

📁 从 IEEE 1394总线接收传输流
💻 C
字号:
/* this file from mpg123 was adapted for mpeg2ts1394dec to provide a function which returns   the current delay of the kernel audio buffer and a function to delay audio by filling the buffer * Copyright (C) 2000-2007, Manfred Weihs <mweihs@users.sourceforge.net>*/#include <sys/types.h>#include <stdio.h>#include <unistd.h>#include <fcntl.h>#include <stdlib.h>#include "mpg123.h"#ifndef AFMT_S16_NE# ifdef OSS_BIG_ENDIAN#  define AFMT_S16_NE AFMT_S16_BE# else#  define AFMT_S16_NE AFMT_S16_LE# endif#endif#ifndef AFMT_U16_NE# ifdef OSS_BIG_ENDIAN#  define AFMT_U16_NE AFMT_U16_BE# else#  define AFMT_U16_NE AFMT_U16_LE# endif#endifextern int outburst;static int current_sample_rate; //added to allow calculation of audio_delay#include <sys/ioctl.h>#include <linux/soundcard.h>int audio_open(struct audio_info_struct *ai){	int r; //auxiliary variable for setting fragments  if(!ai)    return -1;  if(!ai->device)    ai->device = "/dev/dsp";  ai->fn = open(ai->device,O_WRONLY);    if(ai->fn < 0)  {    fprintf(stderr,"Can't open %s!\n",ai->device);    exit(1);  }  r=0x7fff0008;                                           //set fragment size to a suitable  if (ioctl(ai->fn,SNDCTL_DSP_SETFRAGMENT,&r) == -1)      //(small) value, to enhance    {fprintf(stderr,"cannot set fragment size");exit (1);}//accuracy of timing calculation  ioctl(ai->fn, SNDCTL_DSP_GETBLKSIZE, &outburst);  if(outburst > MAXOUTBURST)    outburst = MAXOUTBURST;  if(audio_reset_parameters(ai) < 0) {    close(ai->fn);    return -1;  }  if(ai->gain >= 0) {    int e,mask;    e = ioctl(ai->fn , SOUND_MIXER_READ_DEVMASK ,&mask);    if(e < 0) {      fprintf(stderr,"audio/gain: Can't get audio device features list.\n");    }    else if(mask & SOUND_MASK_PCM) {      int gain = (ai->gain<<8)|(ai->gain);      e = ioctl(ai->fn, SOUND_MIXER_WRITE_PCM , &gain);    }    else if(!(mask & SOUND_MASK_VOLUME)) {      fprintf(stderr,"audio/gain: setable Volume/PCM-Level not supported by your audio device: %#04x\n",mask);    }    else {       int gain = (ai->gain<<8)|(ai->gain);      e = ioctl(ai->fn, SOUND_MIXER_WRITE_VOLUME , &gain);    }  }  return ai->fn;}int audio_reset_parameters(struct audio_info_struct *ai){  int ret;  ret = ioctl(ai->fn,SNDCTL_DSP_RESET,NULL);  if(ret < 0)    fprintf(stderr,"Can't reset audio!\n");  ret = audio_set_format(ai);  ret = audio_set_channels(ai);  ret = audio_set_rate(ai);  return ret;}static int audio_get_parameters(struct audio_info_struct *ai){	int c=-1;	int r=-1;	int f=-1;	if(ioctl(ai->fn,SNDCTL_DSP_SPEED,&r) < 0)		return -1;	if(ioctl(ai->fn,SNDCTL_DSP_STEREO,&c) < 0)		return -1;	if(ioctl(ai->fn,SNDCTL_DSP_SETFMT,&f) < 0)		return -1;	ai->rate = r;	ai->channels = c + 1;	ai->format = f;  current_sample_rate=r;	return 0;}int audio_rate_best_match(struct audio_info_struct *ai){  int ret,dsp_rate;  if(!ai || ai->fn < 0 || ai->rate < 0)    return -1;  dsp_rate = ai->rate;  ret = ioctl(ai->fn, SNDCTL_DSP_SPEED,&dsp_rate);  if(ret < 0)    return ret;  ai->rate = dsp_rate;	current_sample_rate=dsp_rate;  return 0;}int audio_set_rate(struct audio_info_struct *ai){  int dsp_rate;  int ret = 0;  if(ai->rate >= 0) {    dsp_rate = ai->rate;    ret = ioctl(ai->fn, SNDCTL_DSP_SPEED,&dsp_rate);		current_sample_rate=dsp_rate; //needed for calcultion of audio buffer delay  }  return ret;}int audio_set_channels(struct audio_info_struct *ai){  int chan = ai->channels - 1;  int ret;  if(ai->channels < 0)    return 0;  ret = ioctl(ai->fn, SNDCTL_DSP_STEREO, &chan);  if(chan != (ai->channels-1)) {    return -1;  }  return ret;}int audio_set_format(struct audio_info_struct *ai){  int sample_size,fmts;  int sf,ret;  if(ai->format == -1)    return 0;  switch(ai->format) {    case AUDIO_FORMAT_SIGNED_16:    default:      fmts = AFMT_S16_NE;      sample_size = 16;      break;    case AUDIO_FORMAT_UNSIGNED_8:      fmts = AFMT_U8;      sample_size = 8;      break;    case AUDIO_FORMAT_SIGNED_8:      fmts = AFMT_S8;      sample_size = 8;      break;    case AUDIO_FORMAT_ULAW_8:      fmts = AFMT_MU_LAW;      sample_size = 8;      break;    case AUDIO_FORMAT_ALAW_8:      fmts = AFMT_A_LAW;      sample_size = 8;      break;    case AUDIO_FORMAT_UNSIGNED_16:      fmts = AFMT_U16_NE;      break;  }#if 0  if(ioctl(ai->fn, SNDCTL_DSP_SAMPLESIZE,&sample_size) < 0)    return -1;#endif  sf = fmts;  ret = ioctl(ai->fn, SNDCTL_DSP_SETFMT, &fmts);  if(sf != fmts) {    return -1;  }  return ret;}/* * get formats for specific channel/rate parameters */int audio_get_formats(struct audio_info_struct *ai){  int fmt = 0;  int r = ai->rate;  int c = ai->channels;  int i;  static int fmts[] = { 	AUDIO_FORMAT_ULAW_8 , AUDIO_FORMAT_SIGNED_16 ,	AUDIO_FORMAT_UNSIGNED_8 , AUDIO_FORMAT_SIGNED_8 ,	AUDIO_FORMAT_UNSIGNED_16 , AUDIO_FORMAT_ALAW_8 };	  for(i=0;i<6;i++) {	ai->format = fmts[i];	if(audio_set_format(ai) < 0) {		continue;        }	ai->channels = c;	if(audio_set_channels(ai) < 0) {		continue;	}	ai->rate = r;	if(audio_rate_best_match(ai) < 0) {		continue;	}	if( (ai->rate*100 > r*(100-AUDIO_RATE_TOLERANCE)) && (ai->rate*100 < r*(100+AUDIO_RATE_TOLERANCE)) ) {		fmt |= fmts[i];	}  }#if 0  if(ioctl(ai->fn,SNDCTL_DSP_GETFMTS,&fmts) < 0) {fprintf(stderr,"No");    return -1;  }  if(fmts & AFMT_MU_LAW)    ret |= AUDIO_FORMAT_ULAW_8;  if(fmts & AFMT_S16_NE)    ret |= AUDIO_FORMAT_SIGNED_16;  if(fmts & AFMT_U8)    ret |= AUDIO_FORMAT_UNSIGNED_8;  if(fmts & AFMT_S8)    ret |= AUDIO_FORMAT_SIGNED_8;  if(fmts & AFMT_U16_NE)    ret |= AUDIO_FORMAT_UNSIGNED_16;  if(fmts & AFMT_A_LAW)    ret |= AUDIO_FORMAT_ALAW_8;#endif  return fmt;}int audio_play_samples(struct audio_info_struct *ai,unsigned char *buf,int len){#ifdef PPC_ENDIAN#define BYTE0(n) ((unsigned char)(n) & (0xFF))#define BYTE1(n) BYTE0((unsigned int)(n) >> 8)#define BYTE2(n) BYTE0((unsigned int)(n) >> 16)#define BYTE3(n) BYTE0((unsigned int)(n) >> 24)   {     register int i;     int swappedInt;     int *intPtr;     intPtr = (int *)buf;     for (i = 0; i < len / sizeof(int); i++)       {         swappedInt = (BYTE0(*intPtr) << 24 |                       BYTE1(*intPtr) << 16 |                       BYTE2(*intPtr) <<  8 |                       BYTE3(*intPtr)         );         *intPtr = swappedInt;         intPtr++;       }    }#endif /* PPC_ENDIAN */  return write(ai->fn,buf,len);}int audio_close(struct audio_info_struct *ai){  close (ai->fn);  return 0;}long int get_audio_delay(struct audio_info_struct *ai) //returns the delay of audio output in{                                                      //units of 1/90000 seconds	int sample_size; //sample size in bytes//	audio_buf_info info; //audio buffer info structure	int audio_delay_bytes;  switch(ai->format) {    case AUDIO_FORMAT_UNSIGNED_8:    case AUDIO_FORMAT_SIGNED_8:    case AUDIO_FORMAT_ULAW_8:    case AUDIO_FORMAT_ALAW_8:      sample_size = 1;      break;    default:      sample_size = 2;      break;  }	sample_size=sample_size*ai->channels;	if (ioctl(ai->fn, SNDCTL_DSP_GETODELAY,&audio_delay_bytes) == -1)		{fprintf(stderr,"cannot read audio buffer delay\n");exit(1);};//	fprintf(stderr,", audio buffer delay (bytes): %i, ",audio_delay_bytes);	return (90000ll*audio_delay_bytes) / (current_sample_rate*sample_size);}//delays audio output by stuffing the audio buffer with zeros (delay is in units of 1/90000 seconds)void audio_buffer_fill(struct audio_info_struct *ai,long long int delay){		int sample_size; //sample size in bytes	static unsigned char buffer[256]; //FIXME: should be filled with zeros	int fragments,i; //number of fragments to write to output  switch(ai->format) {    case AUDIO_FORMAT_UNSIGNED_8:    case AUDIO_FORMAT_SIGNED_8:    case AUDIO_FORMAT_ULAW_8:    case AUDIO_FORMAT_ALAW_8:      sample_size = 1;      break;    default:      sample_size = 2;      break;  }	sample_size=sample_size*ai->channels;	fragments=(delay*current_sample_rate*sample_size)/(90000*256);	for (i=0;i<fragments;i++)		(void) audio_play_samples(ai,buffer,256);	fprintf(stderr,"%i empty fragments written\n",fragments);}

⌨️ 快捷键说明

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