Example #1
0
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;
}/*}}}*/
Example #2
0
JNIEXPORT void JNICALL Java_com_jtxdriggers_android_ventriloid_VentriloInterface_stopaudio() {
	v3_stop_audio();
}