- Timestamp:
- Feb 5, 2009 10:59:14 AM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/branches/projects/aps-direct/pjmedia/src/pjmedia/sound_port.c
r2394 r2438 36 36 //#define TEST_OVERFLOW_UNDERFLOW 37 37 38 enum39 {40 PJMEDIA_PLC_ENABLED = 1,41 };42 43 //#define DEFAULT_OPTIONS PJMEDIA_PLC_ENABLED44 #define DEFAULT_OPTIONS 045 46 38 47 39 struct pjmedia_snd_port … … 52 44 pjmedia_dir dir; 53 45 pjmedia_port *port; 54 unsigned options;55 46 56 47 pjmedia_echo_state *ec_state; … … 67 58 unsigned samples_per_frame; 68 59 unsigned bits_per_sample; 60 pjmedia_snd_setting setting; 69 61 70 62 #if PJMEDIA_SOUND_USE_DELAYBUF … … 245 237 246 238 /* 239 * The callback called by sound player when it needs more samples to be 240 * played. This version is for non-PCM data. 241 */ 242 static pj_status_t play_cb_ext(/* in */ void *user_data, 243 /* in */ pj_uint32_t timestamp, 244 /* out */ void *output, 245 /* out */ unsigned size) 246 { 247 pjmedia_snd_port *snd_port = (pjmedia_snd_port*) user_data; 248 pjmedia_port *port; 249 pjmedia_frame *frame = (pjmedia_frame*) output; 250 pj_status_t status; 251 252 PJ_UNUSED_ARG(size); 253 PJ_UNUSED_ARG(timestamp); 254 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 */ 261 port = snd_port->port; 262 if (port == NULL) { 263 frame->type = PJMEDIA_FRAME_TYPE_NONE; 264 return PJ_SUCCESS; 265 } 266 267 status = pjmedia_port_get_frame(port, frame); 268 269 return status; 270 } 271 272 273 /* 274 * The callback called by sound recorder when it has finished capturing a 275 * frame. This version is for non-PCM data. 276 */ 277 static pj_status_t rec_cb_ext(/* in */ void *user_data, 278 /* in */ pj_uint32_t timestamp, 279 /* in */ void *input, 280 /* in*/ unsigned size) 281 { 282 pjmedia_snd_port *snd_port = (pjmedia_snd_port*) user_data; 283 pjmedia_port *port; 284 pjmedia_frame *frame = (pjmedia_frame*)input; 285 286 PJ_UNUSED_ARG(size); 287 PJ_UNUSED_ARG(timestamp); 288 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 */ 295 port = snd_port->port; 296 if (port == NULL) 297 return PJ_SUCCESS; 298 299 pjmedia_port_put_frame(port, frame); 300 301 return PJ_SUCCESS; 302 } 303 304 /* 247 305 * Start the sound stream. 248 306 * This may be called even when the sound stream has already been started. … … 251 309 pjmedia_snd_port *snd_port ) 252 310 { 311 pjmedia_snd_rec_cb snd_rec_cb; 312 pjmedia_snd_play_cb snd_play_cb; 253 313 pj_status_t status; 254 314 … … 257 317 return PJ_SUCCESS; 258 318 259 /* Open sound stream. */ 260 if (snd_port->dir == PJMEDIA_DIR_CAPTURE) { 261 status = pjmedia_snd_open_rec( snd_port->rec_id, 262 snd_port->clock_rate, 263 snd_port->channel_count, 264 snd_port->samples_per_frame, 265 snd_port->bits_per_sample, 266 &rec_cb, 267 snd_port, 268 &snd_port->snd_stream); 269 270 } else if (snd_port->dir == PJMEDIA_DIR_PLAYBACK) { 271 status = pjmedia_snd_open_player( snd_port->play_id, 272 snd_port->clock_rate, 273 snd_port->channel_count, 274 snd_port->samples_per_frame, 275 snd_port->bits_per_sample, 276 &play_cb, 277 snd_port, 278 &snd_port->snd_stream); 279 280 } else if (snd_port->dir == PJMEDIA_DIR_CAPTURE_PLAYBACK) { 281 status = pjmedia_snd_open( snd_port->rec_id, 282 snd_port->play_id, 283 snd_port->clock_rate, 284 snd_port->channel_count, 285 snd_port->samples_per_frame, 286 snd_port->bits_per_sample, 287 &rec_cb, 288 &play_cb, 289 snd_port, 290 &snd_port->snd_stream); 319 PJ_ASSERT_RETURN(snd_port->dir == PJMEDIA_DIR_CAPTURE || 320 snd_port->dir == PJMEDIA_DIR_PLAYBACK || 321 snd_port->dir == PJMEDIA_DIR_CAPTURE_PLAYBACK, 322 PJ_EBUG); 323 324 if (snd_port->setting.format.u32 == 0 || 325 snd_port->setting.format.u32 == PJMEDIA_FOURCC_L16) 326 { 327 snd_rec_cb = &rec_cb; 328 snd_play_cb = &play_cb; 291 329 } else { 292 pj_assert(!"Invalid dir"); 293 status = PJ_EBUG; 294 } 330 snd_rec_cb = &rec_cb_ext; 331 snd_play_cb = &play_cb_ext; 332 } 333 334 status = pjmedia_snd_open2( snd_port->dir, 335 snd_port->rec_id, 336 snd_port->play_id, 337 snd_port->clock_rate, 338 snd_port->channel_count, 339 snd_port->samples_per_frame, 340 snd_port->bits_per_sample, 341 snd_rec_cb, 342 snd_play_cb, 343 snd_port, 344 &snd_port->setting, 345 &snd_port->snd_stream); 295 346 296 347 if (status != PJ_SUCCESS) … … 299 350 300 351 #ifdef SIMULATE_LOST_PCT 301 snd_port-> options |= PJMEDIA_PLC_ENABLED;352 snd_port->setting.plc = PJ_TRUE; 302 353 #endif 303 354 … … 307 358 */ 308 359 if ((snd_port->dir & PJMEDIA_DIR_PLAYBACK) && 309 (snd_port-> options & PJMEDIA_PLC_ENABLED))360 (snd_port->setting.plc)) 310 361 { 311 362 status = pjmedia_plc_create(pool, snd_port->clock_rate, … … 374 425 pjmedia_snd_port *snd_port; 375 426 427 PJ_UNUSED_ARG(options); 428 376 429 PJ_ASSERT_RETURN(pool && p_port, PJ_EINVAL); 377 430 … … 382 435 snd_port->play_id = play_id; 383 436 snd_port->dir = PJMEDIA_DIR_CAPTURE_PLAYBACK; 384 snd_port->options = options | DEFAULT_OPTIONS;385 437 snd_port->clock_rate = clock_rate; 386 438 snd_port->channel_count = channel_count; … … 429 481 pjmedia_snd_port *snd_port; 430 482 483 PJ_UNUSED_ARG(options); 484 431 485 PJ_ASSERT_RETURN(pool && p_port, PJ_EINVAL); 432 486 … … 436 490 snd_port->rec_id = dev_id; 437 491 snd_port->dir = PJMEDIA_DIR_CAPTURE; 438 snd_port->options = options | DEFAULT_OPTIONS;439 492 snd_port->clock_rate = clock_rate; 440 493 snd_port->channel_count = channel_count; … … 466 519 pjmedia_snd_port *snd_port; 467 520 521 PJ_UNUSED_ARG(options); 522 468 523 PJ_ASSERT_RETURN(pool && p_port, PJ_EINVAL); 469 524 … … 473 528 snd_port->play_id = dev_id; 474 529 snd_port->dir = PJMEDIA_DIR_PLAYBACK; 475 snd_port->options = options | DEFAULT_OPTIONS;476 530 snd_port->clock_rate = clock_rate; 477 531 snd_port->channel_count = channel_count; … … 486 540 */ 487 541 return start_sound_device( pool, snd_port ); 542 } 543 544 545 /* 546 * Create bidirectional port. 547 */ 548 PJ_DEF(pj_status_t) pjmedia_snd_port_create2(pj_pool_t *pool, 549 pjmedia_dir dir, 550 int rec_id, 551 int play_id, 552 unsigned clock_rate, 553 unsigned channel_count, 554 unsigned samples_per_frame, 555 unsigned bits_per_sample, 556 const pjmedia_snd_setting *setting, 557 pjmedia_snd_port **p_port) 558 { 559 pjmedia_snd_port *snd_port; 560 561 PJ_ASSERT_RETURN(pool && p_port, PJ_EINVAL); 562 563 snd_port = PJ_POOL_ZALLOC_T(pool, pjmedia_snd_port); 564 PJ_ASSERT_RETURN(snd_port, PJ_ENOMEM); 565 566 snd_port->dir = dir; 567 snd_port->rec_id = rec_id; 568 snd_port->play_id = play_id; 569 snd_port->dir = PJMEDIA_DIR_CAPTURE_PLAYBACK; 570 snd_port->clock_rate = clock_rate; 571 snd_port->channel_count = channel_count; 572 snd_port->samples_per_frame = samples_per_frame; 573 snd_port->bits_per_sample = bits_per_sample; 574 snd_port->setting = *setting; 575 576 #if PJMEDIA_SOUND_USE_DELAYBUF 577 if (snd_port->setting.format.u32 == 0 || 578 snd_port->setting.format.u32 == PJMEDIA_FOURCC_L16) 579 { 580 pj_status_t status; 581 unsigned ptime; 582 583 ptime = samples_per_frame * 1000 / (clock_rate * channel_count); 584 585 status = pjmedia_delay_buf_create(pool, "snd_buff", 586 clock_rate, samples_per_frame, 587 channel_count, 588 PJMEDIA_SOUND_BUFFER_COUNT * ptime, 589 0, &snd_port->delay_buf); 590 PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); 591 } 592 #endif 593 594 *p_port = snd_port; 595 596 597 /* Start sound device immediately. 598 * If there's no port connected, the sound callback will return 599 * empty signal. 600 */ 601 return start_sound_device( pool, snd_port ); 602 488 603 } 489 604
Note: See TracChangeset
for help on using the changeset viewer.