Ignore:
Timestamp:
Feb 13, 2009 11:53:12 AM (12 years ago)
Author:
bennylp
Message:

Added APS-Direct emulation to sound port and pjsua_app.c, also fixed miscellaneous compilation warnings

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/branches/projects/aps-direct/pjmedia/src/pjmedia/sound_port.c

    r2438 r2452  
    1919 */ 
    2020#include <pjmedia/sound_port.h> 
     21#include <pjmedia/alaw_ulaw.h> 
    2122#include <pjmedia/delaybuf.h> 
    2223#include <pjmedia/echo.h> 
     
    3637//#define TEST_OVERFLOW_UNDERFLOW 
    3738 
    38  
    3939struct pjmedia_snd_port 
    4040{ 
     
    6363    pjmedia_delay_buf   *delay_buf; 
    6464#endif 
     65 
     66    /* Encoded sound emulation */ 
     67#if !defined(PJMEDIA_SND_SUPPORT_OPEN2) || !PJMEDIA_SND_SUPPORT_OPEN2 
     68    unsigned             frm_buf_size; 
     69    pj_uint8_t          *put_frm_buf; 
     70    pj_uint8_t          *get_frm_buf; 
     71#endif 
    6572}; 
    6673 
     
    7986    pj_status_t status; 
    8087 
    81     /* We're risking accessing the port without holding any mutex. 
    82      * It's possible that port is disconnected then destroyed while 
    83      * we're trying to access it. 
    84      * But in the name of performance, we'll try this approach until 
    85      * someone complains when it crashes. 
    86      */ 
    8788    port = snd_port->port; 
    8889    if (port == NULL) 
     
    198199    pjmedia_frame frame; 
    199200 
    200     /* We're risking accessing the port without holding any mutex. 
    201      * It's possible that port is disconnected then destroyed while 
    202      * we're trying to access it. 
    203      * But in the name of performance, we'll try this approach until 
    204      * someone complains when it crashes. 
    205      */ 
    206201    port = snd_port->port; 
    207202    if (port == NULL) 
     
    245240                               /* out */  unsigned size) 
    246241{ 
     242#if defined(PJMEDIA_SND_SUPPORT_OPEN2) && PJMEDIA_SND_SUPPORT_OPEN2!=0 
     243    /* This is the version to use when the sound device supports 
     244     * open2(). 
     245     */ 
    247246    pjmedia_snd_port *snd_port = (pjmedia_snd_port*) user_data; 
    248247    pjmedia_port *port; 
     
    253252    PJ_UNUSED_ARG(timestamp); 
    254253 
    255     /* We're risking accessing the port without holding any mutex. 
    256      * It's possible that port is disconnected then destroyed while 
    257      * we're trying to access it. 
    258      * But in the name of performance, we'll try this approach until 
    259      * someone complains when it crashes. 
    260      */ 
    261254    port = snd_port->port; 
    262255    if (port == NULL) { 
     
    268261 
    269262    return status; 
     263#else 
     264    /* This is the emulation version */ 
     265    pjmedia_snd_port *snd_port = (pjmedia_snd_port*) user_data; 
     266    pjmedia_port *port = snd_port->port; 
     267    pjmedia_frame_ext *fx = (pjmedia_frame_ext*) snd_port->get_frm_buf; 
     268    pj_status_t status; 
     269 
     270    if (port==NULL) { 
     271        goto no_frame; 
     272    } 
     273 
     274    pj_bzero(fx, sizeof(*fx)); 
     275    fx->base.type = PJMEDIA_FRAME_TYPE_NONE; 
     276    fx->base.buf = ((pj_uint8_t*)fx) + sizeof(*fx); 
     277    fx->base.size = snd_port->frm_buf_size - sizeof(*fx); 
     278    fx->base.timestamp.u32.hi = 0; 
     279    fx->base.timestamp.u32.lo = timestamp; 
     280 
     281    status = pjmedia_port_get_frame(port, &fx->base); 
     282    if (status != PJ_SUCCESS) 
     283        goto no_frame; 
     284 
     285    if (fx->base.type == PJMEDIA_FRAME_TYPE_AUDIO) { 
     286        pj_assert(fx->base.size == size); 
     287        pj_memcpy(output, fx->base.buf, size); 
     288    } else if (fx->base.type == PJMEDIA_FRAME_TYPE_EXTENDED) { 
     289        void (*decoder)(pj_int16_t*, const pj_uint8_t*, pj_size_t) = NULL; 
     290        unsigned i, size_decoded; 
     291 
     292        switch (snd_port->setting.format.u32) { 
     293        case PJMEDIA_FOURCC_PCMA: 
     294            decoder = &pjmedia_alaw_decode; 
     295            break; 
     296        case PJMEDIA_FOURCC_PCMU: 
     297            decoder = &pjmedia_ulaw_decode; 
     298            break; 
     299        default: 
     300            PJ_LOG(1,(THIS_FILE, "Unsupported format %d",  
     301                      snd_port->setting.format.u32)); 
     302            goto no_frame; 
     303        } 
     304 
     305        if (fx->samples_cnt > size>>1) { 
     306            PJ_LOG(4,(THIS_FILE, "Frame too large by %d samples",  
     307                      fx->samples_cnt - (size>>1))); 
     308        } else if (fx->samples_cnt < size>>1) { 
     309            PJ_LOG(4,(THIS_FILE, "Not enough frame by %d samples",  
     310                      (size>>1) - fx->samples_cnt)); 
     311        } 
     312 
     313        for (i=0, size_decoded=0;  
     314             i<fx->subframe_cnt && size_decoded<size;  
     315             ++i)  
     316        { 
     317            pjmedia_frame_ext_subframe *subfrm; 
     318 
     319            subfrm = pjmedia_frame_ext_get_subframe(fx, i);          
     320 
     321            if ((subfrm->bitlen>>3) > (int)(size-size_decoded)) { 
     322                subfrm->bitlen = (pj_uint16_t)((size-size_decoded) << 3); 
     323            } 
     324 
     325            (*decoder)((short*)((pj_uint8_t*)output + size_decoded), 
     326                       subfrm->data, subfrm->bitlen>>3); 
     327 
     328            size_decoded += (subfrm->bitlen>>3) << 1; 
     329        } 
     330 
     331        if (size_decoded < size) { 
     332            pj_bzero((pj_uint8_t*)output + size_decoded, size-size_decoded); 
     333        } 
     334 
     335    } else { 
     336        goto no_frame; 
     337    } 
     338 
     339    return PJ_SUCCESS; 
     340 
     341no_frame: 
     342    pj_bzero(output, size); 
     343    return PJ_SUCCESS; 
     344 
     345#endif  /* PJMEDIA_SND_SUPPORT_OPEN2 */ 
    270346} 
    271347 
     
    280356                              /* in*/    unsigned size) 
    281357{ 
     358#if defined(PJMEDIA_SND_SUPPORT_OPEN2) && PJMEDIA_SND_SUPPORT_OPEN2!=0 
     359    /* This is the version to use when the sound device supports 
     360     * open2(). 
     361     */ 
    282362    pjmedia_snd_port *snd_port = (pjmedia_snd_port*) user_data; 
    283363    pjmedia_port *port; 
     
    287367    PJ_UNUSED_ARG(timestamp); 
    288368 
    289     /* We're risking accessing the port without holding any mutex. 
    290      * It's possible that port is disconnected then destroyed while 
    291      * we're trying to access it. 
    292      * But in the name of performance, we'll try this approach until 
    293      * someone complains when it crashes. 
    294      */ 
    295369    port = snd_port->port; 
    296370    if (port == NULL) 
     
    300374 
    301375    return PJ_SUCCESS; 
     376#else 
     377    pjmedia_snd_port *snd_port = (pjmedia_snd_port*) user_data; 
     378    pjmedia_port *port = snd_port->port; 
     379    pjmedia_frame_ext *fx = (pjmedia_frame_ext*) snd_port->put_frm_buf; 
     380    void (*encoder)(pj_uint8_t*, const pj_int16_t*, pj_size_t) = NULL; 
     381 
     382    if (port==NULL) 
     383        return PJ_SUCCESS; 
     384 
     385    pj_bzero(fx, sizeof(*fx)); 
     386    fx->base.buf = NULL; 
     387    fx->base.size = snd_port->frm_buf_size - sizeof(*fx); 
     388    fx->base.type = PJMEDIA_FRAME_TYPE_EXTENDED; 
     389    fx->base.timestamp.u32.lo = timestamp; 
     390 
     391    switch (snd_port->setting.format.u32) { 
     392    case PJMEDIA_FOURCC_PCMA: 
     393        encoder = &pjmedia_alaw_encode; 
     394        break; 
     395    case PJMEDIA_FOURCC_PCMU: 
     396        encoder = &pjmedia_ulaw_encode; 
     397        break; 
     398    default: 
     399        PJ_LOG(1,(THIS_FILE, "Unsupported format %d",  
     400                  snd_port->setting.format.u32)); 
     401        return PJ_SUCCESS; 
     402    } 
     403 
     404    (*encoder)((pj_uint8_t*)input, (pj_int16_t*)input, size >> 1); 
     405 
     406    pjmedia_frame_ext_append_subframe(fx, input, (size >> 1) << 3,  
     407                                      size >> 1); 
     408    pjmedia_port_put_frame(port, &fx->base); 
     409 
     410    return PJ_SUCCESS; 
     411#endif 
    302412} 
    303413 
     
    332442    } 
    333443 
     444#if defined(PJMEDIA_SND_SUPPORT_OPEN2) && PJMEDIA_SND_SUPPORT_OPEN2!=0 
    334445    status = pjmedia_snd_open2( snd_port->dir, 
    335446                                snd_port->rec_id,  
     
    344455                                &snd_port->setting, 
    345456                                &snd_port->snd_stream); 
     457#else 
     458    status = pjmedia_snd_open(  snd_port->rec_id,  
     459                                snd_port->play_id, 
     460                                snd_port->clock_rate, 
     461                                snd_port->channel_count, 
     462                                snd_port->samples_per_frame, 
     463                                snd_port->bits_per_sample, 
     464                                snd_rec_cb, 
     465                                snd_play_cb, 
     466                                snd_port, 
     467                                &snd_port->snd_stream); 
     468#endif 
    346469 
    347470    if (status != PJ_SUCCESS) 
     
    572695    snd_port->samples_per_frame = samples_per_frame; 
    573696    snd_port->bits_per_sample = bits_per_sample; 
    574     snd_port->setting = *setting; 
     697    pj_memcpy(&snd_port->setting, setting, sizeof(*setting)); 
    575698     
    576699#if PJMEDIA_SOUND_USE_DELAYBUF 
     
    589712                                          0, &snd_port->delay_buf); 
    590713        PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); 
     714    } 
     715#endif 
     716 
     717#if !defined(PJMEDIA_SND_SUPPORT_OPEN2) || PJMEDIA_SND_SUPPORT_OPEN2==0 
     718    /* For devices that doesn't support open2(), enable simulation */ 
     719    if (snd_port->setting.format.u32 != 0 && 
     720        snd_port->setting.format.u32 != PJMEDIA_FOURCC_L16)  
     721    { 
     722        snd_port->frm_buf_size = sizeof(pjmedia_frame_ext) +  
     723                                 (samples_per_frame >> 1) + 
     724                                 16 * sizeof(pjmedia_frame_ext_subframe); 
     725        snd_port->put_frm_buf = (pj_uint8_t*) 
     726                                pj_pool_alloc(pool, snd_port->frm_buf_size); 
     727        snd_port->get_frm_buf = (pj_uint8_t*) 
     728                                pj_pool_alloc(pool, snd_port->frm_buf_size); 
    591729    } 
    592730#endif 
Note: See TracChangeset for help on using the changeset viewer.