예제 #1
0
sample ComplexODF::process_frame(int signal_size, sample* signal)
{
    sample phase_prediction;
    fftw_complex prediction;
    sample sum = 0.0;

    // do a FFT of the current frame
    memcpy(in, &signal[0], sizeof(sample)*frame_size);
    window_frame(in);
    fftw_execute(p);

    // calculate sum of prediction errors
    for(int bin = 0; bin < num_bins; bin++)
    {
        /* Magnitude prediction is just the previous magnitude.
         * Phase prediction is the previous phase plus the difference between
         * the previous two frames
         */
        phase_prediction = (2.0 * prev_phases[bin]) - prev_phases2[bin];
        /* bring it into the range +- pi */
        while(phase_prediction > M_PI) phase_prediction -= 2.0 * M_PI;
        while(phase_prediction < M_PI) phase_prediction += 2.0 * M_PI;
        /* convert back into the complex domain to calculate stationarities */
        prediction[0] = prev_amps[bin] * cos(phase_prediction);
        prediction[1] = prev_amps[bin] * sin(phase_prediction);
        /* get stationarity measures in the complex domain */
        sum += sqrt(((prediction[0] - out[bin][0])*(prediction[0] - out[bin][0])) +
                    ((prediction[1] - out[bin][1])*(prediction[1] - out[bin][1])));
        prev_amps[bin] = sqrt((out[bin][0]*out[bin][0]) + (out[bin][1]*out[bin][1]));
        prev_phases2[bin] = prev_phases[bin];
        prev_phases[bin] = atan2(out[bin][1], out[bin][0]);
    }

    return sum;
}
예제 #2
0
sample LPSpectralDifferenceODF::process_frame(int signal_size, sample* signal)
{
    sample sum = 0.0;
    sample amp = 0.0;
    sample prediction = 0.0;

    // do a FFT of the current frame
    memcpy(in, &signal[0], sizeof(sample)*frame_size);
    window_frame(in);
    fftw_execute(p);

    // calculate the amplitude differences between bins from consecutive frames 
    for(int bin = 0; bin < num_bins; bin++)
    {
        amp = sqrt((out[bin][0]*out[bin][0]) + (out[bin][1]*out[bin][1]));
        /* get LP coefficients */
        burg(order, prev_amps[bin], order, order, coefs);
        /* get the difference between current and predicted values */
        linear_prediction(order, prev_amps[bin], order, coefs, 1, &prediction);
        sum += fabs(amp - prediction);
        /* move frames back by 1 */
        for(int j = 0; j < order-1; j++)
        {
            prev_amps[bin][j] = prev_amps[bin][j+1];
        }
        prev_amps[bin][order-1] = amp;
    }

    return sum;
}
예제 #3
0
sample SpectralDifferenceODF::process_frame(int signal_size, sample* signal)
{
    sample sum = 0.0;
    sample amp;
    int bin;

    /* do a FFT of the current frame */
    memcpy(in, &signal[0], sizeof(sample)*frame_size);
    window_frame(in);
    fftw_execute(p);

    /* calculate the amplitude differences between bins from consecutive frames */
    sum = 0.0;
    for(bin = 0; bin < num_bins; bin++)
    {
        amp = sqrt((out[bin][0]*out[bin][0]) + (out[bin][1]*out[bin][1]));
        sum += fabs(prev_amps[bin] - amp);
        prev_amps[bin] = amp;
    }

    return sum;
}
예제 #4
0
sample LPComplexODF::process_frame(int signal_size, sample* signal)
{
    sample sum = 0.0;
    sample amp = 0.0;
    sample prediction = 0.0;
    sample distance = 0.0;

    // do a FFT of the current frame
    memcpy(in, &signal[0], sizeof(sample)*frame_size);
    window_frame(in);
    fftw_execute(p);

    for(int bin = 0; bin < num_bins; bin++)
    {
        distance = sqrt((out[bin][0]-prev_frame[bin][0])*(out[bin][0]-prev_frame[bin][0]) +
                        (out[bin][1]-prev_frame[bin][1])*(out[bin][1]-prev_frame[bin][1]));

        /* get LP coefficients */
        burg(order, distances[bin], order, order, coefs);
        /* get the difference between current and predicted values */
        linear_prediction(order, distances[bin], order, coefs, 1, &prediction);
        sum += fabs(distance - prediction);

        /* update distances */
        for(int j = 0; j < order-1; j++)
        {
            distances[bin][j] = distances[bin][j+1];
        }
        distances[bin][order-1] = distance;

        /* update previous frame */
        prev_frame[bin][0] = out[bin][0];
        prev_frame[bin][1] = out[bin][1];
    }

    return sum;
}
예제 #5
0
void DatagramConnection::stream_send(const char *buf, const dtn::data::Length &len, bool last) throw (DatagramException)
{
    // build the right flags
    char flags = 0;

    // if this is the first segment, then set the FIRST bit
    if (_send_state == SEND_IDLE) flags |= DatagramService::SEGMENT_FIRST;

    // if this is the last segment, then set the LAST bit
    if (last) flags |= DatagramService::SEGMENT_LAST;

    // set the seqno for this segment
    unsigned int seqno = _last_ack;

    IBRCOMMON_LOGGER_DEBUG_TAG(DatagramConnection::TAG, 25) << "frame to send, flags: " << (int)flags << ", seqno: " << seqno << ", len: " << len << IBRCOMMON_LOGGER_ENDL;

    if (_params.flowcontrol == DatagramService::FLOW_STOPNWAIT)
    {
        // measure the time until the ack is received
        ibrcommon::TimeMeasurement tm;

        // start time measurement
        tm.start();

        // max. 5 retries
        for (size_t i = 0; i < _params.retry_limit; ++i)
        {
            IBRCOMMON_LOGGER_DEBUG_TAG(DatagramConnection::TAG, 30) << "transmit frame seqno: " << seqno << IBRCOMMON_LOGGER_ENDL;

            // send the datagram
            _callback.callback_send(*this, flags, seqno, getIdentifier(), buf, len);

            // enter the wait state
            _send_state = SEND_WAIT_ACK;

            // set timeout to twice the average round-trip-time
            struct timespec ts;
            ibrcommon::Conditional::gettimeout(static_cast<size_t>(_avg_rtt * 2) + 1, &ts);

            try {
                ibrcommon::MutexLock l(_ack_cond);

                // wait here for an ACK
                while (_last_ack != ((seqno + 1) % _params.max_seq_numbers))
                {
                    _ack_cond.wait(&ts);
                }

                // stop the measurement
                tm.stop();

                // success!
                _send_state = last ? SEND_IDLE : SEND_NEXT;

                // adjust the average rtt
                adjust_rtt(tm.getMilliseconds());

                // report result
                _callback.reportSuccess(i, tm.getMilliseconds());

                return;
            } catch (const ibrcommon::Conditional::ConditionalAbortException &e) {
                if (e.reason == ibrcommon::Conditional::ConditionalAbortException::COND_TIMEOUT)
                {
                    IBRCOMMON_LOGGER_DEBUG_TAG(DatagramConnection::TAG, 20) << "ack timeout for seqno " << seqno << IBRCOMMON_LOGGER_ENDL;

                    // fail -> increment the future timeout
                    adjust_rtt(static_cast<double>(_avg_rtt) * 2);

                    // retransmit the frame
                    continue;
                }
                else
                {
                    // aborted
                    break;
                }
            }
        }

        // maximum number of retransmissions hit
        _send_state = SEND_ERROR;

        // report failure
        _callback.reportFailure();

        // transmission failed - abort the stream
        throw DatagramException("transmission failed - abort the stream");
    }
    else if (_params.flowcontrol == DatagramService::FLOW_SLIDING_WINDOW)
    {
        try {
            // lock the ACK variables and frame window
            ibrcommon::MutexLock l(_ack_cond);

            // timeout value
            struct timespec ts;

            // set timeout to twice the average round-trip-time
            ibrcommon::Conditional::gettimeout(static_cast<size_t>(_avg_rtt * 2) + 1, &ts);

            // wait until window has at least one free slot
            while (sw_frames_full()) _ack_cond.wait(&ts);

            // add new frame to the window
            _sw_frames.push_back(window_frame());

            window_frame &new_frame = _sw_frames.back();

            new_frame.flags = flags;
            new_frame.seqno = seqno;
            new_frame.buf.assign(buf, buf+len);
            new_frame.retry = 0;

            // start RTT measurement
            new_frame.tm.start();

            // send the datagram
            _callback.callback_send(*this, new_frame.flags, new_frame.seqno, getIdentifier(), &new_frame.buf[0], new_frame.buf.size());

            // increment next sequence number
            _last_ack = (seqno + 1) % _params.max_seq_numbers;

            // enter the wait state
            _send_state = SEND_WAIT_ACK;

            // set timeout to twice the average round-trip-time
            ibrcommon::Conditional::gettimeout(static_cast<size_t>(_avg_rtt * 2) + 1, &ts);

            // wait until one more slot is available
            // or no more frames are to ACK (if this was the last frame)
            while ((last && !_sw_frames.empty()) || (!last && sw_frames_full()))
            {
                _ack_cond.wait(&ts);
            }
        } catch (const ibrcommon::Conditional::ConditionalAbortException &e) {
            if (e.reason == ibrcommon::Conditional::ConditionalAbortException::COND_TIMEOUT)
            {
                // timeout - retransmit the whole window
                sw_timeout(last);
            }
            else
            {
                // maximum number of retransmissions hit
                _send_state = SEND_ERROR;

                // report failure
                _callback.reportFailure();

                // transmission failed - abort the stream
                throw DatagramException("transmission failed - abort the stream");
            }
        }

        // if this is the last segment switch directly to IDLE
        _send_state = last ? SEND_IDLE : SEND_NEXT;
    }
    else
    {
        IBRCOMMON_LOGGER_DEBUG_TAG(DatagramConnection::TAG, 30) << "transmit frame seqno: " << seqno << IBRCOMMON_LOGGER_ENDL;

        // send the datagram
        _callback.callback_send(*this, flags, seqno, getIdentifier(), buf, len);

        // if this is the last segment switch directly to IDLE
        _send_state = last ? SEND_IDLE : SEND_NEXT;

        // increment next sequence number
        ibrcommon::MutexLock l(_ack_cond);
        _last_ack = (seqno + 1) % _params.max_seq_numbers;
    }
}