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

📄 macsnd.c

📁 linphone 网络电话 linphone 网络电话 linphone 网络电话
💻 C
📖 第 1 页 / 共 2 页
字号:
		int fAudioChannels = 1;	d->caInASBD.mChannelsPerFrame = fAudioChannels;	d->caInASBD.mSampleRate = tmpASBD.mSampleRate;	d->caInASBD.mFormatID = kAudioFormatLinearPCM;	d->caInASBD.mFormatFlags = kAudioFormatFlagIsFloat | kAudioFormatFlagIsPacked |										kAudioFormatFlagIsNonInterleaved;	if (d->caInASBD.mFormatID == kAudioFormatLinearPCM && fAudioChannels == 1)		d->caInASBD.mFormatFlags &= ~kLinearPCMFormatFlagIsNonInterleaved;	d->caInASBD.mFormatFlags = kAudioFormatFlagIsFloat;#if __BIG_ENDIAN__	d->caInASBD.mFormatFlags |= kAudioFormatFlagIsBigEndian;#endif	d->caInASBD.mBitsPerChannel = sizeof(Float32) * 8;	d->caInASBD.mBytesPerFrame = d->caInASBD.mBitsPerChannel / 8;	d->caInASBD.mFramesPerPacket = 1;	d->caInASBD.mBytesPerPacket = d->caInASBD.mBytesPerFrame;	err = AudioUnitSetProperty(d->caInAudioUnit,							kAudioUnitProperty_StreamFormat,							kAudioUnitScope_Output,							1,							&d->caInASBD,							sizeof(AudioStreamBasicDescription));	d->caSourceBuffer=NULL;	// Get the number of frames in the IO buffer(s)	param = sizeof(UInt32);	UInt32 fAudioSamples;	result = AudioUnitGetProperty(d->caInAudioUnit,							kAudioDevicePropertyBufferFrameSize,							kAudioUnitScope_Global,							0,							&fAudioSamples,							&param);	if(err != noErr)	{		fprintf(stderr, "failed to get audio sample size\n");		return;	}	// Allocate our low device audio buffers	d->fAudioBuffer = AllocateAudioBufferList(d->caInASBD.mChannelsPerFrame,						fAudioSamples * d->caInASBD.mBytesPerFrame);	if(d->fAudioBuffer == NULL)	{		fprintf(stderr, "failed to allocate buffers\n");		return;	}	// Allocate our low device audio buffers	d->fMSBuffer = AllocateAudioBufferList(d->caInASBD.mChannelsPerFrame,						fAudioSamples * d->caInASBD.mBytesPerFrame);	if(d->fMSBuffer == NULL)	{		fprintf(stderr, "failed to allocate buffers\n");		return;	}	d->pcmdev=NULL;	d->mixdev=NULL;	d->pcmfd=-1;	d->read_started=FALSE;	d->write_started=FALSE;	d->bits=16;	d->rate=8000;	d->stereo=FALSE;	qinit(&d->rq);	d->bufferizer=ms_bufferizer_new();	ms_mutex_init(&d->mutex,NULL);	card->data=d;}static void ca_uninit(MSSndCard *card){	CAData *d=(CAData*)card->data;	if (d->pcmdev!=NULL) ms_free(d->pcmdev);	if (d->mixdev!=NULL) ms_free(d->mixdev);	ms_bufferizer_destroy(d->bufferizer);	flushq(&d->rq,0);	ms_mutex_destroy(&d->mutex);	ms_free(d);}static void ca_detect(MSSndCardManager *m);static MSSndCard *ca_duplicate(MSSndCard *obj);MSSndCardDesc ca_card_desc={	.driver_type="CA",	.detect=ca_detect,	.init=ca_init,	.set_level=ca_set_level,	.get_level=ca_get_level,	.set_capture=ca_set_source,	.create_reader=ms_ca_read_new,	.create_writer=ms_ca_write_new,	.uninit=ca_uninit,	.duplicate=ca_duplicate};static MSSndCard *ca_duplicate(MSSndCard *obj){	MSSndCard *card=ms_snd_card_new(&ca_card_desc);	CAData *dcard=(CAData*)card->data;	CAData *dobj=(CAData*)obj->data;	dcard->pcmdev=ms_strdup(dobj->pcmdev);	dcard->mixdev=ms_strdup(dobj->mixdev);	card->name=ms_strdup(obj->name);	return card;}static MSSndCard *ca_card_new(){	MSSndCard *card=ms_snd_card_new(&ca_card_desc);	card->name=ms_strdup("Core Audio");	return card;}static void ca_detect(MSSndCardManager *m){	ms_debug("ca_detect");	MSSndCard *card=ca_card_new();        ms_snd_card_manager_add_card(m,card);}static void ca_start_r(MSSndCard *card){	OSStatus err= noErr;	CAData *d=(CAData*)card->data;	ms_debug("ca_start_r");	if (d->read_started==FALSE){		AudioStreamBasicDescription outASBD;		outASBD = d->caInASBD;		outASBD.mSampleRate = d->rate;		outASBD.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked | kLinearPCMFormatFlagIsBigEndian;		outASBD.mBytesPerPacket = (d->bits / 8) * outASBD.mChannelsPerFrame;		outASBD.mBytesPerFrame = (d->bits / 8) * outASBD.mChannelsPerFrame;		outASBD.mFramesPerPacket = 1;		outASBD.mBitsPerChannel = d->bits;		err = AudioConverterNew( &d->caInASBD, &outASBD, &d->caInConverter);		if(err != noErr)			ms_error("AudioConverterNew %x %d", err, outASBD.mBytesPerFrame);		else			CAShow(d->caInConverter);		d->caInRenderCallback.inputProc = readRenderProc;		d->caInRenderCallback.inputProcRefCon = d;		err = AudioUnitSetProperty(d->caInAudioUnit,						kAudioOutputUnitProperty_SetInputCallback,						kAudioUnitScope_Global,						0,						&d->caInRenderCallback,						sizeof(AURenderCallbackStruct));		if(AudioOutputUnitStart(d->caInAudioUnit) == noErr)			d->read_started = TRUE;	}}static void ca_stop_r(MSSndCard *card){	CAData *d=(CAData*)card->data;	OSErr err;	if(d->read_started == TRUE) {		if(AudioOutputUnitStop(d->caInAudioUnit) == noErr)			d->read_started=FALSE;	}}static void ca_start_w(MSSndCard *card){	OSStatus err= noErr;	ms_debug("ca_start_w");	CAData *d=(CAData*)card->data;	if (d->write_started==FALSE){		AudioStreamBasicDescription inASBD;		inASBD = d->caOutASBD;		inASBD.mSampleRate = d->rate;		inASBD.mFormatID = kAudioFormatLinearPCM;		// http://developer.apple.com/documentation/MusicAudio/Reference/CoreAudioDataTypesRef/Reference/reference.html		inASBD.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked | kLinearPCMFormatFlagIsBigEndian;		inASBD.mChannelsPerFrame = d->stereo ? 2 : 1;		inASBD.mBytesPerPacket = (d->bits / 8) * inASBD.mChannelsPerFrame;		inASBD.mBytesPerFrame = (d->bits / 8) * inASBD.mChannelsPerFrame;		inASBD.mFramesPerPacket = 1;		inASBD.mBitsPerChannel = d->bits;		err = AudioConverterNew( &inASBD, &d->caOutASBD, &d->caOutConverter);		if(err != noErr)			ms_error("AudioConverterNew %x %d", err, inASBD.mBytesPerFrame);		else			CAShow(d->caOutConverter);		if (inASBD.mChannelsPerFrame == 1 && d->caOutASBD.mChannelsPerFrame == 2)		{			if (d->caOutConverter)			{				// This should be as large as the number of output channels,				// each element specifies which input channel's data is routed to that output channel				SInt32 channelMap[] = { 0, 0 };				err = AudioConverterSetProperty(d->caOutConverter, kAudioConverterChannelMap, 2*sizeof(SInt32), channelMap);			}		}		memset((char*)&d->caOutRenderCallback, 0, sizeof(AURenderCallbackStruct));		d->caOutRenderCallback.inputProc = writeRenderProc;		d->caOutRenderCallback.inputProcRefCon = d;		err = AudioUnitSetProperty (d->caOutAudioUnit,                             kAudioUnitProperty_SetRenderCallback,                             kAudioUnitScope_Input,                             0,                            &d->caOutRenderCallback,                             sizeof(AURenderCallbackStruct));		if(err != noErr)			ms_error("AudioUnitSetProperty %x", err);		if(err == noErr) {			if(AudioOutputUnitStart(d->caOutAudioUnit) == noErr)				d->write_started=TRUE;		}	}}static void ca_stop_w(MSSndCard *card){	CAData *d=(CAData*)card->data;	OSErr err;	if(d->write_started == TRUE) {		if(AudioOutputUnitStop(d->caOutAudioUnit) == noErr)			d->write_started=FALSE;	}}static mblk_t *ca_get(MSSndCard *card){	CAData *d=(CAData*)card->data;	mblk_t *m;	ms_mutex_lock(&d->mutex);	m=getq(&d->rq);	ms_mutex_unlock(&d->mutex);	return m;}static void ca_put(MSSndCard *card, mblk_t *m){	CAData *d=(CAData*)card->data;	ms_mutex_lock(&d->mutex);	ms_bufferizer_put(d->bufferizer,m);	ms_mutex_unlock(&d->mutex);}static void ca_read_preprocess(MSFilter *f){	MSSndCard *card=(MSSndCard*)f->data;	ca_start_r(card);}static void ca_read_postprocess(MSFilter *f){	MSSndCard *card=(MSSndCard*)f->data;	ca_stop_r(card);}static void ca_read_process(MSFilter *f){	MSSndCard *card=(MSSndCard*)f->data;	mblk_t *m;	while((m=ca_get(card))!=NULL){		ms_queue_put(f->outputs[0],m);	}}static void ca_write_preprocess(MSFilter *f){	ms_debug("ca_write_preprocess");	MSSndCard *card=(MSSndCard*)f->data;	ca_start_w(card);}static void ca_write_postprocess(MSFilter *f){	ms_debug("ca_write_postprocess");	MSSndCard *card=(MSSndCard*)f->data;	ca_stop_w(card);}static void ca_write_process(MSFilter *f){//	ms_debug("ca_write_process");	MSSndCard *card=(MSSndCard*)f->data;	mblk_t *m;	while((m=ms_queue_get(f->inputs[0]))!=NULL){		ca_put(card,m);	}}static int set_rate(MSFilter *f, void *arg){	ms_debug("set_rate %d", *((int*)arg));	MSSndCard *card=(MSSndCard*)f->data;	CAData *d=(CAData*)card->data;	d->rate=*((int*)arg);	return 0;}static int set_nchannels(MSFilter *f, void *arg){	ms_debug("set_nchannels %d", *((int*)arg));	MSSndCard *card=(MSSndCard*)f->data;	CAData *d=(CAData*)card->data;	d->stereo=(*((int*)arg)==2);	return 0;}static MSFilterMethod ca_methods[]={	{	MS_FILTER_SET_SAMPLE_RATE	, set_rate	},	{	MS_FILTER_SET_NCHANNELS		, set_nchannels	},	{	0				, NULL		}};MSFilterDesc ca_read_desc={	.id=MS_CA_READ_ID,	.name="MSCARead",	.text="Sound capture filter for MacOS X Core Audio drivers",	.category=MS_FILTER_OTHER,	.ninputs=0,	.noutputs=1,	.preprocess=ca_read_preprocess,	.process=ca_read_process,	.postprocess=ca_read_postprocess,	.methods=ca_methods};MSFilterDesc ca_write_desc={	.id=MS_CA_WRITE_ID,	.name="MSCAWrite",	.text="Sound playback filter for MacOS X Core Audio drivers",	.category=MS_FILTER_OTHER,	.ninputs=1,	.noutputs=0,	.preprocess=ca_write_preprocess,	.process=ca_write_process,	.postprocess=ca_write_postprocess,	.methods=ca_methods};MSFilter *ms_ca_read_new(MSSndCard *card){	ms_debug("ms_ca_read_new");	MSFilter *f=ms_filter_new_from_desc(&ca_read_desc);	f->data=card;	return f;}MSFilter *ms_ca_write_new(MSSndCard *card){	ms_debug("ms_ca_write_new");	MSFilter *f=ms_filter_new_from_desc(&ca_write_desc);	f->data=card;	return f;}MS_FILTER_DESC_EXPORT(ca_read_desc)MS_FILTER_DESC_EXPORT(ca_write_desc)

⌨️ 快捷键说明

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