static int tdav_speex_jitterbuffer_open(tmedia_jitterbuffer_t* self, uint32_t frame_duration, uint32_t rate, uint32_t channels) { tdav_speex_jitterbuffer_t *jitterbuffer = (tdav_speex_jitterbuffer_t *)self; spx_int32_t tmp; TSK_DEBUG_INFO("Open speex jb (ptime=%u, rate=%u)", frame_duration, rate); if(!(jitterbuffer->state = jitter_buffer_init((int)frame_duration))){ TSK_DEBUG_ERROR("jitter_buffer_init() failed"); return -2; } jitterbuffer->rate = rate; jitterbuffer->frame_duration = frame_duration; jitterbuffer->channels = channels; jitterbuffer->x_data_size = ((frame_duration * jitterbuffer->rate) / 500) << (channels == 2 ? 1 : 0); jitter_buffer_ctl(jitterbuffer->state, JITTER_BUFFER_GET_MARGIN, &tmp); TSK_DEBUG_INFO("Default Jitter buffer margin=%d", tmp); jitter_buffer_ctl(jitterbuffer->state, JITTER_BUFFER_GET_MAX_LATE_RATE, &tmp); TSK_DEBUG_INFO("Default Jitter max late rate=%d", tmp); if((tmp = tmedia_defaults_get_jb_margin()) >= 0){ jitter_buffer_ctl(jitterbuffer->state, JITTER_BUFFER_SET_MARGIN, &tmp); TSK_DEBUG_INFO("New Jitter buffer margin=%d", tmp); } if((tmp = tmedia_defaults_get_jb_max_late_rate()) >= 0){ jitter_buffer_ctl(jitterbuffer->state, JITTER_BUFFER_SET_MAX_LATE_RATE, &tmp); TSK_DEBUG_INFO("New Jitter buffer max late rate=%d", tmp); } return 0; }
int maintestjitter() { char buffer[65536]; JitterBufferPacket in, out; int i; JitterBuffer *jb = jitter_buffer_init(10); out.data = buffer; /* Frozen sender case */ jitterFill(jb); for(i=0;i<100;++i) { out.len = 65536; jitter_buffer_get(jb, &out, 10, NULL); jitter_buffer_tick(jb); } synthIn(&in, 100, 1); jitter_buffer_put(jb, &in); out.len = 65536; if (jitter_buffer_get(jb, &out, 10, NULL) != JITTER_BUFFER_OK) { printf("Failed frozen sender resynchronize\n"); } else { printf("Frozen sender: Jitter %d\n", out.timestamp - 100*10); } return 0; }
JNIEXPORT jlong JNICALL Native_NATIVE(jitter_1buffer_1init) (JNIEnv *env, jclass that, jint arg0) { jlong rc = 0; Native_NATIVE_ENTER(env, that, Native_jitter_1buffer_1init_FUNC); rc = (intptr_t)(JitterBuffer *)jitter_buffer_init(arg0); Native_NATIVE_EXIT(env, that, Native_jitter_1buffer_1init_FUNC); return rc; }
void speex_jitter_init(SpeexJitter *jitter, void *decoder, int sampling_rate) { jitter->dec = decoder; speex_decoder_ctl(decoder, SPEEX_GET_FRAME_SIZE, &jitter->frame_size); jitter->packets = jitter_buffer_init(jitter->frame_size); speex_bits_init(&jitter->current_packet); jitter->valid_bits = 0; jitter->activity_threshold = 0; }
AudioOutputSpeech::AudioOutputSpeech(ClientUser *user, unsigned int freq, MessageHandler::UDPMessageType type) : AudioOutputUser(user->qsName) { int err; p = user; umtType = type; iMixerFreq = freq; cCodec = NULL; cdDecoder = NULL; dsSpeex = NULL; opusState = NULL; bStereo = false; iSampleRate = SAMPLE_RATE; iFrameSize = iSampleRate / 100; iAudioBufferSize = iFrameSize; if (umtType == MessageHandler::UDPVoiceOpus) { #ifdef USE_OPUS iAudioBufferSize *= 12; opusState = opus_decoder_create(iSampleRate, bStereo ? 2 : 1, NULL); #endif } else if (umtType == MessageHandler::UDPVoiceSpeex) { speex_bits_init(&sbBits); dsSpeex = speex_decoder_init(speex_lib_get_mode(SPEEX_MODEID_UWB)); int iArg=1; speex_decoder_ctl(dsSpeex, SPEEX_SET_ENH, &iArg); speex_decoder_ctl(dsSpeex, SPEEX_GET_FRAME_SIZE, &iFrameSize); speex_decoder_ctl(dsSpeex, SPEEX_GET_SAMPLING_RATE, &iSampleRate); iAudioBufferSize = iFrameSize; } iOutputSize = static_cast<unsigned int>(ceilf(static_cast<float>(iAudioBufferSize * iMixerFreq) / static_cast<float>(iSampleRate))); if (bStereo) { iAudioBufferSize *= 2; iOutputSize *= 2; } srs = NULL; fResamplerBuffer = NULL; if (iMixerFreq != iSampleRate) { srs = speex_resampler_init(bStereo ? 2 : 1, iSampleRate, iMixerFreq, 3, &err); fResamplerBuffer = new float[iAudioBufferSize]; } iBufferOffset = iBufferFilled = iLastConsume = 0; bLastAlive = true; iMissCount = 0; iMissedFrames = 0; ucFlags = 0xFF; jbJitter = jitter_buffer_init(iFrameSize); int margin = g.s.iJitterBufferSize * iFrameSize; jitter_buffer_ctl(jbJitter, JITTER_BUFFER_SET_MARGIN, &margin); fFadeIn = new float[iFrameSize]; fFadeOut = new float[iFrameSize]; float mul = static_cast<float>(M_PI / (2.0 * static_cast<double>(iFrameSize))); for (unsigned int i=0;i<iFrameSize;++i) fFadeIn[i] = fFadeOut[iFrameSize-i-1] = sinf(static_cast<float>(i) * mul); }
int main(int argc, char **argv) { int sd, rc, n, tmp; char msg[MAX_MSG]; int nfds; int send_timestamp = 0; int recv_started = 0; struct pollfd *pfds; struct alsa_dev *dev; CELTEncoder *enc_state; CELTDecoder *dec_state; CELTMode *mode; struct sched_param param; JitterBuffer *jitter; SpeexEchoState *echo_state; char mac_own[6], mac_remote[6]; if (argc != 4) panic("Usage %s plughw:0,0 <lmac in xx:xx:xx:xx:xx:xx> <rmac>\n", argv[0]); register_signal(SIGINT, sighandler); hack_mac(mac_own, argv[2], strlen(argv[2])); hack_mac(mac_remote, argv[3], strlen(argv[3])); sd = socket(AF_LANA, SOCK_RAW, 0); if (sd < 0) panic("%s: cannot open socket \n", argv[0]); printf("If ready hit key!\n"); //user must do binding getchar(); dev = alsa_open(argv[1], SAMPLING_RATE, CHANNELS, FRAME_SIZE); mode = celt_mode_create(SAMPLING_RATE, FRAME_SIZE, NULL); enc_state = celt_encoder_create(mode, CHANNELS, NULL); dec_state = celt_decoder_create(mode, CHANNELS, NULL); param.sched_priority = sched_get_priority_min(SCHED_FIFO); if (sched_setscheduler(0, SCHED_FIFO, ¶m)) whine("sched_setscheduler error!\n"); /* Setup all file descriptors for poll()ing */ nfds = alsa_nfds(dev); pfds = xmalloc(sizeof(*pfds) * (nfds + 1)); alsa_getfds(dev, pfds, nfds); pfds[nfds].fd = sd; pfds[nfds].events = POLLIN; /* Setup jitter buffer using decoder */ jitter = jitter_buffer_init(FRAME_SIZE); tmp = FRAME_SIZE; jitter_buffer_ctl(jitter, JITTER_BUFFER_SET_MARGIN, &tmp); /* Echo canceller with 200 ms tail length */ echo_state = speex_echo_state_init(FRAME_SIZE, 10 * FRAME_SIZE); tmp = SAMPLING_RATE; speex_echo_ctl(echo_state, SPEEX_ECHO_SET_SAMPLING_RATE, &tmp); register_signal_f(SIGALRM, timer_elapsed, SA_SIGINFO); alsa_start(dev); printf("ALSA started!\n"); itimer.it_interval.tv_sec = 0; itimer.it_interval.tv_usec = interval; itimer.it_value.tv_sec = 0; itimer.it_value.tv_usec = interval; setitimer(ITIMER_REAL, &itimer, NULL); while (!sigint) { poll(pfds, nfds + 1, -1); /* Received packets */ if (pfds[nfds].revents & POLLIN) { memset(msg, 0, MAX_MSG); n = recv(sd, msg, MAX_MSG, 0); if (n <= 0) goto do_alsa; pkts_in++; int recv_timestamp; memcpy(&recv_timestamp, msg, sizeof(recv_timestamp)); JitterBufferPacket packet; packet.data = msg+4/*+6+6+2*/; packet.len = n-4/*-6-6-2*/; packet.timestamp = recv_timestamp; packet.span = FRAME_SIZE; packet.sequence = 0; /* Put content of the packet into the jitter buffer, except for the pseudo-header */ jitter_buffer_put(jitter, &packet); recv_started = 1; } do_alsa: /* Ready to play a frame (playback) */ if (alsa_play_ready(dev, pfds, nfds)) { short pcm[FRAME_SIZE * CHANNELS] = {0}; if (recv_started) { JitterBufferPacket packet; /* Get audio from the jitter buffer */ packet.data = msg; packet.len = MAX_MSG; jitter_buffer_tick(jitter); jitter_buffer_get(jitter, &packet, FRAME_SIZE, NULL); if (packet.len == 0) packet.data=NULL; celt_decode(dec_state, (const unsigned char *) packet.data, packet.len, pcm); } /* Playback the audio and reset the echo canceller if we got an underrun */ alsa_write(dev, pcm, FRAME_SIZE); // if (alsa_write(dev, pcm, FRAME_SIZE)) // speex_echo_state_reset(echo_state); /* Put frame into playback buffer */ // speex_echo_playback(echo_state, pcm); } /* Audio available from the soundcard (capture) */ if (alsa_cap_ready(dev, pfds, nfds)) { short pcm[FRAME_SIZE * CHANNELS]; //pcm2[FRAME_SIZE * CHANNELS]; char outpacket[MAX_MSG]; alsa_read(dev, pcm, FRAME_SIZE); /* Perform echo cancellation */ // speex_echo_capture(echo_state, pcm, pcm2); // for (i = 0; i < FRAME_SIZE * CHANNELS; ++i) // pcm[i] = pcm2[i]; celt_encode(enc_state, pcm, NULL, (unsigned char *) (outpacket+4+6+6+2), PACKETSIZE); /* Pseudo header: four null bytes and a 32-bit timestamp; XXX hack */ memcpy(outpacket,mac_remote,6); memcpy(outpacket+6,mac_own,6); outpacket[6+6] = (uint8_t) 0xac; outpacket[6+6+1] = (uint8_t) 0xdc; memcpy(outpacket+6+6+2, &send_timestamp, sizeof(send_timestamp)); send_timestamp += FRAME_SIZE; rc = sendto(sd, outpacket, PACKETSIZE+4+6+6+2, 0, NULL, 0); if (rc < 0) panic("cannot send to socket"); pkts_out++; } } itimer.it_interval.tv_sec = 0; itimer.it_interval.tv_usec = 0; itimer.it_value.tv_sec = 0; itimer.it_value.tv_usec = 0; setitimer(ITIMER_REAL, &itimer, NULL); close(sd); return 0; }
AudioInput::AudioInput() { speex_bits_init(&sbBits); speex_bits_reset(&sbBits); iFrames = 0; iSampleRate = SAMPLE_RATE; esEncState=speex_encoder_init(speex_lib_get_mode(SPEEX_MODEID_WB)); speex_encoder_ctl(esEncState,SPEEX_GET_FRAME_SIZE,&iFrameSize); mumble_drft_init(&fftTable, iFrameSize); iFrameCounter = 0; iSilentFrames = 0; iHoldFrames = 0; iBestBin = 0; int iArg=1; float fArg=0.0; speex_encoder_ctl(esEncState,SPEEX_SET_VBR, &iArg); iArg = 0; speex_encoder_ctl(esEncState,SPEEX_SET_VAD, &iArg); speex_encoder_ctl(esEncState,SPEEX_SET_DTX, &iArg); fArg = static_cast<float>(g.s.iQuality); speex_encoder_ctl(esEncState,SPEEX_SET_VBR_QUALITY, &fArg); speex_encoder_ctl(esEncState,SPEEX_GET_BITRATE, &iArg); speex_encoder_ctl(esEncState, SPEEX_SET_VBR_MAX_BITRATE, &iArg); iArg = 5; speex_encoder_ctl(esEncState,SPEEX_SET_COMPLEXITY, &iArg); bResetProcessor = true; sppPreprocess = NULL; sesEcho = NULL; srsMic = srsEcho = NULL; jb = jitter_buffer_init(10); iJitterSeq = 1; psMic = new short[iFrameSize]; psSpeaker = new short[iFrameSize]; psClean = new short[iFrameSize]; iEchoChannels = iMicChannels = 0; iEchoFreq = iMicFreq = SAMPLE_RATE; iEchoFilled = iMicFilled = 0; eMicFormat = eEchoFormat = SampleFloat; iMicSampleSize = iEchoSampleSize = 0; bPreviousVoice = false; pfMicInput = pfEchoInput = pfOutput = NULL; iBitrate = 0; dPeakMic = dPeakSignal = dPeakSpeaker = 0.0; if (g.uiSession) { setMaxBandwidth(g.iMaxBandwidth); } bRunning = false; connect(this, SIGNAL(doMute()), g.mw->qaAudioMute, SLOT(trigger()), Qt::QueuedConnection); }
AudioOutputSpeech::AudioOutputSpeech(boost::shared_ptr<ClientUser> user, MessageHandler::UDPMessageType type) : AudioOutputUser(user->qsName) { int err; p = user; umtType = type; unsigned int srate = 0; cCodec = NULL; cdDecoder = NULL; if (umtType != MessageHandler::UDPVoiceSpeex) { srate = SAMPLE_RATE; iFrameSize = srate / 100; dsSpeex = NULL; } else { speex_bits_init(&sbBits); dsSpeex = speex_decoder_init(speex_lib_get_mode(SPEEX_MODEID_UWB)); int iArg=1; speex_decoder_ctl(dsSpeex, SPEEX_SET_ENH, &iArg); speex_decoder_ctl(dsSpeex, SPEEX_GET_FRAME_SIZE, &iFrameSize); speex_decoder_ctl(dsSpeex, SPEEX_GET_SAMPLING_RATE, &srate); } if (srate != SAMPLE_RATE) srs = speex_resampler_init(1, srate, SAMPLE_RATE, 3, &err); else srs = NULL; iOutputSize = static_cast<unsigned int>(ceilf(static_cast<float>(iFrameSize * SAMPLE_RATE) / static_cast<float>(SAMPLE_RATE))); iBufferOffset = iBufferFilled = iLastConsume = 0; bLastAlive = true; iMissCount = 0; iMissedFrames = 0; ucFlags = 0xFF; jbJitter = jitter_buffer_init(iFrameSize); int margin = g.s.iJitterBufferSize * iFrameSize; jitter_buffer_ctl(jbJitter, JITTER_BUFFER_SET_MARGIN, &margin); fFadeIn = new float[iFrameSize]; fFadeOut = new float[iFrameSize]; float mul = static_cast<float>(M_PI / (2.0 * static_cast<double>(iFrameSize))); for (unsigned int i=0;i<iFrameSize;++i) fFadeIn[i] = fFadeOut[iFrameSize-i-1] = sinf(static_cast<float>(i) * mul); }