Esempio n. 1
0
    /*
     * Call with audio and video on both sides. Alice calls Bob.
     */
    CALL_AND_START_LOOP(TypeVideo, TypeVideo) {
        /* Both send */

        payload_size = toxav_prepare_audio_frame(status_control.Alice.av, status_control.Alice.call_index, prepared_payload,
                       1000, sample_payload, frame_size);

        if ( payload_size < 0 ) {
            ck_assert_msg ( 0, "Failed to encode payload" );
        }

        toxav_send_audio(status_control.Alice.av, status_control.Alice.call_index, prepared_payload, payload_size);

        payload_size = toxav_prepare_audio_frame(status_control.Bob.av, status_control.Bob.call_index, prepared_payload, 1000,
                       sample_payload, frame_size);

        if ( payload_size < 0 ) {
            ck_assert_msg ( 0, "Failed to encode payload" );
        }

        toxav_send_audio(status_control.Bob.av, status_control.Bob.call_index, prepared_payload, payload_size);

//         toxav_send_video(status_control.Alice.av, status_control.Alice.call_index, sample_image);
//         toxav_send_video(status_control.Bob.av, status_control.Bob.call_index, sample_image);


        if (time(NULL) - cur_time > 10) { /* Transmit for 10 seconds */
            step++; /* This terminates the loop */
            toxav_kill_transmission(status_control.Alice.av, status_control.Alice.call_index);
            toxav_kill_transmission(status_control.Bob.av, status_control.Bob.call_index);

            /* Call over Alice hangs up */
            toxav_hangup(status_control.Alice.av, status_control.Alice.call_index);
        }
    }
Esempio n. 2
0
void read_device_callback (const int16_t* captured, uint32_t size, void* data)
{
    int32_t call_index = *((int32_t*)data); /* TODO: Or pass an array of call_idx's */
    
    uint8_t encoded_payload[RTP_PAYLOAD_SIZE];
    int32_t payload_size = toxav_prepare_audio_frame(ASettins.av, call_index, encoded_payload, RTP_PAYLOAD_SIZE, captured, size);
    if ( payload_size <= 0 || toxav_send_audio(ASettins.av, call_index, encoded_payload, payload_size) < 0 ) {
        /*fprintf(stderr, "Could not encode audio packet\n");*/
    }
}
Esempio n. 3
0
void Core::sendCallAudio(int32_t callId, ToxAv* toxav)
{
    if (!calls[callId].active)
        return;

    if (calls[callId].muteMic || !Audio::isInputReady())
    {
        calls[callId].sendAudioTimer->start();
        return;
    }

    const int framesize = (calls[callId].codecSettings.audio_frame_duration * calls[callId].codecSettings.audio_sample_rate) / 1000 * av_DefaultSettings.audio_channels;
    const int bufsize = framesize * 2 * av_DefaultSettings.audio_channels;
    uint8_t buf[bufsize];

    if (Audio::tryCaptureSamples(buf, framesize))
    {
#ifdef QTOX_FILTER_AUDIO
        if (Settings::getInstance().getFilterAudio())
        {
            if (!filterer[callId])
            {
                filterer[callId] = new AudioFilterer();
                filterer[callId]->startFilter(48000);
            }
            // is a null op #ifndef ALC_LOOPBACK_CAPTURE_SAMPLES
            Audio::getEchoesToFilter(filterer[callId], framesize);

            filterer[callId]->filterAudio((int16_t*) buf, framesize);
        }
        else if (filterer[callId])
        {
            delete filterer[callId];
            filterer[callId] = nullptr;
        }
#endif

        uint8_t dest[bufsize];
        int r;
        if ((r = toxav_prepare_audio_frame(toxav, callId, dest, framesize*2, (int16_t*)buf, framesize)) < 0)
        {
            qDebug() << "Core: toxav_prepare_audio_frame error";
            calls[callId].sendAudioTimer->start();
            return;
        }

        if ((r = toxav_send_audio(toxav, callId, dest, r)) < 0)
            qDebug() << "Core: toxav_send_audio error";
    }
    calls[callId].sendAudioTimer->start();
}
Esempio n. 4
0
    /* Media change */
    CALL_AND_START_LOOP(TypeAudio, TypeAudio) {
        /* Both send */
        payload_size = toxav_prepare_audio_frame(status_control.Alice.av, status_control.Alice.call_index, prepared_payload,
                       1000, sample_payload, frame_size);

        if ( payload_size < 0 ) {
            ck_assert_msg ( 0, "Failed to encode payload" );
        }

        toxav_send_audio(status_control.Alice.av, status_control.Alice.call_index, prepared_payload, payload_size);

        payload_size = toxav_prepare_audio_frame(status_control.Bob.av, status_control.Bob.call_index, prepared_payload, 1000,
                       sample_payload, frame_size);

        if ( payload_size < 0 ) {
            ck_assert_msg ( 0, "Failed to encode payload" );
        }

        toxav_send_audio(status_control.Bob.av, status_control.Bob.call_index, prepared_payload, payload_size);

        /* Wait 2 seconds and change transmission type */
        if (time(NULL) - times_they_are_a_changin > 2) {
            times_they_are_a_changin = time(NULL);
            muhcaps.audio_bitrate ++;
            toxav_change_settings(status_control.Alice.av, status_control.Alice.call_index, &muhcaps);
        }

        if (time(NULL) - cur_time > 10) { /* Transmit for 10 seconds */
            step++; /* This terminates the loop */
            toxav_kill_transmission(status_control.Alice.av, status_control.Alice.call_index);
            toxav_kill_transmission(status_control.Bob.av, status_control.Bob.call_index);

            /* Call over Alice hangs up */
            toxav_hangup(status_control.Alice.av, status_control.Alice.call_index);
        }
    }
Esempio n. 5
0
void Core::sendCallAudio(int callId, ToxAv* toxav)
{
    if (!calls[callId].active)
        return;

    if (calls[callId].muteMic)
    {
        calls[callId].sendAudioTimer->start();
        return;
    }

    int framesize = (calls[callId].codecSettings.audio_frame_duration * calls[callId].codecSettings.audio_sample_rate) / 1000;
    uint8_t buf[framesize*2], dest[framesize*2];

    bool frame = false;
    ALint samples;
    alcGetIntegerv(alInDev, ALC_CAPTURE_SAMPLES, sizeof(samples), &samples);
    if(samples >= framesize)
    {
        alcCaptureSamples(alInDev, buf, framesize);
        frame = 1;
    }

    if(frame)
    {
        int r;
        if((r = toxav_prepare_audio_frame(toxav, callId, dest, framesize*2, (int16_t*)buf, framesize)) < 0)
        {
            qDebug() << "Core: toxav_prepare_audio_frame error";
            calls[callId].sendAudioTimer->start();
            return;
        }

        if((r = toxav_send_audio(toxav, callId, dest, r)) < 0)
            qDebug() << "Core: toxav_send_audio error";
    }
    calls[callId].sendAudioTimer->start();
}
Esempio n. 6
0
void *in_thread_call (void *arg)
{
#define call_print(call, what, args...) printf("[%d] " what "\n", call, ##args)

    ACall *this_call = arg;
    uint64_t start = 0;
    int step = 0;
    int call_idx;

    const int frame_size = (av_DefaultSettings.audio_sample_rate * av_DefaultSettings.audio_frame_duration / 1000);
    int16_t sample_payload[frame_size];
    randombytes((uint8_t *)sample_payload, sizeof(int16_t) * frame_size);

    uint8_t prepared_payload[RTP_PAYLOAD_SIZE];

    register_callbacks(this_call->Caller.av, &status_control);
    register_callbacks(this_call->Callee.av, arg);

    /* NOTE: CALLEE WILL ALWAHYS NEED CALL_IDX == 0 */
    pthread_mutex_lock(&muhmutex);

    while (call_running[this_call->idx]) {

        pthread_mutex_unlock(&muhmutex);

        switch ( step ) {
            case 0: /* CALLER */
                toxav_call(this_call->Caller.av, &call_idx, this_call->Callee.id, &av_DefaultSettings, 10);
                call_print(call_idx, "Calling ...");
                step++;
                break;

            case 1: /* CALLEE */
                pthread_mutex_lock(&muhmutex);

                if (this_call->Caller.status == Ringing) {
                    call_print(call_idx, "Callee answers ...");
                    pthread_mutex_unlock(&muhmutex);
                    toxav_answer(this_call->Callee.av, 0, &av_DefaultSettings);
                    step++;
                    start = time(NULL);
                    pthread_mutex_lock(&muhmutex);
                }

                pthread_mutex_unlock(&muhmutex);
                break;

            case 2: /* Rtp transmission */
                pthread_mutex_lock(&muhmutex);

                if (this_call->Caller.status == InCall) { /* I think this is okay */
                    call_print(call_idx, "Sending rtp ...");
                    pthread_mutex_unlock(&muhmutex);

                    c_sleep(1000); /* We have race condition here */
                    toxav_prepare_transmission(this_call->Callee.av, 0, 1);
                    toxav_prepare_transmission(this_call->Caller.av, call_idx, 1);

                    int payload_size = toxav_prepare_audio_frame(this_call->Caller.av, call_idx, prepared_payload, RTP_PAYLOAD_SIZE,
                                       sample_payload, frame_size);

                    if ( payload_size < 0 ) {
                        ck_assert_msg ( 0, "Failed to encode payload" );
                    }


                    while (time(NULL) - start < 10) { /* 10 seconds */
                        /* Both send */
                        toxav_send_audio(this_call->Caller.av, call_idx, prepared_payload, payload_size);

                        toxav_send_audio(this_call->Callee.av, 0, prepared_payload, payload_size);

                        /* Both receive */
                        int16_t storage[RTP_PAYLOAD_SIZE];
                        int recved;

                        c_sleep(20);
                    }

                    step++; /* This terminates the loop */

                    pthread_mutex_lock(&muhmutex);
                    toxav_kill_transmission(this_call->Callee.av, 0);
                    toxav_kill_transmission(this_call->Caller.av, call_idx);
                    pthread_mutex_unlock(&muhmutex);

                    /* Call over CALLER hangs up */
                    toxav_hangup(this_call->Caller.av, call_idx);
                    call_print(call_idx, "Hanging up ...");

                    pthread_mutex_lock(&muhmutex);
                }

                pthread_mutex_unlock(&muhmutex);
                break;

            case 3: /* Wait for Both to have status ended */
                pthread_mutex_lock(&muhmutex);

                if (this_call->Caller.status == Ended) {
                    pthread_mutex_unlock(&muhmutex);
                    c_sleep(1000); /* race condition */
                    pthread_mutex_lock(&muhmutex);
                    this_call->Callee.status = Ended;
                    call_running[this_call->idx] = 0;
                }

                pthread_mutex_unlock(&muhmutex);

                break;

        }

        c_sleep(20);

        pthread_mutex_lock(&muhmutex);
    }

    pthread_mutex_unlock(&muhmutex);
    call_print(call_idx, "Call ended successfully!");
    pthread_exit(NULL);
}
Esempio n. 7
0
    /*
     * Call with audio and video on both sides. Alice calls Bob.
     */
    CALL_AND_START_LOOP(TypeVideo, TypeVideo) {
        /* Both send */

        payload_size = toxav_prepare_audio_frame(status_control.Alice.av, status_control.Alice.call_index, prepared_payload,
                       1000, sample_payload, frame_size);

        if ( payload_size < 0 ) {
            ck_assert_msg ( 0, "Failed to encode payload" );
        }

        toxav_send_audio(status_control.Alice.av, status_control.Alice.call_index, prepared_payload, payload_size);

        payload_size = toxav_prepare_audio_frame(status_control.Bob.av, status_control.Bob.call_index, prepared_payload, 1000,
                       sample_payload, frame_size);

        if ( payload_size < 0 ) {
            ck_assert_msg ( 0, "Failed to encode payload" );
        }

        toxav_send_audio(status_control.Bob.av, status_control.Bob.call_index, prepared_payload, payload_size);

//         toxav_send_video(status_control.Alice.av, status_control.Alice.call_index, sample_image);
//         toxav_send_video(status_control.Bob.av, status_control.Bob.call_index, sample_image);

        /* Both receive */
        int16_t storage[frame_size];
        vpx_image_t *video_storage;
        int recved;

        /* Payload from Bob */
        recved = toxav_recv_audio(status_control.Alice.av, status_control.Alice.call_index, frame_size, storage);

        if ( recved ) {
            /*ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from Bob is invalid");*/
        }

        /* Video payload */
//         toxav_recv_video(status_control.Alice.av, status_control.Alice.call_index, &video_storage);
//
//         if ( video_storage ) {
//             /*ck_assert_msg( memcmp(video_storage->planes[VPX_PLANE_Y], sample_payload, 10) == 0 ||
//             memcmp(video_storage->planes[VPX_PLANE_U], sample_payload, 10) == 0 ||
//             memcmp(video_storage->planes[VPX_PLANE_V], sample_payload, 10) == 0 , "Payload from Bob is invalid");*/
//             vpx_img_free(video_storage);
//         }




        /* Payload from Alice */
        recved = toxav_recv_audio(status_control.Bob.av, status_control.Bob.call_index, frame_size, storage);

        if ( recved ) {
            /*ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from Alice is invalid");*/
        }

        /* Video payload */
//         toxav_recv_video(status_control.Bob.av, status_control.Bob.call_index, &video_storage);
//
//         if ( video_storage ) {
//             /*ck_assert_msg( memcmp(video_storage->planes[VPX_PLANE_Y], sample_payload, 10) == 0 ||
//             memcmp(video_storage->planes[VPX_PLANE_U], sample_payload, 10) == 0 ||
//             memcmp(video_storage->planes[VPX_PLANE_V], sample_payload, 10) == 0 , "Payload from Alice is invalid");*/
//             vpx_img_free(video_storage);
//         }


        if (time(NULL) - cur_time > 10) { /* Transmit for 10 seconds */
            step++; /* This terminates the loop */
            toxav_kill_transmission(status_control.Alice.av, status_control.Alice.call_index);
            toxav_kill_transmission(status_control.Bob.av, status_control.Bob.call_index);

            /* Call over Alice hangs up */
            toxav_hangup(status_control.Alice.av, status_control.Alice.call_index);
        }
    }
Esempio n. 8
0
void Cyanide::audio_thread()
{
    return;
    const char *device_list, *output_device = NULL;
    //void *audio_device = NULL;

    bool call[MAX_CALLS] = {0}, preview = 0;
    bool audio_filtering_enabled;
    // bool groups_audio[MAX_NUM_GROUPS] = {0};

    int perframe = (av_DefaultSettings.audio_frame_duration * av_DefaultSettings.audio_sample_rate) / 1000;
    uint8_t buf[perframe * 2 * av_DefaultSettings.audio_channels], dest[perframe * 2 * av_DefaultSettings.audio_channels];
    memset(buf, 0, sizeof(buf));

    uint8_t audio_count = 0;
    bool record_on = 0;
    #ifdef AUDIO_FILTERING
    qDebug() << "Audio Filtering enabled";
    #ifdef ALC_LOOPBACK_CAPTURE_SAMPLES
    qDebug() << "Echo cancellation enabled";
    #endif
    #endif

    qDebug() << "frame size:" << perframe;

    device_list = alcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER);
    if(device_list) {
        output_device = device_list;
        qDebug() << "Output Device List:";
        while(*device_list) {
            qDebug() << device_list;
            //postmessage(NEW_AUDIO_OUT_DEVICE, 0, 0, (void*)device_list);
            device_list += strlen(device_list) + 1;
        }
    }

    device_out = alcOpenDevice(output_device);
    if(!device_out) {
        qDebug() << "alcOpenDevice() failed";
        return;
    }

    int attrlist[] = {  ALC_FREQUENCY, av_DefaultSettings.audio_sample_rate,
                        ALC_INVALID };

    context = alcCreateContext(device_out, attrlist);
    if(!alcMakeContextCurrent(context)) {
        qDebug() << "alcMakeContextCurrent() failed";
        alcCloseDevice(device_out);
        return;
    }

    alGenSources(countof(source), source);

    static ALuint ringSrc[MAX_CALLS];
    alGenSources(MAX_CALLS, ringSrc);

    /* Create buffer to store samples */
    ALuint RingBuffer;
    alGenBuffers(1, &RingBuffer);

    {
        float frequency1 = 441.f;
        float frequency2 = 882.f;
        int seconds = 4;
        unsigned sample_rate = 22050;
        size_t buf_size = seconds * sample_rate * 2; //16 bit (2 bytes per sample)
        int16_t *samples = (int16_t*)malloc(buf_size * sizeof(int16_t));
        if (!samples)
            return;

        /*Generate an electronic ringer sound that quickly alternates between two frequencies*/
        int index = 0;
        for(index = 0; index < buf_size; ++index) {
            if ((index / (sample_rate)) % 4 < 2 ) {//4 second ring cycle, first 2 secondsring, the rest(2 seconds) is silence
                if((index / 1000) % 2 == 1) {
                    samples[index] = 5000 * sin((2.0 * 3.1415926 * frequency1) / sample_rate * index); //5000=amplitude(volume level). It can be from zero to 32700
                } else {
                    samples[index] = 5000 * sin((2.0 * 3.1415926 * frequency2) / sample_rate * index);
                }
            } else {
                samples[index] = 0;
            }
        }

        alBufferData(RingBuffer, AL_FORMAT_MONO16, samples, buf_size, sample_rate);
        free(samples);
    }

    {
        unsigned int i;
        for (i = 0; i < MAX_CALLS; ++i) {
            alSourcei(ringSrc[i], AL_LOOPING, AL_TRUE);
            alSourcei(ringSrc[i], AL_BUFFER, RingBuffer);
        }
    }
    #ifdef AUDIO_FILTERING
    Filter_Audio *f_a = NULL;
    #endif

    while(loop == LOOP_RUN || loop == LOOP_SUSPEND) {
        #ifdef AUDIO_FILTERING
        if (!f_a && audio_filtering_enabled) {
            f_a = new_filter_audio(av_DefaultSettings.audio_sample_rate);
            if (!f_a) {
                audio_filtering_enabled = 0;
                qDebug() << "filter audio failed";
            } else {
                qDebug() << "filter audio on";
            }
        } else if (f_a && !audio_filtering_enabled) {
            kill_filter_audio(f_a);
            f_a = NULL;
            qDebug() << "filter audio off";
        }
        #else
        if (audio_filtering_enabled)
            audio_filtering_enabled = 0;
        #endif

        bool sleep = 1;

        if(record_on) {
            ALint samples;
            alcGetIntegerv(device_in, ALC_CAPTURE_SAMPLES, sizeof(samples), &samples);
            if(samples >= perframe) {
                alcCaptureSamples(device_in, buf, perframe);
                if (samples >= perframe * 2) {
                    sleep = 0;
                }
            }
        }

        #ifdef AUDIO_FILTERING
        #ifdef ALC_LOOPBACK_CAPTURE_SAMPLES
        if (f_a && audio_filtering_enabled) {
            ALint samples;
            alcGetIntegerv(device_out, ALC_LOOPBACK_CAPTURE_SAMPLES, sizeof(samples), &samples);
            if(samples >= perframe) {
                int16_t buffer[perframe];
                alcCaptureSamplesLoopback(device_out, buffer, perframe);
                pass_audio_output(f_a, buffer, perframe);
                set_echo_delay_ms(f_a, 5);
                    if (samples >= perframe * 2) {
                    sleep = 0;
                }
            }
        }
        #endif
        #endif

        #ifdef AUDIO_FILTERING
        if (f_a && filter_audio(f_a, (int16_t*)buf, perframe) == -1) {
            qDebug() << "filter audio error";
        }
        #endif
        if(preview) {
            audio_play(0, (int16_t*)buf, perframe, av_DefaultSettings.audio_channels, av_DefaultSettings.audio_sample_rate);
        }

        int i;
        for(i = 0; i < MAX_CALLS; i++) {
            if(call[i]) {
                int r;
                if((r = toxav_prepare_audio_frame(toxav, i, dest, sizeof(dest), (const int16_t*)buf, perframe)) < 0) {
                    qDebug() << "toxav_prepare_audio_frame error" << r;
                    continue;
                }

                if((r = toxav_send_audio(toxav, i, dest, r)) < 0) {
                    qDebug() << "toxav_send_audio error" << r;
                }
            }
        }

        if (sleep) {
            usleep(5000);
        }
    }

    #ifdef AUDIO_FILTERING
    kill_filter_audio(f_a);
    #endif

    //missing some cleanup ?
    alDeleteSources(MAX_CALLS, ringSrc);
    alDeleteSources(countof(source), source);
    alDeleteBuffers(1, &RingBuffer);

    if(device_in) {
        if(record_on) {
            alcCaptureStop(device_in);
        }
        alcCaptureCloseDevice(device_in);
    }

    alcMakeContextCurrent(NULL);
    alcDestroyContext(context);
    alcCloseDevice(device_out);
}