Example #1
0
/****************************************************************************
NAME    
    audioSwapMediaChannel
    
DESCRIPTION
    attempt to swap between media channels if two channels exist and one of them
    is currentyl being routed to the speaker.
RETURNS
    successful or not status
*/
bool audioSwapMediaChannel(void)
{
    Sink a2dpSinkPri, a2dpSinkSec; 
    a2dp_stream_state a2dpStatePri, a2dpStateSec;

    /* get the status of the a2dp links */
    getA2dpStreamData(a2dp_primary,   &a2dpSinkPri, &a2dpStatePri);
    getA2dpStreamData(a2dp_secondary, &a2dpSinkSec, &a2dpStateSec);
    
    /* check whether a2dp pri is currently being routed and a2dp sec is available */
    if((theSink.routed_audio == a2dpSinkPri)&&(a2dpSinkSec)&&(a2dpStateSec == a2dp_stream_streaming))
    {
        /* swap to a2dp secondary */
        AudioDisconnect();   
        A2dpRouteAudio(a2dp_secondary, a2dpSinkSec);
        return TRUE;
    }
    /* check whether a2dp sec is currently being routed and swap to a2dp pri */
    else if((theSink.routed_audio == a2dpSinkSec)&&(a2dpSinkPri)&&(a2dpStatePri == a2dp_stream_streaming))
    {
        AudioDisconnect();   
        A2dpRouteAudio(a2dp_primary, a2dpSinkPri);       
        return TRUE;    
    }
    /* not possible to swap media channels */
    return FALSE;
}
Example #2
0
/****************************************************************************
NAME    
    sinkCheckPartyModeAudio
    
DESCRIPTION
    Called when checking for PartyMode being enabled, if not enabled no action is
    taken, when enabled decisions are made as to what audio should be playing or
    paused/resumed etc
    
RETURNS
    bool false if party mode not enabled, true is party mode enabled and action has
    been taken with regards to the routing of the audio source
*/
bool sinkCheckPartyModeAudio(audio_sources requested_source, audio_source_status * lAudioStatus)
{
    uint8 index;
    
    /* check whether party mode is enabled and configured and if the currently routed audio is one of the a2dp streams */
    if((theSink.PartyModeEnabled)&&(theSink.features.PartyMode)&&(lAudioStatus->audio_routed)&&
       ((lAudioStatus->a2dpSinkPri == lAudioStatus->audio_routed)||(lAudioStatus->a2dpSinkSec == lAudioStatus->audio_routed))
      )
    {
        /* determine the PartyMode operating mode required */     
        switch(theSink.features.PartyMode)
        {
            /* simple barge-in mode of operation, a new audio source streaming music
               disconnects any currently streaming device */
            case partymode_barge_in:
                PTY_DEBUG(("PTY: bargein\n"));

                /* if the current streaming audio A2DP pri and a stream for A2DP sec is available, switch to that */            
                if((lAudioStatus->a2dpSinkPri == lAudioStatus->audio_routed)&&(lAudioStatus->a2dpStateSec == a2dp_stream_streaming))
                {
                    PTY_DEBUG(("PTY: drop current pri route new sec\n"));

                    /* drop bluetooth connection to device currently streaming */
                    for(index = a2dp_primary; index < (a2dp_secondary+1); index++)
                    {
                        /* is a2dp connected? */
                        if(theSink.a2dp_link_data->connected[index])
                        {
                            /* check whether the a2dp connection is present and streaming data and that the audio is routed */
                            if(lAudioStatus->audio_routed == A2dpMediaGetSink(theSink.a2dp_link_data->device_id[index], theSink.a2dp_link_data->stream_id[index]))
                            {                                   
                                /* disconnect a2dp audio device */
                                sinkPartyModeDisconnectDevice(index);
                            }
                        }
                    }
                    /* route the audio from the new device */
                    A2dpRouteAudio(a2dp_secondary, lAudioStatus->a2dpSinkSec);
                }
                /* if the current streaming audio A2DP sec and a stream for A2DP pri is available, switch to that */            
                else if((lAudioStatus->a2dpSinkSec == lAudioStatus->audio_routed)&&(lAudioStatus->a2dpStatePri == a2dp_stream_streaming))
                {
                    PTY_DEBUG(("PTY: drop current sec route new pri\n"));
                    /* drop bluetooth connection to device currently streaming */
                    for(index = a2dp_primary; index < (a2dp_secondary+1); index++)
                    {
                        /* is a2dp connected? */
                        if(theSink.a2dp_link_data->connected[index])
                        {
                            /* check whether the a2dp connection is present and streaming data and that the audio is routed */
                            if(lAudioStatus->audio_routed == A2dpMediaGetSink(theSink.a2dp_link_data->device_id[index], theSink.a2dp_link_data->stream_id[index]))
                            {                                   
                                /* disconnect a2dp audio device */
                                sinkPartyModeDisconnectDevice(index);
                            }
                        }
                    }
                    /* route the audio from the new device */
                    A2dpRouteAudio(a2dp_primary, lAudioStatus->a2dpSinkPri);
                }
                /* no action has been taken */
                else
                    return TRUE;
            break;
        
            /* more complex use case, a new streaming audio source is paused using avrcp
               until the current playing track completes */
            case partymode_avrcp_control:
                PTY_DEBUG(("PTY: avrcp ctrl AG1[%x] AG2[%x] AVRCP1[%x] AVRCP[%x] \n",lAudioStatus->a2dpStatePri,lAudioStatus->a2dpStateSec,theSink.avrcp_link_data->play_status[a2dp_primary],theSink.avrcp_link_data->play_status[a2dp_secondary]));

                /* if the current streaming audio is A2DP pri and a stream for A2DP sec is available, pause that and wait for the 
                   current track to finish playing */            
                if((lAudioStatus->a2dpSinkPri == lAudioStatus->audio_routed)&&(lAudioStatus->a2dpStatePri == a2dp_stream_streaming)&&
                   ((lAudioStatus->a2dpStateSec == a2dp_stream_streaming)&&
                    (sinkCheckAvrcpStateMatch(a2dp_secondary, avrcp_play_status_playing)))
                   )
                {
                    PTY_DEBUG(("PTY: suspend a2dp sec audio until pri track finished \n"));
                    SuspendA2dpStream(a2dp_secondary);
                    /* set paused flag */
                    theSink.rundata->partymode_pause.audio_source_secondary_paused = TRUE;
                }
                /* if the current streaming audio A2DP sec and a stream for A2DP pri is available, switch to that */            
                else if((lAudioStatus->a2dpSinkSec == lAudioStatus->audio_routed)&&(lAudioStatus->a2dpStateSec == a2dp_stream_streaming)&&
                        ((lAudioStatus->a2dpStatePri == a2dp_stream_streaming)&&
                         (sinkCheckAvrcpStateMatch(a2dp_primary, avrcp_play_status_playing)))
                       )
                {
                    PTY_DEBUG(("PTY: suspend a2dp pri audio until sec track finished \n"));
                    SuspendA2dpStream(a2dp_primary);
                    /* set paused flag */
                    theSink.rundata->partymode_pause.audio_source_primary_paused = TRUE;
                }
                /* check if currently routed primary source is still valid, disconnect if not */
                else if((lAudioStatus->a2dpSinkPri == lAudioStatus->audio_routed)&&(lAudioStatus->a2dpStatePri != a2dp_stream_streaming))
                {
                    /* check if other source is present and paused */
                    a2dp_link_priority link = sinkPartyModeCheckForOtherPausedSource(a2dp_primary);
                    PTY_DEBUG(("PTY: pri source not valid, disconnect\n"));
                    /* disconnect a2dp primary audio */
                    audioDisconnectActiveSink();
                    /* disconnect primary audio device */
                    if(deviceManagerNumConnectedDevs() > 1)
                        sinkPartyModeDisconnectDevice(a2dp_primary);
                    /* check for other paused audio source to route */                    
                    if((link != a2dp_invalid)&&(theSink.rundata->partymode_pause.audio_source_secondary_paused))
                    {
                        PTY_DEBUG(("PTY: resume paused sec\n"));
                        /* resume paused device */
                        ResumeA2dpStream(a2dp_secondary, lAudioStatus->a2dpStateSec, lAudioStatus->a2dpSinkSec);
                    }
                    return TRUE;                
                }
                /* check if currently routed secondary source is still valid, disconnect if not */
                else if((lAudioStatus->a2dpSinkSec == lAudioStatus->audio_routed)&&(lAudioStatus->a2dpStateSec != a2dp_stream_streaming))
                {
                    /* check if other source is present and paused */
                    a2dp_link_priority link = sinkPartyModeCheckForOtherPausedSource(a2dp_secondary);
                    PTY_DEBUG(("PTY: sec source not valid, disconnect\n"));
                    /* disconnect a2dp secondary audio */
                    audioDisconnectActiveSink();
                    /* disconnect secondary audio device */
                    if(deviceManagerNumConnectedDevs() > 1)
                        sinkPartyModeDisconnectDevice(a2dp_secondary);
                    /* check for other paused audio source to route */                    
                    if((link != a2dp_invalid)&&(theSink.rundata->partymode_pause.audio_source_primary_paused))
                    {
                        PTY_DEBUG(("PTY: resume paused pri\n"));
                        /* resume paused device */
                        ResumeA2dpStream(a2dp_primary, lAudioStatus->a2dpStatePri, lAudioStatus->a2dpSinkPri);
                    }
                    return TRUE;                
                }
                /* take no action at this time */
                else
                {
                    PTY_DEBUG(("PTY: avrcp - no action - AR[%x] Pri[%x] Sec[%x]\n",(uint16)lAudioStatus->audio_routed,lAudioStatus->a2dpStatePri,lAudioStatus->a2dpStateSec));
                    return TRUE;
                }
            break;
            
            /* not a valid configuration of operating mode */
            default:
                PTY_DEBUG(("PTY: invalid mode - no action\n"));
                /* default to standard audio routing mode of operation */
                return FALSE;
            break;
                       
        }
        return TRUE;   
    }        
    /* no audio routed or party mode not enabled */
    else
    {
        /* party mode not active or no audio currently routed, take no action and let standard audio routing
           functions take control */
        PTY_DEBUG(("PTY: NOT ACTIVE [%d] or NO AUDIO ROUTED AR[%x] Pri[%x] Sec[%x]\n",(theSink.PartyModeEnabled && theSink.features.PartyMode)
                                                                                     ,(uint16)lAudioStatus->audio_routed
                                                                                     ,(uint16)lAudioStatus->a2dpSinkPri
                                                                                     ,(uint16)lAudioStatus->a2dpSinkSec));
        return FALSE;
    }
}