/****************************************************************************
DESCRIPTION
    Stop prompt where DSP has not been loaded by the plugin, e.g. (adpcm or pcm) 
    Prompt is either mixing in an existing DSP app or not using the DSP.
*/
static void CsrVoicePresencesPluginStopPhraseMixable ( void ) 
{
    Sink lSink=NULL;
    Task taskdata = NULL;
    
    /* Check for DSP mixing */
    if(GetCurrentDspStatus())
    {
        lSink = StreamKalimbaSink(PRESENT_DSP_PORT);
        /* reset the volume levels of the dsp plugin */
        if(GetAudioPlugin())           	    
            MessageSend( GetAudioPlugin(), AUDIO_PLUGIN_RESET_VOLUME_MSG, 0 ) ;
    }
    else    /* Must be ADPCM not mixing */
    {
        switch(koovox_phrase_data->features.audio_output_type)
        {
            /* is the I2S required? */
            case OUTPUT_INTERFACE_TYPE_I2S:
            {               
                CsrI2SAudioOutputDisconnect( koovox_phrase_data->features.stereo);  
            }
            break;
            
            /* spdif output? */
            case OUTPUT_INTERFACE_TYPE_SPDIF:
            {
                Sink rSink = NULL;
                                
                /* obtain source to SPDIF hardware and disconnect it */
                lSink = StreamAudioSink(AUDIO_HARDWARE_SPDIF, AUDIO_INSTANCE_0, SPDIF_CHANNEL_A );
                rSink = StreamAudioSink(AUDIO_HARDWARE_SPDIF, AUDIO_INSTANCE_0, SPDIF_CHANNEL_B );
                StreamDisconnect(0, lSink);
                StreamDisconnect(0, rSink);
                SinkClose(lSink);
                SinkClose(rSink);
            }
            break;
            
            /* use built in codec */
            default:
            {
                lSink = StreamAudioSink(AUDIO_HARDWARE_CODEC,AUDIO_INSTANCE_0, (koovox_phrase_data->features.stereo ? AUDIO_CHANNEL_A_AND_B : AUDIO_CHANNEL_A));
                /* Disconnect PCM source/sink */
                StreamDisconnect(StreamSourceFromSink(lSink), lSink); 
            }
        }
    }    
    /* close sink and cancel any messages if valid */
    if(lSink)
    {
        /* Cancel all the messages relating to VP that have been sent */
        taskdata = MessageSinkTask(lSink, NULL);
        SinkClose(lSink);
    }
    PRINT(("PRESENT: SinkTask now NULL was %x\n",(uint16)taskdata));
    MessageCancelAll((TaskData*) &csr_voice_presences_plugin, MESSAGE_STREAM_DISCONNECT);
}
Example #2
0
/****************************************************************************
NAME    
    audioControlLowPowerCodecs
    
DESCRIPTION
    Enables / disables the low power codecs. 
    will only use low power codecs is the flag UseLowPowerCodecs is set and 
    enable == TRUE
    
    This fn is called whenever an audioConnect occurs in order to select the 
    right codec ouptut stage power .
    
RETURNS
    none
*/
void audioControlLowPowerCodecs(  bool enable  )
{
    audio_channel channel  =  AUDIO_CHANNEL_A ;
    Sink sink   = NULL ;
    
    if ( theSink.features.stereo )
    {
        channel = AUDIO_CHANNEL_A_AND_B;
    }

    /* obtain sink to audio hardware */
    sink = StreamAudioSink(AUDIO_HARDWARE_CODEC, AUDIO_INSTANCE_0, channel);

    /* ensure sink is valid */
    if(sink)
    {
        /* if low power codec use is disabled in features ps or enable is false */
        if ((!theSink.features.UseLowPowerAudioCodecs)||(!enable))
        {
            /*disable low power codecs as feature disabled or enable override is set */
            AUD_DEBUG(("AUD:LowPowerCodecDisable CODEC NORMAL, feature [%c] enable [%c]\n", theSink.features.UseLowPowerAudioCodecs? 'T':'F', enable? 'L':'N')) ;
        
#ifdef BC5_MULTIMEDIA
            /* set to normal mode */
            PanicFalse(SinkConfigure(sink, STREAM_CODEC_LOW_POWER_OUTPUT_STAGE_ENABLE, FALSE ));
#else        
            /* set codec to high quality mode */
            PanicFalse(SinkConfigure(sink, STREAM_CODEC_QUALITY_MODE, CODEC_HIGH_MODE )) ;  
#endif        
        }
        /* if the low power audio codec feature is enabled and the enable is true */
        else
        {
#ifdef BC5_MULTIMEDIA
            /* enable the low power mode */        
            PanicFalse(SinkConfigure(sink, STREAM_CODEC_LOW_POWER_OUTPUT_STAGE_ENABLE, TRUE)) ;
#else        
            /* set the codec type to low power telephony mode */
            PanicFalse(SinkConfigure(sink, STREAM_CODEC_QUALITY_MODE, CODEC_TELEPHONY_MODE )) ;
#endif
            AUD_DEBUG(("AUD:LowPowerCodecEnable CODEC LOW POWER, feature [%c] enable [%c]\n", theSink.features.UseLowPowerAudioCodecs? 'T':'F', enable? 'L':'N')) ;
        }

        /* Close the Source/Sink */
        SinkClose(sink);
    }
}
Example #3
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));
}
/****************************************************************************
NAME
    connectAudioStreams

DESCRIPTION
    Helper function to connect the audio streams
*/
static void connectAudioStreams(void)
{
    /* Connect the appropriate input stream to Kalimba */
    if (plugin_data->input == SUBWOOFER_INPUT_ADC)
    {
        PRINT(("[SW_PLUGIN] : Plugging ADC to Kalimba [%u]\n", plugin_data->adc_sample_rate));
        
        /* Configure the ADC */
        PanicFalse( SourceConfigure(plugin_data->audio_source, STREAM_CODEC_INPUT_RATE, plugin_data->adc_sample_rate) );
        
        /* Plug the ADC sink into the Kalimba */
        PanicFalse( StreamConnect(plugin_data->audio_source, StreamKalimbaSink(DSP_INPUT_PORT_ADC)) );
    }
    else if (plugin_data->input == SUBWOOFER_INPUT_ESCO)
    {
        /* Enable meta-data on the audio input */
        if ( SourceConfigure(plugin_data->audio_source, VM_SOURCE_SCO_METADATA_ENABLE, 1))
        {
            /* Plug the eSCO sink into the Kalimba */
            if ( !StreamConnect(plugin_data->audio_source, StreamKalimbaSink(DSP_INPUT_PORT_ESCO)) )
            {
                PRINT(("[SW_PLUGIN] : Plugging ESCO to Kalimba [FAILED]\n"));
                sendErrorToClient();
                /* Nothing more can be done here */
                return;
            }
            else
            {
                PRINT(("[SW_PLUGIN] : ESCO connected to Kalimba\n"));
            }
        }
        else
        {
            PRINT(("[SW_PLUGIN] : Plugging ESCO to Kalimba [FAILED]\n"));
            sendErrorToClient();
            /* Nothing more can be done here */
            return;
        }
    }
    else if (plugin_data->input == SUBWOOFER_INPUT_L2CAP)
    {
        /* Plug the L2CAP sink into the Kalimba */
        if ( !StreamConnect(plugin_data->audio_source, StreamKalimbaSink(DSP_INPUT_PORT_L2CAP)) )
        {
            PRINT(("[SW_PLUGIN] : Plugging L2CAP to Kalimba [FAILED]\n"));
            sendErrorToClient();
            /* Nothing more can be done here */
            return;
        }
        else
        {
            PRINT(("[SW_PLUGIN] : L2CAP connected to Kalimba\n"));
        }
    }
    else
    {
        PRINT(("[SW_PLUGIN] : Plugin parameter INPUT[%x] is invalid\n", plugin_data->input));
        Panic();
    }
    
    /* Connect Kalimba to the appropriate output stream */
    if (plugin_data->output == SUBWOOFER_OUTPUT_DAC)
    {
        
        
        /* Get the Codec DAC sink & Configure output rate */
        plugin_data->codec_sink = StreamAudioSink(AUDIO_HARDWARE_CODEC, AUDIO_INSTANCE_0, AUDIO_CHANNEL_A_AND_B);
        if ( !SinkConfigure(plugin_data->codec_sink, STREAM_CODEC_OUTPUT_RATE, plugin_data->sample_rate) )
        {
            PRINT(("[SW_PLUGIN] : Could not configure DAC [%u]\n", plugin_data->sample_rate));
            sendErrorToClient();
            /* Nothing more can be done here */
            return;
        }
        
        /* Plug the audio route from Kalimba to the DAC */
        if ( !StreamConnect(StreamKalimbaSource(DSP_OUTPUT_PORT_DAC), plugin_data->codec_sink) )
        {
            PRINT(("[SW_PLUGIN] : Could not connect DAC to Kalimba[%u]\n", plugin_data->sample_rate));
            sendErrorToClient();
            /* Nothing more can be done here */
            return;
        }
        
        PRINT(("[SW_PLUGIN] : Kalimba connected to DAC\n"));
    }
    else if (plugin_data->output == SUBWOOFER_OUTPUT_I2S)
    {
        PRINT(("[SW_PLUGIN] : Plugging Kalimba to I2S [%u]\n", plugin_data->sample_rate));
        
        /* Is a specified output frequency required? use resampling */
        if(CsrI2SMusicResamplingFrequency())
        {
            CsrI2SAudioOutputConnect(CsrI2SMusicResamplingFrequency(), FALSE, StreamKalimbaSource(DSP_OUTPUT_PORT_I2S), NULL);
        }
        else
        {
            CsrI2SAudioOutputConnect(plugin_data->sample_rate, FALSE, StreamKalimbaSource(DSP_OUTPUT_PORT_I2S), NULL);
        }
    }
    else
    {
        PRINT(("[SW_PLUGIN] : Plugin parameter OUTPUT[%x] is invalid\n", plugin_data->output));
        Panic();
    }
    
    /* set dsp operating flags */
    SetCurrentDspStatus(DSP_RUNNING);
    SetAudioInUse(TRUE);
}
/****************************************************************************
DESCRIPTION
    This function connects APTX low delay audio 
****************************************************************************/
void MusicConnectAptxLowLatency(A2dpPluginConnectParams *codecData, uint8 content_protection)
{
    Sink speaker_snk_a = NULL;
    Transform rtp_transform = 0;
    DECODER_t * DECODER = CsrA2dpDecoderGetDecoderData();
    
    /* when configured for using back channel low latency apps */
    if(isCodecLowLatencyBackChannel())
    {
        /* if the back channel is required and the mic/line input is configured */
        if (codecData->voice_rate)
        {
            /* Bidirectional channel uses faststream mono with the following settings */
            /*
               Configure the SBC format for the microphone data
               16kHz, Mono, Blocks 16, Sub-bands 8, Loudness, Bitpool = 32
               (data rate = 72kbps, packet size = 3*72 + 4 = 220 <= DM5).
            */
           codecData->format     = 0x31;
           codecData->bitpool    = 32;
           PRINT(("DECODER: apt-X Low Latency Bidirectional rate=0x%lx voice_rate=0x%lx\n format=0x%x\n",DECODER->rate,codecData->voice_rate,codecData->format));
        }
    }

    /* ensure the sample rate is valid */
    if (DECODER->rate)
    {
        /* disconnect media sink as it might be disposed */
        StreamDisconnect(StreamSourceFromSink(DECODER->media_sink), 0);

                /* determine the output hardware type */
        switch(DECODER->features.audio_output_type)
        {
            /* using the inbuilt dacs */
            case OUTPUT_INTERFACE_TYPE_NONE:
            case OUTPUT_INTERFACE_TYPE_DAC:
            {
                /* configure built-in audio hardware channel A */
                speaker_snk_a = StreamAudioSink(AUDIO_HARDWARE_CODEC, AUDIO_INSTANCE_0, AUDIO_CHANNEL_A);
                PanicFalse(SinkConfigure(speaker_snk_a, STREAM_CODEC_OUTPUT_RATE, DECODER->rate));
    
                /* if STEREO mode configured then connect the output channel B */
                if(DECODER->features.stereo)
                {
                    Sink speaker_snk_b = NULL;
        
                    PRINT(("DECODER: Stereo\n"));
        
                    /* connect channels B */
                    speaker_snk_b = StreamAudioSink(AUDIO_HARDWARE_CODEC, AUDIO_INSTANCE_0, AUDIO_CHANNEL_B);
                    /* configure channel to required rate */
                    PanicFalse(SinkConfigure(speaker_snk_b, STREAM_CODEC_OUTPUT_RATE, DECODER->rate));
                    /* synchronise both sinks for channels A & B */
                    PanicFalse(SinkSynchronise(speaker_snk_a, speaker_snk_b));
                    /* plug port 1 into Right DAC */
                    PanicFalse(StreamConnect(StreamKalimbaSource(AUDIO_OUT_FROM_DSP_LEFT),speaker_snk_a));
                    PanicFalse(StreamConnect(StreamKalimbaSource(AUDIO_OUT_FROM_DSP_RIGHT),speaker_snk_b));
                }
                /* mono operation, only connect left port */
                else
                {
                    /* plug port 0 into Left DAC */
                    PanicFalse(StreamConnect(StreamKalimbaSource(AUDIO_OUT_FROM_DSP_LEFT),speaker_snk_a));
                }
            }
            break;

            /* using the spdif digital output hardware */
            case OUTPUT_INTERFACE_TYPE_SPDIF:
            {
                Sink speaker_snk_b = NULL;
                /* configure spdif audio hardware channel 0 */
                speaker_snk_a = StreamAudioSink(AUDIO_HARDWARE_SPDIF, AUDIO_INSTANCE_0, SPDIF_CHANNEL_A);
                speaker_snk_b = StreamAudioSink(AUDIO_HARDWARE_SPDIF, AUDIO_INSTANCE_0, SPDIF_CHANNEL_B);
                /* configure channel to required rate */
                PanicFalse(SinkConfigure(speaker_snk_a,  STREAM_SPDIF_OUTPUT_RATE, DECODER->rate));
                PanicFalse(SinkConfigure(speaker_snk_b,  STREAM_SPDIF_OUTPUT_RATE, DECODER->rate));
                /* connect channels B */
                /* synchronise both sinks for channels A & B */
                PanicFalse(SinkSynchronise(speaker_snk_a, speaker_snk_b));
                /* plug port 1 into Right DAC */
                PanicFalse(StreamConnect(StreamKalimbaSource(AUDIO_OUT_FROM_DSP_LEFT),speaker_snk_a));
                PanicFalse(StreamConnect(StreamKalimbaSource(AUDIO_OUT_FROM_DSP_RIGHT),speaker_snk_b));   
      
                PRINT(("DECODER: Stereo\n"));
            }
            break;
            
            /* using the i2s digital output hardware */
            case OUTPUT_INTERFACE_TYPE_I2S:
            {
                /* is a specified output frequency required? use resampling*/
                if(CsrI2SMusicResamplingFrequency())
                    CsrI2SAudioOutputConnect(CsrI2SMusicResamplingFrequency(), DECODER->features.stereo, StreamKalimbaSource(AUDIO_OUT_FROM_DSP_LEFT), StreamKalimbaSource(AUDIO_OUT_FROM_DSP_RIGHT));                                 
                /* use the negotiated sample rate of the input, no resampling required */                
                else
                    CsrI2SAudioOutputConnect(DECODER->rate, DECODER->features.stereo, StreamKalimbaSource(AUDIO_OUT_FROM_DSP_LEFT), StreamKalimbaSource(AUDIO_OUT_FROM_DSP_RIGHT));                                                                
            }            
            break;
        }
    
        /* if content protection is required feed the media sink through the rtp decoder transform */
        if (content_protection)
        {
            rtp_transform = TransformRtpDecode(StreamSourceFromSink(DECODER->media_sink) , StreamKalimbaSink(LOW_LATENCY_CODEC_TO_DSP_PORT));
            TransformConfigure(rtp_transform, VM_TRANSFORM_RTP_SCMS_ENABLE, content_protection);
            /*start the transform decode*/
            PRINT(("aptX: RTP Transform \n"));
            (void)TransformStart( rtp_transform ) ;
        }
        /* connect the media sink to the dsp input port */
        else
        {
            PanicFalse(StreamConnect(StreamSourceFromSink(DECODER->media_sink),StreamKalimbaSink(LOW_LATENCY_CODEC_TO_DSP_PORT)));
        }
    }
    
    /* Send parameters that configure the SRA and buffer settings */
    PRINT(("aptX LL params: initial level=%d target level=%d sra max rate=%d/10000 sra avg time=%d good working buffer level=%d \n",
           codecData->aptx_sprint_params.target_codec_level,codecData->aptx_sprint_params.initial_codec_level,
           codecData->aptx_sprint_params.sra_max_rate,codecData->aptx_sprint_params.sra_avg_time,
           codecData->aptx_sprint_params.good_working_level));
    KalimbaSendMessage(MESSAGE_SET_APTX_LL_PARAMS1, codecData->aptx_sprint_params.target_codec_level,
                       codecData->aptx_sprint_params.initial_codec_level,
                       codecData->aptx_sprint_params.sra_max_rate,   /* Third field is scaled by 10000 */
                       codecData->aptx_sprint_params.sra_avg_time);
    KalimbaSendMessage(MESSAGE_SET_APTX_LL_PARAMS2, codecData->aptx_sprint_params.good_working_level,
                       0, 0, 0);

    /* update the current audio state */
    SetAudioInUse(TRUE);
}