Example #1
0
void A2dpStartKalimbaStreaming(const A2DP *a2dp, uint16 media_sink)
{
    FILE_INDEX index = FILE_NONE;

#ifdef BUILD_FOR_23FW
    Transform t;    
#else    
    Transform t, l_t, r_t;
    
    Source l_src = StreamAudioSource(AUDIO_HARDWARE_CODEC, AUDIO_INSTANCE_0, AUDIO_CHANNEL_A);
    Source r_src = StreamAudioSource(AUDIO_HARDWARE_CODEC, AUDIO_INSTANCE_1, AUDIO_CHANNEL_B);
    Sink   l_snk = StreamAudioSink(AUDIO_HARDWARE_CODEC, AUDIO_INSTANCE_0, AUDIO_CHANNEL_A);
    Sink   r_snk = StreamAudioSink(AUDIO_HARDWARE_CODEC, AUDIO_INSTANCE_1, AUDIO_CHANNEL_B);
#endif
    
    /* load SBC codec */
    index = FileFind(FILE_ROOT, sbc_encoder, sizeof(sbc_encoder)-1);
    if (!KalimbaLoad(index))
        /* codec load failure, Panic as the test isn't going to work now */
        Panic();

    /* Init and configure RTP */
    t = TransformRtpSbcEncode(StreamKalimbaSource(0), (Sink)media_sink);
    TransformConfigure(t, VM_TRANSFORM_RTP_SBC_ENCODE_PACKET_SIZE, 668);
    TransformConfigure(t, VM_TRANSFORM_RTP_SBC_ENCODE_MANAGE_TIMING, FALSE);
    (void)TransformStart(t);

    /* Configure SBC encoding format */
    (void)PanicFalse(KalimbaSendMessage(KALIMBA_MSG_SBCENC_SET_PARAMS, 0x00bd, 0, 0, 0));
    (void)PanicFalse(KalimbaSendMessage(KALIMBA_MSG_SBCENC_SET_BITPOOL, 0x0030, 0, 0, 0));

#ifdef BUILD_FOR_23FW
    StreamDisconnect(StreamPcmSource(0), StreamPcmSink(0));
    StreamDisconnect(StreamPcmSource(1), StreamPcmSink(1));

    /* set up ADCs */
    (void)PcmClearAllRouting();
    (void)PanicFalse(PcmRateAndRoute(0, PCM_NO_SYNC, 44100, 44100, VM_PCM_INTERNAL_A));
    (void)PanicFalse(PcmRateAndRoute(1, 0, 44100, 44100, VM_PCM_INTERNAL_B));
    (void)PanicFalse(StreamConnect(StreamPcmSource(0),StreamKalimbaSink(0)));
    (void)PanicFalse(StreamConnect(StreamPcmSource(1),StreamKalimbaSink(1)));

#else
    SourceClose(l_src);
    SourceClose(r_src);
    SinkClose(l_snk);
    SinkClose(r_snk);
    
    (void) SourceConfigure(l_src, STREAM_CODEC_INPUT_RATE, 44100);
    (void) SourceConfigure(r_src, STREAM_CODEC_INPUT_RATE, 44100);
    (void) SourceSynchronise(l_src, r_src);
    
    /* set up ADCs */
    l_t = StreamConnect(l_src, StreamKalimbaSink(0));
    r_t = StreamConnect(r_src, StreamKalimbaSink(1));
    (void)TransformStart(l_t);
    (void)TransformStart(r_t);
#endif
    
    /* Start decode */
    (void) PanicFalse(KalimbaSendMessage(KALIMBA_MSG_GO,0,0,0,0));
}
/****************************************************************************
DESCRIPTION
    Plays back a voice prompt once DSP has loaded
*/
static Source csrVoicePresencesGetPrompt(voice_prompt* prompt, koovox_phrase_data_T * pData)
{
    const uint8* rx_array;
    Source lSource = NULL;
    uint16 index;

    char file_name[17];

	PRINT(("***check_the_source***\n"));

    if(!pData)
        return NULL;

    /* Must be a prompt, work out the index of the prompt */
    index = pData->prompt_id;
    
    /* Adjust for language */
    index += (pData->language * present_header.no_prompts_per_lang);

	PRINT(("***check prompt id***\n"));
	
    /* Sanity checking */
    if(index >= present_header.no_prompts || !prompt )
        return NULL;
    
    PRINT(("PRESENT: Play prompt %d of %d\n", index+1, present_header.no_prompts));
    
    /* Get the header file name */
    sprintf(file_name, "headers/%d.idx", index);
    lSource = StreamFileSource(FileFind(FILE_ROOT, file_name, strlen(file_name)));

    /* Check source created successfully */
    if(SourceSize(lSource) < SIZE_PROMPT_DATA)
    {
        /* Finished with header source, close it */
        SourceClose(lSource);
        return NULL;
    }
    
    /* Map in header */
    rx_array = SourceMap(lSource);
    
    /* Pack data into result */
    /*    rx_array[0] not used*/
    /*    rx_array[1] index, not used */
    prompt->stereo        = rx_array[4];
    prompt->size          = ((uint32)rx_array[5] << 24) | ((uint32)rx_array[6] << 16) | ((uint16)rx_array[7] << 8) | (rx_array[8]);
    prompt->decompression = rx_array[9];
    prompt->playback_rate = ((uint16)rx_array[10] << 8) | (rx_array[11]);   
    
    /* The size of the prompt must be limited to 16 bits for I2C and SPI as the firmware traps only support a 16 bit size */
    if (prompt->size > PRESENT_MAX_SIZE)
    {
        prompt->size = PRESENT_MAX_SIZE;
        PRINT(("Prompt size adjusted to 16 bit maximum\n"));
    }
    
    /* Get the prompt file name */
    sprintf(file_name, "prompts/%d.prm", index);
    
    PRINT(("File Prompt: %s dec %X rate 0x%x stereo %u size 0x%lx \n", file_name, prompt->decompression,prompt->playback_rate,prompt->stereo,prompt->size));
    
    /* Finished with header source, close it */
    if(!SourceClose(lSource))
        Panic();
    
    return StreamFileSource(FileFind(FILE_ROOT, file_name, strlen(file_name)));
}
/****************************************************************************
DESCRIPTION
	This function connects a synchronous audio stream to the pcm subsystem
*/ 
void CsrSbcEncoderPluginConnect( Sink audio_sink , Task codec_task , uint16 volume , uint32 rate , bool stereo , AUDIO_MODE_T mode , const void * params ) 
{
	/* DSP Application loading and Transform starting is handled by a call to A2dpAudioCodecEnable
		in the application, so should not be done here. */

    const char sbc_encoder[]        = "sbc_encoder/sbc_encoder.kap";
    FILE_INDEX index  = FILE_NONE;

	typedef struct
	{
		uint8 content_protection;
		uint32 voice_rate;
		unsigned bitpool:8;
		unsigned format:8;
		uint16 packet_size;
        uint16 clock_mismatch;
	} sbc_codec_data_type;

	sbc_codec_data_type *sbc_codecData = (sbc_codec_data_type *) params;

	if (!sbc_codecData)
		Panic();

     index = FileFind(FILE_ROOT, sbc_encoder, sizeof(sbc_encoder)-1); 
    
     if (index == FILE_NONE)
         Panic();
     if (!KalimbaLoad(index))
         Panic();
     if (!KalimbaSendMessage(KALIMBA_CODEC_TYPE_MESSAGE, 0,0,0,0))
         Panic();

     CodecSetInputGainNow(codec_task,volume,left_and_right_ch);

    SBC = (SBC_t*)PanicUnlessMalloc (sizeof (SBC_t) ) ;
    
    SBC->media_sink[0] = audio_sink ;
    SBC->codec_task = codec_task ;
	SBC->packet_size = sbc_codecData->packet_size;
    
    StreamDisconnect(StreamKalimbaSource(2), 0);

	/* Initialise the RTP SBC encoder */
	SBC->t[0] = TransformRtpSbcEncode(StreamKalimbaSource(2), audio_sink);

	/* Configure the RTP transform to generate the selected packet size */
	TransformConfigure(SBC->t[0], VM_TRANSFORM_RTP_SBC_ENCODE_PACKET_SIZE, sbc_codecData->packet_size);

	/* Transform should not manage timings. */
	TransformConfigure(SBC->t[0], VM_TRANSFORM_RTP_SBC_ENCODE_MANAGE_TIMING, FALSE);

	/* Start the transform */
	(void) TransformStart(SBC->t[0]);
    
    PRINT(("Audio Plugin: TransformStart sink:0x%x\n",(uint16)audio_sink));
	
	if (SBC->media_sink[1])
	{
		/* There is a 2nd audio stream so initialise this transform */
        StreamDisconnect(StreamKalimbaSource(3), 0);
		
		/* Initialise the RTP SBC encoder */
		SBC->t[1] = TransformRtpSbcEncode(StreamKalimbaSource(3), SBC->media_sink[1]);

		/* Configure the RTP transform to generate the selected packet size */
		TransformConfigure(SBC->t[1], VM_TRANSFORM_RTP_SBC_ENCODE_PACKET_SIZE, sbc_codecData->packet_size);

		/* Transform should not manage timings. */
		TransformConfigure(SBC->t[1], VM_TRANSFORM_RTP_SBC_ENCODE_MANAGE_TIMING, FALSE);

		/* Start the transform */
		(void) TransformStart(SBC->t[1]);
        
        PRINT(("Audio Plugin: TransformStart sink:0x%x\n",(uint16)SBC->media_sink[1]));
	}

	/* Configure SBC encoding format */
	if (!KalimbaSendMessage(KALIMBA_MSG_SBCENC_SET_PARAMS, sbc_codecData->format, 0, 0, 0))
		/* If message fails to get through, abort */
		Panic();

	/* Pass bit pool value to DSP */
	if (!KalimbaSendMessage(KALIMBA_MSG_SBCENC_SET_BITPOOL, sbc_codecData->bitpool, 0, 0, 0))
		/* If message fails to get through, abort */
		Panic();

	/* disard any data sent by the SNK */
    StreamConnectDispose(StreamSourceFromSink(audio_sink));
	
	if (SBC->media_sink[1])
	{
		/* disard any data sent by the 2nd SNK */
	    StreamConnectDispose(StreamSourceFromSink(SBC->media_sink[1]));
	}
	
	/* select the source type */
	{
		PRINT(("Audio Plugin: SourceAnalog\n"));
		/* For analogue input source */
		StreamDisconnect(StreamPcmSource(0), StreamPcmSink(0));
		StreamDisconnect(StreamPcmSource(1), StreamPcmSink(1));
        
		(void)PcmClearAllRouting();

		{
			PRINT(("Audio Plugin: codec_internal\n"));
			/* configure slot 0 and 1 to be left and right channel
			and synchronise the offsets for stereo playback */
			(void)PcmRateAndRoute(0, PCM_NO_SYNC, (uint32) rate, (uint32) rate, VM_PCM_INTERNAL_A);
			(void)PcmRateAndRoute(1, 0, (uint32) rate, (uint32) rate, VM_PCM_INTERNAL_B);
		}
		        
		/* plug Left ADC into port 0 */
		(void)StreamConnect(StreamPcmSource(0),StreamKalimbaSink(0)); 

		/* plug Right ADC into port 1 */
		(void)StreamConnect(StreamPcmSource(1),StreamKalimbaSink(1)); 
		
		/* Select the source type */
		PanicFalse(KalimbaSendMessage(KALIMBA_ENCODER_SELECT, 0x0002, 0, 0, 0)); 
		
		if(!KalimbaSendMessage(KALIMBA_MSG_GO,0,0,0,0))
		{
			PRINT(("SBC: Message KALIMBA_MSG_GO failed!\n"));
			Panic();
		}
	}

	/* Select the source type */
	/*PanicFalse(KalimbaSendMessage(KALIMBA_SOURCE_SELECT, SOURCE_USB, 0, 0, 0)); */
	
    /*CsrSbcEncoderUsbPluginSetVolume(volume) ;*/
	
	/*(void) StreamConnect(PanicNull(StreamUsbEndPointSource(end_point_iso_in)), StreamKalimbaSink(0));
    */
	/* Start decode */
   /* if(!KalimbaSendMessage(KALIMBA_MSG_GO,0,0,0,0))
	{
		PRINT(("SBC: Message KALIMBA_MSG_GO failed!\n"));
		Panic();
	}
	*/
}
/****************************************************************************
DESCRIPTION
	This function connects a synchronous audio stream to the pcm subsystem
*/
void CsrA2dpDecoderPluginConnect( A2dpPluginTaskdata *task, Sink audio_sink , Task codec_task , uint16 volume , uint32 rate , bool stereo , AUDIO_MODE_T mode , const void * params , Task app_task )
{
	FILE_INDEX index = FILE_NONE;
	char* kap_file = NULL ;

	/* Only need to read the PS Key value once */
    if (!pskey_read)
    {
        if (PsFullRetrieve(PSKEY_MAX_CLOCK_MISMATCH, &val_pskey_max_mismatch, sizeof(uint16)) == 0)
            val_pskey_max_mismatch = 0;
        pskey_read = TRUE;
    }

    switch ((A2DP_DECODER_PLUGIN_TYPE_T)task->a2dp_plugin_variant)
	{
	case SBC_DECODER:
		kap_file = "sbc_decoder/sbc_decoder.kap";
      break;
	case MP3_DECODER:
		kap_file = "mp3_decoder/mp3_decoder.kap";
		break;
	case AAC_DECODER:
		kap_file = "aac_decoder/aac_decoder.kap";
		break;
	case FASTSTREAM_SINK:
		kap_file = "faststream_sink/faststream_sink.kap";
		break;
	default:
		Panic();
		break;
	}


   /*ensure that the messages received are from the correct kap file*/
   (void) MessageCancelAll( (TaskData*) task, MESSAGE_FROM_KALIMBA);
   MessageKalimbaTask( (TaskData*) task );


	index = FileFind(FILE_ROOT,(const char *) kap_file ,strlen(kap_file));

	if (index == FILE_NONE)
		Panic();
	if (!KalimbaLoad(index))
		Panic();

    DECODER = (DECODER_t*)PanicUnlessMalloc (sizeof (DECODER_t) ) ;

    DECODER->media_sink = audio_sink ;
    DECODER->codec_task = codec_task ;
    DECODER->volume     = volume;
    DECODER->mode       = mode;
    DECODER->stereo     = stereo;
    DECODER->params     = (uint16) params;
    DECODER->rate       = rate;
    DECODER->app_task	= app_task;

	if ((A2DP_DECODER_PLUGIN_TYPE_T)task->a2dp_plugin_variant == AAC_DECODER)
	{
		/* Workaround for AAC+ sources that negotiate sampling frequency at half the actual value */
		if (rate < 32000)
			DECODER->rate = rate * 2;
	}

   CodecSetOutputGainNow(DECODER->codec_task, 0, left_and_right_ch);

   StreamDisconnect(StreamPcmSource(0), StreamPcmSink(0));
   StreamDisconnect(StreamPcmSource(1), StreamPcmSink(1));

   PanicFalse(PcmClearRouting(0));
   PanicFalse(PcmClearRouting(1));

   /* For sinks disconnect the source in case its currently being disposed. */
   StreamDisconnect(StreamSourceFromSink(audio_sink), 0);

	PRINT(("DECODER: CsrA2dpDecoderPluginConnect completed\n"));
}