Ignore:
Timestamp:
Jun 14, 2008 7:42:37 PM (16 years ago)
Author:
bennylp
Message:

Added ringback/alert tones in pjsua

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjsip-apps/src/pjsua/pjsua_app.c

    r2018 r2021  
    2525//#define STEREO_DEMO 
    2626 
     27/* Ringtones */ 
     28#define RINGBACK_FREQ1  440 
     29#define RINGBACK_FREQ2  480 
     30#define RINGBACK_ON     2000 
     31#define RINGBACK_OFF    4000 
     32 
     33#define RING_FREQ1      500 
     34#define RING_FREQ2      660 
     35#define RING_ON         100 
     36#define RING_OFF        100 
     37#define RING_INTERVAL   4000 
     38 
     39 
    2740/* Call specific data */ 
    2841struct call_data 
    2942{ 
    3043    pj_timer_entry          timer; 
     44    pj_bool_t               ringback_on; 
     45    pj_bool_t               ring_on; 
    3146}; 
    3247 
     
    87102    int                     capture_dev, playback_dev; 
    88103    unsigned                capture_lat, playback_lat; 
     104 
     105    pj_bool_t               no_tones; 
     106    int                     ringback_slot; 
     107    int                     ringback_cnt; 
     108    pjmedia_port           *ringback_port; 
     109    int                     ring_slot; 
     110    int                     ring_cnt; 
     111    pjmedia_port           *ring_port; 
     112 
    89113} app_config; 
    90114 
     
    105129#endif 
    106130pj_status_t app_destroy(void); 
     131 
     132static void ringback_start(pjsua_call_id call_id); 
     133static void ring_start(pjsua_call_id call_id); 
     134static void ring_stop(pjsua_call_id call_id); 
     135 
    107136 
    108137/***************************************************************************** 
     
    205234    puts  ("                      Specify N=-1 (default) to disable this feature."); 
    206235    puts  ("                      Specify N=0 for instant close when unused."); 
     236    puts  ("  --no-tones          Disable audible tones"); 
    207237 
    208238    puts  (""); 
     
    265295    cfg->capture_lat = PJMEDIA_SND_DEFAULT_REC_LATENCY; 
    266296    cfg->playback_lat = PJMEDIA_SND_DEFAULT_PLAY_LATENCY; 
     297    cfg->ringback_slot = PJSUA_INVALID_ID; 
     298    cfg->ring_slot = PJSUA_INVALID_ID; 
    267299 
    268300    for (i=0; i<PJ_ARRAY_SIZE(cfg->acc_cfg); ++i) 
     
    426458           OPT_TLS_NEG_TIMEOUT, 
    427459           OPT_CAPTURE_DEV, OPT_PLAYBACK_DEV, 
    428            OPT_CAPTURE_LAT, OPT_PLAYBACK_LAT, 
     460           OPT_CAPTURE_LAT, OPT_PLAYBACK_LAT, OPT_NO_TONES, 
    429461           OPT_STDOUT_REFRESH, OPT_STDOUT_REFRESH_TEXT, 
    430462           OPT_AUTO_UPDATE_NAT,OPT_USE_COMPACT_FORM,OPT_DIS_CODEC 
     
    519551        { "stdout-refresh-text", 1, 0, OPT_STDOUT_REFRESH_TEXT}, 
    520552        { "snd-auto-close", 1, 0, OPT_SND_AUTO_CLOSE}, 
     553        { "no-tones",    0, 0, OPT_NO_TONES}, 
    521554        { NULL, 0, 0, 0} 
    522555    }; 
     
    11151148        case OPT_SND_AUTO_CLOSE: 
    11161149            cfg->media_cfg.snd_auto_close_time = atoi(pj_optarg); 
     1150            break; 
     1151 
     1152        case OPT_NO_TONES: 
     1153            cfg->no_tones = PJ_TRUE; 
    11171154            break; 
    11181155 
     
    15181555        pj_strcat2(&cfg, line); 
    15191556    } 
     1557    if (config->no_tones) { 
     1558        pj_strcat2(&cfg, "--no-tones\n"); 
     1559    } 
    15201560 
    15211561    /* Sound device latency */ 
     
    16941734 */ 
    16951735 
     1736static void ringback_start(pjsua_call_id call_id) 
     1737{ 
     1738    if (app_config.no_tones) 
     1739        return; 
     1740 
     1741    if (app_config.call_data[call_id].ringback_on) 
     1742        return; 
     1743 
     1744    app_config.call_data[call_id].ringback_on = PJ_TRUE; 
     1745 
     1746    if (++app_config.ringback_cnt==1 &&  
     1747        app_config.ringback_slot!=PJSUA_INVALID_ID)  
     1748    { 
     1749        pjmedia_tone_desc tone; 
     1750 
     1751        pj_bzero(&tone, sizeof(tone)); 
     1752        tone.freq1 = RINGBACK_FREQ1; 
     1753        tone.freq2 = RINGBACK_FREQ2; 
     1754        tone.on_msec = RINGBACK_ON; 
     1755        tone.off_msec = RINGBACK_OFF; 
     1756        pjmedia_tonegen_play(app_config.ringback_port, 1, &tone,  
     1757                             PJMEDIA_TONEGEN_LOOP); 
     1758 
     1759        pjsua_conf_connect(app_config.ringback_slot, 0); 
     1760    } 
     1761} 
     1762 
     1763static void ring_stop(pjsua_call_id call_id) 
     1764{ 
     1765    if (app_config.no_tones) 
     1766        return; 
     1767 
     1768    if (app_config.call_data[call_id].ringback_on) { 
     1769        app_config.call_data[call_id].ringback_on = PJ_FALSE; 
     1770 
     1771        pj_assert(app_config.ringback_cnt>0); 
     1772        if (--app_config.ringback_cnt == 0 &&  
     1773            app_config.ringback_slot!=PJSUA_INVALID_ID)  
     1774        { 
     1775            pjsua_conf_disconnect(app_config.ringback_slot, 0); 
     1776            pjmedia_tonegen_stop(app_config.ringback_port); 
     1777        } 
     1778    } 
     1779 
     1780    if (app_config.call_data[call_id].ring_on) { 
     1781        app_config.call_data[call_id].ring_on = PJ_FALSE; 
     1782 
     1783        pj_assert(app_config.ring_cnt>0); 
     1784        if (--app_config.ring_cnt == 0 &&  
     1785            app_config.ring_slot!=PJSUA_INVALID_ID)  
     1786        { 
     1787            pjsua_conf_disconnect(app_config.ring_slot, 0); 
     1788            pjmedia_tonegen_stop(app_config.ring_port); 
     1789        } 
     1790    } 
     1791} 
     1792 
     1793static void ring_start(pjsua_call_id call_id) 
     1794{ 
     1795    if (app_config.no_tones) 
     1796        return; 
     1797 
     1798    if (app_config.call_data[call_id].ring_on) 
     1799        return; 
     1800 
     1801    app_config.call_data[call_id].ring_on = PJ_TRUE; 
     1802 
     1803    if (++app_config.ring_cnt==1 &&  
     1804        app_config.ring_slot!=PJSUA_INVALID_ID)  
     1805    { 
     1806        unsigned i; 
     1807        pjmedia_tone_desc tone[3]; 
     1808 
     1809        pj_bzero(&tone, sizeof(tone)); 
     1810        for (i=0; i<PJ_ARRAY_SIZE(tone); ++i) { 
     1811            tone[i].freq1 = RING_FREQ1; 
     1812            tone[i].freq2 = RING_FREQ2; 
     1813            tone[i].on_msec = RING_ON; 
     1814            tone[i].off_msec = RING_OFF; 
     1815        } 
     1816        tone[PJ_ARRAY_SIZE(tone)-1].off_msec = RING_INTERVAL; 
     1817 
     1818        pjmedia_tonegen_play(app_config.ring_port, PJ_ARRAY_SIZE(tone),  
     1819                             tone, PJMEDIA_TONEGEN_LOOP); 
     1820 
     1821        pjsua_conf_connect(app_config.ring_slot, 0); 
     1822    } 
     1823} 
     1824 
    16961825/* 
    16971826 * Find next call when current call is disconnected or when user 
     
    17941923 
    17951924    if (call_info.state == PJSIP_INV_STATE_DISCONNECTED) { 
     1925 
     1926        /* Stop all ringback for this call */ 
     1927        ring_stop(call_id); 
    17961928 
    17971929        /* Cancel duration timer, if any */ 
     
    18551987            reason = msg->line.status.reason; 
    18561988 
     1989            /* Start ringback for 180 for UAC unless there's SDP in 180 */ 
     1990            if (call_info.role==PJSIP_ROLE_UAC && code==180 &&  
     1991                msg->body == NULL &&  
     1992                call_info.media_status==PJSUA_CALL_MEDIA_NONE)  
     1993            { 
     1994                ringback_start(call_id); 
     1995            } 
     1996 
    18571997            PJ_LOG(3,(THIS_FILE, "Call %d state changed to %s (%d %.*s)",  
    18581998                      call_id, call_info.state_text.ptr, 
     
    18832023 
    18842024    pjsua_call_get_info(call_id, &call_info); 
     2025 
     2026    /* Start ringback */ 
     2027    ring_start(call_id); 
    18852028 
    18862029    if (app_config.auto_answer > 0) { 
     
    19772120 
    19782121    pjsua_call_get_info(call_id, &call_info); 
     2122 
     2123    /* Stop ringback */ 
     2124    ring_stop(call_id); 
    19792125 
    19802126    if (call_info.media_status == PJSUA_CALL_MEDIA_ACTIVE) { 
     
    36883834    pj_memcpy(&tcp_cfg, &app_config.udp_cfg, sizeof(tcp_cfg)); 
    36893835 
     3836    /* Create ringback tones */ 
     3837    if (app_config.no_tones == PJ_FALSE) { 
     3838        pj_str_t name; 
     3839 
     3840        /* Ringback tone (call is ringing) */ 
     3841        name = pj_str("ringback"); 
     3842        status = pjmedia_tonegen_create2(app_config.pool, &name, 8000, 1, 160, 
     3843                                         16, PJMEDIA_TONEGEN_LOOP,  
     3844                                         &app_config.ringback_port); 
     3845        if (status != PJ_SUCCESS) 
     3846            goto on_error; 
     3847 
     3848        status = pjsua_conf_add_port(app_config.pool, app_config.ringback_port, 
     3849                                     &app_config.ringback_slot); 
     3850        if (status != PJ_SUCCESS) 
     3851            goto on_error; 
     3852 
     3853        /* Ring (to alert incoming call) */ 
     3854        name = pj_str("ring"); 
     3855        status = pjmedia_tonegen_create2(app_config.pool, &name, 8000, 1, 160, 
     3856                                         16, PJMEDIA_TONEGEN_LOOP,  
     3857                                         &app_config.ring_port); 
     3858        if (status != PJ_SUCCESS) 
     3859            goto on_error; 
     3860 
     3861        status = pjsua_conf_add_port(app_config.pool, app_config.ring_port, 
     3862                                     &app_config.ring_slot); 
     3863        if (status != PJ_SUCCESS) 
     3864            goto on_error; 
     3865 
     3866    } 
     3867 
    36903868    /* Add UDP transport unless it's disabled. */ 
    36913869    if (!app_config.no_udp) { 
     
    38764054    } 
    38774055#endif 
     4056 
     4057    /* Close ringback port */ 
     4058    if (app_config.ringback_port &&  
     4059        app_config.ringback_slot != PJSUA_INVALID_ID)  
     4060    { 
     4061        pjsua_conf_remove_port(app_config.ringback_slot); 
     4062        app_config.ringback_slot = PJSUA_INVALID_ID; 
     4063        pjmedia_port_destroy(app_config.ringback_port); 
     4064        app_config.ringback_port = NULL; 
     4065    } 
     4066 
     4067    /* Close ring port */ 
     4068    if (app_config.ring_port && app_config.ring_slot != PJSUA_INVALID_ID) { 
     4069        pjsua_conf_remove_port(app_config.ring_slot); 
     4070        app_config.ring_slot = PJSUA_INVALID_ID; 
     4071        pjmedia_port_destroy(app_config.ring_port); 
     4072        app_config.ring_port = NULL; 
     4073    } 
    38784074 
    38794075    /* Close tone generators */ 
Note: See TracChangeset for help on using the changeset viewer.