JNIEXPORT jboolean JNICALL Java_com_jtxdriggers_android_ventriloid_VentriloInterface_recv() { _v3_net_message *msg; if ((msg = _v3_recv(V3_BLOCK))) { _v3_process_message(msg); } return msg && v3_is_loggedin(); }
void ManglerAudio::input(void) {/*{{{*/ uint8_t *buf = NULL; struct timeval start, vastart, now, diff; int ctr; bool drop, xmit = false; float seconds = 0; register float pcmpeak = 0; float midpeak = 0; float vasilencedur, vasilenceelapsed; uint8_t vapercent; for (;;) { if (stop_input) { break; } gettimeofday(&start, NULL); ctr = 0; seconds = 0; pcmpeak = 0; midpeak = 0; // need to send ~0.115 seconds of audio for each packet for (;;) { /* if (seconds >= 0.115) { //fprintf(stderr, "0.115 seconds of real time has elapsed\n"); break; } */ if (pcm_framesize * ctr > rate * sizeof(int16_t) * 0.115) { //fprintf(stderr, "we have 0.115 seconds of audio in %d iterations\n", ctr); break; } if ((pcm_framesize*(ctr+1)) > 16384) { fprintf(stderr, "audio frames are greater than buffer size. dropping audio frames after %f seconds\n", seconds); drop = true; break; } drop = false; //fprintf(stderr, "reallocating %d bytes of memory\n", pcm_framesize*(ctr+1)); buf = (uint8_t *)realloc(buf, pcm_framesize*(ctr+1)); //fprintf(stderr, "reading %d bytes of memory to %lu\n", pcm_framesize, buf+(pcm_framesize*ctr)); if (Mangler::config["AudioSubsystem"].toLower() != backend->getAudioSubsystem()) { if (!switchBackend(Mangler::config["AudioSubsystem"].toLower()) || !open()) { stop_input = true; break; } } if (!backend->read(buf+(pcm_framesize*ctr))) { close(); stop_input = true; break; } gettimeofday(&now, NULL); timeval_subtract(&diff, &now, &start); seconds = (float)diff.tv_sec + ((float)diff.tv_usec / 1000000.0); //fprintf(stderr, "iteration after %f seconds with %d bytes\n", seconds, pcm_framesize*ctr); for (int16_t *pcmptr = (int16_t *)(buf+(pcm_framesize*ctr)); pcmptr < (int16_t *)(buf+(pcm_framesize*(ctr+1))); pcmptr++) { pcmpeak = abs(*pcmptr) > pcmpeak ? abs(*pcmptr) : pcmpeak; } if (seconds >= 0.115 / 2 && !midpeak && pcmpeak) { midpeak = log10(((pcmpeak / 0x7fff) * 9) + 1); midpeak = (midpeak > 1) ? 1 : midpeak; gdk_threads_enter(); mangler->inputvumeter->set_fraction(midpeak); gdk_threads_leave(); } ctr++; } if (!stop_input) { pcmpeak = log10(((pcmpeak / 0x7fff) * 9) + 1); pcmpeak = (pcmpeak > 1) ? 1 : pcmpeak; gdk_threads_enter(); if (Mangler::config["VoiceActivationEnabled"].toBool() && !mangler->isTransmittingKey && !mangler->isTransmittingMouse && !mangler->isTransmittingButton) { vasilencedur = Mangler::config["VoiceActivationSilenceDuration"].toInt(); vapercent = Mangler::config["VoiceActivationSensitivity"].toUInt(); if (pcmpeak * 100 >= vapercent) { gettimeofday(&vastart, NULL); if (!xmit) { xmit = true; mangler->audioControl->playNotification("talkstart"); mangler->statusIcon->set(mangler->icons["tray_icon_green"]); v3_start_audio(V3_AUDIO_SENDTYPE_U2CCUR); } mangler->channelTree->setUserIcon(v3_get_user_id(), "green", true); } else if (xmit) { gettimeofday(&now, NULL); timeval_subtract(&diff, &now, &vastart); vasilenceelapsed = (float)diff.tv_sec + ((float)diff.tv_usec / 1000000.0); if (vasilenceelapsed * 1000 >= vasilencedur) { xmit = false; v3_stop_audio(); mangler->channelTree->setUserIcon(v3_get_user_id(), "orange", true); mangler->statusIcon->set(mangler->icons["tray_icon_yellow"]); mangler->audioControl->playNotification("talkend"); } else { mangler->channelTree->setUserIcon(v3_get_user_id(), "yellow", true); } } } else { if (!xmit) { xmit = true; mangler->audioControl->playNotification("talkstart"); v3_start_audio(V3_AUDIO_SENDTYPE_U2CCUR); } mangler->channelTree->setUserIcon(v3_get_user_id(), "green", true); mangler->statusIcon->set(mangler->icons["tray_icon_green"]); } mangler->inputvumeter->set_fraction(pcmpeak); gdk_threads_leave(); if (!drop && xmit) { //fprintf(stderr, "sending %d bytes of audio\n", pcm_framesize * ctr); // TODO: hard coding user to channel for now, need to implement U2U uint32_t ret; if ((ret = v3_send_audio(V3_AUDIO_SENDTYPE_U2CCUR, rate, buf, pcm_framesize * ctr, false)) != rate) { if (!(rate = ret) || !open()) { stop_input = true; } } } } free(buf); buf = NULL; } inputStreamOpen = false; close(); gdk_threads_enter(); if (xmit) { xmit = false; v3_stop_audio(); mangler->audioControl->playNotification("talkend"); } if (v3_is_loggedin()) { mangler->channelTree->setUserIcon(v3_get_user_id(), "red"); mangler->statusIcon->set(mangler->icons["tray_icon_red"]); } mangler->inputvumeter->set_fraction(0); if (mangler->inputAudio == this) { mangler->inputAudio = NULL; } gdk_threads_leave(); delete this; return; }/*}}}*/
void ManglerAudio::output(void) {/*{{{*/ ManglerPCM *queuedpcm = NULL; if (!pcm_queue) { return; } g_async_queue_ref(pcm_queue); for (;;) { if (stop_output || (check_loggedin && !v3_is_loggedin())) { close(); break; } if (buffer) { buffer--; ManglerPCM *bufferpcm = (ManglerPCM *)g_async_queue_pop(pcm_queue); if (bufferpcm && bufferpcm->length) { uint32_t prelen = (queuedpcm) ? queuedpcm->length : 0; uint32_t buflen = prelen + bufferpcm->length; uint8_t *bufpcm = (uint8_t *)malloc(buflen); memcpy(bufpcm + prelen, bufferpcm->sample, bufferpcm->length); if (queuedpcm) { memcpy(bufpcm, queuedpcm->sample, queuedpcm->length); delete queuedpcm; } delete bufferpcm; queuedpcm = new ManglerPCM(buflen, bufpcm); free(bufpcm); continue; } else { buffer = 0; finish(); } } if (!queuedpcm) { queuedpcm = (ManglerPCM *)g_async_queue_pop(pcm_queue); } // finish() queues a 0 length packet to notify us that we're done if (!queuedpcm->length) { close(true); break; } if (mangler->muteSound) { delete queuedpcm; queuedpcm = NULL; continue; } if (Mangler::config["AudioSubsystem"].toLower() != backend->getAudioSubsystem()) { if (!switchBackend(Mangler::config["AudioSubsystem"].toLower()) || !open()) { break; } } if (!backend->write(queuedpcm->sample, queuedpcm->length, channels)) { close(); break; } delete queuedpcm; queuedpcm = NULL; } outputStreamOpen = false; close(); while (queuedpcm || (queuedpcm = (ManglerPCM *)g_async_queue_try_pop(pcm_queue))) { delete queuedpcm; queuedpcm = NULL; } g_async_queue_unref(pcm_queue); delete this; return; }/*}}}*/
JNIEXPORT jboolean JNICALL Java_com_jtxdriggers_android_ventriloid_VentriloInterface_isloggedin() { return v3_is_loggedin() != 0; }