- Timestamp:
- Feb 13, 2009 11:53:12 AM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/branches/projects/aps-direct/pjmedia/src/pjmedia/sound_port.c
r2438 r2452 19 19 */ 20 20 #include <pjmedia/sound_port.h> 21 #include <pjmedia/alaw_ulaw.h> 21 22 #include <pjmedia/delaybuf.h> 22 23 #include <pjmedia/echo.h> … … 36 37 //#define TEST_OVERFLOW_UNDERFLOW 37 38 38 39 39 struct pjmedia_snd_port 40 40 { … … 63 63 pjmedia_delay_buf *delay_buf; 64 64 #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 65 72 }; 66 73 … … 79 86 pj_status_t status; 80 87 81 /* We're risking accessing the port without holding any mutex.82 * It's possible that port is disconnected then destroyed while83 * we're trying to access it.84 * But in the name of performance, we'll try this approach until85 * someone complains when it crashes.86 */87 88 port = snd_port->port; 88 89 if (port == NULL) … … 198 199 pjmedia_frame frame; 199 200 200 /* We're risking accessing the port without holding any mutex.201 * It's possible that port is disconnected then destroyed while202 * we're trying to access it.203 * But in the name of performance, we'll try this approach until204 * someone complains when it crashes.205 */206 201 port = snd_port->port; 207 202 if (port == NULL) … … 245 240 /* out */ unsigned size) 246 241 { 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 */ 247 246 pjmedia_snd_port *snd_port = (pjmedia_snd_port*) user_data; 248 247 pjmedia_port *port; … … 253 252 PJ_UNUSED_ARG(timestamp); 254 253 255 /* We're risking accessing the port without holding any mutex.256 * It's possible that port is disconnected then destroyed while257 * we're trying to access it.258 * But in the name of performance, we'll try this approach until259 * someone complains when it crashes.260 */261 254 port = snd_port->port; 262 255 if (port == NULL) { … … 268 261 269 262 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 341 no_frame: 342 pj_bzero(output, size); 343 return PJ_SUCCESS; 344 345 #endif /* PJMEDIA_SND_SUPPORT_OPEN2 */ 270 346 } 271 347 … … 280 356 /* in*/ unsigned size) 281 357 { 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 */ 282 362 pjmedia_snd_port *snd_port = (pjmedia_snd_port*) user_data; 283 363 pjmedia_port *port; … … 287 367 PJ_UNUSED_ARG(timestamp); 288 368 289 /* We're risking accessing the port without holding any mutex.290 * It's possible that port is disconnected then destroyed while291 * we're trying to access it.292 * But in the name of performance, we'll try this approach until293 * someone complains when it crashes.294 */295 369 port = snd_port->port; 296 370 if (port == NULL) … … 300 374 301 375 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 302 412 } 303 413 … … 332 442 } 333 443 444 #if defined(PJMEDIA_SND_SUPPORT_OPEN2) && PJMEDIA_SND_SUPPORT_OPEN2!=0 334 445 status = pjmedia_snd_open2( snd_port->dir, 335 446 snd_port->rec_id, … … 344 455 &snd_port->setting, 345 456 &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 346 469 347 470 if (status != PJ_SUCCESS) … … 572 695 snd_port->samples_per_frame = samples_per_frame; 573 696 snd_port->bits_per_sample = bits_per_sample; 574 snd_port->setting = *setting;697 pj_memcpy(&snd_port->setting, setting, sizeof(*setting)); 575 698 576 699 #if PJMEDIA_SOUND_USE_DELAYBUF … … 589 712 0, &snd_port->delay_buf); 590 713 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); 591 729 } 592 730 #endif
Note: See TracChangeset
for help on using the changeset viewer.