Example #1
0
int
coreaudio_object_open(struct audio_object *object,
                       enum audio_object_format format,
                       uint32_t rate,
                       uint8_t channels)
{
	struct coreaudio_object *self = to_coreaudio_object(object);
	OSStatus err = noErr;
	if (self->initialized)
		return noErr;

	memset(&(self->format), 0, sizeof(AudioStreamBasicDescription));
	(self->format).mSampleRate = rate;
	(self->format).mChannelsPerFrame = channels;
	(self->format).mFramesPerPacket = 1;
	switch (format)
	{
		case AUDIO_OBJECT_FORMAT_S16LE:
			(self->format).mFormatID = kAudioFormatLinearPCM;
			(self->format).mBitsPerChannel = 16;
			(self->format).mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked;
			break;
		default:
			return -1;
	}
	// guess the remaining of the AudioBasicStreamDescription structure
	UInt32 procSize = sizeof(AudioStreamBasicDescription);
	err = AudioFormatGetProperty(kAudioFormatProperty_FormatInfo, 0, NULL, &procSize, &(self->format));
	if(err != noErr) {
		goto cleanup;
	}


	// Find default output
	AudioComponentDescription outputcd = {0,};
	outputcd.componentType = kAudioUnitType_Output;
	outputcd.componentSubType = kAudioUnitSubType_DefaultOutput;
	outputcd.componentManufacturer = kAudioUnitManufacturer_Apple;
	
	// Create a component
	AudioComponent outputComponent = AudioComponentFindNext(NULL, &outputcd);
	err = AudioComponentInstanceNew(outputComponent, &(self->outputUnit));
	if(err != noErr) {
		goto cleanup;
	}

	// set render callback
	AURenderCallbackStruct callbackStruct;
	callbackStruct.inputProcRefCon = self;
	callbackStruct.inputProc = graphRenderProc;
	size_t propSize = sizeof(AURenderCallbackStruct);
	err = AudioUnitSetProperty(self->outputUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Output, 0, &callbackStruct, propSize);
	if(err != noErr) {
		goto cleanup;
	}
	
	// set output unit input format
	propSize = sizeof(AudioStreamBasicDescription);
	err = AudioUnitSetProperty(self->outputUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &(self->format), propSize);
	if(err != noErr) {
		goto cleanup;
	}

	err = AudioUnitInitialize(self->outputUnit);
	if(err != noErr) {
		goto cleanup;
	}
	// create a circular buffer to produce and consume audio
	TPCircularBufferInit(&(self->circularBuffer), COREAUDIO_BUFFER_SIZE);

	self->initialized = TRUE;
	return noErr;
cleanup:
	if(self->outputUnit) {
		AudioUnitUninitialize(self->outputUnit);
		AudioComponentInstanceDispose(self->outputUnit);
	}
	return err;
}
Example #2
0
int CoreAudioDrv_PCM_Init(int * mixrate, int * numchannels, int * samplebits, void * initdata)
{
	OSStatus result = noErr;
	AudioComponentDescription desc;
	AudioStreamBasicDescription requestedDesc;
	
	if (Initialised) {
		CoreAudioDrv_PCM_Shutdown();
	}
	
	if (pthread_mutex_init(&mutex, 0) < 0) {
		ErrorCode = CAErr_Mutex;
		return CAErr_Error;
	}
    
    // Setup a AudioStreamBasicDescription with the requested format
	requestedDesc.mFormatID = kAudioFormatLinearPCM;
	requestedDesc.mFormatFlags = kLinearPCMFormatFlagIsPacked;
	requestedDesc.mChannelsPerFrame = *numchannels;
	requestedDesc.mSampleRate = *mixrate;
	
	requestedDesc.mBitsPerChannel = *samplebits;
	if (*samplebits == 16) {
		requestedDesc.mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger;
	}
	
	requestedDesc.mFramesPerPacket = 1;
	requestedDesc.mBytesPerFrame = requestedDesc.mBitsPerChannel * requestedDesc.mChannelsPerFrame / 8;
	requestedDesc.mBytesPerPacket = requestedDesc.mBytesPerFrame * requestedDesc.mFramesPerPacket;
	
    // Locate the default output audio unit
	desc.componentType = kAudioUnitType_Output;
	desc.componentSubType = kAudioUnitSubType_DefaultOutput;
	desc.componentManufacturer = kAudioUnitManufacturer_Apple;
	desc.componentFlags = 0;
	desc.componentFlagsMask = 0;
	
    comp = AudioComponentFindNext(NULL, &desc);
	if (comp == NULL) {
        ErrorCode = CAErr_FindNextComponent;
		pthread_mutex_destroy(&mutex);
        return CAErr_Error;
	}
	
    // Open & initialize the default output audio unit
    result = AudioComponentInstanceNew(comp, &output_audio_unit);
	if (result != noErr) {
        ErrorCode = CAErr_OpenAComponent;
        //CloseComponent(output_audio_unit);
        pthread_mutex_destroy(&mutex);
        return CAErr_Error;
	}
	
	result = AudioUnitInitialize(output_audio_unit);
	if (result != noErr) {
        ErrorCode = CAErr_AudioUnitInitialize;
        //CloseComponent(output_audio_unit);
		pthread_mutex_destroy(&mutex);
        return CAErr_Error;
	}
	
    // Set the input format of the audio unit.
	result = AudioUnitSetProperty(output_audio_unit,
                                  kAudioUnitProperty_StreamFormat,
                                  kAudioUnitScope_Input,
                                  0,
                                  &requestedDesc,
                                  sizeof(requestedDesc));
	if (result != noErr) {
        ErrorCode = CAErr_AudioUnitSetProperty;
        //CloseComponent(output_audio_unit);
		pthread_mutex_destroy(&mutex);
        return CAErr_Error;
	}
	
    // Set the audio callback
    setMixerCallback();
	
	Initialised = 1;
	
	return CAErr_Ok;
}
Example #3
0
static void *coreaudio_init(const char *device, unsigned rate, unsigned latency)
{
   (void)device;

   coreaudio_t *dev = (coreaudio_t*)calloc(1, sizeof(*dev));
   if (!dev)
      return NULL;

   pthread_mutex_init(&dev->lock, NULL);
   pthread_cond_init(&dev->cond, NULL);

#ifdef IOS
   static bool session_initialized = false;
   if (!session_initialized)
   {
      session_initialized = true;
      AudioSessionInitialize(0, 0, coreaudio_interrupt_listener, 0);
      AudioSessionSetActive(true);
   }
#endif

   // Create AudioComponent
   AudioComponentDescription desc = {0};
   desc.componentType = kAudioUnitType_Output;
#ifdef IOS
   desc.componentSubType = kAudioUnitSubType_RemoteIO;
#else
   desc.componentSubType = kAudioUnitSubType_HALOutput;
#endif
   desc.componentManufacturer = kAudioUnitManufacturer_Apple;

   AudioComponent comp = AudioComponentFindNext(NULL, &desc);
   if (comp == NULL)
      goto error;
   
   if (AudioComponentInstanceNew(comp, &dev->dev) != noErr)
      goto error;

#ifdef OSX
   if (device)
      choose_output_device(dev, device);
#endif

   dev->dev_alive = true;

   // Set audio format
   AudioStreamBasicDescription stream_desc = {0};
   AudioStreamBasicDescription real_desc;
   
   stream_desc.mSampleRate = rate;
   stream_desc.mBitsPerChannel = sizeof(float) * CHAR_BIT;
   stream_desc.mChannelsPerFrame = 2;
   stream_desc.mBytesPerPacket = 2 * sizeof(float);
   stream_desc.mBytesPerFrame = 2 * sizeof(float);
   stream_desc.mFramesPerPacket = 1;
   stream_desc.mFormatID = kAudioFormatLinearPCM;
   stream_desc.mFormatFlags = kAudioFormatFlagIsFloat | kAudioFormatFlagIsPacked | (is_little_endian() ? 0 : kAudioFormatFlagIsBigEndian);
   
   if (AudioUnitSetProperty(dev->dev, kAudioUnitProperty_StreamFormat,
         kAudioUnitScope_Input, 0, &stream_desc, sizeof(stream_desc)) != noErr)
      goto error;
   
   // Check returned audio format
   UInt32 i_size = sizeof(real_desc);;
   if (AudioUnitGetProperty(dev->dev, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &real_desc, &i_size) != noErr)
      goto error;

   if (real_desc.mChannelsPerFrame != stream_desc.mChannelsPerFrame)
      goto error;
   if (real_desc.mBitsPerChannel != stream_desc.mBitsPerChannel)
      goto error;
   if (real_desc.mFormatFlags != stream_desc.mFormatFlags)
      goto error;
   if (real_desc.mFormatID != stream_desc.mFormatID)
      goto error;

   RARCH_LOG("[CoreAudio]: Using output sample rate of %.1f Hz\n", (float)real_desc.mSampleRate);
   g_settings.audio.out_rate = real_desc.mSampleRate;


   // Set channel layout (fails on iOS)
#ifndef IOS
   AudioChannelLayout layout = {0};

   layout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo;
   if (AudioUnitSetProperty(dev->dev, kAudioUnitProperty_AudioChannelLayout,
         kAudioUnitScope_Input, 0, &layout, sizeof(layout)) != noErr)
      goto error;
#endif

   // Set callbacks and finish up
   AURenderCallbackStruct cb = {0};
   cb.inputProc = audio_write_cb;
   cb.inputProcRefCon = dev;

   if (AudioUnitSetProperty(dev->dev, kAudioUnitProperty_SetRenderCallback,
         kAudioUnitScope_Input, 0, &cb, sizeof(cb)) != noErr)
      goto error;

   if (AudioUnitInitialize(dev->dev) != noErr)
      goto error;

   size_t fifo_size;

   fifo_size = (latency * g_settings.audio.out_rate) / 1000;
   fifo_size *= 2 * sizeof(float);
   dev->buffer_size = fifo_size;

   dev->buffer = fifo_new(fifo_size);
   if (!dev->buffer)
      goto error;

   RARCH_LOG("[CoreAudio]: Using buffer size of %u bytes: (latency = %u ms)\n", (unsigned)fifo_size, latency);

   if (AudioOutputUnitStart(dev->dev) != noErr)
      goto error;

   return dev;

error:
   RARCH_ERR("[CoreAudio]: Failed to initialize driver ...\n");
   coreaudio_free(dev);
   return NULL;
}
Example #4
0
int sound_open_AudioUnit(int rate, int bits, int stereo){
    Float64 sampleRate = 48000.0;

    if( soundInit == 1 )
    {
        sound_close_AudioUnit();
    }
    
    if(rate==44100)
        sampleRate = 44100.0;
    if(rate==32000)
        sampleRate = 32000.0;
    else if(rate==22050)
        sampleRate = 22050.0;
    else if(rate==11025)
        sampleRate = 11025.0;
    
    //audioBufferSize =  (rate / 60) * 2 * (stereo==1 ? 2 : 1) ;
    
    OSStatus status;
    
    // Describe audio component
    AudioComponentDescription desc;
    desc.componentType = kAudioUnitType_Output;
    desc.componentSubType = kAudioUnitSubType_RemoteIO;
    
    desc.componentFlags = 0;
    desc.componentFlagsMask = 0;
    desc.componentManufacturer = kAudioUnitManufacturer_Apple;
    
    // Get component
    AudioComponent inputComponent = AudioComponentFindNext(NULL, &desc);
    
    // Get audio units
    status = AudioComponentInstanceNew(inputComponent, &audioUnit);
    checkStatus(status);
    
    UInt32 flag = 1;
    // Enable IO for playback
    status = AudioUnitSetProperty(audioUnit,
                                  kAudioOutputUnitProperty_EnableIO,
                                  kAudioUnitScope_Output,
                                  kOutputBus,
                                  &flag,
                                  sizeof(flag));
    checkStatus(status);
    
    AudioStreamBasicDescription audioFormat;
    
    memset (&audioFormat, 0, sizeof (audioFormat));
    
    audioFormat.mSampleRate = sampleRate;
    audioFormat.mFormatID = kAudioFormatLinearPCM;
    audioFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger  | kAudioFormatFlagIsPacked;
    audioFormat.mBytesPerPacket =  (stereo == 1 ? 4 : 2 );
    audioFormat.mFramesPerPacket = 1;
    audioFormat.mBytesPerFrame = (stereo ==  1? 4 : 2);
    audioFormat.mChannelsPerFrame = (stereo == 1 ? 2 : 1);
    audioFormat.mBitsPerChannel = 16;
    
    status = AudioUnitSetProperty(audioUnit,
                                  kAudioUnitProperty_StreamFormat,
                                  kAudioUnitScope_Input,
                                  kOutputBus,
                                  &audioFormat,
                                  sizeof(audioFormat));
    checkStatus(status);
    
    struct AURenderCallbackStruct callbackStruct;
    // Set output callback
    callbackStruct.inputProc = playbackCallback;
    callbackStruct.inputProcRefCon = NULL;
    status = AudioUnitSetProperty(audioUnit,
                                  kAudioUnitProperty_SetRenderCallback,
                                  kAudioUnitScope_Global,
                                  kOutputBus,
                                  &callbackStruct,
                                  sizeof(callbackStruct));
    checkStatus(status);
    
    status = AudioUnitInitialize(audioUnit);
    checkStatus(status);
    
    //ARRANCAR
    soundInit = 1;
    status = AudioOutputUnitStart(audioUnit);
    checkStatus(status);
    
    return 1;
}
Example #5
0
static int
prepare_audiounit(_THIS, const char *devname, int iscapture,
                  const AudioStreamBasicDescription * strdesc)
{
    OSStatus result = noErr;
    AURenderCallbackStruct callback;
#if MACOSX_COREAUDIO
    ComponentDescription desc;
    Component comp = NULL;
#else
    AudioComponentDescription desc;
    AudioComponent comp = NULL;
#endif
    const AudioUnitElement output_bus = 0;
    const AudioUnitElement input_bus = 1;
    const AudioUnitElement bus = ((iscapture) ? input_bus : output_bus);
    const AudioUnitScope scope = ((iscapture) ? kAudioUnitScope_Output :
                                  kAudioUnitScope_Input);

#if MACOSX_COREAUDIO
    if (!find_device_by_name(this, devname, iscapture)) {
        SDL_SetError("Couldn't find requested CoreAudio device");
        return 0;
    }
#endif

    SDL_zero(desc);
    desc.componentType = kAudioUnitType_Output;
    desc.componentManufacturer = kAudioUnitManufacturer_Apple;

#if MACOSX_COREAUDIO
    if (!iscapture) {
        desc.componentSubType = kAudioUnitSubType_DefaultOutput;
    } else {
        desc.componentSubType = kAudioUnitSubType_HALOutput;
    }
    comp = FindNextComponent(NULL, &desc);
#else
    desc.componentSubType = kAudioUnitSubType_RemoteIO;
    comp = AudioComponentFindNext(NULL, &desc);
#endif

    if (comp == NULL) {
        SDL_SetError("Couldn't find requested CoreAudio component");
        return 0;
    }

    /* Open & initialize the audio unit */
#if MACOSX_COREAUDIO
    result = OpenAComponent(comp, &this->hidden->audioUnit);
    CHECK_RESULT("OpenAComponent");
#else
    /*
       AudioComponentInstanceNew only available on iPhone OS 2.0 and Mac OS X 10.6
       We can't use OpenAComponent on iPhone because it is not present
     */
    result = AudioComponentInstanceNew(comp, &this->hidden->audioUnit);
    CHECK_RESULT("AudioComponentInstanceNew");
#endif

    this->hidden->audioUnitOpened = 1;

#if MACOSX_COREAUDIO
    if (iscapture) {
        UInt32 enableIO = 1;
        result = AudioUnitSetProperty(this->hidden->audioUnit,
                kAudioOutputUnitProperty_EnableIO,
                kAudioUnitScope_Input,
                input_bus,
                &enableIO, sizeof(enableIO));
        CHECK_RESULT("AudioUnitSetProperty (kAudioOutputUnitProperty_EnableIO 1)");
        enableIO = 0;
        result = AudioUnitSetProperty(this->hidden->audioUnit,
                kAudioOutputUnitProperty_EnableIO,
                kAudioUnitScope_Output,
                output_bus,
                &enableIO, sizeof(enableIO));
        CHECK_RESULT("AudioUnitSetProperty (kAudioOutputUnitProperty_EnableIO 0)");
 
        result = AudioUnitSetProperty(this->hidden->audioUnit,
                             kAudioOutputUnitProperty_CurrentDevice,
                             kAudioUnitScope_Global, 1,
                             &this->hidden->deviceID,
                             sizeof(AudioDeviceID));
        CHECK_RESULT("AudioUnitSetProperty (kAudioOutputUnitProperty_CurrentDevice)");
    } else {
        result = AudioUnitSetProperty(this->hidden->audioUnit,
                                      kAudioOutputUnitProperty_CurrentDevice,
                                      kAudioUnitScope_Global, 0,
                                      &this->hidden->deviceID,
                                      sizeof(AudioDeviceID));
        CHECK_RESULT
            ("AudioUnitSetProperty (kAudioOutputUnitProperty_CurrentDevice)");
    }
#endif

    /* Set the data format of the audio unit. */
    result = AudioUnitSetProperty(this->hidden->audioUnit,
                                  kAudioUnitProperty_StreamFormat,
                                  scope, bus, strdesc, sizeof(*strdesc));
    CHECK_RESULT("AudioUnitSetProperty (kAudioUnitProperty_StreamFormat)");

    /* Set the audio callback */
    SDL_memset(&callback, 0, sizeof(AURenderCallbackStruct));
    callback.inputProc = ((iscapture) ? inputCallback : outputCallback);
    callback.inputProcRefCon = this;
    if (!iscapture) {
        result = AudioUnitSetProperty(this->hidden->audioUnit,
                                      kAudioUnitProperty_SetRenderCallback,
                                      scope, bus, &callback, sizeof(callback));
        CHECK_RESULT
            ("AudioUnitSetProperty (kAudioUnitProperty_SetRenderCallback)");
    } else {
        result = AudioUnitSetProperty(this->hidden->audioUnit,
                                      kAudioOutputUnitProperty_SetInputCallback,
                                      kAudioUnitScope_Global, bus, &callback, sizeof(callback));
        CHECK_RESULT
            ("AudioUnitSetProperty (kAudioUnitProperty_SetInputCallback)");
    }

    /* Calculate the final parameters for this audio specification */
    SDL_CalculateAudioSpec(&this->spec);

    /* Allocate a sample buffer */
    this->hidden->bufferOffset = this->hidden->bufferSize = this->spec.size;
    this->hidden->buffer = SDL_malloc(this->hidden->bufferSize);
    if (iscapture) {
        this->hidden->bufferOffset = 0;
    }

    result = AudioUnitInitialize(this->hidden->audioUnit);
    CHECK_RESULT("AudioUnitInitialize");

    /* Finally, start processing of the audio unit */
    result = AudioOutputUnitStart(this->hidden->audioUnit);
    CHECK_RESULT("AudioOutputUnitStart");

    /* We're running! */
    return 1;
}
Example #6
0
static int
prepare_audiounit(_THIS, const char *devname, int iscapture,
                  const AudioStreamBasicDescription * strdesc)
{
    OSStatus result = noErr;
    AURenderCallbackStruct callback;
    AudioComponentDescription desc;
    AudioComponent comp = NULL;

    UInt32 enableIO = 0;
    const AudioUnitElement output_bus = 0;
    const AudioUnitElement input_bus = 1;
    const AudioUnitElement bus = ((iscapture) ? input_bus : output_bus);
    const AudioUnitScope scope = ((iscapture) ? kAudioUnitScope_Output :
                                  kAudioUnitScope_Input);

    SDL_memset(&desc, '\0', sizeof(AudioComponentDescription));
    desc.componentType = kAudioUnitType_Output;
    desc.componentSubType = kAudioUnitSubType_RemoteIO;
    desc.componentManufacturer = kAudioUnitManufacturer_Apple;

    comp = AudioComponentFindNext(NULL, &desc);
    if (comp == NULL) {
        SDL_SetError("Couldn't find requested CoreAudio component");
        return 0;
    }

    /* Open & initialize the audio unit */
    /*
       AudioComponentInstanceNew only available on iPhone OS 2.0 and Mac OS X 10.6  
       We can't use OpenAComponent on iPhone because it is not present
     */
    result = AudioComponentInstanceNew(comp, &this->hidden->audioUnit);
    CHECK_RESULT("AudioComponentInstanceNew");

    this->hidden->audioUnitOpened = 1;

    // !!! FIXME: this is wrong?
    enableIO = ((iscapture) ? 1 : 0);
    result = AudioUnitSetProperty(this->hidden->audioUnit,
                                  kAudioOutputUnitProperty_EnableIO,
                                  kAudioUnitScope_Input, input_bus,
                                  &enableIO, sizeof(enableIO));
    CHECK_RESULT("AudioUnitSetProperty (kAudioUnitProperty_EnableIO input)");

    // !!! FIXME: this is wrong?
    enableIO = ((iscapture) ? 0 : 1);
    result = AudioUnitSetProperty(this->hidden->audioUnit,
                                  kAudioOutputUnitProperty_EnableIO,
                                  kAudioUnitScope_Output, output_bus,
                                  &enableIO, sizeof(enableIO));
    CHECK_RESULT("AudioUnitSetProperty (kAudioUnitProperty_EnableIO output)");

    /*result = AudioUnitSetProperty(this->hidden->audioUnit,
       kAudioOutputUnitProperty_CurrentDevice,
       kAudioUnitScope_Global, 0,
       &this->hidden->deviceID,
       sizeof(AudioDeviceID));

       CHECK_RESULT("AudioUnitSetProperty (kAudioOutputUnitProperty_CurrentDevice)"); */

    /* Set the data format of the audio unit. */
    result = AudioUnitSetProperty(this->hidden->audioUnit,
                                  kAudioUnitProperty_StreamFormat,
                                  scope, bus, strdesc, sizeof(*strdesc));
    CHECK_RESULT("AudioUnitSetProperty (kAudioUnitProperty_StreamFormat)");

    /* Set the audio callback */
    SDL_memset(&callback, '\0', sizeof(AURenderCallbackStruct));
    callback.inputProc = ((iscapture) ? inputCallback : outputCallback);
    callback.inputProcRefCon = this;
    result = AudioUnitSetProperty(this->hidden->audioUnit,
                                  kAudioUnitProperty_SetRenderCallback,
                                  scope, bus, &callback, sizeof(callback));
    CHECK_RESULT
        ("AudioUnitSetProperty (kAudioUnitProperty_SetInputCallback)");

    /* Calculate the final parameters for this audio specification */
    SDL_CalculateAudioSpec(&this->spec);

    /* Allocate a sample buffer */
    this->hidden->bufferOffset = this->hidden->bufferSize = this->spec.size;
    this->hidden->buffer = SDL_malloc(this->hidden->bufferSize);

    result = AudioUnitInitialize(this->hidden->audioUnit);
    CHECK_RESULT("AudioUnitInitialize");

    /* Finally, start processing of the audio unit */
    result = AudioOutputUnitStart(this->hidden->audioUnit);
    CHECK_RESULT("AudioOutputUnitStart");
    /* We're running! */
    return 1;
}
Example #7
0
/*
 *Setup RemoteIO Audio Unit.
 * (TODO) provide dynamic configuration options here.
 */
int MUEAudioIO::setupIO()
{
    try {		
		// Open the output unit
		AudioComponentDescription desc;
		desc.componentType			= kAudioUnitType_Output;
		desc.componentSubType		= kAudioUnitSubType_RemoteIO;
		desc.componentManufacturer	= kAudioUnitManufacturer_Apple;
		desc.componentFlags			= 0;
		desc.componentFlagsMask		= 0;
		
		AudioComponent comp = AudioComponentFindNext(NULL, &desc);
		
		AudioComponentInstanceNew(comp, &rioUnit);
        
		UInt32 one = 1;
		AudioUnitSetProperty(rioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &one, sizeof(one));
        
        
        
        // Setup Callbacks--------------------------------------------------
        printf("setupIO: Initializing Callbacks\n");
        AURenderCallbackStruct inProc;
        
        inProc.inputProc = MUEinputCallback;
        inProc.inputProcRefCon = this;
        
		AudioUnitSetProperty(rioUnit, kAudioOutputUnitProperty_SetInputCallback,
							 kAudioUnitScope_Global, AUDIO_INPUT_BUS, &inProc, sizeof(inProc));
		
        inProc.inputProc = MUEoutputCallback;
        inProc.inputProcRefCon = this;
        
        AudioUnitSetProperty(rioUnit, kAudioUnitProperty_SetRenderCallback,
							 kAudioUnitScope_Global, AUDIO_OUTPUT_BUS, &inProc, sizeof(inProc));
        //-----------------------------------------------------------------
        
        
        // Enable Input and Output------------------------------------------
        // Enable Output....
        UInt32 flag = 1;
        OSStatus status = AudioUnitSetProperty(rioUnit, kAudioOutputUnitProperty_EnableIO, 
											   kAudioUnitScope_Output, AUDIO_OUTPUT_BUS, &flag, sizeof(flag));
        
        if (status != noErr)
        {
            printf("MUEAudioIO::setupIO: Enable Output failed: status = %d\n", status);
        }
        
        // Enable Input....
        status = AudioUnitSetProperty(rioUnit, kAudioOutputUnitProperty_EnableIO, 
									  kAudioUnitScope_Input, AUDIO_INPUT_BUS, &flag, sizeof(flag));
        
        if (status != noErr)
        {
            printf("MUEAudioIO::setupIO: Enable Input failed: status = %d\n", status);
        }
        //-----------------------------------------------------------------
        
        
		// Set up audio I/0 format, data type whatever. Describe the stream.
        // AudioStreamBasicDescription streamDesc;
        // This next function is built into Core Audio
        FillOutASBDForLPCM(m_streamDesc, AUDIO_SAMPLE_RATE, AUDIO_NUM_CHANNELS, AUDIO_BIT_DEPTH,
						   AUDIO_BIT_DEPTH, false, false, AUDIO_FORMAT_IS_NONINTERLEAVED);
        
        
		// XThrowIfError(AudioUnitGetProperty(rioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &m_streamDesc, sizeof(m_streamDesc) ), "couldn't get the remote I/O unit's output client format");
        
        // TODO: why is scope input associated with output bus? and vice versa?
		AudioUnitSetProperty(rioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, AUDIO_OUTPUT_BUS, &m_streamDesc, sizeof(m_streamDesc));
        AudioUnitSetProperty(rioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, AUDIO_INPUT_BUS, &m_streamDesc, sizeof(m_streamDesc));

/*		// Prints audio configuration settings, why wont this print?
		printf("  m_streamDesc initialized with AUDIO_SAMPLE_RATE  : %f", AUDIO_SAMPLE_RATE);
		printf("                                AUDIO_NUM_CHANNELS : %d", AUDIO_NUM_CHANNELS);
		printf("                                AUDIO_BIT_DEPTH    : %d", AUDIO_BIT_DEPTH);
*/		
		AudioUnitInitialize(rioUnit);

	}
	catch (...) {
		printf("An unknown error occurred\n");
		return 1;
	}	
	
	return 0;
	
	
}
Example #8
0
Error AudioDriverCoreAudio::init() {
	mutex = Mutex::create();

	AudioComponentDescription desc;
	zeromem(&desc, sizeof(desc));
	desc.componentType = kAudioUnitType_Output;
#ifdef OSX_ENABLED
	desc.componentSubType = kAudioUnitSubType_HALOutput;
#else
	desc.componentSubType = kAudioUnitSubType_RemoteIO;
#endif
	desc.componentManufacturer = kAudioUnitManufacturer_Apple;

	AudioComponent comp = AudioComponentFindNext(NULL, &desc);
	ERR_FAIL_COND_V(comp == NULL, FAILED);

	OSStatus result = AudioComponentInstanceNew(comp, &audio_unit);
	ERR_FAIL_COND_V(result != noErr, FAILED);

#ifdef OSX_ENABLED
	AudioObjectPropertyAddress prop;
	prop.mSelector = kAudioHardwarePropertyDefaultOutputDevice;
	prop.mScope = kAudioObjectPropertyScopeGlobal;
	prop.mElement = kAudioObjectPropertyElementMaster;

	result = AudioObjectAddPropertyListener(kAudioObjectSystemObject, &prop, &output_device_address_cb, this);
	ERR_FAIL_COND_V(result != noErr, FAILED);
#endif

	AudioStreamBasicDescription strdesc;

	zeromem(&strdesc, sizeof(strdesc));
	UInt32 size = sizeof(strdesc);
	result = AudioUnitGetProperty(audio_unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, kOutputBus, &strdesc, &size);
	ERR_FAIL_COND_V(result != noErr, FAILED);

	switch (strdesc.mChannelsPerFrame) {
		case 2: // Stereo
		case 4: // Surround 3.1
		case 6: // Surround 5.1
		case 8: // Surround 7.1
			channels = strdesc.mChannelsPerFrame;
			break;

		default:
			// Unknown number of channels, default to stereo
			channels = 2;
			break;
	}

	mix_rate = GLOBAL_DEF_RST("audio/mix_rate", DEFAULT_MIX_RATE);

	zeromem(&strdesc, sizeof(strdesc));
	strdesc.mFormatID = kAudioFormatLinearPCM;
	strdesc.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
	strdesc.mChannelsPerFrame = channels;
	strdesc.mSampleRate = mix_rate;
	strdesc.mFramesPerPacket = 1;
	strdesc.mBitsPerChannel = 16;
	strdesc.mBytesPerFrame = strdesc.mBitsPerChannel * strdesc.mChannelsPerFrame / 8;
	strdesc.mBytesPerPacket = strdesc.mBytesPerFrame * strdesc.mFramesPerPacket;

	result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, kOutputBus, &strdesc, sizeof(strdesc));
	ERR_FAIL_COND_V(result != noErr, FAILED);

	int latency = GLOBAL_DEF_RST("audio/output_latency", DEFAULT_OUTPUT_LATENCY);
	// Sample rate is independent of channels (ref: https://stackoverflow.com/questions/11048825/audio-sample-frequency-rely-on-channels)
	buffer_frames = closest_power_of_2(latency * mix_rate / 1000);

#ifdef OSX_ENABLED
	result = AudioUnitSetProperty(audio_unit, kAudioDevicePropertyBufferFrameSize, kAudioUnitScope_Global, kOutputBus, &buffer_frames, sizeof(UInt32));
	ERR_FAIL_COND_V(result != noErr, FAILED);
#endif

	unsigned int buffer_size = buffer_frames * channels;
	samples_in.resize(buffer_size);
	input_buf.resize(buffer_size);
	input_buffer.resize(buffer_size * 8);
	input_position = 0;
	input_size = 0;

	print_verbose("CoreAudio: detected " + itos(channels) + " channels");
	print_verbose("CoreAudio: audio buffer frames: " + itos(buffer_frames) + " calculated latency: " + itos(buffer_frames * 1000 / mix_rate) + "ms");

	AURenderCallbackStruct callback;
	zeromem(&callback, sizeof(AURenderCallbackStruct));
	callback.inputProc = &AudioDriverCoreAudio::output_callback;
	callback.inputProcRefCon = this;
	result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, kOutputBus, &callback, sizeof(callback));
	ERR_FAIL_COND_V(result != noErr, FAILED);

	result = AudioUnitInitialize(audio_unit);
	ERR_FAIL_COND_V(result != noErr, FAILED);

	return capture_init();
}
Example #9
0
Error AudioDriverCoreAudio::capture_init() {
	AudioComponentDescription desc;
	zeromem(&desc, sizeof(desc));
	desc.componentType = kAudioUnitType_Output;
#ifdef OSX_ENABLED
	desc.componentSubType = kAudioUnitSubType_HALOutput;
#else
	desc.componentSubType = kAudioUnitSubType_RemoteIO;
#endif
	desc.componentManufacturer = kAudioUnitManufacturer_Apple;

	AudioComponent comp = AudioComponentFindNext(NULL, &desc);
	ERR_FAIL_COND_V(comp == NULL, FAILED);

	OSStatus result = AudioComponentInstanceNew(comp, &input_unit);
	ERR_FAIL_COND_V(result != noErr, FAILED);

#ifdef OSX_ENABLED
	AudioObjectPropertyAddress prop;
	prop.mSelector = kAudioHardwarePropertyDefaultInputDevice;
	prop.mScope = kAudioObjectPropertyScopeGlobal;
	prop.mElement = kAudioObjectPropertyElementMaster;

	result = AudioObjectAddPropertyListener(kAudioObjectSystemObject, &prop, &input_device_address_cb, this);
	ERR_FAIL_COND_V(result != noErr, FAILED);
#endif

	UInt32 flag = 1;
	result = AudioUnitSetProperty(input_unit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, kInputBus, &flag, sizeof(flag));
	ERR_FAIL_COND_V(result != noErr, FAILED);
	flag = 0;
	result = AudioUnitSetProperty(input_unit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, kOutputBus, &flag, sizeof(flag));
	ERR_FAIL_COND_V(result != noErr, FAILED);

	UInt32 size;
#ifdef OSX_ENABLED
	AudioDeviceID deviceId;
	size = sizeof(AudioDeviceID);
	AudioObjectPropertyAddress property = { kAudioHardwarePropertyDefaultInputDevice, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };

	result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &property, 0, NULL, &size, &deviceId);
	ERR_FAIL_COND_V(result != noErr, FAILED);

	result = AudioUnitSetProperty(input_unit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &deviceId, sizeof(AudioDeviceID));
	ERR_FAIL_COND_V(result != noErr, FAILED);
#endif

	AudioStreamBasicDescription strdesc;
	zeromem(&strdesc, sizeof(strdesc));
	size = sizeof(strdesc);
	result = AudioUnitGetProperty(input_unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, kInputBus, &strdesc, &size);
	ERR_FAIL_COND_V(result != noErr, FAILED);

	switch (strdesc.mChannelsPerFrame) {
		case 1: // Mono
			capture_channels = 1;
			break;

		case 2: // Stereo
			capture_channels = 2;
			break;

		default:
			// Unknown number of channels, default to stereo
			capture_channels = 2;
			break;
	}

	mix_rate = GLOBAL_DEF_RST("audio/mix_rate", DEFAULT_MIX_RATE);

	zeromem(&strdesc, sizeof(strdesc));
	strdesc.mFormatID = kAudioFormatLinearPCM;
	strdesc.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
	strdesc.mChannelsPerFrame = capture_channels;
	strdesc.mSampleRate = mix_rate;
	strdesc.mFramesPerPacket = 1;
	strdesc.mBitsPerChannel = 16;
	strdesc.mBytesPerFrame = strdesc.mBitsPerChannel * strdesc.mChannelsPerFrame / 8;
	strdesc.mBytesPerPacket = strdesc.mBytesPerFrame * strdesc.mFramesPerPacket;

	result = AudioUnitSetProperty(input_unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, kInputBus, &strdesc, sizeof(strdesc));
	ERR_FAIL_COND_V(result != noErr, FAILED);

	AURenderCallbackStruct callback;
	zeromem(&callback, sizeof(AURenderCallbackStruct));
	callback.inputProc = &AudioDriverCoreAudio::input_callback;
	callback.inputProcRefCon = this;
	result = AudioUnitSetProperty(input_unit, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, kInputBus, &callback, sizeof(callback));
	ERR_FAIL_COND_V(result != noErr, FAILED);

	result = AudioUnitInitialize(input_unit);
	ERR_FAIL_COND_V(result != noErr, FAILED);

	return OK;
}