// returns bytes read, else -1 if error (0 is OK) int RtmpAudio::get(unsigned long long system_ts, unsigned char* buffer, int output_sample_rate, unsigned int nb_samples) { // - buffer RTMP audio // - read from RTMP recv buffer unsigned int user_ts = scaleSystemTS(system_ts); //DBG("get(%u, %u)\n",user_ts,nb_samples); process_recv_queue(user_ts); nb_samples = (unsigned int)((float)nb_samples * (float)getSampleRate() / (float)output_sample_rate); u_int32_t size = PCM16_S2B(playout_buffer.read(user_ts, (ShortSample*)((unsigned char*)samples), nb_samples)); if(output_sample_rate != getSampleRate()) { size = resampleOutput((unsigned char*)samples, size, getSampleRate(), output_sample_rate); } memcpy(buffer,(unsigned char*)samples,size); return size; }
// returns bytes written, else -1 if error (0 is OK) int AmAudio::put(unsigned long long system_ts, unsigned char* buffer, int input_sample_rate, unsigned int size) { if(!size){ return 0; } if(max_rec_time > -1 && rec_time >= max_rec_time) return -1; memcpy((unsigned char*)samples,buffer,size); size = resampleInput((unsigned char*)samples, size, input_sample_rate, getSampleRate()); int s = encode(size); if(s>0){ incRecordTime(bytes2samples(size)); unsigned int wr_ts = scaleSystemTS(system_ts); //DBG("write(wr_ts = %10.u; s = %u)\n",wr_ts,s); return write(wr_ts,(unsigned int)s); } else{ return s; } }
// returns bytes read, else -1 if error (0 is OK) int AmAudio::get(unsigned long long system_ts, unsigned char* buffer, int output_sample_rate, unsigned int nb_samples) { int size = calcBytesToRead((int)((float)nb_samples * (float)getSampleRate() / (float)output_sample_rate)); unsigned int rd_ts = scaleSystemTS(system_ts); //DBG("\tread(rd_ts = %10.u; size = %u)\n",rd_ts,size); size = read(rd_ts,size); if(size <= 0){ return size; } size = decode(size); if(size < 0) { DBG("decode returned %i\n",size); return -1; } size = downMix(size); size = resampleOutput((unsigned char*)samples, size, getSampleRate(), output_sample_rate); if(size>0) memcpy(buffer,(unsigned char*)samples,size); return size; }
int AmRtpAudio::get(unsigned long long system_ts, unsigned char* buffer, int output_sample_rate, unsigned int nb_samples) { if (!(receiving || getPassiveMode())) return 0; // like nothing received int ret = receive(system_ts); if(ret < 0) return ret; // like nothing received? if (!active) return 0; unsigned int user_ts = scaleSystemTS(system_ts); nb_samples = (unsigned int)((float)nb_samples * (float)getSampleRate() / (float)output_sample_rate); u_int32_t size = PCM16_S2B(playout_buffer->read(user_ts, (ShortSample*)((unsigned char*)samples), nb_samples)); if(output_sample_rate != getSampleRate()) { size = resampleOutput((unsigned char*)samples, size, getSampleRate(), output_sample_rate); } memcpy(buffer,(unsigned char*)samples,size); return size; }
bool AmRtpAudio::checkInterval(unsigned long long ts) { if(!last_check_i){ send_int = true; last_check_i = true; last_check = ts; } else { if(scaleSystemTS(ts - last_check) >= getFrameSize()){ send_int = true; last_check = ts; } else { send_int = false; } } return send_int; }
// returns bytes written, else -1 if error (0 is OK) int RtmpAudio::put(unsigned long long system_ts, unsigned char* buffer, int input_sample_rate, unsigned int size) { if(!size){ return 0; } //dump_audio((unsigned char*)buffer,size); // copy into internal buffer memcpy((unsigned char*)samples,buffer,size); size = resampleInput((unsigned char*)samples, size, input_sample_rate, getSampleRate()); int s = encode(size); //DBG("s = %i\n",s); if(s<=0){ return s; } return send(scaleSystemTS(system_ts),(unsigned int)s); }
/* @param wallclock_ts [in] the current ts in the audio buffer */ int AmRtpAudio::receive(unsigned long long system_ts) { int size; unsigned int rtp_ts; int new_payload = -1; if(!fmt.get() || (!playout_buffer.get())) { DBG("audio format not initialized\n"); return RTP_ERROR; } unsigned int wallclock_ts = scaleSystemTS(system_ts); while(true) { size = AmRtpStream::receive((unsigned char*)samples, (unsigned int)AUDIO_BUFFER_SIZE, rtp_ts, new_payload); if(size <= 0) { switch(size){ case 0: break; case RTP_DTMF: case RTP_UNKNOWN_PL: case RTP_PARSE_ERROR: continue; case RTP_TIMEOUT: //FIXME: postRequest(new SchedRequest(AmMediaProcessor::RemoveSession,s)); // post to the session (FIXME: is session always set? seems to be...) session->postEvent(new AmRtpTimeoutEvent()); return -1; case RTP_BUFFER_SIZE: default: ERROR("AmRtpStream::receive() returned %i\n",size); //FIXME: postRequest(new SchedRequest(AmMediaProcessor::ClearSession,s)); // or AmMediaProcessor::instance()->clearSession(session); return -1; break; } break; } if (// don't process if we don't need to // ignore CN COMFORT_NOISE_PAYLOAD_TYPE == new_payload || // ignore packet if payload not found setCurrentPayload(new_payload) ){ playout_buffer->clearLastTs(); continue; } size = decode(size); if(size <= 0){ ERROR("decode() returned %i\n",size); return -1; } // This only works because the possible ratio (Rate/TSRate) // is 2. Rate and TSRate are only different in case of g722. // For g722, TSRate=8000 and Rate=16000 // AmAudioRtpFormat* rtp_fmt = (AmAudioRtpFormat*)fmt.get(); unsigned long long adjusted_rtp_ts = rtp_ts; if(rtp_fmt->getRate() != rtp_fmt->getTSRate()) { adjusted_rtp_ts = (unsigned long long)rtp_ts * (unsigned long long)rtp_fmt->getRate() / (unsigned long long)rtp_fmt->getTSRate(); } playout_buffer->write(wallclock_ts, adjusted_rtp_ts, (ShortSample*)((unsigned char *)samples), PCM16_B2S(size), begin_talk); if(!active) { DBG("switching to active-mode\t(ts=%u;stream=%p)\n", rtp_ts,this); active = true; } } return size; }
bool AmRtpAudio::sendIntReached(unsigned long long ts) { if (!last_send_ts_i) return true; else return (scaleSystemTS(ts - last_send_ts) >= getFrameSize()); }