Changeset 2416
- Timestamp:
- Jan 5, 2009 3:27:02 PM (16 years ago)
- Location:
- pjproject/trunk/pjmedia
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/include/pjmedia/alaw_ulaw.h
r2394 r2416 140 140 #endif 141 141 142 /** 143 * Encode 16-bit linear PCM data to 8-bit U-Law data. 144 * 145 * @param dst Destination buffer for 8-bit U-Law data. 146 * @param src Source, 16-bit linear PCM data. 147 * @param len Number of samples. 148 */ 149 PJ_INLINE(void) pjmedia_ulaw_encode(pj_uint8_t *dst, const pj_int16_t *src, 150 pj_size_t len) 151 { 152 const pj_int16_t *end = src + len; 153 154 while (src < end) { 155 *dst++ = pjmedia_linear2ulaw(*src++); 156 } 157 } 158 159 /** 160 * Encode 16-bit linear PCM data to 8-bit A-Law data. 161 * 162 * @param dst Destination buffer for 8-bit A-Law data. 163 * @param src Source, 16-bit linear PCM data. 164 * @param len Number of samples. 165 */ 166 PJ_INLINE(void) pjmedia_alaw_encode(pj_uint8_t *dst, const pj_int16_t *src, 167 pj_size_t len) 168 { 169 const pj_int16_t *end = src + len; 170 171 while (src < end) { 172 *dst++ = pjmedia_linear2alaw(*src++); 173 } 174 } 175 176 /** 177 * Decode 8-bit U-Law data to 16-bit linear PCM data. 178 * 179 * @param dst Destination buffer for 16-bit PCM data. 180 * @param src Source, 8-bit U-Law data. 181 * @param len Number of samples. 182 */ 183 PJ_INLINE(void) pjmedia_ulaw_decode(pj_int16_t *dst, const pj_uint8_t *src, 184 pj_size_t len) 185 { 186 const pj_uint8_t *end = src + len; 187 188 while (src < end) { 189 *dst++ = pjmedia_ulaw2linear(*src++); 190 } 191 } 192 193 /** 194 * Decode 8-bit A-Law data to 16-bit linear PCM data. 195 * 196 * @param dst Destination buffer for 16-bit PCM data. 197 * @param src Source, 8-bit A-Law data. 198 * @param len Number of samples. 199 */ 200 PJ_INLINE(void) pjmedia_alaw_decode(pj_int16_t *dst, const pj_uint8_t *src, 201 pj_size_t len) 202 { 203 const pj_uint8_t *end = src + len; 204 205 while (src < end) { 206 *dst++ = pjmedia_alaw2linear(*src++); 207 } 208 } 209 142 210 PJ_END_DECL 143 211 -
pjproject/trunk/pjmedia/src/pjmedia/symbian_sound_aps.cpp
r2394 r2416 23 23 #include <pj/assert.h> 24 24 #include <pj/log.h> 25 #include <pj/math.h> 25 26 #include <pj/os.h> 26 27 … … 268 269 269 270 static CPjAudioEngine *NewL(pjmedia_snd_stream *parent_strm, 270 pjmedia_dir dir,271 271 pjmedia_snd_rec_cb rec_cb, 272 272 pjmedia_snd_play_cb play_cb, … … 280 280 private: 281 281 CPjAudioEngine(pjmedia_snd_stream *parent_strm, 282 pjmedia_dir dir,283 282 pjmedia_snd_rec_cb rec_cb, 284 283 pjmedia_snd_play_cb play_cb, … … 300 299 State state_; 301 300 pjmedia_snd_stream *parentStrm_; 302 pjmedia_dir dir_;303 301 pjmedia_snd_rec_cb recCb_; 304 302 pjmedia_snd_play_cb playCb_; … … 317 315 CQueueHandler *iRecCommHandler; 318 316 CQueueHandler *iRecHandler; 317 318 static pj_uint8_t aps_samples_per_frame; 319 320 pj_int16_t *play_buf; 321 pj_uint16_t play_buf_len; 322 pj_uint16_t play_buf_start; 323 pj_int16_t *rec_buf; 324 pj_uint16_t rec_buf_len; 319 325 }; 320 326 321 327 328 pj_uint8_t CPjAudioEngine::aps_samples_per_frame = 0; 329 330 322 331 CPjAudioEngine* CPjAudioEngine::NewL(pjmedia_snd_stream *parent_strm, 323 pjmedia_dir dir,324 332 pjmedia_snd_rec_cb rec_cb, 325 333 pjmedia_snd_play_cb play_cb, 326 334 void *user_data) 327 335 { 328 CPjAudioEngine* self = new (ELeave) CPjAudioEngine(parent_strm, dir,336 CPjAudioEngine* self = new (ELeave) CPjAudioEngine(parent_strm, 329 337 rec_cb, play_cb, 330 338 user_data); … … 336 344 337 345 CPjAudioEngine::CPjAudioEngine(pjmedia_snd_stream *parent_strm, 338 pjmedia_dir dir,339 346 pjmedia_snd_rec_cb rec_cb, 340 347 pjmedia_snd_play_cb play_cb, … … 342 349 : state_(STATE_NULL), 343 350 parentStrm_(parent_strm), 344 dir_(dir),345 351 recCb_(rec_cb), 346 352 playCb_(play_cb), … … 364 370 365 371 if (state_ == STATE_READY) { 366 if ( dir_!= PJMEDIA_DIR_PLAYBACK) {372 if (parentStrm_->dir != PJMEDIA_DIR_PLAYBACK) { 367 373 iReadQ.Close(); 368 374 iReadCommQ.Close(); … … 474 480 iSettings.iSettings.iSampleRate = EMMFSampleRate8000Hz; 475 481 iSettings.iSettings.iVolume = 0; 482 483 /* play_buf size is samples per frame of parent stream. */ 484 play_buf = (pj_int16_t*)pj_pool_alloc(parentStrm_->pool, 485 parentStrm_->samples_per_frame << 1); 486 play_buf_len = 0; 487 play_buf_start = 0; 488 489 /* rec_buf size is samples per frame of parent stream. */ 490 rec_buf = (pj_int16_t*)pj_pool_alloc(parentStrm_->pool, 491 parentStrm_->samples_per_frame << 1); 492 rec_buf_len = 0; 476 493 } 477 494 … … 484 501 iSession.SetVadMode(EFalse); 485 502 iSession.SetPlc(EFalse); 486 iSession.SetEncoderMode(E ALawOr20ms);487 iSession.SetDecoderMode(E ALawOr20ms);503 iSession.SetEncoderMode(EULawOr30ms); 504 iSession.SetDecoderMode(EULawOr30ms); 488 505 iSession.ActivateLoudspeaker(act_loudspeaker); 489 506 490 507 // Not only playback 491 if ( dir_!= PJMEDIA_DIR_PLAYBACK) {508 if (parentStrm_->dir != PJMEDIA_DIR_PLAYBACK) { 492 509 iRecHandler = CQueueHandler::NewL(this, &iReadQ, 493 510 CQueueHandler::ERecordQueue); 494 511 iRecHandler->Start(); 495 512 iSession.Read(); 513 TRACE_((THIS_FILE, "APS recorder started")); 496 514 } 497 515 498 516 // Not only capture 499 if ( dir_!= PJMEDIA_DIR_CAPTURE) {517 if (parentStrm_->dir != PJMEDIA_DIR_CAPTURE) { 500 518 iSession.Write(); 519 TRACE_((THIS_FILE, "APS player started")); 501 520 } 502 521 … … 505 524 } 506 525 526 /////////////////////////////////////////////////////////// 507 527 // Inherited from MQueueHandlerObserver 528 // 529 508 530 void CPjAudioEngine::InputStreamInitialized(const TInt aStatus) 509 531 { … … 521 543 522 544 if (aStatus == KErrNone) { 523 if ( dir_== PJMEDIA_DIR_PLAYBACK) {545 if (parentStrm_->dir == PJMEDIA_DIR_PLAYBACK) { 524 546 state_ = STATE_READY; 525 547 // Only playback, start directly … … 537 559 void CPjAudioEngine::RecCb(TAPSCommBuffer &buffer) 538 560 { 539 pj_int16_t buf[160];540 561 pj_assert(buffer.iBuffer[0] == 1 && buffer.iBuffer[1] == 0); 541 562 542 for (int i=0; i<160; ++i) 543 buf[i] = pjmedia_alaw2linear(buffer.iBuffer[i+2]); 544 545 recCb_(userData_, 0, buf, sizeof(buf)); 563 /* Detect the recorder G.711 frame size, player frame size will follow 564 * this recorder frame size. 565 */ 566 if (CPjAudioEngine::aps_samples_per_frame == 0) { 567 CPjAudioEngine::aps_samples_per_frame = buffer.iBuffer.Length() < 160? 568 80 : 160; 569 TRACE_((THIS_FILE, "Detected APS G.711 frame size = %u samples", 570 CPjAudioEngine::aps_samples_per_frame)); 571 } 572 573 /* Decode APS buffer (coded in G.711) and put the PCM result into rec_buf. 574 * Whenever rec_buf is full, call parent stream callback. 575 */ 576 unsigned dec_len = 0; 577 578 while (dec_len < CPjAudioEngine::aps_samples_per_frame) { 579 unsigned tmp; 580 581 tmp = PJ_MIN(parentStrm_->samples_per_frame - rec_buf_len, 582 CPjAudioEngine::aps_samples_per_frame - dec_len); 583 pjmedia_ulaw_decode(&rec_buf[rec_buf_len], 584 buffer.iBuffer.Ptr() + 2 + dec_len, 585 tmp); 586 rec_buf_len += tmp; 587 dec_len += tmp; 588 589 pj_assert(rec_buf_len <= parentStrm_->samples_per_frame); 590 591 if (rec_buf_len == parentStrm_->samples_per_frame) { 592 recCb_(userData_, 0, rec_buf, rec_buf_len << 1); 593 rec_buf_len = 0; 594 } 595 } 546 596 } 547 597 548 598 void CPjAudioEngine::PlayCb(TAPSCommBuffer &buffer) 549 599 { 550 pj_int16_t buf[160];551 552 playCb_(userData_, 0, buf, sizeof(buf));553 554 600 buffer.iCommand = CQueueHandler::EAPSPlayData; 555 601 buffer.iStatus = 0; … … 557 603 buffer.iBuffer.Append(1); 558 604 buffer.iBuffer.Append(0); 559 for (int i=0; i<160; ++i) 560 buffer.iBuffer.Append(pjmedia_linear2alaw(buf[i])); 605 606 /* Send 10ms silence frame if frame size hasn't been known. */ 607 if (CPjAudioEngine::aps_samples_per_frame == 0) { 608 pjmedia_zero_samples(play_buf, 80); 609 pjmedia_ulaw_encode((pj_uint8_t*)play_buf, play_buf, 80); 610 buffer.iBuffer.Append((TUint8*)play_buf, 80); 611 iWriteQ.Send(buffer); 612 return; 613 } 614 615 unsigned enc_len = 0; 616 617 /* Call parent stream callback to get PCM samples to play, 618 * encode the PCM samples into G.711 and put it into APS buffer. 619 */ 620 while (enc_len < CPjAudioEngine::aps_samples_per_frame) { 621 if (play_buf_len == 0) { 622 playCb_(userData_, 0, play_buf, 623 sizeof(parentStrm_->samples_per_frame<<1)); 624 play_buf_len = parentStrm_->samples_per_frame; 625 play_buf_start = 0; 626 } 627 628 unsigned tmp; 629 630 tmp = PJ_MIN(play_buf_len, 631 CPjAudioEngine::aps_samples_per_frame - enc_len); 632 pjmedia_ulaw_encode((pj_uint8_t*)&play_buf[play_buf_start], 633 &play_buf[play_buf_start], 634 tmp); 635 buffer.iBuffer.Append((TUint8*)&play_buf[play_buf_start], tmp); 636 enc_len += tmp; 637 play_buf_len -= tmp; 638 play_buf_start += tmp; 639 } 561 640 562 641 iWriteQ.Send(buffer); 563 642 } 643 644 // 645 // End of inherited from MQueueHandlerObserver 646 ///////////////////////////////////////////////////////////// 564 647 565 648 … … 642 725 643 726 // Create the audio engine. 644 TRAPD(err, strm->engine = CPjAudioEngine::NewL(strm, strm->dir, 645 rec_cb, play_cb, 727 TRAPD(err, strm->engine = CPjAudioEngine::NewL(strm, rec_cb, play_cb, 646 728 user_data)); 647 729 if (err != KErrNone) {
Note: See TracChangeset
for help on using the changeset viewer.