Changeset 2470


Ignore:
Timestamp:
Feb 22, 2009 5:15:34 PM (11 years ago)
Author:
bennylp
Message:
  • Added pjmedia-audiodev/config.h
  • Added a bit of doxygen documentation
  • Added support for PCMA/PCMU codecs in wmme_dev.c
Location:
pjproject/branches/projects/aps-direct/pjmedia
Files:
1 added
7 edited

Legend:

Unmodified
Added
Removed
  • pjproject/branches/projects/aps-direct/pjmedia/build/pjmedia_audiodev.dsp

    r2468 r2470  
    130130SOURCE="..\include\pjmedia-audiodev\audiotest.h" 
    131131# End Source File 
     132# Begin Source File 
     133 
     134SOURCE="..\include\pjmedia-audiodev\config.h" 
     135# End Source File 
    132136# End Group 
    133137# End Target 
  • pjproject/branches/projects/aps-direct/pjmedia/include/pjmedia-audiodev/audiodev.h

    r2469 r2470  
    2525 * @brief Audio device API. 
    2626 */ 
     27#include <pjmedia-audiodev/config.h> 
    2728#include <pjmedia/port.h> 
    2829#include <pj/pool.h> 
     
    3233 
    3334/** 
    34  * @defgroup PJMED_AUD_DEV Audio device API 
    35  * @ingroup PJMED_AUD_PORT 
    36  * @brief API to work with audio devices and to implement new audio device backends. 
    37  * @{ 
    38  * 
    39  * The audio device API contains two parts: 
    40  *  - the base API, for both applications and audio device implementors, and 
    41  *  - the API for audio device implementors, for extending the audio device 
    42  *    framework with new audio device drivers. 
    43  * 
    44  * @} 
    45  */ 
    46  
    47 /** 
    48  * @defgroup PJMED_AUD_DEV_API Base Audio Device API 
    49  * @ingroup PJMED_AUD_DEV 
    50  * @brief The base API, for both applications and audio device implementors 
     35 * @defgroup s2_audio_device_reference Audio Device API Reference 
     36 * @ingroup audio_device_api 
     37 * @brief API Reference 
    5138 * @{ 
    5239 */ 
     
    222209 
    223210/** 
    224  * Device information structure returned by #pjmedia_aud_get_dev_info. 
     211 * Device information structure returned by #pjmedia_aud_dev_get_info(). 
    225212 */ 
    226213typedef struct pjmedia_aud_dev_info 
     
    498485 * @param drv_name      The driver name. 
    499486 * @param dev_name      The device name. 
     487 * @param id            Pointer to store the returned device ID. 
    500488 * 
    501489 * @return              PJ_SUCCESS if the device can be found. 
     
    530518 * @param user_data     Arbitrary user data, which will be given back in the 
    531519 *                      callbacks. 
    532  * @param p_aud_strm    Pointer to receive the audio stream. 
     520 * @param p_strm        Pointer to receive the audio stream. 
    533521 * 
    534522 * @return              PJ_SUCCESS on successful operation or the appropriate 
     
    635623#define PJMEDIA_EAUD_SYSERR     -1 
    636624 
    637  
    638 /** 
    639  * @) 
     625/* Bad or invalid format */ 
     626#define PJMEDIA_EAUD_BADFORMAT  -1 
     627 
     628/** 
     629 * @} 
    640630 */ 
    641631 
  • pjproject/branches/projects/aps-direct/pjmedia/include/pjmedia-audiodev/audiodev_imp.h

    r2469 r2470  
    2424 
    2525/** 
    26  * @defgroup PJMED_AUD_DEV_IMP_API Audio Device Implementors API 
    27  * @ingroup PJMED_AUD_DEV 
     26 * @defgroup s8_audio_device_implementors_api Audio Device Implementors API 
     27 * @ingroup audio_device_api 
    2828 * @brief API for audio device implementors 
    2929 * @{ 
  • pjproject/branches/projects/aps-direct/pjmedia/include/pjmedia-audiodev/audiotest.h

    r2468 r2470  
    3131 
    3232/** 
    33  * @defgroup PJMED_AUD_TEST Audio tests utility. 
    34  * @ingroup PJMED_AUD_PORT 
     33 * @defgroup s30_audio_test_utility Audio tests utility. 
     34 * @ingroup audio_device_api 
    3535 * @brief Audio test utility. 
    3636 * @{ 
     
    9696 
    9797/** 
    98  * @) 
     98 * @} 
    9999 */ 
    100100 
  • pjproject/branches/projects/aps-direct/pjmedia/include/pjmedia/port.h

    r2456 r2470  
    332332 */ 
    333333PJ_INLINE(pjmedia_frame_ext_subframe*)  
    334           pjmedia_frame_ext_get_subframe(const pjmedia_frame_ext *frm, 
    335                                          unsigned n) 
     334pjmedia_frame_ext_get_subframe(const pjmedia_frame_ext *frm, unsigned n) 
    336335{ 
    337336    pjmedia_frame_ext_subframe *sf = NULL; 
     
    354353         
    355354/** 
     355 * Extract all frame payload to the specified buffer.  
     356 * 
     357 * @param frm               The frame. 
     358 * @param dst               Destination buffer. 
     359 * @param maxsize           Maximum size to copy (i.e. the size of the 
     360 *                          destination buffer). 
     361 * 
     362 * @return                  Total size of payload copied. 
     363 */ 
     364PJ_INLINE(unsigned)  
     365pjmedia_frame_ext_copy_payload(const pjmedia_frame_ext *frm, 
     366                               void *dst,  
     367                               unsigned maxlen) 
     368{ 
     369    unsigned i, copied=0; 
     370    for (i=0; i<frm->subframe_cnt; ++i) { 
     371        pjmedia_frame_ext_subframe *sf; 
     372        unsigned sz; 
     373 
     374        sf = pjmedia_frame_ext_get_subframe(frm, i); 
     375        if (!sf) 
     376            continue; 
     377 
     378        sz = ((sf->bitlen + 7) >> 3); 
     379        if (sz + copied > maxlen) 
     380            break; 
     381 
     382        pj_memcpy(((pj_uint8_t*)dst) + copied, sf->data, sz); 
     383        copied += sz; 
     384    } 
     385    return copied; 
     386} 
     387 
     388 
     389/** 
    356390 * Pop out first n subframes from #pjmedia_frame_ext. 
    357391 * 
     
    362396 */ 
    363397PJ_INLINE(pj_status_t)  
    364           pjmedia_frame_ext_pop_subframes(pjmedia_frame_ext *frm, unsigned n) 
     398pjmedia_frame_ext_pop_subframes(pjmedia_frame_ext *frm, unsigned n) 
    365399{ 
    366400    pjmedia_frame_ext_subframe *sf; 
     
    387421    return PJ_SUCCESS; 
    388422} 
    389          
     423 
    390424/** 
    391425 * Port interface. 
  • pjproject/branches/projects/aps-direct/pjmedia/src/pjmedia-audiodev/audiodev.c

    r2469 r2470  
    2121#include <pj/errno.h> 
    2222#include <pj/log.h> 
     23#include <pj/pool.h> 
    2324#include <pj/string.h> 
    2425 
     
    6364 
    6465/* extern functions to create factories */ 
     66#if PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO 
    6567pjmedia_aud_dev_factory* pjmedia_pa_factory(pj_pool_factory *pf); 
     68#endif 
     69 
     70#if PJMEDIA_AUDIO_DEV_HAS_WMME 
    6671pjmedia_aud_dev_factory* pjmedia_wmme_factory(pj_pool_factory *pf); 
     72#endif 
     73 
    6774 
    6875#define MAX_DRIVERS     16 
     
    219226 
    220227    /* Register creation functions */ 
     228#if PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO 
    221229    aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_pa_factory; 
     230#endif 
     231#if PJMEDIA_AUDIO_DEV_HAS_WMME 
    222232    aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_wmme_factory; 
     233#endif 
    223234 
    224235    /* Initialize each factory and build the device ID list */ 
  • pjproject/branches/projects/aps-direct/pjmedia/src/pjmedia-audiodev/wmme_dev.c

    r2469 r2470  
    3131#include <windows.h> 
    3232#include <mmsystem.h> 
     33#include <mmreg.h> 
    3334 
    3435#ifdef _MSC_VER 
     
    103104    void                *buffer;            /**< Temp. frame buffer.   */ 
    104105    unsigned             clock_rate;        /**< Clock rate.           */ 
     106    unsigned             bytes_per_frame;   /**< Bytes per frame       */ 
    105107    unsigned             samples_per_frame; /**< Samples per frame.    */ 
    106108    unsigned             bits_per_sample;   /**< Bits per sample.      */ 
    107109    unsigned             channel_count;     /**< Channel count.        */ 
     110 
     111    pjmedia_frame_ext   *xfrm;              /**< Extended frame buffer */ 
     112    unsigned             xfrm_size;         /**< Total ext frm size    */ 
    108113 
    109114    pj_thread_t         *thread;            /**< Thread handle.        */ 
     
    193198/* Internal: build device info from WAVEINCAPS/WAVEOUTCAPS */ 
    194199static void build_dev_info(UINT deviceId, struct wmme_dev_info *wdi,  
    195                            WAVEINCAPS *wic, WAVEOUTCAPS *woc) 
     200                           const WAVEINCAPS *wic, const WAVEOUTCAPS *woc) 
    196201{ 
    197202#define WIC_WOC(wic,woc,field)  (wic? wic->field : woc->field) 
     
    205210        wdi->info.name[sizeof(wdi->info.name)-1] = '\0'; 
    206211    } else { 
    207         pj_char_t *szPname = WIC_WOC(wic, woc, szPname); 
     212        const pj_char_t *szPname = WIC_WOC(wic, woc, szPname); 
    208213        PJ_DECL_ANSI_TEMP_BUF(wTmp, sizeof(wdi->info.name)); 
    209214         
     
    246251        } 
    247252    } 
     253 
     254    /* Extended formats */ 
     255    wdi->info.caps |= PJMEDIA_AUD_DEV_CAP_EXT_FORMAT; 
     256    wdi->info.ext_fmt_cnt = 2; 
     257    wdi->info.ext_fmt[0].id = PJMEDIA_FORMAT_PCMU; 
     258    wdi->info.ext_fmt[0].bitrate = 64000; 
     259    wdi->info.ext_fmt[0].vad = 0; 
     260    wdi->info.ext_fmt[1].id = PJMEDIA_FORMAT_PCMA; 
     261    wdi->info.ext_fmt[1].bitrate = 64000; 
     262    wdi->info.ext_fmt[1].vad = 0; 
    248263} 
    249264 
     
    280295                                  sizeof(struct wmme_dev_info)); 
    281296 
    282     if (devCount) { 
     297    if (inputDeviceCount && outputDeviceCount) { 
    283298        /* Attempt to add WAVE_MAPPER as input and output device */ 
    284299        WAVEINCAPS wic; 
     
    435450 
    436451/* Internal: init WAVEFORMATEX */ 
    437 static void init_waveformatex (LPWAVEFORMATEX pcmwf,  
    438                                unsigned clock_rate, 
    439                                unsigned channel_count) 
    440 { 
    441     pj_bzero(pcmwf, sizeof(PCMWAVEFORMAT));  
    442     pcmwf->wFormatTag = WAVE_FORMAT_PCM;  
    443     pcmwf->nChannels = (pj_uint16_t)channel_count; 
    444     pcmwf->nSamplesPerSec = clock_rate; 
    445     pcmwf->nBlockAlign = (pj_uint16_t)(channel_count * BYTES_PER_SAMPLE); 
    446     pcmwf->nAvgBytesPerSec = clock_rate * channel_count * BYTES_PER_SAMPLE; 
    447     pcmwf->wBitsPerSample = BITS_PER_SAMPLE; 
     452static pj_status_t init_waveformatex(LPWAVEFORMATEX wfx,  
     453                                     const pjmedia_aud_param *prm) 
     454{ 
     455 
     456    pj_bzero(wfx, sizeof(PCMWAVEFORMAT));  
     457    if (prm->ext_fmt.id == PJMEDIA_FORMAT_L16) { 
     458        wfx->wFormatTag = WAVE_FORMAT_PCM;  
     459        wfx->nChannels = (pj_uint16_t)prm->channel_count; 
     460        wfx->nSamplesPerSec = prm->clock_rate; 
     461        wfx->nBlockAlign = (pj_uint16_t)(prm->channel_count *  
     462                                         BYTES_PER_SAMPLE); 
     463        wfx->nAvgBytesPerSec = prm->clock_rate * prm->channel_count *  
     464                               BYTES_PER_SAMPLE; 
     465        wfx->wBitsPerSample = BITS_PER_SAMPLE; 
     466 
     467        return PJ_SUCCESS; 
     468 
     469    } else if ((prm->flags & PJMEDIA_AUD_DEV_CAP_EXT_FORMAT) && 
     470               (prm->ext_fmt.id == PJMEDIA_FORMAT_PCMA || 
     471                prm->ext_fmt.id == PJMEDIA_FORMAT_PCMU)) 
     472    { 
     473        unsigned ptime; 
     474 
     475        ptime = prm->samples_per_frame * 1000 /  
     476                (prm->clock_rate * prm->channel_count); 
     477        wfx->wFormatTag = (pj_uint16_t) 
     478                          ((prm->ext_fmt.id==PJMEDIA_FORMAT_PCMA) ? 
     479                            WAVE_FORMAT_ALAW : WAVE_FORMAT_MULAW);   
     480        wfx->nChannels = (pj_uint16_t)prm->channel_count; 
     481        wfx->nSamplesPerSec = prm->clock_rate; 
     482        wfx->nAvgBytesPerSec = prm->clock_rate * prm->channel_count; 
     483        wfx->nBlockAlign = (pj_uint16_t)(wfx->nAvgBytesPerSec * ptime / 
     484                                         1000); 
     485        wfx->wBitsPerSample = 8; 
     486        wfx->cbSize = 0; 
     487 
     488        return PJ_SUCCESS; 
     489 
     490    } else { 
     491 
     492        return PJMEDIA_EAUD_BADFORMAT; 
     493 
     494    } 
    448495} 
    449496 
     
    452499static pj_status_t init_player_stream(  struct wmme_factory *wf, 
    453500                                        pj_pool_t *pool, 
     501                                        struct wmme_stream *parent, 
    454502                                        struct wmme_channel *wmme_strm, 
    455                                         unsigned dev_id, 
    456                                         unsigned clock_rate, 
    457                                         unsigned channel_count, 
    458                                         unsigned samples_per_frame, 
     503                                        const pjmedia_aud_param *prm, 
    459504                                        unsigned buffer_count) 
    460505{ 
    461506    MMRESULT mr; 
    462     WAVEFORMATEX pcmwf;  
    463     unsigned bytes_per_frame; 
    464     unsigned i; 
    465  
    466     PJ_ASSERT_RETURN(dev_id < wf->dev_count, PJ_EINVAL); 
     507    WAVEFORMATEX wfx;  
     508    unsigned i, ptime; 
     509    pj_status_t status; 
     510 
     511    PJ_ASSERT_RETURN(prm->play_id < (int)wf->dev_count, PJ_EINVAL); 
    467512 
    468513    /* 
     
    476521     * Set up wave format structure for opening the device. 
    477522     */ 
    478     init_waveformatex(&pcmwf, clock_rate, channel_count); 
    479     bytes_per_frame = samples_per_frame * BYTES_PER_SAMPLE; 
     523    status = init_waveformatex(&wfx, prm); 
     524    if (status != PJ_SUCCESS) 
     525        return status; 
     526 
     527    ptime = prm->samples_per_frame * 1000 /  
     528            (prm->clock_rate * prm->channel_count); 
     529    ptime = prm->samples_per_frame * 1000 /  
     530            (prm->clock_rate * prm->channel_count); 
     531    parent->bytes_per_frame = wfx.nAvgBytesPerSec / ptime; 
    480532 
    481533    /* 
    482534     * Open wave device. 
    483535     */ 
    484     mr = waveOutOpen(&wmme_strm->hWave.Out, wf->dev_info[dev_id].deviceId,  
    485                      &pcmwf, (DWORD)wmme_strm->hEvent, 0, CALLBACK_EVENT); 
     536    mr = waveOutOpen(&wmme_strm->hWave.Out,  
     537                     wf->dev_info[prm->play_id].deviceId, 
     538                     &wfx, (DWORD)wmme_strm->hEvent, 0, CALLBACK_EVENT); 
    486539    if (mr != MMSYSERR_NOERROR) { 
    487540        return CONVERT_MM_ERROR(mr); 
     
    500553                         pj_pool_zalloc(pool, sizeof(WAVEHDR) * buffer_count); 
    501554    for (i = 0; i < buffer_count; ++i) { 
    502         wmme_strm->WaveHdr[i].lpData = pj_pool_zalloc(pool, bytes_per_frame); 
    503         wmme_strm->WaveHdr[i].dwBufferLength = bytes_per_frame; 
     555        wmme_strm->WaveHdr[i].lpData = pj_pool_zalloc(pool,  
     556                                                      parent->bytes_per_frame); 
     557        wmme_strm->WaveHdr[i].dwBufferLength = parent->bytes_per_frame; 
    504558        mr = waveOutPrepareHeader(wmme_strm->hWave.Out,  
    505559                                  &(wmme_strm->WaveHdr[i]), 
     
    523577               " WaveAPI Sound player \"%s\" initialized (clock_rate=%d, " 
    524578               "channel_count=%d, samples_per_frame=%d (%dms))", 
    525                wf->dev_info[dev_id].info.name, 
    526                clock_rate, channel_count, samples_per_frame, 
    527                samples_per_frame * 1000 / clock_rate)); 
     579               wf->dev_info[prm->play_id].info.name, 
     580               prm->clock_rate, prm->channel_count, prm->samples_per_frame, 
     581               prm->samples_per_frame * 1000 / prm->clock_rate)); 
    528582 
    529583    return PJ_SUCCESS; 
     
    534588static pj_status_t init_capture_stream( struct wmme_factory *wf, 
    535589                                        pj_pool_t *pool, 
     590                                        struct wmme_stream *parent, 
    536591                                        struct wmme_channel *wmme_strm, 
    537                                         unsigned dev_id, 
    538                                         unsigned clock_rate, 
    539                                         unsigned channel_count, 
    540                                         unsigned samples_per_frame, 
     592                                        const pjmedia_aud_param *prm, 
    541593                                        unsigned buffer_count) 
    542594{ 
    543595    MMRESULT mr; 
    544     WAVEFORMATEX pcmwf;  
    545     unsigned bytes_per_frame; 
    546     unsigned i; 
    547  
    548     PJ_ASSERT_RETURN(dev_id < wf->dev_count, PJ_EINVAL); 
     596    WAVEFORMATEX wfx;  
     597    unsigned i, ptime; 
     598 
     599    PJ_ASSERT_RETURN(prm->rec_id < (int)wf->dev_count, PJ_EINVAL); 
    549600 
    550601    /* 
     
    559610     * Set up wave format structure for opening the device. 
    560611     */ 
    561     init_waveformatex(&pcmwf, clock_rate, channel_count); 
    562     bytes_per_frame = samples_per_frame * BYTES_PER_SAMPLE; 
     612    init_waveformatex(&wfx, prm); 
     613    ptime = prm->samples_per_frame * 1000 /  
     614            (prm->clock_rate * prm->channel_count); 
     615    parent->bytes_per_frame = wfx.nAvgBytesPerSec / ptime; 
    563616 
    564617    /* 
    565618     * Open wave device. 
    566619     */ 
    567     mr = waveInOpen(&wmme_strm->hWave.In, wf->dev_info[dev_id].deviceId,  
    568                     &pcmwf, (DWORD)wmme_strm->hEvent, 0, CALLBACK_EVENT); 
     620    mr = waveInOpen(&wmme_strm->hWave.In,  
     621                    wf->dev_info[prm->rec_id].deviceId,  
     622                    &wfx, (DWORD)wmme_strm->hEvent, 0, CALLBACK_EVENT); 
    569623    if (mr != MMSYSERR_NOERROR) { 
    570624        return CONVERT_MM_ERROR(mr); 
     
    577631                         pj_pool_zalloc(pool, sizeof(WAVEHDR) * buffer_count); 
    578632    for (i = 0; i < buffer_count; ++i) { 
    579         wmme_strm->WaveHdr[i].lpData = pj_pool_zalloc(pool, bytes_per_frame); 
    580         wmme_strm->WaveHdr[i].dwBufferLength = bytes_per_frame; 
     633        wmme_strm->WaveHdr[i].lpData = pj_pool_zalloc(pool,  
     634                                                      parent->bytes_per_frame); 
     635        wmme_strm->WaveHdr[i].dwBufferLength = parent->bytes_per_frame; 
    581636        mr = waveInPrepareHeader(wmme_strm->hWave.In,  
    582637                                 &(wmme_strm->WaveHdr[i]), 
     
    600655        " WaveAPI Sound recorder \"%s\" initialized (clock_rate=%d, " 
    601656        "channel_count=%d, samples_per_frame=%d (%dms))", 
    602         wf->dev_info[dev_id].info.name, 
    603         clock_rate, channel_count, samples_per_frame, 
    604         samples_per_frame * 1000 / clock_rate)); 
     657        wf->dev_info[prm->rec_id].info.name, 
     658        prm->clock_rate, prm->channel_count, prm->samples_per_frame, 
     659        prm->samples_per_frame * 1000 / prm->clock_rate)); 
    605660 
    606661    return PJ_SUCCESS; 
     
    614669    HANDLE events[3]; 
    615670    unsigned eventCount; 
    616     unsigned bytes_per_frame; 
    617671    pj_status_t status = PJ_SUCCESS; 
    618  
    619672 
    620673    eventCount = 0; 
     
    638691#endif 
    639692 
    640     /* Calculate bytes per frame */ 
    641     bytes_per_frame = strm->samples_per_frame * BYTES_PER_SAMPLE; 
    642  
    643693    /* 
    644694     * Loop while not signalled to quit, wait for event objects to be  
     
    677727        { 
    678728            struct wmme_channel *wmme_strm = &strm->play_strm; 
    679             MMRESULT mr = MMSYSERR_NOERROR; 
     729 
    680730            status = PJ_SUCCESS; 
    681731 
     
    688738            { 
    689739                void *buffer = wmme_strm->WaveHdr[wmme_strm->dwBufIdx].lpData; 
    690                 pjmedia_frame frame; 
     740                pjmedia_frame pcm_frame, *frame; 
     741                pj_bool_t has_frame = PJ_FALSE; 
    691742 
    692743                //PJ_LOG(5,(THIS_FILE, "Finished writing buffer %d",  
    693744                //        wmme_strm->dwBufIdx)); 
    694745 
    695                 frame.type = PJMEDIA_FRAME_TYPE_AUDIO; 
    696                 frame.size = bytes_per_frame; 
    697                 frame.buf = buffer; 
    698                 frame.timestamp.u64 = wmme_strm->timestamp.u64; 
    699                 frame.bit_info = 0; 
     746                if (strm->xfrm == NULL) { 
     747                    /* PCM mode */ 
     748                    frame = &pcm_frame; 
     749 
     750                    frame->type = PJMEDIA_FRAME_TYPE_AUDIO; 
     751                    frame->size = strm->bytes_per_frame; 
     752                    frame->buf = buffer; 
     753                    frame->timestamp.u64 = wmme_strm->timestamp.u64; 
     754                    frame->bit_info = 0; 
     755                } else { 
     756                    /* Codec mode */ 
     757                    frame = &strm->xfrm->base; 
     758 
     759                    strm->xfrm->base.type = PJMEDIA_FRAME_TYPE_EXTENDED; 
     760                    strm->xfrm->base.size = strm->bytes_per_frame; 
     761                    strm->xfrm->base.buf = NULL; 
     762                    strm->xfrm->base.timestamp.u64 = wmme_strm->timestamp.u64; 
     763                    strm->xfrm->base.bit_info = 0; 
     764                } 
    700765 
    701766                /* Get frame from application. */ 
    702                 status = (*strm->play_cb)(strm->user_data, &frame); 
     767                status = (*strm->play_cb)(strm->user_data, frame); 
    703768 
    704769                if (status != PJ_SUCCESS) 
    705770                    break; 
    706771 
    707                 if (frame.type != PJMEDIA_FRAME_TYPE_AUDIO) { 
    708                     pj_bzero(buffer, bytes_per_frame); 
     772                if (strm->xfrm == NULL) { 
     773                    /* PCM mode */ 
     774                    if (frame->type == PJMEDIA_FRAME_TYPE_NONE) { 
     775                        pj_bzero(buffer, strm->bytes_per_frame); 
     776                        has_frame = PJ_TRUE; 
     777                    } else if (frame->type == PJMEDIA_FRAME_TYPE_EXTENDED) { 
     778                        pj_assert(!"Frame type not supported"); 
     779                    } else if (frame->type == PJMEDIA_FRAME_TYPE_AUDIO) { 
     780                        has_frame = PJ_TRUE; 
     781                    } else { 
     782                        pj_assert(!"Frame type not supported"); 
     783                    } 
     784                } else { 
     785                    /* Codec mode */ 
     786                    if (frame->type == PJMEDIA_FRAME_TYPE_NONE) { 
     787                        /* Not supported */ 
     788                    } else if (frame->type == PJMEDIA_FRAME_TYPE_EXTENDED) { 
     789                        unsigned sz; 
     790                        sz = pjmedia_frame_ext_copy_payload(strm->xfrm, 
     791                                                            buffer, 
     792                                                            strm->bytes_per_frame); 
     793                        pj_assert(sz == strm->bytes_per_frame); 
     794                    } else { 
     795                        pj_assert(!"Frame type not supported"); 
     796                    } 
    709797                } 
    710798 
    711799                /* Write to the device. */ 
    712                 mr = waveOutWrite(wmme_strm->hWave.Out,  
    713                                   &(wmme_strm->WaveHdr[wmme_strm->dwBufIdx]),  
    714                                   sizeof(WAVEHDR)); 
    715                 if (mr != MMSYSERR_NOERROR) 
    716                 { 
    717                     status = CONVERT_MM_ERROR(mr); 
    718                     break; 
     800                if (has_frame) { 
     801                    MMRESULT mr = MMSYSERR_NOERROR; 
     802 
     803                    mr = waveOutWrite(wmme_strm->hWave.Out,  
     804                                      &(wmme_strm->WaveHdr[wmme_strm->dwBufIdx]), 
     805                                      sizeof(WAVEHDR)); 
     806                    if (mr != MMSYSERR_NOERROR) { 
     807                        status = CONVERT_MM_ERROR(mr); 
     808                        break; 
     809                    } 
    719810                } 
    720811 
     
    766857                unsigned cap_len =  
    767858                        wmme_strm->WaveHdr[wmme_strm->dwBufIdx].dwBytesRecorded; 
    768                 pjmedia_frame frame; 
     859                pjmedia_frame pcm_frame, *frame; 
    769860 
    770861                /* 
     
    772863                          wmme_strm->dwBufIdx)); 
    773864                */ 
    774  
    775                 if (cap_len < bytes_per_frame) 
    776                     pj_bzero(buffer + cap_len, bytes_per_frame - cap_len); 
    777  
    778                 /* Copy the audio data out of the wave buffer. */ 
    779                 pj_memcpy(strm->buffer, buffer, bytes_per_frame); 
     865             
     866                if (strm->xfrm == NULL) { 
     867                    /* PCM mode */ 
     868                    if (cap_len < strm->bytes_per_frame) 
     869                        pj_bzero(buffer + cap_len,  
     870                                 strm->bytes_per_frame - cap_len); 
     871 
     872                    /* Copy the audio data out of the wave buffer. */ 
     873                    pj_memcpy(strm->buffer, buffer, strm->bytes_per_frame); 
     874 
     875                    /* Prepare frame */ 
     876                    frame = &pcm_frame; 
     877                    frame->type = PJMEDIA_FRAME_TYPE_AUDIO; 
     878                    frame->buf = strm->buffer; 
     879                    frame->size = strm->bytes_per_frame; 
     880                    frame->timestamp.u64 = wmme_strm->timestamp.u64; 
     881                    frame->bit_info = 0; 
     882 
     883                } else { 
     884                    /* Codec mode */ 
     885                    frame = &strm->xfrm->base; 
     886 
     887                    frame->type = PJMEDIA_FRAME_TYPE_EXTENDED; 
     888                    frame->buf = NULL; 
     889                    frame->size = strm->bytes_per_frame; 
     890                    frame->timestamp.u64 = wmme_strm->timestamp.u64; 
     891                    frame->bit_info = 0; 
     892 
     893                    strm->xfrm->samples_cnt = 0; 
     894                    strm->xfrm->subframe_cnt = 0; 
     895                    pjmedia_frame_ext_append_subframe(strm->xfrm, buffer, 
     896                                                      strm->bytes_per_frame *8, 
     897                                                      strm->samples_per_frame); 
     898                } 
    780899 
    781900                /* Re-add the buffer to the device. */ 
     
    788907                } 
    789908 
    790                 /* Prepare frame */ 
    791                 frame.type = PJMEDIA_FRAME_TYPE_AUDIO; 
    792                 frame.buf = strm->buffer; 
    793                 frame.size = bytes_per_frame; 
    794                 frame.timestamp.u64 = wmme_strm->timestamp.u64; 
    795                 frame.bit_info = 0; 
    796909 
    797910                /* Call callback */ 
    798                 status = (*strm->rec_cb)(strm->user_data, &frame); 
     911                status = (*strm->rec_cb)(strm->user_data, frame); 
    799912                if (status != PJ_SUCCESS) 
    800913                    break; 
     
    866979 
    867980        status = init_player_stream(wf, strm->pool, 
     981                                    strm, 
    868982                                    &strm->play_strm, 
    869                                     param->play_id, 
    870                                     param->clock_rate, 
    871                                     param->channel_count, 
    872                                     param->samples_per_frame, 
     983                                    param, 
    873984                                    buf_count); 
    874985 
     
    8921003 
    8931004        status = init_capture_stream(wf, strm->pool, 
     1005                                     strm, 
    8941006                                     &strm->rec_strm, 
    895                                      param->rec_id, 
    896                                      param->clock_rate, 
    897                                      param->channel_count, 
    898                                      param->samples_per_frame, 
     1007                                     param, 
    8991008                                     buf_count); 
    9001009 
     
    9031012            return status; 
    9041013        } 
     1014    } 
     1015 
     1016    /* If format is extended, must create buffer for the extended frame. */ 
     1017    if (param->ext_fmt.id != PJMEDIA_FORMAT_L16) { 
     1018        unsigned ptime = param->samples_per_frame * 1000 / 
     1019                         (param->clock_rate * param->channel_count); 
     1020        strm->xfrm_size = sizeof(pjmedia_frame_ext) +  
     1021                          32 * sizeof(pjmedia_frame_ext_subframe) + 
     1022                          (8000 * ptime / 1000) + 4; 
     1023        strm->xfrm = (pjmedia_frame_ext*) 
     1024                     pj_pool_alloc(pool, strm->xfrm_size); 
    9051025    } 
    9061026 
Note: See TracChangeset for help on using the changeset viewer.