Ignore:
Timestamp:
Feb 18, 2009 2:28:49 PM (15 years ago)
Author:
nanang
Message:
  • Added APS-direct sound device management into pjsua-lib (and removed it from apps).
  • Fixed bug in conf_switch.c to always update ts_rx (even if port is not transmitting).
  • Minor updates: 'fmt_id' to 'id', added transmitter_Cnt in conf port info, explicit mapping in Symbian audio APS impl from pjmedia_format_id to Symbian APS fourcc.
Location:
pjproject/branches/projects/aps-direct
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • pjproject/branches/projects/aps-direct/pjmedia/include/pjmedia/conference.h

    r2456 r2460  
    6262    unsigned            listener_cnt;       /**< Number of listeners.       */ 
    6363    unsigned           *listener_slots;     /**< Array of listeners.        */ 
     64    unsigned            transmitter_cnt;    /**< Number of transmitter.     */ 
    6465    unsigned            clock_rate;         /**< Clock rate of the port.    */ 
    6566    unsigned            channel_count;      /**< Number of channels.        */ 
  • pjproject/branches/projects/aps-direct/pjmedia/include/pjmedia/sound.h

    r2457 r2460  
    117117    pjmedia_format      format;   /**< Format.                      */  
    118118    pj_bool_t           plc;      /**< PLC enabled/disabled.        */ 
    119     pj_bool_t           cng;      /**< CNG enabled/disabled.        */ 
    120119    pjmedia_snd_route   route;    /**< Audio routing.               */ 
    121120} pjmedia_snd_setting; 
  • pjproject/branches/projects/aps-direct/pjmedia/include/pjmedia/types.h

    r2457 r2460  
    205205{ 
    206206    /** Format ID */ 
    207     pjmedia_format_id   fmt_id; 
     207    pjmedia_format_id   id; 
    208208 
    209209    /** Bitrate. */ 
  • pjproject/branches/projects/aps-direct/pjmedia/src/pjmedia/conf_switch.c

    r2457 r2460  
    588588    dst_port = conf->ports[sink_slot]; 
    589589 
    590     /* Source and sink format must match. */ 
    591     if (src_port->info->format.fmt_id != dst_port->info->format.fmt_id) { 
     590    /* Format must match. */ 
     591    if (src_port->info->format.id != dst_port->info->format.id || 
     592        src_port->info->format.bitrate != dst_port->info->format.bitrate)  
     593    { 
    592594        pj_mutex_unlock(conf->mutex); 
    593595        return PJMEDIA_ENOTCOMPATIBLE; 
     596    } 
     597 
     598    /* Clock rate must match. */ 
     599    if (src_port->info->clock_rate != dst_port->info->clock_rate) { 
     600        pj_mutex_unlock(conf->mutex); 
     601        return PJMEDIA_ENCCLOCKRATE; 
     602    } 
     603 
     604    /* Channel count must match. */ 
     605    if (src_port->info->channel_count != dst_port->info->channel_count) { 
     606        pj_mutex_unlock(conf->mutex); 
     607        return PJMEDIA_ENCCLOCKRATE; 
    594608    } 
    595609 
     
    866880    info->listener_cnt = conf_port->listener_cnt; 
    867881    info->listener_slots = conf_port->listener_slots; 
     882    info->transmitter_cnt = conf_port->transmitter_cnt; 
    868883    info->clock_rate = conf_port->info->clock_rate; 
    869884    info->channel_count = conf_port->info->channel_count; 
     
    952967 
    953968    /* Level adjustment is applicable only for ports that work with raw PCM. */ 
    954     PJ_ASSERT_RETURN(conf_port->info->format.fmt_id == PJMEDIA_FORMAT_L16, 
     969    PJ_ASSERT_RETURN(conf_port->info->format.id == PJMEDIA_FORMAT_L16, 
    955970                     PJ_EIGNORED); 
    956971 
     
    9861001 
    9871002    /* Level adjustment is applicable only for ports that work with raw PCM. */ 
    988     PJ_ASSERT_RETURN(conf_port->info->format.fmt_id == PJMEDIA_FORMAT_L16, 
     1003    PJ_ASSERT_RETURN(conf_port->info->format.id == PJMEDIA_FORMAT_L16, 
    9891004                     PJ_EIGNORED); 
    9901005 
     
    10501065        f_start = (pj_int16_t*)frm_src->buf; 
    10511066        f_end   = f_start + (frm_src->size >> 1); 
     1067 
    10521068        while (f_start < f_end) { 
    10531069            unsigned nsamples_to_copy, nsamples_req; 
     
    11111127        /* Check port format. */ 
    11121128        if (cport_dst->port && 
    1113             cport_dst->port->info.format.fmt_id == PJMEDIA_FORMAT_L16) 
     1129            cport_dst->port->info.format.id == PJMEDIA_FORMAT_L16) 
    11141130        { 
    11151131            /* When there is already some samples in listener's TX buffer,  
     
    12101226        { 
    12111227            cport->rx_level = 0; 
     1228            pj_add_timestamp32(&cport->ts_rx,  
     1229                               conf->master_port->info.samples_per_frame); 
    12121230            continue; 
    12131231        } 
     
    12261244             
    12271245            f->buf = &conf->buf[sizeof(pjmedia_frame)]; 
    1228             f->size = BUFFER_SIZE - sizeof(pjmedia_frame); 
     1246            f->size = cport->info->samples_per_frame<<1; 
    12291247 
    12301248            /* Get frame from port. */ 
  • pjproject/branches/projects/aps-direct/pjmedia/src/pjmedia/conference.c

    r2434 r2460  
    11721172    info->listener_cnt = conf_port->listener_cnt; 
    11731173    info->listener_slots = conf_port->listener_slots; 
     1174    info->transmitter_cnt = conf_port->transmitter_cnt; 
    11741175    info->clock_rate = conf_port->clock_rate; 
    11751176    info->channel_count = conf_port->channel_count; 
  • pjproject/branches/projects/aps-direct/pjmedia/src/pjmedia/sound_port.c

    r2457 r2460  
    290290        unsigned i, size_decoded; 
    291291 
    292         switch (snd_port->setting.format.fmt_id) { 
     292        switch (snd_port->setting.format.id) { 
    293293        case PJMEDIA_FORMAT_PCMA: 
    294294            decoder = &pjmedia_alaw_decode; 
     
    299299        default: 
    300300            PJ_LOG(1,(THIS_FILE, "Unsupported format %d",  
    301                       snd_port->setting.format.fmt_id)); 
     301                      snd_port->setting.format.id)); 
    302302            goto no_frame; 
    303303        } 
     
    392392    fx->base.timestamp.u32.lo = timestamp; 
    393393 
    394     switch (snd_port->setting.format.fmt_id) { 
     394    switch (snd_port->setting.format.id) { 
    395395    case PJMEDIA_FORMAT_PCMA: 
    396396        encoder = &pjmedia_alaw_encode; 
     
    401401    default: 
    402402        PJ_LOG(1,(THIS_FILE, "Unsupported format %d",  
    403                   snd_port->setting.format.fmt_id)); 
     403                  snd_port->setting.format.id)); 
    404404        return PJ_SUCCESS; 
    405405    } 
     
    435435                     PJ_EBUG); 
    436436 
    437     if (snd_port->setting.format.fmt_id == PJMEDIA_FORMAT_L16) { 
     437    if (snd_port->setting.format.id == PJMEDIA_FORMAT_L16) { 
    438438        snd_rec_cb = &rec_cb; 
    439439        snd_play_cb = &play_cb; 
     
    716716#if !defined(PJMEDIA_SND_SUPPORT_OPEN2) || PJMEDIA_SND_SUPPORT_OPEN2==0 
    717717    /* For devices that doesn't support open2(), enable simulation */ 
    718     if (snd_port->setting.format.fmt_id != PJMEDIA_FORMAT_L16) { 
     718    if (snd_port->setting.format.id != PJMEDIA_FORMAT_L16) { 
    719719        snd_port->frm_buf_size = sizeof(pjmedia_frame_ext) +  
    720720                                 (samples_per_frame << 1) + 
  • pjproject/branches/projects/aps-direct/pjmedia/src/pjmedia/stream.c

    r2457 r2460  
    868868    } else if (frame->type == PJMEDIA_FRAME_TYPE_AUDIO && 
    869869               frame->buf == NULL && 
    870                stream->port.info.format.fmt_id == PJMEDIA_FORMAT_L16 && 
     870               stream->port.info.format.id == PJMEDIA_FORMAT_L16 && 
    871871               (stream->dir & PJMEDIA_DIR_ENCODING) && 
    872872               stream->codec_param.info.frm_ptime * 
     
    16061606    stream->port.info.clock_rate = info->fmt.clock_rate; 
    16071607    stream->port.info.channel_count = info->fmt.channel_cnt; 
    1608     stream->port.info.format.fmt_id = info->param->info.fmt_id; 
    1609     stream->port.info.format.bitrate = info->param->info.avg_bps; 
    1610     stream->port.info.format.vad = (info->param->setting.vad != 0); 
     1608    stream->port.info.format.id = info->param->info.fmt_id; 
    16111609    stream->port.port_data.pdata = stream; 
    1612     if (stream->port.info.format.fmt_id == PJMEDIA_FORMAT_L16) { 
     1610    if (stream->port.info.format.id == PJMEDIA_FORMAT_L16) { 
    16131611        stream->port.put_frame = &put_frame; 
    16141612        stream->port.get_frame = &get_frame; 
    16151613    } else { 
     1614        stream->port.info.format.bitrate = info->param->info.avg_bps; 
     1615        stream->port.info.format.vad = (info->param->setting.vad != 0); 
     1616 
    16161617        stream->port.put_frame = &put_frame; 
    16171618        stream->port.get_frame = &get_frame_ext; 
  • pjproject/branches/projects/aps-direct/pjmedia/src/pjmedia/symbian_sound_aps.cpp

    r2456 r2460  
    708708    pjmedia_frame_ext *frame = (pjmedia_frame_ext*) strm->rec_buf; 
    709709     
    710     switch(strm->setting.format.u32) { 
     710    switch(strm->setting.format.id) { 
    711711    case PJMEDIA_FORMAT_AMR: 
    712712        { 
     
    757757            unsigned samples_got; 
    758758             
    759             samples_got = strm->setting.mode == 30? 240 : 160; 
     759            samples_got = strm->setting.format.bitrate == 15200? 160 : 240; 
    760760             
    761761            /* Check if we got a normal frame. */ 
     
    836836    buf.iBuffer.Zero(); 
    837837 
    838     switch(strm->setting.format.u32) { 
     838    switch(strm->setting.format.id) { 
    839839    case PJMEDIA_FORMAT_AMR: 
    840840        { 
     
    949949                sf = pjmedia_frame_ext_get_subframe(frame, 0); 
    950950                samples_cnt = frame->samples_cnt / frame->subframe_cnt; 
    951                 pj_assert((strm->setting.mode == 30 && samples_cnt == 240) || 
    952                           (strm->setting.mode == 20 && samples_cnt == 160)); 
     951                 
     952                pj_assert((strm->setting.format.bitrate == 15200 &&  
     953                           samples_cnt == 160) || 
     954                          (strm->setting.format.bitrate != 15200 && 
     955                           samples_cnt == 240)); 
    953956                 
    954957                if (sf->data && sf->bitlen) { 
     
    10061009                    } else { 
    10071010                        pj_uint8_t silc; 
    1008                         silc = (strm->setting.format.u32==PJMEDIA_FORMAT_PCMU)? 
     1011                        silc = (strm->setting.format.id==PJMEDIA_FORMAT_PCMU)? 
    10091012                                pjmedia_linear2ulaw(0) : pjmedia_linear2alaw(0); 
    10101013                        buf.iBuffer.AppendFill(silc, samples_cnt); 
     
    10171020                    pj_uint8_t silc; 
    10181021                     
    1019                     silc = (strm->setting.format.u32==PJMEDIA_FORMAT_PCMU)? 
     1022                    silc = (strm->setting.format.id==PJMEDIA_FORMAT_PCMU)? 
    10201023                            pjmedia_linear2ulaw(0) : pjmedia_linear2alaw(0); 
    10211024                    buf.iBuffer.AppendFill(silc, samples_req - samples_ready); 
     
    11061109 
    11071110    /* Set audio engine fourcc. */ 
    1108     if (strm->setting.format.u32 == PJMEDIA_FORMAT_PCMU || 
    1109         strm->setting.format.u32 == PJMEDIA_FORMAT_PCMA || 
    1110         strm->setting.format.u32 == PJMEDIA_FORMAT_L16) 
     1111    switch(strm->setting.format.id) { 
     1112    case PJMEDIA_FORMAT_L16: 
     1113    case PJMEDIA_FORMAT_PCMU: 
     1114    case PJMEDIA_FORMAT_PCMA: 
     1115        aps_setting.fourcc = TFourCC(KMCPFourCCIdG711); 
     1116        break; 
     1117    case PJMEDIA_FORMAT_AMR: 
     1118        aps_setting.fourcc = TFourCC(KMCPFourCCIdAMRNB); 
     1119        break; 
     1120    case PJMEDIA_FORMAT_G729: 
     1121        aps_setting.fourcc = TFourCC(KMCPFourCCIdG729); 
     1122        break; 
     1123    case PJMEDIA_FORMAT_ILBC: 
     1124        aps_setting.fourcc = TFourCC(KMCPFourCCIdILBC); 
     1125        break; 
     1126    default: 
     1127        aps_setting.fourcc = 0; 
     1128        break; 
     1129    } 
     1130 
     1131    /* Set audio engine mode. */ 
     1132    if (strm->setting.format.id == PJMEDIA_FORMAT_AMR) 
    11111133    { 
    1112         aps_setting.fourcc = TFourCC(KMCPFourCCIdG711); 
    1113     } else { 
    1114         aps_setting.fourcc = TFourCC(strm->setting.format.u32); 
    1115     } 
    1116  
    1117     /* Set audio engine mode. */ 
    1118     if (strm->setting.format.u32 == PJMEDIA_FORMAT_AMR) 
    1119     { 
    1120         aps_setting.mode = (TAPSCodecMode)strm->setting.bitrate; 
     1134        aps_setting.mode = (TAPSCodecMode)strm->setting.format.bitrate; 
    11211135    }  
    1122     else if (strm->setting.format.u32 == PJMEDIA_FORMAT_PCMU || 
    1123              strm->setting.format.u32 == PJMEDIA_FORMAT_L16 || 
    1124             (strm->setting.format.u32 == PJMEDIA_FORMAT_ILBC  && 
    1125              strm->setting.mode == 30)) 
     1136    else if (strm->setting.format.id == PJMEDIA_FORMAT_PCMU || 
     1137             strm->setting.format.id == PJMEDIA_FORMAT_L16 || 
     1138            (strm->setting.format.id == PJMEDIA_FORMAT_ILBC  && 
     1139             strm->setting.format.bitrate != 15200)) 
    11261140    { 
    11271141        aps_setting.mode = EULawOr30ms; 
    11281142    }  
    1129     else if (strm->setting.format.u32 == PJMEDIA_FORMAT_PCMA || 
    1130             (strm->setting.format.u32 == PJMEDIA_FORMAT_ILBC && 
    1131              strm->setting.mode == 20)) 
     1143    else if (strm->setting.format.id == PJMEDIA_FORMAT_PCMA || 
     1144            (strm->setting.format.id == PJMEDIA_FORMAT_ILBC && 
     1145             strm->setting.format.bitrate == 15200)) 
    11321146    { 
    11331147        aps_setting.mode = EALawOr20ms; 
     
    11351149 
    11361150    /* Disable VAD on L16 and G711. */ 
    1137     if (strm->setting.format.u32 == PJMEDIA_FORMAT_PCMU || 
    1138         strm->setting.format.u32 == PJMEDIA_FORMAT_PCMA || 
    1139         strm->setting.format.u32 == PJMEDIA_FORMAT_L16) 
     1151    if (strm->setting.format.id == PJMEDIA_FORMAT_PCMU || 
     1152        strm->setting.format.id == PJMEDIA_FORMAT_PCMA || 
     1153        strm->setting.format.id == PJMEDIA_FORMAT_L16) 
    11401154    { 
    11411155        aps_setting.vad = EFalse; 
    11421156    } else { 
    1143         aps_setting.vad = strm->setting.vad; 
     1157        aps_setting.vad = strm->setting.format.vad; 
    11441158    } 
    11451159     
    11461160    /* Set other audio engine attributes. */ 
    11471161    aps_setting.plc = strm->setting.plc; 
    1148     aps_setting.cng = strm->setting.cng; 
    1149     aps_setting.loudspk = strm->setting.loudspk; 
     1162    aps_setting.cng = aps_setting.vad; 
     1163    aps_setting.loudspk = strm->setting.route == PJMEDIA_SND_ROUTE_LOUDSPEAKER; 
    11501164 
    11511165    /* Set audio engine callbacks. */ 
    1152     if (strm->setting.format.u32 == PJMEDIA_FORMAT_L16) { 
     1166    if (strm->setting.format.id == PJMEDIA_FORMAT_L16) { 
    11531167        aps_play_cb = &PlayCbPcm; 
    11541168        aps_rec_cb  = &RecCbPcm; 
     
    11801194    strm->rec_buf_len = 0; 
    11811195 
    1182     if (strm->setting.format.u32 == PJMEDIA_FORMAT_G729) { 
     1196    if (strm->setting.format.id == PJMEDIA_FORMAT_G729) { 
    11831197        TBitStream *g729_bitstream = new TBitStream; 
    11841198         
     
    12121226 
    12131227    pj_bzero(&setting, sizeof(setting)); 
    1214     setting.format.u32 = PJMEDIA_FORMAT_L16; 
     1228    setting.format.id = PJMEDIA_FORMAT_L16; 
    12151229     
    12161230    return sound_open(PJMEDIA_DIR_CAPTURE, clock_rate, channel_count, 
     
    12341248 
    12351249    pj_bzero(&setting, sizeof(setting)); 
    1236     setting.format.u32 = PJMEDIA_FORMAT_L16; 
     1250    setting.format.id = PJMEDIA_FORMAT_L16; 
    12371251 
    12381252    return sound_open(PJMEDIA_DIR_PLAYBACK, clock_rate, channel_count, 
     
    12591273 
    12601274    pj_bzero(&setting, sizeof(setting)); 
    1261     setting.format.u32 = PJMEDIA_FORMAT_L16; 
     1275    setting.format.id = PJMEDIA_FORMAT_L16; 
    12621276 
    12631277    return sound_open(PJMEDIA_DIR_CAPTURE_PLAYBACK, clock_rate, channel_count, 
     
    13471361    stream->engine = NULL; 
    13481362 
    1349     if (stream->setting.format.u32 == PJMEDIA_FORMAT_G729) { 
     1363    if (stream->setting.format.id == PJMEDIA_FORMAT_G729) { 
    13501364        TBitStream *g729_bitstream = (TBitStream*)stream->strm_data; 
    13511365        stream->strm_data = NULL; 
  • pjproject/branches/projects/aps-direct/pjsip-apps/src/pjsua/pjsua_app.c

    r2457 r2460  
    24022402} 
    24032403 
    2404 #ifdef PJSUA_SIMULATE_APS_DIRECT 
    2405 /* To simulate APS direct, add these to config_site.h: 
    2406 #define PJSUA_SIMULATE_APS_DIRECT 
    2407 #ifdef PJSUA_SIMULATE_APS_DIRECT 
    2408     #define PJMEDIA_CONF_USE_SWITCH_BOARD       1 
    2409     #define PJMEDIA_HAS_PASSTHROUGH_CODECS      1 
    2410  
    2411     #define PJMEDIA_HAS_L16_CODEC               0 
    2412     #define PJMEDIA_HAS_GSM_CODEC               0 
    2413     #define PJMEDIA_HAS_SPEEX_CODEC             0 
    2414     #define PJMEDIA_HAS_ILBC_CODEC              0 
    2415     #define PJMEDIA_HAS_G722_CODEC              0 
    2416     #define PJMEDIA_HAS_INTEL_IPP               0 
    2417  
    2418     #define PJMEDIA_HAS_PASSTHROUGH_CODEC_AMR   0 
    2419     #define PJMEDIA_HAS_PASSTHROUGH_CODEC_G729  0 
    2420     #define PJMEDIA_HAS_PASSTHROUGH_CODEC_ILBC  0 
    2421 #endif 
    2422 */ 
    2423  
    2424 /* Global sound port. */ 
    2425 static pjmedia_snd_port *g_snd_port; 
    2426  
    2427  
    2428 /* Reopen sound device on on_stream_created() pjsua callback. */ 
    2429 static void on_call_stream_created(pjsua_call_id call_id,  
    2430                                    pjmedia_session *sess, 
    2431                                    unsigned stream_idx,  
    2432                                    pjmedia_port **p_port) 
    2433 { 
    2434     pjmedia_port *conf; 
    2435     pjmedia_session_info sess_info; 
    2436     pjmedia_port *port; 
    2437     pjmedia_stream_info *strm_info; 
    2438     pjmedia_snd_setting setting; 
    2439     unsigned samples_per_frame; 
    2440     pj_status_t status; 
    2441  
    2442     PJ_UNUSED_ARG(call_id); 
    2443     PJ_UNUSED_ARG(p_port); 
    2444  
    2445     /* Get active format for this stream, based on SDP negotiation result. */     
    2446     pjmedia_session_get_info(sess, &sess_info); 
    2447     strm_info = &sess_info.stream_info[stream_idx]; 
    2448  
    2449     pjmedia_session_get_port(sess, stream_idx, &port); 
    2450  
    2451     /* Init sound device setting based on stream info. */ 
    2452     pj_bzero(&setting, sizeof(setting)); 
    2453     setting.format = port->info.format; 
    2454     setting.cng = strm_info->param->setting.cng; 
    2455     setting.plc = strm_info->param->setting.plc; 
    2456  
    2457     /* Close sound device and get the conference port. */ 
    2458     conf = pjsua_set_no_snd_dev(); 
    2459      
    2460     samples_per_frame = strm_info->param->info.clock_rate * 
    2461                         strm_info->param->info.frm_ptime * 
    2462                         strm_info->param->setting.frm_per_pkt * 
    2463                         strm_info->param->info.channel_cnt / 
    2464                         1000; 
    2465  
    2466     /* Reset conference port attributes. */ 
    2467     conf->info.samples_per_frame = samples_per_frame; 
    2468     conf->info.clock_rate = strm_info->param->info.clock_rate; 
    2469     conf->info.channel_count = 1; 
    2470     conf->info.bits_per_sample = 16; 
    2471  
    2472     /* Reopen sound device. */ 
    2473     status = pjmedia_snd_port_create2(app_config.pool,  
    2474                                       PJMEDIA_DIR_CAPTURE_PLAYBACK, 
    2475                                       -1, 
    2476                                       -1, 
    2477                                       strm_info->param->info.clock_rate, 
    2478                                       strm_info->param->info.channel_cnt, 
    2479                                       samples_per_frame, 
    2480                                       16, 
    2481                                       &setting, 
    2482                                       &g_snd_port); 
    2483     if (status != PJ_SUCCESS) { 
    2484         pjsua_perror(THIS_FILE, "Error opening sound device", status); 
    2485         return; 
    2486     } 
    2487  
    2488     /* Connect sound to conference port. */ 
    2489     pjmedia_snd_port_connect(g_snd_port, conf); 
    2490 } 
    2491  
    2492 static void on_call_stream_destroyed(pjsua_call_id call_id, 
    2493                                      pjmedia_session *sess,  
    2494                                      unsigned stream_idx) 
    2495 { 
    2496     PJ_UNUSED_ARG(call_id); 
    2497     PJ_UNUSED_ARG(sess); 
    2498     PJ_UNUSED_ARG(stream_idx); 
    2499  
    2500     if (g_snd_port) { 
    2501         pjmedia_snd_port_destroy(g_snd_port); 
    2502         g_snd_port = NULL; 
    2503     } 
    2504 } 
    2505  
    2506 #endif 
    2507  
    25082404/* 
    25092405 * DTMF callback. 
     
    41514047    app_config.cfg.cb.on_call_state = &on_call_state; 
    41524048    app_config.cfg.cb.on_call_media_state = &on_call_media_state; 
    4153 #ifdef PJSUA_SIMULATE_APS_DIRECT 
    4154     app_config.cfg.cb.on_stream_created = &on_call_stream_created; 
    4155     app_config.cfg.cb.on_stream_destroyed = &on_call_stream_destroyed; 
    4156 #endif 
    41574049    app_config.cfg.cb.on_incoming_call = &on_incoming_call; 
    41584050    app_config.cfg.cb.on_call_tsx_state = &on_call_tsx_state; 
  • pjproject/branches/projects/aps-direct/pjsip-apps/src/symbian_ua/ua.cpp

    r2456 r2460  
    9292static pjsua_buddy_id g_buddy_id = PJSUA_INVALID_ID; 
    9393 
    94 static pj_pool_t *app_pool; 
    95 static pjmedia_snd_port *g_snd_port; 
    96  
    9794 
    9895/* Callback called by the library upon receiving incoming call */ 
     
    254251} 
    255252 
    256 /* Notification that stream is created. */ 
    257 static void on_stream_created(pjsua_call_id call_id,  
    258                               pjmedia_session *sess, 
    259                               unsigned stream_idx,  
    260                               pjmedia_port **p_port) 
    261 { 
    262     pjmedia_port *conf; 
    263     pjmedia_session_info sess_info; 
    264     pjmedia_stream_info *strm_info; 
    265     pjmedia_snd_setting setting; 
    266     unsigned samples_per_frame; 
    267     pj_status_t status; 
    268      
    269     PJ_UNUSED_ARG(call_id); 
    270     PJ_UNUSED_ARG(p_port); 
    271      
    272     status = pjmedia_session_get_info(sess, &sess_info); 
    273     if (status != PJ_SUCCESS) { 
    274         PJ_LOG(1,(THIS_FILE, "on_stream_created() failed to get session info, " 
    275                              "status=%d", status)); 
    276         return; 
    277     } 
    278      
    279     strm_info = &sess_info.stream_info[stream_idx]; 
    280     if (strm_info->type != PJMEDIA_TYPE_AUDIO) 
    281         return; 
    282  
    283     /* Init sound device setting based on stream info. */ 
    284     pj_bzero(&setting, sizeof(setting)); 
    285     setting.format = strm_info->param->info.format; 
    286     setting.bitrate = strm_info->param->info.avg_bps; 
    287     setting.cng = strm_info->param->setting.cng; 
    288     setting.vad = strm_info->param->setting.vad; 
    289     setting.plc = strm_info->param->setting.plc; 
    290     if (setting.format.u32 == PJMEDIA_FORMAT_ILBC) { 
    291         unsigned i; 
    292         pjmedia_codec_fmtp *fmtp = &strm_info->param->setting.dec_fmtp; 
    293          
    294         /* Initialize mode. */ 
    295         setting.mode = 30; 
    296          
    297         /* Get mode. */ 
    298         for (i = 0; i < fmtp->cnt; ++i) { 
    299             if (pj_stricmp2(&fmtp->param[i].name, "mode") == 0) { 
    300                 setting.mode = (pj_uint32_t) pj_strtoul(&fmtp->param[i].val); 
    301                 break; 
    302             } 
    303         } 
    304     } 
    305  
    306     samples_per_frame = strm_info->param->info.clock_rate * 
    307                         strm_info->param->info.frm_ptime * 
    308                         strm_info->param->info.channel_cnt / 
    309                         1000; 
    310      
    311     /* Close sound device. */ 
    312     conf = pjsua_set_no_snd_dev(); 
    313      
    314     /* Reset conference attributes. */ 
    315     conf->info.samples_per_frame = samples_per_frame; 
    316     conf->info.clock_rate = strm_info->param->info.clock_rate; 
    317     conf->info.channel_count = strm_info->param->info.channel_cnt; 
    318     conf->info.bits_per_sample = 16; 
    319     conf->info.format = strm_info->param->info.format; 
    320  
    321     /* Reopen sound device. */ 
    322     status = pjmedia_snd_port_create2(app_pool,  
    323                                       PJMEDIA_DIR_CAPTURE_PLAYBACK, 
    324                                       0, 
    325                                       0, 
    326                                       strm_info->param->info.clock_rate, 
    327                                       strm_info->param->info.channel_cnt, 
    328                                       samples_per_frame, 
    329                                       16, 
    330                                       &setting, 
    331                                       &g_snd_port); 
    332     if (status != PJ_SUCCESS) { 
    333         PJ_LOG(1,(THIS_FILE, "on_stream_created() failed to reopen sound " 
    334                              "device, status=%d", status)); 
    335         return; 
    336     } 
    337      
    338     status = pjmedia_snd_port_connect(g_snd_port, conf); 
    339     if (status != PJ_SUCCESS) { 
    340         PJ_LOG(1,(THIS_FILE, "on_stream_created() failed to connect sound " 
    341                              "device to conference, status=%d", status)); 
    342         return; 
    343     } 
    344 } 
    345  
    346 static void on_stream_destroyed(pjsua_call_id call_id, 
    347                                 pjmedia_session *sess,  
    348                                 unsigned stream_idx) 
    349 { 
    350     PJ_UNUSED_ARG(call_id); 
    351     PJ_UNUSED_ARG(sess); 
    352     PJ_UNUSED_ARG(stream_idx); 
    353  
    354     if (g_snd_port) { 
    355         pjmedia_snd_port_destroy(g_snd_port); 
    356         g_snd_port = NULL; 
    357     } 
    358 } 
    359253 
    360254//#include<e32debug.h> 
     
    397291    } 
    398292 
    399     /* Create pool for application */ 
    400     app_pool = pjsua_pool_create("pjsua-app", 1000, 1000); 
    401      
    402293    /* Init pjsua */ 
    403294    pjsua_config cfg; 
     
    420311    cfg.cb.on_call_replaced = &on_call_replaced; 
    421312    cfg.cb.on_nat_detect = &on_nat_detect; 
    422     cfg.cb.on_stream_created = &on_stream_created; 
    423     cfg.cb.on_stream_destroyed = &on_stream_destroyed; 
    424313     
    425314    if (SIP_PROXY) { 
     
    636525#   if PJMEDIA_SOUND_IMPLEMENTATION == PJMEDIA_SOUND_SYMB_APS_SOUND 
    637526    case 't': 
    638         if (g_snd_port) { 
    639             static pj_bool_t act_loudspk = PJ_TRUE; 
    640             pjmedia_snd_stream *strm; 
     527        do { 
     528            static pjmedia_snd_route route = PJMEDIA_SND_ROUTE_LOUDSPEAKER; 
    641529             
    642             strm = pjmedia_snd_port_get_snd_stream(g_snd_port); 
    643             pjmedia_snd_aps_activate_loudspeaker(strm, act_loudspk); 
    644             act_loudspk = !act_loudspk; 
    645         } else { 
    646             PJ_LOG(3,(THIS_FILE, "Sound device is not active.")); 
    647         } 
     530            pjsua_set_snd_route(route); 
     531             
     532            if (route == PJMEDIA_SND_ROUTE_LOUDSPEAKER) 
     533                route = PJMEDIA_SND_ROUTE_EARPIECE; 
     534            else 
     535                route = PJMEDIA_SND_ROUTE_LOUDSPEAKER; 
     536                 
     537        } while(0); 
    648538        break; 
    649539#   endif 
     
    1013903#endif 
    1014904         
    1015     if (g_snd_port) { 
    1016         pjmedia_snd_port_destroy(g_snd_port); 
    1017         g_snd_port = NULL; 
    1018     } 
    1019  
    1020     // Release application pool 
    1021     if (app_pool) { 
    1022         pj_pool_release(app_pool); 
    1023         app_pool = NULL; 
    1024     } 
    1025      
    1026905    // Shutdown pjsua 
    1027906    pjsua_destroy(); 
  • pjproject/branches/projects/aps-direct/pjsip/include/pjsua-lib/pjsua.h

    r2394 r2460  
    49134913 
    49144914 
     4915/** 
     4916 * Set sound device route. 
     4917 * 
     4918 * @param route         Sound device route to be set. 
     4919 * 
     4920 * @return              PJ_SUCCESS on success, or the appropriate error code. 
     4921 */ 
     4922PJ_DECL(pj_status_t) pjsua_set_snd_route(pjmedia_snd_route route); 
     4923 
    49154924 
    49164925/***************************************************************************** 
  • pjproject/branches/projects/aps-direct/pjsip/src/pjsua-lib/pjsua_media.c

    r2438 r2460  
    15101510} 
    15111511 
     1512#if PJMEDIA_CONF_USE_SWITCH_BOARD 
     1513 
     1514/* 
     1515 * Open sound device with extended setting. 
     1516 */ 
     1517static pj_status_t open_snd_dev_ext( int capture_dev, 
     1518                                     int playback_dev, 
     1519                                     unsigned clock_rate, 
     1520                                     unsigned channel_count, 
     1521                                     unsigned samples_per_frame, 
     1522                                     const pjmedia_snd_setting *setting) 
     1523{ 
     1524    pjmedia_port *conf_port; 
     1525    pj_status_t status; 
     1526 
     1527    PJ_ASSERT_RETURN(setting, PJ_EINVAL); 
     1528 
     1529    /* Check if NULL sound device is used */ 
     1530    if (NULL_SND_DEV_ID == capture_dev || NULL_SND_DEV_ID == playback_dev) { 
     1531        return pjsua_set_null_snd_dev(); 
     1532    } 
     1533 
     1534    /* Close existing sound port */ 
     1535    close_snd_dev(); 
     1536 
     1537    /* Create memory pool for sound device. */ 
     1538    pjsua_var.snd_pool = pjsua_pool_create("pjsua_snd", 4000, 4000); 
     1539    PJ_ASSERT_RETURN(pjsua_var.snd_pool, PJ_ENOMEM); 
     1540 
     1541 
     1542    /* Get the port0 of the conference bridge. */ 
     1543    conf_port = pjmedia_conf_get_master_port(pjsua_var.mconf); 
     1544    pj_assert(conf_port != NULL); 
     1545 
     1546    PJ_LOG(4,(THIS_FILE, "Opening sound device @%d/%d/%s", 
     1547              clock_rate, channel_count, 
     1548              (setting->format.id==PJMEDIA_FORMAT_L16?"raw":"encoded"))); 
     1549 
     1550    status = pjmedia_snd_port_create2( pjsua_var.snd_pool,  
     1551                                       PJMEDIA_DIR_CAPTURE_PLAYBACK, 
     1552                                       capture_dev, 
     1553                                       playback_dev,  
     1554                                       clock_rate,  
     1555                                       channel_count, 
     1556                                       samples_per_frame, 
     1557                                       16,  
     1558                                       setting,  
     1559                                       &pjsua_var.snd_port); 
     1560 
     1561    /* Update port 0 info when sound dev opened successfully. */ 
     1562    if (status == PJ_SUCCESS) { 
     1563        conf_port->info.format = setting->format; 
     1564        conf_port->info.clock_rate = clock_rate; 
     1565        conf_port->info.samples_per_frame = samples_per_frame; 
     1566        conf_port->info.channel_count = channel_count; 
     1567        conf_port->info.bits_per_sample = 16; 
     1568    } else { 
     1569        pjsua_perror(THIS_FILE, "Unable to open sound device", status); 
     1570        return status; 
     1571    } 
     1572 
     1573    /* Connect sound port to the bridge */ 
     1574    status = pjmedia_snd_port_connect(pjsua_var.snd_port,         
     1575                                      conf_port );        
     1576    if (status != PJ_SUCCESS) {           
     1577        pjsua_perror(THIS_FILE, "Unable to connect conference port to " 
     1578                                "sound device", status);          
     1579        pjmedia_snd_port_destroy(pjsua_var.snd_port);     
     1580        pjsua_var.snd_port = NULL;        
     1581        return status;    
     1582    } 
     1583 
     1584    /* Save the device IDs */ 
     1585    pjsua_var.cap_dev = capture_dev; 
     1586    pjsua_var.play_dev = playback_dev; 
     1587 
     1588    /* Update sound device name. */ 
     1589    do { 
     1590        const pjmedia_snd_dev_info *play_info; 
     1591        pjmedia_snd_stream *strm; 
     1592        pjmedia_snd_stream_info si; 
     1593        pj_str_t tmp; 
     1594 
     1595        strm = pjmedia_snd_port_get_snd_stream(pjsua_var.snd_port); 
     1596        pjmedia_snd_stream_get_info(strm, &si); 
     1597        play_info = pjmedia_snd_get_dev_info(si.rec_id); 
     1598 
     1599        pjmedia_conf_set_port0_name(pjsua_var.mconf,  
     1600                                    pj_cstr(&tmp, play_info->name)); 
     1601    } while(0); 
     1602 
     1603    return PJ_SUCCESS; 
     1604} 
     1605 
     1606#endif 
     1607 
     1608 
     1609/* Close existing sound device */ 
     1610static void close_snd_dev(void) 
     1611{ 
     1612    /* Close sound device */ 
     1613    if (pjsua_var.snd_port) { 
     1614        pjmedia_snd_dev_info cap_info, play_info; 
     1615        pjmedia_snd_stream *strm; 
     1616        pjmedia_snd_stream_info si; 
     1617 
     1618        strm = pjmedia_snd_port_get_snd_stream(pjsua_var.snd_port); 
     1619        pjmedia_snd_stream_get_info(strm, &si); 
     1620        cap_info = *(pjmedia_snd_get_dev_info(si.rec_id)); 
     1621        play_info = *(pjmedia_snd_get_dev_info(si.play_id)); 
     1622 
     1623        PJ_LOG(4,(THIS_FILE, "Closing %s sound playback device and " 
     1624                             "%s sound capture device", 
     1625                             play_info.name, cap_info.name)); 
     1626 
     1627        pjmedia_snd_port_disconnect(pjsua_var.snd_port); 
     1628        pjmedia_snd_port_destroy(pjsua_var.snd_port); 
     1629        pjsua_var.snd_port = NULL; 
     1630    } 
     1631 
     1632    /* Close null sound device */ 
     1633    if (pjsua_var.null_snd) { 
     1634        PJ_LOG(4,(THIS_FILE, "Closing null sound device..")); 
     1635        pjmedia_master_port_destroy(pjsua_var.null_snd, PJ_FALSE); 
     1636        pjsua_var.null_snd = NULL; 
     1637    } 
     1638 
     1639    if (pjsua_var.snd_pool)  
     1640        pj_pool_release(pjsua_var.snd_pool); 
     1641    pjsua_var.snd_pool = NULL; 
     1642} 
     1643 
    15121644 
    15131645/* 
     
    16251757    } 
    16261758 
     1759#if PJMEDIA_CONF_USE_SWITCH_BOARD 
     1760 
     1761    /* Check if sound device need to be reopened, i.e: its attributes 
     1762     * (format, clock rate, channel count) must match to peer's.  
     1763     * Note that sound device can be reopened only if it doesn't have 
     1764     * any connection. 
     1765     */ 
     1766    do { 
     1767        pjmedia_conf_port_info port0_info; 
     1768        pjmedia_conf_port_info peer_info; 
     1769        unsigned peer_id; 
     1770        pj_bool_t need_reopen = PJ_FALSE; 
     1771        pj_status_t status; 
     1772 
     1773        peer_id = (source!=0)? source : sink; 
     1774        status = pjmedia_conf_get_port_info(pjsua_var.mconf, peer_id,  
     1775                                            &peer_info); 
     1776        pj_assert(status == PJ_SUCCESS); 
     1777 
     1778        status = pjmedia_conf_get_port_info(pjsua_var.mconf, 0, &port0_info); 
     1779        pj_assert(status == PJ_SUCCESS); 
     1780 
     1781        /* Check if sound device is instantiated. */ 
     1782        need_reopen = (pjsua_var.snd_port==NULL && pjsua_var.null_snd==NULL &&  
     1783                      !pjsua_var.no_snd); 
     1784 
     1785        /* Check if sound device need to reopen because it needs to modify  
     1786         * settings to match its peer. Sound device must be idle in this case  
     1787         * though. 
     1788         */ 
     1789        if (!need_reopen &&  
     1790            port0_info.listener_cnt==0 && port0_info.transmitter_cnt==0)  
     1791        { 
     1792            need_reopen = (peer_info.format.id != port0_info.format.id || 
     1793                           peer_info.format.bitrate != port0_info.format.bitrate || 
     1794                           peer_info.clock_rate != port0_info.clock_rate || 
     1795                           peer_info.channel_count != port0_info.channel_count); 
     1796        } 
     1797 
     1798        if (need_reopen) { 
     1799            pjmedia_snd_setting setting; 
     1800 
     1801            pj_bzero(&setting, sizeof(setting)); 
     1802            setting.format = peer_info.format; 
     1803            setting.plc = PJ_FALSE; 
     1804            setting.route = PJMEDIA_SND_ROUTE_DEFAULT; 
     1805             
     1806            status = open_snd_dev_ext(pjsua_var.cap_dev, pjsua_var.play_dev, 
     1807                                      peer_info.clock_rate, 
     1808                                      peer_info.channel_count, 
     1809                                      peer_info.samples_per_frame, 
     1810                                      &setting); 
     1811            if (status != PJ_SUCCESS) { 
     1812                pjsua_perror(THIS_FILE, "Error opening sound device", status); 
     1813                return status; 
     1814            } 
     1815        } 
     1816    } while(0); 
     1817 
     1818#else 
     1819 
    16271820    /* Create sound port if none is instantiated */ 
    16281821    if (pjsua_var.snd_port==NULL && pjsua_var.null_snd==NULL &&  
     
    16371830        } 
    16381831    } 
     1832 
     1833#endif 
    16391834 
    16401835    return pjmedia_conf_connect_port(pjsua_var.mconf, source, sink, 0); 
     
    21322327    return PJ_SUCCESS; 
    21332328} 
    2134  
    2135  
    2136 /* Close existing sound device */ 
    2137 static void close_snd_dev(void) 
    2138 { 
    2139     /* Close sound device */ 
    2140     if (pjsua_var.snd_port) { 
    2141         const pjmedia_snd_dev_info *cap_info, *play_info; 
    2142  
    2143         cap_info = pjmedia_snd_get_dev_info(pjsua_var.cap_dev); 
    2144         play_info = pjmedia_snd_get_dev_info(pjsua_var.play_dev); 
    2145  
    2146         PJ_LOG(4,(THIS_FILE, "Closing %s sound playback device and " 
    2147                              "%s sound capture device", 
    2148                              play_info->name, cap_info->name)); 
    2149  
    2150         pjmedia_snd_port_disconnect(pjsua_var.snd_port); 
    2151         pjmedia_snd_port_destroy(pjsua_var.snd_port); 
    2152         pjsua_var.snd_port = NULL; 
    2153     } 
    2154  
    2155     /* Close null sound device */ 
    2156     if (pjsua_var.null_snd) { 
    2157         PJ_LOG(4,(THIS_FILE, "Closing null sound device..")); 
    2158         pjmedia_master_port_destroy(pjsua_var.null_snd, PJ_FALSE); 
    2159         pjsua_var.null_snd = NULL; 
    2160     } 
    2161  
    2162     if (pjsua_var.snd_pool)  
    2163         pj_pool_release(pjsua_var.snd_pool); 
    2164     pjsua_var.snd_pool = NULL; 
    2165 } 
    2166  
    21672329/* 
    21682330 * Select or change sound device. Application may call this function at 
     
    24192581 
    24202582 
     2583/* 
     2584 * Set sound device route. 
     2585 */ 
     2586PJ_DEF(pj_status_t) pjsua_set_snd_route(pjmedia_snd_route route) 
     2587{ 
     2588    PJ_UNUSED_ARG(route); 
     2589 
     2590    PJ_TODO(IMPLEMENT_SETTING_AUDIO_ROUTE); 
     2591    return PJ_ENOTSUP; 
     2592} 
     2593 
    24212594/***************************************************************************** 
    24222595 * Codecs. 
Note: See TracChangeset for help on using the changeset viewer.