All pastes #2101259 Raw Edit

vikky

public c v1 · immutable
#2101259 ·published 2012-01-08 18:52 UTC
rendered paste body
/*   xine_driver.c - Xine audio driver   See README for Copyright and License*/#include "audio.h"#include "xine_driver.h"#include <stdlib.h>static xine_t			*xine;static xine_stream_t		*stream;static xine_stream_t		*mstream;static xine_audio_port_t	*ao_port;static xine_event_queue_t	*event_queue;static char *audio_output;const char *AUDIO_get_driver(AUDIO_SESSION *s){	return audio_output;}int AUDIO_get_drivers(AUDIO_SESSION *s,char *buffer){	const char *const *driver_ids;	int i,length;	driver_ids = xine_list_audio_output_plugins (xine);	length = sprintf(buffer,"%s,", "auto");	for(i=0;driver_ids[i];i++){		length += sprintf(buffer+length,"%s,", driver_ids[i]);	}	return 0;}int AUDIO_is_audio(AUDIO_SESSION *s,const char *url){	char *cptr;	int rv;	if(!url || !mstream){		printf("AUDIO_is_audio error\n");		return 1;	}	/* First Pass file filter */	cptr = strrchr(url,'.');	if(cptr){		/* In order from MOST likely to LEAST likely */		if(!strcasecmp(cptr,".jpg"))return 1;		if(!strcasecmp(cptr,".png"))return 1;		if(!strcasecmp(cptr,".gif"))return 1;		if(!strcasecmp(cptr,".jpeg"))return 1;	}			if(!xine_open(mstream,url))return 1;			/* Second Pass file filter */	/* FIXME: Find a better/faster way of filtering streams */	// Note: INFO_AUDIO_HANDLED is true for pictures 	rv = xine_get_stream_info(mstream,XINE_STREAM_INFO_AUDIO_HANDLED);	xine_close(mstream);		return !rv;}int AUDIO_get_metadata(AUDIO_SESSION *s, const char *url, AUDIO_metadata *mdata){	const char *info;	int length=0;	if(!mstream){		printf("AUDIO_get_metedata: No metadata stream loaded\n");		return 1;	}	/* Clear out the meta struct */	AUDIO_zero_metadata(mdata);	if(!xine_open(mstream,url)){		printf("AUDIO_get_metedata: Could not open stream = '%s'\n",url);		return 1;	}	/* Copy metadata into meta data struct */	info=xine_get_meta_info (mstream,XINE_META_INFO_TITLE );	if(info)strncpy(mdata->title,info,LONG_FIELD);	info =xine_get_meta_info (mstream,XINE_META_INFO_ARTIST );	if(info)strncpy(mdata->artist,info,LONG_FIELD);	info = xine_get_meta_info (mstream,XINE_META_INFO_ALBUM );	if(info)strncpy(mdata->album,info,LONG_FIELD);	info = xine_get_meta_info (mstream,XINE_META_INFO_YEAR );	if(info)mdata->year = atoi(info);	info = xine_get_meta_info (mstream,XINE_META_INFO_TRACK_NUMBER);	/* info = "[Track No]/[Track Count]" */	if(info)mdata->track = atoi(info);	xine_get_pos_length (mstream,NULL,NULL,&length);	mdata->length = length / 1000; // xine gives us ms 	info = xine_get_meta_info (mstream,XINE_META_INFO_DISCNUMBER);	if(info)mdata->disc = atoi(info);        mdata->title [LONG_FIELD-1]=0;        mdata->artist[LONG_FIELD-1]=0;        mdata->album [LONG_FIELD-1]=0;	xine_close(mstream);		return 0;}int AUDIO_driver_init(AUDIO_SESSION *s, const char *audiodriver){	printf("XINE_driver - init, ao=%s\n",audiodriver);	char configfile[256];	audio_output = NULL;	xine = NULL;	xine = xine_new();	sprintf(configfile, "%s/%s", getenv("HOME"), ".xine/config");	xine_config_load(xine,configfile);	xine_init(xine);	/* Open playback stream */	ao_port = xine_open_audio_driver(xine , audiodriver, NULL);	stream = xine_stream_new(xine, ao_port,NULL);	/* Register stream with event callback */	event_queue = xine_event_new_queue(stream);	xine_event_create_listener_thread(event_queue, 		XINE_DRIVER_event_listener,s);		/* Open a stream with no drivers for meta data collection */	mstream = xine_stream_new(xine, NULL,NULL);	printf("Status: %i\n",xine_get_error(mstream));	if(!mstream){		printf("AUDIO init error\n");		return 1;	}	audio_output = strdup(audiodriver);	return 0;}int AUDIO_play(AUDIO_SESSION *s,char *url, int seek){	int rv=0;	if(url== NULL) goto just_play;	xine_close(stream); // will this stop the leak?	rv = xine_open(stream, url);	/* XINE uses negative logic, 1=OK, 0=BAD */	if(!rv){		fprintf(stderr,"ERROR: AUDIO_play: Cannot open stream: %s\n",url);		fprintf(stderr,"ERROR: AUDIO_play: Xine Error %i\n",			xine_get_error(stream));		fprintf(stderr,"ERROR: AUDIO_play: Xine Status %i\n",			xine_get_status(stream));		return 1;	}	if(s->url){		free(s->url);	}	s->url = strdup(url);	/* Get the stream length for our audio session */	int blah;	xine_get_pos_length(stream,&blah,&blah,&s->length);	s->length = (s->length+500)/1000; // Xine returns in milliseconds 	time(&s->start_time);	just_play:	/* NULL position */	if(seek < 0 ) seek = 0;	rv = xine_play(stream, 0, seek*1000);	if(!rv){		fprintf(stderr,"ERROR: AUDIO_play: Cannot play stream: %s\n",url);		return 1;	}	s->playing = 1;	/* Dont inform the GUI if we are just seeking */	if(!seek && s->AUDIO_UI_caller){		s->AUDIO_UI_caller(AUDIO_START,s->cdata);	}	return 0;}int AUDIO_pause(AUDIO_SESSION *s){	int param;	param = xine_get_param(stream,XINE_PARAM_SPEED);	if(param == XINE_SPEED_PAUSE){		xine_set_param(stream,XINE_PARAM_SPEED,XINE_SPEED_NORMAL);		return 0;	}else if (param == XINE_SPEED_NORMAL){		xine_set_param(stream,XINE_PARAM_SPEED,XINE_SPEED_PAUSE);		return 0;	}	return 1;}int AUDIO_stop(AUDIO_SESSION *s){	xine_stop(stream);	s->playing =0;	if(s->AUDIO_UI_caller)s->AUDIO_UI_caller(AUDIO_STOP,s->cdata);	return 0;}	int AUDIO_seek(AUDIO_SESSION *s, int time){	int rv = 0;	int pos = 0;	rv = AUDIO_get_position(s,&pos);	rv = AUDIO_play(s,NULL,pos+time);	return rv;}int AUDIO_driver_dinit(AUDIO_SESSION *s){	printf("audi dinit\n");	//  xine_event_dispose_queue(event_queue);	if(s==NULL)return 0;	if(mstream)xine_dispose(mstream);	if(stream)xine_dispose(stream);	if(xine && ao_port){		xine_close_audio_driver(xine, ao_port);		xine_exit(xine);	}	if(audio_output) free(audio_output);	return 0;}int AUDIO_get_position(AUDIO_SESSION *s,int *pos_time){	int bl,ah;	int rv;	rv = xine_get_pos_length(stream,&bl,pos_time,&ah);	/* Xine returns the time in milliseconds, so divide and round off*/	// 1 000  = 1s,  1 555 = 2s	*pos_time = (*pos_time+500)/1000;	return !rv;}static void XINE_DRIVER_event_listener(void *user_data, const xine_event_t *event) {	AUDIO_SESSION *s;	s = (AUDIO_SESSION*)user_data;	switch(event->type) {	case XINE_EVENT_UI_PLAYBACK_FINISHED:		s->playing = 0;		xine_close(stream);		if(s->AUDIO_UI_caller)			s->AUDIO_UI_caller(AUDIO_END,s->cdata);		break;	}}