static int tdav_consumer_audiounit_start(tmedia_consumer_t* self)
{
	tdav_consumer_audiounit_t* consumer = (tdav_consumer_audiounit_t*)self;
	
    if(!consumer){
		TSK_DEBUG_ERROR("Invalid parameter");
		return -1;
	}
	if(consumer->paused){
		consumer->paused = tsk_false;
	}
	if(consumer->started){
		TSK_DEBUG_WARN("Already started");
		return 0;
	}
	else {
		int ret = tdav_audiounit_handle_start(consumer->audioUnitHandle);
		if(ret){
			TSK_DEBUG_ERROR("tdav_audiounit_handle_start failed with error code=%d", ret);
			return ret;
		}
	}
	consumer->started = tsk_true;
	TSK_DEBUG_INFO("AudioUnit consumer started");
	return 0;
}
static int tdav_producer_audiounit_start(tmedia_producer_t* self)
{
	tdav_producer_audiounit_t* producer = (tdav_producer_audiounit_t*)self;
	
    if(!producer){
		TSK_DEBUG_ERROR("Invalid parameter");
		return -1;
	}
	if(producer->paused){
		producer->paused = tsk_false;
		return tsk_false;
	}
	
	int ret;
	if(producer->started){
		TSK_DEBUG_WARN("Already started");
		return 0;
	}
	else {
		ret = tdav_audiounit_handle_start(producer->audioUnitHandle);
		if(ret){
			TSK_DEBUG_ERROR("tdav_audiounit_handle_start failed with error code=%d", ret);
			return ret;
		}
	}
	producer->started = tsk_true;
    
    // apply parameters (because could be lost when the producer is restarted -handle recreated-)
    ret = tdav_audiounit_handle_mute(producer->audioUnitHandle, producer->muted);

	TSK_DEBUG_INFO("AudioUnit producer started");
	return 0;
}
static int tdav_producer_audiounit_start(tmedia_producer_t* self)
{
	tdav_producer_audiounit_t* producer = (tdav_producer_audiounit_t*)self;
	
    if(!producer){
		TSK_DEBUG_ERROR("Invalid parameter");
		return -1;
	}
	if(producer->paused){
		producer->paused = tsk_false;
		return tsk_false;
	}
	
	int ret;
	if(producer->started){
		TSK_DEBUG_WARN("Already started");
		return 0;
	}
	else {
		ret = tdav_audiounit_handle_start(producer->audioUnitHandle);
		if(ret){
			TSK_DEBUG_ERROR("tdav_audiounit_handle_start failed with error code=%d", ret);
			return ret;
		}
	}
	producer->started = tsk_true;
	
	// create conditional variable
    if (!producer->senderCondWait) {
        if (!(producer->senderCondWait = tsk_condwait_create())){
            TSK_DEBUG_ERROR("Failed to create conditional variable");
            return -2;
        }
    }
	// start the reader thread
	ret = tsk_thread_create(&producer->senderThreadId[0], __sender_thread, producer);
	if(ret){
		TSK_DEBUG_ERROR("Failed to start the sender thread. error code=%d", ret);
		return ret;
	}

	TSK_DEBUG_INFO("AudioUnit producer started");
	return 0;
}
static int tdav_consumer_audiounit_start(tmedia_consumer_t* self)
{
    tdav_consumer_audiounit_t* consumer = (tdav_consumer_audiounit_t*)self;

    if(!consumer) {
        TSK_DEBUG_ERROR("Invalid parameter");
        return -1;
    }
    if (consumer->paused) {
        consumer->paused = tsk_false;
    }
    if (consumer->started) {
        TSK_DEBUG_WARN("Already started");
        return 0;
    }
    else {
        int ret;
        // Initialize the consumer if not already done
        if (!consumer->ready) {
            ret = tdav_consumer_audiounit_init(self);
            if (ret) {
                tdav_consumer_audiounit_deinit(self);
                TSK_DEBUG_ERROR("tdav_consumer_audiounit_init failed with error code=%d", ret);
                return ret;
            }
        }
        // Start the handle (will wait until producer is ready)
        ret = tdav_audiounit_handle_start(consumer->audioUnitHandle);
        if (ret) {
            tdav_consumer_audiounit_deinit(self);
            TSK_DEBUG_ERROR("tdav_audiounit_handle_start failed with error code=%d", ret);
            return ret;
        }
    }
    consumer->started = tsk_true;
    TSK_DEBUG_INFO("AudioUnit consumer started");
    return 0;
}