Exemplo n.º 1
0
static void ca_stop_r(CAData *d){
	OSErr err;
	if(d->read_started == TRUE) {
		if(AudioOutputUnitStop(d->caInAudioUnit) == noErr)
			d->read_started=FALSE;
	}
	if (d->caInConverter!=NULL)
	{
		AudioConverterDispose(d->caInConverter);
		d->caInConverter=NULL;
	}
	if (d->caInAudioUnit!=NULL)
	{
		AudioUnitUninitialize(d->caInAudioUnit);
		d->caInAudioUnit=NULL;
	}
	if (d->fAudioBuffer)
		DestroyAudioBufferList(d->fAudioBuffer);
	d->fAudioBuffer=NULL;
	if (d->fMSBuffer)
		DestroyAudioBufferList(d->fMSBuffer);
	d->fMSBuffer=NULL;
}
Exemplo n.º 2
0
// Convenience function to allocate our audio buffers
AudioBufferList *
AllocateAudioBufferList (UInt32 numChannels, UInt32 size)
{
  AudioBufferList *list;

  list = (AudioBufferList *) calloc (1, sizeof (AudioBufferList));
  if (list == NULL)
    return NULL;

  list->mNumberBuffers = 1;
  list->mBuffers[0].mNumberChannels = numChannels;
  list->mBuffers[0].mDataByteSize = size;
  list->mBuffers[0].mData = malloc (size);
  if (list->mBuffers[0].mData == NULL) {
    DestroyAudioBufferList (list);
    return NULL;
  }
  return list;
}
Exemplo n.º 3
0
// Convenience function to allocate our audio buffers
AudioBufferList *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;
}
Exemplo n.º 4
0
static void audio_cap_ca_done(void *state)
{
        struct state_ca_capture *s = (struct state_ca_capture *) state;

        if(!s)
                return;

        pthread_mutex_destroy(&s->lock);
        pthread_cond_destroy(&s->cv);
        DestroyAudioBufferList(s->theBufferList);
        free(s->frame.data);
        ring_buffer_destroy(s->buffer);
        free(s->tmp);

#ifdef HAVE_SPEEX
        if(s->resampler) {
                speex_resampler_destroy(s->resampler);
        }
        free(s->resampled);
#endif // HAVE_SPEEX

        free(s);
}
Exemplo n.º 5
0
OSStatus readRenderProc(void *inRefCon, 
						AudioUnitRenderActionFlags *inActionFlags,
						const AudioTimeStamp *inTimeStamp, 
						UInt32 inBusNumber,
						UInt32 inNumFrames, 
						AudioBufferList *ioData)
{
	CAData *d=(CAData*)inRefCon;
	OSStatus	err = noErr;
	
	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);
		return err;
	}
	
	UInt32 AvailableOutputBytes = inNumFrames * sizeof (float) * d->caInASBD.mChannelsPerFrame;
    UInt32 propertySize = sizeof (AvailableOutputBytes);
    err = AudioConverterGetProperty (d->caInConverter,
									 kAudioConverterPropertyCalculateOutputBufferSize,
									 &propertySize,
									 &AvailableOutputBytes);
	
	if(err != noErr)
	{
		ms_error("AudioConverterGetProperty kAudioConverterPropertyCalculateOutputBufferSize %d", err);
		return err;
	}
	
	if (AvailableOutputBytes>d->fMSBuffer->mBuffers[0].mDataByteSize)
	{	
		DestroyAudioBufferList(d->fMSBuffer);
		d->fMSBuffer = AllocateAudioBufferList(d->stereo ? 2 : 1,
											   AvailableOutputBytes);
	}
	
	UInt32 ActualOutputFrames = AvailableOutputBytes / ((d->bits / 8) * 1) / d->caInASBD.mChannelsPerFrame;
	err = AudioConverterFillComplexBuffer (d->caInConverter,
										   (AudioConverterComplexInputDataProc)(readACInputProc),
										   inRefCon,
										   &ActualOutputFrames,
										   d->fMSBuffer,
										   NULL);
	if(err != noErr)
	{
		ms_error("readRenderProc:AudioConverterFillComplexBuffer %d", err);
		return err;
	}
	
	mblk_t *rm=NULL;
	rm=allocb(ActualOutputFrames*2,0);
	memcpy(rm->b_wptr, d->fMSBuffer->mBuffers[0].mData, ActualOutputFrames*2);
	rm->b_wptr+=ActualOutputFrames*2;
	
	if (gain_volume_in != 1.0f)
	{
		int16_t *ptr=(int16_t *)rm->b_rptr;
		for (;ptr<(int16_t *)rm->b_wptr;ptr++)
		{
			*ptr=(int16_t)(((float)(*ptr))*gain_volume_in);
		}
	}
	
	ms_mutex_lock(&d->mutex);
	putq(&d->rq,rm);
	ms_mutex_unlock(&d->mutex);
	rm=NULL;
	
	return err;
}
Exemplo n.º 6
0
static void * audio_cap_ca_init(char *cfg)
{
        if(cfg && strcmp(cfg, "help") == 0) {
                printf("Available Core Audio capture devices:\n");
                audio_cap_ca_help(NULL);
                return &audio_init_state_ok;
        }
        struct state_ca_capture *s;
        OSErr ret = noErr;
#if OS_VERSION_MAJOR <= 9
        Component comp;
        ComponentDescription desc;
#else
        AudioComponent comp;
        AudioComponentDescription desc;
#endif
        UInt32 size;
        AudioDeviceID device;

        s = (struct state_ca_capture *) calloc(1, sizeof(struct state_ca_capture));

        size=sizeof(device);
        if(cfg != NULL) {
                device = atoi(cfg);
        } else {
                ret = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &size, &device);
                if(ret) {
                        fprintf(stderr, "Error finding default input device.\n");
                        goto error;
                }
        }

        pthread_mutex_init(&s->lock, NULL);
        pthread_cond_init(&s->cv, NULL);
        s->boss_waiting = FALSE;
        s->data_ready = FALSE;
        s->frame.bps = audio_capture_bps ? audio_capture_bps : 2;
        s->frame.ch_count = audio_capture_channels;

        double rate;
        size = sizeof(double);
        ret = AudioDeviceGetProperty(device, 0, 0, kAudioDevicePropertyNominalSampleRate, &size, &rate);
        s->nominal_sample_rate = rate;
        s->frame.sample_rate = audio_capture_sample_rate ? audio_capture_sample_rate :
                rate;
#if !defined HAVE_SPEEX || defined DISABLE_SPPEX_RESAMPLER
        s->frame.sample_rate = rate;
#if !defined HAVE_SPEEX
        fprintf(stderr, "[CoreAudio] Libspeex support not compiled in, resampling won't work (check manual or wiki how to enable it)!\n");
#endif
#else
        s->resampler = NULL;
        if(s->frame.sample_rate != s->nominal_sample_rate) {
                int err;
                s->resampler = speex_resampler_init(s->frame.ch_count, s->nominal_sample_rate, s->frame.sample_rate, 10, &err); 
                if(err) {
                        s->frame.sample_rate = s->nominal_sample_rate;
                }
        }
#endif

        s->frame.max_size = s->frame.bps * s->frame.ch_count * s->frame.sample_rate;
        int nonres_channel_size = s->frame.bps * s->nominal_sample_rate;

        s->theBufferList = AllocateAudioBufferList(s->frame.ch_count, nonres_channel_size);
        s->tmp = (char *) malloc(nonres_channel_size * s->frame.ch_count);

        s->buffer = ring_buffer_init(s->frame.max_size);
        s->frame.data = (char *) malloc(s->frame.max_size);
#ifdef HAVE_SPEEX
        s->resampled = (char *) malloc(s->frame.max_size);
#endif

        //There are several different types of Audio Units.
        //Some audio units serve as Outputs, Mixers, or DSP
        //units. See AUComponent.h for listing
        desc.componentType = kAudioUnitType_Output;

        //Every Component has a subType, which will give a clearer picture
        //of what this components function will be.
        //desc.componentSubType = kAudioUnitSubType_DefaultOutput;
        desc.componentSubType = kAudioUnitSubType_HALOutput;

        //all Audio Units in AUComponent.h must use 
        //"kAudioUnitManufacturer_Apple" as the Manufacturer
        desc.componentManufacturer = kAudioUnitManufacturer_Apple;
        desc.componentFlags = 0;
        desc.componentFlagsMask = 0;

#if OS_VERSION_MAJOR > 9
        comp = AudioComponentFindNext(NULL, &desc);
        if(!comp) {
                fprintf(stderr, "Error finding AUHAL component.\n");
                goto error;
        }
        ret = AudioComponentInstanceNew(comp, &s->auHALComponentInstance);
        if (ret != noErr) {
                fprintf(stderr, "Error opening AUHAL component.\n");
                goto error;
        }
#else
        comp = FindNextComponent(NULL, &desc);
        if(!comp) {
                fprintf(stderr, "Error finding AUHAL component.\n");
                goto error;
        }
        ret = OpenAComponent(comp, &s->auHALComponentInstance);
        if (ret != noErr) {
                fprintf(stderr, "Error opening AUHAL component.\n");
                goto error;
        }
#endif
        UInt32 enableIO;

        //When using AudioUnitSetProperty the 4th parameter in the method
        //refer to an AudioUnitElement. When using an AudioOutputUnit
        //the input element will be '1' and the output element will be '0'.


        enableIO = 1;
        ret = AudioUnitSetProperty(s->auHALComponentInstance,
                kAudioOutputUnitProperty_EnableIO,
                kAudioUnitScope_Input,
                1, // input element
                &enableIO,
                sizeof(enableIO));
        if (ret != noErr) {
                fprintf(stderr, "Error enabling input on AUHAL.\n");
                goto error;
        }

        enableIO = 0;
        ret = AudioUnitSetProperty(s->auHALComponentInstance,
                kAudioOutputUnitProperty_EnableIO,
                kAudioUnitScope_Output,
                0,   //output element
                &enableIO,
                sizeof(enableIO));
        if (ret != noErr) {
                fprintf(stderr, "Error disabling output on AUHAL.\n");
                goto error;
        }
        


        size=sizeof(device);
        ret = AudioUnitSetProperty(s->auHALComponentInstance,
                         kAudioOutputUnitProperty_CurrentDevice, 
                         kAudioUnitScope_Global, 
                         0, 
                         &device, 
                         sizeof(device));
        if(ret) {
                fprintf(stderr, "[CoreAudio] Error setting device to AUHAL instance.\n");
                goto error;
        }


        {
                AudioStreamBasicDescription desc;

                size = sizeof(desc);
                ret = AudioUnitGetProperty(s->auHALComponentInstance, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input,
                                1, &desc, &size);
                if(ret) {
                        fprintf(stderr, "[CoreAudio] Error getting default device properties.\n");
                        goto error;
                }

                desc.mChannelsPerFrame = s->frame.ch_count;
                desc.mSampleRate = (double) s->nominal_sample_rate;
                desc.mFormatID = kAudioFormatLinearPCM;
                desc.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked | kAudioFormatFlagIsNonInterleaved;
                if (desc.mFormatID == kAudioFormatLinearPCM && s->frame.ch_count == 1)
                        desc.mFormatFlags &= ~kLinearPCMFormatFlagIsNonInterleaved;

/*#if __BIG_ENDIAN__
                desc.mFormatFlags |= kAudioFormatFlagIsBigEndian;
#endif */
                desc.mBitsPerChannel = s->frame.bps * 8;
                desc.mBytesPerFrame = desc.mBitsPerChannel / 8;
                desc.mFramesPerPacket = 1;
                desc.mBytesPerPacket = desc.mBytesPerFrame;
                s->audio_packet_size = desc.mBytesPerPacket;

                ret = AudioUnitSetProperty(s->auHALComponentInstance, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output,
                                1, &desc, sizeof(desc));
                if(ret) {
                        fprintf(stderr, "[CoreAudio] Error setting device properties.\n");
                        goto error;
                }

                AURenderCallbackStruct input;
                input.inputProc = InputProc;
                input.inputProcRefCon = s;
                ret = AudioUnitSetProperty(s->auHALComponentInstance, kAudioOutputUnitProperty_SetInputCallback,
                                kAudioUnitScope_Global, 0, &input, sizeof(input));
                if(ret) {
                        fprintf(stderr, "[CoreAudio] Error setting input callback.\n");
                        goto error;
                }
        }

        ret = AudioUnitInitialize(s->auHALComponentInstance);
        if(ret) {
                fprintf(stderr, "[CoreAudio] Error initializing device.\n");
                goto error;
        }

        ret = AudioOutputUnitStart(s->auHALComponentInstance);
        if(ret) {
                fprintf(stderr, "[CoreAudio] Error starting device.\n");
                goto error;
        }

        return s;

error:
        pthread_mutex_destroy(&s->lock);
        pthread_cond_destroy(&s->cv);
        DestroyAudioBufferList(s->theBufferList);
        free(s->frame.data);
        ring_buffer_destroy(s->buffer);
        free(s->tmp);
        free(s);
        return NULL;
}