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

📄 ao_sun.c

📁 自己移植的linux下的流媒体播放器原代码,支持mms协议,支持ftp和http协议.
💻 C
📖 第 1 页 / 共 2 页
字号:
	if ((sun_mixer_device = mixer_device) == NULL || !sun_mixer_device[0]) {	    sun_mixer_device = malloc(strlen(audio_dev) + 4);	    strcpy(sun_mixer_device, audio_dev);	    strcat(sun_mixer_device, "ctl");	}    }    if (ao_subdevice) audio_dev = ao_subdevice;}// to set/get/query special features/parametersstatic int control(int cmd,void *arg){    switch(cmd){    case AOCONTROL_SET_DEVICE:	audio_dev=(char*)arg;	return CONTROL_OK;    case AOCONTROL_QUERY_FORMAT:	return CONTROL_TRUE;    case AOCONTROL_GET_VOLUME:    {        int fd;	if ( !sun_mixer_device )    /* control function is used before init? */	    setup_device_paths();	fd=open( sun_mixer_device,O_RDONLY );	if ( fd != -1 )	{	    ao_control_vol_t *vol = (ao_control_vol_t *)arg;	    float volume;	    struct audio_info info;	    ioctl( fd,AUDIO_GETINFO,&info);	    volume = info.play.gain * 100. / AUDIO_MAX_GAIN;	    if ( info.play.balance == AUDIO_MID_BALANCE ) {		vol->right = vol->left = volume;	    } else if ( info.play.balance < AUDIO_MID_BALANCE ) {		vol->left  = volume;		vol->right = volume * info.play.balance / AUDIO_MID_BALANCE;	    } else {		vol->left  = volume * (AUDIO_RIGHT_BALANCE-info.play.balance)							/ AUDIO_MID_BALANCE;		vol->right = volume;	    }	    close( fd );	    return CONTROL_OK;	}		return CONTROL_ERROR;    }    case AOCONTROL_SET_VOLUME:    {	ao_control_vol_t *vol = (ao_control_vol_t *)arg;        int fd;	if ( !sun_mixer_device )    /* control function is used before init? */	    setup_device_paths();	fd=open( sun_mixer_device,O_RDONLY );	if ( fd != -1 )	{	    struct audio_info info;	    float volume;	    AUDIO_INITINFO(&info);	    volume = vol->right > vol->left ? vol->right : vol->left;	    if ( volume != 0 ) {		info.play.gain = volume * AUDIO_MAX_GAIN / 100;		if ( vol->right == vol->left )		    info.play.balance = AUDIO_MID_BALANCE;		else		    info.play.balance = (vol->right - vol->left + volume) * AUDIO_RIGHT_BALANCE / (2*volume);	    }#if !defined (__OpenBSD__) && !defined (__NetBSD__)	    info.output_muted = (volume == 0);#endif	    ioctl( fd,AUDIO_SETINFO,&info );	    close( fd );	    return CONTROL_OK;	}		return CONTROL_ERROR;    }    }    return CONTROL_UNKNOWN;}// open & setup audio device// return: 1=success 0=failstatic int init(int rate,int channels,int format,int flags){    audio_info_t info;    int pass;    int ok;    int convert_u8_s8;    setup_device_paths();    if (enable_sample_timing == RTSC_UNKNOWN	&& !getenv("AO_SUN_DISABLE_SAMPLE_TIMING")) {	enable_sample_timing = realtime_samplecounter_available(audio_dev);    }    printf("ao2: %d Hz  %d chans  %s [0x%X]\n",	   rate,channels,af_fmt2str_short(format),format);    audio_fd=open(audio_dev, O_WRONLY);    if(audio_fd<0){	mp_msg(MSGT_AO, MSGL_ERR, MSGTR_AO_SUN_CantOpenAudioDev, audio_dev, strerror(errno));	return 0;    }    ioctl(audio_fd, AUDIO_DRAIN, 0);    if (af2sunfmt(format) == AUDIO_ENCODING_NONE)      format = AF_FORMAT_S16_NE;    for (ok = pass = 0; pass <= 5; pass++) { /* pass 6&7 not useful */	AUDIO_INITINFO(&info);	info.play.encoding = af2sunfmt(ao_data.format = format);	info.play.precision =	    (format==AF_FORMAT_S16_NE	     ? AUDIO_PRECISION_16	     : AUDIO_PRECISION_8);	info.play.channels = ao_data.channels = channels;	info.play.sample_rate = ao_data.samplerate = rate;	convert_u8_s8 = 0;	if (pass & 1) {	    /*	     * on some sun audio drivers, 8-bit unsigned LINEAR8 encoding is 	     * not supported, but 8-bit signed encoding is.	     *	     * Try S8, and if it works, use our own U8->S8 conversion before	     * sending the samples to the sound driver.	     */#ifdef AUDIO_ENCODING_LINEAR8	    if (info.play.encoding != AUDIO_ENCODING_LINEAR8)#endif		continue;	    info.play.encoding = AUDIO_ENCODING_LINEAR;	    convert_u8_s8 = 1;	}	if (pass & 2) {	    /*	     * on some sun audio drivers, only certain fixed sample rates are	     * supported.	     *	     * In case the requested sample rate is very close to one of the	     * supported rates,  use the fixed supported rate instead.	     */	    if (!(info.play.sample_rate =		  find_close_samplerate_match(audio_fd, rate))) 	      continue;	    /*	     * I'm not returning the correct sample rate in	     * |ao_data.samplerate|, to avoid software resampling.	     *	     * ao_data.samplerate = info.play.sample_rate;	     */	}	if (pass & 4) {	    /* like "pass & 2", but use the highest supported sample rate */	    if (!(info.play.sample_rate		  = ao_data.samplerate		  = find_highest_samplerate(audio_fd)))		continue;	}	ok = ioctl(audio_fd, AUDIO_SETINFO, &info) >= 0;	if (ok) {	    /* audio format accepted by audio driver */	    break;	}	/*	 * format not supported?	 * retry with different encoding and/or sample rate	 */    }    if (!ok) {	char buf[128];	mp_msg(MSGT_AO, MSGL_ERR, MSGTR_AO_SUN_UnsupSampleRate,	       channels, af_fmt2str(format, buf, 128), rate);	return 0;    }    if (convert_u8_s8)      ao_data.format = AF_FORMAT_S8;    bytes_per_sample = channels * info.play.precision / 8;    ao_data.bps = byte_per_sec = bytes_per_sample * ao_data.samplerate;    ao_data.outburst = byte_per_sec > 100000 ? 16384 : 8192;#ifdef	__not_used__    /*     * hmm, ao_data.buffersize is currently not used in this driver, do there's     * no need to measure it     */    if(ao_data.buffersize==-1){	// Measuring buffer size:	void* data;	ao_data.buffersize=0;#ifdef HAVE_AUDIO_SELECT	data = malloc(ao_data.outburst);	memset(data, format==AF_FORMAT_U8 ? 0x80 : 0, ao_data.outburst);	while(ao_data.buffersize<0x40000){	    fd_set rfds;	    struct timeval tv;	    FD_ZERO(&rfds); FD_SET(audio_fd,&rfds);	    tv.tv_sec=0; tv.tv_usec = 0;	    if(!select(audio_fd+1, NULL, &rfds, NULL, &tv)) break;	    write(audio_fd,data,ao_data.outburst);	    ao_data.buffersize+=ao_data.outburst;	}	free(data);	if(ao_data.buffersize==0){	    mp_msg(MSGT_AO, MSGL_ERR, MSGTR_AO_SUN_CantUseSelect);	    return 0;	}#ifdef	__svr4__	// remove the 0 bytes from the above ao_data.buffersize measurement from the	// audio driver's STREAMS queue	ioctl(audio_fd, I_FLUSH, FLUSHW);#endif	ioctl(audio_fd, AUDIO_DRAIN, 0);#endif    }#endif	/* __not_used__ */    AUDIO_INITINFO(&info);    info.play.samples = 0;    info.play.eof = 0;    info.play.error = 0;    ioctl (audio_fd, AUDIO_SETINFO, &info);    queued_bursts = 0;    queued_samples = 0;    return 1;}// close audio devicestatic void uninit(int immed){#ifdef	__svr4__    // throw away buffered data in the audio driver's STREAMS queue    if (immed)	ioctl(audio_fd, I_FLUSH, FLUSHW);#endif    close(audio_fd);}// stop playing and empty buffers (for seeking/pause)static void reset(){    audio_info_t info;    uninit(1);    audio_fd=open(audio_dev, O_WRONLY);    if(audio_fd<0){	mp_msg(MSGT_AO, MSGL_FATAL, MSGTR_AO_SUN_CantReopenReset, strerror(errno));	return;    }    ioctl(audio_fd, AUDIO_DRAIN, 0);    AUDIO_INITINFO(&info);    info.play.encoding = af2sunfmt(ao_data.format);    info.play.precision =	(ao_data.format==AF_FORMAT_S16_NE 	 ? AUDIO_PRECISION_16	 : AUDIO_PRECISION_8);    info.play.channels = ao_data.channels;    info.play.sample_rate = ao_data.samplerate;    info.play.samples = 0;    info.play.eof = 0;    info.play.error = 0;    ioctl (audio_fd, AUDIO_SETINFO, &info);    queued_bursts = 0;    queued_samples = 0;}// stop playing, keep buffers (for pause)static void audio_pause(){    struct audio_info info;    AUDIO_INITINFO(&info);    info.play.pause = 1;    ioctl(audio_fd, AUDIO_SETINFO, &info);}// resume playing, after audio_pause()static void audio_resume(){    struct audio_info info;    AUDIO_INITINFO(&info);    info.play.pause = 0;    ioctl(audio_fd, AUDIO_SETINFO, &info);}// return: how many bytes can be played without blockingstatic int get_space(){    audio_info_t info;    // check buffer#ifdef HAVE_AUDIO_SELECT    {	fd_set rfds;	struct timeval tv;	FD_ZERO(&rfds);	FD_SET(audio_fd, &rfds);	tv.tv_sec = 0;	tv.tv_usec = 0;	if(!select(audio_fd+1, NULL, &rfds, NULL, &tv)) return 0; // not block!    }#endif#if !defined (__OpenBSD__) && !defined(__NetBSD__)    ioctl(audio_fd, AUDIO_GETINFO, &info);    if (queued_bursts - info.play.eof > 2)	return 0;#endif#if defined(__NetBSD__) || defined(__OpenBSD__)    ioctl(audio_fd, AUDIO_GETINFO, &info);    return info.hiwat * info.blocksize - info.play.seek;#else    return ao_data.outburst;#endif}// plays 'len' bytes of 'data'// it should round it down to outburst*n// return: number of bytes playedstatic int play(void* data,int len,int flags){    if (len < ao_data.outburst) return 0;    len /= ao_data.outburst;    len *= ao_data.outburst;    len = write(audio_fd, data, len);    if(len > 0) {	queued_samples += len / bytes_per_sample;	if (write(audio_fd,data,0) < 0)	    perror("ao_sun: send EOF audio record");	else	    queued_bursts ++;    }    return len;}// return: delay in seconds between first and last sample in bufferstatic float get_delay(){    audio_info_t info;    ioctl(audio_fd, AUDIO_GETINFO, &info);#if defined (__OpenBSD__) || defined(__NetBSD__)    return (float) info.play.seek/ (float)byte_per_sec ;#else    if (info.play.samples && enable_sample_timing == RTSC_ENABLED)	return (float)(queued_samples - info.play.samples) / (float)ao_data.samplerate;    else	return (float)((queued_bursts - info.play.eof) * ao_data.outburst) / (float)byte_per_sec;#endif}

⌨️ 快捷键说明

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