/****************************************************************************
DESCRIPTION
	handles the internal cvc messages /  messages from the dsp
*/
void CsrA2dpDecoderPluginInternalMessage( A2dpPluginTaskdata *task ,uint16 id , Message message )
{
	switch(id)
	{
        case MESSAGE_FROM_KALIMBA:
		{
			const DSP_REGISTER_T *m = (const DSP_REGISTER_T *) message;
	        PRINT(("DECODER: msg id[%x] a[%x] b[%x] c[%x] d[%x]\n", m->id, m->a, m->b, m->c, m->d));

            switch ( m->id )
			{
              case MUSIC_READY_MSG:
                {
					if (DECODER)
					{
                    	KalimbaSendMessage(MUSIC_LOADPARAMS_MSG, MUSIC_PS_BASE, 0, 0, 0);

                    	/*A2dp is now loaded, signal that tones etc can be scheduled*/
                    	AUDIO_BUSY = NULL ;

                    	PRINT(("DECODER: DECODER_READY \n"));

                     CsrA2dpDecoderPluginSetMode(DECODER->mode, task, 0);

                    	MusicConnectAudio (task, DECODER->stereo);
					}
                }
                break;
			    case MUSIC_CODEC_MSG:
	            {
                    uint16 lOutput_gain_l = m->a;
                    uint16 lOutput_gain_r = m->b;

					if (DECODER)
					{
                    	CodecSetOutputGainNow(DECODER->codec_task, lOutput_gain_l, left_ch);
                    	CodecSetOutputGainNow(DECODER->codec_task, lOutput_gain_r, right_ch);
					}
	            }
                break;
				case KALIMBA_MSG_SOURCE_CLOCK_MISMATCH_RATE:
				{
					MAKE_AUDIO_MESSAGE(AUDIO_PLUGIN_DSP_MSG);
					message->id = KALIMBA_MSG_SOURCE_CLOCK_MISMATCH_RATE;
					message->value = m->a;
					MessageSend(DECODER->app_task, AUDIO_PLUGIN_DSP_MSG, message);
					break;
				}
            }
		}
		break;

        default:
        break ;
	}
}
Пример #2
0
void CsrSubwooferPluginConnect(Sink audio_sink, Task codec_task, Task app_task, subwooferPluginConnectParams * params)
{
    FILE_INDEX index;
    
    /* Update the current DSP status */
    SetCurrentDspStatus(DSP_LOADING);
    
    /* Give Kalimba the plugin task so it knows where to send messages */
    (void) MessageCancelAll( (TaskData*)&csr_subwoofer_plugin, MESSAGE_FROM_KALIMBA);
    MessageKalimbaTask( (TaskData*)&csr_subwoofer_plugin );
    
    /* Load the Subwofoer DSP application - Panic if it could not be loaded */
    index = PanicFalse( FileFind(FILE_ROOT, kal, sizeof(kal) - 1) );
    PanicFalse( KalimbaLoad(index) );
    
    /* update current DSP status */
    SetCurrentDspStatus(DSP_LOADED_IDLE);
    
    /* Allocate memory to store the plugin data */
    plugin_data = (subwooferPluginData*)PanicUnlessMalloc(sizeof(subwooferPluginData));
    
    /* Initialise the plugin data based on parameters supplied by the application */
    plugin_data->audio_source           = StreamSourceFromSink(audio_sink);
    plugin_data->swat_system_volume_db  = params->swat_system_volume_db;
    plugin_data->swat_trim_gain_db      = params->swat_trim_gain_db;
    plugin_data->adc_volume_index       = params->adc_volume;
    plugin_data->input                  = params->input;
    plugin_data->output                 = params->output;
    plugin_data->sample_rate            = params->sample_rate;
    plugin_data->adc_sample_rate        = params->adc_sample_rate;
    plugin_data->codec_task             = codec_task;
    plugin_data->app_task               = app_task;
    plugin_data->dsp_set_sample_rate    = 0; /* set later in response to AUDIO_PLUGIN_SET_MODE_MSG */
    
    /* Zero the codecs output gain */
    CodecSetOutputGainNow(plugin_data->codec_task, 0, left_and_right_ch);
    CodecSetInputGainNow(plugin_data->codec_task, 0, left_and_right_ch);
    
    
    /* If using the ADC, set the ADC source */
    if (plugin_data->input == SUBWOOFER_INPUT_ADC)
    {
        /* Get the ADC source */
        plugin_data->audio_source = StreamAudioSource(AUDIO_HARDWARE_CODEC, AUDIO_INSTANCE_0, AUDIO_CHANNEL_A);
    }
    
    
    /* Disconnect the source in case it's currently being disposed */
    StreamDisconnect(StreamSourceFromSink(audio_sink), 0);
    
    PRINT(("[SW_PLUGIN] : CsrSubwooferPluginConnect - complete\n"));
}
Пример #3
0
void handleInternalPluginMessage(Task task, MessageId id, Message message)
{
    switch(id)
    {
        case MESSAGE_FROM_KALIMBA:
        {
            const DSP_REGISTER_T *msg = (const DSP_REGISTER_T *)message;
            
            /* Handle the message sent from Kalimba */
            switch(msg->id)
            {
                case MUSIC_READY_MSG:
                {
                    PRINT(("[SW_PLUGIN] : MUSIC_READY_MSG a[%x] b[%x] c[%x] d[%x]\n", msg->a, msg->b, msg->c, msg->d));
                    if (plugin_data)
                    {
                        /* Send parameters PSKEY to DSP */
                        KalimbaSendMessage(MUSIC_LOADPARAMS_MSG, MUSIC_PS_BASE, 0, 0, 0);
                    }
                    else
                    {
                        SetCurrentDspStatus(DSP_ERROR);
                    }
                }
                break;
                case MUSIC_PARAMS_LOADED_MSG:
                {
                    /* Send a message to the app to inform the number of subwoofer volume gains (for ADC mode) */
                    AUDIO_PLUGIN_DSP_IND_T * message = PanicUnlessNew(AUDIO_PLUGIN_DSP_IND_T);
                    message->id = SUB_PLUGIN_NUM_VOL_GAINS;
                    message->size_value = 1;
                    message->value[0] = msg->a;
                    MessageSend(plugin_data->app_task, AUDIO_PLUGIN_DSP_IND, message);
                    
                    PRINT(("[SW_PLUGIN] : MUSIC_PARAMS_LOADED_MSG a[%x] b[%x] c[%x] d[%x]\n", msg->a, msg->b, msg->c, msg->d));
                    
                    /* Connect input and output streams */
                    connectAudioStreams();
                    
                    /* Send Volume to DSP */
                    KalimbaSendMessage(MUSIC_VOLUME_MSG, plugin_data->swat_system_volume_db, plugin_data->swat_trim_gain_db, 0, plugin_data->adc_volume_index);
                    
                    /* Set the DSP status */
                    SetCurrentDspStatus(DSP_RUNNING);
                    
                    /* Send GO to DSP */
                    PanicFalse(KalimbaSendMessage(KALIMBA_MSG_GO, 0, 0, 0, 0));
                    
                    /* Send a message to the app to inform that the plugin is ready to recieve audio data */
                    MessageSend(plugin_data->app_task, AUDIO_PLUGIN_DSP_READY_FOR_DATA, 0);
                }
                break;
                case MUSIC_CODEC_MSG:
                {
                    PRINT(("[SW_PLUGIN] : MUSIC_CODEC_MSG a[%x] b[%x] c[%x] d[%x]\n", msg->a, msg->b, msg->c, msg->d));
                    
                    /* Parameters for this message :                */
                    /* msg->a BITS[0-3] = input gain                */
                    /* msg->a BIT[15]   = enable/disable mic preamp */
                    /* msg->b = output gain                         */
                    
                    /* Only set the input gain if using the ADC input (ESCO/L2CAP inputs don't use the ADC) */
                    if (plugin_data->input == SUBWOOFER_INPUT_ADC)
                    {
                        PRINT(("[SW PLUGIN] : Set ADC input GAIN[%x] Pre-amp enable[%x]\n", (msg->a & 0x1F), (msg->a>>15) & 0x1));
                        AudioPluginSetMicGain(plugin_data->audio_source, FALSE, (msg->a & 0x1F), (msg->a>>15) & 0x1);
                    }
                    
                    PRINT(("[SW PLUGIN] : Set DAC GAIN[%x]\n", msg->b));

                    /* Set the codec output gain according to what the DSP sent */
                    if (plugin_data->output == SUBWOOFER_OUTPUT_I2S)
                    {
                        CsrI2SAudioOutputSetVolume(FALSE, msg->b, msg->b, FALSE);
                    }
                    else
                    {
                        CodecSetOutputGainNow(plugin_data->codec_task, msg->b, left_and_right_ch);
                    }
                }
                break;
                case MUSIC_CUR_EQ_BANK:
                {
                    PRINT(("[SW_PLUGIN] : MUSIC_CUR_EQ_BANK a[%x] b[%x] c[%x] d[%x]\n", msg->a, msg->b, msg->c, msg->d));
                    
                    /* TODO */
                }
                break;
                case MUSIC_SIGNAL_DETECT_STATUS:
                {
                    /* msg->a = 1 if playing audio, 0 if audio is silent */
                    PRINT(("[SW_PLUGIN] : MUSIC_SIGNAL_DETECT_STATUS a[%x]\n", msg->a));
                    
                    if (msg->a)
                    {
                        /* Audio on wired input has been detected - Inform client task */
                        AUDIO_PLUGIN_DSP_IND_T * message = PanicUnlessNew(AUDIO_PLUGIN_DSP_IND_T);
                        message->id = SUB_PLUGIN_ADC_SIGNAL_ACTIVE;
                        message->size_value = 1;
                        message->value[0] = 0;
                        MessageSend(plugin_data->app_task, AUDIO_PLUGIN_DSP_IND, message);
                    }
                    else
                    {
                        /* Audio on wired input is now silent - Inform client task */
                        AUDIO_PLUGIN_DSP_IND_T * message = PanicUnlessNew(AUDIO_PLUGIN_DSP_IND_T);
                        message->id = SUB_PLUGIN_ADC_SIGNAL_IDLE;
                        message->size_value = 1;
                        message->value[0] = 0;
                        MessageSend(plugin_data->app_task, AUDIO_PLUGIN_DSP_IND, message);
                    }
                 }
                break;
                default:
                {
                    PRINT(("[SW_PLUGIN] : Unhandled message from Kalimba ID[%x]\n", msg->id));
                }
                break;
            }
        }
        break;
        default:
        {
            PRINT(("[SW_PLUGIN] : Unhandled internal message ID[%x]\n", id));
        }
        break;
    }
/****************************************************************************
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"));
}