Changeset 352 for pjproject/trunk
- Timestamp:
- Mar 23, 2006 1:15:59 PM (19 years ago)
- Location:
- pjproject/trunk
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/include/pjmedia/sound.h
r321 r352 112 112 113 113 /** 114 * Create a new audio stream for audio capture purpose. 114 * Create sound stream for both capturing audio and audio playback, from the 115 * same device. This is the recommended way to create simultaneous recorder 116 * and player streams, because it should work on backends that does not allow 117 * a device to be opened more than once. 118 * 119 * @param rec_id Device index for recorder/capture stream, or 120 * -1 to use the first capable device. 121 * @param play_id Device index for playback stream, or -1 to use 122 * the first capable device. 123 * @param clock_rate Sound device's clock rate to set. 124 * @param channel_count Set number of channels, 1 for mono, or 2 for 125 * stereo. The channel count determines the format 126 * of the frame. 127 * @param samples_per_frame Number of samples per frame. 128 * @param bits_per_sample Set the number of bits per sample. The normal 129 * value for this parameter is 16 bits per sample. 130 * @param rec_cb Callback to handle captured audio samples. 131 * @param play_cb Callback to be called when the sound player needs 132 * more audio samples to play. 133 * @param user_data User data to be associated with the stream. 134 * @param p_snd_strm Pointer to receive the stream instance. 135 * 136 * @return PJ_SUCCESS on success. 137 */ 138 PJ_DECL(pj_status_t) pjmedia_snd_open(int rec_id, 139 int play_id, 140 unsigned clock_rate, 141 unsigned channel_count, 142 unsigned samples_per_frame, 143 unsigned bits_per_sample, 144 pjmedia_snd_rec_cb rec_cb, 145 pjmedia_snd_play_cb play_cb, 146 void *user_data, 147 pjmedia_snd_stream **p_snd_strm); 148 149 150 /** 151 * Create a unidirectional audio stream for capturing audio samples from 152 * the sound device. 115 153 * 116 154 * @param index Device index, or -1 to let the library choose the … … 129 167 * @return PJ_SUCCESS on success. 130 168 */ 131 PJ_DECL(pj_status_t) pjmedia_snd_open_rec order( int index,169 PJ_DECL(pj_status_t) pjmedia_snd_open_rec( int index, 132 170 unsigned clock_rate, 133 171 unsigned channel_count, … … 139 177 140 178 /** 141 * Create a new audio stream for playing audio samples. 179 * Create a unidirectional audio stream for playing audio samples to the 180 * sound device. 142 181 * 143 182 * @param index Device index, or -1 to let the library choose the … … 166 205 pjmedia_snd_stream **p_snd_strm ); 167 206 207 168 208 /** 169 209 * Start the stream. -
pjproject/trunk/pjmedia/include/pjmedia/sound_port.h
r321 r352 42 42 typedef struct pjmedia_snd_port pjmedia_snd_port; 43 43 44 /** 45 * Create sound device port for capturing audio streams from the sound device 46 * with the specified parameters. 44 45 /** 46 * Create bidirectional sound port for both capturing and playback of 47 * audio samples. 48 * 49 * @param pool Pool to allocate sound port structure. 50 * @param rec_id Device index for recorder/capture stream, or 51 * -1 to use the first capable device. 52 * @param play_id Device index for playback stream, or -1 to use 53 * the first capable device. 54 * @param clock_rate Sound device's clock rate to set. 55 * @param channel_count Set number of channels, 1 for mono, or 2 for 56 * stereo. The channel count determines the format 57 * of the frame. 58 * @param samples_per_frame Number of samples per frame. 59 * @param bits_per_sample Set the number of bits per sample. The normal 60 * value for this parameter is 16 bits per sample. 61 * @param options Options flag, currently must be zero. 62 * @param p_port Pointer to receive the sound device port instance. 63 * 64 * @return PJ_SUCCESS on success, or the appropriate error 65 * code. 66 */ 67 PJ_DECL(pj_status_t) pjmedia_snd_port_create( pj_pool_t *pool, 68 int rec_id, 69 int play_id, 70 unsigned clock_rate, 71 unsigned channel_count, 72 unsigned samples_per_frame, 73 unsigned bits_per_sample, 74 unsigned options, 75 pjmedia_snd_port **p_port); 76 77 /** 78 * Create unidirectional sound device port for capturing audio streams from 79 * the sound device with the specified parameters. 47 80 * 48 81 * @param pool Pool to allocate sound port structure. … … 72 105 73 106 /** 74 * Create sound device port for playing audio streams with the specified75 * parameters.107 * Create unidirectional sound device port for playing audio streams with the 108 * specified parameters. 76 109 * 77 110 * @param pool Pool to allocate sound port structure. … … 113 146 114 147 /** 115 * Connect a port to the sound device port. If the sound device port is a 148 * Retrieve the sound stream associated by this sound device port. 149 * 150 * @param snd_port The sound device port. 151 * 152 * @return The sound stream instance. 153 */ 154 PJ_DECL(pjmedia_snd_stream*) pjmedia_snd_port_get_snd_stream( 155 pjmedia_snd_port *snd_port); 156 157 158 /** 159 * Connect a port to the sound device port. If the sound device port has a 116 160 * sound recorder device, then this will start periodic function call to 117 * the port's put_frame() function. If the sound device is a sound player161 * the port's put_frame() function. If the sound device has a sound player 118 162 * device, then this will start periodic function call to the port's 119 163 * get_frame() function. -
pjproject/trunk/pjmedia/include/pjmedia/types.h
r320 r352 64 64 }; 65 65 66 /* Alternate names for media direction: */ 67 68 /** 69 * Direction is capturing audio frames. 70 */ 71 #define PJMEDIA_DIR_CAPTURE PJMEDIA_DIR_ENCODING 72 73 /** 74 * Direction is playback of audio frames. 75 */ 76 #define PJMEDIA_DIR_PLAYBACK PJMEDIA_DIR_DECODING 77 78 /** 79 * Direction is both capture and playback. 80 */ 81 #define PJMEDIA_DIR_CAPTURE_PLAYBACK PJMEDIA_DIR_ENCODING_DECODING 82 66 83 67 84 /** -
pjproject/trunk/pjmedia/src/pjmedia/conference.c
r347 r352 159 159 unsigned port_cnt; /**< Current number of ports. */ 160 160 unsigned connect_cnt; /**< Total number of connections */ 161 pjmedia_snd_port *snd_rec; /**< Sound recorder stream. */ 162 pjmedia_snd_port *snd_player; /**< Sound player stream. */ 161 pjmedia_snd_port *snd_dev_port; /**< Sound device port. */ 163 162 pjmedia_port *master_port; /**< Port zero's port. */ 164 163 pj_mutex_t *mutex; /**< Conference mutex. */ … … 343 342 344 343 345 /* Create sound devices: */ 346 347 /* Create recorder only if mic is not disabled. */ 348 if ((conf->options & PJMEDIA_CONF_NO_DEVICE) == 0 && 349 (conf->options & PJMEDIA_CONF_NO_MIC) == 0) 350 { 351 status = pjmedia_snd_port_create_rec( pool, -1, conf->clock_rate, 344 /* Create sound device port: */ 345 346 if ((conf->options & PJMEDIA_CONF_NO_DEVICE) == 0) { 347 348 /* 349 * If capture is disabled then create player only port. 350 * Otherwise create bidirectional sound device port. 351 */ 352 if (conf->options & PJMEDIA_CONF_NO_MIC) { 353 status = pjmedia_snd_port_create_player(pool, -1, conf->clock_rate, 354 conf->channel_count, 355 conf->samples_per_frame, 356 conf->bits_per_sample, 357 0, /* options */ 358 &conf->snd_dev_port); 359 360 } else { 361 status = pjmedia_snd_port_create( pool, -1, -1, conf->clock_rate, 352 362 conf->channel_count, 353 363 conf->samples_per_frame, 354 364 conf->bits_per_sample, 355 365 0, /* Options */ 356 &conf->snd_rec); 357 if (status != PJ_SUCCESS) { 358 conf->snd_rec = NULL; 366 &conf->snd_dev_port); 367 } 368 369 if (status != PJ_SUCCESS) 359 370 return status; 360 }361 }362 363 /* Create player device */364 if ((conf->options & PJMEDIA_CONF_NO_DEVICE) == 0) {365 status = pjmedia_snd_port_create_player(pool, -1, conf->clock_rate,366 conf->channel_count,367 conf->samples_per_frame,368 conf->bits_per_sample,369 0, /* options */370 &conf->snd_player);371 if (status != PJ_SUCCESS) {372 if (conf->snd_rec) {373 pjmedia_snd_port_destroy(conf->snd_rec);374 conf->snd_rec = NULL;375 }376 conf->snd_player = NULL;377 return status;378 }379 371 } 380 372 … … 434 426 conf->master_port->info.encoding_name = pj_str("pcm"); 435 427 conf->master_port->info.has_info = 1; 436 conf->master_port->info.name = pj_str(" master port");428 conf->master_port->info.name = pj_str("sound-dev"); 437 429 conf->master_port->info.need_info = 0; 438 430 conf->master_port->info.pt = 0xFF; … … 465 457 * master port. 466 458 */ 467 if (conf->snd_ player) {468 status = pjmedia_snd_port_connect( conf->snd_ player,459 if (conf->snd_dev_port) { 460 status = pjmedia_snd_port_connect( conf->snd_dev_port, 469 461 conf->master_port ); 470 462 if (status != PJ_SUCCESS) { … … 474 466 } 475 467 476 if (conf->snd_rec) {477 status = pjmedia_snd_port_connect( conf->snd_rec,478 conf->master_port);479 if (status != PJ_SUCCESS) {480 pjmedia_conf_destroy(conf);481 return status;482 }483 }484 485 468 486 469 /* Done */ … … 520 503 PJ_ASSERT_RETURN(conf != NULL, PJ_EINVAL); 521 504 522 /* Destroy sound devices. */ 523 if (conf->snd_rec) { 524 pjmedia_snd_port_destroy(conf->snd_rec); 525 conf->snd_rec = NULL; 526 } 527 if (conf->snd_player) { 528 pjmedia_snd_port_destroy(conf->snd_player); 529 conf->snd_player = NULL; 505 /* Destroy sound device port. */ 506 if (conf->snd_dev_port) { 507 pjmedia_snd_port_destroy(conf->snd_dev_port); 508 conf->snd_dev_port = NULL; 530 509 } 531 510 -
pjproject/trunk/pjmedia/src/pjmedia/nullsound.c
r321 r352 48 48 } 49 49 50 PJ_DEF(pj_status_t) pjmedia_snd_open_rec order( int index,50 PJ_DEF(pj_status_t) pjmedia_snd_open_rec( int index, 51 51 unsigned clock_rate, 52 52 unsigned channel_count, … … 92 92 } 93 93 94 PJ_DEF(pj_status_t) pjmedia_snd_open( int rec_id, 95 int play_id, 96 unsigned clock_rate, 97 unsigned channel_count, 98 unsigned samples_per_frame, 99 unsigned bits_per_sample, 100 pjmedia_snd_rec_cb rec_cb, 101 pjmedia_snd_play_cb play_cb, 102 void *user_data, 103 pjmedia_snd_stream **p_snd_strm) 104 { 105 PJ_UNUSED_ARG(rec_id); 106 PJ_UNUSED_ARG(play_id); 107 PJ_UNUSED_ARG(clock_rate); 108 PJ_UNUSED_ARG(channel_count); 109 PJ_UNUSED_ARG(samples_per_frame); 110 PJ_UNUSED_ARG(bits_per_sample); 111 PJ_UNUSED_ARG(rec_cb); 112 PJ_UNUSED_ARG(play_cb); 113 PJ_UNUSED_ARG(user_data); 114 115 *p_snd_strm = (void*)1; 116 117 return PJ_SUCCESS; 118 } 119 120 94 121 PJ_DEF(pj_status_t) pjmedia_snd_stream_start(pjmedia_snd_stream *stream) 95 122 { -
pjproject/trunk/pjmedia/src/pjmedia/pasound.c
r334 r352 33 33 } snd_mgr; 34 34 35 /* 36 * Sound stream descriptor. 37 * This struct may be used for both unidirectional or bidirectional sound 38 * streams. 39 */ 35 40 struct pjmedia_snd_stream 36 41 { 37 pj_pool_t *pool; 38 pj_str_t name; 39 PaStream *stream; 40 int dev_index; 41 int bytes_per_sample; 42 pj_uint32_t samples_per_sec; 43 int channel_count; 44 pj_uint32_t timestamp; 45 pj_uint32_t underflow; 46 pj_uint32_t overflow; 47 void *user_data; 48 pjmedia_snd_rec_cb rec_cb; 49 pjmedia_snd_play_cb play_cb; 50 pj_bool_t quit_flag; 51 pj_bool_t thread_has_exited; 52 pj_bool_t thread_initialized; 53 pj_thread_desc thread_desc; 54 pj_thread_t *thread; 42 pj_pool_t *pool; 43 pj_str_t name; 44 pjmedia_dir dir; 45 int bytes_per_sample; 46 pj_uint32_t samples_per_sec; 47 int channel_count; 48 49 PaStream *stream; 50 void *user_data; 51 pjmedia_snd_rec_cb rec_cb; 52 pjmedia_snd_play_cb play_cb; 53 54 pj_uint32_t timestamp; 55 pj_uint32_t underflow; 56 pj_uint32_t overflow; 57 58 pj_bool_t quit_flag; 59 60 pj_bool_t thread_exited; 61 pj_bool_t thread_initialized; 62 pj_thread_desc thread_desc; 63 pj_thread_t *thread; 55 64 }; 56 65 … … 73 82 74 83 if (stream->thread_initialized == 0) { 75 status = pj_thread_register("pa_rec", stream->thread_desc, &stream->thread); 84 status = pj_thread_register("pa_rec", stream->thread_desc, 85 &stream->thread); 76 86 stream->thread_initialized = 1; 77 87 PJ_LOG(5,(THIS_FILE, "Recorder thread started")); … … 93 103 94 104 on_break: 95 stream->thread_ has_exited = 1;105 stream->thread_exited = 1; 96 106 return paAbort; 97 107 } … … 116 126 117 127 if (stream->thread_initialized == 0) { 118 status = pj_thread_register("pa_rec", stream->thread_desc, &stream->thread); 128 status = pj_thread_register("portaudio", stream->thread_desc, 129 &stream->thread); 119 130 stream->thread_initialized = 1; 120 131 PJ_LOG(5,(THIS_FILE, "Player thread started")); … … 135 146 136 147 on_break: 137 stream->thread_ has_exited = 1;148 stream->thread_exited = 1; 138 149 return paAbort; 150 } 151 152 153 static int PaRecorderPlayerCallback( const void *input, 154 void *output, 155 unsigned long frameCount, 156 const PaStreamCallbackTimeInfo* timeInfo, 157 PaStreamCallbackFlags statusFlags, 158 void *userData ) 159 { 160 int rc; 161 162 rc = PaRecorderCallback(input, output, frameCount, timeInfo, 163 statusFlags, userData); 164 if (rc != paContinue) 165 return rc; 166 167 rc = PaPlayerCallback(input, output, frameCount, timeInfo, 168 statusFlags, userData); 169 return rc; 139 170 } 140 171 … … 195 226 * Open stream. 196 227 */ 197 PJ_DEF(pj_status_t) pjmedia_snd_open_rec order( int index,228 PJ_DEF(pj_status_t) pjmedia_snd_open_rec( int index, 198 229 unsigned clock_rate, 199 230 unsigned channel_count, … … 216 247 for (index=0; index<count; ++index) { 217 248 paDevInfo = Pa_GetDeviceInfo(index); 218 if (paDevInfo->maxInputChannels > 0)249 if (paDevInfo->maxInputChannels >= (int)channel_count) 219 250 break; 220 251 } … … 246 277 stream = pj_pool_zalloc(pool, sizeof(*stream)); 247 278 stream->pool = pool; 248 stream->name = pj_str("snd-rec"); 279 pj_strdup2_with_null(pool, &stream->name, paDevInfo->name); 280 stream->dir = PJMEDIA_DIR_CAPTURE; 249 281 stream->user_data = user_data; 250 stream->dev_index = index;251 282 stream->samples_per_sec = samples_per_frame; 252 283 stream->bytes_per_sample = bits_per_sample / 8; … … 305 336 for (index=0; index<count; ++index) { 306 337 paDevInfo = Pa_GetDeviceInfo(index); 307 if (paDevInfo->maxOutputChannels > 0)338 if (paDevInfo->maxOutputChannels >= (int)channel_count) 308 339 break; 309 340 } … … 335 366 stream = pj_pool_calloc(pool, 1, sizeof(*stream)); 336 367 stream->pool = pool; 337 stream->name = pj_str("player"); 368 pj_strdup2_with_null(pool, &stream->name, paDevInfo->name); 369 stream->dir = stream->dir = PJMEDIA_DIR_PLAYBACK; 338 370 stream->user_data = user_data; 339 371 stream->samples_per_sec = samples_per_frame; 340 372 stream->bytes_per_sample = bits_per_sample / 8; 341 373 stream->channel_count = channel_count; 342 stream->dev_index = index;343 374 stream->play_cb = play_cb; 344 375 … … 375 406 376 407 /* 408 * Open both player and recorder. 409 */ 410 PJ_DEF(pj_status_t) pjmedia_snd_open( int rec_id, 411 int play_id, 412 unsigned clock_rate, 413 unsigned channel_count, 414 unsigned samples_per_frame, 415 unsigned bits_per_sample, 416 pjmedia_snd_rec_cb rec_cb, 417 pjmedia_snd_play_cb play_cb, 418 void *user_data, 419 pjmedia_snd_stream **p_snd_strm) 420 { 421 pj_pool_t *pool; 422 pjmedia_snd_stream *stream; 423 PaStreamParameters inputParam; 424 PaStreamParameters outputParam; 425 int sampleFormat; 426 const PaDeviceInfo *paRecDevInfo = NULL; 427 const PaDeviceInfo *paPlayDevInfo = NULL; 428 unsigned paFrames; 429 PaError err; 430 431 if (rec_id == -1) { 432 int count = Pa_GetDeviceCount(); 433 for (rec_id=0; rec_id<count; ++rec_id) { 434 paRecDevInfo = Pa_GetDeviceInfo(rec_id); 435 if (paRecDevInfo->maxInputChannels >= (int)channel_count) 436 break; 437 } 438 if (rec_id == count) { 439 /* No such device. */ 440 return PJMEDIA_ENOSNDREC; 441 } 442 } else { 443 paRecDevInfo = Pa_GetDeviceInfo(rec_id); 444 if (!paRecDevInfo) { 445 /* Assumed it is "No such device" error. */ 446 return PJMEDIA_ESNDINDEVID; 447 } 448 } 449 450 if (play_id == -1) { 451 int count = Pa_GetDeviceCount(); 452 for (play_id=0; play_id<count; ++play_id) { 453 paPlayDevInfo = Pa_GetDeviceInfo(play_id); 454 if (paPlayDevInfo->maxOutputChannels >= (int)channel_count) 455 break; 456 } 457 if (play_id == count) { 458 /* No such device. */ 459 return PJMEDIA_ENOSNDPLAY; 460 } 461 } else { 462 paPlayDevInfo = Pa_GetDeviceInfo(play_id); 463 if (!paPlayDevInfo) { 464 /* Assumed it is "No such device" error. */ 465 return PJMEDIA_ESNDINDEVID; 466 } 467 } 468 469 if (bits_per_sample == 8) 470 sampleFormat = paUInt8; 471 else if (bits_per_sample == 16) 472 sampleFormat = paInt16; 473 else if (bits_per_sample == 32) 474 sampleFormat = paInt32; 475 else 476 return PJMEDIA_ESNDINSAMPLEFMT; 477 478 pool = pj_pool_create( snd_mgr.factory, "sndstream", 1024, 1024, NULL); 479 if (!pool) 480 return PJ_ENOMEM; 481 482 stream = pj_pool_zalloc(pool, sizeof(*stream)); 483 stream->pool = pool; 484 pj_strdup2_with_null(pool, &stream->name, paRecDevInfo->name); 485 stream->dir = PJMEDIA_DIR_CAPTURE_PLAYBACK; 486 stream->user_data = user_data; 487 stream->samples_per_sec = samples_per_frame; 488 stream->bytes_per_sample = bits_per_sample / 8; 489 stream->channel_count = channel_count; 490 stream->rec_cb = rec_cb; 491 stream->play_cb = play_cb; 492 493 pj_memset(&inputParam, 0, sizeof(inputParam)); 494 inputParam.device = rec_id; 495 inputParam.channelCount = channel_count; 496 inputParam.hostApiSpecificStreamInfo = NULL; 497 inputParam.sampleFormat = sampleFormat; 498 inputParam.suggestedLatency = paRecDevInfo->defaultLowInputLatency; 499 500 pj_memset(&outputParam, 0, sizeof(outputParam)); 501 outputParam.device = play_id; 502 outputParam.channelCount = channel_count; 503 outputParam.hostApiSpecificStreamInfo = NULL; 504 outputParam.sampleFormat = sampleFormat; 505 outputParam.suggestedLatency = paPlayDevInfo->defaultLowInputLatency; 506 507 /* Frames in PortAudio is number of samples in a single channel */ 508 paFrames = samples_per_frame / channel_count; 509 510 err = Pa_OpenStream( &stream->stream, &inputParam, &outputParam, 511 clock_rate, paFrames, 512 paClipOff, &PaRecorderPlayerCallback, stream ); 513 if (err != paNoError) { 514 pj_pool_release(pool); 515 return PJMEDIA_ERRNO_FROM_PORTAUDIO(err); 516 } 517 518 PJ_LOG(5,(THIS_FILE, "%s opening device %s/%s for recording and playback, " 519 "sample rate=%d, channel count=%d, " 520 "%d bits per sample, %d samples per buffer", 521 (err==0 ? "Success" : "Error"), 522 paRecDevInfo->name, paPlayDevInfo->name, 523 clock_rate, channel_count, 524 bits_per_sample, samples_per_frame)); 525 526 *p_snd_strm = stream; 527 528 529 return PJ_SUCCESS; 530 } 531 532 /* 377 533 * Start stream. 378 534 */ … … 398 554 399 555 stream->quit_flag = 1; 400 for (i=0; !stream->thread_ has_exited && i<100; ++i)556 for (i=0; !stream->thread_exited && i<100; ++i) 401 557 pj_thread_sleep(10); 402 558 … … 418 574 { 419 575 int i, err; 420 const PaDeviceInfo *paDevInfo;421 576 422 577 stream->quit_flag = 1; 423 for (i=0; !stream->thread_has_exited && i<100; ++i) 424 pj_thread_sleep(10); 425 426 pj_thread_sleep(1); 427 428 paDevInfo = Pa_GetDeviceInfo(stream->dev_index); 429 430 PJ_LOG(5,(THIS_FILE, "Closing %s: %lu underflow, %lu overflow", 431 paDevInfo->name, 578 for (i=0; !stream->thread_exited && i<100; ++i) { 579 pj_thread_sleep(1); 580 } 581 582 PJ_LOG(5,(THIS_FILE, "Closing %.*s: %lu underflow, %lu overflow", 583 (int)stream->name.slen, 584 stream->name.ptr, 432 585 stream->underflow, stream->overflow)); 433 586 -
pjproject/trunk/pjmedia/src/pjmedia/sound_port.c
r321 r352 24 24 struct pjmedia_snd_port 25 25 { 26 int snd_index; 26 int rec_id; 27 int play_id; 27 28 pjmedia_snd_stream *snd_stream; 28 29 pjmedia_dir dir; … … 124 125 125 126 /* Open sound stream. */ 126 if (snd_port->dir == PJMEDIA_DIR_ENCODING) { 127 status = pjmedia_snd_open_recorder( snd_port->snd_index, 128 snd_port->clock_rate, 129 snd_port->channel_count, 130 snd_port->samples_per_frame, 131 snd_port->bits_per_sample, 132 &rec_cb, 133 snd_port, 134 &snd_port->snd_stream); 135 } else { 136 status = pjmedia_snd_open_player( snd_port->snd_index, 127 if (snd_port->dir == PJMEDIA_DIR_CAPTURE) { 128 status = pjmedia_snd_open_rec( snd_port->rec_id, 129 snd_port->clock_rate, 130 snd_port->channel_count, 131 snd_port->samples_per_frame, 132 snd_port->bits_per_sample, 133 &rec_cb, 134 snd_port, 135 &snd_port->snd_stream); 136 137 } else if (snd_port->dir == PJMEDIA_DIR_PLAYBACK) { 138 status = pjmedia_snd_open_player( snd_port->play_id, 137 139 snd_port->clock_rate, 138 140 snd_port->channel_count, … … 142 144 snd_port, 143 145 &snd_port->snd_stream); 146 147 } else if (snd_port->dir == PJMEDIA_DIR_CAPTURE_PLAYBACK) { 148 status = pjmedia_snd_open( snd_port->rec_id, 149 snd_port->play_id, 150 snd_port->clock_rate, 151 snd_port->channel_count, 152 snd_port->samples_per_frame, 153 snd_port->bits_per_sample, 154 &rec_cb, 155 &play_cb, 156 snd_port, 157 &snd_port->snd_stream); 158 } else { 159 pj_assert(!"Invalid dir"); 160 status = PJ_EBUG; 144 161 } 145 162 … … 177 194 178 195 /* 196 * Create bidirectional port. 197 */ 198 PJ_DEF(pj_status_t) pjmedia_snd_port_create( pj_pool_t *pool, 199 int rec_id, 200 int play_id, 201 unsigned clock_rate, 202 unsigned channel_count, 203 unsigned samples_per_frame, 204 unsigned bits_per_sample, 205 unsigned options, 206 pjmedia_snd_port **p_port) 207 { 208 pjmedia_snd_port *snd_port; 209 210 PJ_ASSERT_RETURN(pool && p_port, PJ_EINVAL); 211 PJ_ASSERT_RETURN(options == 0, PJ_EINVAL); 212 213 snd_port = pj_pool_zalloc(pool, sizeof(pjmedia_snd_port)); 214 PJ_ASSERT_RETURN(snd_port, PJ_ENOMEM); 215 216 snd_port->rec_id = rec_id; 217 snd_port->play_id = play_id; 218 snd_port->dir = PJMEDIA_DIR_CAPTURE_PLAYBACK; 219 snd_port->clock_rate = clock_rate; 220 snd_port->channel_count = channel_count; 221 snd_port->samples_per_frame = samples_per_frame; 222 snd_port->bits_per_sample = bits_per_sample; 223 224 *p_port = snd_port; 225 226 /* Start sound device immediately. 227 * If there's no port connected, the sound callback will return 228 * empty signal. 229 */ 230 return start_sound_device( snd_port ); 231 232 } 233 234 /* 179 235 * Create sound recorder port. 180 236 */ 181 237 PJ_DEF(pj_status_t) pjmedia_snd_port_create_rec( pj_pool_t *pool, 182 int index,238 int dev_id, 183 239 unsigned clock_rate, 184 240 unsigned channel_count, … … 196 252 PJ_ASSERT_RETURN(snd_port, PJ_ENOMEM); 197 253 198 snd_port-> snd_index = index;199 snd_port->dir = PJMEDIA_DIR_ ENCODING;254 snd_port->rec_id = dev_id; 255 snd_port->dir = PJMEDIA_DIR_CAPTURE; 200 256 snd_port->clock_rate = clock_rate; 201 257 snd_port->channel_count = channel_count; … … 217 273 */ 218 274 PJ_DEF(pj_status_t) pjmedia_snd_port_create_player( pj_pool_t *pool, 219 int index,275 int dev_id, 220 276 unsigned clock_rate, 221 277 unsigned channel_count, … … 233 289 PJ_ASSERT_RETURN(snd_port, PJ_ENOMEM); 234 290 235 snd_port-> snd_index = index;236 snd_port->dir = PJMEDIA_DIR_ DECODING;291 snd_port->play_id = dev_id; 292 snd_port->dir = PJMEDIA_DIR_PLAYBACK; 237 293 snd_port->clock_rate = clock_rate; 238 294 snd_port->channel_count = channel_count; … … 262 318 263 319 /* 320 * Retrieve the sound stream associated by this sound device port. 321 */ 322 PJ_DEF(pjmedia_snd_stream*) pjmedia_snd_port_get_snd_stream( 323 pjmedia_snd_port *snd_port) 324 { 325 PJ_ASSERT_RETURN(snd_port, NULL); 326 return snd_port->snd_stream; 327 } 328 329 330 /* 264 331 * Connect a port. 265 332 */ -
pjproject/trunk/pjsip-apps/src/samples/confsample.c
r350 r352 93 93 { 94 94 puts(""); 95 puts("Usage: confsample [file1.wav] [file2.wav] ..."); 96 puts(""); 97 puts("where:"); 98 puts(" fileN.WAV are optional WAV files to be connected to the conference"); 99 puts(" bridge. The WAV files MUST have single channel (mono) and 16 bit PCM"); 100 puts(" samples. They can have arbitrary/different sampling rate."); 95 puts(desc); 101 96 } 102 97
Note: See TracChangeset
for help on using the changeset viewer.