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

📄 alsa.c

📁 linphone的最新版本
💻 C
📖 第 1 页 / 共 2 页
字号:
					snd_mixer_selem_get_playback_volume_range(elem, &sndMixerPMin, &sndMixerPMax);					newvol=(((sndMixerPMax-sndMixerPMin)*level)/100)+sndMixerPMin;					snd_mixer_selem_set_playback_volume_all(elem,newvol);					//ms_message("Successfully set playback level for %s.",elemname);					return;				}				break;				case CAPTURE_SWITCH:				if (snd_mixer_selem_has_capture_switch(elem)){					snd_mixer_selem_set_capture_switch_all(elem,level);					//ms_message("Successfully set capture switch for %s.",elemname);				}				break;				case PLAYBACK_SWITCH:				if (snd_mixer_selem_has_playback_switch(elem)){					snd_mixer_selem_set_playback_switch_all(elem,level);					//ms_message("Successfully set capture switch for %s.",elemname);				}				break;			}		}		elem=snd_mixer_elem_next(elem);	}	return ;}static void alsa_card_set_level(MSSndCard *obj,MSSndCardMixerElem e,int a){		snd_mixer_t *mixer;	AlsaData *ad=(AlsaData*)obj->data;	mixer=alsa_mixer_open(ad->mixdev);	if (mixer==NULL) return ;	switch(e){		case MS_SND_CARD_MASTER:			set_mixer_element(mixer,"Master",a,PLAYBACK);		break;		case MS_SND_CARD_CAPTURE:			set_mixer_element(mixer,"Capture",a,CAPTURE);		break;		case MS_SND_CARD_PLAYBACK:			set_mixer_element(mixer,"PCM",a,PLAYBACK);		break;		default:			ms_warning("alsa_card_set_level: unsupported command.");	}	alsa_mixer_close(mixer);}static int alsa_card_get_level(MSSndCard *obj, MSSndCardMixerElem e){	snd_mixer_t *mixer;	AlsaData *ad=(AlsaData*)obj->data;	int value = -1;	mixer=alsa_mixer_open(ad->mixdev);	if (mixer==NULL) return 0;	switch(e){		case MS_SND_CARD_MASTER:			value=get_mixer_element(mixer,"Master",PLAYBACK);			break;		case MS_SND_CARD_CAPTURE:			value=get_mixer_element(mixer,"Capture",CAPTURE);			break;		case MS_SND_CARD_PLAYBACK:			value=get_mixer_element(mixer,"PCM",PLAYBACK);			break;		default:			ms_warning("alsa_card_set_level: unsupported command.");	}	alsa_mixer_close(mixer);	return value;}static void alsa_card_set_source(MSSndCard *obj,MSSndCardCapture source){	snd_mixer_t *mixer;	AlsaData *ad=(AlsaData*)obj->data;	mixer=alsa_mixer_open(ad->mixdev);	if (mixer==NULL) return;	switch (source){		case MS_SND_CARD_MIC:			set_mixer_element(mixer,"Mic",1,CAPTURE_SWITCH);			set_mixer_element(mixer,"Capture",1,CAPTURE_SWITCH);			break;		case MS_SND_CARD_LINE:			set_mixer_element(mixer,"Line",1,CAPTURE_SWITCH);			set_mixer_element(mixer,"Capture",1,CAPTURE_SWITCH);			break;	}	alsa_mixer_close(mixer);}static MSFilter *alsa_card_create_reader(MSSndCard *card){	AlsaData *ad=(AlsaData*)card->data;	MSFilter *f=ms_alsa_read_new(ad->pcmdev);	return f;}static MSFilter *alsa_card_create_writer(MSSndCard *card){	AlsaData *ad=(AlsaData*)card->data;	MSFilter *f=ms_alsa_write_new(ad->pcmdev);	return f;}static void alsa_card_init(MSSndCard *obj){	AlsaData *ad=ms_new0(AlsaData,1);	obj->data=ad;}static void alsa_card_uninit(MSSndCard *obj){	AlsaData *ad=(AlsaData*)obj->data;	if (ad->pcmdev!=NULL) ms_free(ad->pcmdev);	if (ad->mixdev!=NULL) ms_free(ad->mixdev);}static void alsa_card_detect(MSSndCardManager *m){	int i;	for (i=-1;i<10;i++){		MSSndCard *card=alsa_card_new(i);		if (card!=NULL)			ms_snd_card_manager_add_card(m,card);	}}MSSndCardDesc alsa_card_desc={	.driver_type="ALSA",	.detect=alsa_card_detect,	.init=alsa_card_init,	.set_level=alsa_card_set_level,	.get_level=alsa_card_get_level,	.set_capture=alsa_card_set_source,	.create_reader=alsa_card_create_reader,	.create_writer=alsa_card_create_writer,	.uninit=alsa_card_uninit,	.duplicate=alsa_card_duplicate};static MSSndCard *alsa_card_duplicate(MSSndCard *obj){	MSSndCard *card=ms_snd_card_new(&alsa_card_desc);	AlsaData* dcard=(AlsaData*)card->data;	AlsaData* dobj=(AlsaData*)obj->data;	card->name=ms_strdup(obj->name);	card->id=ms_strdup(obj->id);	dcard->pcmdev=ms_strdup(dobj->pcmdev);	dcard->mixdev=ms_strdup(dobj->mixdev);	return card;}MSSndCard * ms_alsa_card_new_custom(const char *pcmdev, const char *mixdev){	MSSndCard * obj;	AlsaData *ad;	obj=ms_snd_card_new(&alsa_card_desc);	ad=(AlsaData*)obj->data;	obj->name=ms_strdup(pcmdev);	ad->pcmdev=ms_strdup(pcmdev);	ad->mixdev=ms_strdup(mixdev);	return obj;}static MSSndCard * alsa_card_new(int id){	MSSndCard * obj;	char *name=NULL;	AlsaData *ad;	int err;	if (id!=-1){		err=snd_card_get_name(id,&name);		if (err<0) {			return NULL;		}	}	obj=ms_snd_card_new(&alsa_card_desc);	ad=(AlsaData*)obj->data;	if (id==-1) {		/* the default pcm device */		obj->name=ms_strdup("default device");		ad->pcmdev=ms_strdup("default");		ad->mixdev=ms_strdup("default");	}else{		/* remove trailing spaces from card name */		char *pos1, *pos2;		pos1=ms_strdup(name);		pos2=pos1+strlen(pos1)-1;		for (; pos2>pos1 && *pos2==' '; pos2--) *pos2='\0';		obj->name=pos1;		ad->pcmdev=ms_strdup_printf("default:%i",id);		ad->mixdev=ms_strdup_printf("default:%i",id);	}	free(name);	/*ms_message("alsa device %s found",obj->name);*/	return obj;}struct _AlsaReadData{	char *pcmdev;	snd_pcm_t *handle;	int rate;	int nchannels;};typedef struct _AlsaReadData AlsaReadData;void alsa_read_init(MSFilter *obj){	AlsaReadData *ad=ms_new(AlsaReadData,1);	ad->pcmdev=NULL;	ad->handle=NULL;	ad->rate=8000;	ad->nchannels=1;	obj->data=ad;}void alsa_read_postprocess(MSFilter *obj){	AlsaReadData *ad=(AlsaReadData*)obj->data;	if (ad->handle!=NULL) snd_pcm_close(ad->handle);	ad->handle=NULL;}void alsa_read_uninit(MSFilter *obj){	AlsaReadData *ad=(AlsaReadData*)obj->data;	if (ad->pcmdev!=NULL) ms_free(ad->pcmdev);	if (ad->handle!=NULL) snd_pcm_close(ad->handle);	ms_free(ad);}void alsa_read_process(MSFilter *obj){	AlsaReadData *ad=(AlsaReadData*)obj->data;#ifdef AMD_HACK	int samples=(160*ad->rate)/8000;#else	int samples=(128*ad->rate)/8000;#endif	int err;	mblk_t *om=NULL;	if (ad->handle==NULL && ad->pcmdev!=NULL){		ad->handle=alsa_open_r(ad->pcmdev,16,ad->nchannels==2,ad->rate);	}	if (ad->handle==NULL) return;	while (alsa_can_read(ad->handle,samples)){		int size=samples*2;		om=allocb(size,0);		if ((err=alsa_read(ad->handle,om->b_wptr,samples))<=0) {			ms_warning("Fail to read samples");			freemsg(om);			return;		}		size=err*2;		om->b_wptr+=size;		/*ms_message("alsa_read_process: Outputing %i bytes",size);*/		ms_queue_put(obj->outputs[0],om);#ifdef AMD_HACK		break;#endif	}}static int alsa_read_set_sample_rate(MSFilter *obj, void *param){	AlsaReadData *ad=(AlsaReadData*)obj->data;	ad->rate=*((int*)param);	return 0;}static int alsa_read_set_nchannels(MSFilter *obj, void *param){	AlsaReadData *ad=(AlsaReadData*)obj->data;	ad->nchannels=*((int*)param);	return 0;}MSFilterMethod alsa_read_methods[]={	{MS_FILTER_SET_SAMPLE_RATE, alsa_read_set_sample_rate},	{MS_FILTER_SET_SAMPLE_RATE, alsa_read_set_nchannels},	{0,NULL}};MSFilterDesc alsa_read_desc={	.id=MS_ALSA_READ_ID,	.name="MSAlsaRead",	.text="Alsa sound source",	.category=MS_FILTER_OTHER,	.ninputs=0,	.noutputs=1,	.init=alsa_read_init,	.process=alsa_read_process,	.postprocess=alsa_read_postprocess,	.uninit=alsa_read_uninit,	.methods=alsa_read_methods};static MSFilter * ms_alsa_read_new(const char *dev){	MSFilter *f=ms_filter_new_from_desc(&alsa_read_desc);	AlsaReadData *ad=(AlsaReadData*)f->data;	ad->pcmdev=ms_strdup(dev);	return f;}typedef struct _AlsaReadData AlsaWriteData;void alsa_write_init(MSFilter *obj){	AlsaWriteData *ad=ms_new(AlsaWriteData,1);	ad->pcmdev=NULL;	ad->handle=NULL;	ad->rate=8000;	ad->nchannels=1;	obj->data=ad;}void alsa_write_postprocess(MSFilter *obj){	AlsaReadData *ad=(AlsaReadData*)obj->data;	if (ad->handle!=NULL) snd_pcm_close(ad->handle);	ad->handle=NULL;}void alsa_write_uninit(MSFilter *obj){	AlsaWriteData *ad=(AlsaWriteData*)obj->data;	if (ad->pcmdev!=NULL) ms_free(ad->pcmdev);	if (ad->handle!=NULL) snd_pcm_close(ad->handle);	ms_free(ad);}int alsa_write_set_sample_rate(MSFilter *obj, void *data){	int *rate=(int*)data;	AlsaWriteData *ad=(AlsaWriteData*)obj->data;	ad->rate=*rate;	return 0;}int alsa_write_set_nchannels(MSFilter *obj, void *data){	int *n=(int*)data;	AlsaWriteData *ad=(AlsaWriteData*)obj->data;	ad->nchannels=*n;	return 0;}void alsa_write_process(MSFilter *obj){	AlsaWriteData *ad=(AlsaWriteData*)obj->data;	mblk_t *im=NULL;	int size;	int samples;	int err;	if (ad->handle==NULL && ad->pcmdev!=NULL){		ad->handle=alsa_open_w(ad->pcmdev,16,ad->nchannels==2,ad->rate);#ifdef EPIPE_BUGFIX		alsa_fill_w (ad->pcmdev);#endif	}	if (ad->handle==NULL) {		ms_queue_flush(obj->inputs[0]);		return;	}	while ((im=ms_queue_get(obj->inputs[0]))!=NULL){		while((size=im->b_wptr-im->b_rptr)>0){			samples=size/(2*ad->nchannels);			err=alsa_write(ad->handle,im->b_rptr,samples);			if (err>0) {				im->b_rptr+=err*(2*ad->nchannels);			}			else break;		}		freemsg(im);	}}MSFilterMethod alsa_write_methods[]={	{MS_FILTER_SET_SAMPLE_RATE, alsa_write_set_sample_rate},	{MS_FILTER_SET_NCHANNELS, alsa_write_set_nchannels},	{0,NULL}};MSFilterDesc alsa_write_desc={	.id=MS_ALSA_WRITE_ID,	.name="MSAlsaWrite",	.text="Alsa sound output",	.category=MS_FILTER_OTHER,	.ninputs=1,	.noutputs=0,	.init=alsa_write_init,	.process=alsa_write_process,	.postprocess=alsa_write_postprocess,	.uninit=alsa_write_uninit,	.methods=alsa_write_methods};static MSFilter * ms_alsa_write_new(const char *dev){	MSFilter *f=ms_filter_new_from_desc(&alsa_write_desc);	AlsaWriteData *ad=(AlsaWriteData*)f->data;	ad->pcmdev=ms_strdup(dev);	return f;}MS_FILTER_DESC_EXPORT(alsa_write_desc)MS_FILTER_DESC_EXPORT(alsa_read_desc)

⌨️ 快捷键说明

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