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

📄 audiobuffer.c

📁 从 IEEE 1394总线接收传输流
💻 C
字号:
/* * MPEG2-TS over IEEE 1394 decoder - receive and decode MPEG-2 transport *                                   streams according to IEC 61883-4 * * Copyright (C) 2000-2007, Manfred Weihs <mweihs@users.sourceforge.net> * * This program 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 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include <stdlib.h>#include <stdio.h>#include <pthread.h>#include "synchronisation.h"#include "audiobuffer.h"#include "common.h"extern int debug;struct audiobuffer_entry audiobuffer[AUDIOFRAMESINBUFFER];volatile int audiobufferstart,audiobufferend;sem_t audiobuffer_sem;void play_frame(struct frame *);int initmpegaudioplayer(struct frame *fr);int donempegaudioplayer();long int get_audio_delay(struct audio_info_struct *ai);//FIXME: put this into .h-filevoid audio_buffer_fill(struct audio_info_struct *ai,long long int delay);extern struct audio_info_struct ai;extern struct bitstream_info bsi;extern unsigned char *bsbuf, *bsbufold;extern int fsizeold,ssize;static struct frame fr;	/* standard-frame */static pthread_t audio_decoder_thread;static volatile int terminate_decoder;#if ! SIMPLE_SYNCHRONISATIONstatic long long int integrator;#define PLL_I_CONSTANT 100000#define PLL_P_CONSTANT 1000#endif#define MAX_DEVIATION  9000int prepareandplayframe(){	if (audiobufferstart == audiobufferend) /* should never happen, since we use semaphore */	{		fprintf(stderr,"no frame in buffer\n");		return 0;	}	else	{		struct audiobuffer_entry *aubufakt=&audiobuffer[audiobufferstart], *aubufold=&audiobuffer[(audiobufferstart+AUDIOFRAMESINBUFFER-1) % AUDIOFRAMESINBUFFER];		bsbuf=aubufakt->buffer+512;		bsbufold=aubufold->buffer+512;		bsi.bitindex=0;		bsi.wordpointer= bsbuf;		ssize=aubufakt->ssize;		fsizeold= aubufold->fr.framesize;/*			These parts of frame are changed by play_frame and must therefore be saved between the frames			aubufakt->fr.alloc=aubufold->fr.alloc;			aubufakt->fr.II_sblimit=aubufold->fr.II_sblimit;			aubufakt->fr.jsbound=aubufold->fr.jsbound;			aubufakt->fr.single=aubufold->fr.single;			aubufakt->fr.down_sample=aubufold->fr.down_sample;			aubufakt->fr.down_sample_sblimit=aubufold->fr.down_sample_sblimit;			aubufakt->fr.synth=aubufold->fr.synth;			aubufakt->fr.synth_mono=aubufold->fr.synth_mono;*//*    These parts of frame are set by decoder and must be put into the frame data which is used to play the frame  */		fr.stereo=aubufakt->fr.stereo;		fr.lsf=aubufakt->fr.lsf;		fr.mpeg25=aubufakt->fr.mpeg25;		fr.header_change=aubufakt->fr.header_change;		fr.lay=aubufakt->fr.lay;		fr.do_layer=aubufakt->fr.do_layer;		fr.error_protection=aubufakt->fr.error_protection;		fr.bitrate_index=aubufakt->fr.bitrate_index;		fr.sampling_frequency=aubufakt->fr.sampling_frequency;		fr.padding=aubufakt->fr.padding;		fr.extension=aubufakt->fr.extension;		fr.mode=aubufakt->fr.mode;		fr.mode_ext=aubufakt->fr.mode_ext;		fr.copyright=aubufakt->fr.copyright;		fr.original=aubufakt->fr.original;		fr.emphasis=aubufakt->fr.emphasis;		fr.framesize=aubufakt->fr.framesize;		if (aubufakt->havepts && is_sync_enabled()) /* check synchronisation */		{			long long stc = getSTC();			long long int deviation=(long long int) aubufakt->pts - stc; /* how long shall we delay this frame */			long long int audio_delay;			/* fprintf(stderr,"Audio deviation uncompensated: %Li , pts: %Li, stc: %Li ",deviation,aubufakt->pts,stc); */			/* compensate overflow in pcr or dts */			/* bring difference into the interval [-4294967296;4294967295] */			if (deviation < -4294967296ll) /* is in [-8589934591;-4294967297] */				deviation +=8589934592ll;			else if (deviation > 4294967295ll) /* is in [4294967296;8589934591] */				deviation -= 8589934592ll;			audio_delay=get_audio_delay(&ai);			/* fprintf(stderr," audio buffer delay: %Li, ",audio_delay); */			deviation -= audio_delay; /* add delay of kernel audio driver buffer */			if (debug) {				fprintf(stdout,"Audio deviation: %Li ,",deviation);			}			if (deviation > MAX_DEVIATION) /* we are 0,1 s to early */			{				if (deviation > (90000*3)) { /* more than 3 second too early */					fprintf(stderr,"Audio frame more than 3 seconds too early, it seems we lost synchronisation, comensating just 0.1 s.\n");					audio_buffer_fill(&ai,9000); /* fill the audio buffer with zeros to compensate deviation */				} else {					audio_buffer_fill(&ai,deviation); /* fill the audio buffer with zeros to compensate deviation */				}				/* now the deviation is compensated, so we now can play the frame at its scheduled time */				play_frame(&fr); //play the frame			}			else if (deviation < -MAX_DEVIATION) /* we are 0,1 s late */			{ //drop this frame				if (fr.lay == 3)   // I do not know, why we need this for layer III, ...					set_pointer(512);// but since mpg123 does it when dropping frames, it should be correct...				fprintf(stderr,"Audio frame dropped, because we are decoding too slowly (synchronisation)\n");			}			else /* if |deviation| is < MAX_DEVIATION, we use the PI-controller */			{#if ! SIMPLE_SYNCHRONISATION				/* this code acts as a PLL. It implements a kind of PI-controller */				integrator += deviation; /* integrate deviations -> this should stay approximately constant, when we have the correct frequency */				if (debug) {					fprintf(stdout," integrator: %Li ,",integrator);				}				if (integrator > freqs[fr.sampling_frequency] * PLL_I_CONSTANT / 5) /* limit I-component to 20% of dsp sample rate */					{integrator= freqs[fr.sampling_frequency] * PLL_I_CONSTANT / 5;if (debug) fprintf(stdout,"integrator limited upper bound,");}				else if (integrator < -freqs[fr.sampling_frequency] * PLL_I_CONSTANT / 5)					{integrator= -freqs[fr.sampling_frequency] * PLL_I_CONSTANT / 5;if (debug) fprintf(stdout,"integrator limited lower bound,");}				if (deviation > freqs[fr.sampling_frequency] * PLL_P_CONSTANT / 5) /* limit P-component to 20% of dsp sample rate */					{deviation= freqs[fr.sampling_frequency] * PLL_P_CONSTANT / 5;if (debug) fprintf(stdout,"p component limited upper bound,");}				else if (deviation < -freqs[fr.sampling_frequency] * PLL_P_CONSTANT / 5)					{deviation= -freqs[fr.sampling_frequency] * PLL_P_CONSTANT / 5;if (debug) fprintf(stdout,"p component limited lower bound,");}				long n = freqs[fr.sampling_frequency] - (integrator / PLL_I_CONSTANT) - (deviation / PLL_P_CONSTANT);				long m = ai.rate;				synth_ntom_set_step(n,m);				if(n>m) {					fr.down_sample_sblimit = SBLIMIT * m;					fr.down_sample_sblimit /= n;					if (debug) {						fprintf(stdout,"Audio sampling set to: %2.4f:1 conversion",(float)n/(float)m);					}				}				else {					fr.down_sample_sblimit = SBLIMIT;					if (debug) {						fprintf(stderr,"Audio sampling set to: 1:%2.4f conversion",(float)m/(float)n);					}				}				init_layer3(fr.down_sample_sblimit);#endif				if (debug) {					fprintf(stdout,"\n");				}				play_frame(&fr);			}		}		else /* if we have no sync info (dts), we just play the frame */			play_frame(&fr);		audiobufferstart=(audiobufferstart+1) % AUDIOFRAMESINBUFFER;		return 1;	}}static void* audio_decoder_thread_function(void *arg){	while (!terminate_decoder)	{		if (sem_wait(&audiobuffer_sem)) /* wait for frame in buffer */		{			fprintf(stderr,"Cannot P semaphore\n");			exit(0);		}		if (!terminate_decoder) /* if we shall not yet terminate the decoder */			(void) prepareandplayframe();	}	donempegaudioplayer();	return 0; /* terminate thread */}int audio_system_init(){	if (!initmpegaudioplayer(&fr))	{		fprintf(stderr,"Cannot initialize audio subsystem");		exit(1);	}	audiobufferstart=audiobufferend=0;	terminate_decoder=0;#if ! SIMPLE_SYNCHRONISATION	integrator=0; /* initialize PLL */#endif	if (sem_init(&audiobuffer_sem,0,0))	{		fprintf(stderr,"Cannot create audio semaphore\n");		exit(1);	}	if (pthread_create(&audio_decoder_thread,NULL,audio_decoder_thread_function,0))	{		fprintf(stderr,"Cannot create audio decoder thread\n");		exit(1);	}	return 1;}int audio_system_done(){	void *result;	terminate_decoder=1;	if (sem_post(&audiobuffer_sem))  /* we do this to ensure that the thread is activated */	{		fprintf(stderr,"Cannot V semaphore\n");		exit(0);	}	if (pthread_join(audio_decoder_thread,&result))	/* wait for thread to exit */	{		fprintf(stderr,"Cannot join audio decoder thread\n");		exit(1);	}	if (debug) {		fprintf(stdout,"Audio decoder terminated\n");fflush(stdout);	}	if (sem_destroy(&audiobuffer_sem))	{		fprintf(stderr,"Cannot destroy audio semaphore\n");		exit(1);	}	return 1;}

⌨️ 快捷键说明

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