Changeset 727


Ignore:
Timestamp:
Sep 18, 2006 11:33:44 PM (15 years ago)
Author:
bennylp
Message:

Support for reading non-canonical WAV file in WAV file player port.

Location:
pjproject/trunk/pjmedia
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/include/pjmedia/wave.h

    r518 r727  
    9797typedef struct pjmedia_wave_hdr pjmedia_wave_hdr; 
    9898 
     99/** 
     100 * This structure describes generic RIFF subchunk header. 
     101 */ 
     102typedef struct pjmedia_wave_subchunk 
     103{ 
     104    pj_uint32_t     id;                 /**< Subchunk ASCII tag.            */ 
     105    pj_uint32_t     len;                /**< Length following this field    */ 
     106} pjmedia_wave_subchunk; 
     107 
     108 
     109/** 
     110 * Normalize subchunk header from little endian (the representation of 
     111 * RIFF file) into host's endian. 
     112 */ 
     113#if defined(PJ_IS_BIG_ENDIAN) && PJ_IS_BIG_ENDIAN!=0 
     114#   define PJMEDIA_WAVE_NORMALIZE_SUBCHUNK(ch)  \ 
     115            do { \ 
     116                (ch)->id = pj_swap32((ch)->id); \ 
     117                (ch)->len = pj_swap32((ch)->len); \ 
     118            } while (0) 
     119#else 
     120#   define PJMEDIA_WAVE_NORMALIZE_SUBCHUNK(ch) 
     121#endif 
     122 
    99123 
    100124/** 
  • pjproject/trunk/pjmedia/src/pjmedia/wav_player.c

    r633 r727  
    6363 
    6464    pj_off_t         fsize; 
     65    unsigned         start_data; 
    6566    pj_off_t         fpos; 
    6667    pj_oshandle_t    fd; 
     
    165166                          (int)fport->base.info.name.slen, 
    166167                          fport->base.info.name.ptr)); 
    167                 fport->fpos = sizeof(struct pjmedia_wave_hdr); 
     168                fport->fpos = fport->start_data; 
    168169                pj_file_setpos( fport->fd, fport->fpos, PJ_SEEK_SET); 
    169170            } 
     
    189190{ 
    190191    pjmedia_wave_hdr wave_hdr; 
    191     pj_ssize_t size_read; 
     192    pj_ssize_t size_to_read, size_read; 
    192193    struct file_port *fport; 
     194    pj_off_t pos; 
    193195    pj_status_t status; 
    194196 
     
    226228        return status; 
    227229 
    228     /* Read the WAVE header. */ 
    229     size_read = sizeof(wave_hdr); 
     230    /* Read the file header plus fmt header only. */ 
     231    size_read = size_to_read = sizeof(wave_hdr) - 8; 
    230232    status = pj_file_read( fport->fd, &wave_hdr, &size_read); 
    231233    if (status != PJ_SUCCESS) { 
     
    233235        return status; 
    234236    } 
    235     if (size_read != sizeof(wave_hdr)) { 
     237    if (size_read != size_to_read) { 
    236238        pj_file_close(fport->fd); 
    237239        return PJMEDIA_ENOTVALIDWAVE; 
     
    271273    } 
    272274 
     275    /* If length of fmt_header is greater than 16, skip the remaining 
     276     * fmt header data. 
     277     */ 
     278    if (wave_hdr.fmt_hdr.len > 16) { 
     279        size_to_read = wave_hdr.fmt_hdr.len - 16; 
     280        status = pj_file_setpos(fport->fd, size_to_read, PJ_SEEK_CUR); 
     281        if (status != PJ_SUCCESS) { 
     282            pj_file_close(fport->fd); 
     283            return status; 
     284        } 
     285    } 
     286 
     287    /* Repeat reading the WAVE file until we have 'data' chunk */ 
     288    for (;;) { 
     289        pjmedia_wave_subchunk subchunk; 
     290        size_read = 8; 
     291        status = pj_file_read(fport->fd, &subchunk, &size_read); 
     292        if (status != PJ_SUCCESS || size_read != 8) { 
     293            pj_file_close(fport->fd); 
     294            return PJMEDIA_EWAVETOOSHORT; 
     295        } 
     296 
     297        /* Normalize endianness */ 
     298        PJMEDIA_WAVE_NORMALIZE_SUBCHUNK(&subchunk); 
     299 
     300        /* Break if this is "data" chunk */ 
     301        if (subchunk.id == PJMEDIA_DATA_TAG) { 
     302            wave_hdr.data_hdr.data = PJMEDIA_DATA_TAG; 
     303            wave_hdr.data_hdr.len = subchunk.len; 
     304            break; 
     305        } 
     306 
     307        /* Otherwise skip the chunk contents */ 
     308        size_to_read = subchunk.len; 
     309        status = pj_file_setpos(fport->fd, size_to_read, PJ_SEEK_CUR); 
     310        if (status != PJ_SUCCESS) { 
     311            pj_file_close(fport->fd); 
     312            return status; 
     313        } 
     314    } 
     315 
     316    /* Current file position now points to start of data */ 
     317    status = pj_file_getpos(fport->fd, &pos); 
     318    fport->start_data = (unsigned)pos; 
     319 
    273320    /* Validate length. */ 
    274     if (wave_hdr.data_hdr.len != fport->fsize-sizeof(pjmedia_wave_hdr)) { 
     321    if (wave_hdr.data_hdr.len != fport->fsize - fport->start_data) { 
    275322        pj_file_close(fport->fd); 
    276323        return PJMEDIA_EWAVEUNSUPP; 
     
    311358        return PJ_ENOMEM; 
    312359    } 
    313  
     360  
    314361    fport->readpos = fport->buf; 
    315362 
    316363    /* Set initial position of the file. */ 
    317     fport->fpos = sizeof(struct pjmedia_wave_hdr); 
     364    fport->fpos = fport->start_data; 
    318365 
    319366    /* Fill up the buffer. */ 
     
    360407    fport = (struct file_port*) port; 
    361408 
    362     PJ_ASSERT_RETURN(bytes < fport->fsize - sizeof(pjmedia_wave_hdr),  
    363                      PJ_EINVAL); 
    364  
    365     fport->fpos = sizeof(struct pjmedia_wave_hdr) + bytes; 
     409    PJ_ASSERT_RETURN(bytes < fport->fsize - fport->start_data, PJ_EINVAL); 
     410 
     411    fport->fpos = fport->start_data + bytes; 
    366412    pj_file_setpos( fport->fd, fport->fpos, PJ_SEEK_SET); 
    367413 
     
    387433    fport = (struct file_port*) port; 
    388434 
    389     payload_pos = (pj_size_t)(fport->fpos - sizeof(pjmedia_wave_hdr)); 
     435    payload_pos = (pj_size_t)(fport->fpos - fport->start_data); 
    390436    if (payload_pos >= fport->bufsize) 
    391437        return payload_pos - fport->bufsize + (fport->readpos - fport->buf); 
Note: See TracChangeset for help on using the changeset viewer.