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

📄 macsnd.c

📁 linphone 网络电话 linphone 网络电话 linphone 网络电话
💻 C
📖 第 1 页 / 共 2 页
字号:
/*mediastreamer2 library - modular sound and video processing and streamingCopyright (C) 2006  Simon MORLAT (simon.morlat@linphone.org)This program is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public Licenseas published by the Free Software Foundation; either version 2of 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 ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.*//* this file is specifically distributed under a BSD license *//*** Copyright (C) 2007  Hiroki Mori (himori@users.sourceforge.net)* All rights reserved.* * Redistribution and use in source and binary forms, with or without* modification, are permitted provided that the following conditions are met:*     * Redistributions of source code must retain the above copyright*       notice, this list of conditions and the following disclaimer.*     * Redistributions in binary form must reproduce the above copyright*       notice, this list of conditions and the following disclaimer in the*       documentation and/or other materials provided with the distribution.*     * Neither the name of the <organization> nor the*       names of its contributors may be used to endorse or promote products*       derived from this software without specific prior written permission.** THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.**/#include <CoreServices/CoreServices.h>#include <AudioUnit/AudioUnit.h>#include <AudioToolbox/AudioToolbox.h>#include "mediastreamer2/mssndcard.h"#include "mediastreamer2/msfilter.h"MSFilter *ms_ca_read_new(MSSndCard *card);MSFilter *ms_ca_write_new(MSSndCard *card);typedef struct CAData{	char *pcmdev;	char *mixdev;	AudioUnit caOutAudioUnit;	AudioUnit caInAudioUnit;	AudioStreamBasicDescription caOutASBD;	AudioStreamBasicDescription caInASBD;	AURenderCallbackStruct caOutRenderCallback;	AURenderCallbackStruct caInRenderCallback;	AudioConverterRef caOutConverter;	AudioConverterRef caInConverter;	int pcmfd;	int rate;	int bits;	ms_mutex_t mutex;	queue_t rq;	MSBufferizer * bufferizer;	bool_t read_started;	bool_t write_started;	bool_t stereo;	void *caSourceBuffer;	AudioBufferList	*fAudioBuffer, *fMSBuffer;} CAData;// Convenience function to dispose of our audio buffersvoid DestroyAudioBufferList(AudioBufferList* list){	UInt32						i;		if(list) {		for(i = 0; i < list->mNumberBuffers; i++) {			if(list->mBuffers[i].mData)			free(list->mBuffers[i].mData);		}		free(list);	}}// Convenience function to allocate our audio buffersAudioBufferList *AllocateAudioBufferList(UInt32 numChannels, UInt32 size){	AudioBufferList*			list;	UInt32						i;		list = (AudioBufferList*)calloc(1, sizeof(AudioBufferList) + numChannels * sizeof(AudioBuffer));	if(list == NULL)	return NULL;		list->mNumberBuffers = numChannels;	for(i = 0; i < numChannels; ++i) {		list->mBuffers[i].mNumberChannels = 1;		list->mBuffers[i].mDataByteSize = size;		list->mBuffers[i].mData = malloc(size);		if(list->mBuffers[i].mData == NULL) {			DestroyAudioBufferList(list);			return NULL;		}	}	return list;}OSStatus writeACInputProc (	AudioConverterRef inAudioConverter,	UInt32 *ioNumberDataPackets,	AudioBufferList *ioData,	AudioStreamPacketDescription **outDataPacketDescription,	void* inUserData){    OSStatus    err = noErr;	CAData *d=(CAData*)inUserData;	UInt32 packetSize = (d->bits / 8) * (d->stereo ? 2 : 1);//	ms_error("writeACInputProc %d", *ioNumberDataPackets);	if(*ioNumberDataPackets) {		if(d->caSourceBuffer != NULL) {			free(d->caSourceBuffer);			d->caSourceBuffer = NULL;		}		d->caSourceBuffer = (void *) calloc (1, *ioNumberDataPackets * packetSize);		ioData->mBuffers[0].mData = d->caSourceBuffer;			// tell the Audio Converter where it's source data is		ms_mutex_lock(&d->mutex);		int readsize = ms_bufferizer_read(d->bufferizer,d->caSourceBuffer,*ioNumberDataPackets * packetSize);		ms_mutex_unlock(&d->mutex);		if(readsize != *ioNumberDataPackets * packetSize) {			ms_error("ms_bufferizer_read error request = %d result = %d", *ioNumberDataPackets * packetSize, readsize);			memset(d->caSourceBuffer, 0, *ioNumberDataPackets * packetSize);			ioData->mBuffers[0].mDataByteSize = *ioNumberDataPackets * packetSize;		// tell the Audio Converter how much source data there is		} else {			ioData->mBuffers[0].mDataByteSize = readsize;		// tell the Audio Converter how much source data there is		}	}	return err;}OSStatus readACInputProc (AudioConverterRef inAudioConverter,				     UInt32* ioNumberDataPackets,				     AudioBufferList* ioData,				     AudioStreamPacketDescription** ioASPD,				     void* inUserData){	CAData *d=(CAData*)inUserData;	AudioBufferList* l_inputABL = d->fAudioBuffer;	UInt32 totalInputBufferSizeBytes = ((*ioNumberDataPackets) * sizeof (float));	int counter = d->caInASBD.mChannelsPerFrame;	ioData->mNumberBuffers = d->caInASBD.mChannelsPerFrame;	while (--counter >= 0)  {		AudioBuffer* l_ioD_AB = &(ioData->mBuffers[counter]);		l_ioD_AB->mNumberChannels = 1;		l_ioD_AB->mData = (float*)(l_inputABL->mBuffers[counter].mData);		l_ioD_AB->mDataByteSize = totalInputBufferSizeBytes;	}	return (noErr);}OSStatus readRenderProc(void *inRefCon, 	AudioUnitRenderActionFlags *inActionFlags,	const AudioTimeStamp *inTimeStamp, 	UInt32 inBusNumber,	UInt32 inNumFrames, 	AudioBufferList *ioData){	CAData *d=(CAData*)inRefCon;	OSStatus	err = noErr;	// Render into audio buffer	err = AudioUnitRender(d->caInAudioUnit, inActionFlags, inTimeStamp, inBusNumber,				inNumFrames, d->fAudioBuffer);	if(err != noErr)		ms_error("AudioUnitRender %d size = %d", err, d->fAudioBuffer->mBuffers[0].mDataByteSize);	UInt32 AvailableOutputBytes = inNumFrames * sizeof (float);    UInt32 propertySize = sizeof (AvailableOutputBytes);    err = AudioConverterGetProperty (d->caInConverter,		   kAudioConverterPropertyCalculateOutputBufferSize,				     &propertySize,				     &AvailableOutputBytes);	if(err != noErr)		ms_error("AudioConverterGetProperty %d", err);	UInt32 ActualOutputFrames = AvailableOutputBytes / sizeof (short);	err = AudioConverterFillComplexBuffer (d->caInConverter,	   (AudioConverterComplexInputDataProc)(readACInputProc),					   inRefCon,					   &ActualOutputFrames,					   d->fMSBuffer,					   NULL);	if(err != noErr)		ms_error("readRenderProc:AudioConverterFillComplexBuffer %08x mNumberBuffers = %d", err, ioData->mNumberBuffers);	mblk_t *rm=NULL;	rm=allocb(d->fMSBuffer->mBuffers[0].mDataByteSize,0);	memcpy(rm->b_wptr, d->fMSBuffer->mBuffers[0].mData, d->fMSBuffer->mBuffers[0].mDataByteSize);//	memset(rm->b_wptr, 0, d->fMSBuffer->mBuffers[0].mDataByteSize);	rm->b_wptr+=d->fMSBuffer->mBuffers[0].mDataByteSize;	ms_mutex_lock(&d->mutex);	putq(&d->rq,rm);	ms_mutex_unlock(&d->mutex);	rm=NULL;	return err;}OSStatus writeRenderProc(void *inRefCon, 	AudioUnitRenderActionFlags *inActionFlags,	const AudioTimeStamp *inTimeStamp, 	UInt32 inBusNumber,	UInt32 inNumFrames, 	AudioBufferList *ioData){    OSStatus err= noErr;    void *inInputDataProcUserData=NULL;	CAData *d=(CAData*)inRefCon;	if(d->write_started != FALSE) {		AudioStreamPacketDescription* outPacketDescription = NULL;		err = AudioConverterFillComplexBuffer(d->caOutConverter, writeACInputProc, inRefCon,			&inNumFrames, ioData, outPacketDescription);		if(err != noErr)			ms_error("writeRenderProc:AudioConverterFillComplexBuffer err %08x %d", err, ioData->mNumberBuffers);	}    return err;}static void ca_set_level(MSSndCard *card, MSSndCardMixerElem e, int percent){	CAData *d=(CAData*)card->data;}static int ca_get_level(MSSndCard *card, MSSndCardMixerElem e){	CAData *d=(CAData*)card->data;	return 0;}static void ca_set_source(MSSndCard *card, MSSndCardCapture source){	CAData *d=(CAData*)card->data;}static void ca_init(MSSndCard *card){	ms_debug("ca_init");	OSStatus err;	UInt32 param;	AudioDeviceID fInputDeviceID;	CAData *d=ms_new(CAData,1);	ComponentDescription desc;  	// Get Default Output audio unit	desc.componentType = kAudioUnitType_Output;	desc.componentSubType = kAudioUnitSubType_DefaultOutput;	desc.componentManufacturer = kAudioUnitManufacturer_Apple;	desc.componentFlags = 0;	desc.componentFlagsMask = 0;	Component comp = FindNextComponent(NULL, &desc);		if (comp == NULL) return;	err = OpenAComponent(comp, &d->caOutAudioUnit);	if(err != noErr) return;	// Get Default Input audio unit	desc.componentType = kAudioUnitType_Output;	desc.componentSubType = kAudioUnitSubType_HALOutput;	desc.componentManufacturer = kAudioUnitManufacturer_Apple;	desc.componentFlags = 0;	desc.componentFlagsMask = 0;	comp = FindNextComponent(NULL, &desc);		if (comp == NULL) return;	err = OpenAComponent(comp, &d->caInAudioUnit);	if(err != noErr) return;	AudioUnitInitialize(d->caOutAudioUnit);	AudioUnitInitialize(d->caInAudioUnit);	UInt32 asbdsize = sizeof(AudioStreamBasicDescription);	memset((char *)&d->caOutASBD, 0, asbdsize);	memset((char *)&d->caInASBD, 0, asbdsize);	// Setup Output audio unit	OSStatus result = AudioUnitGetProperty (d->caOutAudioUnit,							kAudioUnitProperty_StreamFormat,							kAudioUnitScope_Output,							0,							&d->caOutASBD,							&asbdsize);	result = AudioUnitSetProperty (d->caOutAudioUnit,							kAudioUnitProperty_StreamFormat,							kAudioUnitScope_Input,							0,							&d->caOutASBD,							asbdsize);	// Setup Input audio unit	// Enable input on the AUHAL	param = 1;	result = AudioUnitSetProperty(d->caInAudioUnit,							kAudioOutputUnitProperty_EnableIO,							kAudioUnitScope_Input,							1,							&param,							sizeof(UInt32));// Select the default input device	param = sizeof(AudioDeviceID);	result = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice,							&param,							&fInputDeviceID);	// Set the current device to the default input unit.	result = AudioUnitSetProperty(d->caInAudioUnit,							kAudioOutputUnitProperty_CurrentDevice,							kAudioUnitScope_Global,							0,							&fInputDeviceID,							sizeof(AudioDeviceID));	AudioStreamBasicDescription tmpASBD;	result = AudioUnitGetProperty (d->caInAudioUnit,							kAudioUnitProperty_StreamFormat,							kAudioUnitScope_Input,							0,							&tmpASBD,							&asbdsize);

⌨️ 快捷键说明

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