- Timestamp:
- Feb 5, 2009 10:59:14 AM (16 years ago)
- Location:
- pjproject/branches/projects/aps-direct
- Files:
-
- 1 added
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/branches/projects/aps-direct/build.symbian/bld.inf
r2434 r2438 21 21 libgsmcodec.mmp 22 22 libspeexcodec.mmp 23 libpassthroughcodec.mmp 23 24 24 25 /* Sound device impl */ -
pjproject/branches/projects/aps-direct/build.symbian/symbian_ua.mmp
r2434 r2438 35 35 STATICLIBRARY pjnath.lib pjlib_util.lib pjlib.lib 36 36 STATICLIBRARY libsrtp.lib 37 STATICLIBRARY libgsmcodec.lib libspeexcodec.lib 37 STATICLIBRARY libgsmcodec.lib libspeexcodec.lib libpassthroughcodec.lib 38 38 STATICLIBRARY symbian_audio.lib 39 39 -
pjproject/branches/projects/aps-direct/pjmedia/include/pjmedia-codec.h
r2394 r2438 32 32 #include <pjmedia-codec/g722.h> 33 33 #include <pjmedia-codec/ipp_codecs.h> 34 #include <pjmedia-codec/passthrough.h> 34 35 35 36 -
pjproject/branches/projects/aps-direct/pjmedia/include/pjmedia-codec/config.h
r2436 r2438 218 218 #ifndef PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMU 219 219 # define PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMU 1 220 #endif 221 222 #ifndef PJMEDIA_HAS_PASSTHROUGH_CODEC_G729 220 # undef PJMEDIA_HAS_G711_CODEC 221 #endif 222 223 #ifndef PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMA 223 224 # define PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMA 1 225 # undef PJMEDIA_HAS_G711_CODEC 224 226 #endif 225 227 -
pjproject/branches/projects/aps-direct/pjmedia/include/pjmedia/port.h
r2437 r2438 360 360 361 361 /** 362 * Pop out first n subframes from #pjmedia_frame_ext. 363 * 364 * @param frm The #pjmedia_frame_ext. 365 * @param n Number of first subframes to be popped out. 366 * 367 * @return PJ_SUCCESS, or PJ_ENOTFOUND if frame is empty. 368 */ 369 PJ_INLINE(pj_status_t) 370 pjmedia_frame_ext_pop_subframes(pjmedia_frame_ext *frm, unsigned n) 371 { 372 pjmedia_frame_ext_subframe *sf; 373 pj_uint8_t *move_src; 374 unsigned move_len; 375 376 if (frm->subframe_cnt <= n) { 377 frm->subframe_cnt = 0; 378 frm->samples_cnt = 0; 379 return PJ_SUCCESS; 380 } 381 382 move_src = (pj_uint8_t*)pjmedia_frame_ext_get_subframe(frm, n); 383 sf = pjmedia_frame_ext_get_subframe(frm, frm->subframe_cnt-1); 384 move_len = (pj_uint8_t*)sf - move_src + sf->bitlen/8; 385 if (sf->bitlen % 8 != 0) 386 ++move_len; 387 pj_memmove((pj_uint8_t*)frm+sizeof(pjmedia_frame_ext), 388 move_src, move_len); 389 390 frm->samples_cnt = (pj_uint16_t) 391 (frm->samples_cnt - n*frm->samples_cnt/frm->subframe_cnt); 392 frm->subframe_cnt = (pj_uint16_t) (frm->subframe_cnt - n); 393 394 return PJ_SUCCESS; 395 } 396 397 /** 362 398 * Port interface. 363 399 */ -
pjproject/branches/projects/aps-direct/pjmedia/include/pjmedia/sound.h
r2394 r2438 92 92 unsigned play_latency; /**< Playback latency, in samples. */ 93 93 } pjmedia_snd_stream_info; 94 95 96 /** 97 * Stream setting for opening sound device with non-PCM data. 98 */ 99 typedef struct pjmedia_snd_setting 100 { 101 pjmedia_fourcc format; /**< Format (FourCC ID). */ 102 pj_uint32_t bitrate; /**< Bitrate (bps). */ 103 pj_uint32_t mode; /**< Mode, e.g: iLBC format has 104 20ms or 30ms frame size. */ 105 pj_bool_t plc; /**< PLC enabled/disabled. */ 106 pj_bool_t vad; /**< VAD enabled/disabled. */ 107 pj_bool_t cng; /**< CNG enabled/disabled. */ 108 pj_bool_t loudspk; /**< Audio routed to loudspeaker. */ 109 } pjmedia_snd_setting; 94 110 95 111 … … 274 290 275 291 /** 292 * Create sound stream for capturing audio and/or audio playback, from the 293 * same device. This also allows opening sound stream with extended settings, 294 * e.g: stream format, see #pjmedia_snd_setting. 295 * 296 * @param dir Sound stream direction. 297 * @param rec_id Device index for recorder/capture stream, or 298 * -1 to use the first capable device. 299 * @param play_id Device index for playback stream, or -1 to use 300 * the first capable device. 301 * @param clock_rate Sound device's clock rate to set. 302 * @param channel_count Set number of channels, 1 for mono, or 2 for 303 * stereo. The channel count determines the format 304 * of the frame. 305 * @param samples_per_frame Number of samples per frame. 306 * @param bits_per_sample Set the number of bits per sample. The normal 307 * value for this parameter is 16 bits per sample. 308 * @param rec_cb Callback to handle captured audio samples. 309 * @param play_cb Callback to be called when the sound player needs 310 * more audio samples to play. 311 * @param user_data User data to be associated with the stream. 312 * @param setting Sound device extended setting. 313 * @param p_snd_strm Pointer to receive the stream instance. 314 * 315 * @return PJ_SUCCESS on success. 316 */ 317 PJ_DECL(pj_status_t) pjmedia_snd_open2( pjmedia_dir dir, 318 int rec_id, 319 int play_id, 320 unsigned clock_rate, 321 unsigned channel_count, 322 unsigned samples_per_frame, 323 unsigned bits_per_sample, 324 pjmedia_snd_rec_cb rec_cb, 325 pjmedia_snd_play_cb play_cb, 326 void *user_data, 327 const pjmedia_snd_setting *setting, 328 pjmedia_snd_stream **p_snd_strm); 329 330 331 /** 276 332 * Get information about live stream. 277 333 * -
pjproject/branches/projects/aps-direct/pjmedia/include/pjmedia/sound_port.h
r2394 r2438 160 160 unsigned options, 161 161 pjmedia_snd_port **p_port); 162 162 163 164 /** 165 * Create unidirectional or bidirectional sound port. This also allows 166 * creating sound port with extended settings, e.g: audio format, see 167 * #pjmedia_snd_setting. 168 * 169 * @param pool Pool to allocate sound port structure. 170 * @param dir Sound device direction. 171 * @param rec_id Device index for recorder/capture stream, or 172 * -1 to use the first capable device. 173 * @param play_id Device index for playback stream, or -1 to use 174 * the first capable device. 175 * @param clock_rate Sound device's clock rate to set. 176 * @param channel_count Set number of channels, 1 for mono, or 2 for 177 * stereo. The channel count determines the format 178 * of the frame. 179 * @param samples_per_frame Number of samples per frame. 180 * @param bits_per_sample Set the number of bits per sample. The normal 181 * value for this parameter is 16 bits per sample. 182 * @param setting Sound device extended settings, see 183 * #pjmedia_snd_setting. 184 * @param p_port Pointer to receive the sound device port instance. 185 * 186 * @return PJ_SUCCESS on success, or the appropriate error 187 * code. 188 */ 189 PJ_DECL(pj_status_t) pjmedia_snd_port_create2(pj_pool_t *pool, 190 pjmedia_dir dir, 191 int rec_id, 192 int play_id, 193 unsigned clock_rate, 194 unsigned channel_count, 195 unsigned samples_per_frame, 196 unsigned bits_per_sample, 197 const pjmedia_snd_setting *setting, 198 pjmedia_snd_port **p_port); 199 163 200 164 201 /** -
pjproject/branches/projects/aps-direct/pjmedia/include/pjmedia/symbian_sound_aps.h
r2434 r2438 54 54 * 55 55 * @param stream The sound device stream, the stream should be started 56 * before calling this function. This param can be NULL 57 * to set the behaviour of next opened stream. 56 * before calling this function. 58 57 * @param active Specify PJ_TRUE to activate loudspeaker, and PJ_FALSE 59 58 * otherwise. … … 65 64 pj_bool_t active); 66 65 67 68 /**69 * Set a codec and its settings to be used on the next sound device session.70 *71 * @param setting APS sound device setting, see @pjmedia_snd_aps_setting.72 *73 * @return PJ_SUCCESS on success.74 */75 PJ_DECL(pj_status_t) pjmedia_snd_aps_modify_setting(76 const pjmedia_snd_aps_setting *setting);77 78 79 66 PJ_END_DECL 80 67 -
pjproject/branches/projects/aps-direct/pjmedia/include/pjmedia/types.h
r2434 r2438 191 191 * FourCC packing macro. 192 192 */ 193 #define PJMEDIA_FOURCC_PACK(C1, C2, C3, C4) ( C 1<<24 | C2<<16 | C3<<8 | C4)193 #define PJMEDIA_FOURCC_PACK(C1, C2, C3, C4) ( C4<<24 | C3<<16 | C2<<8 | C1 ) 194 194 195 195 /** -
pjproject/branches/projects/aps-direct/pjmedia/src/pjmedia-codec/passthrough.c
r2436 r2438 460 460 codec_desc[i].channel_count / 461 461 codec_desc[i].clock_rate); 462 attr->info.format .u32 = codec_desc[i].format.u32;462 attr->info.format = codec_desc[i].format; 463 463 464 464 /* Default flags. */ 465 465 attr->setting.frm_per_pkt = codec_desc[i].frm_per_pkt; 466 attr->setting.plc = 1;466 attr->setting.plc = 0; 467 467 attr->setting.penh= 0; 468 attr->setting.vad = 1;468 attr->setting.vad = 0; 469 469 attr->setting.cng = attr->setting.vad; 470 470 attr->setting.dec_fmtp = codec_desc[i].dec_fmtp; … … 720 720 frames[count].timestamp.u64 = ts->u64 + count*desc->samples_per_frame; 721 721 722 pkt = ( (char*)pkt)+ codec_data->avg_frame_size;722 pkt = (pj_uint8_t*)pkt + codec_data->avg_frame_size; 723 723 pkt_size -= codec_data->avg_frame_size; 724 724 … … 800 800 pjmedia_frame_ext *output_ = (pjmedia_frame_ext*) output; 801 801 802 /* Check if input is formatted in pjmedia_frame */ 803 pj_assert(input && input->type == PJMEDIA_FRAME_TYPE_AUDIO); 802 pj_assert(input && input->size > 0); 804 803 805 804 #if PJMEDIA_HAS_PASSTHROUGH_CODEC_AMR … … 818 817 } 819 818 #endif 820 821 pj_bzero(output_, sizeof(pjmedia_frame_ext)); 822 output_->base.type = PJMEDIA_FRAME_TYPE_EXTENDED; 823 824 if (input && input->size > 0) { 825 PJ_ASSERT_RETURN(output_buf_len >= sizeof(pjmedia_frame_ext) + 826 sizeof(pjmedia_frame_ext_subframe) + 827 input->size, 828 PJMEDIA_CODEC_EFRMTOOSHORT); 829 830 pjmedia_frame_ext_append_subframe(output_, input->buf, 831 (pj_uint16_t)(input->size << 3), 832 (pj_uint16_t)desc->samples_per_frame); 833 } 819 /* 820 PJ_ASSERT_RETURN(output_buf_len >= sizeof(pjmedia_frame_ext) + 821 sizeof(pjmedia_frame_ext_subframe) + 822 input->size, 823 PJMEDIA_CODEC_EFRMTOOSHORT); 824 */ 825 826 pjmedia_frame_ext_append_subframe(output_, input->buf, 827 (pj_uint16_t)(input->size << 3), 828 (pj_uint16_t)desc->samples_per_frame); 834 829 835 830 return PJ_SUCCESS; … … 843 838 struct pjmedia_frame *output) 844 839 { 845 return codec_decode(codec, NULL, output_buf_len, output); 840 codec_private_t *codec_data = (codec_private_t*) codec->codec_data; 841 struct codec_desc *desc = &codec_desc[codec_data->codec_idx]; 842 pjmedia_frame_ext *output_ = (pjmedia_frame_ext*) output; 843 844 PJ_UNUSED_ARG(output_buf_len); 845 846 pjmedia_frame_ext_append_subframe(output_, NULL, 0, 847 (pj_uint16_t)desc->samples_per_frame); 848 849 return PJ_SUCCESS; 846 850 } 847 851 -
pjproject/branches/projects/aps-direct/pjmedia/src/pjmedia/conf_switch.c
r2437 r2438 997 997 (pjmedia_frame*)f_dst); 998 998 999 /* Update TX timestamp. */1000 pj_add_timestamp32(&cport_dst->ts_tx,1001 cport_dst->samples_per_frame);1002 1003 999 /* Reset TX buffer. */ 1004 1000 f_dst->subframe_cnt = 0; 1005 1001 f_dst->samples_cnt = 0; 1006 1002 } 1003 1004 /* Update TX timestamp. */ 1005 pj_add_timestamp32(&cport_dst->ts_tx, 1006 cport_dst->samples_per_frame); 1007 1007 1008 } 1008 1009 } … … 1037 1038 pjmedia_port_put_frame(cport_dst->port, frm_dst); 1038 1039 1039 /* Update TX timestamp. */1040 pj_add_timestamp32(&cport_dst->ts_tx,1041 cport_dst->samples_per_frame);1042 1043 1040 /* Reset TX buffer. */ 1044 1041 frm_dst->size = 0; 1045 1042 } 1043 1044 /* Update TX timestamp. */ 1045 pj_add_timestamp32(&cport_dst->ts_tx, 1046 cport_dst->samples_per_frame); 1046 1047 } 1047 1048 } … … 1063 1064 frm_dst->type = PJMEDIA_FRAME_TYPE_AUDIO; 1064 1065 frm_dst->size = cport_dst->samples_per_frame << 1; 1065 if (cport_dst->port) 1066 if (cport_dst->port) { 1066 1067 pjmedia_port_put_frame(cport_dst->port, frm_dst); 1068 1069 /* Reset TX buffer. */ 1070 frm_dst->size = 0; 1071 } 1067 1072 1068 1073 /* Update TX timestamp. */ 1069 1074 pj_add_timestamp32(&cport_dst->ts_tx, 1070 1075 cport_dst->samples_per_frame); 1071 1072 /* Reset TX buffer. */1073 frm_dst->size = 0;1074 1076 } 1075 1077 } else { … … 1080 1082 pjmedia_frame_ext_append_subframe(f_dst, NULL, 0, (pj_uint16_t) 1081 1083 (cport_dst->samples_per_frame- 1082 f_dst->samples_cnt));1083 if (cport_dst->port) 1084 f_dst->samples_cnt)); 1085 if (cport_dst->port) { 1084 1086 pjmedia_port_put_frame(cport_dst->port, frm_dst); 1087 1088 /* Reset TX buffer. */ 1089 f_dst->subframe_cnt = 0; 1090 f_dst->samples_cnt = 0; 1091 } 1085 1092 1086 1093 /* Update TX timestamp. */ 1087 1094 pj_add_timestamp32(&cport_dst->ts_tx, 1088 1095 cport_dst->samples_per_frame); 1089 1090 /* Reset TX buffer. */1091 f_dst->subframe_cnt = 0;1092 f_dst->samples_cnt = 0;1093 1096 } 1094 1097 } … … 1096 1099 /* Synchronize clock. */ 1097 1100 while (pj_cmp_timestamp(&cport_dst->ts_clock, 1098 &cport_dst->ts_tx) > =0)1101 &cport_dst->ts_tx) > 0) 1099 1102 { 1100 if (cport_dst->port) {1101 frm_dst->type = PJMEDIA_FRAME_TYPE_NONE;1102 frm_dst->timestamp = cport_dst->ts_tx;1103 frm_dst->type = PJMEDIA_FRAME_TYPE_NONE; 1104 frm_dst->timestamp = cport_dst->ts_tx; 1105 if (cport_dst->port) 1103 1106 pjmedia_port_put_frame(cport_dst->port, frm_dst); 1104 } 1107 1108 /* Update TX timestamp. */ 1105 1109 pj_add_timestamp32(&cport_dst->ts_tx, cport_dst->samples_per_frame); 1106 1110 } … … 1235 1239 cport->tx_level = 0; 1236 1240 1237 while (pj_cmp_timestamp(&cport->ts_clock, &cport->ts_tx) > =0)1241 while (pj_cmp_timestamp(&cport->ts_clock, &cport->ts_tx) > 0) 1238 1242 { 1239 1243 if (cport->tx_setting == PJMEDIA_PORT_ENABLE) { … … 1265 1269 pj_uint16_t samples_per_subframe; 1266 1270 1271 if (f_src_->samples_cnt < this_cport->samples_per_frame) { 1272 pj_bzero(this_cport->tx_buf, sizeof(pjmedia_frame_ext)); 1273 frame->type = PJMEDIA_FRAME_TYPE_NONE; 1274 break; 1275 } 1276 1267 1277 f_dst->samples_cnt = 0; 1268 1278 f_dst->subframe_cnt = 0; … … 1270 1280 samples_per_subframe = f_src_->samples_cnt / f_src_->subframe_cnt; 1271 1281 1282 1272 1283 while (f_dst->samples_cnt < this_cport->samples_per_frame) { 1273 1284 sf = pjmedia_frame_ext_get_subframe(f_src_, i++); 1285 pj_assert(sf); 1274 1286 pjmedia_frame_ext_append_subframe(f_dst, sf->data, sf->bitlen, 1275 1287 samples_per_subframe); … … 1277 1289 1278 1290 /* Shift left TX buffer. */ 1279 sf = pjmedia_frame_ext_get_subframe(f_src_, i); 1280 if (sf) { 1281 pjmedia_frame_ext_subframe *sf_end; 1282 unsigned len; 1283 1284 sf_end = pjmedia_frame_ext_get_subframe(f_src_, 1285 f_src_->subframe_cnt -1); 1286 len = (pj_uint8_t*)sf_end - (pj_uint8_t*)sf + sf_end->bitlen/8; 1287 if (sf_end->bitlen % 8 != 0) 1288 ++len; 1289 pj_memmove(this_cport->tx_buf + sizeof(pjmedia_frame_ext), sf, 1290 len); 1291 pjmedia_frame_ext_pop_subframes(f_src_, i); 1292 1293 } else if (f_src->type == PJMEDIA_FRAME_TYPE_AUDIO) { 1294 if ((f_src->size>>1) < this_cport->samples_per_frame) { 1295 pj_bzero(this_cport->tx_buf, sizeof(pjmedia_frame_ext)); 1296 frame->type = PJMEDIA_FRAME_TYPE_NONE; 1297 break; 1291 1298 } 1292 f_src_->samples_cnt = f_src_->samples_cnt - 1293 (pj_uint16_t)(i * samples_per_subframe); 1294 f_src_->subframe_cnt = f_src_->subframe_cnt - (pj_uint16_t)i; 1295 1296 } else if (f_src->type == PJMEDIA_FRAME_TYPE_AUDIO) { 1299 1297 1300 pjmedia_copy_samples((pj_int16_t*)frame->buf, 1298 1301 (pj_int16_t*)f_src->buf, … … 1307 1310 this_cport->samples_per_frame, 1308 1311 f_src->size >> 1); 1312 } else { /* PJMEDIA_FRAME_TYPE_NONE */ 1313 /* Reset TX buffer */ 1314 pj_bzero(this_cport->tx_buf, sizeof(pjmedia_frame_ext)); 1315 frame->type = PJMEDIA_FRAME_TYPE_NONE; 1309 1316 } 1310 1317 } while (0); … … 1326 1333 unsigned j; 1327 1334 pj_int32_t level; 1328 1329 /* Check for correct size. */1330 PJ_ASSERT_RETURN( f->size == conf->samples_per_frame *1331 conf->bits_per_sample / 8,1332 PJMEDIA_ENCSAMPLESPFRAME);1333 1335 1334 1336 pj_add_timestamp32(&cport->ts_rx, cport->samples_per_frame); -
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 -
pjproject/branches/projects/aps-direct/pjmedia/src/pjmedia/stream.c
r2394 r2438 411 411 412 412 413 /* The other version of get_frame callback used when stream port format 414 * is non linear PCM. 415 */ 416 static pj_status_t get_frame_ext( pjmedia_port *port, pjmedia_frame *frame) 417 { 418 pjmedia_stream *stream = (pjmedia_stream*) port->port_data.pdata; 419 pjmedia_channel *channel = stream->dec; 420 pjmedia_frame_ext *f = (pjmedia_frame_ext*)frame; 421 unsigned samples_per_frame, samples_required; 422 pj_status_t status; 423 424 /* Return no frame if channel is paused */ 425 if (channel->paused) { 426 frame->type = PJMEDIA_FRAME_TYPE_NONE; 427 return PJ_SUCCESS; 428 } 429 430 /* Repeat get frame from the jitter buffer and decode the frame 431 * until we have enough frames according to codec's ptime. 432 */ 433 434 samples_required = stream->port.info.samples_per_frame; 435 samples_per_frame = stream->codec_param.info.frm_ptime * 436 stream->codec_param.info.clock_rate * 437 stream->codec_param.info.channel_cnt / 438 1000; 439 440 pj_bzero(f, sizeof(pjmedia_frame_ext)); 441 f->base.type = PJMEDIA_FRAME_TYPE_EXTENDED; 442 443 while (f->samples_cnt < samples_required) { 444 char frame_type; 445 pj_size_t frame_size; 446 pj_uint32_t bit_info; 447 448 /* Lock jitter buffer mutex first */ 449 pj_mutex_lock( stream->jb_mutex ); 450 451 /* Get frame from jitter buffer. */ 452 pjmedia_jbuf_get_frame2(stream->jb, channel->out_pkt, &frame_size, 453 &frame_type, &bit_info); 454 455 /* Unlock jitter buffer mutex. */ 456 pj_mutex_unlock( stream->jb_mutex ); 457 458 if (frame_type == PJMEDIA_JB_NORMAL_FRAME) { 459 /* Got "NORMAL" frame from jitter buffer */ 460 pjmedia_frame frame_in; 461 462 /* Decode */ 463 frame_in.buf = channel->out_pkt; 464 frame_in.size = frame_size; 465 frame_in.bit_info = bit_info; 466 frame_in.type = PJMEDIA_FRAME_TYPE_AUDIO; 467 468 status = stream->codec->op->decode( stream->codec, &frame_in, 469 0, frame); 470 if (status != PJ_SUCCESS) { 471 LOGERR_((port->info.name.ptr, "codec decode() error", 472 status)); 473 pjmedia_frame_ext_append_subframe(f, NULL, 0, 474 (pj_uint16_t)samples_per_frame); 475 } 476 } else { 477 status = (*stream->codec->op->recover)(stream->codec, 478 0, frame); 479 if (status != PJ_SUCCESS) { 480 pjmedia_frame_ext_append_subframe(f, NULL, 0, 481 (pj_uint16_t)samples_per_frame); 482 } 483 484 if (frame_type == PJMEDIA_JB_MISSING_FRAME) { 485 PJ_LOG(1,(stream->port.info.name.ptr, "Frame lost!")); 486 } else if (frame_type == PJMEDIA_JB_ZERO_EMPTY_FRAME) { 487 /* Jitter buffer is empty. Check if this is the first "empty" 488 * state. 489 */ 490 if (frame_type != stream->jb_last_frm) { 491 pjmedia_jb_state jb_state; 492 493 /* Report the state of jitter buffer */ 494 pjmedia_jbuf_get_state(stream->jb, &jb_state); 495 PJ_LOG(1,(stream->port.info.name.ptr, 496 "Jitter buffer empty (prefetch=%d)", 497 jb_state.prefetch)); 498 } 499 } else { 500 pjmedia_jb_state jb_state; 501 502 /* It can only be PJMEDIA_JB_ZERO_PREFETCH frame */ 503 pj_assert(frame_type == PJMEDIA_JB_ZERO_PREFETCH_FRAME); 504 505 /* Get the state of jitter buffer */ 506 pjmedia_jbuf_get_state(stream->jb, &jb_state); 507 508 if (stream->jb_last_frm != frame_type) { 509 PJ_LOG(1,(stream->port.info.name.ptr, 510 "Jitter buffer is bufferring (prefetch=%d)", 511 jb_state.prefetch)); 512 } 513 } 514 } 515 516 stream->jb_last_frm = frame_type; 517 } 518 519 return PJ_SUCCESS; 520 } 521 522 413 523 /* 414 524 * Transmit DTMF … … 689 799 if (frame->type == PJMEDIA_FRAME_TYPE_AUDIO) 690 800 ts_len = (frame->size >> 1) / stream->codec_param.info.channel_cnt; 801 else if (frame->type == PJMEDIA_FRAME_TYPE_EXTENDED) 802 ts_len = stream->port.info.samples_per_frame / 803 stream->port.info.channel_count; 691 804 else 692 805 ts_len = 0; … … 755 868 } else if (frame->type == PJMEDIA_FRAME_TYPE_AUDIO && 756 869 frame->buf == NULL && 870 (stream->port.info.format.u32 == 0 || 871 stream->port.info.format.u32 == PJMEDIA_FOURCC_L16) && 757 872 (stream->dir & PJMEDIA_DIR_ENCODING) && 758 873 stream->codec_param.info.frm_ptime * … … 1492 1607 stream->port.info.clock_rate = info->fmt.clock_rate; 1493 1608 stream->port.info.channel_count = info->fmt.channel_cnt; 1609 stream->port.info.format = info->param->info.format; 1494 1610 stream->port.port_data.pdata = stream; 1495 stream->port.put_frame = &put_frame; 1496 stream->port.get_frame = &get_frame; 1611 if (stream->port.info.format.u32 == 0 || 1612 stream->port.info.format.u32 == PJMEDIA_FOURCC_L16) 1613 { 1614 stream->port.put_frame = &put_frame; 1615 stream->port.get_frame = &get_frame; 1616 } else { 1617 stream->port.put_frame = &put_frame; 1618 stream->port.get_frame = &get_frame_ext; 1619 } 1497 1620 1498 1621 -
pjproject/branches/projects/aps-direct/pjmedia/src/pjmedia/symbian_sound_aps.cpp
r2434 r2438 18 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 19 */ 20 #include <pjmedia/sound.h> 20 21 #include <pjmedia/symbian_sound_aps.h> 21 #include <pjmedia/sound.h>22 22 #include <pjmedia/alaw_ulaw.h> 23 23 #include <pjmedia/errno.h> 24 #include <pjmedia/port.h> 24 25 #include <pj/assert.h> 25 26 #include <pj/log.h> … … 59 60 /* App UID to open global APS queues to communicate with the APS server. */ 60 61 extern TPtrC APP_UID; 61 62 /* Default setting */63 static pjmedia_snd_aps_setting def_setting;64 62 65 63 /* APS G.711 frame length */ … … 88 86 pjmedia_snd_play_cb play_cb; 89 87 void *user_data; 88 pjmedia_snd_setting setting; 90 89 91 90 // Audio engine … … 405 404 // the client session. 406 405 TTime start, now; 407 enum { APS_CLOSE_WAIT_TIME = 200 }; 406 enum { APS_CLOSE_WAIT_TIME = 200 }; /* in msecs */ 407 408 408 start.UniversalTime(); 409 now.UniversalTime(); 410 while (now.MicroSecondsFrom(start) < APS_CLOSE_WAIT_TIME * 1000) { 409 do { 411 410 pj_symbianos_poll(-1, APS_CLOSE_WAIT_TIME); 412 411 now.UniversalTime(); 413 } 412 } while (now.MicroSecondsFrom(start) < APS_CLOSE_WAIT_TIME * 1000); 414 413 415 414 iSession.Close(); … … 618 617 pjmedia_snd_stream *strm = (pjmedia_snd_stream*) user_data; 619 618 619 /* Buffer has to contain normal speech. */ 620 620 pj_assert(buf.iBuffer[0] == 1 && buf.iBuffer[1] == 0); 621 621 … … 660 660 unsigned g711_frame_len = aps_g711_frame_len; 661 661 662 /* Init buffer attributes and header. */ 662 663 buf.iCommand = CQueueHandler::EAPSPlayData; 663 664 buf.iStatus = 0; … … 697 698 static void RecCb(TAPSCommBuffer &buf, void *user_data) 698 699 { 700 pjmedia_snd_stream *strm = (pjmedia_snd_stream*) user_data; 701 pjmedia_frame_ext *frame = (pjmedia_frame_ext*) strm->rec_buf; 702 unsigned samples_processed = 0; 703 704 switch(strm->setting.format.u32) { 705 706 case PJMEDIA_FOURCC_G711U: 707 case PJMEDIA_FOURCC_G711A: 708 pj_assert(buf.iBuffer[0] == 1 && buf.iBuffer[1] == 0); 709 710 /* Detect the recorder G.711 frame size, player frame size will follow 711 * this recorder frame size. 712 */ 713 if (aps_g711_frame_len == 0) { 714 aps_g711_frame_len = buf.iBuffer.Length() < 160? 80 : 160; 715 TRACE_((THIS_FILE, "Detected APS G.711 frame size = %u samples", 716 aps_g711_frame_len)); 717 } 718 719 /* Convert APS buffer format into pjmedia_frame_ext. Whenever 720 * samples count in the frame is equal to stream's samples per frame, 721 * call parent stream callback. 722 */ 723 while (samples_processed < aps_g711_frame_len) { 724 unsigned tmp; 725 const pj_uint8_t *pb = (const pj_uint8_t*)buf.iBuffer.Ptr() + 2 + 726 samples_processed; 727 728 tmp = PJ_MIN(strm->samples_per_frame - frame->samples_cnt, 729 aps_g711_frame_len - samples_processed); 730 731 pjmedia_frame_ext_append_subframe(frame, pb, tmp << 3, tmp); 732 samples_processed += tmp; 733 734 if (frame->samples_cnt == strm->samples_per_frame) { 735 frame->base.type = PJMEDIA_FRAME_TYPE_EXTENDED; 736 strm->rec_cb(strm->user_data, 0, strm->rec_buf, 0); 737 frame->samples_cnt = 0; 738 frame->subframe_cnt = 0; 739 } 740 } 741 break; 742 743 default: 744 break; 745 } 699 746 } 700 747 701 748 static void PlayCb(TAPSCommBuffer &buf, void *user_data) 702 749 { 750 pjmedia_snd_stream *strm = (pjmedia_snd_stream*) user_data; 751 pjmedia_frame_ext *frame = (pjmedia_frame_ext*) strm->play_buf; 752 unsigned g711_frame_len = aps_g711_frame_len; 753 unsigned samples_ready = 0; 754 755 /* Init buffer attributes and header. */ 756 buf.iCommand = CQueueHandler::EAPSPlayData; 757 buf.iStatus = 0; 758 buf.iBuffer.Zero(); 759 760 switch(strm->setting.format.u32) { 761 762 case PJMEDIA_FOURCC_G711U: 763 case PJMEDIA_FOURCC_G711A: 764 /* Add header. */ 765 buf.iBuffer.Append(1); 766 buf.iBuffer.Append(0); 767 768 /* Assume frame size is 10ms if frame size hasn't been known. */ 769 if (g711_frame_len == 0) 770 g711_frame_len = 80; 771 772 /* Call parent stream callback to get samples to play. */ 773 while (samples_ready < g711_frame_len) { 774 if (frame->samples_cnt == 0) { 775 frame->base.type = PJMEDIA_FRAME_TYPE_EXTENDED; 776 strm->play_cb(strm->user_data, 0, strm->play_buf, 777 strm->samples_per_frame<<1); 778 779 pj_assert(frame->base.type == PJMEDIA_FRAME_TYPE_EXTENDED || 780 frame->base.type == PJMEDIA_FRAME_TYPE_NONE); 781 } 782 783 if (frame->base.type == PJMEDIA_FRAME_TYPE_EXTENDED) { 784 pjmedia_frame_ext_subframe *sf; 785 unsigned samples_cnt; 786 787 sf = pjmedia_frame_ext_get_subframe(frame, 0); 788 samples_cnt = frame->samples_cnt / frame->subframe_cnt; 789 if (sf->data && sf->bitlen) 790 buf.iBuffer.Append((TUint8*)sf->data, sf->bitlen>>3); 791 else 792 buf.iBuffer.AppendFill(0, samples_cnt); 793 samples_ready += samples_cnt; 794 795 pjmedia_frame_ext_pop_subframes(frame, 1); 796 797 } else { /* PJMEDIA_FRAME_TYPE_NONE */ 798 buf.iBuffer.AppendFill(0, g711_frame_len - samples_ready); 799 samples_ready = g711_frame_len; 800 frame->samples_cnt = 0; 801 frame->subframe_cnt = 0; 802 } 803 } 804 break; 805 806 default: 807 break; 808 } 809 810 unsigned tes = buf.iBuffer.Length(); 703 811 } 704 812 … … 709 817 { 710 818 snd_pool_factory = factory; 711 712 def_setting.format.u32 = PJMEDIA_FOURCC_L16;713 def_setting.mode = 0;714 def_setting.bitrate = 128000;715 def_setting.plc = PJ_FALSE;716 def_setting.vad = PJ_FALSE;717 def_setting.cng = PJ_FALSE;718 def_setting.loudspk = PJ_FALSE;719 819 720 820 return PJ_SUCCESS; … … 751 851 pjmedia_snd_play_cb play_cb, 752 852 void *user_data, 853 const pjmedia_snd_setting *setting, 753 854 pjmedia_snd_stream **p_snd_strm) 754 855 { 755 856 pj_pool_t *pool; 756 857 pjmedia_snd_stream *strm; 757 CPjAudioSetting setting;858 CPjAudioSetting aps_setting; 758 859 PjAudioCallback aps_rec_cb; 759 860 PjAudioCallback aps_play_cb; … … 779 880 strm->channel_count = channel_count; 780 881 strm->samples_per_frame = samples_per_frame; 882 strm->setting = *setting; 883 884 if (strm->setting.format.u32 == 0) 885 strm->setting.format.u32 = PJMEDIA_FOURCC_L16; 781 886 782 887 /* Set audio engine settings. */ 783 if ( def_setting.format.u32 == PJMEDIA_FOURCC_G711U ||784 def_setting.format.u32 == PJMEDIA_FOURCC_L16)888 if (strm->setting.format.u32 == PJMEDIA_FOURCC_G711U || 889 strm->setting.format.u32 == PJMEDIA_FOURCC_L16) 785 890 { 786 setting.fourcc = TFourCC(KMCPFourCCIdG711);891 aps_setting.fourcc = TFourCC(KMCPFourCCIdG711); 787 892 } else { 788 setting.fourcc = TFourCC(def_setting.format.u32);789 } 790 791 if ( def_setting.format.u32 == PJMEDIA_FOURCC_AMR)893 aps_setting.fourcc = TFourCC(strm->setting.format.u32); 894 } 895 896 if (strm->setting.format.u32 == PJMEDIA_FOURCC_AMR) 792 897 { 793 setting.mode = (TAPSCodecMode)def_setting.bitrate;794 } else if ( def_setting.format.u32 == PJMEDIA_FOURCC_G711U ||795 def_setting.format.u32 == PJMEDIA_FOURCC_L16 ||796 ( def_setting.format.u32 == PJMEDIA_FOURCC_ILBC &&797 def_setting.mode == 30))898 aps_setting.mode = (TAPSCodecMode)strm->setting.bitrate; 899 } else if (strm->setting.format.u32 == PJMEDIA_FOURCC_G711U || 900 strm->setting.format.u32 == PJMEDIA_FOURCC_L16 || 901 (strm->setting.format.u32 == PJMEDIA_FOURCC_ILBC && 902 strm->setting.mode == 30)) 798 903 { 799 setting.mode = EULawOr30ms;904 aps_setting.mode = EULawOr30ms; 800 905 } else { 801 setting.mode = EALawOr20ms; 802 } 803 804 setting.vad = def_setting.vad; 805 setting.plc = def_setting.plc; 806 setting.cng = def_setting.cng; 807 setting.loudspk = def_setting.loudspk; 808 809 if (def_setting.format.u32 == PJMEDIA_FOURCC_AMR || 810 def_setting.format.u32 == PJMEDIA_FOURCC_G711A || 811 def_setting.format.u32 == PJMEDIA_FOURCC_G711U || 812 def_setting.format.u32 == PJMEDIA_FOURCC_G729 || 813 def_setting.format.u32 == PJMEDIA_FOURCC_ILBC) 814 { 906 aps_setting.mode = EALawOr20ms; 907 } 908 909 aps_setting.vad = strm->setting.format.u32==PJMEDIA_FOURCC_L16? 910 EFalse : strm->setting.vad; 911 aps_setting.plc = strm->setting.plc; 912 aps_setting.cng = strm->setting.cng; 913 aps_setting.loudspk = strm->setting.loudspk; 914 915 if (strm->setting.format.u32 == PJMEDIA_FOURCC_L16) { 916 aps_play_cb = &PlayCbPcm; 917 aps_rec_cb = &RecCbPcm; 918 } else { 815 919 aps_play_cb = &PlayCb; 816 920 aps_rec_cb = &RecCb; 817 } else {818 aps_play_cb = &PlayCbPcm;819 aps_rec_cb = &RecCbPcm;820 921 } 821 922 … … 823 924 TRAPD(err, strm->engine = CPjAudioEngine::NewL(strm, 824 925 aps_rec_cb, aps_play_cb, 825 strm, setting));926 strm, aps_setting)); 826 927 if (err != KErrNone) { 827 928 pj_pool_release(pool); … … 834 935 835 936 /* play_buf size is samples per frame. */ 836 strm->play_buf = (pj_int16_t*)pj_pool_ alloc(pool, samples_per_frame << 1);937 strm->play_buf = (pj_int16_t*)pj_pool_zalloc(pool, samples_per_frame << 1); 837 938 strm->play_buf_len = 0; 838 939 strm->play_buf_start = 0; 839 940 840 941 /* rec_buf size is samples per frame. */ 841 strm->rec_buf = (pj_int16_t*)pj_pool_ alloc(pool, samples_per_frame << 1);942 strm->rec_buf = (pj_int16_t*)pj_pool_zalloc(pool, samples_per_frame << 1); 842 943 strm->rec_buf_len = 0; 843 944 … … 861 962 pjmedia_snd_stream **p_snd_strm) 862 963 { 964 pjmedia_snd_setting setting; 965 863 966 if (index < 0) index = 0; 864 967 PJ_ASSERT_RETURN(index == 0, PJ_EINVAL); 865 968 969 pj_bzero(&setting, sizeof(setting)); 970 setting.format.u32 = PJMEDIA_FOURCC_L16; 971 setting.bitrate = 128000; 972 866 973 return sound_open(PJMEDIA_DIR_CAPTURE, clock_rate, channel_count, 867 974 samples_per_frame, bits_per_sample, rec_cb, NULL, 868 user_data, p_snd_strm);975 user_data, &setting, p_snd_strm); 869 976 } 870 977 … … 878 985 pjmedia_snd_stream **p_snd_strm ) 879 986 { 987 pjmedia_snd_setting setting; 988 880 989 if (index < 0) index = 0; 881 990 PJ_ASSERT_RETURN(index == 0, PJ_EINVAL); 882 991 992 pj_bzero(&setting, sizeof(setting)); 993 setting.format.u32 = PJMEDIA_FOURCC_L16; 994 setting.bitrate = 128000; 995 883 996 return sound_open(PJMEDIA_DIR_PLAYBACK, clock_rate, channel_count, 884 997 samples_per_frame, bits_per_sample, NULL, play_cb, 885 user_data, p_snd_strm);998 user_data, &setting, p_snd_strm); 886 999 } 887 1000 … … 897 1010 pjmedia_snd_stream **p_snd_strm) 898 1011 { 1012 pjmedia_snd_setting setting; 1013 899 1014 if (rec_id < 0) rec_id = 0; 900 1015 if (play_id < 0) play_id = 0; 901 1016 PJ_ASSERT_RETURN(play_id == 0 && rec_id == 0, PJ_EINVAL); 902 1017 1018 pj_bzero(&setting, sizeof(setting)); 1019 setting.format.u32 = PJMEDIA_FOURCC_L16; 1020 setting.bitrate = 128000; 1021 903 1022 return sound_open(PJMEDIA_DIR_CAPTURE_PLAYBACK, clock_rate, channel_count, 904 1023 samples_per_frame, bits_per_sample, rec_cb, play_cb, 905 user_data, p_snd_strm); 1024 user_data, &setting, p_snd_strm); 1025 } 1026 1027 PJ_DEF(pj_status_t) pjmedia_snd_open2( pjmedia_dir dir, 1028 int rec_id, 1029 int play_id, 1030 unsigned clock_rate, 1031 unsigned channel_count, 1032 unsigned samples_per_frame, 1033 unsigned bits_per_sample, 1034 pjmedia_snd_rec_cb rec_cb, 1035 pjmedia_snd_play_cb play_cb, 1036 void *user_data, 1037 const pjmedia_snd_setting *setting, 1038 pjmedia_snd_stream **p_snd_strm) 1039 { 1040 if (rec_id < 0) rec_id = 0; 1041 if (play_id < 0) play_id = 0; 1042 PJ_ASSERT_RETURN(play_id == 0 && rec_id == 0, PJ_EINVAL); 1043 1044 return sound_open(dir, clock_rate, channel_count, 1045 samples_per_frame, bits_per_sample, rec_cb, play_cb, 1046 user_data, setting, p_snd_strm); 906 1047 } 907 1048 … … 994 1135 } 995 1136 996 997 1137 /* 998 1138 * Activate/deactivate loudspeaker. … … 1002 1142 pj_bool_t active) 1003 1143 { 1004 if (stream == NULL) { 1005 def_setting.loudspk = active; 1006 } else { 1007 if (stream->engine == NULL) 1008 return PJ_EINVAL; 1009 1010 TInt err = stream->engine->ActivateSpeaker(active); 1011 if (err != KErrNone) 1012 return PJ_RETURN_OS_ERROR(err); 1013 } 1144 PJ_ASSERT_RETURN(stream && stream->engine, PJ_EINVAL); 1145 1146 TInt err = stream->engine->ActivateSpeaker(active); 1147 if (err != KErrNone) 1148 return PJ_RETURN_OS_ERROR(err); 1014 1149 1015 1150 return PJ_SUCCESS; 1016 1151 } 1017 1152 1018 /**1019 * Set a codec and its settings to be used on the next sound device session.1020 */1021 PJ_DEF(pj_status_t) pjmedia_snd_aps_modify_setting(1022 const pjmedia_snd_aps_setting *setting)1023 {1024 PJ_ASSERT_RETURN(setting, PJ_EINVAL);1025 1026 def_setting = *setting;1027 1028 return PJ_SUCCESS;1029 }1030 1031 1153 #endif // PJMEDIA_SOUND_IMPLEMENTATION == PJMEDIA_SOUND_SYMB_APS_SOUND -
pjproject/branches/projects/aps-direct/pjsip-apps/src/symbian_ua/ua.cpp
r2394 r2438 91 91 static pjsua_buddy_id g_buddy_id = PJSUA_INVALID_ID; 92 92 93 static pj_pool_t *app_pool; 94 static pjmedia_snd_port *snd_port; 95 93 96 94 97 /* Callback called by the library upon receiving incoming call */ … … 130 133 if (call_id == g_call_id) 131 134 g_call_id = PJSUA_INVALID_ID; 135 if (snd_port) { 136 pjmedia_snd_port_destroy(snd_port); 137 snd_port = NULL; 138 } 132 139 } else if (ci.state != PJSIP_INV_STATE_INCOMING) { 133 140 if (g_call_id == PJSUA_INVALID_ID) … … 250 257 } 251 258 259 /* Notification that stream is created. */ 260 static void on_stream_created(pjsua_call_id call_id, 261 pjmedia_session *sess, 262 unsigned stream_idx, 263 pjmedia_port **p_port) 264 { 265 pjmedia_port *conf; 266 pjmedia_session_info sess_info; 267 pjmedia_stream_info *strm_info; 268 pjmedia_snd_setting setting; 269 unsigned samples_per_frame; 270 pj_status_t status; 271 272 status = pjmedia_session_get_info(sess, &sess_info); 273 if (status != PJ_SUCCESS) { 274 PJ_LOG(1,(THIS_FILE, "on_stream_created() failed to get session info, " 275 "status=%d", status)); 276 return; 277 } 278 279 strm_info = &sess_info.stream_info[stream_idx]; 280 if (strm_info->type != PJMEDIA_TYPE_AUDIO) 281 return; 282 283 /* Don't need to reopen sound device when the session doesn't use 284 * PCM format. 285 */ 286 if (strm_info->param->info.format.u32 == 0 || 287 strm_info->param->info.format.u32 == PJMEDIA_FOURCC_L16) 288 { 289 return; 290 } 291 292 pj_bzero(&setting, sizeof(setting)); 293 setting.format = strm_info->param->info.format; 294 setting.bitrate = strm_info->param->info.avg_bps; 295 setting.cng = strm_info->param->setting.cng; 296 setting.vad = strm_info->param->setting.vad; 297 setting.plc = strm_info->param->setting.plc; 298 299 /* Reopen sound device. */ 300 conf = pjsua_set_no_snd_dev(); 301 302 samples_per_frame = conf->info.samples_per_frame; 303 304 status = pjmedia_snd_port_create2(app_pool, 305 PJMEDIA_DIR_CAPTURE_PLAYBACK, 306 0, 307 0, 308 8000, 309 1, 310 samples_per_frame, 311 16, 312 &setting, 313 &snd_port); 314 if (status != PJ_SUCCESS) { 315 PJ_LOG(1,(THIS_FILE, "on_stream_created() failed to reopen sound " 316 "device, status=%d", status)); 317 return; 318 } 319 320 status = pjmedia_snd_port_connect(snd_port, conf); 321 if (status != PJ_SUCCESS) { 322 PJ_LOG(1,(THIS_FILE, "on_stream_created() failed to connect sound " 323 "device to conference, status=%d", status)); 324 return; 325 } 326 } 252 327 253 328 //#include<e32debug.h> … … 290 365 } 291 366 367 /* Create pool for application */ 368 app_pool = pjsua_pool_create("pjsua-app", 1000, 1000); 369 292 370 /* Init pjsua */ 293 371 pjsua_config cfg; … … 310 388 cfg.cb.on_call_replaced = &on_call_replaced; 311 389 cfg.cb.on_nat_detect = &on_nat_detect; 390 cfg.cb.on_stream_created = &on_stream_created; 312 391 313 392 if (SIP_PROXY) { … … 338 417 med_cfg.has_ioqueue = PJ_FALSE; 339 418 med_cfg.clock_rate = 8000; 340 #if defined(PJMEDIA_SYM_SND_USE_APS) && (PJMEDIA_SYM_SND_USE_APS==1)341 med_cfg.audio_frame_ptime = 20;342 #else343 419 med_cfg.audio_frame_ptime = 40; 344 #endif345 420 med_cfg.ec_tail_len = 0; 346 421 med_cfg.enable_ice = USE_ICE; 347 med_cfg.snd_auto_close_time = 5; // wait for 5seconds idle before sound dev get auto-closed422 med_cfg.snd_auto_close_time = 0; // wait for 0 seconds idle before sound dev get auto-closed 348 423 349 424 status = pjsua_init(&cfg, &log_cfg, &med_cfg); … … 803 878 #endif 804 879 880 // Let pjsua destroys app pool, since the pool may still be used by app 881 // until pjsua_destroy() finished. 882 // e.g: quitting app when there is an active call may cause sound port 883 // memory destroyed before sound port itself gets closed/destroyed. 884 /* 885 // Release application pool 886 if (app_pool) { 887 pj_pool_release(app_pool); 888 app_pool = NULL; 889 } 890 */ 891 805 892 // Shutdown pjsua 806 893 pjsua_destroy(); -
pjproject/branches/projects/aps-direct/pjsip/src/pjsua-lib/pjsua_media.c
r2425 r2438 173 173 #endif /* PJMEDIA_HAS_INTEL_IPP */ 174 174 175 #if PJMEDIA_HAS_PASSTHROUGH_CODECS 176 /* Register passthrough codecs */ 177 status = pjmedia_codec_passthrough_init(pjsua_var.med_endpt); 178 if (status != PJ_SUCCESS) { 179 pjsua_perror(THIS_FILE, "Error initializing passthrough codecs", 180 status); 181 return status; 182 } 183 #endif /* PJMEDIA_HAS_PASSTHROUGH_CODECS */ 184 175 185 #if PJMEDIA_HAS_L16_CODEC 176 186 /* Register L16 family codecs, but disable all */ … … 574 584 pjmedia_codec_ipp_deinit(); 575 585 # endif /* PJMEDIA_HAS_INTEL_IPP */ 586 587 # if PJMEDIA_HAS_PASSTHROUGH_CODECS 588 pjmedia_codec_passthrough_deinit(); 589 # endif /* PJMEDIA_HAS_PASSTHROUGH_CODECS */ 576 590 577 591 # if PJMEDIA_HAS_L16_CODEC
Note: See TracChangeset
for help on using the changeset viewer.