Changeset 2270 for pjproject/trunk/pjmedia/src/pjmedia/wav_writer.c
- Timestamp:
- Sep 10, 2008 7:48:45 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/src/pjmedia/wav_writer.c
r2039 r2270 18 18 */ 19 19 #include <pjmedia/wav_port.h> 20 #include <pjmedia/alaw_ulaw.h> 20 21 #include <pjmedia/errno.h> 21 22 #include <pjmedia/wave.h> … … 30 31 #define THIS_FILE "wav_writer.c" 31 32 #define SIGNATURE PJMEDIA_PORT_SIGNATURE('F', 'W', 'R', 'T') 32 #define BYTES_PER_SAMPLE 233 33 34 34 … … 36 36 { 37 37 pjmedia_port base; 38 pjmedia_wave_fmt_tag fmt_tag; 39 pj_uint16_t bytes_per_sample; 40 38 41 pj_size_t bufsize; 39 42 char *buf; … … 73 76 pj_status_t status; 74 77 75 PJ_UNUSED_ARG(flags);76 77 78 /* Check arguments. */ 78 79 PJ_ASSERT_RETURN(pool && filename && p_port, PJ_EINVAL); … … 97 98 fport->base.on_destroy = &file_on_destroy; 98 99 100 if (flags == PJMEDIA_FILE_WRITE_ALAW) { 101 fport->fmt_tag = PJMEDIA_WAVE_FMT_TAG_ALAW; 102 fport->bytes_per_sample = 1; 103 } else if (flags == PJMEDIA_FILE_WRITE_ULAW) { 104 fport->fmt_tag = PJMEDIA_WAVE_FMT_TAG_ULAW; 105 fport->bytes_per_sample = 1; 106 } else { 107 fport->fmt_tag = PJMEDIA_WAVE_FMT_TAG_PCM; 108 fport->bytes_per_sample = 2; 109 } 99 110 100 111 /* Open file in write and read mode. … … 114 125 wave_hdr.fmt_hdr.fmt = PJMEDIA_FMT_TAG; 115 126 wave_hdr.fmt_hdr.len = 16; 116 wave_hdr.fmt_hdr.fmt_tag = 1;127 wave_hdr.fmt_hdr.fmt_tag = fport->fmt_tag; 117 128 wave_hdr.fmt_hdr.nchan = (pj_int16_t)channel_count; 118 129 wave_hdr.fmt_hdr.sample_rate = sampling_rate; 119 130 wave_hdr.fmt_hdr.bytes_per_sec = sampling_rate * channel_count * 120 bits_per_sample / 8; 121 wave_hdr.fmt_hdr.block_align = (pj_int16_t) (channel_count * 122 bits_per_sample / 8); 123 wave_hdr.fmt_hdr.bits_per_sample = (pj_int16_t)bits_per_sample; 131 fport->bytes_per_sample; 132 wave_hdr.fmt_hdr.block_align = fport->bytes_per_sample * channel_count; 133 wave_hdr.fmt_hdr.bits_per_sample = fport->bytes_per_sample * 8; 124 134 125 135 wave_hdr.data_hdr.data = PJMEDIA_DATA_TAG; … … 134 144 135 145 /* Write WAVE header */ 136 size = sizeof(pjmedia_wave_hdr); 137 status = pj_file_write(fport->fd, &wave_hdr, &size); 138 if (status != PJ_SUCCESS) { 139 pj_file_close(fport->fd); 140 return status; 146 if (fport->fmt_tag != PJMEDIA_WAVE_FMT_TAG_PCM) { 147 pjmedia_wave_subchunk fact_chunk; 148 pj_uint32_t tmp = 0; 149 150 fact_chunk.id = PJMEDIA_FACT_TAG; 151 fact_chunk.len = 4; 152 153 PJMEDIA_WAVE_NORMALIZE_SUBCHUNK(&fact_chunk); 154 155 /* Write WAVE header without DATA chunk header */ 156 size = sizeof(pjmedia_wave_hdr) - sizeof(wave_hdr.data_hdr); 157 status = pj_file_write(fport->fd, &wave_hdr, &size); 158 if (status != PJ_SUCCESS) { 159 pj_file_close(fport->fd); 160 return status; 161 } 162 163 /* Write FACT chunk if it stores compressed data */ 164 size = sizeof(fact_chunk); 165 status = pj_file_write(fport->fd, &fact_chunk, &size); 166 if (status != PJ_SUCCESS) { 167 pj_file_close(fport->fd); 168 return status; 169 } 170 size = 4; 171 status = pj_file_write(fport->fd, &tmp, &size); 172 if (status != PJ_SUCCESS) { 173 pj_file_close(fport->fd); 174 return status; 175 } 176 177 /* Write DATA chunk header */ 178 size = sizeof(wave_hdr.data_hdr); 179 status = pj_file_write(fport->fd, &wave_hdr.data_hdr, &size); 180 if (status != PJ_SUCCESS) { 181 pj_file_close(fport->fd); 182 return status; 183 } 184 } else { 185 size = sizeof(pjmedia_wave_hdr); 186 status = pj_file_write(fport->fd, &wave_hdr, &size); 187 if (status != PJ_SUCCESS) { 188 pj_file_close(fport->fd); 189 return status; 190 } 141 191 } 142 192 … … 259 309 { 260 310 struct file_port *fport = (struct file_port *)this_port; 311 unsigned frame_size; 312 313 if (fport->fmt_tag == PJMEDIA_WAVE_FMT_TAG_PCM) 314 frame_size = frame->size; 315 else 316 frame_size = frame->size >> 1; 261 317 262 318 /* Flush buffer if we don't have enough room for the frame. */ 263 if (fport->writepos + frame ->size > fport->buf + fport->bufsize) {319 if (fport->writepos + frame_size > fport->buf + fport->bufsize) { 264 320 pj_status_t status; 265 321 status = flush_buffer(fport); … … 269 325 270 326 /* Check if frame is not too large. */ 271 PJ_ASSERT_RETURN(fport->writepos+frame ->size <= fport->buf+fport->bufsize,327 PJ_ASSERT_RETURN(fport->writepos+frame_size <= fport->buf+fport->bufsize, 272 328 PJMEDIA_EFRMFILETOOBIG); 273 329 274 330 /* Copy frame to buffer. */ 275 pj_memcpy(fport->writepos, frame->buf, frame->size); 276 fport->writepos += frame->size; 331 if (fport->fmt_tag == PJMEDIA_WAVE_FMT_TAG_PCM) { 332 pj_memcpy(fport->writepos, frame->buf, frame->size); 333 } else { 334 unsigned i; 335 pj_int16_t *src = (pj_int16_t*)frame->buf; 336 pj_uint8_t *dst = (pj_uint8_t*)fport->writepos; 337 338 if (fport->fmt_tag == PJMEDIA_WAVE_FMT_TAG_ULAW) { 339 for (i = 0; i < frame_size; ++i) { 340 *dst++ = pjmedia_linear2ulaw(*src++); 341 } 342 } else { 343 for (i = 0; i < frame_size; ++i) { 344 *dst++ = pjmedia_linear2alaw(*src++); 345 } 346 } 347 348 } 349 fport->writepos += frame_size; 277 350 278 351 /* Increment total written, and check if we need to call callback */ 279 fport->total += frame ->size;352 fport->total += frame_size; 280 353 if (fport->cb && fport->total >= fport->cb_size) { 281 354 pj_status_t (*cb)(pjmedia_port*, void*); … … 315 388 pj_uint32_t wave_data_len; 316 389 pj_status_t status; 390 pj_uint32_t data_len_pos = DATA_LEN_POS; 317 391 318 392 /* Flush remaining buffers. */ … … 342 416 PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); 343 417 418 /* Write samples_len in FACT chunk */ 419 if (fport->fmt_tag != PJMEDIA_WAVE_FMT_TAG_PCM) { 420 enum { SAMPLES_LEN_POS = 44}; 421 pj_uint32_t wav_samples_len; 422 423 /* Adjust wave_data_len & data_len_pos since there is FACT chunk */ 424 wave_data_len -= 12; 425 data_len_pos += 12; 426 wav_samples_len = wave_data_len; 427 428 /* Seek to samples_len field. */ 429 status = pj_file_setpos(fport->fd, SAMPLES_LEN_POS, PJ_SEEK_SET); 430 PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); 431 432 /* Write samples_len */ 433 bytes = sizeof(wav_samples_len); 434 status = pj_file_write(fport->fd, &wav_samples_len, &bytes); 435 PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); 436 } 437 344 438 /* Seek to data_len field. */ 345 status = pj_file_setpos(fport->fd, DATA_LEN_POS, PJ_SEEK_SET);439 status = pj_file_setpos(fport->fd, data_len_pos, PJ_SEEK_SET); 346 440 PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); 347 441
Note: See TracChangeset
for help on using the changeset viewer.